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; @@ -883,6 +883,8 @@ if (!claimed && panic_on_nmi != 0) panic("NMI"); + + return (claimed); } void @@ -891,7 +893,7 @@ #ifdef SMP if (nmi_is_broadcast) { - nmi_call_kdb_smp(type, frame); + nmi_call_handler_smp(type, frame, nmi_call_kdb); return; } #endif 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); } /*