svn commit: r356199 - in head/sys/powerpc: include powernv

Brandon Bergren bdragon at FreeBSD.org
Mon Dec 30 02:56:48 UTC 2019


Author: bdragon
Date: Mon Dec 30 02:56:47 2019
New Revision: 356199
URL: https://svnweb.freebsd.org/changeset/base/356199

Log:
  [PowerPC] Fix panic when attempting to handle an HMI from an idle thread
  
  In IRC, sfs_ finally managed to get a good trace of a kernel panic that was
  happening when attempting to use webengine.
  
  As it turns out, we were using vtophys() from interrupt context on an idle
  thread in opal_hmi_handler2().
  
  Since this involves locking the kernel pmap on PPC64 at the moment, this
  ended up tripping a KASSERT in mtx_lock(), which then caused a parallel
  panic stampede.
  
  So, avoid this by preallocating the flags variable and storing it in PCPU.
  
  Fixes "panic: mtx_lock() by idle thread 0x... on sleep mutex kernelpmap".
  
  Differential Revision:	https://reviews.freebsd.org/D22962

Modified:
  head/sys/powerpc/include/pcpu.h
  head/sys/powerpc/powernv/opal_hmi.c

Modified: head/sys/powerpc/include/pcpu.h
==============================================================================
--- head/sys/powerpc/include/pcpu.h	Mon Dec 30 02:40:55 2019	(r356198)
+++ head/sys/powerpc/include/pcpu.h	Mon Dec 30 02:56:47 2019	(r356199)
@@ -68,7 +68,8 @@ struct pvo_entry;
 	uint8_t		slbstack[1024];				\
 	struct pvo_entry *qmap_pvo;					\
 	struct mtx	qmap_lock;					\
-	char		__pad[1345];
+	uint64_t	opal_hmi_flags;					\
+	char		__pad[1337];
 
 #ifdef __powerpc64__
 #define PCPU_MD_AIM_FIELDS	PCPU_MD_AIM64_FIELDS

Modified: head/sys/powerpc/powernv/opal_hmi.c
==============================================================================
--- head/sys/powerpc/powernv/opal_hmi.c	Mon Dec 30 02:40:55 2019	(r356198)
+++ head/sys/powerpc/powernv/opal_hmi.c	Mon Dec 30 02:56:47 2019	(r356199)
@@ -84,13 +84,17 @@ opal_hmi_event_handler(void *unused, struct opal_msg *
 static int
 opal_hmi_handler2(struct trapframe *frame)
 {
-	uint64_t flags;
+	/*
+	 * Use DMAP preallocated pcpu memory to handle
+	 * the phys flags pointer.
+	 */
+	uint64_t *flags = PCPU_PTR(aim.opal_hmi_flags);
 	int err;
 
-	flags = 0;
-	err = opal_call(OPAL_HANDLE_HMI2, vtophys(&flags));
+	*flags = 0;
+	err = opal_call(OPAL_HANDLE_HMI2, DMAP_TO_PHYS((vm_offset_t)flags));
 
-	if (flags & OPAL_HMI_FLAGS_TOD_TB_FAIL)
+	if (*flags & OPAL_HMI_FLAGS_TOD_TB_FAIL)
 		panic("TOD/TB recovery failure");
 
 	if (err == OPAL_SUCCESS)


More information about the svn-src-head mailing list