Page MenuHomeFreeBSD

D30909.id.diff
No OneTemporary

D30909.id.diff

diff --git a/sys/dev/xen/bus/intr-internal.h b/sys/dev/xen/bus/intr-internal.h
--- a/sys/dev/xen/bus/intr-internal.h
+++ b/sys/dev/xen/bus/intr-internal.h
@@ -60,4 +60,34 @@
volatile u_int xi_refcount;
};
+/***************** Functions called by the architecture code *****************/
+
+extern void xen_intr_resume(void);
+extern void xen_intr_enable_source(struct xenisrc *isrc);
+extern void xen_intr_disable_source(struct xenisrc *isrc);
+extern void xen_intr_enable_intr(struct xenisrc *isrc);
+extern void xen_intr_disable_intr(struct xenisrc *isrc);
+extern int xen_intr_assign_cpu(struct xenisrc *isrc, u_int to_cpu);
+
+/******************* Functions implemented by each architecture **************/
+
+#if 0
+/*
+ * These are sample prototypes, the architecture should include its own in
+ * <machine/xen/arch-intr.h>. The architecture may implement these as inline.
+ */
+void xen_arch_intr_init(void);
+u_long xen_arch_intr_execute_handlers(struct xenisrc *isrc,
+ struct trapframe *frame);
+int xen_arch_intr_add_handler(const char *name,
+ driver_filter_t filter, driver_intr_t handler, void *arg,
+ enum intr_type flags, struct xenisrc *isrc,
+ void **cookiep);
+int xen_arch_intr_describe(struct xenisrc *isrc, void *cookie,
+ const char *descr);
+int xen_arch_intr_remove_handler(struct xenisrc *isrc,
+ void *cookie);
+int xen_arch_intr_event_bind(struct xenisrc *isrc, u_int cpu);
+#endif
+
#endif /* _XEN_INTR_INTERNAL_H_ */
diff --git a/sys/x86/include/xen/arch-intr.h b/sys/x86/include/xen/arch-intr.h
--- a/sys/x86/include/xen/arch-intr.h
+++ b/sys/x86/include/xen/arch-intr.h
@@ -36,6 +36,51 @@
u_int vector; /* Global isrc vector number */
} xen_arch_isrc_t;
+extern struct pic xen_intr_pic;
+
#include <dev/xen/bus/intr-internal.h>
+/******************************* ARCH wrappers *******************************/
+
+extern void xen_arch_intr_init(void);
+
+static inline u_long
+xen_arch_intr_execute_handlers(struct xenisrc *isrc, struct trapframe *frame)
+{
+
+ intr_execute_handlers(&isrc->xi_arch.intsrc, frame);
+ return (0);
+}
+
+static inline int
+xen_arch_intr_add_handler(const char *name, driver_filter_t filter,
+ driver_intr_t handler, void *arg, enum intr_type flags,
+ struct xenisrc *isrc, void **cookiep)
+{
+
+ return (intr_add_handler(name, isrc->xi_arch.vector, filter, handler,
+ arg, flags, cookiep, 0));
+}
+
+static inline int
+xen_arch_intr_describe(struct xenisrc *isrc, void *cookie, const char *descr)
+{
+
+ return (intr_describe(isrc->xi_arch.vector, cookie, descr));
+}
+
+static inline int
+xen_arch_intr_remove_handler(struct xenisrc *isrc, void *cookie)
+{
+
+ return (intr_remove_handler(cookie));
+}
+
+static inline int
+xen_arch_intr_event_bind(struct xenisrc *isrc, u_int cpu)
+{
+
+ return (intr_event_bind(isrc->xi_arch.intsrc.is_event, cpu));
+}
+
#endif /* _MACHINE__XEN_ARCH_INTR_H_ */
diff --git a/sys/x86/xen/xen_arch_intr.c b/sys/x86/xen/xen_arch_intr.c
--- a/sys/x86/xen/xen_arch_intr.c
+++ b/sys/x86/xen/xen_arch_intr.c
@@ -1,6 +1,7 @@
/*-
* SPDX-License-Identifier: MIT OR GPL-2.0-only
*
+ * Copyright © 2015 Julien Grall
* Copyright © 2013 Spectra Logic Corporation
* Copyright © 2018 John Baldwin/The FreeBSD Foundation
* Copyright © 2019 Roger Pau Monné/Citrix Systems R&D
@@ -32,8 +33,14 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/bus.h>
+#include <sys/malloc.h>
#include <sys/kernel.h>
+#include <sys/limits.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/interrupt.h>
#include <sys/pcpu.h>
#include <sys/proc.h>
#include <sys/smp.h>
@@ -41,8 +48,8 @@
#include <xen/xen-os.h>
#include <xen/xen_intr.h>
+#include <machine/xen/arch-intr.h>
-#include <x86/intr_machdep.h>
#include <x86/apicvar.h>
/************************ Xen x86 interrupt interface ************************/
@@ -101,3 +108,165 @@
critical_exit();
}
+
+/******************************** EVTCHN PIC *********************************/
+
+static void
+xen_intr_pic_enable_source(struct intsrc *isrc)
+{
+
+ _Static_assert(offsetof(struct xenisrc, xi_arch.intsrc) == 0,
+ "xi_arch MUST be at top of xenisrc for x86");
+ xen_intr_enable_source((struct xenisrc *)isrc);
+}
+
+/*
+ * Perform any necessary end-of-interrupt acknowledgements.
+ *
+ * \param isrc The interrupt source to EOI.
+ */
+static void
+xen_intr_pic_disable_source(struct intsrc *isrc, int eoi)
+{
+
+ _Static_assert(offsetof(struct xenisrc, xi_arch.intsrc) == 0,
+ "xi_arch MUST be at top of xenisrc for x86");
+ xen_intr_disable_source((struct xenisrc *)isrc);
+}
+
+static void
+xen_intr_pic_eoi_source(struct intsrc *isrc)
+{
+
+ /* Nothing to do on end-of-interrupt */
+}
+
+static void
+xen_intr_pic_enable_intr(struct intsrc *isrc)
+{
+
+ _Static_assert(offsetof(struct xenisrc, xi_arch.intsrc) == 0,
+ "xi_arch MUST be at top of xenisrc for x86");
+ xen_intr_enable_intr((struct xenisrc *)isrc);
+}
+
+static void
+xen_intr_pic_disable_intr(struct intsrc *isrc)
+{
+
+ _Static_assert(offsetof(struct xenisrc, xi_arch.intsrc) == 0,
+ "xi_arch MUST be at top of xenisrc for x86");
+ xen_intr_disable_intr((struct xenisrc *)isrc);
+}
+
+/**
+ * Determine the global interrupt vector number for
+ * a Xen interrupt source.
+ *
+ * \param isrc The interrupt source to query.
+ *
+ * \return The vector number corresponding to the given interrupt source.
+ */
+static int
+xen_intr_pic_vector(struct intsrc *isrc)
+{
+
+ _Static_assert(offsetof(struct xenisrc, xi_arch.intsrc) == 0,
+ "xi_arch MUST be at top of xenisrc for x86");
+
+ return (((struct xenisrc *)isrc)->xi_arch.vector);
+}
+
+/**
+ * Determine whether or not interrupt events are pending on the
+ * the given interrupt source.
+ *
+ * \param isrc The interrupt source to query.
+ *
+ * \returns 0 if no events are pending, otherwise non-zero.
+ */
+static int
+xen_intr_pic_source_pending(struct intsrc *isrc)
+{
+ /*
+ * EventChannels are edge triggered and never masked.
+ * There can be no pending events.
+ */
+ return (0);
+}
+
+/**
+ * Prepare this PIC for system suspension.
+ */
+static void
+xen_intr_pic_suspend(struct pic *pic)
+{
+
+ /* Nothing to do on suspend */
+}
+
+static void
+xen_intr_pic_resume(struct pic *pic, bool suspend_cancelled)
+{
+
+ if (!suspend_cancelled)
+ xen_intr_resume();
+}
+
+/**
+ * Perform configuration of an interrupt source.
+ *
+ * \param isrc The interrupt source to configure.
+ * \param trig Edge or level.
+ * \param pol Active high or low.
+ *
+ * \returns 0 if no events are pending, otherwise non-zero.
+ */
+static int
+xen_intr_pic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
+ enum intr_polarity pol)
+{
+ /* Configuration is only possible via the evtchn apis. */
+ return (ENODEV);
+}
+
+
+static int
+xen_intr_pic_assign_cpu(struct intsrc *isrc, u_int apic_id)
+{
+
+ _Static_assert(offsetof(struct xenisrc, xi_arch.intsrc) == 0,
+ "xi_arch MUST be at top of xenisrc for x86");
+ return (xen_intr_assign_cpu((struct xenisrc *)isrc,
+ apic_cpuid(apic_id)));
+}
+
+/**
+ * PIC interface for all event channel port types except physical IRQs.
+ */
+struct pic xen_intr_pic = {
+ .pic_enable_source = xen_intr_pic_enable_source,
+ .pic_disable_source = xen_intr_pic_disable_source,
+ .pic_eoi_source = xen_intr_pic_eoi_source,
+ .pic_enable_intr = xen_intr_pic_enable_intr,
+ .pic_disable_intr = xen_intr_pic_disable_intr,
+ .pic_vector = xen_intr_pic_vector,
+ .pic_source_pending = xen_intr_pic_source_pending,
+ .pic_suspend = xen_intr_pic_suspend,
+ .pic_resume = xen_intr_pic_resume,
+ .pic_config_intr = xen_intr_pic_config_intr,
+ .pic_assign_cpu = xen_intr_pic_assign_cpu,
+};
+
+/******************************* ARCH wrappers *******************************/
+
+void
+xen_arch_intr_init(void)
+{
+ int error;
+
+ error = intr_register_pic(&xen_intr_pic);
+ if (error != 0)
+ panic("%s(): failed registering Xen/x86 PIC, error=%d\n",
+ __func__, error);
+}
diff --git a/sys/x86/xen/xen_intr.c b/sys/x86/xen/xen_intr.c
--- a/sys/x86/xen/xen_intr.c
+++ b/sys/x86/xen/xen_intr.c
@@ -117,37 +117,6 @@
#define INVALID_EVTCHN (~(evtchn_port_t)0) /* Invalid event channel */
#define is_valid_evtchn(x) ((uintmax_t)(x) < NR_EVENT_CHANNELS)
-static void xen_intr_suspend(struct pic *);
-static void xen_intr_resume(struct pic *, bool suspend_cancelled);
-static void xen_intr_enable_source(struct intsrc *isrc);
-static void xen_intr_disable_source(struct intsrc *isrc, int eoi);
-static void xen_intr_eoi_source(struct intsrc *isrc);
-static void xen_intr_enable_intr(struct intsrc *isrc);
-static void xen_intr_disable_intr(struct intsrc *isrc);
-static int xen_intr_vector(struct intsrc *isrc);
-static int xen_intr_source_pending(struct intsrc *isrc);
-static int xen_intr_config_intr(struct intsrc *isrc,
- enum intr_trigger trig, enum intr_polarity pol);
-static int xen_intr_assign_cpu(struct intsrc *isrc, u_int to_cpu);
-static int xen_intr_pic_assign_cpu(struct intsrc *isrc, u_int apic_id);
-
-/**
- * PIC interface for all event channel port types except physical IRQs.
- */
-struct pic xen_intr_pic = {
- .pic_enable_source = xen_intr_enable_source,
- .pic_disable_source = xen_intr_disable_source,
- .pic_eoi_source = xen_intr_eoi_source,
- .pic_enable_intr = xen_intr_enable_intr,
- .pic_disable_intr = xen_intr_disable_intr,
- .pic_vector = xen_intr_vector,
- .pic_source_pending = xen_intr_source_pending,
- .pic_suspend = xen_intr_suspend,
- .pic_resume = xen_intr_resume,
- .pic_config_intr = xen_intr_config_intr,
- .pic_assign_cpu = xen_intr_pic_assign_cpu,
-};
-
/*
* Lock for interrupt core data.
*
@@ -413,8 +382,7 @@
* unless specified otherwise, so shuffle them to balance
* the interrupt load.
*/
- xen_intr_assign_cpu(&isrc->xi_arch.intsrc,
- apic_cpuid(intr_next_cpu(0)));
+ xen_intr_assign_cpu(isrc, apic_cpuid(intr_next_cpu(0)));
}
#endif
@@ -544,8 +512,7 @@
("Received unexpected event on vCPU#%u, event bound to vCPU#%u",
PCPU_GET(cpuid), isrc->xi_cpu));
- intr_execute_handlers(&isrc->xi_arch.intsrc,
- trap_frame);
+ xen_arch_intr_execute_handlers(isrc, trap_frame);
/*
* If this is the final port processed,
@@ -609,7 +576,7 @@
for (i = 0; i < nitems(s->evtchn_mask); i++)
atomic_store_rel_long(&s->evtchn_mask[i], ~0);
- intr_register_pic(&xen_intr_pic);
+ xen_arch_intr_init();
if (bootverbose)
printf("Xen interrupt system initialized\n");
@@ -629,13 +596,6 @@
}
/*--------------------------- Common PIC Functions ---------------------------*/
-/**
- * Prepare this PIC for system suspension.
- */
-static void
-xen_intr_suspend(struct pic *unused)
-{
-}
static void
xen_rebind_ipi(struct xenisrc *isrc)
@@ -699,7 +659,7 @@
#ifdef SMP
isrc->xi_cpu = 0;
- error = xen_intr_assign_cpu(&isrc->xi_arch.intsrc, cpu);
+ error = xen_intr_assign_cpu(isrc, cpu);
if (error)
panic("%s(): unable to rebind Xen channel %u to vCPU%u: %d",
__func__, isrc->xi_port, cpu, error);
@@ -713,16 +673,13 @@
/**
* Return this PIC to service after being suspended.
*/
-static void
-xen_intr_resume(struct pic *unused, bool suspend_cancelled)
+void
+xen_intr_resume(void)
{
shared_info_t *s = HYPERVISOR_shared_info;
u_int isrc_idx;
int i;
- if (suspend_cancelled)
- return;
-
/* Reset the per-CPU masks */
CPU_FOREACH(i) {
struct xen_intr_pcpu_data *pcpu;
@@ -767,65 +724,13 @@
*
* \param isrc The interrupt source to disable.
*/
-static void
-xen_intr_disable_intr(struct intsrc *base_isrc)
+void
+xen_intr_disable_intr(struct xenisrc *isrc)
{
- struct xenisrc *isrc = (struct xenisrc *)base_isrc;
evtchn_mask_port(isrc->xi_port);
}
-/**
- * Determine the global interrupt vector number for
- * a Xen interrupt source.
- *
- * \param isrc The interrupt source to query.
- *
- * \return The vector number corresponding to the given interrupt source.
- */
-static int
-xen_intr_vector(struct intsrc *base_isrc)
-{
- struct xenisrc *isrc = (struct xenisrc *)base_isrc;
-
- return (isrc->xi_arch.vector);
-}
-
-/**
- * Determine whether or not interrupt events are pending on the
- * the given interrupt source.
- *
- * \param isrc The interrupt source to query.
- *
- * \returns 0 if no events are pending, otherwise non-zero.
- */
-static int
-xen_intr_source_pending(struct intsrc *isrc)
-{
- /*
- * EventChannels are edge triggered and never masked.
- * There can be no pending events.
- */
- return (0);
-}
-
-/**
- * Perform configuration of an interrupt source.
- *
- * \param isrc The interrupt source to configure.
- * \param trig Edge or level.
- * \param pol Active high or low.
- *
- * \returns 0 if no events are pending, otherwise non-zero.
- */
-static int
-xen_intr_config_intr(struct intsrc *isrc, enum intr_trigger trig,
- enum intr_polarity pol)
-{
- /* Configuration is only possible via the evtchn apis. */
- return (ENODEV);
-}
-
/**
* Configure CPU affinity for interrupt source event delivery.
*
@@ -834,12 +739,11 @@
*
* \returns 0 if successful, otherwise an errno.
*/
-static int
-xen_intr_assign_cpu(struct intsrc *base_isrc, u_int to_cpu)
+int
+xen_intr_assign_cpu(struct xenisrc *isrc, u_int to_cpu)
{
#ifdef SMP
struct evtchn_bind_vcpu bind_vcpu;
- struct xenisrc *isrc;
u_int vcpu_id = XEN_CPUID_TO_VCPUID(to_cpu);
int error, masked;
@@ -847,7 +751,6 @@
return (EOPNOTSUPP);
mtx_lock(&xen_intr_isrc_lock);
- isrc = (struct xenisrc *)base_isrc;
if (!is_valid_evtchn(isrc->xi_port)) {
mtx_unlock(&xen_intr_isrc_lock);
return (EINVAL);
@@ -894,28 +797,15 @@
#endif
}
-/* Wrapper of xen_intr_assign_cpu to use as pic callbacks */
-static int
-xen_intr_pic_assign_cpu(struct intsrc *isrc, u_int apic_id)
-{
-
- return (xen_intr_assign_cpu(isrc, apic_cpuid(apic_id)));
-}
-
/*------------------- Virtual Interrupt Source PIC Functions -----------------*/
/*
* Mask a level triggered interrupt source.
*
* \param isrc The interrupt source to mask (if necessary).
- * \param eoi If non-zero, perform any necessary end-of-interrupt
- * acknowledgements.
*/
-static void
-xen_intr_disable_source(struct intsrc *base_isrc, int eoi)
+void
+xen_intr_disable_source(struct xenisrc *isrc)
{
- struct xenisrc *isrc;
-
- isrc = (struct xenisrc *)base_isrc;
/*
* NB: checking if the event channel is already masked is
@@ -933,36 +823,22 @@
*
* \param isrc The interrupt source to unmask (if necessary).
*/
-static void
-xen_intr_enable_source(struct intsrc *base_isrc)
+void
+xen_intr_enable_source(struct xenisrc *isrc)
{
- struct xenisrc *isrc;
-
- isrc = (struct xenisrc *)base_isrc;
if (isrc->xi_masked == 0)
evtchn_unmask_port(isrc->xi_port);
}
-/*
- * Perform any necessary end-of-interrupt acknowledgements.
- *
- * \param isrc The interrupt source to EOI.
- */
-static void
-xen_intr_eoi_source(struct intsrc *base_isrc)
-{
-}
-
/*
* Enable and unmask the interrupt source.
*
* \param isrc The interrupt source to enable.
*/
-static void
-xen_intr_enable_intr(struct intsrc *base_isrc)
+void
+xen_intr_enable_intr(struct xenisrc *isrc)
{
- struct xenisrc *isrc = (struct xenisrc *)base_isrc;
evtchn_unmask_port(isrc->xi_port);
}
@@ -1091,7 +967,7 @@
#ifdef SMP
if (error == 0)
- error = intr_event_bind(isrc->xi_arch.intsrc.is_event, cpu);
+ error = xen_arch_intr_event_bind(isrc, cpu);
#endif
if (error != 0) {
@@ -1111,7 +987,7 @@
* masks manually so events can't fire on the wrong cpu
* during AP startup.
*/
- xen_intr_assign_cpu(&isrc->xi_arch.intsrc, cpu);
+ xen_intr_assign_cpu(isrc, cpu);
}
#endif
@@ -1167,7 +1043,7 @@
* masks manually so events can't fire on the wrong cpu
* during AP startup.
*/
- xen_intr_assign_cpu(&isrc->xi_arch.intsrc, cpu);
+ xen_intr_assign_cpu(isrc, cpu);
}
/*
@@ -1195,7 +1071,7 @@
va_start(ap, fmt);
vsnprintf(descr, sizeof(descr), fmt, ap);
va_end(ap);
- return (intr_describe(isrc->xi_arch.vector, isrc->xi_cookie, descr));
+ return (xen_arch_intr_describe(isrc, isrc->xi_cookie, descr));
}
void
@@ -1219,7 +1095,7 @@
mtx_unlock(&xen_intr_isrc_lock);
if (isrc->xi_cookie != NULL)
- intr_remove_handler(isrc->xi_cookie);
+ xen_arch_intr_remove_handler(isrc, isrc->xi_cookie);
xen_intr_release_isrc(isrc);
}
@@ -1262,8 +1138,8 @@
if (isrc == NULL || isrc->xi_cookie != NULL)
return (EINVAL);
- error = intr_add_handler(name, isrc->xi_arch.vector, filter, handler,
- arg, flags|INTR_EXCL, &isrc->xi_cookie, 0);
+ error = xen_arch_intr_add_handler(name, filter, handler, arg,
+ flags | INTR_EXCL, isrc, &isrc->xi_cookie);
if (error != 0)
printf("%s: %s: add handler failed: %d\n", name, __func__,
error);

File Metadata

Mime Type
text/plain
Expires
Thu, Oct 23, 7:09 PM (3 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24099637
Default Alt Text
D30909.id.diff (16 KB)

Event Timeline