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)
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to