diff --git a/executer/kernel/mcctrl/control.c b/executer/kernel/mcctrl/control.c index 3700c3d0..f3022733 100644 --- a/executer/kernel/mcctrl/control.c +++ b/executer/kernel/mcctrl/control.c @@ -476,25 +476,33 @@ out: static DECLARE_WAIT_QUEUE_HEAD(signalq); +struct mcctrl_signal_desc { + struct mcctrl_signal msig; + struct mcctrl_wakeup_desc wakeup; + void *addrs[1]; +}; + static long mcexec_send_signal(ihk_os_t os, struct signal_desc *sigparam) { struct ikc_scd_packet isp; struct mcctrl_channel *c; struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os); struct signal_desc sig; - struct mcctrl_signal msig[2]; + struct mcctrl_signal_desc *desc; struct mcctrl_signal *msigp; - int rc; + int rc, do_free; if (copy_from_user(&sig, sigparam, sizeof(struct signal_desc))) { return -EFAULT; } - msigp = msig; - if(((unsigned long)msig & 0xfffffffffffff000L) != - ((unsigned long)(msig + 1) & 0xfffffffffffff000L)) - msigp++; - memset(msigp, '\0', sizeof msig); + desc = kmalloc(sizeof(*desc), GFP_KERNEL); + if (!desc) { + return -ENOMEM; + } + + msigp = &desc->msig; + memset(msigp, '\0', sizeof(*msigp)); msigp->sig = sig.sig; msigp->pid = sig.pid; msigp->tid = sig.tid; @@ -506,25 +514,19 @@ static long mcexec_send_signal(ihk_os_t os, struct signal_desc *sigparam) isp.pid = sig.pid; isp.arg = virt_to_phys(msigp); - if ((rc = mcctrl_ikc_send(os, sig.cpu, &isp)) < 0) { + rc = mcctrl_ikc_send_wait(os, sig.cpu, &isp, 0, &desc->wakeup, + &do_free, 1, desc); + if (rc < 0) { printk("mcexec_send_signal: mcctrl_ikc_send ret=%d\n", rc); + if (do_free) + kfree(desc); return rc; } - wait_event_interruptible(signalq, msigp->cond != 0); + kfree(desc); return 0; } -void -sig_done(unsigned long arg, int err) -{ - struct mcctrl_signal *msigp; - - msigp = phys_to_virt(arg); - msigp->cond = 1; - wake_up_interruptible(&signalq); -} - static long mcexec_get_cpu(ihk_os_t os) { struct ihk_cpu_info *info; diff --git a/executer/kernel/mcctrl/ikc.c b/executer/kernel/mcctrl/ikc.c index acf88860..1faf7f5d 100644 --- a/executer/kernel/mcctrl/ikc.c +++ b/executer/kernel/mcctrl/ikc.c @@ -106,7 +106,8 @@ int mcctrl_ikc_send_wait(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp, int alloc_desc = (desc == NULL); va_list ap; - *do_frees = 1; + if (free_addrs_count) + *do_frees = 1; if (alloc_desc) desc = kmalloc(sizeof(struct mcctrl_wakeup_desc) + (free_addrs_count + 1) * sizeof(void *), @@ -153,7 +154,8 @@ int mcctrl_ikc_send_wait(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp, spin_lock_irqsave(&usrdata->wakeup_descs_lock, flags); list_add(&desc->chain, &usrdata->wakeup_descs_list); spin_unlock_irqrestore(&usrdata->wakeup_descs_lock, flags); - *do_frees = 0; + if (free_addrs_count) + *do_frees = 0; return ret < 0 ? ret : -ETIME; } @@ -179,6 +181,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, case SCD_MSG_PREPARE_PROCESS_ACKED: case SCD_MSG_PERF_ACK: + case SCD_MSG_SEND_SIGNAL_ACK: mcctrl_wakeup_cb(__os, pisp); break; @@ -190,9 +193,6 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, procfs_answer(usrdata, pisp->pid); break; - case SCD_MSG_SEND_SIGNAL: - sig_done(pisp->arg, pisp->err); - break; case SCD_MSG_SYSFS_REQ_CREATE: case SCD_MSG_SYSFS_REQ_MKDIR: diff --git a/executer/kernel/mcctrl/mcctrl.h b/executer/kernel/mcctrl/mcctrl.h index d1c37e26..1761861b 100644 --- a/executer/kernel/mcctrl/mcctrl.h +++ b/executer/kernel/mcctrl/mcctrl.h @@ -55,7 +55,8 @@ #define SCD_MSG_INIT_CHANNEL_ACKED 0x6 #define SCD_MSG_SYSCALL_ONESIDE 0x4 -#define SCD_MSG_SEND_SIGNAL 0x8 +#define SCD_MSG_SEND_SIGNAL 0x7 +#define SCD_MSG_SEND_SIGNAL_ACK 0x8 #define SCD_MSG_CLEANUP_PROCESS 0x9 #define SCD_MSG_GET_VDSO_INFO 0xa diff --git a/kernel/host.c b/kernel/host.c index d34a0346..5d62544e 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -655,10 +655,11 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, 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.msg = SCD_MSG_SEND_SIGNAL_ACK; pckt.err = 0; pckt.ref = packet->ref; pckt.arg = packet->arg; + pckt.reply = packet->reply; syscall_channel_send(resp_channel, &pckt); rc = do_kill(NULL, info.pid, info.tid, info.sig, &info.info, 0); diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index e18b13d5..35807168 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -37,8 +37,9 @@ #define SCD_MSG_INIT_CHANNEL_ACKED 0x6 #define SCD_MSG_SYSCALL_ONESIDE 0x4 -#define SCD_MSG_SEND_SIGNAL 0x8 -#define SCD_MSG_CLEANUP_PROCESS 0x9 +#define SCD_MSG_SEND_SIGNAL 0x7 +#define SCD_MSG_SEND_SIGNAL_ACK 0x8 +#define SCD_MSG_CLEANUP_PROCESS 0x9 #define SCD_MSG_GET_VDSO_INFO 0xa #define SCD_MSG_GET_CPU_MAPPING 0xc