shithub: riscv

Download patch

ref: 4364b71cccf8353dc8f65a5e0db4041f6a0a1e53
parent: 1a73b594e684623c9ea1b72141f4e70ee913740b
author: cinap_lenrek <[email protected]>
date: Sat Jan 20 12:26:39 EST 2024

kernel: make trap() handlers consistent and check for stack overflow in kenter() for all archs

--- a/sys/src/9/arm64/trap.c
+++ b/sys/src/9/arm64/trap.c
@@ -226,7 +226,6 @@
 		}
 		
 		if(scallnr >= nsyscall || systab[scallnr] == nil){
-			pprint("bad sys call number %lud pc %#p", scallnr, ureg->pc);
 			postnote(up, 1, "sys: bad sys call", NDebug);
 			error(Ebadarg);
 		}
--- a/sys/src/9/bcm/trap.c
+++ b/sys/src/9/bcm/trap.c
@@ -136,20 +136,6 @@
 	uintptr va;
 	char buf[ERRMAX];
 
-	assert(!islo());
-	if(up != nil)
-		rem = ((char*)ureg)-((char*)up - KSTACK);
-	else
-		rem = ((char*)ureg)-((char*)m+sizeof(Mach));
-	if(rem < 256) {
-		iprint("trap: %d stack bytes left, up %#p ureg %#p at pc %#lux\n",
-			rem, up, ureg, ureg->pc);
-		delay(1000);
-		dumpstack();
-		panic("trap: %d stack bytes left, up %#p ureg %#p at pc %#lux",
-			rem, up, ureg, ureg->pc);
-	}
-
 	user = kenter(ureg);
 	/*
 	 * All interrupts/exceptions should be resumed at ureg->pc-4,
--- a/sys/src/9/cycv/trap.c
+++ b/sys/src/9/cycv/trap.c
@@ -237,8 +237,7 @@
 			startns = todget(nil);
 		}
 		
-		if(scallnr >= nsyscall || systab[scallnr] == 0){
-			pprint("bad sys call number %lud pc %lux", scallnr, ureg->pc);
+		if(scallnr >= nsyscall || systab[scallnr] == nil){
 			postnote(up, 1, "sys: bad sys call", NDebug);
 			error(Ebadarg);
 		}
@@ -272,14 +271,14 @@
 	if(scallnr == NOTED)
 		noted(ureg, *((ulong *) up->s.args));
 
-	if(scallnr != RFORK && (up->procctl || up->nnote)){
-		splhi();
+	splhi();
+	if(scallnr != RFORK && (up->procctl || up->nnote))
 		notify(ureg);
-	}
-	if(up->delaysched)
+	if(up->delaysched){
 		sched();
+		splhi();
+	}
 	kexit(ureg);
-	splhi();
 }
 
 int
--- a/sys/src/9/kw/syscall.c
+++ b/sys/src/9/kw/syscall.c
@@ -188,16 +188,11 @@
 			splx(s);
 			startns = todget(nil);
 		}
-		if(scallnr >= nsyscall){
-			pprint("bad sys call number %d pc %#lux\n",
-				scallnr, ureg->pc);
+		if(scallnr >= nsyscall || systab[scallnr] == nil){
 			postnote(up, 1, "sys: bad sys call", NDebug);
 			error(Ebadarg);
 		}
 		up->psstate = sysctab[scallnr];
-
-	/*	iprint("%s: syscall %s\n", up->text, sysctab[scallnr]?sysctab[scallnr]:"huh?"); */
-
 		ret = systab[scallnr]((va_list)up->s.args);
 		poperror();
 	}else{
--- a/sys/src/9/kw/trap.c
+++ b/sys/src/9/kw/trap.c
@@ -193,6 +193,7 @@
 	Handler *h;
 	Irq irq;
 
+	m->perf.intrts = perfticks();
 	clockintr = 0;
 
 	assert(sort >= 0 && sort < nelem(irqs));
@@ -369,16 +370,6 @@
 	u32int fsr;
 	uintptr va;
 	char buf[ERRMAX];
-
-	if(up != nil)
-		rem = (char*)ureg - ((char*)up - KSTACK);
-	else
-		rem = (char*)ureg - ((char*)m + sizeof(Mach));
-	if(rem < 256) {
-		dumpstack();
-		panic("trap %d bytes remaining, up %#p ureg %#p at pc %#lux",
-			rem, up, ureg, ureg->pc);
-	}
 
 	user = kenter(ureg);
 	if(ureg->type == PsrMabt+1)
--- a/sys/src/9/mt7688/syscall.c
+++ b/sys/src/9/mt7688/syscall.c
@@ -42,17 +42,12 @@
 	ret = -1;
 
 	if(!waserror()){
+		if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)))
+			validaddr(sp, sizeof(Sargs), 0);
 
