support sigqueue

This commit is contained in:
Tomoki Shirasawa
2014-09-23 23:17:53 +09:00
parent 55aeceb1bf
commit 39f36120c1
12 changed files with 188 additions and 38 deletions

View File

@@ -496,7 +496,7 @@ static void syscall_channel_send(struct ihk_ikc_channel_desc *c,
ihk_ikc_send(c, packet, 0);
}
extern unsigned long do_kill(int, int, int);
extern unsigned long do_kill(int, int, int, struct siginfo *);
extern void settid(struct process *proc, int mode, int newcpuid, int oldcpuid);
extern void process_procfs_request(unsigned long rarg);
@@ -508,6 +508,14 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
struct ikc_scd_packet pckt;
int rc;
struct process *proc;
struct mcctrl_signal {
int cond;
int sig;
int pid;
int tid;
struct siginfo info;
} *sp, info;
unsigned long pp;
switch (packet->msg) {
case SCD_MSG_INIT_CHANNEL_ACKED:
@@ -540,8 +548,19 @@ 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->pid, (int)(packet->arg >> 32), packet->arg & 0x00000000ffffffffL);
kprintf("SCD_MSG_SEND_SIGNAL: %lx, rc=%d\n", packet->arg, rc);
pp = ihk_mc_map_memory(NULL, packet->arg, sizeof(struct mcctrl_signal));
sp = (struct mcctrl_signal *)ihk_mc_map_virtual(pp, 1, PTATTR_WRITABLE | PTATTR_ACTIVE);
memcpy(&info, sp, sizeof(struct mcctrl_signal));
ihk_mc_unmap_virtual(sp, 1, 0);
ihk_mc_unmap_memory(NULL, pp, sizeof(struct mcctrl_signal));
pckt.msg = SCD_MSG_SEND_SIGNAL;
pckt.err = 0;
pckt.ref = packet->ref;
pckt.arg = packet->arg;
syscall_channel_send(c, &pckt);
rc = do_kill(info.pid, info.tid, info.sig, &info.info);
kprintf("SCD_MSG_SEND_SIGNAL: do_kill(pid=%d, tid=%d, sig=%d)=%d\n", info.pid, info.tid, info.sig, rc);
return 0;
case SCD_MSG_PROCFS_REQUEST:
process_procfs_request(packet->arg);

View File

