Author: luporl
Date: Mon Dec 10 14:54:28 2018
New Revision: 341797
URL: https://svnweb.freebsd.org/changeset/base/341797

Log:
  ppc64: handle exception 0x1500 (soft patch)
  
  This change adds a hypervisor trap handler for exception 0x1500 (soft patch),
  normalizing all VSX registers and returning.
  This avoids a kernel panic due to unknown exception.
  
  Change made with the collaboration of leonardo.bianconi_eldorado.org.br,
  that found out that this is a hypervisor exception and not a supervisor one,
  and fixed this in the code.
  
  Reviewed by:  jhibbits, sbruno
  Differential Revision:        https://reviews.freebsd.org/D17806

Modified:
  head/sys/powerpc/aim/aim_machdep.c
  head/sys/powerpc/include/trap.h
  head/sys/powerpc/powerpc/db_trace.c
  head/sys/powerpc/powerpc/trap.c

Modified: head/sys/powerpc/aim/aim_machdep.c
==============================================================================
--- head/sys/powerpc/aim/aim_machdep.c  Mon Dec 10 14:50:11 2018        
(r341796)
+++ head/sys/powerpc/aim/aim_machdep.c  Mon Dec 10 14:54:28 2018        
(r341797)
@@ -366,6 +366,7 @@ aim_cpu_init(vm_offset_t toc)
        bcopy(&hypertrapcode, (void *)(EXC_HEA + trap_offset), trapsize);
        bcopy(&hypertrapcode, (void *)(EXC_HMI + trap_offset), trapsize);
        bcopy(&hypertrapcode, (void *)(EXC_HVI + trap_offset), trapsize);
+       bcopy(&hypertrapcode, (void *)(EXC_SOFT_PATCH + trap_offset), trapsize);
        #endif
 
        bcopy(&rstcode, (void *)(EXC_RST + trap_offset), (size_t)&rstcodeend -

Modified: head/sys/powerpc/include/trap.h
==============================================================================
--- head/sys/powerpc/include/trap.h     Mon Dec 10 14:50:11 2018        
(r341796)
+++ head/sys/powerpc/include/trap.h     Mon Dec 10 14:54:28 2018        
(r341797)
@@ -103,6 +103,9 @@
 #define        EXC_SPFPD       0x2f30          /* SPE Floating-point Data */
 #define        EXC_SPFPR       0x2f40          /* SPE Floating-point Round */
 
+/* POWER8 */
+#define EXC_SOFT_PATCH 0x1500          /* POWER8 Soft Patch Exception */
+
 #define        EXC_LAST        0x2f00          /* Last possible exception 
vector */
 
 #define        EXC_AST         0x3000          /* Fake AST vector */

Modified: head/sys/powerpc/powerpc/db_trace.c
==============================================================================
--- head/sys/powerpc/powerpc/db_trace.c Mon Dec 10 14:50:11 2018        
(r341796)
+++ head/sys/powerpc/powerpc/db_trace.c Mon Dec 10 14:54:28 2018        
(r341797)
@@ -255,6 +255,7 @@ db_backtrace(struct thread *td, db_addr_t fp, int coun
                        case EXC_DECR: trapstr = "DECR"; break;
                        case EXC_PERF: trapstr = "PERF"; break;
                        case EXC_VSX: trapstr = "VSX"; break;
+                       case EXC_SOFT_PATCH: trapstr = "SOFT_PATCH"; break;
                        default: trapstr = NULL; break;
                        }
                        if (trapstr != NULL) {

Modified: head/sys/powerpc/powerpc/trap.c
==============================================================================
--- head/sys/powerpc/powerpc/trap.c     Mon Dec 10 14:50:11 2018        
(r341796)
+++ head/sys/powerpc/powerpc/trap.c     Mon Dec 10 14:54:28 2018        
(r341797)
@@ -95,6 +95,7 @@ static void   syscall(struct trapframe *frame);
        void    handle_kernel_slb_spill(int, register_t, register_t);
 static int     handle_user_slb_spill(pmap_t pm, vm_offset_t addr);
 extern int     n_slbs;
+static void    normalize_inputs(void);
 #endif
 
 extern vm_offset_t __startkernel;
@@ -147,6 +148,7 @@ static struct powerpc_exception powerpc_exceptions[] =
        { EXC_VECAST_G4,        "altivec assist" },
        { EXC_THRM,     "thermal management" },
        { EXC_RUNMODETRC,       "run mode/trace" },
+       { EXC_SOFT_PATCH, "soft patch exception" },
        { EXC_LAST,     NULL }
 };
 
@@ -382,6 +384,17 @@ trap(struct trapframe *frame)
                        ucode = BUS_OBJERR;
                        break;
 
+#if defined(__powerpc64__) && defined(AIM)
+               case EXC_SOFT_PATCH:
+                       /*
+                        * Point to the instruction that generated the 
exception to execute it again,
+                        * and normalize the register values.
+                        */
+                       frame->srr0 -= 4;
+                       normalize_inputs();
+                       break;
+#endif
+
                default:
                        trap_fatal(frame);
                }
@@ -908,6 +921,49 @@ fix_unaligned(struct thread *td, struct trapframe *fra
 
        return (-1);
 }
+
+#if defined(__powerpc64__) && defined(AIM)
+#define MSKNSHL(x, m, n) "(((" #x ") & " #m ") << " #n ")"
+#define MSKNSHR(x, m, n) "(((" #x ") & " #m ") >> " #n ")"
+
+/* xvcpsgndp instruction, built in opcode format.
+ * This can be changed to use mnemonic after a toolchain update.
+ */
+#define XVCPSGNDP(xt, xa, xb) \
+       __asm __volatile(".long (" \
+               MSKNSHL(60, 0x3f, 26) " | " \
+               MSKNSHL(xt, 0x1f, 21) " | " \
+               MSKNSHL(xa, 0x1f, 16) " | " \
+               MSKNSHL(xb, 0x1f, 11) " | " \
+               MSKNSHL(240, 0xff, 3) " | " \
+               MSKNSHR(xa,  0x20, 3) " | " \
+               MSKNSHR(xa,  0x20, 4) " | " \
+               MSKNSHR(xa,  0x20, 5) ")")
+
+/* Macros to normalize 1 or 10 VSX registers */
+#define NORM(x)        XVCPSGNDP(x, x, x)
+#define NORM10(x) \
+       NORM(x ## 0); NORM(x ## 1); NORM(x ## 2); NORM(x ## 3); NORM(x ## 4); \
+       NORM(x ## 5); NORM(x ## 6); NORM(x ## 7); NORM(x ## 8); NORM(x ## 9)
+
+static void
+normalize_inputs(void)
+{
+       unsigned long msr;
+
+       /* enable VSX */
+       msr = mfmsr();
+       mtmsr(msr | PSL_VSX);
+
+       NORM(0);   NORM(1);   NORM(2);   NORM(3);   NORM(4);
+       NORM(5);   NORM(6);   NORM(7);   NORM(8);   NORM(9);
+       NORM10(1); NORM10(2); NORM10(3); NORM10(4); NORM10(5);
+       NORM(60);  NORM(61);  NORM(62);  NORM(63);
+
+       /* restore MSR */
+       mtmsr(msr);
+}
+#endif
 
 #ifdef KDB
 int
_______________________________________________
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