svn commit: r336473 - in head/sys: x86/xen xen

Roger Pau Monné royger at FreeBSD.org
Thu Jul 19 08:13:43 UTC 2018


Author: royger
Date: Thu Jul 19 08:13:41 2018
New Revision: 336473
URL: https://svnweb.freebsd.org/changeset/base/336473

Log:
  xen: allow very early initialization of the hypercall page
  
  Allow the hypercall page to be initialized very early, even before
  vtophys is functional. Also make the function global so it can be
  called by other files.
  
  This will be needed in order to perform the early bringup on PVHv2
  guests.
  
  Sponsored by: Citrix Systems R&D

Modified:
  head/sys/x86/xen/hvm.c
  head/sys/xen/hvm.h

Modified: head/sys/x86/xen/hvm.c
==============================================================================
--- head/sys/x86/xen/hvm.c	Thu Jul 19 08:00:52 2018	(r336472)
+++ head/sys/x86/xen/hvm.c	Thu Jul 19 08:13:41 2018	(r336473)
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
+#include <vm/vm_param.h>
 
 #include <dev/pci/pcivar.h>
 
@@ -63,13 +64,6 @@ __FBSDID("$FreeBSD$");
 /*--------------------------- Forward Declarations ---------------------------*/
 static void xen_hvm_cpu_init(void);
 
-/*-------------------------------- Local Types -------------------------------*/
-enum xen_hvm_init_type {
-	XEN_HVM_INIT_COLD,
-	XEN_HVM_INIT_CANCELLED_SUSPEND,
-	XEN_HVM_INIT_RESUME
-};
-
 /*-------------------------------- Global Data -------------------------------*/
 enum xen_domain_type xen_domain_type = XEN_NATIVE;
 
@@ -119,51 +113,67 @@ xen_hvm_cpuid_base(void)
 	return (0);
 }
 
+static void
+hypervisor_quirks(unsigned int major, unsigned int minor)
+{
+#ifdef SMP
+	if (((major < 4) || (major == 4 && minor <= 5)) &&
+	    msix_disable_migration == -1) {
+		/*
+		 * Xen hypervisors prior to 4.6.0 do not properly
+		 * handle updates to enabled MSI-X table entries,
+		 * so disable MSI-X interrupt migration in that
+		 * case.
+		 */
+		if (bootverbose)
+			printf(
+"Disabling MSI-X interrupt migration due to Xen hypervisor bug.\n"
+"Set machdep.msix_disable_migration=0 to forcefully enable it.\n");
+		msix_disable_migration = 1;
+	}
+#endif
+}
+
+static void
+hypervisor_version(void)
+{
+	uint32_t regs[4];
+	int major, minor;
+
+	do_cpuid(cpuid_base + 1, regs);
+
+	major = regs[0] >> 16;
+	minor = regs[0] & 0xffff;
+	printf("XEN: Hypervisor version %d.%d detected.\n", major, minor);
+
+	hypervisor_quirks(major, minor);
+}
+
 /*
  * Allocate and fill in the hypcall page.
  */
-static int
+int
 xen_hvm_init_hypercall_stubs(enum xen_hvm_init_type init_type)
 {
 	uint32_t regs[4];
 
-	if (xen_pv_domain()) {
-		/* hypercall page is already set in the PV case */
-		return (0);
+	if (xen_domain() && init_type == XEN_HVM_INIT_LATE) {
+		/*
+		 * If the domain type is already set we can assume that the
+		 * hypercall page has been populated too, so just print the
+		 * version (and apply any quirks) and exit.
+		 */
+		hypervisor_version();
+		return 0;
 	}
 
 	cpuid_base = xen_hvm_cpuid_base();
 	if (cpuid_base == 0)
 		return (ENXIO);
 
-	if (init_type == XEN_HVM_INIT_COLD) {
-		int major, minor;
+	if (init_type == XEN_HVM_INIT_LATE)
+		hypervisor_version();
 
-		do_cpuid(cpuid_base + 1, regs);
-
-		major = regs[0] >> 16;
-		minor = regs[0] & 0xffff;
-		printf("XEN: Hypervisor version %d.%d detected.\n", major,
-			minor);
-
-#ifdef SMP
-		if (((major < 4) || (major == 4 && minor <= 5)) &&
-		    msix_disable_migration == -1) {
-			/*
-			 * Xen hypervisors prior to 4.6.0 do not properly
-			 * handle updates to enabled MSI-X table entries,
-			 * so disable MSI-X interrupt migration in that
-			 * case.
-			 */
-			if (bootverbose)
-				printf(
-"Disabling MSI-X interrupt migration due to Xen hypervisor bug.\n"
-"Set machdep.msix_disable_migration=0 to forcefully enable it.\n");
-			msix_disable_migration = 1;
-		}
-#endif
-	}
-
 	/*
 	 * Find the hypercall pages.
 	 */
@@ -171,7 +181,9 @@ xen_hvm_init_hypercall_stubs(enum xen_hvm_init_type in
 	if (regs[0] != 1)
 		return (EINVAL);
 
-	wrmsr(regs[1], vtophys(&hypercall_page));
+	wrmsr(regs[1], (init_type == XEN_HVM_INIT_EARLY)
+	    ? ((vm_paddr_t)&hypercall_page - KERNBASE)
+	    : vtophys(&hypercall_page));
 
 	return (0);
 }
@@ -307,7 +319,7 @@ xen_hvm_init(enum xen_hvm_init_type init_type)
 	error = xen_hvm_init_hypercall_stubs(init_type);
 
 	switch (init_type) {
-	case XEN_HVM_INIT_COLD:
+	case XEN_HVM_INIT_LATE:
 		if (error != 0)
 			return;
 
@@ -371,7 +383,7 @@ xen_hvm_resume(bool suspend_cancelled)
 static void
 xen_hvm_sysinit(void *arg __unused)
 {
-	xen_hvm_init(XEN_HVM_INIT_COLD);
+	xen_hvm_init(XEN_HVM_INIT_LATE);
 }
 SYSINIT(xen_hvm_init, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, xen_hvm_sysinit, NULL);
 

Modified: head/sys/xen/hvm.h
==============================================================================
--- head/sys/xen/hvm.h	Thu Jul 19 08:00:52 2018	(r336472)
+++ head/sys/xen/hvm.h	Thu Jul 19 08:13:41 2018	(r336473)
@@ -91,6 +91,14 @@ enum {
     (((uint64_t)HVM_CB_TYPE_VECTOR << HVM_CB_TYPE_SHIFT) \
    | (((vector) & HVM_CB_GSI_GSI_MASK) << HVM_CB_GSI_GSI_SHIFT))
 
+enum xen_hvm_init_type {
+	XEN_HVM_INIT_EARLY,
+	XEN_HVM_INIT_LATE,
+	XEN_HVM_INIT_CANCELLED_SUSPEND,
+	XEN_HVM_INIT_RESUME,
+};
+
+int xen_hvm_init_hypercall_stubs(enum xen_hvm_init_type);
 void xen_hvm_set_callback(device_t);
 void xen_hvm_suspend(void);
 void xen_hvm_resume(bool suspend_cancelled);


More information about the svn-src-head mailing list