@@ -168,7 +168,7 @@ static struct ihk_mc_interrupt_handler query_free_mem_handler = {
.priv = NULL,
};
void set_signal(int sig, void *regs);
void set_signal(int sig, void *regs, struct siginfo *info);
void check_signal(unsigned long rc, void *regs);
int gencore(struct process *, void *, struct coretable **, int *);
void freecore(struct coretable **);
@@ -371,16 +371,19 @@ static void page_fault_handler(void *fault_addr, uint64_t reason, void *regs)
error = page_fault_process(proc, fault_addr, reason);
if (error) {
struct siginfo info;
kprintf("[%d]page_fault_handler(%p,%lx,%p):"
"fault proc failed. %d\n",
ihk_mc_get_processor_id(), fault_addr,
reason, regs, error);
unhandled_page_fault(proc, fault_addr, regs);
memset(&info, '\0', sizeof info);
if (error == -ERANGE) {
set_signal(SIGBUS, regs);
set_signal(SIGBUS, regs, &info);
}
else {
set_signal(SIGSEGV, regs);
set_signal(SIGSEGV, regs, &info);
}
check_signal(0, regs);
goto out;

View File

@@ -95,7 +95,7 @@ static char *syscall_name[] MCKERNEL_UNUSED = {
void check_signal(unsigned long rc, void *regs);
void do_signal(long rc, void *regs, struct process *proc, struct sig_pending *pending);
extern unsigned long do_kill(int pid, int tid, int sig);
extern unsigned long do_kill(int pid, int tid, int sig, struct siginfo *info);
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);
@@ -460,7 +460,13 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx)
/* Signal parent if still attached */
ihk_mc_spinlock_lock_noirq(&ftn->parent->lock);
if (ftn->parent->owner) {
do_kill(ftn->parent->owner->pid, -1, SIGCHLD);
struct siginfo info;
memset(&info, '\0', sizeof info);
info.si_signo = SIGCHLD;
info.si_code = sig? ((sig & 0x80)? 3: 2): 1;
info._sifields._sigchld.si_pid = proc->pid;
info._sifields._sigchld.si_status = ((rc & 0x00ff) << 8) | (sig & 0xff);
do_kill(ftn->parent->owner->pid, -1, SIGCHLD, &info);
/*
sigchld_parent(ftn->parent->owner, 0);
*/
@@ -1513,8 +1519,15 @@ SYSCALL_DECLARE(kill)
{
int pid = ihk_mc_syscall_arg0(ctx);
int sig = ihk_mc_syscall_arg1(ctx);
struct process *proc = cpu_local_var(current);
struct siginfo info;
return do_kill(pid, -1, sig);
memset(&info, '\0', sizeof info);
info.si_signo = sig;
info.si_code = SI_USER;
info._sifields._kill.si_pid = proc->pid;
return do_kill(pid, -1, sig, &info);
}
// see linux-2.6.34.13/kernel/signal.c
@@ -1523,13 +1536,20 @@ SYSCALL_DECLARE(tgkill)
int tgid = ihk_mc_syscall_arg0(ctx);
int tid = ihk_mc_syscall_arg1(ctx);
int sig = ihk_mc_syscall_arg2(ctx);
struct process *proc = cpu_local_var(current);
struct siginfo info;
memset(&info, '\0', sizeof info);
info.si_signo = sig;
info.si_code = SI_TKILL;
info._sifields._kill.si_pid = proc->pid;
if(tid <= 0)
return -EINVAL;
if(tgid <= 0 && tgid != -1)
return -EINVAL;
return do_kill(tgid, tid, sig);
return do_kill(tgid, tid, sig, &info);
}
SYSCALL_DECLARE(setpgid)
@@ -1650,6 +1670,16 @@ SYSCALL_DECLARE(rt_sigpending)
return 0;
}
SYSCALL_DECLARE(signalfd)
{
return -EOPNOTSUPP;
}
SYSCALL_DECLARE(signalfd4)
{
return -EOPNOTSUPP;
}
SYSCALL_DECLARE(rt_sigtimedwait)
{
struct process *proc = cpu_local_var(current);
@@ -1664,29 +1694,38 @@ SYSCALL_DECLARE(rt_sigtimedwait)
if (sigsetsize > sizeof(sigset_t))
return -EINVAL;
if(set == NULL)
return -EFAULT;
memset(&winfo, '\0', sizeof winfo);
if(copy_from_user(proc, &wset, set, sizeof wset))
return -EFAULT;
if(copy_from_user(proc, wtimeout, timeout, sizeof wtimeout))
return -EFAULT;
if(copy_to_user(proc, info, &winfo, sizeof winfo))
return -EFAULT;
if(timeout)
if(copy_from_user(proc, wtimeout, timeout, sizeof wtimeout))
return -EFAULT;
if(info)
if(copy_to_user(proc, info, &winfo, sizeof winfo))
return -EFAULT;
return -EOPNOTSUPP;
}
SYSCALL_DECLARE(rt_sigqueueinfo)
{
struct process *proc = cpu_local_var(current);
int pid = (int)ihk_mc_syscall_arg0(ctx);
int sig = (int)ihk_mc_syscall_arg1(ctx);
siginfo_t *info = (siginfo_t *)ihk_mc_syscall_arg2(ctx);
siginfo_t winfo;
void *winfo = (void *)ihk_mc_syscall_arg2(ctx);
struct process *proc = cpu_local_var(current);
struct siginfo info;
if(copy_from_user(proc, &winfo, info, sizeof winfo))
if(pid <= 0)
return -ESRCH;
if(copy_from_user(proc, &info, winfo, sizeof info))
return -EFAULT;
return -EOPNOTSUPP;
return do_kill(pid, -1, sig, &info);
}
static int