-		if(scallnr >= nsyscall){
-			iprint("bad sys call number %lud pc %#lux\n",
-				scallnr, ureg->pc);
-			postnote(up, 1, "sys: bad sys call", NDebug);
-			error(Ebadarg);
-		}
+		up->s = *((Sargs*)(sp));	/* spim's libc is different to mips ... */
 
 		if(up->procctl == Proc_tracesyscall){
-			iprint("tracesyscall\n");
-			delay(50);
 			syscallfmt(scallnr, ureg->pc, (va_list)up->s.args);
 			s = splhi();
 			up->procctl = Proc_stopme;
@@ -61,16 +56,11 @@
 			startns = todget(nil);
 		}
 
-		if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)))
-			validaddr(sp, sizeof(Sargs), 0);
-
-		up->s = *((Sargs*)(sp));	/* spim's libc is different to mips ... */
+		if(scallnr >= nsyscall || systab[scallnr] == nil){
+			postnote(up, 1, "sys: bad sys call", NDebug);
+			error(Ebadarg);
+		}
 		up->psstate = sysctab[scallnr];
-
-//		iprint("[%luX] %s: syscall %s\n", (ulong)&ureg, up->text, sysctab[scallnr]?sysctab[scallnr]:"huh?");
-//		delay(20);
-//		dumpregs(ureg);
-
 		ret = systab[scallnr]((va_list)up->s.args);
 		poperror();
 	}else{
@@ -120,6 +110,7 @@
 	/* if we delayed sched because we held a lock, sched now */
 	if(up->delaysched){
 		sched();
+		splhi();
 	}
 
 	kexit(ureg);
--- a/sys/src/9/mt7688/trap.c
+++ b/sys/src/9/mt7688/trap.c
@@ -152,19 +152,6 @@
 	char buf[2*ERRMAX], buf1[ERRMAX], *fpexcep;
 	static int dumps;
 
-	if (up && (char *)(ur) - ((char *)up - KSTACK) < 1024 && dumps++ == 0) {
-		iprint("trap: proc %ld kernel stack getting full\n", up->pid);
-		dumpregs(ur);
-		dumpstack();
-		for(;;);
-	}
-	if (up == nil &&
-	    (char *)(ur) - (char *)m->stack < 1024 && dumps++ == 0) {
-		iprint("trap: cpu%d kernel stack getting full\n", m->machno);
-		dumpregs(ur);
-		dumpstack();
-		for(;;);
-	}
 	user = kenter(ur);
 	if (ur->cause & TS)
 		panic("trap: tlb shutdown");
--- a/sys/src/9/mtx/trap.c
+++ b/sys/src/9/mtx/trap.c
@@ -613,18 +613,16 @@
 	up->nerrlab = 0;
 	ret = -1;
 	if(!waserror()){
-		if(scallnr >= nsyscall || systab[scallnr] == nil){
-			pprint("bad sys call number %d pc %lux\n", scallnr, ureg->pc);
-			postnote(up, 1, "sys: bad sys call", NDebug);
-			error(Ebadarg);
-		}
-
 		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs)-BY2WD))
 			validaddr(sp, sizeof(Sargs)+BY2WD, 0);
 
 		up->s = *((Sargs*)(sp+BY2WD));
