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