diff options
author | gibbs <gibbs@FreeBSD.org> | 2013-09-20 22:59:22 +0000 |
---|---|---|
committer | gibbs <gibbs@FreeBSD.org> | 2013-09-20 22:59:22 +0000 |
commit | 7ed30adae7eb0c6e156983ca0c96c04e1e6a8e0d (patch) | |
tree | 301b6e7f4ff8cd017faecbcf64de6922be093a7e | |
parent | ec391855a94cc7ab44ba6ba5b3d8d27a5a1c224d (diff) | |
download | FreeBSD-src-7ed30adae7eb0c6e156983ca0c96c04e1e6a8e0d.zip FreeBSD-src-7ed30adae7eb0c6e156983ca0c96c04e1e6a8e0d.tar.gz |
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.
-rw-r--r-- | sys/amd64/amd64/mp_machdep.c | 28 | ||||
-rw-r--r-- | sys/amd64/conf/GENERIC | 4 | ||||
-rw-r--r-- | sys/amd64/conf/XENHVM | 22 | ||||
-rw-r--r-- | sys/amd64/include/cpu.h | 2 | ||||
-rw-r--r-- | sys/i386/conf/GENERIC | 4 | ||||
-rw-r--r-- | sys/i386/conf/XENHVM | 22 | ||||
-rw-r--r-- | sys/i386/i386/mp_machdep.c | 28 | ||||
-rw-r--r-- | sys/i386/include/cpu.h | 2 | ||||
-rw-r--r-- | sys/kern/subr_smp.c | 14 | ||||
-rw-r--r-- | sys/x86/xen/hvm.c | 53 | ||||
-rw-r--r-- | sys/xen/hvm.h | 1 |
11 files changed, 71 insertions, 109 deletions
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 1f02211..4ef4b3d 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -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(); diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index 4de94ce..7b2f8ee 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -72,6 +72,7 @@ options KDTRACE_FRAME # Ensure frames are compiled in 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 diff --git a/sys/amd64/conf/XENHVM b/sys/amd64/conf/XENHVM deleted file mode 100644 index ee745ec..0000000 --- a/sys/amd64/conf/XENHVM +++ /dev/null @@ -1,22 +0,0 @@ -# -# XENHVM -- Xen HVM kernel configuration file for FreeBSD/amd64 -# -# $FreeBSD$ -# -include GENERIC -ident XENHVM - -# -# Adaptive locks rely on a lock-free pointer read to determine the run state -# of the thread holding a lock when under contention; under a virtualisation -# system, the thread run state may not accurately reflect whether the thread -# (or rather its host VCPU) is actually executing. As such, disable this -# optimisation. -# -options NO_ADAPTIVE_MUTEXES -options NO_ADAPTIVE_RWLOCKS -options NO_ADAPTIVE_SX - -# Xen HVM support -options XENHVM -device xenpci diff --git a/sys/amd64/include/cpu.h b/sys/amd64/include/cpu.h index 5b994e1..3d9ff531 100644 --- a/sys/amd64/include/cpu.h +++ b/sys/amd64/include/cpu.h @@ -61,6 +61,8 @@ * hypervisor environment. */ struct cpu_ops { + void (*cpu_init)(void); + void (*cpu_resume)(void); void (*ipi_vectored)(u_int, int); }; diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index 20e1057..dfaf4ab 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -72,6 +72,7 @@ options MAC # TrustedBSD MAC Framework 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 diff --git a/sys/i386/conf/XENHVM b/sys/i386/conf/XENHVM deleted file mode 100644 index 9e1b52e..0000000 --- a/sys/i386/conf/XENHVM +++ /dev/null @@ -1,22 +0,0 @@ -# -# XENHVM -- Xen HVM kernel configuration file for FreeBSD/i386 -# -# $FreeBSD$ -# -include GENERIC -ident XENHVM - -# -# Adaptive locks rely on a lock-free pointer read to determine the run state -# of the thread holding a lock when under contention; under a virtualisation -# system, the thread run state may not accurately reflect whether the thread -# (or rather its host VCPU) is actually executing. As such, disable this -# optimisation. -# -options NO_ADAPTIVE_MUTEXES -options NO_ADAPTIVE_RWLOCKS -options NO_ADAPTIVE_SX - -# Xen HVM support -options XENHVM -device xenpci diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index 1d6d58a..8ee8653 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -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(); diff --git a/sys/i386/include/cpu.h b/sys/i386/include/cpu.h index 9655a15..49a8815 100644 --- a/sys/i386/include/cpu.h +++ b/sys/i386/include/cpu.h @@ -61,6 +61,8 @@ * hypervisor environment. */ struct cpu_ops { + void (*cpu_init)(void); + void (*cpu_resume)(void); void (*ipi_vectored)(u_int, int); }; diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c index 77d1b2b..86fbebb 100644 --- a/sys/kern/subr_smp.c +++ b/sys/kern/subr_smp.c @@ -225,17 +225,15 @@ generic_stop_cpus(cpuset_t map, u_int type) 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 type) } } -#ifdef XENHVM if (type == IPI_SUSPEND) mtx_unlock_spin(&smp_ipi_mtx); -#endif stopping_cpu = NOCPU; return (1); diff --git a/sys/x86/xen/hvm.c b/sys/x86/xen/hvm.c index b0c2df6..2286cf0 100644 --- a/sys/x86/xen/hvm.c +++ b/sys/x86/xen/hvm.c @@ -72,6 +72,9 @@ static driver_filter_t xen_cpustop_handler; 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_type) 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); diff --git a/sys/xen/hvm.h b/sys/xen/hvm.h index c7d40cb..07d3d7b 100644 --- a/sys/xen/hvm.h +++ b/sys/xen/hvm.h @@ -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__ */ |