-		up->psstate = sysctab[scallnr];
 
+		if(scallnr >= nsyscall || systab[scallnr] == nil){
+			postnote(up, 1, "sys: bad sys call", NDebug);
+			error(Ebadarg);
+		}
+		up->psstate = sysctab[scallnr];
 		ret = systab[scallnr](up->s.args);
 		poperror();
 	}else{
--- a/sys/src/9/omap/syscall.c
+++ b/sys/src/9/omap/syscall.c
@@ -181,21 +181,15 @@
 	up->nerrlab = 0;
 	ret = -1;
 	if(!waserror()){
-		if(scallnr >= nsyscall){
-			pprint("bad sys call number %d pc %#lux\n",
-				scallnr, ureg->pc);
-			postnote(up, 1, "sys: bad sys call", NDebug);
-			error(Ebadarg);
-		}
-
 		if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD))
 			validaddr(sp, sizeof(Sargs)+BY2WD, 0);
 
 		up->s = *((Sargs*)(sp+BY2WD));
+		if(scallnr >= nsyscall || systab[scallnr] == nil){
+			postnote(up, 1, "sys: bad sys call", NDebug);
+			error(Ebadarg);
+		}
 		up->psstate = sysctab[scallnr];
-
-	/*	iprint("%s: syscall %s\n", up->text, sysctab[scallnr]?sysctab[scallnr]:"huh?"); */
-
 		ret = systab[scallnr]((va_list)up->s.args);
 		poperror();
 	}else{
--- a/sys/src/9/omap/trap.c
+++ b/sys/src/9/omap/trap.c
@@ -451,20 +451,6 @@
 	uintptr va;
 	char buf[ERRMAX];
 
-	splhi();			/* paranoia */
-	if(up != nil)
-		rem = ((char*)ureg)-((char*)up-KSTACK);
-	else
-		rem = ((char*)ureg)-((char*)m+sizeof(Mach));
-	if(rem < 1024) {
-		iprint("trap: %d stack bytes left, up %#p ureg %#p at pc %#lux\n",
-			rem, up, ureg, ureg->pc);
-		delay(1000);
-		dumpstack();
-		panic("trap: %d stack bytes left, up %#p ureg %#p at pc %#lux",
-			rem, up, ureg, ureg->pc);
-	}
-
 	user = kenter(ureg);
 	/*
 	 * All interrupts/exceptions should be resumed at ureg->pc-4,
--- a/sys/src/9/pc/trap.c
+++ b/sys/src/9/pc/trap.c
@@ -382,14 +382,11 @@
 static void
 debugbpt(Ureg* ureg, void*)
 {
-	char buf[ERRMAX];
-
 	if(up == 0)
 		panic("kernel bpt");
 	/* restore pc to instruction that caused the trap */
 	ureg->pc--;
-	sprint(buf, "sys: breakpoint");
-	postnote(up, 1, buf, NDebug);
+	postnote(up, 1, "sys: breakpoint", NDebug);
 }
 
 static void
@@ -500,9 +497,7 @@
 			startns = todget(nil);
 		}
 
