From eac414d6d801acc31d43564904c31ac8e43044f5 Mon Sep 17 00:00:00 2001 From: Balazs Gerofi Date: Mon, 9 Mar 2020 16:42:16 +0900 Subject: [PATCH] CPU read/write reg: use generic IHK messaging interface Change-Id: Ia9637d1516d9329fdadf37822bfce7594d69105f --- arch/arm64/kernel/cpu.c | 5 +++ executer/kernel/mcctrl/control.c | 76 +++++++++----------------------- executer/kernel/mcctrl/ikc.c | 5 +-- executer/kernel/mcctrl/mcctrl.h | 2 +- kernel/host.c | 14 ++++-- kernel/include/syscall.h | 2 +- 6 files changed, 40 insertions(+), 64 deletions(-) diff --git a/arch/arm64/kernel/cpu.c b/arch/arm64/kernel/cpu.c index 024a80d3..5ba95027 100644 --- a/arch/arm64/kernel/cpu.c +++ b/arch/arm64/kernel/cpu.c @@ -1880,6 +1880,11 @@ int arch_cpu_read_write_register( ret = -1; } + dkprintf("%s: MCCTRL_OS_CPU_%s_REGISTER: reg: 0x%lx, val: 0x%lx\n", + __FUNCTION__, + (op == MCCTRL_OS_CPU_READ_REGISTER ? "READ" : "WRITE"), + desc->addr, desc->val); + return ret; } diff --git a/executer/kernel/mcctrl/control.c b/executer/kernel/mcctrl/control.c index 8e3daceb..d027f8dc 100644 --- a/executer/kernel/mcctrl/control.c +++ b/executer/kernel/mcctrl/control.c @@ -3399,14 +3399,6 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg, return -EINVAL; } -/* Per-CPU register manipulation functions */ -struct mcctrl_os_cpu_response { - int done; - unsigned long val; - int err; - wait_queue_head_t wq; -}; - int mcctrl_get_request_os_cpu(ihk_os_t os, int *ret_cpu) { struct mcctrl_usrdata *usrdata; @@ -3470,31 +3462,14 @@ out_put_ppd: return ret; } -void mcctrl_os_read_write_cpu_response(ihk_os_t os, - struct ikc_scd_packet *pisp) -{ - struct mcctrl_os_cpu_response *resp; - - /* XXX: What if caller thread is unblocked by a signal - * before this message arrives? */ - resp = pisp->resp; - if (!resp) { - return; - } - - resp->val = pisp->desc.val; - resp->done = 1; - resp->err = pisp->err; - wake_up_interruptible(&resp->wq); -} - int __mcctrl_os_read_write_cpu_register(ihk_os_t os, int cpu, struct ihk_os_cpu_register *desc, enum mcctrl_os_cpu_operation op) { struct mcctrl_usrdata *udp = ihk_host_os_get_usrdata(os); struct ikc_scd_packet isp; - struct mcctrl_os_cpu_response resp; + struct ihk_os_cpu_register *ldesc = NULL; + int do_free = 0; int ret = -EINVAL; if (!udp) { @@ -3511,50 +3486,43 @@ int __mcctrl_os_read_write_cpu_register(ihk_os_t os, int cpu, } + /* Keep a dynamic structure around that can + * survive an early return due to a signal */ + ldesc = kmalloc(sizeof(*ldesc), GFP_KERNEL); + if (!ldesc) { + printk("%s: ERROR: allocating cpu register desc\n", __FUNCTION__); + return -ENOMEM; + } + *ldesc = *desc; + memset(&isp, '\0', sizeof(struct ikc_scd_packet)); isp.msg = SCD_MSG_CPU_RW_REG; isp.op = op; - isp.desc = *desc; - isp.resp = &resp; + isp.pdesc = virt_to_phys(ldesc); - resp.done = 0; - resp.err = 0; - init_waitqueue_head(&resp.wq); - - mb(); - ret = mcctrl_ikc_send(os, cpu, &isp); - if (ret < 0) { + ret = mcctrl_ikc_send_wait(os, cpu, &isp, 0, NULL, &do_free, 1, ldesc); + if (ret != 0) { printk("%s: ERROR sending IKC msg: %d\n", __FUNCTION__, ret); goto out; } - /* Wait for response */ - ret = wait_event_interruptible(resp.wq, resp.done); - if (ret < 0) { - printk("%s: ERROR after wait: %d\n", __FUNCTION__, ret); - goto out; - } - - ret = resp.err; - if (ret != 0) { - printk("%s: ERROR receive: %d\n", __FUNCTION__, resp.err); - goto out; - } - /* Update if read */ - if (ret == 0 && op == MCCTRL_OS_CPU_READ_REGISTER) { - desc->val = resp.val; + if (op == MCCTRL_OS_CPU_READ_REGISTER) { + desc->val = ldesc->val; } /* Notify caller (for future async implementation) */ atomic_set(&desc->sync, 1); - dprintk("%s: MCCTRL_OS_CPU_%s_REGISTER: reg: 0x%lx, val: 0x%lx\n", + dprintk("%s: MCCTRL_OS_CPU_%s_REGISTER: CPU: %d, addr_ext: 0x%lx, val: 0x%lx\n", __FUNCTION__, - (op == MCCTRL_OS_CPU_READ_REGISTER ? "READ" : "WRITE"), - desc->addr, desc->val); + (op == MCCTRL_OS_CPU_READ_REGISTER ? "READ" : "WRITE"), cpu, + desc->addr_ext, desc->val); out: + if (do_free) { + kfree(ldesc); + } return ret; } diff --git a/executer/kernel/mcctrl/ikc.c b/executer/kernel/mcctrl/ikc.c index 26ced484..2e280760 100644 --- a/executer/kernel/mcctrl/ikc.c +++ b/executer/kernel/mcctrl/ikc.c @@ -209,6 +209,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, case SCD_MSG_SEND_SIGNAL_ACK: case SCD_MSG_PROCFS_ANSWER: case SCD_MSG_REMOTE_PAGE_FAULT_ANSWER: + case SCD_MSG_CPU_RW_REG_RESP: mcctrl_wakeup_cb(__os, pisp); break; @@ -239,10 +240,6 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, get_vdso_info(__os, pisp->arg); break; - case SCD_MSG_CPU_RW_REG_RESP: - mcctrl_os_read_write_cpu_response(__os, pisp); - break; - case SCD_MSG_EVENTFD: dkprintf("%s: SCD_MSG_EVENTFD,pisp->eventfd_type=%d\n", __FUNCTION__, pisp->eventfd_type); mcctrl_eventfd(__os, pisp); diff --git a/executer/kernel/mcctrl/mcctrl.h b/executer/kernel/mcctrl/mcctrl.h index 8c95e0b3..549b89e7 100644 --- a/executer/kernel/mcctrl/mcctrl.h +++ b/executer/kernel/mcctrl/mcctrl.h @@ -154,7 +154,7 @@ struct ikc_scd_packet { /* SCD_MSG_CPU_RW_REG */ struct { - struct ihk_os_cpu_register desc; + unsigned long pdesc; /* Physical addr of the descriptor */ enum mcctrl_os_cpu_operation op; void *resp; }; diff --git a/kernel/host.c b/kernel/host.c index 9c03b2e6..76bd9b46 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -619,6 +619,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, { struct ikc_scd_packet *packet = __packet; struct ikc_scd_packet pckt; + struct ihk_os_cpu_register *cpu_desc; struct ihk_ikc_channel_desc *resp_channel = cpu_local_var(ikc2linux); int rc; struct thread *thread; @@ -839,12 +840,17 @@ out_remote_pf: break; case SCD_MSG_CPU_RW_REG: + pp = ihk_mc_map_memory(NULL, packet->pdesc, + sizeof(struct ihk_os_cpu_register)); + cpu_desc = (struct ihk_os_cpu_register *)ihk_mc_map_virtual( + pp, 1, PTATTR_WRITABLE | PTATTR_ACTIVE); pckt.msg = SCD_MSG_CPU_RW_REG_RESP; - memcpy(&pckt.desc, &packet->desc, - sizeof(struct ihk_os_cpu_register)); - pckt.resp = packet->resp; - pckt.err = arch_cpu_read_write_register(&pckt.desc, packet->op); + pckt.reply = packet->reply; + pckt.err = arch_cpu_read_write_register(cpu_desc, packet->op); + + ihk_mc_unmap_virtual(cpu_desc, 1); + ihk_mc_unmap_memory(NULL, pp, sizeof(struct ihk_os_cpu_register)); ihk_ikc_send(resp_channel, &pckt, 0); break; diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index 7a79ea3e..b23874ad 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -287,7 +287,7 @@ struct ikc_scd_packet { /* SCD_MSG_CPU_RW_REG */ struct { - struct ihk_os_cpu_register desc; + unsigned long pdesc; /* Physical addr of the descriptor */ enum mcctrl_os_cpu_operation op; void *resp; };