svn commit: r364002 - in stable/12/sys: kern sys x86/x86

Alexander Motin mav at FreeBSD.org
Fri Aug 7 00:56:21 UTC 2020


Author: mav
Date: Fri Aug  7 00:56:20 2020
New Revision: 364002
URL: https://svnweb.freebsd.org/changeset/base/364002

Log:
  MFC r360328 (by vangyzen):
  Fix handling of NMIs from unknown sources (BMC, hypervisor)
  
  Release kernels have no KDB backends enabled, so they discard an NMI
  if it is not due to a hardware failure.  This includes NMIs from
  IPMI BMCs and hypervisors.
  
  Furthermore, the interaction of panic_on_nmi, kdb_on_nmi, and
  debugger_on_panic is confusing.
  
  Respond to all NMIs according to panic_on_nmi and debugger_on_panic.
  Remove kdb_on_nmi.  Expand the meaning of panic_on_nmi by making
  it a bitfield.  There are currently two bits: one for NMIs due to
  hardware failure, and one for all others.  Leave room for more.
  
  If panic_on_nmi and debugger_on_panic are both true, don't actually panic,
  but directly enter the debugger, to allow someone to leave the debugger
  and [hopefully] resume normal execution.
  
  Relnotes:	yes: machdep.kdb_on_nmi is gone; machdep.panic_on_nmi changed

Modified:
  stable/12/sys/kern/kern_shutdown.c
  stable/12/sys/sys/kdb.h
  stable/12/sys/x86/x86/cpu_machdep.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/kern/kern_shutdown.c
==============================================================================
--- stable/12/sys/kern/kern_shutdown.c	Fri Aug  7 00:50:41 2020	(r364001)
+++ stable/12/sys/kern/kern_shutdown.c	Fri Aug  7 00:56:20 2020	(r364002)
@@ -115,9 +115,9 @@ SYSCTL_INT(_kern, OID_AUTO, panic_reboot_wait_time, CT
 
 #ifdef KDB
 #ifdef KDB_UNATTENDED
-static int debugger_on_panic = 0;
+int debugger_on_panic = 0;
 #else
-static int debugger_on_panic = 1;
+int debugger_on_panic = 1;
 #endif
 SYSCTL_INT(_debug, OID_AUTO, debugger_on_panic,
     CTLFLAG_RWTUN | CTLFLAG_SECURE,

Modified: stable/12/sys/sys/kdb.h
==============================================================================
--- stable/12/sys/sys/kdb.h	Fri Aug  7 00:50:41 2020	(r364001)
+++ stable/12/sys/sys/kdb.h	Fri Aug  7 00:56:20 2020	(r364002)
@@ -62,6 +62,7 @@ struct kdb_dbbe {
 	DATA_SET(kdb_dbbe_set, name##_dbbe)
 
 extern u_char kdb_active;		/* Non-zero while in debugger. */
+extern int debugger_on_panic;		/* enter the debugger on panic. */
 extern int debugger_on_trap;		/* enter the debugger on trap. */
 extern struct kdb_dbbe *kdb_dbbe;	/* Default debugger backend or NULL. */
 extern struct trapframe *kdb_frame;	/* Frame to kdb_trap(). */

Modified: stable/12/sys/x86/x86/cpu_machdep.c
==============================================================================
--- stable/12/sys/x86/x86/cpu_machdep.c	Fri Aug  7 00:50:41 2020	(r364001)
+++ stable/12/sys/x86/x86/cpu_machdep.c	Fri Aug  7 00:56:20 2020	(r364002)
@@ -803,20 +803,14 @@ cpu_idle_tun(void *unused __unused)
 }
 SYSINIT(cpu_idle_tun, SI_SUB_CPU, SI_ORDER_MIDDLE, cpu_idle_tun, NULL);
 
-static int panic_on_nmi = 1;
+static int panic_on_nmi = 0xff;
 SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RWTUN,
     &panic_on_nmi, 0,
-    "Panic on NMI raised by hardware failure");
+    "Panic on NMI: 1 = H/W failure; 2 = unknown; 0xff = all");
 int nmi_is_broadcast = 1;
 SYSCTL_INT(_machdep, OID_AUTO, nmi_is_broadcast, CTLFLAG_RWTUN,
     &nmi_is_broadcast, 0,
     "Chipset NMI is broadcast");
-#ifdef KDB
-int kdb_on_nmi = 1;
-SYSCTL_INT(_machdep, OID_AUTO, kdb_on_nmi, CTLFLAG_RWTUN,
-    &kdb_on_nmi, 0,
-    "Go to KDB on NMI with unknown source");
-#endif
 
 void
 nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame)
@@ -827,19 +821,31 @@ nmi_call_kdb(u_int cpu, u_int type, struct trapframe *
 	/* machine/parity/power fail/"kitchen sink" faults */
 	if (isa_nmi(frame->tf_err)) {
 		claimed = true;
-		if (panic_on_nmi)
+		if ((panic_on_nmi & 1) != 0)
 			panic("NMI indicates hardware failure");
 	}
 #endif /* DEV_ISA */
+
+	/*
+	 * NMIs can be useful for debugging.  They can be hooked up to a
+	 * pushbutton, usually on an ISA, PCI, or PCIe card.  They can also be
+	 * generated by an IPMI BMC, either manually or in response to a
+	 * watchdog timeout.  For example, see the "power diag" command in
+	 * ports/sysutils/ipmitool.  They can also be generated by a
+	 * hypervisor; see "bhyvectl --inject-nmi".
+	 */
+
 #ifdef KDB
-	if (!claimed && kdb_on_nmi) {
-		/*
-		 * NMI can be hooked up to a pushbutton for debugging.
-		 */
-		printf("NMI/cpu%d ... going to debugger\n", cpu);
-		kdb_trap(type, 0, frame);
+	if (!claimed && (panic_on_nmi & 2) != 0) {
+		if (debugger_on_panic) {
+			printf("NMI/cpu%d ... going to debugger\n", cpu);
+			claimed = kdb_trap(type, 0, frame);
+		}
 	}
 #endif /* KDB */
+
+	if (!claimed && panic_on_nmi != 0)
+		panic("NMI");
 }
 
 void


More information about the svn-src-stable-12 mailing list