xen/x86: Get the right intrframe pointer in ddb ipi.

This was broken with the transition from evtchn_set_handler to
intr_establish_xname in 2017, remained broken with the transition
from intr_establish_xname to xen_intr_establish_xname in 2018, and
still remained broken when xen_intr_establish_xname was changed back
to evtchn_set_handler in 2020.

The mechanism is grody -- instead of a secret second argument to the
interrupt handler, the intrframe pointer should be replaced by a
struct cpu_info member that is saved and restored by the interrupt
handler calling logic.  But we should make sure the replacement
actually works first -- which is not trivial in part because the
users are hidden behind sketchy function pointer casts.

With any luck, this will make `mach cpu N' work in ddb on Xen.

XXX pullup-10
XXX pullup-9 (by patch)
This commit is contained in:
riastradh 2023-08-06 16:07:53 +00:00
parent 7dcb2534d3
commit 2095a1529c
1 changed files with 6 additions and 8 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: xen_ipi.c,v 1.40 2022/01/05 20:21:29 christos Exp $ */
/* $NetBSD: xen_ipi.c,v 1.41 2023/08/06 16:07:53 riastradh Exp $ */
/*-
* Copyright (c) 2011, 2019 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
* Based on: x86/ipi.c
*/
__KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.40 2022/01/05 20:21:29 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.41 2023/08/06 16:07:53 riastradh Exp $");
#include "opt_ddb.h"
@ -90,18 +90,15 @@ static void (*xen_ipifunc[XEN_NIPIS])(struct cpu_info *, struct intrframe *) =
};
static int
xen_ipi_handler(void *arg)
xen_ipi_handler(void *arg, struct intrframe *regs)
{
uint32_t pending;
int bit;
struct cpu_info *ci;
struct intrframe *regs;
ci = curcpu();
regs = arg;
KASSERT(ci == arg);
pending = atomic_swap_32(&ci->ci_ipis, 0);
KDASSERT((pending >> XEN_NIPIS) == 0);
@ -142,8 +139,9 @@ xen_ipi_init(void)
snprintf(intr_xname, sizeof(intr_xname), "%s ipi",
device_xname(ci->ci_dev));
if (event_set_handler(evtchn, xen_ipi_handler, ci, IPL_HIGH, NULL,
intr_xname, true, ci) == NULL) {
if (event_set_handler(evtchn,
__FPTRCAST(int (*)(void *), xen_ipi_handler), ci, IPL_HIGH,
NULL, intr_xname, true, ci) == NULL) {
panic("%s: unable to register ipi handler\n", __func__);
/* NOTREACHED */
}