shithub: riscv

Download patch

ref: e3277b466076029e4b951a4a4b14002d4c25b653
parent: a8f96b5343726f5f45110c1c8350e3db5a5a30ea
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Jul 8 08:19:34 EDT 2023

bcm64, imx8, pc64: save stack space in fault handler

Move fault-note generation in separate faultnote()
function to avoid having to allocate ERRMAX bytes
on the kernel stack.

--- a/sys/src/9/bcm64/trap.c
+++ b/sys/src/9/bcm64/trap.c
@@ -406,11 +406,24 @@
 	}
 }
 
-void
-faultarm64(Ureg *ureg)
+static void
+faultnote(Ureg *ureg, char *access, uintptr addr)
 {
 	extern void checkpages(void);
 	char buf[ERRMAX];
+
+	if(!userureg(ureg)){
+		dumpregs(ureg);
+		panic("fault: %s addr=%#p", access, addr);
+	}
+	checkpages();
+	snprint(buf, sizeof(buf), "sys: trap: fault %s addr=%#p", access, addr);
+	postnote(up, 1, buf, NDebug);
+}
+
+void
+faultarm64(Ureg *ureg)
+{
 	int user, read;
 	uintptr addr;
 
@@ -456,13 +469,7 @@
 	case 61:				// first level domain fault
 	case 62:				// second level domain fault
 	default:
-		if(!user){
-			dumpregs(ureg);
-			panic("fault: %s addr=%#p", read ? "read" : "write", addr);
-		}
-		checkpages();
-		sprint(buf, "sys: trap: fault %s addr=%#p", read ? "read" : "write", addr);
-		postnote(up, 1, buf, NDebug);
+		faultnote(ureg, read? "read": "write", addr);
 	}
 
 	if(user)
--- a/sys/src/9/imx8/trap.c
+++ b/sys/src/9/imx8/trap.c
@@ -406,11 +406,24 @@
 	}
 }
 
-void
-faultarm64(Ureg *ureg)
+static void
+faultnote(Ureg *ureg, char *access, uintptr addr)
 {
 	extern void checkpages(void);
 	char buf[ERRMAX];
+
+	if(!userureg(ureg)){
+		dumpregs(ureg);
+		panic("fault: %s addr=%#p", access, addr);
+	}
+	checkpages();
+	snprint(buf, sizeof(buf), "sys: trap: fault %s addr=%#p", access, addr);
+	postnote(up, 1, buf, NDebug);
+}
+
+void
+faultarm64(Ureg *ureg)
+{
 	int user, read;
 	uintptr addr;
 
@@ -456,13 +469,7 @@
 	case 61:				// first level domain fault
 	case 62:				// second level domain fault
 	default:
-		if(!user){
-			dumpregs(ureg);
-			panic("fault: %s addr=%#p", read ? "read" : "write", addr);
-		}
-		checkpages();
-		sprint(buf, "sys: trap: fault %s addr=%#p", read ? "read" : "write", addr);
-		postnote(up, 1, buf, NDebug);
+		faultnote(ureg, read? "read": "write", addr);
 	}
 
 	if(user)
--- a/sys/src/9/pc64/trap.c
+++ b/sys/src/9/pc64/trap.c
@@ -122,7 +122,7 @@
 
 	if(vno < nelem(excname)){
 		spllo();
-		sprint(buf, "sys: trap: %s", excname[vno]);
+		snprint(buf, sizeof(buf), "sys: trap: %s", excname[vno]);
 		postnote(up, 1, buf, NDebug);
 		return 1;
 	}
@@ -332,7 +332,7 @@
 	m = (m >> 4 | m >> 3) & 8 | (m >> 3 | m >> 2) & 4 | (m >> 2 | m >> 1) & 2 | (m >> 1 | m) & 1;
 	m &= dr6;
 	if(m == 0){
-		sprint(buf, "sys: debug exception dr6=%#.8ullx", dr6);
+		snprint(buf, sizeof(buf), "sys: debug exception dr6=%#.8ullx", dr6);
 		postnote(up, 0, buf, NDebug);
 	}else{
 		p = buf;
@@ -355,7 +355,7 @@
 		panic("kernel bpt");
 	/* restore pc to instruction that caused the trap */
 	ureg->pc--;
-	sprint(buf, "sys: breakpoint");
+	snprint(buf, sizeof(buf), "sys: breakpoint");
 	postnote(up, 1, buf, NDebug);
 }
 
@@ -371,14 +371,26 @@
 	print("unexpected trap %llud; ignoring\n", ureg->type);
 }
 
-extern void checkpages(void);
+static void
+faultnote(Ureg *ureg, char *access, uintptr addr)
+{
+	extern void checkpages(void);
+	char buf[ERRMAX];
 
+	if(!userureg(ureg)){
+		dumpregs(ureg);
+		panic("fault: %s addr=%#p", access, addr);
+	}
+	checkpages();
+	snprint(buf, sizeof(buf), "sys: trap: fault %s addr=%#p", access, addr);
+	postnote(up, 1, buf, NDebug);
+}
+
 static void
 faultamd64(Ureg* ureg, void*)
 {
 	uintptr addr;
 	int read, user;
-	char buf[ERRMAX];
 
 	addr = getcr2();
 	read = !(ureg->error & 2);
@@ -405,16 +417,8 @@
 		}
 	}
 
-	if(fault(addr, ureg->pc, read) < 0){
-		if(!user){
-			dumpregs(ureg);
-			panic("fault: %#p", addr);
-		}
-		checkpages();
-		sprint(buf, "sys: trap: fault %s addr=%#p",
-			read ? "read" : "write", addr);
-		postnote(up, 1, buf, NDebug);
-	}
+	if(fault(addr, ureg->pc, read))
+		faultnote(ureg, read? "read": "write", addr);
 
 	if(user)
 		up->insyscall = 0;