[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
This commit is contained in:
Brandon Bergren 2019-12-30 02:56:47 +00:00
parent 06b367b2b6
commit 9367fb301c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=356199
2 changed files with 10 additions and 5 deletions

View File

@ -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

View File

@ -84,13 +84,17 @@ opal_hmi_event_handler(void *unused, struct opal_msg *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)