svn commit: r267527 - in head/sys: conf x86/xen

Roger Pau Monné royger at FreeBSD.org
Mon Jun 16 08:43:47 UTC 2014


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));


More information about the svn-src-all mailing list