diff --git a/arch/x86/kernel/cpu.c b/arch/x86/kernel/cpu.c index 38261579..7d4ba5de 100644 --- a/arch/x86/kernel/cpu.c +++ b/arch/x86/kernel/cpu.c @@ -448,8 +448,6 @@ void handle_interrupt(int vector, struct x86_regs *regs) check_signal(0, regs); check_need_resched(); - //kprintf("handle_interrupt,exit\n"); - //schedule(); } void gpe_handler(struct x86_regs *regs) diff --git a/arch/x86/kernel/syscall.c b/arch/x86/kernel/syscall.c index 8f28faca..92b8be1e 100644 --- a/arch/x86/kernel/syscall.c +++ b/arch/x86/kernel/syscall.c @@ -246,7 +246,7 @@ do_signal(unsigned long rc, void *regs0, struct process *proc, struct sig_pendin copy_to_user(proc, &sigsp->sigrc, &rc, sizeof(long))){ kfree(pending); ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate); - kprintf("do_signal,copy_to_user failed\n"); + kprintf("do_signal,copy_to_user failed\n"); terminate(0, sig, (ihk_mc_user_context_t *)regs->rsp); return; } @@ -351,7 +351,8 @@ do_signal(unsigned long rc, void *regs0, struct process *proc, struct sig_pendin } } -static int ptrace_report_signal(struct process *proc, struct sig_pending *pending) { +static int ptrace_report_signal(struct process *proc, struct sig_pending *pending) +{ int sig; __sigset_t w; long rc; @@ -363,7 +364,6 @@ static int ptrace_report_signal(struct process *proc, struct sig_pending *pendin /* Transition process state */ proc->ftn->status = PS_TRACED; ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock); - if (proc->ftn->parent) { /* kill SIGCHLD */ ihk_mc_spinlock_lock_noirq(&proc->ftn->parent->lock); @@ -381,7 +381,7 @@ static int ptrace_report_signal(struct process *proc, struct sig_pending *pendin } } ihk_mc_spinlock_unlock_noirq(&proc->ftn->parent->lock); - + /* Wake parent (if sleeping in wait4()) */ waitq_wakeup(&proc->ftn->parent->waitpid_q); } @@ -406,7 +406,7 @@ check_signal(unsigned long rc, void *regs0) ihk_spinlock_t *lock; __sigset_t w, sig_bv; int irqstate; - int sig; + int sig; if(clv == NULL) return; @@ -453,11 +453,11 @@ check_signal(unsigned long rc, void *regs0) return; } - for(sig_bv = pending->sigmask.__val[0], sig = 0; sig_bv; sig++, sig_bv >>= 1); - if((proc->ftn->ptrace & PT_TRACED) && sig != SIGKILL) { - sig = ptrace_report_signal(proc, pending); - /* TODO: Tracing process could overwrite signal, so handle the case here. */ - } + for(sig_bv = pending->sigmask.__val[0], sig = 0; sig_bv; sig++, sig_bv >>= 1); + if((proc->ftn->ptrace & PT_TRACED) && sig != SIGKILL) { + sig = ptrace_report_signal(proc, pending); + /* TODO: Tracing process could overwrite signal, so handle the case here. */ + } do_signal(rc, regs, proc, pending); } @@ -466,7 +466,7 @@ check_signal(unsigned long rc, void *regs0) unsigned long do_kill(int pid, int tid, int sig, siginfo_t *info) { - dkprintf("do_kill,pid=%d,tid=%d,sig=%d\n", pid, tid, sig); + dkprintf("do_kill,pid=%d,tid=%d,sig=%d\n", pid, tid, sig); struct cpu_local_var *v; struct process *p; struct process *proc = cpu_local_var(current); @@ -549,7 +549,7 @@ do_kill(int pid, int tid, int sig, siginfo_t *info) tproc = p; if(!found && savelock) { ihk_mc_spinlock_unlock_noirq(savelock); - } + } found = 1; savelock = &(v->runq_lock); if(savelock0 && savelock0 != savelock){ @@ -572,7 +572,7 @@ do_kill(int pid, int tid, int sig, siginfo_t *info) } if(!found) { ihk_mc_spinlock_unlock_noirq(&(v->runq_lock)); - } + } } if(tproc == NULL){ tproc = tproc0; @@ -637,11 +637,11 @@ do_kill(int pid, int tid, int sig, siginfo_t *info) head = &tproc->sigpending; } - rc = 0; /* Put signal event even when handler is SIG_IGN or SIG_DFL because target ptraced process must call ptrace_report_signal in check_signal */ pending = NULL; + rc = 0; if (sig < 33) { // SIGRTMIN - SIGRTMAX list_for_each_entry(pending, head, list){ if(pending->sigmask.__val[0] == mask) @@ -672,47 +672,47 @@ do_kill(int pid, int tid, int sig, siginfo_t *info) } if(doint && !(mask & tproc->sigmask.__val[0])){ - switch(sig) { - case SIGCONT: - break; - case SIGSTOP: - case SIGKILL: - default: - if(proc != tproc){ - dkprintf("do_kill,ipi,pid=%d,cpu_id=%d\n", - tproc->pid, tproc->cpu_id); - ihk_mc_interrupt_cpu(get_x86_cpu_local_variable(tproc->cpu_id)->apic_id, 0xd0); - } - break; - } + switch(sig) { + case SIGCONT: + break; + case SIGSTOP: + case SIGKILL: + default: + if(proc != tproc){ + dkprintf("do_kill,ipi,pid=%d,cpu_id=%d\n", + tproc->pid, tproc->cpu_id); + ihk_mc_interrupt_cpu(get_x86_cpu_local_variable(tproc->cpu_id)->apic_id, 0xd0); + } + break; + } - ihk_mc_spinlock_unlock_noirq(savelock); - cpu_restore_interrupt(irqstate); + ihk_mc_spinlock_unlock_noirq(savelock); + cpu_restore_interrupt(irqstate); - switch(sig) { - case SIGKILL: + switch(sig) { + case SIGKILL: #if 0 /* Is this really needed? */ - kprintf("do_kill,sending kill to mcexec,pid=%d,cpuid=%d\n", - tproc->pid, tproc->cpu_id); - interrupt_syscall(tproc->pid, tproc->cpu_id); + kprintf("do_kill,sending kill to mcexec,pid=%d,cpuid=%d\n", + tproc->pid, tproc->cpu_id); + interrupt_syscall(tproc->pid, tproc->cpu_id); #endif break; - case SIGCONT: - /* Wake up the target only when stopped by SIGSTOP */ - sched_wakeup_process(tproc, PS_STOPPED); - ihk_mc_spinlock_lock_noirq(&tproc->ftn->lock); - if (tproc->ftn->status & PS_STOPPED) { - xchg4((int *)(&tproc->ftn->status), PS_RUNNING); - /* Reap and set singal_flags */ - tproc->ftn->signal_flags = SIGNAL_STOP_CONTINUED; - } - ihk_mc_spinlock_unlock_noirq(&tproc->ftn->lock); - break; - case SIGSTOP: - default: - break; - } + case SIGCONT: + /* Wake up the target only when stopped by SIGSTOP */ + sched_wakeup_process(tproc, PS_STOPPED); + ihk_mc_spinlock_lock_noirq(&tproc->ftn->lock); + if (tproc->ftn->status & PS_STOPPED) { + xchg4((int *)(&tproc->ftn->status), PS_RUNNING); + /* Reap and set singal_flags */ + tproc->ftn->signal_flags = SIGNAL_STOP_CONTINUED; + } + ihk_mc_spinlock_unlock_noirq(&tproc->ftn->lock); + break; + case SIGSTOP: + default: + break; + } } else{ ihk_mc_spinlock_unlock_noirq(savelock); diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index ae61ff11..205b3123 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -447,7 +447,7 @@ retry: /* Check whether the resolved path is a symlink */ if (lstat(path, &sb) == -1) { - fprintf(stderr, "lookup_exec_path(): %s, error stat\n"); + fprintf(stderr, "lookup_exec_path(): error stat\n"); return errno; } diff --git a/kernel/host.c b/kernel/host.c index 15d5f0ba..cc595b3a 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -362,7 +362,6 @@ static int process_msg_prepare_process(unsigned long rphys) return -ENOMEM; } proc->pid = pn->pid; - kprintf("prepare_process,pid=%d,ptrace=%08x\n", proc->pid, proc->ftn->ptrace); proc->pgid = pn->pgid; proc->ftn->pid = pn->pid; proc->vm->region.user_start = pn->user_start; diff --git a/kernel/process.c b/kernel/process.c index 60bed7d2..4ae6473c 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -318,8 +318,8 @@ err_free_proc: } int ptrace_traceme(void){ - struct process *proc = cpu_local_var(current); - struct fork_tree_node *ftn = proc->ftn, *parent; + struct process *proc = cpu_local_var(current); + struct fork_tree_node *ftn = proc->ftn, *parent; ftn->ptrace = PT_TRACED; @@ -1952,10 +1952,10 @@ redo: void check_need_resched(void) { struct cpu_local_var *v = get_this_cpu_local_var(); - if (v->flags & CPU_FLAG_NEED_RESCHED) { + if (v->flags & CPU_FLAG_NEED_RESCHED) { v->flags &= ~CPU_FLAG_NEED_RESCHED; schedule(); - } + } } @@ -1966,8 +1966,8 @@ int sched_wakeup_process(struct process *proc, int valid_states) unsigned long irqstate; struct cpu_local_var *v = get_cpu_local_var(proc->cpu_id); - dkprintf("sched_wakeup_process,proc->pid=%d,valid_states=%08x,proc->status=%08x,proc->cpu_id=%d,my cpu_id=%d\n", - proc->pid, valid_states, proc->status, proc->cpu_id, ihk_mc_get_processor_id()); + dkprintf("sched_wakeup_process,proc->pid=%d,valid_states=%08x,proc->status=%08x,proc->cpu_id=%d,my cpu_id=%d\n", + proc->pid, valid_states, proc->status, proc->cpu_id, ihk_mc_get_processor_id()); irqstate = ihk_mc_spinlock_lock(&(proc->spin_sleep_lock)); if (proc->spin_sleep) { @@ -1982,7 +1982,7 @@ int sched_wakeup_process(struct process *proc, int valid_states) if (spin_slept) { return status; - } + } irqstate = ihk_mc_spinlock_lock(&(v->runq_lock)); @@ -1997,7 +1997,7 @@ int sched_wakeup_process(struct process *proc, int valid_states) ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate); if (!status && (proc->cpu_id != ihk_mc_get_processor_id())) { - dkprintf("sched_wakeup_process,issuing IPI,proc->cpu_id=%d\n", + dkprintf("sched_wakeup_process,issuing IPI,proc->cpu_id=%d\n", proc->cpu_id); ihk_mc_interrupt_cpu(get_x86_cpu_local_variable(proc->cpu_id)->apic_id, 0xd1); diff --git a/kernel/syscall.c b/kernel/syscall.c index d7b1ee9e..7575111a 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -324,56 +324,57 @@ static int wait_zombie(struct process *proc, struct fork_tree_node *child, int * return ret; } -static int wait_stopped(struct process *proc, struct fork_tree_node *child, int *status, int options) { - dkprintf("wait_stopped,proc->pid=%d,child->pid=%d,options=%08x\n", +static int wait_stopped(struct process *proc, struct fork_tree_node *child, int *status, int options) +{ + dkprintf("wait_stopped,proc->pid=%d,child->pid=%d,options=%08x\n", proc->pid, child->pid, options); - int ret; - - /* Copy exit_status created in do_signal */ - int *exit_status = (child->ptrace & PT_TRACED) ? - &child->exit_status : - &child->group_exit_status; - - /* Skip this process because exit_status has been reaped. */ - if (!*exit_status) { - ret = 0; - goto out; - } + int ret; - /* TODO: define 0x7f in kernel/include/process.h */ - if (status) { - *status = (*exit_status << 8) | 0x7f; - } - - /* Reap exit_status. signal_flags is reaped on receiving signal - in do_kill(). */ - if(!(options & WNOWAIT)) { - *exit_status = 0; - } - - dkprintf("wait_stopped,child->pid=%d,status=%08x\n", + /* Copy exit_status created in do_signal */ + int *exit_status = (child->ptrace & PT_TRACED) ? + &child->exit_status : + &child->group_exit_status; + + /* Skip this process because exit_status has been reaped. */ + if (!*exit_status) { + ret = 0; + goto out; + } + + /* TODO: define 0x7f in kernel/include/process.h */ + if (status) { + *status = (*exit_status << 8) | 0x7f; + } + + /* Reap exit_status. signal_flags is reaped on receiving signal + in do_kill(). */ + if(!(options & WNOWAIT)) { + *exit_status = 0; + } + + dkprintf("wait_stopped,child->pid=%d,status=%08x\n", child->pid, status ? *status : -1); - ret = child->pid; + ret = child->pid; out: - return ret; + return ret; } static int wait_continued(struct process *proc, struct fork_tree_node *child, int *status, int options) { - int ret; - - if (status) { - *status = 0xffff; - } + int ret; - /* Reap signal_flags */ - if(!(options & WNOWAIT)) { - child->signal_flags &= ~SIGNAL_STOP_CONTINUED; - } + if (status) { + *status = 0xffff; + } - dkprintf("wait4,SIGNAL_STOP_CONTINUED,pid=%d,status=%08x\n", + /* Reap signal_flags */ + if(!(options & WNOWAIT)) { + child->signal_flags &= ~SIGNAL_STOP_CONTINUED; + } + + dkprintf("wait4,SIGNAL_STOP_CONTINUED,pid=%d,status=%08x\n", child->pid, status ? *status : -1); - ret = child->pid; - return ret; + ret = child->pid; + return ret; } /* @@ -391,92 +392,92 @@ SYSCALL_DECLARE(wait4) struct waitq_entry waitpid_wqe; int empty = 1; - dkprintf("wait4,proc->pid=%d,pid=%d\n", proc->pid, pid); - if (options & ~(WNOHANG | WUNTRACED | WCONTINUED)) { - ret = -EINVAL; - goto exit; - } -rescan: + dkprintf("wait4,proc->pid=%d,pid=%d\n", proc->pid, pid); + if (options & ~(WNOHANG | WUNTRACED | WCONTINUED)) { + ret = -EINVAL; + goto exit; + } + rescan: pid = (int)ihk_mc_syscall_arg0(ctx); - + ihk_mc_spinlock_lock_noirq(&proc->ftn->lock); - + list_for_each_entry(child_iter, &proc->ftn->children, siblings_list) { ihk_mc_spinlock_lock_noirq(&child_iter->lock); - + if ((pid < 0 && -pid == child_iter->pgid) || pid == -1 || (pid == 0 && pgid == child_iter->pgid) || (pid > 0 && pid == child_iter->pid)) { - empty = 0; + empty = 0; - if(child_iter->status == PS_ZOMBIE) { - ret = wait_zombie(proc, child_iter, status, ctx); - if(ret) { - goto out_found; - } - } + if(child_iter->status == PS_ZOMBIE) { + ret = wait_zombie(proc, child_iter, status, ctx); + if(ret) { + goto out_found; + } + } - if((child_iter->signal_flags & SIGNAL_STOP_STOPPED) && - (options & WUNTRACED)) { - /* Not ptraced and in stopped state and WUNTRACED is specified */ - ret = wait_stopped(proc, child_iter, status, options); - if(ret) { - goto out_found; - } - } - - if((child_iter->signal_flags & SIGNAL_STOP_CONTINUED) && - (options & WCONTINUED)) { - ret = wait_continued(proc, child_iter, status, options); - if(ret) { - goto out_found; - } - } + if((child_iter->signal_flags & SIGNAL_STOP_STOPPED) && + (options & WUNTRACED)) { + /* Not ptraced and in stopped state and WUNTRACED is specified */ + ret = wait_stopped(proc, child_iter, status, options); + if(ret) { + goto out_found; + } + } + + if((child_iter->signal_flags & SIGNAL_STOP_CONTINUED) && + (options & WCONTINUED)) { + ret = wait_continued(proc, child_iter, status, options); + if(ret) { + goto out_found; + } + } } - + ihk_mc_spinlock_unlock_noirq(&child_iter->lock); } list_for_each_entry(child_iter, &proc->ftn->ptrace_children, ptrace_siblings_list) { ihk_mc_spinlock_lock_noirq(&child_iter->lock); - + if ((pid < 0 && -pid == child_iter->pgid) || pid == -1 || (pid == 0 && pgid == child_iter->pgid) || (pid > 0 && pid == child_iter->pid)) { - empty = 0; + empty = 0; - if(child_iter->status == PS_ZOMBIE) { - ret = wait_zombie(proc, child_iter, status, ctx); - if(ret) { - goto out_found; - } - } + if(child_iter->status == PS_ZOMBIE) { + ret = wait_zombie(proc, child_iter, status, ctx); + if(ret) { + goto out_found; + } + } - if(child_iter->status & (PS_STOPPED | PS_TRACED)) { - /* ptraced and in stopped or trace-stopped state */ - ret = wait_stopped(proc, child_iter, status, options); - if(ret) { - goto out_found; - } - } else { - /* ptraced and in running or sleeping state */ - } + if(child_iter->status & (PS_STOPPED | PS_TRACED)) { + /* ptraced and in stopped or trace-stopped state */ + ret = wait_stopped(proc, child_iter, status, options); + if(ret) { + goto out_found; + } + } else { + /* ptraced and in running or sleeping state */ + } - if((child_iter->signal_flags & SIGNAL_STOP_CONTINUED) && - (options & WCONTINUED)) { - ret = wait_continued(proc, child_iter, status, options); - if(ret) { - goto out_found; - } - } + if((child_iter->signal_flags & SIGNAL_STOP_CONTINUED) && + (options & WCONTINUED)) { + ret = wait_continued(proc, child_iter, status, options); + if(ret) { + goto out_found; + } + } } - + ihk_mc_spinlock_unlock_noirq(&child_iter->lock); } @@ -484,7 +485,7 @@ rescan: ret = -ECHILD; goto out_notfound; } - + /* Don't sleep if WNOHANG requested */ if (options & WNOHANG) { *status = 0; @@ -493,7 +494,7 @@ rescan: } /* Sleep */ - dkprintf("wait4,sleeping\n"); + dkprintf("wait4,sleeping\n"); waitq_init_entry(&waitpid_wqe, proc); waitq_prepare_to_wait(&proc->ftn->waitpid_q, &waitpid_wqe, PS_INTERRUPTIBLE); @@ -505,14 +506,14 @@ rescan: waitq_finish_wait(&proc->ftn->waitpid_q, &waitpid_wqe); goto rescan; - + exit: - return ret; + return ret; out_found: - ihk_mc_spinlock_unlock_noirq(&child_iter->lock); + ihk_mc_spinlock_unlock_noirq(&child_iter->lock); out_notfound: - ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock); - goto exit; + ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock); + goto exit; } void @@ -522,8 +523,8 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx) struct process *proc = cpu_local_var(current); struct fork_tree_node *ftn = proc->ftn; struct fork_tree_node *child, *next; - struct process *parent_owner; - int error; + struct process *parent_owner; + int error; request.number = __NR_exit_group; request.args[0] = ((rc & 0x00ff) << 8) | (sig & 0xff); @@ -554,7 +555,7 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx) dkprintf("terminate,ftn->parent->owner->pid=%d\n", ftn->parent->owner->pid); - + ihk_mc_spinlock_lock_noirq(&ftn->lock); ftn->pid = proc->pid; ftn->exit_status = ((rc & 0x00ff) << 8) | (sig & 0xff); @@ -584,7 +585,7 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx) sigchld_parent(ftn->parent->owner, 0); */ dkprintf("terminate,klll SIGCHILD,error=%d\n", - error); + error); } release_fork_tree_node(ftn->parent); @@ -605,7 +606,7 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx) void interrupt_syscall(int pid, int cpuid) { - dkprintf("interrupt_syscall,target pid=%d,target cpuid=%d\n", pid, cpuid); + dkprintf("interrupt_syscall,target pid=%d,target cpuid=%d\n", pid, cpuid); ihk_mc_user_context_t ctx; long lerror; @@ -1364,7 +1365,8 @@ SYSCALL_DECLARE(arch_prctl) ihk_mc_syscall_arg1(ctx)); } -static int ptrace_report_exec(struct process *proc) { +static int ptrace_report_exec(struct process *proc) +{ int error = 0; long rc; struct siginfo info; @@ -1382,13 +1384,13 @@ static int ptrace_report_exec(struct process *proc) { /* Transition process state */ proc->ftn->status = PS_TRACED; ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock); - + /* Signal myself so that my parent can wait for me */ rc = do_kill(proc->ftn->pid, -1, SIGTRAP, &info); if (rc < 0) { kprintf("ptrace_report_exec,do_kill failed\n"); } - + if (proc->ftn->parent) { /* kill SIGCHLD */ ihk_mc_spinlock_lock_noirq(&proc->ftn->parent->lock); @@ -1404,7 +1406,7 @@ static int ptrace_report_exec(struct process *proc) { } } ihk_mc_spinlock_unlock_noirq(&proc->ftn->parent->lock); - + /* Wake parent (if sleeping in wait4()) */ waitq_wakeup(&proc->ftn->parent->waitpid_q); } @@ -1415,7 +1417,7 @@ out: SYSCALL_DECLARE(execve) { - int error; + int error; long ret; char *empty_envp[1] = {NULL}; const char *filename = (const char *)ihk_mc_syscall_arg0(ctx); @@ -1530,10 +1532,10 @@ SYSCALL_DECLARE(execve) panic(""); } - error = ptrace_report_exec(cpu_local_var(current)); - if(error) { + error = ptrace_report_exec(cpu_local_var(current)); + if(error) { kprintf("execve(): ERROR: ptrace_report_exec()\n"); - } + } /* Switch to new execution context */ dkprintf("execve(): switching to new process\n"); @@ -2352,19 +2354,20 @@ SYSCALL_DECLARE(ptrace) const int pid = (int)ihk_mc_syscall_arg1(ctx); const long addr = (long)ihk_mc_syscall_arg2(ctx); const long data = (long)ihk_mc_syscall_arg3(ctx); - int error; + int error; - switch(request) { - case PTRACE_TRACEME: - error = ptrace_traceme(); - case PTRACE_KILL: - case PTRACE_CONT: - error = ptrace_wakeup_sig(pid, request, data); - break; - default: - error = 0; - break; - } + switch(request) { + case PTRACE_TRACEME: + error = ptrace_traceme(); + break; + case PTRACE_KILL: + case PTRACE_CONT: + error = ptrace_wakeup_sig(pid, request, data); + break; + default: + error = 0; + break; + } dkprintf("ptrace(%d,%ld,%p,%p): returning %d\n", request, pid, addr, data, error); return error;