CPU read/write reg: use generic IHK messaging interface

Change-Id: Ia9637d1516d9329fdadf37822bfce7594d69105f
This commit is contained in:
Balazs Gerofi
2020-03-09 16:42:16 +09:00
committed by Masamichi Takagi
parent bb725f5f50
commit eac414d6d8
6 changed files with 40 additions and 64 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
};

View File

@ -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;

View File

@ -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;
};