Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 20 Sep 2013 22:59:22 +0000 (UTC)
From:      "Justin T. Gibbs" <gibbs@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r255744 - in head/sys: amd64/amd64 amd64/conf amd64/include i386/conf i386/i386 i386/include kern x86/xen xen
Message-ID:  <201309202259.r8KMxMP3084866@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gibbs
Date: Fri Sep 20 22:59:22 2013
New Revision: 255744
URL: http://svnweb.freebsd.org/changeset/base/255744

Log:
  Merge Xen PVHVM support into the GENERIC kernel config for both
  amd64 and i386.
  
  Submitted by:	Roger Pau Monné
  Sponsored by:	Citrix Systems R&D
  Reviewed by:	gibbs
  Approved by:	re (blanket Xen)
  MFC after:	2 weeks
  
  sys/amd64/amd64/mp_machdep.c:
  sys/amd64/include/cpu.h:
  sys/i386/i386/mp_machdep.c:
  sys/i386/include/cpu.h:
  	- Introduce two new CPU hooks for initialization and resume
  	  purposes. This allows us to get rid of the XENHVM ifdefs in
  	  mp_machdep, and also sets some hooks into common code that can be
  	  used by other hypervisor implementations.
  
  sys/amd64/conf/XENHVM:
  sys/i386/conf/XENHVM:
  	- Remove these configs now that GENERIC has builtin support for Xen
  	  HVM.
  
  sys/kern/subr_smp.c:
  	- Make sure there are no pending IPIs when suspending a system.
  
  sys/x86/xen/hvm.c:
  	- Add cpu init and resume vectors that are called from mp_machdep
  	  using the new hooks.
  	- Only clear the vcpu_info mapping data on resume.  It is already
  	  clear for the BSP on a cold boot and is set correctly as APs
  	  are started.
  	- Gate xen_hvm_init_cpu only to systems running under Xen.
  
  sys/x86/xen/xen_intr.c:
  	 - Gate the setup of event channels only to systems running under Xen.

Deleted:
  head/sys/amd64/conf/XENHVM
  head/sys/i386/conf/XENHVM
Modified:
  head/sys/amd64/amd64/mp_machdep.c
  head/sys/amd64/conf/GENERIC
  head/sys/amd64/include/cpu.h
  head/sys/i386/conf/GENERIC
  head/sys/i386/i386/mp_machdep.c
  head/sys/i386/include/cpu.h
  head/sys/kern/subr_smp.c
  head/sys/x86/xen/hvm.c
  head/sys/xen/hvm.h

Modified: head/sys/amd64/amd64/mp_machdep.c
==============================================================================
--- head/sys/amd64/amd64/mp_machdep.c	Fri Sep 20 22:00:07 2013	(r255743)
+++ head/sys/amd64/amd64/mp_machdep.c	Fri Sep 20 22:59:22 2013	(r255744)
@@ -71,10 +71,6 @@ __FBSDID("$FreeBSD$");
 #include <machine/tss.h>
 #include <machine/cpu.h>
 
-#ifdef XENHVM
-#include <xen/hvm.h>
-#endif
-
 #define WARMBOOT_TARGET		0
 #define WARMBOOT_OFF		(KERNBASE + 0x0467)
 #define WARMBOOT_SEG		(KERNBASE + 0x0469)
@@ -161,7 +157,7 @@ int cpu_apic_ids[MAXCPU];
 int apic_cpuids[MAX_APIC_ID + 1];
 
 /* Holds pending bitmap based IPIs per CPU */
-static volatile u_int cpu_ipi_pending[MAXCPU];
+volatile u_int cpu_ipi_pending[MAXCPU];
 
 static u_int boot_address;
 static int cpu_logical;			/* logical cpus per core */
@@ -732,10 +728,8 @@ init_secondary(void)
 	/* set up FPU state on the AP */
 	fpuinit();
 