-		if(scallnr >= nsyscall || systab[scallnr] == 0){
-			pprint("bad sys call number %lud pc %lux\n",
-				scallnr, ureg->pc);
+		if(scallnr >= nsyscall || systab[scallnr] == nil){
 			postnote(up, 1, "sys: bad sys call", NDebug);
 			error(Ebadarg);
 		}
@@ -548,13 +543,14 @@
 	if(scallnr == NOTED)
 		noted(ureg, *((ulong*)up->s.args));
 
-	if(scallnr!=RFORK && (up->procctl || up->nnote)){
-		splhi();
+	splhi();
+	if(scallnr!=RFORK && (up->procctl || up->nnote))
 		notify(ureg);
-	}
 	/* if we delayed sched because we held a lock, sched now */
-	if(up->delaysched)
+	if(up->delaysched){
 		sched();
+		splhi();
+	}
 	kexit(ureg);
 }
 
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -111,6 +111,19 @@
 	if(user){
 		up->dbgreg = ureg;
 		cycles(&up->kentry);
+	} else {
+		int rem;
+
+		if((uchar*)&ureg < (uchar*)ureg){
+			/* stack grows down */
+			rem = (int)((uintptr)ureg - (up!=nil? (uintptr)up - KSTACK: (uintptr)m->stack));
+		} else {
+			/* stack grows up */
+			rem = (int)((up!=nil? (uintptr)up: (uintptr)m + MACHSIZE) - (uintptr)ureg);
+		}
+		if(rem < 256)
+			panic("kenter: %d stack bytes left, up %#p ureg %#p at pc %#p",
+				rem, up, ureg, ureg->pc);
 	}
 	return user;
 }
--- a/sys/src/9/ppc/trap.c
+++ b/sys/src/9/ppc/trap.c
@@ -282,9 +282,6 @@
 	splhi();
 
 	if(user) {
-		if (up->fpstate == FPactive && (ureg->srr1 & MSR_FP) == 0){
-			postnote(up, 1, buf, NDebug);
-		}
 		notify(ureg);
 		if(up->fpstate != FPactive)
 			ureg->srr1 &= ~MSR_FP;
@@ -600,18 +597,15 @@
 	up->nerrlab = 0;
 	ret = -1;
 	if(!waserror()){
-		if(scallnr >= nsyscall || systab[scallnr] == nil){
-			pprint("bad sys call number %d pc %lux\n", scallnr, ureg->pc);
-			postnote(up, 1, "sys: bad sys call", NDebug);
-			error(Ebadarg);
-		}
-
 		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs)-BY2WD))
 			validaddr(sp, sizeof(Sargs)+BY2WD, 0);
 
 		up->s = *((Sargs*)(sp+BY2WD));
+		if(scallnr >= nsyscall || systab[scallnr] == nil){
+			postnote(up, 1, "sys: bad sys call", NDebug);
+			error(Ebadarg);
+		}
 		up->psstate = sysctab[scallnr];
