diff --git a/arch/x86/kernel/syscall.c b/arch/x86/kernel/syscall.c index 6c6d8d7b..a976289c 100644 --- a/arch/x86/kernel/syscall.c +++ b/arch/x86/kernel/syscall.c @@ -98,6 +98,8 @@ SYSCALL_DECLARE(rt_sigreturn) } extern struct cpu_local_var *clv; +extern unsigned long do_kill(int pid, int sig); +extern void interrupt_syscall(); void check_signal(unsigned long rc, unsigned long *regs) @@ -123,7 +125,6 @@ check_signal(unsigned long rc, unsigned long *regs) else{ rc = regs[9]; /* rax */ } - k = proc->sighandler->action + sig - 1; if(k->sa.sa_handler == (void *)1){ @@ -133,6 +134,13 @@ check_signal(unsigned long rc, unsigned long *regs) else if(k->sa.sa_handler){ unsigned long *usp; /* user stack */ + if(regs[14] & 0x8000000000000000){ // kernel addr + proc->signal = sig; + interrupt_syscall(); + ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate); + return; + } + usp = (void *)regs[14]; memcpy(proc->sigstack, regs, 128); proc->sigrc = rc; @@ -153,8 +161,6 @@ check_signal(unsigned long rc, unsigned long *regs) } } -extern unsigned long do_kill(int pid, int sig); - unsigned long do_kill(int pid, int sig) { @@ -187,4 +193,5 @@ set_signal(int sig, unsigned long *regs) if(proc == NULL || proc->pid == 0) return; proc->signal = sig; + interrupt_syscall(); } diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index a357678e..3484a03c 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -116,6 +116,11 @@ static int fd; static char *altroot; static const char rlimit_stack_envname[] = "MCKERNEL_RLIMIT_STACK"; +pid_t gettid(void) +{ + return syscall(SYS_gettid); +} + struct program_load_desc *load_elf(FILE *fp, char **interp_pathp) { Elf64_Ehdr hdr; @@ -483,6 +488,8 @@ struct thread_data_s { int ret; pthread_mutex_t *lock; } *thread_data; +int ncpu; +pid_t master_tid; static void *main_loop_thread_func(void *arg) { @@ -498,6 +505,9 @@ sendsig(int sig) { unsigned long param; + if(gettid() != master_tid) + return; + param = ((unsigned long)sig) << 32 | ((unsigned long)getpid()); if (ioctl(fd, MCEXEC_UP_SEND_SIGNAL, param) != 0) { perror("send_signal"); @@ -562,7 +572,6 @@ int main(int argc, char **argv) char **a; char *p; int i; - int ncpu; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; FILE *interp = NULL; char *interp_path; @@ -766,6 +775,18 @@ int main(int argc, char **argv) __dprint("mccmd server initialized\n"); #endif + master_tid = gettid(); + for (i = 1; i <= 64; i++) + if (i != SIGCHLD && i != SIGCONT && i != SIGSTOP && + i != SIGTSTP && i != SIGTTIN && i != SIGTTOU){ + struct sigaction act; + + sigaction(i, NULL, &act); + act.sa_handler = sendsig; + act.sa_flags &= ~(SA_RESTART); + sigaction(i, &act, NULL); + } + for (i = 0; i <= ncpu; ++i) { int ret; @@ -787,11 +808,6 @@ int main(int argc, char **argv) return 1; } - for (i = 1; i <= 64; i++) - if (i != SIGCHLD && i != SIGCONT && i != SIGSTOP && - i != SIGTSTP && i != SIGTTIN && i != SIGTTOU) - signal(i, sendsig); - for (i = 0; i <= ncpu; ++i) { pthread_join(thread_data[i].thread_id, NULL); } @@ -851,6 +867,21 @@ do_generic_syscall( return ret; } +static void +kill_thread(unsigned long cpu) +{ + if(cpu >= 0 && cpu < ncpu){ + pthread_kill(thread_data[cpu].thread_id, SIGINT); + } + else{ + int i; + + for (i = 0; i < ncpu; ++i) { + pthread_kill(thread_data[i].thread_id, SIGINT); + } + } +} + #define SET_ERR(ret) if (ret == -1) ret = -errno int main_loop(int fd, int cpu, pthread_mutex_t *lock) @@ -860,10 +891,10 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) char *fn; int sig; int term; - + w.cpu = cpu; - while (ioctl(fd, MCEXEC_UP_WAIT_SYSCALL, (unsigned long)&w) == 0) { + while (((ret = ioctl(fd, MCEXEC_UP_WAIT_SYSCALL, (unsigned long)&w)) == 0) || (ret == -1 && errno == EINTR)) { /* Don't print when got a msg to stdout */ if (!(w.sr.number == __NR_write && w.sr.args[0] == 1)) @@ -909,6 +940,10 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) w.sr.args[0], sizeof(struct timeval)); break; + case __NR_kill: // interrupt syscall + kill_thread(w.sr.args[0]); + do_syscall_return(fd, cpu, 0, 0, 0, 0, 0); + break; case __NR_exit: case __NR_exit_group: sig = 0; @@ -963,6 +998,8 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) } #endif default: +fprintf(stderr, "syscall=%ld\n", w.sr.number); +fflush(stderr); ret = do_generic_syscall(&w); do_syscall_return(fd, cpu, ret, 0, 0, 0, 0); break; diff --git a/kernel/syscall.c b/kernel/syscall.c index 97d87ca3..35d1c31f 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -108,7 +108,8 @@ static void send_syscall(struct syscall_request *req) struct ihk_ikc_channel_desc *syscall_channel; int cpu; - if(req->number == __NR_exit_group){ + if(req->number == __NR_exit_group || + req->number == __NR_kill){ // interrupt syscall extern int num_processors; scp = &get_cpu_local_var(0)->scp2; @@ -160,7 +161,8 @@ int do_syscall(struct syscall_request *req, ihk_mc_user_context_t *ctx) ihk_mc_get_processor_id(), req->number); - if(req->number == __NR_exit_group){ + if(req->number == __NR_exit_group || + req->number == __NR_kill){ // interrupt syscall scp = &get_cpu_local_var(0)->scp2; } else{ @@ -250,6 +252,22 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx) schedule(); } +void +interrupt_syscall() +{ + ihk_mc_user_context_t ctx; + long lerror; + + ihk_mc_syscall_arg0(&ctx) = ihk_mc_get_processor_id(); + ihk_mc_syscall_arg1(&ctx) = 0; + + lerror = syscall_generic_forwarding(__NR_kill, &ctx); + if (lerror) { + kprintf("clear_host_pte failed. %ld\n", lerror); + } + return; +} + SYSCALL_DECLARE(exit_group) { #if 0