summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorroyger <royger@FreeBSD.org>2014-03-11 10:24:13 +0000
committerroyger <royger@FreeBSD.org>2014-03-11 10:24:13 +0000
commit6b1be122340e08f3cd907273f419d173138cf66e (patch)
tree321190d6e7f2a3801f2989218ddc460bf9a4c1f9
parent891131cb52c5aa334778f1f5cb0ac125c88c32cb (diff)
downloadFreeBSD-src-6b1be122340e08f3cd907273f419d173138cf66e.zip
FreeBSD-src-6b1be122340e08f3cd907273f419d173138cf66e.tar.gz
xen: use the same hypercall mechanism for XEN and XENHVM
Currently XEN (PV) and XENHVM (PVHVM) ports use different ways to issue hypercalls, unify this by filling the hypercall_page under HVM also. Approved by: gibbs Sponsored by: Citrix Systems R&D amd64/include/xen/hypercall.h: - Unify Xen hypercall code by always using the PV way. i386/i386/locore.s: - Define hypercall_page on i386 XENHVM. x86/xen/hvm.c: - Fill hypercall_page on XENHVM kernels using the HVM method (only when running as an HVM guest).
-rw-r--r--sys/amd64/include/xen/hypercall.h7
-rw-r--r--sys/i386/i386/locore.s9
-rw-r--r--sys/i386/include/xen/hypercall.h8
-rw-r--r--sys/x86/xen/hvm.c24
4 files changed, 19 insertions, 29 deletions
diff --git a/sys/amd64/include/xen/hypercall.h b/sys/amd64/include/xen/hypercall.h
index a1b2a5c..499fb4d 100644
--- a/sys/amd64/include/xen/hypercall.h
+++ b/sys/amd64/include/xen/hypercall.h
@@ -51,15 +51,8 @@
#define CONFIG_XEN_COMPAT 0x030002
#define __must_check
-#ifdef XEN
#define HYPERCALL_STR(name) \
"call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"
-#else
-#define HYPERCALL_STR(name) \
- "mov $("STR(__HYPERVISOR_##name)" * 32),%%eax; "\
- "add hypercall_stubs(%%rip),%%rax; " \
- "call *%%rax"
-#endif
#define _hypercall0(type, name) \
({ \
diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s
index 68cb430..bd136b1 100644
--- a/sys/i386/i386/locore.s
+++ b/sys/i386/i386/locore.s
@@ -898,3 +898,12 @@ done_pde:
#endif
ret
+
+#ifdef XENHVM
+/* Xen Hypercall page */
+ .text
+.p2align PAGE_SHIFT, 0x90 /* Hypercall_page needs to be PAGE aligned */
+
+NON_GPROF_ENTRY(hypercall_page)
+ .skip 0x1000, 0x90 /* Fill with "nop"s */
+#endif
diff --git a/sys/i386/include/xen/hypercall.h b/sys/i386/include/xen/hypercall.h
index edc13f4..16b5ee2 100644
--- a/sys/i386/include/xen/hypercall.h
+++ b/sys/i386/include/xen/hypercall.h
@@ -39,16 +39,8 @@
#define ENOXENSYS 38
#define CONFIG_XEN_COMPAT 0x030002
-
-#if defined(XEN)
#define HYPERCALL_STR(name) \
"call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"
-#else
-#define HYPERCALL_STR(name) \
- "mov hypercall_stubs,%%eax; " \
- "add $("STR(__HYPERVISOR_##name)" * 32),%%eax; " \
- "call *%%eax"
-#endif
#define _hypercall0(type, name) \
({ \
diff --git a/sys/x86/xen/hvm.c b/sys/x86/xen/hvm.c
index 6977d56..cb895e5 100644
--- a/sys/x86/xen/hvm.c
+++ b/sys/x86/xen/hvm.c
@@ -147,7 +147,7 @@ DPCPU_DEFINE(xen_intr_handle_t, ipi_handle[nitems(xen_ipis)]);
/*------------------ Hypervisor Access Shared Memory Regions -----------------*/
/** Hypercall table accessed via HYPERVISOR_*_op() methods. */
-char *hypercall_stubs;
+extern char *hypercall_page;
shared_info_t *HYPERVISOR_shared_info;
start_info_t *HYPERVISOR_start_info;
@@ -386,16 +386,21 @@ xen_hvm_cpuid_base(void)
* Allocate and fill in the hypcall page.
*/
static int
-xen_hvm_init_hypercall_stubs(void)
+xen_hvm_init_hypercall_stubs(enum xen_hvm_init_type init_type)
{
uint32_t base, regs[4];
int i;
+ if (xen_pv_domain()) {
+ /* hypercall page is already set in the PV case */
+ return (0);
+ }
+
base = xen_hvm_cpuid_base();
if (base == 0)
return (ENXIO);
- if (hypercall_stubs == NULL) {
+ if (init_type == XEN_HVM_INIT_COLD) {
do_cpuid(base + 1, regs);
printf("XEN: Hypervisor version %d.%d detected.\n",
regs[0] >> 16, regs[0] & 0xffff);
@@ -405,18 +410,9 @@ xen_hvm_init_hypercall_stubs(void)
* Find the hypercall pages.
*/
do_cpuid(base + 2, regs);
-
- if (hypercall_stubs == NULL) {
- size_t call_region_size;
-
- call_region_size = regs[0] * PAGE_SIZE;
- hypercall_stubs = malloc(call_region_size, M_XENHVM, M_NOWAIT);
- if (hypercall_stubs == NULL)
- panic("Unable to allocate Xen hypercall region");
- }
for (i = 0; i < regs[0]; i++)
- wrmsr(regs[1], vtophys(hypercall_stubs + i * PAGE_SIZE) + i);
+ wrmsr(regs[1], vtophys(&hypercall_page + i * PAGE_SIZE) + i);
return (0);
}
@@ -519,7 +515,7 @@ xen_hvm_init(enum xen_hvm_init_type init_type)
if (init_type == XEN_HVM_INIT_CANCELLED_SUSPEND)
return;
- error = xen_hvm_init_hypercall_stubs();
+ error = xen_hvm_init_hypercall_stubs(init_type);
switch (init_type) {
case XEN_HVM_INIT_COLD:
OpenPOWER on IntegriCloud