diff --git a/sys/x86/include/x86_var.h b/sys/x86/include/x86_var.h --- a/sys/x86/include/x86_var.h +++ b/sys/x86/include/x86_var.h @@ -104,6 +104,12 @@ struct trapframe; struct minidumpstate; +/* + * NMI callback function to allow framework like kdb, watchdog be able to call + * their callback handlers in trap handling path. + */ +typedef bool (*nmi_fn)(u_int, u_int, struct trapframe *); + /* * The interface type of the interrupt handler entry point cannot be * expressed in C. Use simplest non-variadic function type as an @@ -144,8 +150,8 @@ void x86_rngds_mitg_recalculate(bool all_cpus); void zenbleed_sanitize_enable(void); void zenbleed_check_and_apply(bool all_cpus); -void nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame); -void nmi_call_kdb_smp(u_int type, struct trapframe *frame); +bool nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame); +bool nmi_call_handler_smp(u_int type, struct trapframe *frame, nmi_fn cb_fn); void nmi_handle_intr(u_int type, struct trapframe *frame); void pagecopy(void *from, void *to); void printcpuinfo(void); diff --git a/sys/x86/x86/cpu_machdep.c b/sys/x86/x86/cpu_machdep.c --- a/sys/x86/x86/cpu_machdep.c +++ b/sys/x86/x86/cpu_machdep.c @@ -845,7 +845,7 @@ "Chipset NMI is broadcast"); int (*apei_nmi)(void); -void +bool nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame) { bool claimed = false; @@ -881,21 +881,22 @@ } #endif /* KDB */ - if (!claimed && panic_on_nmi != 0) - panic("NMI"); + return (claimed); } void nmi_handle_intr(u_int type, struct trapframe *frame) { + bool claimed; #ifdef SMP - if (nmi_is_broadcast) { - nmi_call_kdb_smp(type, frame); - return; - } + if (nmi_is_broadcast) + claimed = nmi_call_handler_smp(type, frame, nmi_call_kdb); + else #endif - nmi_call_kdb(PCPU_GET(cpuid), type, frame); + claimed = nmi_call_kdb(PCPU_GET(cpuid), type, frame); + if (!claimed && panic_on_nmi != 0) + panic("NMI"); } static int hw_ibrs_active; diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c --- a/sys/x86/x86/mp_x86.c +++ b/sys/x86/x86/mp_x86.c @@ -1487,15 +1487,19 @@ int nmi_kdb_lock; -void -nmi_call_kdb_smp(u_int type, struct trapframe *frame) +bool +nmi_call_handler_smp(u_int type, struct trapframe *frame, nmi_fn cb_fn) { - int cpu; - bool call_post; + u_int cpu; + bool call_post, claimed; + + if (cb_fn == NULL) + return (false); cpu = PCPU_GET(cpuid); + claimed = false; if (atomic_cmpset_acq_int(&nmi_kdb_lock, 0, 1)) { - nmi_call_kdb(cpu, type, frame); + claimed = (*cb_fn)(cpu, type, frame); call_post = false; } else { savectx(&stoppcbs[cpu]); @@ -1507,6 +1511,8 @@ atomic_store_rel_int(&nmi_kdb_lock, 0); if (call_post) cpustop_handler_post(cpu); + + return (claimed); } /*