Date: Mon, 16 Jun 2014 08:43:46 +0000 (UTC) From: Roger Pau Monné <royger@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r267527 - in head/sys: conf x86/xen Message-ID: <201406160843.s5G8hkDl074065@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: royger Date: Mon Jun 16 08:43:45 2014 New Revision: 267527 URL: http://svnweb.freebsd.org/changeset/base/267527 Log: xen: add hooks for Xen PV APIC Create the necessary hooks in order to provide a Xen PV APIC implementation that can be used on PVH. Most of the lapic ops shouldn't be called on Xen, since we trap those operations at a higher layer. Sponsored by: Citrix Systems R&D Approved by: gibbs x86/xen/hvm.c: x86/xen/xen_apic.c: - Move IPI related code to xen_apic.c x86/xen/xen_apic.c: - Introduce Xen PV APIC implementation, most of the functions of the lapic interface should never be called when running as PV(H) guest, so make sure FreeBSD panics when trying to use one of those. - Define the Xen APIC implementation in xen_apic_ops. xen/xen_pv.h: - Extern declaration of the xen_apic struct. x86/xen/pv.c: - Use xen_apic_ops as apic_ops when running as PVH guest. conf/files.amd64: conf/files.i386: - Include the xen_apic.c file in the build of i386/amd64 kernels using XENHVM. Modified: head/sys/conf/files.amd64 head/sys/conf/files.i386 head/sys/x86/xen/hvm.c head/sys/x86/xen/pv.c Modified: head/sys/conf/files.amd64 ============================================================================== --- head/sys/conf/files.amd64 Mon Jun 16 08:43:03 2014 (r267526) +++ head/sys/conf/files.amd64 Mon Jun 16 08:43:45 2014 (r267527) @@ -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 Modified: head/sys/conf/files.i386 ============================================================================== --- head/sys/conf/files.i386 Mon Jun 16 08:43:03 2014 (r267526) +++ head/sys/conf/files.i386 Mon Jun 16 08:43:45 2014 (r267527) @@ -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 Modified: head/sys/x86/xen/hvm.c ============================================================================== --- head/sys/x86/xen/hvm.c Mon Jun 16 08:43:03 2014 (r267526) +++ head/sys/x86/xen/hvm.c Mon Jun 16 08:43:45 2014 (r267527) @@ -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); Modified: head/sys/x86/xen/pv.c ============================================================================== --- head/sys/x86/xen/pv.c Mon Jun 16 08:43:03 2014 (r267526) +++ head/sys/x86/xen/pv.c Mon Jun 16 08:43:45 2014 (r267527) @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include <xen/xen-os.h> #include <xen/hypervisor.h> #include <xen/xenstore/xenstorevar.h> +#include <xen/xen_pv.h> #include <xen/interface/vcpu.h> @@ -180,6 +181,7 @@ hammer_time_xen(start_info_t *si, uint64 /* 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));
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201406160843.s5G8hkDl074065>