Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F133079750
D30909.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
16 KB
Referenced Files
None
Subscribers
None
D30909.id.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D30909: xen/intr: introduce xen_arch_intr.c
Attached
Detach File
Event Timeline
Log In to Comment