Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F106263715
D30006.id94623.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D30006.id94623.diff
View Options
Index: sys/amd64/amd64/apic_vector.S
===================================================================
--- sys/amd64/amd64/apic_vector.S
+++ sys/amd64/amd64/apic_vector.S
@@ -159,7 +159,7 @@
INTR_HANDLER xen_intr_upcall
KMSAN_ENTER
movq %rsp, %rdi
- call xen_intr_handle_upcall
+ call xen_arch_intr_handle_upcall
KMSAN_LEAVE
jmp doreti
#endif
Index: sys/i386/i386/apic_vector.s
===================================================================
--- sys/i386/i386/apic_vector.s
+++ sys/i386/i386/apic_vector.s
@@ -183,7 +183,7 @@
cld
KENTER
pushl %esp
- movl $xen_intr_handle_upcall, %eax
+ movl $xen_arch_intr_handle_upcall, %eax
call *%eax
add $4, %esp
jmp doreti
Index: sys/x86/xen/xen_arch_intr.c
===================================================================
--- sys/x86/xen/xen_arch_intr.c
+++ sys/x86/xen/xen_arch_intr.c
@@ -48,6 +48,11 @@
#include <xen/xen_intr.h>
#include <xen/arch-intr.h>
+/*
+ * Pointers to the interrupt counters
+ */
+DPCPU_DEFINE_STATIC(u_long *, pintrcnt);
+
/*
* Lock for x86-related structures. Notably modifying
* xen_intr_auto_vector_count, and allocating interrupts require this lock be
@@ -60,6 +65,67 @@
static u_int xen_intr_auto_vector_count;
+/*
+ * Transition from assembly language, called from
+ * sys/{amd64/amd64|i386/i386}/apic_vector.[Ss]
+ */
+extern void xen_arch_intr_handle_upcall(struct trapframe *);
+void
+xen_arch_intr_handle_upcall(struct trapframe *trap_frame)
+{
+
+ /*
+ * Disable preemption in order to always check and fire events
+ * on the right vCPU
+ */
+ critical_enter();
+
+ ++*DPCPU_PTR(pintrcnt);
+
+ xen_intr_handle_upcall(trap_frame);
+
+ if (xen_evtchn_needs_ack)
+ lapic_eoi();
+
+ critical_exit();
+}
+
+/**
+ * Allocate and register a per-cpu Xen upcall interrupt counter.
+ *
+ * \param cpu The cpu for which to register this interrupt count.
+ */
+static void
+xen_intr_intrcnt_add(const u_int cpu)
+{
+ char buf[MAXCOMLEN + 1];
+ u_long **ppintrcnt;
+
+ ppintrcnt = DPCPU_ID_PTR(cpu, pintrcnt);
+ if (ppintrcnt != NULL)
+ return;
+
+ snprintf(buf, sizeof(buf), "cpu%d:xen", cpu);
+ intrcnt_add(buf, ppintrcnt);
+}
+
+static void
+xen_intrcnt_init(void *dummy __unused)
+{
+ unsigned int i;
+
+ if (!xen_domain())
+ return;
+
+ /*
+ * Register interrupt count manually as we aren't guaranteed to see a
+ * call to xen_intr_assign_cpu() before our first interrupt.
+ */
+ CPU_FOREACH(i)
+ xen_intr_intrcnt_add(i);
+}
+SYSINIT(xen_intrcnt_init, SI_SUB_INTR, SI_ORDER_MIDDLE, xen_intrcnt_init, NULL);
+
void
xen_intr_alloc_irqs(void)
{
Index: sys/xen/xen_intr.h
===================================================================
--- sys/xen/xen_intr.h
+++ sys/xen/xen_intr.h
@@ -38,7 +38,12 @@
/** Registered Xen interrupt callback handle. */
typedef void * xen_intr_handle_t;
-void xen_intr_handle_upcall(struct trapframe *trap_frame);
+/*
+ * NOTE: This function is a critical section and must be executed with
+ * preemption disabled to remain on the correct vCPU. Before/after this
+ * function is called, critical_enter()/critical_exit() must be invoked.
+ */
+int xen_intr_handle_upcall(struct trapframe *trap_frame);
/**
* Associate an already allocated local event channel port an interrupt
Index: sys/xen/xen_intr.c
===================================================================
--- sys/xen/xen_intr.c
+++ sys/xen/xen_intr.c
@@ -87,9 +87,6 @@
*/
u_int last_processed_l2i;
- /** Pointer to this CPU's interrupt statistic counter. */
- u_long *evtchn_intrcnt;
-
/**
* A bitmap of ports that can be serviced from this CPU.
* A set bit means interrupt handling is enabled.
@@ -196,25 +193,6 @@
xen_set_bit(port, pcpu->evtchn_enabled);
}
-/**
- * Allocate and register a per-cpu Xen upcall interrupt counter.
- *
- * \param cpu The cpu for which to register this interrupt count.
- */
-static void
-xen_intr_intrcnt_add(u_int cpu)
-{
- char buf[MAXCOMLEN + 1];
- struct xen_intr_pcpu_data *pcpu;
-
- pcpu = DPCPU_ID_PTR(cpu, xen_intr_pcpu);
- if (pcpu->evtchn_intrcnt != NULL)
- return;
-
- snprintf(buf, sizeof(buf), "cpu%d:xen", cpu);
- intrcnt_add(buf, &pcpu->evtchn_intrcnt);
-}
-
/**
* Attempt to free an active Xen interrupt source object.
*
@@ -350,8 +328,12 @@
* Interrupt handler for processing all Xen event channel events.
*
* \param trap_frame The trap frame context for the current interrupt.
+ *
+ * NOTE: This function is a critical section and must be executed with
+ * preemption disabled to remain on the correct vCPU. Before/after this
+ * function is called, critical_enter()/critical_exit() must be invoked.
*/
-void
+int
xen_intr_handle_upcall(struct trapframe *trap_frame)
{
u_int l1i, l2i, port, cpu;
@@ -362,11 +344,7 @@
struct xen_intr_pcpu_data *pc;
u_long l1, l2;
- /*
- * Disable preemption in order to always check and fire events
- * on the right vCPU
- */
- critical_enter();
+ bool handled = false;
cpu = PCPU_GET(cpuid);
pc = DPCPU_PTR(xen_intr_pcpu);
@@ -390,7 +368,6 @@
l1i = pc->last_processed_l1i;
l2i = pc->last_processed_l2i;
- (*pc->evtchn_intrcnt)++;
while (l1 != 0) {
l1i = (l1i + 1) % LONG_BIT;
@@ -433,7 +410,8 @@
("Received unexpected event on vCPU#%d, event bound to vCPU#%d",
PCPU_GET(cpuid), isrc->xi_cpu));
- xen_arch_intr_execute_handlers(isrc, trap_frame);
+ if (xen_arch_intr_execute_handlers(isrc, trap_frame))
+ handled = true;
/*
* If this is the final port processed,
@@ -454,10 +432,7 @@
}
}
- if (xen_evtchn_needs_ack)
- lapic_eoi();
-
- critical_exit();
+ return (handled ? FILTER_HANDLED : FILTER_STRAY);
}
static int
@@ -494,23 +469,6 @@
}
SYSINIT(xen_intr_init, SI_SUB_INTR, SI_ORDER_SECOND, xen_intr_init, NULL);
-static void
-xen_intrcnt_init(void *dummy __unused)
-{
- unsigned int i;
-
- if (!xen_domain())
- return;
-
- /*
- * Register interrupt count manually as we aren't guaranteed to see a
- * call to xen_intr_assign_cpu() before our first interrupt.
- */
- CPU_FOREACH(i)
- xen_intr_intrcnt_add(i);
-}
-SYSINIT(xen_intrcnt_init, SI_SUB_INTR, SI_ORDER_MIDDLE, xen_intrcnt_init, NULL);
-
/*--------------------------- Common PIC Functions ---------------------------*/
/**
* Prepare this PIC for system suspension.
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Dec 29, 4:30 AM (8 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15627678
Default Alt Text
D30006.id94623.diff (6 KB)
Attached To
Mode
D30006: xen/intr: adjust xen_intr_handle_upcall() to match interrupt filter
Attached
Detach File
Event Timeline
Log In to Comment