From 1d6922553262c28212bdca5ae0e47386f2cf56a3 Mon Sep 17 00:00:00 2001 From: Tomoki Shirasawa Date: Mon, 19 Aug 2013 12:17:23 +0900 Subject: [PATCH] mcexec forward signal to MIC process. --- arch/x86/kernel/cpu.c | 10 +++-- arch/x86/kernel/include/syscall_list.h | 5 +++ arch/x86/kernel/syscall.c | 40 ++++++++++++++---- executer/include/uprotocol.h | 1 + executer/kernel/control.c | 19 +++++++++ executer/kernel/driver.c | 1 + executer/kernel/mcctrl.h | 1 + executer/user/mcexec.c | 22 +++++++++- kernel/host.c | 6 +++ kernel/include/process.h | 7 +++- kernel/include/syscall.h | 1 + kernel/mem.c | 6 ++- kernel/process.c | 9 ++-- kernel/syscall.c | 57 +++++++++++++++++--------- 14 files changed, 148 insertions(+), 37 deletions(-) diff --git a/arch/x86/kernel/cpu.c b/arch/x86/kernel/cpu.c index c411ca71..6a29d057 100644 --- a/arch/x86/kernel/cpu.c +++ b/arch/x86/kernel/cpu.c @@ -8,6 +8,7 @@ #include #include #include +#include #define LAPIC_ID 0x020 #define LAPIC_TIMER 0x320 @@ -341,6 +342,8 @@ void setup_x86_ap(void (*next_func)(void)) } void arch_show_interrupt_context(const void *reg); +void set_signal(int, void *); +void check_signal(long, void *); void handle_interrupt(int vector, struct x86_regs *regs) { @@ -371,16 +374,17 @@ void handle_interrupt(int vector, struct x86_regs *regs) } } } -} -void sigill(void *); + check_signal(0, regs); +} void gpe_handler(struct x86_regs *regs) { kprintf("General protection fault (err: %lx, %lx:%lx)\n", regs->error, regs->cs, regs->rip); arch_show_interrupt_context(regs); - sigill(regs); + set_signal(SIGILL, regs); + check_signal(0, regs); // panic("GPF"); } diff --git a/arch/x86/kernel/include/syscall_list.h b/arch/x86/kernel/include/syscall_list.h index 1ad33cda..1d63b08b 100644 --- a/arch/x86/kernel/include/syscall_list.h +++ b/arch/x86/kernel/include/syscall_list.h @@ -49,6 +49,11 @@ SYSCALL_DELEGATED(107, geteuid) SYSCALL_DELEGATED(108, getegid) SYSCALL_DELEGATED(110, getppid) SYSCALL_DELEGATED(111, getpgrp) +SYSCALL_HANDLED(127, rt_sigpending) +SYSCALL_HANDLED(128, rt_sigtimedwait) +SYSCALL_HANDLED(129, rt_sigqueueinfo) +SYSCALL_HANDLED(130, rt_sigsuspend) +SYSCALL_HANDLED(131, sigaltstack) SYSCALL_HANDLED(158, arch_prctl) SYSCALL_DELEGATED(201, time) SYSCALL_HANDLED(202, futex) diff --git a/arch/x86/kernel/syscall.c b/arch/x86/kernel/syscall.c index 51293856..9e8fc49b 100644 --- a/arch/x86/kernel/syscall.c +++ b/arch/x86/kernel/syscall.c @@ -8,6 +8,7 @@ #include #include #include +#include void terminate(int, int, ihk_mc_user_context_t *); @@ -91,8 +92,12 @@ check_signal(unsigned long rc, unsigned long *regs) struct k_sigaction *k; int sig = proc->signal; + if(proc == NULL || proc->pid == 0) + return; + proc->signal = 0; if(sig){ + int irqstate = ihk_mc_spinlock_lock(&proc->sighandler->lock); if(regs == NULL){ /* call from syscall */ asm volatile ("movq %%gs:132,%0" : "=r" (regs)); regs -= 16; @@ -104,6 +109,7 @@ check_signal(unsigned long rc, unsigned long *regs) k = proc->sighandler->action + sig - 1; if(k->sa.sa_handler == (void *)1){ + ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate); return; } else if(k->sa.sa_handler){ @@ -118,8 +124,10 @@ check_signal(unsigned long rc, unsigned long *regs) regs[4] = (unsigned long)sig; regs[11] = (unsigned long)k->sa.sa_handler; regs[14] = (unsigned long)usp; + ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate); } else{ + ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate); if(sig == SIGCHLD || sig == SIGURG) return; terminate(0, sig, (ihk_mc_user_context_t *)regs[14]); @@ -127,20 +135,38 @@ check_signal(unsigned long rc, unsigned long *regs) } } -void -sigsegv(unsigned long *regs) +extern unsigned long do_kill(int pid, int sig); + +unsigned long +do_kill(int pid, int sig) { struct process *proc = cpu_local_var(current); - proc->signal = SIGSEGV; - check_signal(0, regs); + if(proc == NULL || proc->pid == 0){ + return -ESRCH; + } + if(proc->pid == pid){ + proc->signal = sig; + return 0; + } + + if(pid <= 0){ + return -EINVAL; + } + if(sig == 0){ + return 0; + } + else{ + return -EPERM; + } } void -sigill(unsigned long *regs) +set_signal(int sig, unsigned long *regs) { struct process *proc = cpu_local_var(current); - proc->signal = SIGILL; - check_signal(0, regs); + if(proc == NULL || proc->pid == 0) + return; + proc->signal = sig; } diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index e96a96e6..d7b82147 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -7,6 +7,7 @@ #define MCEXEC_UP_WAIT_SYSCALL 0x30a02903 #define MCEXEC_UP_RET_SYSCALL 0x30a02904 #define MCEXEC_UP_LOAD_SYSCALL 0x30a02905 +#define MCEXEC_UP_SEND_SIGNAL 0x30a02906 #define MCEXEC_UP_PREPARE_DMA 0x30a02910 #define MCEXEC_UP_FREE_DMA 0x30a02911 diff --git a/executer/kernel/control.c b/executer/kernel/control.c index 02110fcf..22c9230f 100644 --- a/executer/kernel/control.c +++ b/executer/kernel/control.c @@ -209,6 +209,22 @@ static long mcexec_start_image(ihk_os_t os, return 0; } +static long mcexec_send_signal(ihk_os_t os, unsigned long sigparam) +{ + struct ikc_scd_packet isp; + struct mcctrl_channel *c; + struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os); + + c = usrdata->channels; + isp.msg = SCD_MSG_SEND_SIGNAL; + isp.ref = 0; + isp.arg = sigparam; + + mcctrl_ikc_send(os, 0, &isp); + + return 0; +} + int mcexec_syscall(struct mcctrl_channel *c, unsigned long arg) { c->req = 1; @@ -536,6 +552,9 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg) case MCEXEC_UP_LOAD_SYSCALL: return mcexec_load_syscall(os, (struct syscall_load_desc *)arg); + case MCEXEC_UP_SEND_SIGNAL: + return mcexec_send_signal(os, arg); + case MCEXEC_UP_PREPARE_DMA: return mcexec_pin_region(os, (unsigned long *)arg); diff --git a/executer/kernel/driver.c b/executer/kernel/driver.c index 1551ffd5..2aac296e 100644 --- a/executer/kernel/driver.c +++ b/executer/kernel/driver.c @@ -31,6 +31,7 @@ static struct ihk_os_user_call_handler mcctrl_uchs[] = { { .request = MCEXEC_UP_WAIT_SYSCALL, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_RET_SYSCALL, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_LOAD_SYSCALL, .func = mcctrl_ioctl }, + { .request = MCEXEC_UP_SEND_SIGNAL, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_PREPARE_DMA, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_FREE_DMA, .func = mcctrl_ioctl }, }; diff --git a/executer/kernel/mcctrl.h b/executer/kernel/mcctrl.h index 5d20c24d..f5e90835 100644 --- a/executer/kernel/mcctrl.h +++ b/executer/kernel/mcctrl.h @@ -16,6 +16,7 @@ #define SCD_MSG_INIT_CHANNEL_ACKED 0x6 #define SCD_MSG_SYSCALL_ONESIDE 0x4 +#define SCD_MSG_SEND_SIGNAL 0x8 #define DMA_PIN_SHIFT 21 diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index 4ed7edf5..3a19e56f 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -80,6 +80,8 @@ struct kernel_termios { int main_loop(int fd, int cpu, pthread_mutex_t *lock); +static int fd; + struct program_load_desc *load_elf(FILE *fp) { Elf64_Ehdr hdr; @@ -332,9 +334,22 @@ static void *main_loop_thread_func(void *arg) return NULL; } +void +sendsig(int sig) +{ + unsigned long param; + + param = ((unsigned long)sig) << 32 | ((unsigned long)getpid()); + if (ioctl(fd, MCEXEC_UP_SEND_SIGNAL, param) != 0) { + perror("send_signal"); + close(fd); + exit(1); + } +} + int main(int argc, char **argv) { - int fd; +// int fd; #if 0 int fdm; long r; @@ -489,6 +504,11 @@ 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 < NUM_HANDLER_THREADS; ++i) { pthread_join(thread_data[i].thread_id, NULL); } diff --git a/kernel/host.c b/kernel/host.c index 08ea5809..5e3651c9 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -368,6 +368,8 @@ static void syscall_channel_send(struct ihk_ikc_channel_desc *c, ihk_ikc_send(c, packet, 0); } +extern unsigned long do_kill(int, int); + static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, void *__packet, void *ihk_os) { @@ -404,6 +406,10 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, //cpu_local_var(next) = (struct process *)packet->arg; return 0; + case SCD_MSG_SEND_SIGNAL: + rc = do_kill((int)packet->arg, (int)(packet->arg >> 32)); + kprintf("SCD_MSG_SEND_SIGNAL: %lx, rc=%d\n", packet->arg, rc); + return 0; } return 0; } diff --git a/kernel/include/process.h b/kernel/include/process.h index 5e137c5a..2a031c60 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -55,8 +55,8 @@ struct vm_regions { struct process_vm; struct sig_handler { - // TODO: lock; - int use; + ihk_spinlock_t lock; + ihk_atomic_t use; struct k_sigaction action[_NSIG]; }; @@ -83,9 +83,12 @@ struct process { } thread; int signal; + sigset_t sigpend; + sigset_t sigmask; struct sig_handler *sighandler; ihk_mc_kernel_context_t sigctx; char sigstack[512]; + // TODO: backup FR and MMX regs unsigned long sigrc; // return code of rt_sigreturn (x86_64: rax reg.) }; diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index 893889e2..f38ec465 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -21,6 +21,7 @@ #define SCD_MSG_INIT_CHANNEL_ACKED 0x6 #define SCD_MSG_SYSCALL_ONESIDE 0x4 +#define SCD_MSG_SEND_SIGNAL 0x8 #define ARCH_SET_GS 0x1001 #define ARCH_SET_FS 0x1002 diff --git a/kernel/mem.c b/kernel/mem.c index bd34d499..00bb7194 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -141,7 +141,8 @@ static struct ihk_mc_interrupt_handler query_free_mem_handler = { .priv = NULL, }; -void sigsegv(void *); +void set_signal(int, unsigned long *); +void check_signal(long, unsigned long *); static void unhandled_page_fault(struct process *proc, void *fault_addr, void *regs) { @@ -194,7 +195,8 @@ static void unhandled_page_fault(struct process *proc, void *fault_addr, void *r #if 0 panic("mem fault"); #endif - sigsegv(regs); + set_signal(SIGSEGV, regs); + check_signal(0, regs); return; } diff --git a/kernel/process.c b/kernel/process.c index 423381d9..6028abfa 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -62,7 +62,8 @@ struct process *create_process(unsigned long user_pc) return NULL; } memset(proc->sighandler, '\0', sizeof(struct sig_handler)); - proc->sighandler->use = 1; + ihk_atomic_set(&proc->sighandler->use, 1); + ihk_mc_spinlock_init(&proc->sighandler->lock); ihk_mc_init_user_process(&proc->ctx, &proc->uctx, ((char *)proc) + @@ -106,9 +107,8 @@ struct process *clone_process(struct process *org, unsigned long pc, ihk_atomic_inc(&org->vm->refcount); proc->vm = org->vm; - // TODO: lock proc->sighandler = org->sighandler; - org->sighandler->use++; + ihk_atomic_inc(&org->sighandler->use); ihk_mc_spinlock_init(&proc->spin_sleep_lock); proc->spin_sleep = 0; @@ -1054,6 +1054,9 @@ void hold_process(struct process *proc) void destroy_process(struct process *proc) { + if(ihk_atomic_dec_and_test(&proc->sighandler->use)){ + kfree(proc->sighandler); + } ihk_mc_free_pages(proc, KERNEL_STACK_NR_PAGES); } diff --git a/kernel/syscall.c b/kernel/syscall.c index c9c9bbd0..de757c78 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -66,7 +66,7 @@ static char *syscall_name[] MCKERNEL_UNUSED = { #undef SYSCALL_DELEGATED }; -void check_signal(unsigned long rc, unsigned long *regs); +void check_signal(long rc, unsigned long *regs); #ifdef DCFA_KMOD static void do_mod_exit(int status); @@ -830,26 +830,14 @@ SYSCALL_DECLARE(set_tid_address) return cpu_local_var(current)->pid; } +extern unsigned long do_kill(int pid, int sig); + SYSCALL_DECLARE(kill) { int pid = ihk_mc_syscall_arg0(ctx); int sig = ihk_mc_syscall_arg1(ctx); - struct process *proc = cpu_local_var(current); - - if(proc->pid == pid){ - proc->signal = sig; - return 0; - } - - if(pid <= 0) { return -EINVAL; } - // search pid - // check kill permission - if(sig == 0) { - return 0; - } else { - return -EPERM; - } + return do_kill(pid, sig); } // see linux-2.6.34.13/kernel/signal.c @@ -879,14 +867,16 @@ do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) { struct process *proc = cpu_local_var(current); struct k_sigaction *k; - // TODO: sigmask + int irqstate; + irqstate = ihk_mc_spinlock_lock(&proc->sighandler->lock); k = proc->sighandler->action + sig - 1; if(oact) memcpy(oact, k, sizeof(struct k_sigaction)); if(act){ memcpy(k, act, sizeof(struct k_sigaction)); } + ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate); return 0; } @@ -913,9 +903,38 @@ SYSCALL_DECLARE(rt_sigaction) SYSCALL_DECLARE(rt_sigprocmask) { - // kprintf("sys_rt_sigprocmask called. returning zero...\n"); - return 0; + int how = ihk_mc_syscall_arg0(ctx); + const sigset_t *set = (const sigset_t *)ihk_mc_syscall_arg1(ctx); + sigset_t *oldset = (sigset_t *)ihk_mc_syscall_arg2(ctx); + // kprintf("sys_rt_sigprocmask called. returning zero...\n"); + return 0; } + +SYSCALL_DECLARE(rt_sigpending) +{ + return 0; +} + +SYSCALL_DECLARE(rt_sigtimedwait) +{ + return 0; +} + +SYSCALL_DECLARE(rt_sigqueueinfo) +{ + return 0; +} + +SYSCALL_DECLARE(rt_sigsuspend) +{ + return 0; +} + +SYSCALL_DECLARE(sigaltstack) +{ + return 0; +} + SYSCALL_DECLARE(madvise) { // kprintf("sys_madvise called. returning zero...\n");