diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 6eefb4c816d..71f32ed1e4e 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -557,3 +557,4 @@ x86/xen/hvm.c optional xenhvm x86/xen/xen_intr.c optional xen | xenhvm x86/xen/pv.c optional xenhvm x86/xen/pvcpu_enum.c optional xenhvm +x86/xen/xen_apic.c optional xenhvm diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index ae0238251d5..3a93a6b66c5 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -594,3 +594,4 @@ x86/x86/tsc.c standard x86/x86/delay.c standard x86/xen/hvm.c optional xenhvm x86/xen/xen_intr.c optional xen | xenhvm +x86/xen/xen_apic.c optional xenhvm diff --git a/sys/x86/xen/hvm.c b/sys/x86/xen/hvm.c index ca0f91f89c0..8fda923b8a6 100644 --- a/sys/x86/xen/hvm.c +++ b/sys/x86/xen/hvm.c @@ -59,37 +59,14 @@ __FBSDID("$FreeBSD$"); /*--------------------------- Forward Declarations ---------------------------*/ #ifdef SMP -static driver_filter_t xen_smp_rendezvous_action; -static driver_filter_t xen_invltlb; -static driver_filter_t xen_invlpg; -static driver_filter_t xen_invlrng; -static driver_filter_t xen_invlcache; -#ifdef __i386__ -static driver_filter_t xen_lazypmap; -#endif -static driver_filter_t xen_ipi_bitmap_handler; -static driver_filter_t xen_cpustop_handler; -static driver_filter_t xen_cpususpend_handler; -static driver_filter_t xen_cpustophard_handler; -static void xen_ipi_vectored(u_int vector, int dest); static void xen_hvm_cpu_resume(void); #endif static void xen_hvm_cpu_init(void); /*---------------------------- Extern Declarations ---------------------------*/ -#ifdef __i386__ -extern void pmap_lazyfix_action(void); -#endif -#ifdef __amd64__ -extern int pmap_pcid_enabled; -#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) - /*-------------------------------- Local Types -------------------------------*/ enum xen_hvm_init_type { XEN_HVM_INIT_COLD, @@ -97,12 +74,6 @@ enum xen_hvm_init_type { XEN_HVM_INIT_RESUME }; -struct xen_ipi_handler -{ - driver_filter_t *filter; - const char *description; -}; - /*-------------------------------- Global Data -------------------------------*/ enum xen_domain_type xen_domain_type = XEN_NATIVE; @@ -115,24 +86,6 @@ struct cpu_ops xen_hvm_cpu_ops = { static MALLOC_DEFINE(M_XENHVM, "xen_hvm", "Xen HVM PV Support"); -#ifdef SMP -static struct xen_ipi_handler xen_ipis[] = -{ - [IPI_TO_IDX(IPI_RENDEZVOUS)] = { xen_smp_rendezvous_action, "r" }, - [IPI_TO_IDX(IPI_INVLTLB)] = { xen_invltlb, "itlb"}, - [IPI_TO_IDX(IPI_INVLPG)] = { xen_invlpg, "ipg" }, - [IPI_TO_IDX(IPI_INVLRNG)] = { xen_invlrng, "irg" }, - [IPI_TO_IDX(IPI_INVLCACHE)] = { xen_invlcache, "ic" }, -#ifdef __i386__ - [IPI_TO_IDX(IPI_LAZYPMAP)] = { xen_lazypmap, "lp" }, -#endif - [IPI_TO_IDX(IPI_BITMAP_VECTOR)] = { xen_ipi_bitmap_handler, "b" }, - [IPI_TO_IDX(IPI_STOP)] = { xen_cpustop_handler, "st" }, - [IPI_TO_IDX(IPI_SUSPEND)] = { xen_cpususpend_handler, "sp" }, - [IPI_TO_IDX(IPI_STOP_HARD)] = { xen_cpustophard_handler, "sth" }, -}; -#endif - /** * If non-zero, the hypervisor has been configured to use a direct * IDT event callback for interrupt injection. @@ -142,9 +95,6 @@ int xen_vector_callback_enabled; /*------------------------------- Per-CPU Data -------------------------------*/ DPCPU_DEFINE(struct vcpu_info, vcpu_local_info); DPCPU_DEFINE(struct vcpu_info *, vcpu_info); -#ifdef SMP -DPCPU_DEFINE(xen_intr_handle_t, ipi_handle[nitems(xen_ipis)]); -#endif /*------------------ Hypervisor Access Shared Memory Regions -----------------*/ /** Hypercall table accessed via HYPERVISOR_*_op() methods. */ @@ -153,156 +103,6 @@ shared_info_t *HYPERVISOR_shared_info; start_info_t *HYPERVISOR_start_info; #ifdef SMP -/*---------------------------- XEN PV IPI Handlers ---------------------------*/ -/* - * This are C clones of the ASM functions found in apic_vector.s - */ -static int -xen_ipi_bitmap_handler(void *arg) -{ - struct trapframe *frame; - - frame = arg; - ipi_bitmap_handler(*frame); - return (FILTER_HANDLED); -} - -static int -xen_smp_rendezvous_action(void *arg) -{ -#ifdef COUNT_IPIS - (*ipi_rendezvous_counts[PCPU_GET(cpuid)])++; -#endif /* COUNT_IPIS */ - - smp_rendezvous_action(); - return (FILTER_HANDLED); -} - -static int -xen_invltlb(void *arg) -{ - - invltlb_handler(); - return (FILTER_HANDLED); -} - -#ifdef __amd64__ -static int -xen_invltlb_pcid(void *arg) -{ - - invltlb_pcid_handler(); - return (FILTER_HANDLED); -} -#endif - -static int -xen_invlpg(void *arg) -{ - - invlpg_handler(); - return (FILTER_HANDLED); -} - -#ifdef __amd64__ -static int -xen_invlpg_pcid(void *arg) -{ - - invlpg_pcid_handler(); - return (FILTER_HANDLED); -} -#endif - -static int -xen_invlrng(void *arg) -{ - - invlrng_handler(); - return (FILTER_HANDLED); -} - -static int -xen_invlcache(void *arg) -{ - - invlcache_handler(); - return (FILTER_HANDLED); -} - -#ifdef __i386__ -static int -xen_lazypmap(void *arg) -{ - - pmap_lazyfix_action(); - return (FILTER_HANDLED); -} -#endif - -static int -xen_cpustop_handler(void *arg) -{ - - cpustop_handler(); - return (FILTER_HANDLED); -} - -static int -xen_cpususpend_handler(void *arg) -{ - - cpususpend_handler(); - return (FILTER_HANDLED); -} - -static int -xen_cpustophard_handler(void *arg) -{ - - ipi_nmi_handler(); - return (FILTER_HANDLED); -} - -/* Xen PV IPI sender */ -static void -xen_ipi_vectored(u_int vector, int dest) -{ - xen_intr_handle_t *ipi_handle; - int ipi_idx, to_cpu, self; - - ipi_idx = IPI_TO_IDX(vector); - if (ipi_idx > nitems(xen_ipis)) - panic("IPI out of range"); - - switch(dest) { - case APIC_IPI_DEST_SELF: - ipi_handle = DPCPU_GET(ipi_handle); - xen_intr_signal(ipi_handle[ipi_idx]); - break; - case APIC_IPI_DEST_ALL: - CPU_FOREACH(to_cpu) { - ipi_handle = DPCPU_ID_GET(to_cpu, ipi_handle); - xen_intr_signal(ipi_handle[ipi_idx]); - } - break; - case APIC_IPI_DEST_OTHERS: - self = PCPU_GET(cpuid); - CPU_FOREACH(to_cpu) { - if (to_cpu != self) { - ipi_handle = DPCPU_ID_GET(to_cpu, ipi_handle); - xen_intr_signal(ipi_handle[ipi_idx]); - } - } - break; - default: - to_cpu = apic_cpuid(dest); - ipi_handle = DPCPU_ID_GET(to_cpu, ipi_handle); - xen_intr_signal(ipi_handle[ipi_idx]); - break; - } -} - /* XEN diverged cpu operations */ static void xen_hvm_cpu_resume(void) @@ -318,56 +118,7 @@ xen_hvm_cpu_resume(void) /* register vcpu_info area */ xen_hvm_cpu_init(); } - -static void -xen_cpu_ipi_init(int cpu) -{ - xen_intr_handle_t *ipi_handle; - const struct xen_ipi_handler *ipi; - device_t dev; - int idx, rc; - - ipi_handle = DPCPU_ID_GET(cpu, ipi_handle); - dev = pcpu_find(cpu)->pc_device; - KASSERT((dev != NULL), ("NULL pcpu device_t")); - - for (ipi = xen_ipis, idx = 0; idx < nitems(xen_ipis); ipi++, idx++) { - - if (ipi->filter == NULL) { - ipi_handle[idx] = NULL; - continue; - } - - rc = xen_intr_alloc_and_bind_ipi(dev, cpu, ipi->filter, - INTR_TYPE_TTY, &ipi_handle[idx]); - if (rc != 0) - panic("Unable to allocate a XEN IPI port"); - xen_intr_describe(ipi_handle[idx], "%s", ipi->description); - } -} - -static void -xen_setup_cpus(void) -{ - int i; - - if (!xen_vector_callback_enabled) - return; - -#ifdef __amd64__ - if (pmap_pcid_enabled) { - xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter = xen_invltlb_pcid; - xen_ipis[IPI_TO_IDX(IPI_INVLPG)].filter = xen_invlpg_pcid; - } #endif - CPU_FOREACH(i) - xen_cpu_ipi_init(i); - - /* Set the xen pv ipi ops to replace the native ones */ - apic_ops.ipi_vectored = xen_ipi_vectored; -} -#endif - /*---------------------- XEN Hypervisor Probe and Setup ----------------------*/ static uint32_t xen_hvm_cpuid_base(void) @@ -654,9 +405,5 @@ xen_hvm_cpu_init(void) } SYSINIT(xen_hvm_init, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, xen_hvm_sysinit, NULL); -#ifdef SMP -/* We need to setup IPIs before APs are started */ -SYSINIT(xen_setup_cpus, SI_SUB_SMP-1, SI_ORDER_FIRST, xen_setup_cpus, NULL); -#endif SYSINIT(xen_hvm_cpu_init, SI_SUB_INTR, SI_ORDER_FIRST, xen_hvm_cpu_init, NULL); SYSINIT(xen_set_vcpu_id, SI_SUB_CPU, SI_ORDER_ANY, xen_set_vcpu_id, NULL); diff --git a/sys/x86/xen/pv.c b/sys/x86/xen/pv.c index 263e2113653..f008161eec6 100644 --- a/sys/x86/xen/pv.c +++ b/sys/x86/xen/pv.c @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include @@ -180,6 +181,7 @@ hammer_time_xen(start_info_t *si, uint64_t xenstack) /* Set the hooks for early functions that diverge from bare metal */ init_ops = xen_init_ops; + apic_ops = xen_apic_ops; /* Now we can jump into the native init function */ return (hammer_time(0, physfree));