Page MenuHomeFreeBSD

D30006.id94623.diff
No OneTemporary

D30006.id94623.diff

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

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)

Event Timeline