Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Dec 2018 14:54:28 +0000 (UTC)
From:      Leandro Lupori <luporl@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r341797 - in head/sys/powerpc: aim include powerpc
Message-ID:  <201812101454.wBAEsSvh068887@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201812101454.wBAEsSvh068887>