diff --git a/arch/x86/kernel/include/syscall_list.h b/arch/x86/kernel/include/syscall_list.h index af7fb177..b0775db2 100644 --- a/arch/x86/kernel/include/syscall_list.h +++ b/arch/x86/kernel/include/syscall_list.h @@ -61,6 +61,7 @@ SYSCALL_DELEGATED(102, getuid) SYSCALL_DELEGATED(104, getgid) SYSCALL_DELEGATED(107, geteuid) SYSCALL_DELEGATED(108, getegid) +SYSCALL_HANDLED(109, setpgid) SYSCALL_DELEGATED(110, getppid) SYSCALL_DELEGATED(111, getpgrp) SYSCALL_HANDLED(127, rt_sigpending) diff --git a/arch/x86/kernel/syscall.c b/arch/x86/kernel/syscall.c index d9fc3d86..34f9e582 100644 --- a/arch/x86/kernel/syscall.c +++ b/arch/x86/kernel/syscall.c @@ -159,6 +159,34 @@ extern unsigned long do_kill(int pid, int tid, int sig); extern void interrupt_syscall(int all, int pid); extern int num_processors; +void +do_setpgid(int pid, int pgid) +{ + struct cpu_local_var *v; + struct process *p; + struct process *proc = cpu_local_var(current); + int i; + unsigned long irqstate; + + if(pid == 0) + pid = proc->pid; + if(pgid == 0) + pgid = pid; + + for(i = 0; i < num_processors; i++){ + v = get_cpu_local_var(i); + irqstate = ihk_mc_spinlock_lock(&(v->runq_lock)); + list_for_each_entry(p, &(v->runq), sched_list){ + if(p->pid <= 0) + continue; + if(p->pid == pid){ + p->pgid = pgid; + } + } + ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate); + } +} + void do_signal(unsigned long rc, void *regs0, struct process *proc, struct sig_pending *pending) { @@ -319,6 +347,52 @@ do_kill(int pid, int tid, int sig) if(sig > 64 || sig < 0) return -EINVAL; + if(tid == -1 && pid <= 0){ + int pgid = -pid; + int rc = -ESRCH; + int *pids; + int i; + int n = 0; + int sendme = 0; + + pids = kmalloc(sizeof(int) * num_processors, IHK_MC_AP_NOWAIT); + if(!pids) + return -ENOMEM; + if(pid == 0) + pgid = proc->pgid; + for(i = 0; i < num_processors; i++){ + v = get_cpu_local_var(i); + irqstate = ihk_mc_spinlock_lock(&(v->runq_lock)); + list_for_each_entry(p, &(v->runq), sched_list){ + if(p->pid <= 0) + continue; + if(p->pid == proc->pid){ + sendme = 1; + continue; + } + if(pgid == 1 || p->pgid == pgid){ + int j; + + for(j = 0; j < n; j++) + if(pids[j] == p->pid) + break; + if(j == n){ + pids[n] = p->pid; + n++; + } + } + } + ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate); + } + for(i = 0; i < n; i++) + rc = do_kill(pids[i], -1, sig); + if(sendme) + rc = do_kill(proc->pid, -1, sig); + + kfree(pids); + return rc; + } + mask = __sigmask(sig); if(tid == -1){ struct process *tproc0 = NULL; @@ -381,7 +455,6 @@ do_kill(int pid, int tid, int sig) if(sig == 0) return 0; - doint = 0; if(tid == -1){ irqstate = ihk_mc_spinlock_lock(&tproc->sigshared->lock); diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index 87b53892..cb2e95c7 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -70,6 +70,7 @@ struct program_load_desc { int pid; int err; int stack_prot; + int pgid; unsigned long entry; unsigned long user_start; unsigned long user_end; diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index 647b665d..90f1c51d 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -215,6 +215,7 @@ struct program_load_desc *load_elf(FILE *fp, char **interp_pathp) } } desc->pid = getpid(); + desc->pgid = getpgid(0); desc->entry = hdr.e_entry; desc->at_phdr = load_addr + hdr.e_phoff; diff --git a/kernel/host.c b/kernel/host.c index 7f469fa1..2330972c 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -391,6 +391,7 @@ static int process_msg_prepare_process(unsigned long rphys) } proc->pid = pn->pid; proc->tid = pn->pid; + proc->pgid = pn->pgid; proc->ftn->pid = pn->pid; proc->vm->region.user_start = pn->user_start; proc->vm->region.user_end = pn->user_end; diff --git a/kernel/include/process.h b/kernel/include/process.h index 09ea47e0..f3a9e4eb 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -194,6 +194,7 @@ struct process { cpu_set_t cpu_set; unsigned long saved_auxv[AUXV_LEN]; + int pgid; /* process group id */ }; struct process_vm { diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index fcb718fe..d04d9a90 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -110,6 +110,7 @@ struct program_load_desc { int pid; int err; int stack_prot; + int pgid; unsigned long entry; unsigned long user_start; unsigned long user_end; diff --git a/kernel/syscall.c b/kernel/syscall.c index 7b1593e2..1b64b233 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -98,6 +98,7 @@ void do_signal(long rc, void *regs, struct process *proc, struct sig_pending *pe extern unsigned long do_kill(int pid, int tid, int sig); int copy_from_user(struct process *, void *, const void *, size_t); int copy_to_user(struct process *, void *, const void *, size_t); +void do_setpgid(int, int); int prepare_process_ranges_args_envs(struct process *proc, struct program_load_desc *pn, @@ -1318,6 +1319,8 @@ SYSCALL_DECLARE(clone) return -ENOMEM; } + new->pgid = cpu_local_var(current)->pgid; + cpu_set(cpuid, &new->vm->cpu_set, &new->vm->cpu_set_lock); if (clone_flags & CLONE_VM) { @@ -1430,10 +1433,28 @@ SYSCALL_DECLARE(kill) SYSCALL_DECLARE(tgkill) { int tgid = ihk_mc_syscall_arg0(ctx); - int pid = ihk_mc_syscall_arg1(ctx); + int tid = ihk_mc_syscall_arg1(ctx); int sig = ihk_mc_syscall_arg2(ctx); - return do_kill(tgid, pid, sig); + if(tid <= 0) + return -EINVAL; + if(tgid <= 0 && tgid != -1) + return -EINVAL; + + return do_kill(tgid, tid, sig); +} + +SYSCALL_DECLARE(setpgid) +{ + int pid = ihk_mc_syscall_arg0(ctx); + int pgid = ihk_mc_syscall_arg1(ctx); + long rc; + + rc = syscall_generic_forwarding(__NR_setpgid, ctx); + if(rc == 0){ + do_setpgid(pid, pgid); + } + return rc; } SYSCALL_DECLARE(set_robust_list)