-
 		ret = systab[scallnr]((va_list)up->s.args);
 		poperror();
 	}else{
--- a/sys/src/9/sgi/trap.c
+++ b/sys/src/9/sgi/trap.c
@@ -158,21 +158,7 @@
 	int ecode, user, cop, x, fpchk;
 	ulong fpfcr31;
 	char buf[2*ERRMAX], buf1[ERRMAX], *fpexcep;
-	static int dumps;
 
-	if (up && (char *)(ur) - ((char *)up - KSTACK) < 1024 && dumps++ == 0) {
-		iprint("trap: proc %ld kernel stack getting full\n", up->pid);
-		dumpregs(ur);
-		dumpstack();
-		for(;;);
-	}
-	if (up == nil &&
-	    (char *)(ur) - (char *)m->stack < 1024 && dumps++ == 0) {
-		iprint("trap: cpu%d kernel stack getting full\n", m->machno);
-		dumpregs(ur);
-		dumpstack();
-		for(;;);
-	}
 	user = kenter(ur);
 	if (ur->cause & TS)
 		panic("trap: tlb shutdown");
@@ -662,16 +648,7 @@
 	up->nerrlab = 0;
 	ret = -1;
 	if(!waserror()) {
-		if(scallnr >= nsyscall || systab[scallnr] == 0){
-			pprint("bad sys call number %ld pc %#lux\n",
-				scallnr, ur->pc);
-			postnote(up, 1, "sys: bad sys call", NDebug);
-			error(Ebadarg);
-		}
-
 		if(sp & (BY2WD-1)){
-			pprint("odd sp in sys call pc %#lux sp %#lux\n",
-				ur->pc, ur->sp);
 			postnote(up, 1, "sys: odd stack", NDebug);
 			error(Ebadarg);
 		}
@@ -680,6 +657,10 @@
 			validaddr(sp, sizeof(Sargs)+BY2WD, 0);
 
 		up->s = *((Sargs*)(sp+BY2WD));
+		if(scallnr >= nsyscall || systab[scallnr] == nil){
+			postnote(up, 1, "sys: bad sys call", NDebug);
+			error(Ebadarg);
+		}
 		up->psstate = sysctab[scallnr];
 
 		ret = systab[scallnr]((va_list)up->s.args);
@@ -714,8 +695,10 @@
 	if(scallnr!=RFORK && (up->procctl || up->nnote))
 		notify(ur);
 	/* if we delayed sched because we held a lock, sched now */
-	if(up->delaysched)
+	if(up->delaysched){
 		sched();
+		splhi();
+	}
 	/* replicate fpstate to ureg status */
 	if(up->fpstate != FPactive)
 		ur->status &= ~CU1;
--- a/sys/src/9/teg2/syscall.c
+++ b/sys/src/9/teg2/syscall.c
@@ -206,21 +206,15 @@
 
 	l1cache->wb();			/* system is more stable with this */
 	if(!waserror()){
-		if(scallnr >= nsyscall){
-			pprint("bad sys call number %d pc %#lux\n",
-				scallnr, ureg->pc);
-			postnote(up, 1, "sys: bad sys call", NDebug);
-			error(Ebadarg);
-		}
-
 		if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD))
 			validaddr(sp, sizeof(Sargs)+BY2WD, 0);
 
 		up->s = *((Sargs*)(sp+BY2WD));
+		if(scallnr >= nsyscall || systab[scallnr] == nil){
+			postnote(up, 1, "sys: bad sys call", NDebug);
+			error(Ebadarg);
+		}
 		up->psstate = sysctab[scallnr];
-
-	/*	iprint("%s: syscall %s\n", up->text, sysctab[scallnr]?sysctab[scallnr]:"huh?"); */
-
 		ret = systab[scallnr]((va_list)up->s.args);
 		poperror();
 	}else{
--- a/sys/src/9/teg2/trap.c
+++ b/sys/src/9/teg2/trap.c
@@ -633,12 +633,12 @@
 irq(Ureg* ureg)
 {
 	int clockintr, ack;
-	uint irqno, handled, t, ticks;
+	uint irqno, handled;
 	Intrcpuregs *icp = (Intrcpuregs *)soc.intr;
 	Vctl *v;
 
 	m->intr++;
-	ticks = perfticks();
+	m->perf.intrts = perfticks();
 	handled = 0;
 	ack = intack(icp);
 	irqno = ack & Intrmask;
@@ -677,17 +677,6 @@
 			iprint("cpu%d: unexpected interrupt %d, now masked\n",
 				m->machno, irqno);
 		}
-	t = perfticks();
-	if (0) {			/* left over from another port? */
-		ilock(&nintrlock);
-		ninterrupt++;
-		if(t < ticks)
-			ninterruptticks += ticks-t;
-		else
-			ninterruptticks += t-ticks;
-		iunlock(&nintrlock);
-	}
-	USED(t, ticks);
 	clockintr = m->inclockintr == 1;
 	if (irqno == Loctmrirq)
 		m->inclockintr--;
@@ -818,20 +807,6 @@
 	int user, rem;
 	uintptr va, ifar, ifsr;
 
-	splhi();			/* paranoia */
-	if(up != nil)
-		rem = ((char*)ureg)-((char*)up-KSTACK);
-	else
-		rem = ((char*)ureg)-((char*)m+sizeof(Mach));
-	if(rem < 1024) {
-		iprint("trap: %d stack bytes left, up %#p ureg %#p m %#p cpu%d at pc %#lux\n",
-			rem, up, ureg, m, m->machno, ureg->pc);
-		dumpstackwithureg(ureg);
-		panic("trap: %d stack bytes left, up %#p ureg %#p at pc %#lux",
-			rem, up, ureg, ureg->pc);
-	}
-
-	m->perf.intrts = perfticks();
 	user = kenter(ureg);
 	/*
 	 * All interrupts/exceptions should be resumed at ureg->pc-4,
--- a/sys/src/9/xen/trap.c
+++ b/sys/src/9/xen/trap.c
@@ -303,15 +303,11 @@
 static void
 debugbpt(Ureg* ureg, void*)
 {
-	char buf[ERRMAX];
-	print("debugbpt\n");
 	if(up == 0)
 		panic("kernel bpt");
 	/* restore pc to instruction that caused the trap */
 	ureg->pc--;
-	sprint(buf, "sys: breakpoint");
-	postnote(up, 1, buf, NDebug);
-	print("debugbpt for proc %lud\n", up->pid);
+	postnote(up, 1, "sys: breakpoint", NDebug);
 }
 
 static void
