|
[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 |