-#ifdef XENHVM
-	/* register vcpu_info area */
-	xen_hvm_init_cpu();
-#endif
+	if (cpu_ops.cpu_init)
+		cpu_ops.cpu_init();
 
 	/* A quick check from sanity claus */
 	cpuid = PCPU_GET(cpuid);
@@ -1466,12 +1460,9 @@ cpususpend_handler(void)
 {
 	u_int cpu;
 
-	cpu = PCPU_GET(cpuid);
-
-#ifdef XENHVM
 	mtx_assert(&smp_ipi_mtx, MA_NOTOWNED);
-#endif
 
+	cpu = PCPU_GET(cpuid);
 	if (savectx(susppcbs[cpu])) {
 		ctx_fpusave(susppcbs[cpu]->pcb_fpususpend);
 		wbinvd();
@@ -1490,15 +1481,8 @@ cpususpend_handler(void)
 	while (!CPU_ISSET(cpu, &started_cpus))
 		ia32_pause();
 
-#ifdef XENHVM
-	/*
-	 * Reset pending bitmap IPIs, because Xen doesn't preserve pending
-	 * event channels on migration.
-	 */
-	cpu_ipi_pending[cpu] = 0;
-	/* register vcpu_info area */
-	xen_hvm_init_cpu();
-#endif
+	if (cpu_ops.cpu_resume)
+		cpu_ops.cpu_resume();
 
 	/* Resume MCA and local APIC */
 	mca_resume();

Modified: head/sys/amd64/conf/GENERIC
==============================================================================
--- head/sys/amd64/conf/GENERIC	Fri Sep 20 22:00:07 2013	(r255743)
+++ head/sys/amd64/conf/GENERIC	Fri Sep 20 22:59:22 2013	(r255744)
@@ -72,6 +72,7 @@ options 	KDTRACE_FRAME		# Ensure frames 
 options 	KDTRACE_HOOKS		# Kernel DTrace hooks
 options 	DDB_CTF			# Kernel ELF linker loads CTF data
 options 	INCLUDE_CONFIG_FILE     # Include this file in kernel
+options 	XENHVM			# Include Xen support
 
 # Debugging support.  Always need this:
 options 	KDB			# Enable kernel debugger support.
@@ -341,5 +342,8 @@ device		virtio_blk	# VirtIO Block device
 device		virtio_scsi	# VirtIO SCSI device
 device		virtio_balloon	# VirtIO Memory Balloon device
 
+# Xen support
+device		xenpci		# Generic Xen bus
+
 # VMware support
 device		vmx		# VMware VMXNET3 Ethernet

Modified: head/sys/amd64/include/cpu.h
==============================================================================
--- head/sys/amd64/include/cpu.h	Fri Sep 20 22:00:07 2013	(r255743)
+++ head/sys/amd64/include/cpu.h	Fri Sep 20 22:59:22 2013	(r255744)
@@ -61,6 +61,8 @@
  * hypervisor environment.
  */
 struct cpu_ops {
+	void (*cpu_init)(void);
+	void (*cpu_resume)(void);
 	void (*ipi_vectored)(u_int, int);
 };
 

Modified: head/sys/i386/conf/GENERIC
==============================================================================
--- head/sys/i386/conf/GENERIC	Fri Sep 20 22:00:07 2013	(r255743)
+++ head/sys/i386/conf/GENERIC	Fri Sep 20 22:59:22 2013	(r255744)
@@ -72,6 +72,7 @@ options 	MAC			# TrustedBSD MAC Framewor
 options 	KDTRACE_HOOKS		# Kernel DTrace hooks
 options 	DDB_CTF			# Kernel ELF linker loads CTF data
 options 	INCLUDE_CONFIG_FILE     # Include this file in kernel
+options 	XENHVM			# Include Xen support
 
 # Debugging support.  Always need this:
 options 	KDB			# Enable kernel debugger support.
@@ -355,5 +356,8 @@ device		virtio_blk	# VirtIO Block device
 device		virtio_scsi	# VirtIO SCSI device
 device		virtio_balloon	# VirtIO Memory Balloon device
 
+# Xen support
+device		xenpci		# Generic Xen bus
+
 # VMware support
 device		vmx		# VMware VMXNET3 Ethernet

Modified: head/sys/i386/i386/mp_machdep.c
==============================================================================
--- head/sys/i386/i386/mp_machdep.c	Fri Sep 20 22:00:07 2013	(r255743)
+++ head/sys/i386/i386/mp_machdep.c	Fri Sep 20 22:59:22 2013	(r255744)
@@ -83,10 +83,6 @@ __FBSDID("$FreeBSD$");
 #include <machine/specialreg.h>
 #include <machine/cpu.h>
 
-#ifdef XENHVM
-#include <xen/hvm.h>
-#endif
-
 #define WARMBOOT_TARGET		0
 #define WARMBOOT_OFF		(KERNBASE + 0x0467)
 #define WARMBOOT_SEG		(KERNBASE + 0x0469)
@@ -202,7 +198,7 @@ int cpu_apic_ids[MAXCPU];
 int apic_cpuids[MAX_APIC_ID + 1];
 
 /* Holds pending bitmap based IPIs per CPU */
-static volatile u_int cpu_ipi_pending[MAXCPU];
+volatile u_int cpu_ipi_pending[MAXCPU];
 
 static u_int boot_address;
 static int cpu_logical;			/* logical cpus per core */
@@ -757,10 +753,8 @@ init_secondary(void)
 	/* set up SSE registers */
 	enable_sse();
 
-#ifdef XENHVM
-	/* register vcpu_info area */
-	xen_hvm_init_cpu();
-#endif
+	if (cpu_ops.cpu_init)
+		cpu_ops.cpu_init();
 
 #ifdef PAE
 	/* Enable the PTE no-execute bit. */
@@ -1527,12 +1521,9 @@ cpususpend_handler(void)
 {
 	u_int cpu;
 
-	cpu = PCPU_GET(cpuid);
-
-#ifdef XENHVM
 	mtx_assert(&smp_ipi_mtx, MA_NOTOWNED);
-#endif
 
+	cpu = PCPU_GET(cpuid);
 	if (savectx(susppcbs[cpu])) {
 		wbinvd();
 		CPU_SET_ATOMIC(cpu, &suspended_cpus);
@@ -1549,15 +1540,8 @@ cpususpend_handler(void)
 	while (!CPU_ISSET(cpu, &started_cpus))
 		ia32_pause();
 
-#ifdef XENHVM
-	/*
-	 * Reset pending bitmap IPIs, because Xen doesn't preserve pending
-	 * event channels on migration.
-	 */
-	cpu_ipi_pending[cpu] = 0;
-	/* register vcpu_info area */
-	xen_hvm_init_cpu();
-#endif
+	if (cpu_ops.cpu_resume)
+		cpu_ops.cpu_resume();
 
 	/* Resume MCA and local APIC */
 	mca_resume();

Modified: head/sys/i386/include/cpu.h
==============================================================================
--- head/sys/i386/include/cpu.h	Fri Sep 20 22:00:07 2013	(r255743)
+++ head/sys/i386/include/cpu.h	Fri Sep 20 22:59:22 2013	(r255744)
@@ -61,6 +61,8 @@
  * hypervisor environment.
  */
 struct cpu_ops {
+	void (*cpu_init)(void);
+	void (*cpu_resume)(void);
 	void (*ipi_vectored)(u_int, int);
 };
 

Modified: head/sys/kern/subr_smp.c
==============================================================================
--- head/sys/kern/subr_smp.c	Fri Sep 20 22:00:07 2013	(r255743)
+++ head/sys/kern/subr_smp.c	Fri Sep 20 22:59:22 2013	(r255744)
@@ -225,17 +225,15 @@ generic_stop_cpus(cpuset_t map, u_int ty
 	CTR2(KTR_SMP, "stop_cpus(%s) with %u type",
 	    cpusetobj_strprint(cpusetbuf, &map), type);
 
-#ifdef XENHVM
 	/*
-	 * When migrating a PVHVM domain we need to make sure there are
-	 * no IPIs in progress.  IPIs that have been issued, but not
-	 * yet delivered (not pending on a vCPU) will be lost in the
-	 * IPI rebinding process, violating FreeBSD's assumption of
-	 * reliable IPI delivery.
+	 * When suspending, ensure there are are no IPIs in progress.
+	 * IPIs that have been issued, but not yet delivered (e.g.
+	 * not pending on a vCPU when running under virtualization)
+	 * will be lost, violating FreeBSD's assumption of reliable
+	 * IPI delivery.
 	 */
 	if (type == IPI_SUSPEND)
 		mtx_lock_spin(&smp_ipi_mtx);
-#endif
 
 	if (stopping_cpu != PCPU_GET(cpuid))
 		while (atomic_cmpset_int(&stopping_cpu, NOCPU,
@@ -264,10 +262,8 @@ generic_stop_cpus(cpuset_t map, u_int ty
 		}
 	}
 
-#ifdef XENHVM
 	if (type == IPI_SUSPEND)
 		mtx_unlock_spin(&smp_ipi_mtx);
-#endif
 
 	stopping_cpu = NOCPU;
 	return (1);

Modified: head/sys/x86/xen/hvm.c
==============================================================================
--- head/sys/x86/xen/hvm.c	Fri Sep 20 22:00:07 2013	(r255743)
+++ head/sys/x86/xen/hvm.c	Fri Sep 20 22:59:22 2013	(r255744)
@@ -72,6 +72,9 @@ static driver_filter_t xen_cpustop_handl
 static driver_filter_t xen_cpususpend_handler;
 static driver_filter_t xen_cpustophard_handler;
 #endif
+static void xen_ipi_vectored(u_int vector, int dest);
+static void xen_hvm_cpu_resume(void);
+static void xen_hvm_cpu_init(void);
 
 /*---------------------------- Extern Declarations ---------------------------*/
 /* Variables used by mp_machdep to perform the MMU related IPIs */
@@ -91,6 +94,9 @@ extern pmap_t smp_tlb_pmap;
 extern void pmap_lazyfix_action(void);
 #endif
 
+/* Variables used by mp_machdep to perform the bitmap IPI */
+extern volatile u_int cpu_ipi_pending[MAXCPU];
+
 /*---------------------------------- Macros ----------------------------------*/
 #define	IPI_TO_IDX(ipi) ((ipi) - APIC_IPI_INTS)
 
@@ -110,6 +116,12 @@ struct xen_ipi_handler
 /*-------------------------------- Global Data -------------------------------*/
 enum xen_domain_type xen_domain_type = XEN_NATIVE;
 
+struct cpu_ops xen_hvm_cpu_ops = {
+	.ipi_vectored	= xen_ipi_vectored,
+	.cpu_init	= xen_hvm_cpu_init,
+	.cpu_resume	= xen_hvm_cpu_resume
+};
+
 static MALLOC_DEFINE(M_XENHVM, "xen_hvm", "Xen HVM PV Support");
 
 #ifdef SMP
@@ -462,6 +474,22 @@ xen_ipi_vectored(u_int vector, int dest)
 	}
 }
 
+/* XEN diverged cpu operations */
+static void
+xen_hvm_cpu_resume(void)
+{
+	u_int cpuid = PCPU_GET(cpuid);
+
+	/*
+	 * Reset pending bitmap IPIs, because Xen doesn't preserve pending
+	 * event channels on migration.
+	 */
+	cpu_ipi_pending[cpuid] = 0;
+
+	/* register vcpu_info area */
+	xen_hvm_cpu_init();
+}
+
 static void
 xen_cpu_ipi_init(int cpu)
 {
@@ -490,7 +518,7 @@ xen_cpu_ipi_init(int cpu)
 }
 
 static void
-xen_init_ipis(void)
+xen_setup_cpus(void)
 {
 	int i;
 
@@ -507,7 +535,7 @@ xen_init_ipis(void)
 		xen_cpu_ipi_init(i);
 
 	/* Set the xen pv ipi ops to replace the native ones */
-	cpu_ops.ipi_vectored = xen_ipi_vectored;
+	cpu_ops = xen_hvm_cpu_ops;
 }
 #endif
 
@@ -675,15 +703,15 @@ xen_hvm_init(enum xen_hvm_init_type init
 	case XEN_HVM_INIT_RESUME:
 		if (error != 0)
 			panic("Unable to init Xen hypercall stubs on resume");
+
+		/* Clear stale vcpu_info. */
+		CPU_FOREACH(i)
+			DPCPU_ID_SET(i, vcpu_info, NULL);
 		break;
 	default:
 		panic("Unsupported HVM initialization type");
 	}
 
-	/* Clear any stale vcpu_info. */
-	CPU_FOREACH(i)
-		DPCPU_ID_SET(i, vcpu_info, NULL);
-
 	xen_vector_callback_enabled = 0;
 	xen_domain_type = XEN_HVM_DOMAIN;
 	xen_hvm_init_shared_info_page();
@@ -704,7 +732,7 @@ xen_hvm_resume(bool suspend_cancelled)
 	    XEN_HVM_INIT_CANCELLED_SUSPEND : XEN_HVM_INIT_RESUME);
 
 	/* Register vcpu_info area for CPU#0. */
-	xen_hvm_init_cpu();
+	xen_hvm_cpu_init();
 }
  
 static void
@@ -713,13 +741,16 @@ xen_hvm_sysinit(void *arg __unused)
 	xen_hvm_init(XEN_HVM_INIT_COLD);
 }
 
-void
-xen_hvm_init_cpu(void)
+static void
+xen_hvm_cpu_init(void)
 {
 	struct vcpu_register_vcpu_info info;
 	struct vcpu_info *vcpu_info;
 	int cpu, rc;
 
+	if (!xen_domain())
+		return;
+
 	if (DPCPU_GET(vcpu_info) != NULL) {
 		/*
 		 * vcpu_info is already set.  We're resuming
@@ -743,6 +774,6 @@ xen_hvm_init_cpu(void)
 
 SYSINIT(xen_hvm_init, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, xen_hvm_sysinit, NULL);
 #ifdef SMP
-SYSINIT(xen_init_ipis, SI_SUB_SMP, SI_ORDER_FIRST, xen_init_ipis, NULL);
+SYSINIT(xen_setup_cpus, SI_SUB_SMP, SI_ORDER_FIRST, xen_setup_cpus, NULL);
 #endif
-SYSINIT(xen_hvm_init_cpu, SI_SUB_INTR, SI_ORDER_FIRST, xen_hvm_init_cpu, NULL);
+SYSINIT(xen_hvm_cpu_init, SI_SUB_INTR, SI_ORDER_FIRST, xen_hvm_cpu_init, NULL);

Modified: head/sys/xen/hvm.h
==============================================================================
--- head/sys/xen/hvm.h	Fri Sep 20 22:00:07 2013	(r255743)
+++ head/sys/xen/hvm.h	Fri Sep 20 22:59:22 2013	(r255744)
@@ -94,5 +94,4 @@ enum {
 void xen_hvm_set_callback(device_t);
 void xen_hvm_suspend(void);
 void xen_hvm_resume(bool suspend_cancelled);
-void xen_hvm_init_cpu(void);
 #endif	/* __XEN_HVM_H__ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201309202259.r8KMxMP3084866>