[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC 2/2] xen/x86: Introduce XEN_SYSCTL_cpuid hypercall
which permits a toolstack to execute an arbitrary cpuid instruction on a specified physical cpu. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CC: Keir Fraser <keir@xxxxxxx> CC: Jan Beulich <JBeulich@xxxxxxxx> CC: Tim Deegan <tim@xxxxxxx> CC: Ian Campbell <Ian.Campbell@xxxxxxxxxx> CC: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> --- tools/libxc/xc_misc.c | 25 +++++++++++++++++++++++++ tools/libxc/xenctrl.h | 7 +++++++ xen/arch/x86/sysctl.c | 30 ++++++++++++++++++++++++++++++ xen/include/public/sysctl.h | 9 +++++++++ 4 files changed, 71 insertions(+) diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c index 4f672ce..48ef33e 100644 --- a/tools/libxc/xc_misc.c +++ b/tools/libxc/xc_misc.c @@ -774,6 +774,31 @@ int xc_hvm_inject_trap( return rc; } +int xc_xen_cpuid(xc_interface *xch, uint32_t cpu, uint32_t *eax, + uint32_t *ebx, uint32_t *ecx, uint32_t *edx) +{ + int ret; + DECLARE_SYSCTL; + + sysctl.cmd = XEN_SYSCTL_cpuid; + sysctl.u.cpuid.cpu = cpu; + sysctl.u.cpuid.eax = *eax; + sysctl.u.cpuid.ebx = *ebx; + sysctl.u.cpuid.ecx = *ecx; + sysctl.u.cpuid.edx = *edx; + + ret = do_sysctl(xch, &sysctl); + if ( ret ) + return ret; + + *eax = sysctl.u.cpuid.eax; + *ebx = sysctl.u.cpuid.ebx; + *ecx = sysctl.u.cpuid.ecx; + *edx = sysctl.u.cpuid.edx; + + return 0; +} + /* * Local variables: * mode: C diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 50126ae..a714156 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -1801,6 +1801,13 @@ int xc_hvm_inject_trap( uint64_t cr2); /* + * Run the cpuid instruction on a specificied physical cpu with the given + * parameters. + */ +int xc_xen_cpuid(xc_interface *xch, uint32_t cpu, uint32_t *eax, + uint32_t *ebx, uint32_t *ecx, uint32_t *edx); + +/* * LOGGING AND ERROR REPORTING */ diff --git a/xen/arch/x86/sysctl.c b/xen/arch/x86/sysctl.c index 15d4b91..dbad1ee 100644 --- a/xen/arch/x86/sysctl.c +++ b/xen/arch/x86/sysctl.c @@ -66,6 +66,18 @@ void arch_do_physinfo(xen_sysctl_physinfo_t *pi) pi->capabilities |= XEN_SYSCTL_PHYSCAP_hvm_directio; } +void sysctl_cpuid_helper(void *data) +{ + struct xen_sysctl_cpuid *cpuid = data; + + ASSERT(smp_processor_id() == cpuid->cpu); + asm volatile ("cpuid" + : "=a" (cpuid->eax), "=b" (cpuid->ebx), + "=c" (cpuid->ecx), "=d" (cpuid->edx) + : "a" (cpuid->eax), "b" (cpuid->ebx), + "c" (cpuid->ecx), "d" (cpuid->edx) ); +} + long arch_do_sysctl( struct xen_sysctl *sysctl, XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl) { @@ -101,6 +113,24 @@ long arch_do_sysctl( } break; + case XEN_SYSCTL_cpuid: + { + int cpu = sysctl->u.cpuid.cpu; + + if ( cpu == smp_processor_id() ) + sysctl_cpuid_helper(&sysctl->u.cpuid); + else if ( cpu >= nr_cpu_ids || !cpu_online(cpu) ) + ret = -EINVAL; + else + on_selected_cpus(cpumask_of(cpu), + sysctl_cpuid_helper, + &sysctl->u.cpuid, 1); + + if ( !ret && __copy_to_guest(u_sysctl, sysctl, 1) ) + ret = -EFAULT; + } + break; + default: ret = -ENOSYS; break; diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h index 8437d31..afa8a73 100644 --- a/xen/include/public/sysctl.h +++ b/xen/include/public/sysctl.h @@ -633,6 +633,13 @@ typedef struct xen_sysctl_coverage_op xen_sysctl_coverage_op_t; DEFINE_XEN_GUEST_HANDLE(xen_sysctl_coverage_op_t); +struct xen_sysctl_cpuid { + uint32_t cpu; /* IN - Pcpu to execute on */ + uint32_t eax, ebx, ecx, edx; /* IN/OUT - Parameters to `cpuid` */ +}; +typedef struct xen_sysctl_cpuid xen_sysctl_cpuid_t; +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_cpuid_t); + struct xen_sysctl { uint32_t cmd; #define XEN_SYSCTL_readconsole 1 @@ -654,6 +661,7 @@ struct xen_sysctl { #define XEN_SYSCTL_cpupool_op 18 #define XEN_SYSCTL_scheduler_op 19 #define XEN_SYSCTL_coverage_op 20 +#define XEN_SYSCTL_cpuid 21 uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */ union { struct xen_sysctl_readconsole readconsole; @@ -675,6 +683,7 @@ struct xen_sysctl { struct xen_sysctl_cpupool_op cpupool_op; struct xen_sysctl_scheduler_op scheduler_op; struct xen_sysctl_coverage_op coverage_op; + struct xen_sysctl_cpuid cpuid; uint8_t pad[128]; } u; }; -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |