From f1dee044ae2c5627ab918d5b947ec6785d2d74c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= <royger@FreeBSD.org> Date: Tue, 5 Mar 2024 14:15:03 +0100 Subject: [PATCH] x86/xen: fix accounted interrupt time The current addition to the interrupt nesting level in xen_arch_intr_handle_upcall() is wrong, as intr_execute_handlers() as called by xen_arch_intr_execute_handlers() will already add one nesting level and save the previous frame. Such extra interrupt nesting count lead to statclock() reporting idle time as interrupt, as the call from interrupt context will always be seen as a nested one (td->td_intr_nesting_level >= 2) due to the nesting count increase done by both xen_arch_intr_handle_upcall() and intr_execute_handlers(). Fix this by removing the extra nesting increase done in xen_arch_intr_handle_upcall(). PR: 277231 Reported by: Matthew Grooms <mgrooms@shrew.net> Fixes: af610cabf1f4 ('xen/intr: adjust xen_intr_handle_upcall() to match driver filter') Sponsored by: Cloud Software Group --- sys/dev/xen/bus/xen_intr.c | 4 ++-- sys/x86/xen/xen_arch_intr.c | 10 +--------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/sys/dev/xen/bus/xen_intr.c b/sys/dev/xen/bus/xen_intr.c index 609f31b5418a..30a755de81fa 100644 --- a/sys/dev/xen/bus/xen_intr.c +++ b/sys/dev/xen/bus/xen_intr.c @@ -344,9 +344,9 @@ xen_intr_active_ports(const struct xen_intr_pcpu_data *const pcpu, * \param trap_frame The trap frame context for the current interrupt. */ int -xen_intr_handle_upcall(void *unused __unused) +xen_intr_handle_upcall(void *data) { - struct trapframe *trap_frame = curthread->td_intr_frame; + struct trapframe *trap_frame = data; u_int l1i, l2i, port, cpu __diagused; u_long masked_l1, masked_l2; struct xenisrc *isrc; diff --git a/sys/x86/xen/xen_arch_intr.c b/sys/x86/xen/xen_arch_intr.c index dcf8b4aa35f1..4136f9bfc7f8 100644 --- a/sys/x86/xen/xen_arch_intr.c +++ b/sys/x86/xen/xen_arch_intr.c @@ -81,7 +81,6 @@ extern void xen_arch_intr_handle_upcall(struct trapframe *); void xen_arch_intr_handle_upcall(struct trapframe *trap_frame) { - struct trapframe *old; /* * Disable preemption in order to always check and fire events @@ -91,14 +90,7 @@ xen_arch_intr_handle_upcall(struct trapframe *trap_frame) ++*DPCPU_GET(pintrcnt); - ++curthread->td_intr_nesting_level; - old = curthread->td_intr_frame; - curthread->td_intr_frame = trap_frame; - - xen_intr_handle_upcall(NULL); - - curthread->td_intr_frame = old; - --curthread->td_intr_nesting_level; + xen_intr_handle_upcall(trap_frame); if (xen_evtchn_needs_ack) lapic_eoi(); -- 2.44.0