@@ -409,19 +405,16 @@
 	up->nerrlab = 0;
 	ret = -1;
 	if(!waserror()){
-		if(scallnr >= nsyscall || systab[scallnr] == 0){
-			pprint("bad sys call number %lud pc %lux\n",
-				scallnr, ureg->pc);
-			postnote(up, 1, "sys: bad sys call", NDebug);
-			error(Ebadarg);
-		}
-
 		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs)-BY2WD))
 			validaddr(sp, sizeof(Sargs)+BY2WD, 0);
 
 		up->s = *((Sargs*)(sp+BY2WD));
-		up->psstate = sysctab[scallnr];
 
+		if(scallnr >= nsyscall || systab[scallnr] == nil){
+			postnote(up, 1, "sys: bad sys call", NDebug);
+			error(Ebadarg);
+		}
+		up->psstate = sysctab[scallnr];
 		ret = systab[scallnr]((va_list)up->s.args);
 		poperror();
 	}else{
@@ -462,13 +455,14 @@
 	if(scallnr == NOTED)
 		noted(ureg, *(ulong*)(sp+BY2WD));
 
-	if(scallnr!=RFORK && (up->procctl || up->nnote)){
-		splhi();
+	splhi();
+	if(scallnr!=RFORK && (up->procctl || up->nnote))
 		notify(ureg);
-	}
 	/* if we delayed sched because we held a lock, sched now */
-	if(up->delaysched)
+	if(up->delaysched){
 		sched();
+		splhi();
+	}
 	INTRLOG(dprint("before kexit\n");)
 	kexit(ureg);
 }
--- a/sys/src/9/zynq/trap.c
+++ b/sys/src/9/zynq/trap.c
@@ -236,9 +236,7 @@
 			splx(s);
 			startns = todget(nil);
 		}
-		
-		if(scallnr >= nsyscall || systab[scallnr] == 0){
-			pprint("bad sys call number %lud pc %lux", scallnr, ureg->pc);
+		if(scallnr >= nsyscall || systab[scallnr] == nil){
 			postnote(up, 1, "sys: bad sys call", NDebug);
 			error(Ebadarg);
 		}
@@ -272,14 +270,14 @@
 	if(scallnr == NOTED)
 		noted(ureg, *((ulong *) up->s.args));
 
-	if(scallnr != RFORK && (up->procctl || up->nnote)){
-		splhi();
+	splhi();
+	if(scallnr != RFORK && (up->procctl || up->nnote))
 		notify(ureg);
-	}
-	if(up->delaysched)
+	if(up->delaysched){
 		sched();
+		splhi();
+	}
 	kexit(ureg);
-	splhi();
 }
 
 int