CPU read/write reg: use generic IHK messaging interface
Change-Id: Ia9637d1516d9329fdadf37822bfce7594d69105f
This commit is contained in:
committed by
Masamichi Takagi
parent
bb725f5f50
commit
eac414d6d8
@@ -1880,6 +1880,11 @@ int arch_cpu_read_write_register(
|
|||||||
ret = -1;
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3399,14 +3399,6 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg,
|
|||||||
return -EINVAL;
|
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)
|
int mcctrl_get_request_os_cpu(ihk_os_t os, int *ret_cpu)
|
||||||
{
|
{
|
||||||
struct mcctrl_usrdata *usrdata;
|
struct mcctrl_usrdata *usrdata;
|
||||||
@@ -3470,31 +3462,14 @@ out_put_ppd:
|
|||||||
return ret;
|
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,
|
int __mcctrl_os_read_write_cpu_register(ihk_os_t os, int cpu,
|
||||||
struct ihk_os_cpu_register *desc,
|
struct ihk_os_cpu_register *desc,
|
||||||
enum mcctrl_os_cpu_operation op)
|
enum mcctrl_os_cpu_operation op)
|
||||||
{
|
{
|
||||||
struct mcctrl_usrdata *udp = ihk_host_os_get_usrdata(os);
|
struct mcctrl_usrdata *udp = ihk_host_os_get_usrdata(os);
|
||||||
struct ikc_scd_packet isp;
|
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;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
if (!udp) {
|
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));
|
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||||
isp.msg = SCD_MSG_CPU_RW_REG;
|
isp.msg = SCD_MSG_CPU_RW_REG;
|
||||||
isp.op = op;
|
isp.op = op;
|
||||||
isp.desc = *desc;
|
isp.pdesc = virt_to_phys(ldesc);
|
||||||
isp.resp = &resp;
|
|
||||||
|
|
||||||
resp.done = 0;
|
ret = mcctrl_ikc_send_wait(os, cpu, &isp, 0, NULL, &do_free, 1, ldesc);
|
||||||
resp.err = 0;
|
if (ret != 0) {
|
||||||
init_waitqueue_head(&resp.wq);
|
|
||||||
|
|
||||||
mb();
|
|
||||||
ret = mcctrl_ikc_send(os, cpu, &isp);
|
|
||||||
if (ret < 0) {
|
|
||||||
printk("%s: ERROR sending IKC msg: %d\n", __FUNCTION__, ret);
|
printk("%s: ERROR sending IKC msg: %d\n", __FUNCTION__, ret);
|
||||||
goto out;
|
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 */
|
/* Update if read */
|
||||||
if (ret == 0 && op == MCCTRL_OS_CPU_READ_REGISTER) {
|
if (op == MCCTRL_OS_CPU_READ_REGISTER) {
|
||||||
desc->val = resp.val;
|
desc->val = ldesc->val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Notify caller (for future async implementation) */
|
/* Notify caller (for future async implementation) */
|
||||||
atomic_set(&desc->sync, 1);
|
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__,
|
__FUNCTION__,
|
||||||
(op == MCCTRL_OS_CPU_READ_REGISTER ? "READ" : "WRITE"),
|
(op == MCCTRL_OS_CPU_READ_REGISTER ? "READ" : "WRITE"), cpu,
|
||||||
desc->addr, desc->val);
|
desc->addr_ext, desc->val);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
if (do_free) {
|
||||||
|
kfree(ldesc);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -209,6 +209,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
|||||||
case SCD_MSG_SEND_SIGNAL_ACK:
|
case SCD_MSG_SEND_SIGNAL_ACK:
|
||||||
case SCD_MSG_PROCFS_ANSWER:
|
case SCD_MSG_PROCFS_ANSWER:
|
||||||
case SCD_MSG_REMOTE_PAGE_FAULT_ANSWER:
|
case SCD_MSG_REMOTE_PAGE_FAULT_ANSWER:
|
||||||
|
case SCD_MSG_CPU_RW_REG_RESP:
|
||||||
mcctrl_wakeup_cb(__os, pisp);
|
mcctrl_wakeup_cb(__os, pisp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -239,10 +240,6 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
|||||||
get_vdso_info(__os, pisp->arg);
|
get_vdso_info(__os, pisp->arg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCD_MSG_CPU_RW_REG_RESP:
|
|
||||||
mcctrl_os_read_write_cpu_response(__os, pisp);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCD_MSG_EVENTFD:
|
case SCD_MSG_EVENTFD:
|
||||||
dkprintf("%s: SCD_MSG_EVENTFD,pisp->eventfd_type=%d\n", __FUNCTION__, pisp->eventfd_type);
|
dkprintf("%s: SCD_MSG_EVENTFD,pisp->eventfd_type=%d\n", __FUNCTION__, pisp->eventfd_type);
|
||||||
mcctrl_eventfd(__os, pisp);
|
mcctrl_eventfd(__os, pisp);
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ struct ikc_scd_packet {
|
|||||||
|
|
||||||
/* SCD_MSG_CPU_RW_REG */
|
/* SCD_MSG_CPU_RW_REG */
|
||||||
struct {
|
struct {
|
||||||
struct ihk_os_cpu_register desc;
|
unsigned long pdesc; /* Physical addr of the descriptor */
|
||||||
enum mcctrl_os_cpu_operation op;
|
enum mcctrl_os_cpu_operation op;
|
||||||
void *resp;
|
void *resp;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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 *packet = __packet;
|
||||||
struct ikc_scd_packet pckt;
|
struct ikc_scd_packet pckt;
|
||||||
|
struct ihk_os_cpu_register *cpu_desc;
|
||||||
struct ihk_ikc_channel_desc *resp_channel = cpu_local_var(ikc2linux);
|
struct ihk_ikc_channel_desc *resp_channel = cpu_local_var(ikc2linux);
|
||||||
int rc;
|
int rc;
|
||||||
struct thread *thread;
|
struct thread *thread;
|
||||||
@@ -839,12 +840,17 @@ out_remote_pf:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SCD_MSG_CPU_RW_REG:
|
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;
|
pckt.msg = SCD_MSG_CPU_RW_REG_RESP;
|
||||||
memcpy(&pckt.desc, &packet->desc,
|
pckt.reply = packet->reply;
|
||||||
sizeof(struct ihk_os_cpu_register));
|
pckt.err = arch_cpu_read_write_register(cpu_desc, packet->op);
|
||||||
pckt.resp = packet->resp;
|
|
||||||
pckt.err = arch_cpu_read_write_register(&pckt.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);
|
ihk_ikc_send(resp_channel, &pckt, 0);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ struct ikc_scd_packet {
|
|||||||
|
|
||||||
/* SCD_MSG_CPU_RW_REG */
|
/* SCD_MSG_CPU_RW_REG */
|
||||||
struct {
|
struct {
|
||||||
struct ihk_os_cpu_register desc;
|
unsigned long pdesc; /* Physical addr of the descriptor */
|
||||||
enum mcctrl_os_cpu_operation op;
|
enum mcctrl_os_cpu_operation op;
|
||||||
void *resp;
|
void *resp;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user