svn commit: r255744 - in head/sys: amd64/amd64 amd64/conf amd64/include i386/conf i386/i386 i386/include kern x86/xen xen
Justin T. Gibbs
gibbs at FreeBSD.org
Fri Sep 20 22:59:24 UTC 2013
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__ */
More information about the svn-src-all
mailing list