From adb6cce3ce9cfddf81d029856a67b43d27a1e944 Mon Sep 17 00:00:00 2001 From: Tomoki Shirasawa Date: Fri, 29 Nov 2019 09:40:34 +0900 Subject: [PATCH] The process sending SIGCONT resumes the stopped process. Change-Id: I64ee10172b99aa58540ffe8e9dd80fa0a64f4d01 Refs: #1420 --- arch/arm64/kernel/syscall.c | 36 +++++++++++++++++++++-------------- arch/x86_64/kernel/syscall.c | 37 ++++++++++++++++++++++-------------- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index 6f232b3a..679fd3fd 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -1282,15 +1282,6 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi dkprintf("SIGTRAP(): woken up\n"); break; case SIGCONT: - memset(&info, '\0', sizeof info); - info.si_signo = SIGCHLD; - info.si_code = CLD_CONTINUED; - info._sifields._sigchld.si_pid = proc->pid; - info._sifields._sigchld.si_status = 0x0000ffff; - do_kill(cpu_local_var(current), proc->parent->pid, -1, SIGCHLD, &info, 0); - proc->main_thread->signal_flags = SIGNAL_STOP_CONTINUED; - proc->status = PS_RUNNING; - dkprintf("do_signal,SIGCONT,do nothing\n"); break; case SIGQUIT: case SIGILL: @@ -1861,6 +1852,28 @@ done: mcs_rwlock_writer_unlock_noirq(savelock, &mcs_rw_node); cpu_restore_interrupt(irqstate); + if (sig == SIGCONT || ptracecont == 1) { + /* Wake up the target only when stopped by SIGSTOP */ + if (sched_wakeup_thread(tthread, PS_STOPPED) == 0) { + struct siginfo info; + + tthread->proc->main_thread->signal_flags = + SIGNAL_STOP_CONTINUED; + tthread->proc->status = PS_RUNNING; + memset(&info, '\0', sizeof(info)); + info.si_signo = SIGCHLD; + info.si_code = CLD_CONTINUED; + info._sifields._sigchld.si_pid = tthread->proc->pid; + info._sifields._sigchld.si_status = 0x0000ffff; + do_kill(tthread, tthread->proc->parent->pid, -1, + SIGCHLD, &info, 0); + if (thread != tthread) { + ihk_mc_interrupt_cpu(tthread->cpu_id, + ihk_mc_get_vector(IHK_GV_IKC)); + } + doint = 0; + } + } if (doint && !(mask & tthread->sigmask.__val[0])) { int status = tthread->status; @@ -1875,11 +1888,6 @@ done: /* Wake up the target only when stopped by ptrace-reporting */ sched_wakeup_thread(tthread, PS_TRACED | PS_STOPPED | PS_INTERRUPTIBLE); } - else if(sig == SIGCONT || ptracecont == 1){ - /* Wake up the target only when stopped by SIGSTOP */ - sched_wakeup_thread(tthread, PS_STOPPED); - tthread->proc->status = PS_RUNNING; - } else { sched_wakeup_thread(tthread, PS_INTERRUPTIBLE); } diff --git a/arch/x86_64/kernel/syscall.c b/arch/x86_64/kernel/syscall.c index aec4baae..f784bebd 100644 --- a/arch/x86_64/kernel/syscall.c +++ b/arch/x86_64/kernel/syscall.c @@ -987,15 +987,6 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi dkprintf("SIGTRAP(): woken up\n"); break; case SIGCONT: - memset(&info, '\0', sizeof info); - info.si_signo = SIGCHLD; - info.si_code = CLD_CONTINUED; - info._sifields._sigchld.si_pid = proc->pid; - info._sifields._sigchld.si_status = 0x0000ffff; - do_kill(cpu_local_var(current), proc->parent->pid, -1, SIGCHLD, &info, 0); - proc->main_thread->signal_flags = SIGNAL_STOP_CONTINUED; - proc->status = PS_RUNNING; - dkprintf("do_signal,SIGCONT,do nothing\n"); break; case SIGQUIT: case SIGILL: @@ -1588,6 +1579,29 @@ done: mcs_rwlock_writer_unlock_noirq(savelock, &mcs_rw_node); cpu_restore_interrupt(irqstate); + if (sig == SIGCONT || ptracecont == 1) { + /* Wake up the target only when stopped by SIGSTOP */ + if (sched_wakeup_thread(tthread, PS_STOPPED) == 0) { + struct siginfo info; + + tthread->proc->main_thread->signal_flags = + SIGNAL_STOP_CONTINUED; + tthread->proc->status = PS_RUNNING; + memset(&info, '\0', sizeof(info)); + info.si_signo = SIGCHLD; + info.si_code = CLD_CONTINUED; + info._sifields._sigchld.si_pid = tthread->proc->pid; + info._sifields._sigchld.si_status = 0x0000ffff; + do_kill(tthread, tthread->proc->parent->pid, -1, + SIGCHLD, &info, 0); + tthread->proc->status = PS_RUNNING; + if (thread != tthread) { + ihk_mc_interrupt_cpu(tthread->cpu_id, + ihk_mc_get_vector(IHK_GV_IKC)); + } + doint = 0; + } + } if (doint && !(mask & tthread->sigmask.__val[0])) { int status = tthread->status; @@ -1603,11 +1617,6 @@ done: /* Wake up the target only when stopped by ptrace-reporting */ sched_wakeup_thread(tthread, PS_TRACED | PS_STOPPED | PS_INTERRUPTIBLE); } - else if(sig == SIGCONT || ptracecont == 1){ - /* Wake up the target only when stopped by SIGSTOP */ - sched_wakeup_thread(tthread, PS_STOPPED); - tthread->proc->status = PS_RUNNING; - } else { sched_wakeup_thread(tthread, PS_INTERRUPTIBLE); }