[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v14 01/10] x86: add generic resource (e.g. MSR) access hypercall
Add a generic resource access hypercall for tool stack or other components, e.g., accessing MSR, port I/O, etc. Signed-off-by: Dongxiao Xu <dongxiao.xu@xxxxxxxxx> Signed-off-by: Chao Peng <chao.p.peng@xxxxxxxxxxxxxxx> --- xen/arch/x86/platform_hypercall.c | 90 ++++++++++++++++++++++++++++++ xen/arch/x86/x86_64/platform_hypercall.c | 4 ++ xen/include/public/platform.h | 27 +++++++++ xen/include/xlat.lst | 2 + 4 files changed, 123 insertions(+) diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index 2162811..52d89c7 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -61,6 +61,42 @@ long cpu_down_helper(void *data); long core_parking_helper(void *data); uint32_t get_cur_idle_nums(void); +struct xen_resource_access { + int32_t ret; + struct xenpf_resource_data data; +}; + +static bool_t allow_access_msr(unsigned int msr) +{ + return 0; +} + +static void resource_access_one(void *info) +{ + struct xen_resource_access *ra = info; + int ret = 0; + + switch ( ra->data.cmd ) + { + case XEN_RESOURCE_OP_MSR_READ: + case XEN_RESOURCE_OP_MSR_WRITE: + if ( ra->data.idx >> 32 ) + ret = -EINVAL; + if ( !allow_access_msr(ra->data.idx) ) + ret = -EACCES; + if ( ra->data.cmd == XEN_RESOURCE_OP_MSR_READ ) + ret = rdmsr_safe(ra->data.idx, ra->data.val); + else + ret = wrmsr_safe(ra->data.idx, ra->data.val); + break; + default: + ret = -EINVAL; + break; + } + + ra->ret = ret; +} + ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) { ret_t ret = 0; @@ -601,6 +637,60 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) } break; + case XENPF_resource_op: + { + struct xen_resource_access ra; + struct xenpf_resource_op *rsc_op = &op->u.resource_op; + unsigned int i, j = 0, cpu = smp_processor_id(); + + for ( i = 0; i < rsc_op->nr; i++ ) + { + if ( copy_from_guest_offset(&ra.data, rsc_op->data, i, 1) ) + { + ret = -EFAULT; + break; + } + + if ( ra.data.cpu == cpu ) + resource_access_one(&ra); + else if ( cpu_online(ra.data.cpu) ) + on_selected_cpus(cpumask_of(ra.data.cpu), + resource_access_one, &ra, 1); + else + { + ret = -ENODEV; + break; + } + + if ( ra.ret ) + { + ret = ra.ret; + break; + } + + if ( copy_to_guest_offset(rsc_op->data, i, &ra.data, 1) ) + { + ret = -EFAULT; + break; + } + + /* Find the start point that requires no preemption */ + if ( ra.data.flag && j == 0 ) + j = i; + /* Set j = 0 when walking out of the non-preemption area */ + if ( ra.data.flag == 0 ) + j = 0; + if ( hypercall_preempt_check() ) + { + ret = hypercall_create_continuation( + __HYPERVISOR_platform_op, "ih", + ra.data.flag ? j : i, u_xenpf_op); + break; + } + } + } + break; + default: ret = -ENOSYS; break; diff --git a/xen/arch/x86/x86_64/platform_hypercall.c b/xen/arch/x86/x86_64/platform_hypercall.c index b6f380e..4db6622 100644 --- a/xen/arch/x86/x86_64/platform_hypercall.c +++ b/xen/arch/x86/x86_64/platform_hypercall.c @@ -32,6 +32,10 @@ CHECK_pf_pcpu_version; CHECK_pf_enter_acpi_sleep; #undef xen_pf_enter_acpi_sleep +#define xen_pf_resource_data xenpf_resource_data +CHECK_pf_resource_data; +#undef xen_pf_resource_data + #define COMPAT #define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t) #define _XEN_GUEST_HANDLE_PARAM(t) XEN_GUEST_HANDLE_PARAM(t) diff --git a/xen/include/public/platform.h b/xen/include/public/platform.h index 053b9fa..7590179 100644 --- a/xen/include/public/platform.h +++ b/xen/include/public/platform.h @@ -527,6 +527,32 @@ struct xenpf_core_parking { typedef struct xenpf_core_parking xenpf_core_parking_t; DEFINE_XEN_GUEST_HANDLE(xenpf_core_parking_t); +#define XENPF_resource_op 61 + +#define XEN_RESOURCE_OP_MSR_READ 0 +#define XEN_RESOURCE_OP_MSR_WRITE 1 + +struct xenpf_resource_data { + uint16_t cmd; /* XEN_RESOURCE_OP_* */ + uint16_t flag; /* avoid preemption between certain iterations */ + uint32_t cpu; + uint64_t idx; + uint64_t val; +}; +typedef struct xenpf_resource_data xenpf_resource_data_t; +DEFINE_XEN_GUEST_HANDLE(xenpf_resource_data_t); + +/* + * This is a dynamic interface structure where "data" points to the elements + * start address, and "nr" specifies the element number. + */ +struct xenpf_resource_op { + uint32_t nr; + XEN_GUEST_HANDLE(xenpf_resource_data_t) data; +}; +typedef struct xenpf_resource_op xenpf_resource_op_t; +DEFINE_XEN_GUEST_HANDLE(xenpf_resource_op_t); + /* * ` enum neg_errnoval * ` HYPERVISOR_platform_op(const struct xen_platform_op*); @@ -553,6 +579,7 @@ struct xen_platform_op { struct xenpf_cpu_hotadd cpu_add; struct xenpf_mem_hotadd mem_add; struct xenpf_core_parking core_parking; + struct xenpf_resource_op resource_op; uint8_t pad[128]; } u; }; diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index 9a35dd7..100fcf5 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -88,6 +88,8 @@ ? xenpf_enter_acpi_sleep platform.h ? xenpf_pcpuinfo platform.h ? xenpf_pcpu_version platform.h +? xenpf_resource_op platform.h +? xenpf_resource_data platform.h ! sched_poll sched.h ? sched_remote_shutdown sched.h ? sched_shutdown sched.h -- 1.7.9.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |