git: e0516c7553da - main - x86/apic: remove apic_ops

From: Roger Pau Monné <royger_at_FreeBSD.org>
Date: Tue, 18 Jan 2022 09:19:19 UTC
The branch main has been updated by royger:

URL: https://cgit.FreeBSD.org/src/commit/?id=e0516c7553da636f7e2746a46dcfb47d4f9b9e9f

commit e0516c7553da636f7e2746a46dcfb47d4f9b9e9f
Author:     Roger Pau Monné <royger@FreeBSD.org>
AuthorDate: 2022-01-13 13:48:32 +0000
Commit:     Roger Pau Monné <royger@FreeBSD.org>
CommitDate: 2022-01-18 09:19:04 +0000

    x86/apic: remove apic_ops
    
    All supported Xen instances by FreeBSD provide a local APIC
    implementation, so there's no need to replace the native local APIC
    implementation anymore.
    
    Leave just the ipi_vectored hook in order to be able to override it
    with an implementation based on event channels if the underlying local
    APIC is not virtualized by hardware. Note the hook cannot use ifuncs,
    because at the point where ifuncs are resolved the kernel doesn't yet
    know whether it will benefit from using the optimization.
    
    Sponsored by: Citrix Systems R&D
    Reviewed by: kib
    Differential revision: https://reviews.freebsd.org/D33917
---
 sys/conf/files.x86        |   2 +-
 sys/x86/include/apicvar.h | 309 ++++++----------------------------------------
 sys/x86/x86/local_apic.c  | 216 +++++++++++---------------------
 sys/x86/xen/xen_apic.c    | 269 +---------------------------------------
 4 files changed, 109 insertions(+), 687 deletions(-)

diff --git a/sys/conf/files.x86 b/sys/conf/files.x86
index 739ce6886384..f5dfcd3e49e7 100644
--- a/sys/conf/files.x86
+++ b/sys/conf/files.x86
@@ -335,4 +335,4 @@ x86/x86/ucode.c			standard
 x86/x86/delay.c			standard
 x86/xen/hvm.c			optional	xenhvm
 x86/xen/xen_intr.c		optional	xenhvm
-x86/xen/xen_apic.c		optional	xenhvm
+x86/xen/xen_apic.c		optional	xenhvm smp
diff --git a/sys/x86/include/apicvar.h b/sys/x86/include/apicvar.h
index 373e7d576426..ff6bb97d7f80 100644
--- a/sys/x86/include/apicvar.h
+++ b/sys/x86/include/apicvar.h
@@ -190,6 +190,9 @@ inthand_t
 extern vm_paddr_t lapic_paddr;
 extern int *apic_cpuids;
 
+/* Allow to replace the lapic_ipi_vectored implementation. */
+extern void (*ipi_vectored)(u_int, int);
+
 void	apic_register_enumerator(struct apic_enumerator *enumerator);
 void	*ioapic_create(vm_paddr_t addr, int32_t apic_id, int intbase);
 int	ioapic_disable_pin(void *cookie, u_int pin);
@@ -204,286 +207,48 @@ int	ioapic_set_triggermode(void *cookie, u_int pin,
 	    enum intr_trigger trigger);
 int	ioapic_set_smi(void *cookie, u_int pin);
 
-/*
- * Struct containing pointers to APIC functions whose
- * implementation is run time selectable.
- */
-struct apic_ops {
-	void	(*create)(u_int, int);
-	void	(*init)(vm_paddr_t);
-	void	(*xapic_mode)(void);
-	bool	(*is_x2apic)(void);
-	void	(*setup)(int);
-	void	(*dump)(const char *);
-	void	(*disable)(void);
-	void	(*eoi)(void);
-	int	(*id)(void);
-	int	(*intr_pending)(u_int);
-	void	(*set_logical_id)(u_int, u_int, u_int);
-	u_int	(*cpuid)(u_int);
-
-	/* Vectors */
-	u_int	(*alloc_vector)(u_int, u_int);
-	u_int	(*alloc_vectors)(u_int, u_int *, u_int, u_int);
-	void	(*enable_vector)(u_int, u_int);
-	void	(*disable_vector)(u_int, u_int);
-	void	(*free_vector)(u_int, u_int, u_int);
-
-	/* Timer */
-	void	(*calibrate_timer)(void);
-
-	/* PMC */
-	int	(*enable_pmc)(void);
-	void	(*disable_pmc)(void);
-	void	(*reenable_pmc)(void);
-
-	/* CMC */
-	void	(*enable_cmc)(void);
-
-	/* AMD ELVT */
-	int	(*enable_mca_elvt)(void);
-
-	/* IPI */
-	void	(*ipi_raw)(register_t, u_int);
-	void	(*ipi_vectored)(u_int, int);
-	int	(*ipi_wait)(int);
-	int	(*ipi_alloc)(inthand_t *ipifunc);
-	void	(*ipi_free)(int vector);
-
-	/* LVT */
-	int	(*set_lvt_mask)(u_int, u_int, u_char);
-	int	(*set_lvt_mode)(u_int, u_int, u_int32_t);
-	int	(*set_lvt_polarity)(u_int, u_int, enum intr_polarity);
-	int	(*set_lvt_triggermode)(u_int, u_int, enum intr_trigger);
-};
-
-extern struct apic_ops apic_ops;
-
-static inline void
-lapic_create(u_int apic_id, int boot_cpu)
-{
-
-	apic_ops.create(apic_id, boot_cpu);
-}
-
-static inline void
-lapic_init(vm_paddr_t addr)
-{
-
-	apic_ops.init(addr);
-}
-
-static inline void
-lapic_xapic_mode(void)
-{
-
-	apic_ops.xapic_mode();
-}
-
-static inline bool
-lapic_is_x2apic(void)
-{
-
-	return (apic_ops.is_x2apic());
-}
-
-static inline void
-lapic_setup(int boot)
-{
-
-	apic_ops.setup(boot);
-}
-
-static inline void
-lapic_dump(const char *str)
-{
-
-	apic_ops.dump(str);
-}
-
-static inline void
-lapic_disable(void)
-{
-
-	apic_ops.disable();
-}
-
-static inline void
-lapic_eoi(void)
-{
-
-	apic_ops.eoi();
-}
-
-static inline int
-lapic_id(void)
-{
-
-	return (apic_ops.id());
-}
-
-static inline int
-lapic_intr_pending(u_int vector)
-{
-
-	return (apic_ops.intr_pending(vector));
-}
-
+void	lapic_create(u_int apic_id, int boot_cpu);
+void	lapic_init(vm_paddr_t addr);
+void	lapic_xapic_mode(void);
+bool	lapic_is_x2apic(void);
+void	lapic_setup(int boot);
+void	lapic_dump(const char *str);
+void	lapic_disable(void);
+void	lapic_eoi(void);
+int	lapic_id(void);
+int	lapic_intr_pending(u_int vector);
 /* XXX: UNUSED */
-static inline void
-lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id)
-{
-
-	apic_ops.set_logical_id(apic_id, cluster, cluster_id);
-}
-
-static inline u_int
-apic_cpuid(u_int apic_id)
-{
-
-	return (apic_ops.cpuid(apic_id));
-}
-
-static inline u_int
-apic_alloc_vector(u_int apic_id, u_int irq)
-{
-
-	return (apic_ops.alloc_vector(apic_id, irq));
-}
-
-static inline u_int
-apic_alloc_vectors(u_int apic_id, u_int *irqs, u_int count, u_int align)
-{
-
-	return (apic_ops.alloc_vectors(apic_id, irqs, count, align));
-}
-
-static inline void
-apic_enable_vector(u_int apic_id, u_int vector)
-{
-
-	apic_ops.enable_vector(apic_id, vector);
-}
-
-static inline void
-apic_disable_vector(u_int apic_id, u_int vector)
-{
-
-	apic_ops.disable_vector(apic_id, vector);
-}
-
-static inline void
-apic_free_vector(u_int apic_id, u_int vector, u_int irq)
-{
-
-	apic_ops.free_vector(apic_id, vector, irq);
-}
-
-static inline void
-lapic_calibrate_timer(void)
-{
-
-	apic_ops.calibrate_timer();
-}
-
-static inline int
-lapic_enable_pmc(void)
-{
-
-	return (apic_ops.enable_pmc());
-}
-
-static inline void
-lapic_disable_pmc(void)
-{
-
-	apic_ops.disable_pmc();
-}
-
-static inline void
-lapic_reenable_pmc(void)
-{
-
-	apic_ops.reenable_pmc();
-}
-
-static inline void
-lapic_enable_cmc(void)
-{
-
-	apic_ops.enable_cmc();
-}
-
-static inline int
-lapic_enable_mca_elvt(void)
-{
-
-	return (apic_ops.enable_mca_elvt());
-}
-
-static inline void
-lapic_ipi_raw(register_t icrlo, u_int dest)
-{
-
-	apic_ops.ipi_raw(icrlo, dest);
-}
+void	lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id);
+u_int	apic_cpuid(u_int apic_id);
+u_int	apic_alloc_vector(u_int apic_id, u_int irq);
+u_int	apic_alloc_vectors(u_int apic_id, u_int *irqs, u_int count, u_int align);
+void	apic_enable_vector(u_int apic_id, u_int vector);
+void	apic_disable_vector(u_int apic_id, u_int vector);
+void	apic_free_vector(u_int apic_id, u_int vector, u_int irq);
+void	lapic_calibrate_timer(void);
+int	lapic_enable_pmc(void);
+void	lapic_disable_pmc(void);
+void	lapic_reenable_pmc(void);
+void	lapic_enable_cmc(void);
+int	lapic_enable_mca_elvt(void);
+void	lapic_ipi_raw(register_t icrlo, u_int dest);
 
 static inline void
 lapic_ipi_vectored(u_int vector, int dest)
 {
 
-	apic_ops.ipi_vectored(vector, dest);
-}
-
-static inline int
-lapic_ipi_wait(int delay)
-{
-
-	return (apic_ops.ipi_wait(delay));
-}
-
-static inline int
-lapic_ipi_alloc(inthand_t *ipifunc)
-{
-
-	return (apic_ops.ipi_alloc(ipifunc));
-}
-
-static inline void
-lapic_ipi_free(int vector)
-{
-
-	return (apic_ops.ipi_free(vector));
-}
-
-static inline int
-lapic_set_lvt_mask(u_int apic_id, u_int lvt, u_char masked)
-{
-
-	return (apic_ops.set_lvt_mask(apic_id, lvt, masked));
-}
-
-static inline int
-lapic_set_lvt_mode(u_int apic_id, u_int lvt, u_int32_t mode)
-{
-
-	return (apic_ops.set_lvt_mode(apic_id, lvt, mode));
-}
-
-static inline int
-lapic_set_lvt_polarity(u_int apic_id, u_int lvt, enum intr_polarity pol)
-{
-
-	return (apic_ops.set_lvt_polarity(apic_id, lvt, pol));
-}
-
-static inline int
-lapic_set_lvt_triggermode(u_int apic_id, u_int lvt, enum intr_trigger trigger)
-{
-
-	return (apic_ops.set_lvt_triggermode(apic_id, lvt, trigger));
+	ipi_vectored(vector, dest);
 }
 
+int	lapic_ipi_wait(int delay);
+int	lapic_ipi_alloc(inthand_t *ipifunc);
+void	lapic_ipi_free(int vector);
+int	lapic_set_lvt_mask(u_int apic_id, u_int lvt, u_char masked);
+int	lapic_set_lvt_mode(u_int apic_id, u_int lvt, u_int32_t mode);
+int	lapic_set_lvt_polarity(u_int apic_id, u_int lvt,
+	    enum intr_polarity pol);
+int	lapic_set_lvt_triggermode(u_int apic_id, u_int lvt,
+	    enum intr_trigger trigger);
 void	lapic_handle_cmc(void);
 void	lapic_handle_error(void);
 void	lapic_handle_intr(int vector, struct trapframe *frame);
diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c
index 7be603c71146..8e3c7eb27078 100644
--- a/sys/x86/x86/local_apic.c
+++ b/sys/x86/x86/local_apic.c
@@ -319,7 +319,7 @@ lapic_write_self_ipi(uint32_t vector)
 #endif /* SMP */
 
 static void
-native_lapic_enable_x2apic(void)
+lapic_enable_x2apic(void)
 {
 	uint64_t apic_base;
 
@@ -328,8 +328,8 @@ native_lapic_enable_x2apic(void)
 	wrmsr(MSR_APICBASE, apic_base);
 }
 
-static bool
-native_lapic_is_x2apic(void)
+bool
+lapic_is_x2apic(void)
 {
 	uint64_t apic_base;
 
@@ -355,84 +355,6 @@ static void	lapic_set_tpr(u_int vector);
 
 struct pic lapic_pic = { .pic_resume = lapic_resume };
 
-/* Forward declarations for apic_ops */
-static void	native_lapic_create(u_int apic_id, int boot_cpu);
-static void	native_lapic_init(vm_paddr_t addr);
-static void	native_lapic_xapic_mode(void);
-static void	native_lapic_setup(int boot);
-static void	native_lapic_dump(const char *str);
-static void	native_lapic_disable(void);
-static void	native_lapic_eoi(void);
-static int	native_lapic_id(void);
-static int	native_lapic_intr_pending(u_int vector);
-static u_int	native_apic_cpuid(u_int apic_id);
-static u_int	native_apic_alloc_vector(u_int apic_id, u_int irq);
-static u_int	native_apic_alloc_vectors(u_int apic_id, u_int *irqs,
-		    u_int count, u_int align);
-static void 	native_apic_disable_vector(u_int apic_id, u_int vector);
-static void 	native_apic_enable_vector(u_int apic_id, u_int vector);
-static void 	native_apic_free_vector(u_int apic_id, u_int vector, u_int irq);
-static void 	native_lapic_set_logical_id(u_int apic_id, u_int cluster,
-		    u_int cluster_id);
-static void	native_lapic_calibrate_timer(void);
-static int 	native_lapic_enable_pmc(void);
-static void 	native_lapic_disable_pmc(void);
-static void 	native_lapic_reenable_pmc(void);
-static void 	native_lapic_enable_cmc(void);
-static int 	native_lapic_enable_mca_elvt(void);
-static int 	native_lapic_set_lvt_mask(u_int apic_id, u_int lvt,
-		    u_char masked);
-static int 	native_lapic_set_lvt_mode(u_int apic_id, u_int lvt,
-		    uint32_t mode);
-static int 	native_lapic_set_lvt_polarity(u_int apic_id, u_int lvt,
-		    enum intr_polarity pol);
-static int 	native_lapic_set_lvt_triggermode(u_int apic_id, u_int lvt,
-		    enum intr_trigger trigger);
-#ifdef SMP
-static void 	native_lapic_ipi_raw(register_t icrlo, u_int dest);
-static void 	native_lapic_ipi_vectored(u_int vector, int dest);
-static int 	native_lapic_ipi_wait(int delay);
-#endif /* SMP */
-static int	native_lapic_ipi_alloc(inthand_t *ipifunc);
-static void	native_lapic_ipi_free(int vector);
-
-struct apic_ops apic_ops = {
-	.create			= native_lapic_create,
-	.init			= native_lapic_init,
-	.xapic_mode		= native_lapic_xapic_mode,
-	.is_x2apic		= native_lapic_is_x2apic,
-	.setup			= native_lapic_setup,
-	.dump			= native_lapic_dump,
-	.disable		= native_lapic_disable,
-	.eoi			= native_lapic_eoi,
-	.id			= native_lapic_id,
-	.intr_pending		= native_lapic_intr_pending,
-	.set_logical_id		= native_lapic_set_logical_id,
-	.cpuid			= native_apic_cpuid,
-	.alloc_vector		= native_apic_alloc_vector,
-	.alloc_vectors		= native_apic_alloc_vectors,
-	.enable_vector		= native_apic_enable_vector,
-	.disable_vector		= native_apic_disable_vector,
-	.free_vector		= native_apic_free_vector,
-	.calibrate_timer	= native_lapic_calibrate_timer,
-	.enable_pmc		= native_lapic_enable_pmc,
-	.disable_pmc		= native_lapic_disable_pmc,
-	.reenable_pmc		= native_lapic_reenable_pmc,
-	.enable_cmc		= native_lapic_enable_cmc,
-	.enable_mca_elvt	= native_lapic_enable_mca_elvt,
-#ifdef SMP
-	.ipi_raw		= native_lapic_ipi_raw,
-	.ipi_vectored		= native_lapic_ipi_vectored,
-	.ipi_wait		= native_lapic_ipi_wait,
-#endif
-	.ipi_alloc		= native_lapic_ipi_alloc,
-	.ipi_free		= native_lapic_ipi_free,
-	.set_lvt_mask		= native_lapic_set_lvt_mask,
-	.set_lvt_mode		= native_lapic_set_lvt_mode,
-	.set_lvt_polarity	= native_lapic_set_lvt_polarity,
-	.set_lvt_triggermode	= native_lapic_set_lvt_triggermode,
-};
-
 static uint32_t
 lvt_mode_impl(struct lapic *la, struct lvt *lvt, u_int pin, uint32_t value)
 {
@@ -502,8 +424,8 @@ elvt_mode(struct lapic *la, u_int idx, uint32_t value)
 /*
  * Map the local APIC and setup necessary interrupt vectors.
  */
-static void
-native_lapic_init(vm_paddr_t addr)
+void
+lapic_init(vm_paddr_t addr)
 {
 #ifdef SMP
 	uint64_t r, r1, r2, rx;
@@ -526,7 +448,7 @@ native_lapic_init(vm_paddr_t addr)
 	lapic_paddr = addr;
 	lapic_map = pmap_mapdev(addr, PAGE_SIZE);
 	if (x2apic_mode) {
-		native_lapic_enable_x2apic();
+		lapic_enable_x2apic();
 		lapic_map = NULL;
 	}
 
@@ -614,7 +536,7 @@ native_lapic_init(vm_paddr_t addr)
 	 * Calibrate the busy loop waiting for IPI ack in xAPIC mode.
 	 * lapic_ipi_wait_mult contains the number of iterations which
 	 * approximately delay execution for 1 microsecond (the
-	 * argument to native_lapic_ipi_wait() is in microseconds).
+	 * argument to lapic_ipi_wait() is in microseconds).
 	 *
 	 * We assume that TSC is present and already measured.
 	 * Possible TSC frequency jumps are irrelevant to the
@@ -646,8 +568,8 @@ native_lapic_init(vm_paddr_t addr)
 /*
  * Create a local APIC instance.
  */
-static void
-native_lapic_create(u_int apic_id, int boot_cpu)
+void
+lapic_create(u_int apic_id, int boot_cpu)
 {
 	int i;
 
@@ -722,8 +644,8 @@ amd_read_elvt_count(void)
 /*
  * Dump contents of local APIC registers
  */
-static void
-native_lapic_dump(const char* str)
+void
+lapic_dump(const char* str)
 {
 	uint32_t version;
 	uint32_t maxlvt;
@@ -761,19 +683,19 @@ native_lapic_dump(const char* str)
 	}
 }
 
-static void
-native_lapic_xapic_mode(void)
+void
+lapic_xapic_mode(void)
 {
 	register_t saveintr;
 
 	saveintr = intr_disable();
 	if (x2apic_mode)
-		native_lapic_enable_x2apic();
+		lapic_enable_x2apic();
 	intr_restore(saveintr);
 }
 
-static void
-native_lapic_setup(int boot)
+void
+lapic_setup(int boot)
 {
 	struct lapic *la;
 	uint32_t version;
@@ -863,7 +785,7 @@ native_lapic_setup(int boot)
 }
 
 static void
-native_lapic_intrcnt(void *dummy __unused)
+lapic_intrcnt(void *dummy __unused)
 {
 	struct pcpu *pc;
 	struct lapic *la;
@@ -882,11 +804,10 @@ native_lapic_intrcnt(void *dummy __unused)
 		intrcnt_add(buf, &la->la_timer_count);
 	}
 }
-SYSINIT(native_lapic_intrcnt, SI_SUB_INTR, SI_ORDER_MIDDLE, native_lapic_intrcnt,
-    NULL);
+SYSINIT(lapic_intrcnt, SI_SUB_INTR, SI_ORDER_MIDDLE, lapic_intrcnt, NULL);
 
-static void
-native_lapic_reenable_pmc(void)
+void
+lapic_reenable_pmc(void)
 {
 #ifdef HWPMC_HOOKS
 	uint32_t value;
@@ -909,8 +830,8 @@ lapic_update_pmc(void *dummy)
 }
 #endif
 
-static void
-native_lapic_calibrate_timer(void)
+void
+lapic_calibrate_timer(void)
 {
 	struct lapic *la;
 	register_t intr;
@@ -934,8 +855,8 @@ native_lapic_calibrate_timer(void)
 	}
 }
 
-static int
-native_lapic_enable_pmc(void)
+int
+lapic_enable_pmc(void)
 {
 #ifdef HWPMC_HOOKS
 	u_int32_t maxlvt;
@@ -975,8 +896,8 @@ native_lapic_enable_pmc(void)
 #endif
 }
 
-static void
-native_lapic_disable_pmc(void)
+void
+lapic_disable_pmc(void)
 {
 #ifdef HWPMC_HOOKS
 	u_int32_t maxlvt;
@@ -1131,8 +1052,8 @@ lapic_et_stop(struct eventtimer *et)
 	return (0);
 }
 
-static void
-native_lapic_disable(void)
+void
+lapic_disable(void)
 {
 	uint32_t value;
 
@@ -1164,8 +1085,8 @@ lapic_resume(struct pic *pic, bool suspend_cancelled)
 	lapic_setup(0);
 }
 
-static int
-native_lapic_id(void)
+int
+lapic_id(void)
 {
 	uint32_t v;
 
@@ -1176,8 +1097,8 @@ native_lapic_id(void)
 	return (v);
 }
 
-static int
-native_lapic_intr_pending(u_int vector)
+int
+lapic_intr_pending(u_int vector)
 {
 	uint32_t irr;
 
@@ -1192,8 +1113,8 @@ native_lapic_intr_pending(u_int vector)
 	return (irr & 1 << (vector % 32));
 }
 
-static void
-native_lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id)
+void
+lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id)
 {
 	struct lapic *la;
 
@@ -1208,8 +1129,8 @@ native_lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id)
 	la->la_cluster_id = cluster_id;
 }
 
-static int
-native_lapic_set_lvt_mask(u_int apic_id, u_int pin, u_char masked)
+int
+lapic_set_lvt_mask(u_int apic_id, u_int pin, u_char masked)
 {
 
 	if (pin > APIC_LVT_MAX)
@@ -1231,8 +1152,8 @@ native_lapic_set_lvt_mask(u_int apic_id, u_int pin, u_char masked)
 	return (0);
 }
 
-static int
-native_lapic_set_lvt_mode(u_int apic_id, u_int pin, u_int32_t mode)
+int
+lapic_set_lvt_mode(u_int apic_id, u_int pin, u_int32_t mode)
 {
 	struct lvt *lvt;
 
@@ -1287,8 +1208,8 @@ native_lapic_set_lvt_mode(u_int apic_id, u_int pin, u_int32_t mode)
 	return (0);
 }
 
-static int
-native_lapic_set_lvt_polarity(u_int apic_id, u_int pin, enum intr_polarity pol)
+int
+lapic_set_lvt_polarity(u_int apic_id, u_int pin, enum intr_polarity pol)
 {
 
 	if (pin > APIC_LVT_MAX || pol == INTR_POLARITY_CONFORM)
@@ -1312,8 +1233,8 @@ native_lapic_set_lvt_polarity(u_int apic_id, u_int pin, enum intr_polarity pol)
 	return (0);
 }
 
-static int
-native_lapic_set_lvt_triggermode(u_int apic_id, u_int pin,
+int
+lapic_set_lvt_triggermode(u_int apic_id, u_int pin,
      enum intr_trigger trigger)
 {
 
@@ -1356,8 +1277,8 @@ lapic_set_tpr(u_int vector)
 #endif
 }
 
-static void
-native_lapic_eoi(void)
+void
+lapic_eoi(void)
 {
 
 	lapic_write32_nofence(LAPIC_EOI, 0);
@@ -1519,8 +1440,8 @@ lapic_handle_cmc(void)
  * is called prior to lapic_setup() during boot, this just needs to unmask
  * this CPU's LVT_CMCI entry.
  */
-static void
-native_lapic_enable_cmc(void)
+void
+lapic_enable_cmc(void)
 {
 	u_int apic_id;
 
@@ -1535,8 +1456,8 @@ native_lapic_enable_cmc(void)
 	lapics[apic_id].la_lvts[APIC_LVT_CMCI].lvt_active = 1;
 }
 
-static int
-native_lapic_enable_mca_elvt(void)
+int
+lapic_enable_mca_elvt(void)
 {
 	u_int apic_id;
 	uint32_t value;
@@ -1583,8 +1504,8 @@ lapic_handle_error(void)
 	lapic_eoi();
 }
 
-static u_int
-native_apic_cpuid(u_int apic_id)
+u_int
+apic_cpuid(u_int apic_id)
 {
 #ifdef SMP
 	return apic_cpuids[apic_id];
@@ -1594,8 +1515,8 @@ native_apic_cpuid(u_int apic_id)
 }
 
 /* Request a free IDT vector to be used by the specified IRQ. */
-static u_int
-native_apic_alloc_vector(u_int apic_id, u_int irq)
+u_int
+apic_alloc_vector(u_int apic_id, u_int irq)
 {
 	u_int vector;
 
@@ -1623,8 +1544,8 @@ native_apic_alloc_vector(u_int apic_id, u_int irq)
  * aligned on a boundary of 'align'.  If the request cannot be
  * satisfied, 0 is returned.
  */
-static u_int
-native_apic_alloc_vectors(u_int apic_id, u_int *irqs, u_int count, u_int align)
+u_int
+apic_alloc_vectors(u_int apic_id, u_int *irqs, u_int count, u_int align)
 {
 	u_int first, run, vector;
 
@@ -1682,8 +1603,8 @@ native_apic_alloc_vectors(u_int apic_id, u_int *irqs, u_int count, u_int align)
  * which do not have the vector configured would report spurious interrupts
  * should it fire.
  */
-static void
-native_apic_enable_vector(u_int apic_id, u_int vector)
+void
+apic_enable_vector(u_int apic_id, u_int vector)
 {
 
 	KASSERT(vector != IDT_SYSCALL, ("Attempt to overwrite syscall entry"));
@@ -1697,8 +1618,8 @@ native_apic_enable_vector(u_int apic_id, u_int vector)
 	    SDT_APIC, SEL_KPL, GSEL_APIC);
 }
 
-static void
-native_apic_disable_vector(u_int apic_id, u_int vector)
+void
+apic_disable_vector(u_int apic_id, u_int vector)
 {
 
 	KASSERT(vector != IDT_SYSCALL, ("Attempt to overwrite syscall entry"));
@@ -1719,8 +1640,8 @@ native_apic_disable_vector(u_int apic_id, u_int vector)
 }
 
 /* Release an APIC vector when it's no longer in use. */
-static void
-native_apic_free_vector(u_int apic_id, u_int vector, u_int irq)
+void
+apic_free_vector(u_int apic_id, u_int vector, u_int irq)
 {
 	struct thread *td;
 
@@ -2057,8 +1978,8 @@ SYSINIT(apic_setup_io, SI_SUB_INTR, SI_ORDER_THIRD, apic_setup_io, NULL);
  * Wait delay microseconds for IPI to be sent.  If delay is -1, we
  * wait forever.
  */
-static int
-native_lapic_ipi_wait(int delay)
+int
+lapic_ipi_wait(int delay)
 {
 	uint64_t rx;
 
@@ -2075,8 +1996,8 @@ native_lapic_ipi_wait(int delay)
 	return (0);
 }
 
-static void
-native_lapic_ipi_raw(register_t icrlo, u_int dest)
+void
+lapic_ipi_raw(register_t icrlo, u_int dest)
 {
 	uint32_t icrhi;
 
@@ -2184,6 +2105,7 @@ native_lapic_ipi_vectored(u_int vector, int dest)
 #endif /* DETECT_DEADLOCK */
 }
 
+void (*ipi_vectored)(u_int, int) = &native_lapic_ipi_vectored;
 #endif /* SMP */
 
 /*
@@ -2199,8 +2121,8 @@ native_lapic_ipi_vectored(u_int vector, int dest)
  * explicit 'mfence' before the ICR MSR is written. Therefore in both cases
  * the IDT slot update is globally visible before the IPI is delivered.
  */
-static int
-native_lapic_ipi_alloc(inthand_t *ipifunc)
+int
+lapic_ipi_alloc(inthand_t *ipifunc)
 {
 	struct gate_descriptor *ip;
 	long func;
@@ -2228,8 +2150,8 @@ native_lapic_ipi_alloc(inthand_t *ipifunc)
 	return (vector);
 }
 
-static void
-native_lapic_ipi_free(int vector)
+void
+lapic_ipi_free(int vector)
 {
 	struct gate_descriptor *ip;
 	long func __diagused;
diff --git a/sys/x86/xen/xen_apic.c b/sys/x86/xen/xen_apic.c
index c268e747f44a..77268d5f9846 100644
--- a/sys/x86/xen/xen_apic.c
+++ b/sys/x86/xen/xen_apic.c
@@ -57,13 +57,7 @@ __FBSDID("$FreeBSD$");
 #include <xen/interface/arch-x86/cpuid.h>
 #include <xen/interface/vcpu.h>
 
-/*--------------------------------- Macros -----------------------------------*/
-
-#define XEN_APIC_UNSUPPORTED \
-	panic("%s: not available in Xen PV port.", __func__)
-
 /*--------------------------- Forward Declarations ---------------------------*/
-#ifdef SMP
 static driver_filter_t xen_smp_rendezvous_action;
 #ifdef __amd64__
 static driver_filter_t xen_invlop;
@@ -77,13 +71,11 @@ 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_ipi_swi_handler;
-#endif
 
 /*---------------------------------- Macros ----------------------------------*/
 #define	IPI_TO_IDX(ipi) ((ipi) - APIC_IPI_INTS)
 
 /*--------------------------------- Xen IPIs ---------------------------------*/
-#ifdef SMP
 struct xen_ipi_handler
 {
 	driver_filter_t	*filter;
@@ -106,7 +98,6 @@ static struct xen_ipi_handler xen_ipis[] =
 	[IPI_TO_IDX(IPI_SUSPEND)]	= { xen_cpususpend_handler,	"sp"  },
 	[IPI_TO_IDX(IPI_SWI)]		= { xen_ipi_swi_handler,	"sw"  },
 };
-#endif
 
 /*
  * Save previous (native) handler as a fallback. Xen < 4.7 doesn't support
@@ -117,170 +108,10 @@ static struct xen_ipi_handler xen_ipis[] =
 void (*native_ipi_vectored)(u_int, int);
 
 /*------------------------------- Per-CPU Data -------------------------------*/
-#ifdef SMP
 DPCPU_DEFINE(xen_intr_handle_t, ipi_handle[nitems(xen_ipis)]);
-#endif
 
 /*------------------------------- Xen PV APIC --------------------------------*/
 
-static void
-xen_pv_lapic_create(u_int apic_id, int boot_cpu)
-{
-#ifdef SMP
-	cpu_add(apic_id, boot_cpu);
-#endif
-}
-
-static void
-xen_pv_lapic_init(vm_paddr_t addr)
-{
-
-}
-
-static void
-xen_pv_lapic_setup(int boot)
-{
-
-}
-
-static void
-xen_pv_lapic_dump(const char *str)
-{
-
-	printf("cpu%d %s XEN PV LAPIC\n", PCPU_GET(cpuid), str);
-}
-
-static void
-xen_pv_lapic_disable(void)
-{
-
-}
-
-static bool
-xen_pv_lapic_is_x2apic(void)
-{
-
-	return (false);
-}
-
-static void
-xen_pv_lapic_eoi(void)
-{
-
-	XEN_APIC_UNSUPPORTED;
-}
-
-static int
-xen_pv_lapic_id(void)
-{
-
-	return (PCPU_GET(apic_id));
-}
-
-static int
-xen_pv_lapic_intr_pending(u_int vector)
-{
-
-	XEN_APIC_UNSUPPORTED;
-	return (0);
-}
-
-static u_int
-xen_pv_apic_cpuid(u_int apic_id)
-{
-#ifdef SMP
-	return (apic_cpuids[apic_id]);
-#else
-	return (0);
-#endif
-}
-
-static u_int
-xen_pv_apic_alloc_vector(u_int apic_id, u_int irq)
-{
-
-	XEN_APIC_UNSUPPORTED;
-	return (0);
-}
*** 197 LINES SKIPPED ***