code: plan9front

Download patch

ref: c8e25d2a18c0395431abc5818a1d2f0561b0181f
parent: 7828ffb8a486e188b61394436a434e8cae4fd487
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Wed Aug 17 11:21:22 EDT 2022

kernel: simplify notify() adding common popnote() function

Handlin notes is common for all architectures
except how the note has to be pushed on the user
stack.

This change adds a popnote() function that returns
only the note string or nil if the process should
not be notified (no notes or user notes hold off).

Popnote() also handles common errors like notify
during note handling or missing note handler and
will suicide the process in that case.

--- a/sys/src/9/bcm64/trap.c
+++ b/sys/src/9/bcm64/trap.c
@@ -274,9 +274,8 @@
 int
 notify(Ureg *ureg)
 {
-	int l;
 	uintptr s, sp;
-	Note *n;
+	char *msg;
 
 	if(up->procctl)
 		procctl();
@@ -290,32 +289,13 @@
 
 	s = spllo();
 	qlock(&up->debug);
-	up->notepending = 0;
-	n = &up->note[0];
-	if(strncmp(n->msg, "sys:", 4) == 0){
-		l = strlen(n->msg);
-		if(l > ERRMAX-23)	/* " pc=0x0123456789abcdef\0" */
-			l = ERRMAX-23;
-		sprint(n->msg+l, " pc=%#p", ureg->pc);
-	}
-
-	if(n->flag!=NUser && (up->notified || up->notify==0)){
+	msg = popnote(ureg);
+	if(msg == nil){
 		qunlock(&up->debug);
-		if(n->flag == NDebug)
-			pprint("suicide: %s\n", n->msg);
-		pexit(n->msg, n->flag!=NDebug);
-	}
-
-	if(up->notified){
-		qunlock(&up->debug);
 		splhi();
 		return 0;
 	}
 
-	if(!up->notify){
-		qunlock(&up->debug);
-		pexit(n->msg, n->flag!=NDebug);
-	}
 	sp = ureg->sp;
 	sp -= 256;	/* debugging: preserve context causing problem */
 	sp -= sizeof(Ureg);
@@ -335,7 +315,7 @@
 	*(Ureg**)(sp-BY2WD) = up->ureg;	/* word under Ureg is old up->ureg */
 	up->ureg = (void*)sp;
 	sp -= BY2WD+ERRMAX;
-	memmove((char*)sp, up->note[0].msg, ERRMAX);
+	memmove((char*)sp, msg, ERRMAX);
 	sp -= 3*BY2WD;
 	*(uintptr*)(sp+2*BY2WD) = sp+3*BY2WD;
 	*(uintptr*)(sp+1*BY2WD) = (uintptr)up->ureg;
@@ -343,11 +323,6 @@
 	ureg->sp = sp;
 	ureg->pc = (uintptr) up->notify;
 	ureg->link = 0;
-	up->notified = 1;
-	up->nnote--;
-	memmove(&up->lastnote, &up->note[0], sizeof(Note));
-	memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
-
 	qunlock(&up->debug);
 	splx(s);
 	return 1;
--- a/sys/src/9/cycv/trap.c
+++ b/sys/src/9/cycv/trap.c
@@ -285,9 +285,8 @@
 int
 notify(Ureg *ureg)
 {
-	int l;
 	ulong s, sp;
-	Note *n;
+	char *msg;
 
 	if(up->procctl)
 		procctl();
@@ -302,32 +301,13 @@
 
 	s = spllo();
 	qlock(&up->debug);
-	up->notepending = 0;
-	n = &up->note[0];
-	if(strncmp(n->msg, "sys:", 4) == 0){
-		l = strlen(n->msg);
-		if(l > ERRMAX-15)	/* " pc=0x12345678\0" */
-			l = ERRMAX-15;
-		sprint(n->msg+l, " pc=0x%.8lux", ureg->pc);
-	}
-
-	if(n->flag!=NUser && (up->notified || up->notify==0)){
+	msg = popnote(ureg);
+	if(msg == nil){
 		qunlock(&up->debug);
-		if(n->flag == NDebug)
-			pprint("suicide: %s\n", n->msg);
-		pexit(n->msg, n->flag!=NDebug);
-	}
-
-	if(up->notified){
-		qunlock(&up->debug);
 		splhi();
 		return 0;
 	}
 
-	if(!up->notify){
-		qunlock(&up->debug);
-		pexit(n->msg, n->flag!=NDebug);
-	}
 	sp = ureg->sp;
 	sp -= 256;	/* debugging: preserve context causing problem */
 	sp -= sizeof(Ureg);
@@ -345,7 +325,7 @@
 	*(Ureg**)(sp-BY2WD) = up->ureg;	/* word under Ureg is old up->ureg */
 	up->ureg = (void*)sp;
 	sp -= BY2WD+ERRMAX;
-	memmove((char*)sp, up->note[0].msg, ERRMAX);
+	memmove((char*)sp, msg, ERRMAX);
 	sp -= 3*BY2WD;
 	*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD;
 	*(ulong*)(sp+1*BY2WD) = (ulong)up->ureg;
@@ -353,11 +333,6 @@
 	ureg->sp = sp;
 	ureg->pc = (uintptr) up->notify;
 	ureg->r14 = 0;
-	up->notified = 1;
-	up->nnote--;
-	memmove(&up->lastnote, &up->note[0], sizeof(Note));
-	memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
-
 	qunlock(&up->debug);
 	splx(s);
 	return 1;
--- a/sys/src/9/imx8/trap.c
+++ b/sys/src/9/imx8/trap.c
@@ -274,9 +274,8 @@
 int
 notify(Ureg *ureg)
 {
-	int l;
 	uintptr s, sp;
-	Note *n;
+	char *msg;
 
 	if(up->procctl)
 		procctl();
@@ -290,32 +289,13 @@
 
 	s = spllo();
 	qlock(&up->debug);
-	up->notepending = 0;
-	n = &up->note[0];
-	if(strncmp(n->msg, "sys:", 4) == 0){
-		l = strlen(n->msg);
-		if(l > ERRMAX-23)	/* " pc=0x0123456789abcdef\0" */
-			l = ERRMAX-23;
-		sprint(n->msg+l, " pc=%#p", ureg->pc);
-	}
-
-	if(n->flag!=NUser && (up->notified || up->notify==0)){
+	msg = popnote(ureg);
+	if(msg == nil){
 		qunlock(&up->debug);
-		if(n->flag == NDebug)
-			pprint("suicide: %s\n", n->msg);
-		pexit(n->msg, n->flag!=NDebug);
-	}
-
-	if(up->notified){
-		qunlock(&up->debug);
 		splhi();
 		return 0;
 	}
 
-	if(!up->notify){
-		qunlock(&up->debug);
-		pexit(n->msg, n->flag!=NDebug);
-	}
 	sp = ureg->sp;
 	sp -= 256;	/* debugging: preserve context causing problem */
 	sp -= sizeof(Ureg);
@@ -335,7 +315,7 @@
 	*(Ureg**)(sp-BY2WD) = up->ureg;	/* word under Ureg is old up->ureg */
 	up->ureg = (void*)sp;
 	sp -= BY2WD+ERRMAX;
-	memmove((char*)sp, up->note[0].msg, ERRMAX);
+	memmove((char*)sp, msg, ERRMAX);
 	sp -= 3*BY2WD;
 	*(uintptr*)(sp+2*BY2WD) = sp+3*BY2WD;
 	*(uintptr*)(sp+1*BY2WD) = (uintptr)up->ureg;
@@ -343,11 +323,6 @@
 	ureg->sp = sp;
 	ureg->pc = (uintptr) up->notify;
 	ureg->link = 0;
-	up->notified = 1;
-	up->nnote--;
-	memmove(&up->lastnote, &up->note[0], sizeof(Note));
-	memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
-
 	qunlock(&up->debug);
 	splx(s);
 	return 1;
--- a/sys/src/9/kw/syscall.c
+++ b/sys/src/9/kw/syscall.c
@@ -98,11 +98,10 @@
 int
 notify(Ureg* ureg)
 {
-	int l;
-	Note *n;
 	u32int s;
 	uintptr sp;
 	NFrame *nf;
+	char *msg;
 
 	if(up->procctl)
 		procctl();
@@ -113,33 +112,13 @@
 
 	s = spllo();
 	qlock(&up->debug);
-
-	up->notepending = 0;
-	n = &up->note[0];
-	if(strncmp(n->msg, "sys:", 4) == 0){
-		l = strlen(n->msg);
-		if(l > ERRMAX-23)	/* " pc=0x0123456789abcdef\0" */
-			l = ERRMAX-23;
-		snprint(n->msg + l, sizeof n->msg - l, " pc=%#lux", ureg->pc);
-	}
-
-	if(n->flag != NUser && (up->notified || up->notify == 0)){
+	msg = popnote(ureg);
+	if(msg == nil){
 		qunlock(&up->debug);
-		if(n->flag == NDebug)
-			pprint("suicide: %s\n", n->msg);
-		pexit(n->msg, n->flag != NDebug);
-	}
-
-	if(up->notified){
-		qunlock(&up->debug);
 		splhi();
 		return 0;
 	}
-		
-	if(up->notify == nil){
-		qunlock(&up->debug);
-		pexit(n->msg, n->flag != NDebug);
-	}
+
 	if(!okaddr((uintptr)up->notify, 1, 0)){
 		qunlock(&up->debug);
 		pprint("suicide: notify function address %#p\n", up->notify);
@@ -157,7 +136,7 @@
 	memmove(&nf->ureg, ureg, sizeof(Ureg));
 	nf->old = up->ureg;
 	up->ureg = nf;
-	memmove(nf->msg, up->note[0].msg, ERRMAX);
+	memmove(nf->msg, msg, ERRMAX);
 	nf->arg1 = nf->msg;
 	nf->arg0 = &nf->ureg;
 	nf->ip = 0;
@@ -165,11 +144,6 @@
 	ureg->sp = sp;
 	ureg->pc = (uintptr)up->notify;
 	ureg->r0 = (uintptr)nf->arg0;
-
-	up->notified = 1;
-	up->nnote--;
-	memmove(&up->lastnote, &up->note[0], sizeof(Note));
-	memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
 
 	qunlock(&up->debug);
 	splx(s);
--- a/sys/src/9/mtx/trap.c
+++ b/sys/src/9/mtx/trap.c
@@ -677,9 +677,8 @@
 int
 notify(Ureg* ur)
 {
-	int l;
 	ulong s, sp;
-	Note *n;
+	char *msg;
 
 	if(up->procctl)
 		procctl();
@@ -688,32 +687,13 @@
 
 	s = spllo();
 	qlock(&up->debug);
-	up->notepending = 0;
-	n = &up->note[0];
-	if(strncmp(n->msg, "sys:", 4) == 0){
-		l = strlen(n->msg);
-		if(l > ERRMAX-15)	/* " pc=0x12345678\0" */
-			l = ERRMAX-15;
-		sprint(n->msg+l, " pc=0x%.8lux", ur->pc);
-	}
-
-	if(n->flag!=NUser && (up->notified || up->notify==0)){
+	msg = popnote(ur);
+	if(msg == nil){
 		qunlock(&up->debug);
-		if(n->flag == NDebug)
-			pprint("suicide: %s\n", n->msg);
-		pexit(n->msg, n->flag!=NDebug);
-	}
-
-	if(up->notified) {
-		qunlock(&up->debug);
 		splhi();
 		return 0;
 	}
 
-	if(!up->notify) {
-		qunlock(&up->debug);
-		pexit(n->msg, n->flag!=NDebug);
-	}
 	sp = ur->usp & ~(BY2V-1);
 	sp -= sizeof(Ureg);
 
@@ -728,7 +708,7 @@
 	*(Ureg**)(sp-BY2WD) = up->ureg;	/* word under Ureg is old up->ureg */
 	up->ureg = (void*)sp;
 	sp -= BY2WD+ERRMAX;
-	memmove((char*)sp, up->note[0].msg, ERRMAX);
+	memmove((char*)sp, msg, ERRMAX);
 	sp -= 3*BY2WD;
 	*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD;	/* arg 2 is string */
 	ur->r1 = (long)up->ureg;		/* arg 1 is ureg* */
@@ -736,11 +716,6 @@
 	((ulong*)sp)[0] = 0;			/* arg 0 is pc */
 	ur->usp = sp;
 	ur->pc = (ulong)up->notify;
-	up->notified = 1;
-	up->nnote--;
-	memmove(&up->lastnote, &up->note[0], sizeof(Note));
-	memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
-
 	qunlock(&up->debug);
 	splx(s);
 	return 1;
--- a/sys/src/9/omap/syscall.c
+++ b/sys/src/9/omap/syscall.c
@@ -98,11 +98,10 @@
 int
 notify(Ureg* ureg)
 {
-	int l;
-	Note *n;
 	u32int s;
 	uintptr sp;
 	NFrame *nf;
+	char *msg;
 
 	if(up->procctl)
 		procctl();
@@ -113,33 +112,13 @@
 
 	s = spllo();
 	qlock(&up->debug);
-
-	up->notepending = 0;
-	n = &up->note[0];
-	if(strncmp(n->msg, "sys:", 4) == 0){
-		l = strlen(n->msg);
-		if(l > ERRMAX-23)	/* " pc=0x0123456789abcdef\0" */
-			l = ERRMAX-23;
-		snprint(n->msg + l, sizeof n->msg - l, " pc=%#lux", ureg->pc);
-	}
-
-	if(n->flag != NUser && (up->notified || up->notify == 0)){
+	msg = popnote(ureg);
+	if(msg == nil){
 		qunlock(&up->debug);
-		if(n->flag == NDebug)
-			pprint("suicide: %s\n", n->msg);
-		pexit(n->msg, n->flag != NDebug);
-	}
-
-	if(up->notified){
-		qunlock(&up->debug);
 		splhi();
 		return 0;
 	}
-		
-	if(up->notify == nil){
-		qunlock(&up->debug);
-		pexit(n->msg, n->flag != NDebug);
-	}
+
 	if(!okaddr((uintptr)up->notify, 1, 0)){
 		qunlock(&up->debug);
 		pprint("suicide: notify function address %#p\n", up->notify);
@@ -157,7 +136,7 @@
 	memmove(&nf->ureg, ureg, sizeof(Ureg));
 	nf->old = up->ureg;
 	up->ureg = nf;
-	memmove(nf->msg, up->note[0].msg, ERRMAX);
+	memmove(nf->msg, msg, ERRMAX);
 	nf->arg1 = nf->msg;
 	nf->arg0 = &nf->ureg;
 	nf->ip = 0;
@@ -165,11 +144,6 @@
 	ureg->sp = sp;
 	ureg->pc = (uintptr)up->notify;
 	ureg->r0 = (uintptr)nf->arg0;
-
-	up->notified = 1;
-	up->nnote--;
-	memmove(&up->lastnote, &up->note[0], sizeof(Note));
-	memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
 
 	qunlock(&up->debug);
 	splx(s);
--- a/sys/src/9/pc/trap.c
+++ b/sys/src/9/pc/trap.c
@@ -565,9 +565,8 @@
 int
 notify(Ureg* ureg)
 {
-	int l;
 	ulong s, sp;
-	Note *n;
+	char *msg;
 
 	if(up->procctl)
 		procctl();
@@ -582,37 +581,18 @@
 
 	s = spllo();
 	qlock(&up->debug);
-	up->notepending = 0;
-	n = &up->note[0];
-	if(strncmp(n->msg, "sys:", 4) == 0){
-		l = strlen(n->msg);
-		if(l > ERRMAX-15)	/* " pc=0x12345678\0" */
-			l = ERRMAX-15;
-		sprint(n->msg+l, " pc=0x%.8lux", ureg->pc);
-	}
-
-	if(n->flag!=NUser && (up->notified || up->notify==0)){
+	msg = popnote(ureg);
+	if(msg == nil){
 		qunlock(&up->debug);
-		if(n->flag == NDebug)
-			pprint("suicide: %s\n", n->msg);
-		pexit(n->msg, n->flag!=NDebug);
-	}
-
-	if(up->notified){
-		qunlock(&up->debug);
 		splhi();
 		return 0;
 	}
 
-	if(!up->notify){
-		qunlock(&up->debug);
-		pexit(n->msg, n->flag!=NDebug);
-	}
 	sp = ureg->usp;
 	sp -= 256;	/* debugging: preserve context causing problem */
 	sp -= sizeof(Ureg);
 if(0) print("%s %lud: notify %.8lux %.8lux %.8lux %s\n",
-	up->text, up->pid, ureg->pc, ureg->usp, sp, n->msg);
+	up->text, up->pid, ureg->pc, ureg->usp, sp, msg);
 
 	if(!okaddr((uintptr)up->notify, 1, 0)
 	|| !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)){
@@ -625,7 +605,7 @@
 	*(Ureg**)(sp-BY2WD) = up->ureg;	/* word under Ureg is old up->ureg */
 	up->ureg = (void*)sp;
 	sp -= BY2WD+ERRMAX;
-	memmove((char*)sp, up->note[0].msg, ERRMAX);
+	memmove((char*)sp, msg, ERRMAX);
 	sp -= 3*BY2WD;
 	*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD;		/* arg 2 is string */
 	*(ulong*)(sp+1*BY2WD) = (ulong)up->ureg;	/* arg 1 is ureg* */
@@ -634,11 +614,6 @@
 	ureg->pc = (ulong)up->notify;
 	ureg->cs = UESEL;
 	ureg->ss = ureg->ds = ureg->es = UDSEL;
-	up->notified = 1;
-	up->nnote--;
-	memmove(&up->lastnote, &up->note[0], sizeof(Note));
-	memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
-
 	qunlock(&up->debug);
 	splx(s);
 	return 1;
--- a/sys/src/9/pc64/trap.c
+++ b/sys/src/9/pc64/trap.c
@@ -554,9 +554,8 @@
 int
 notify(Ureg* ureg)
 {
-	int l;
 	uintptr sp;
-	Note *n;
+	char *msg;
 
 	if(up->procctl)
 		procctl();
@@ -564,39 +563,18 @@
 		return 0;
 	spllo();
 	qlock(&up->debug);
-	up->notepending = 0;
-	n = &up->note[0];
-	if(strncmp(n->msg, "sys:", 4) == 0){
-		l = strlen(n->msg);
-		if(l > ERRMAX-15)	/* " pc=0x12345678\0" */
-			l = ERRMAX-15;
-		sprint(n->msg+l, " pc=%#p", ureg->pc);
-	}
-
-	if(n->flag!=NUser && (up->notified || up->notify==0)){
+	msg = popnote(ureg);
+	if(msg == nil){
 		qunlock(&up->debug);
-		if(n->flag == NDebug){
-			up->fpstate &= ~FPillegal;
-			pprint("suicide: %s\n", n->msg);
-		}
-		pexit(n->msg, n->flag!=NDebug);
-	}
-
-	if(up->notified){
-		qunlock(&up->debug);
 		splhi();
 		return 0;
 	}
 
-	if(!up->notify){
-		qunlock(&up->debug);
-		pexit(n->msg, n->flag!=NDebug);
-	}
 	sp = ureg->sp;
 	sp -= 256;	/* debugging: preserve context causing problem */
 	sp -= sizeof(Ureg);
 if(0) print("%s %lud: notify %#p %#p %#p %s\n",
-	up->text, up->pid, ureg->pc, ureg->sp, sp, n->msg);
+	up->text, up->pid, ureg->pc, ureg->sp, sp, msg);
 
 	if(!okaddr((uintptr)up->notify, 1, 0)
 	|| !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)){
@@ -610,7 +588,7 @@
 	*(Ureg**)(sp-BY2WD) = up->ureg;	/* word under Ureg is old up->ureg */
 	up->ureg = (void*)sp;
 	sp -= BY2WD+ERRMAX;
-	memmove((char*)sp, up->note[0].msg, ERRMAX);
+	memmove((char*)sp, msg, ERRMAX);
 	sp -= 3*BY2WD;
 	((uintptr*)sp)[2] = sp + 3*BY2WD;	/* arg2 string */
 	((uintptr*)sp)[1] = (uintptr)up->ureg;	/* arg1 is ureg* */
@@ -620,10 +598,6 @@
 	ureg->bp = (uintptr)up->ureg;		/* arg1 passed in RARG */
 	ureg->cs = UESEL;
 	ureg->ss = UDSEL;
-	up->notified = 1;
-	up->nnote--;
-	memmove(&up->lastnote, &up->note[0], sizeof(Note));
-	memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
 	qunlock(&up->debug);
 	splhi();
 	if(up->fpstate == FPactive){
--- a/sys/src/9/port/portfns.h
+++ b/sys/src/9/port/portfns.h
@@ -235,6 +235,7 @@
 #define		waserror()		setlabel(&up->errlab[up->nerrlab++])
 #define		poperror()		up->nerrlab--
 void		portcountpagerefs(ulong*, int);
+char*		popnote(Ureg*);
 int		postnote(Proc*, int, char*, int);
 int		pprint(char*, ...);
 int		preempted(void);
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -899,6 +899,48 @@
 }
 
 /*
+ *  pop a note from the calling process or suicide if theres
+ *  no note handler or notify during note handling. 
+ *  Called from notify() with up->debug lock held.
+ */
+char*
+popnote(Ureg *u)
+{
+	assert(!canqlock(&up->debug));
+
+	up->notepending = 0;
+	if(up->nnote == 0)
+		return nil;
+	assert(up->nnote > 0);
+
+	/* hold off user notes during note handling */
+	if(up->notified && up->note[0].flag == NUser)
+		return nil;
+
+	memmove(&up->lastnote, &up->note[0], sizeof(Note));
+	if(--up->nnote)
+		memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
+
+	if(u != nil && strncmp(up->lastnote.msg, "sys:", 4) == 0){
+		int l = strlen(up->lastnote.msg);
+		assert(l < ERRMAX);
+		snprint(up->lastnote.msg+l, ERRMAX-l, " pc=%#p", u->pc);
+	}
+
+	if(up->notify == nil || up->notified){
+		qunlock(&up->debug);
+		if(up->lastnote.flag == NDebug){
+			up->fpstate &= ~FPillegal;
+			pprint("suicide: %s\n", up->lastnote.msg);
+		}
+		pexit(up->lastnote.msg, up->lastnote.flag!=NDebug);
+	}
+	up->notified = 1;
+
+	return up->lastnote.msg;
+}
+
+/*
  *  if waking a sleeping process, this routine must hold both
  *  p->rlock and r->lock.  However, it can't know them in
  *  the same order as wakeup causing a possible lock ordering
--- a/sys/src/9/ppc/trap.c
+++ b/sys/src/9/ppc/trap.c
@@ -666,9 +666,8 @@
 int
 notify(Ureg* ur)
 {
-	int l;
 	ulong s, sp;
-	Note *n;
+	char *msg;
 
 	if(up->procctl)
 		procctl();
@@ -683,33 +682,13 @@
 
 	s = spllo();
 	qlock(&up->debug);
-	up->notepending = 0;
-	n = &up->note[0];
-	if(strncmp(n->msg, "sys:", 4) == 0){
-		l = strlen(n->msg);
-		if(l > ERRMAX-15)	/* " pc=0x12345678\0" */
-			l = ERRMAX-15;
-		sprint(n->msg+l, " pc=0x%.8lux", ur->pc);
-	}
-
-	if(n->flag!=NUser && (up->notified || up->notify==0)){
+	msg = popnote(ur);
+	if(msg == nil){
 		qunlock(&up->debug);
-		if(n->flag == NDebug)
-			pprint("suicide: %s\n", n->msg);
-		pexit(n->msg, n->flag!=NDebug);
-	}
-
-	if(up->notified) {
-		qunlock(&up->debug);
 		splhi();
 		return 0;
 	}
 
-	if(!up->notify) {
-		qunlock(&up->debug);
-		pexit(n->msg, n->flag!=NDebug);
-	}
-
 	sp = ur->usp & ~(BY2V-1);
 	sp -= sizeof(Ureg);
 
@@ -724,7 +703,7 @@
 	*(Ureg**)(sp-BY2WD) = up->ureg;	/* word under Ureg is old up->ureg */
 	up->ureg = (void*)sp;
 	sp -= BY2WD+ERRMAX;
-	memmove((char*)sp, up->note[0].msg, ERRMAX);
+	memmove((char*)sp, msg, ERRMAX);
 	sp -= 3*BY2WD;
 	*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD;	/* arg 2 is string */
 	ur->r1 = (long)up->ureg;		/* arg 1 is ureg* */
@@ -732,11 +711,6 @@
 	((ulong*)sp)[0] = 0;			/* arg 0 is pc */
 	ur->usp = sp;
 	ur->pc = (ulong)up->notify;
-	up->notified = 1;
-	up->nnote--;
-	memmove(&up->lastnote, &up->note[0], sizeof(Note));
-	memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
-
 	qunlock(&up->debug);
 	splx(s);
 	return 1;
--- a/sys/src/9/sgi/trap.c
+++ b/sys/src/9/sgi/trap.c
@@ -470,9 +470,9 @@
 int
 notify(Ureg *ur)
 {
-	int l, s;
+	int s;
 	ulong sp;
-	Note *n;
+	char *msg;
 
 	if(up->procctl)
 		procctl();
@@ -487,34 +487,13 @@
 
 	s = spllo();
 	qlock(&up->debug);
-	up->notepending = 0;
-	n = &up->note[0];
-	if(strncmp(n->msg, "sys:", 4) == 0) {
-		l = strlen(n->msg);
-		if(l > ERRMAX-15)	/* " pc=0x12345678\0" */
-			l = ERRMAX-15;
-
-		seprint(n->msg+l, &n->msg[sizeof n->msg], " pc=%#lux", ur->pc);
-	}
-
-	if(n->flag != NUser && (up->notified || up->notify==0)) {
-		if(n->flag == NDebug)
-			pprint("suicide: %s\n", n->msg);
-
+	msg = popnote(ur);
+	if(msg == nil){
 		qunlock(&up->debug);
-		pexit(n->msg, n->flag!=NDebug);
-	}
-
-	if(up->notified) {
-		qunlock(&up->debug);
 		splx(s);
 		return 0;
 	}
 
-	if(!up->notify) {
-		qunlock(&up->debug);
-		pexit(n->msg, n->flag!=NDebug);
-	}
 	sp = ur->usp & ~(BY2V-1);
 	sp -= sizeof(Ureg);
 
@@ -530,7 +509,7 @@
 	up->ureg = (void*)sp;
 
 	sp -= BY2WD+ERRMAX;
-	memmove((char*)sp, up->note[0].msg, ERRMAX);	/* push err string */
+	memmove((char*)sp, msg, ERRMAX);	/* push err string */
 
 	sp -= 3*BY2WD;
 	*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD;	/* arg 2 is string */
@@ -543,11 +522,6 @@
 	 * were being called.
 	 */
 	ur->pc = (ulong)up->notify;
-
-	up->notified = 1;
-	up->nnote--;
-	memmove(&up->lastnote, &up->note[0], sizeof(Note));
-	memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
 
 	qunlock(&up->debug);
 	splx(s);
--- a/sys/src/9/teg2/syscall.c
+++ b/sys/src/9/teg2/syscall.c
@@ -104,11 +104,10 @@
 int
 notify(Ureg* ureg)
 {
-	int l;
-	Note *n;
 	u32int s;
 	uintptr sp;
 	NFrame *nf;
+	char *msg;
 
 	if(up->procctl)
 		procctl();
@@ -119,33 +118,13 @@
 
 	s = spllo();
 	qlock(&up->debug);
-
-	up->notepending = 0;
-	n = &up->note[0];
-	if(strncmp(n->msg, "sys:", 4) == 0){
-		l = strlen(n->msg);
-		if(l > ERRMAX-23)	/* " pc=0x0123456789abcdef\0" */
-			l = ERRMAX-23;
-		snprint(n->msg + l, sizeof n->msg - l, " pc=%#lux", ureg->pc);
-	}
-
-	if(n->flag != NUser && (up->notified || up->notify == 0)){
+	msg = popnote(ureg);
+	if(msg == nil){
 		qunlock(&up->debug);
-		if(n->flag == NDebug)
-			pprint("suicide: %s\n", n->msg);
-		pexit(n->msg, n->flag != NDebug);
-	}
-
-	if(up->notified){
-		qunlock(&up->debug);
 		splhi();
 		return 0;
 	}
-		
-	if(up->notify == nil){
-		qunlock(&up->debug);
-		pexit(n->msg, n->flag != NDebug);
-	}
+
 	if(!okaddr((uintptr)up->notify, 1, 0)){
 		qunlock(&up->debug);
 		pprint("suicide: notify function address %#p\n", up->notify);
@@ -163,7 +142,7 @@
 	memmove(&nf->ureg, ureg, sizeof(Ureg));
 	nf->old = up->ureg;
 	up->ureg = nf;
-	memmove(nf->msg, up->note[0].msg, ERRMAX);
+	memmove(nf->msg, msg, ERRMAX);
 	nf->arg1 = nf->msg;
 	nf->arg0 = &nf->ureg;
 	nf->ip = 0;
@@ -171,11 +150,6 @@
 	ureg->sp = sp;
 	ureg->pc = (uintptr)up->notify;
 	ureg->r0 = (uintptr)nf->arg0;
-
-	up->notified = 1;
-	up->nnote--;
-	memmove(&up->lastnote, &up->note[0], sizeof(Note));
-	memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
 
 	qunlock(&up->debug);
 	splx(s);
--- a/sys/src/9/xen/trap.c
+++ b/sys/src/9/xen/trap.c
@@ -480,9 +480,8 @@
 int
 notify(Ureg* ureg)
 {
-	int l;
 	ulong s, sp;
-	Note *n;
+	char *msg;
 
 	if(up->procctl)
 		procctl();
@@ -497,39 +496,20 @@
 
 	s = spllo();
 	qlock(&up->debug);
-	up->notepending = 0;
-	n = &up->note[0];
-	if(strncmp(n->msg, "sys:", 4) == 0){
-		l = strlen(n->msg);
-		if(l > ERRMAX-15)	/* " pc=0x12345678\0" */
-			l = ERRMAX-15;
-		sprint(n->msg+l, " pc=0x%.8lux", ureg->pc);
-	}
-
-	if(n->flag!=NUser && (up->notified || up->notify==0)){
-		if(n->flag == NDebug)
-			pprint("suicide: %s\n", n->msg);
+	msg = popnote(ureg);
+	if(msg == nil){
 		qunlock(&up->debug);
-		pexit(n->msg, n->flag!=NDebug);
-	}
-
-	if(up->notified){
-		qunlock(&up->debug);
 		splhi();
 		return 0;
 	}
-		
-	if(!up->notify){
-		qunlock(&up->debug);
-		pexit(n->msg, n->flag!=NDebug);
-	}
+
 	sp = ureg->usp;
 	sp -= sizeof(Ureg);
 
 	if(!okaddr((ulong)up->notify, 1, 0)
 	|| !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)){
-		pprint("suicide: bad address in notify\n");
 		qunlock(&up->debug);
+		pprint("suicide: bad address in notify\n");
 		pexit("Suicide", 0);
 	}
 
@@ -538,7 +518,7 @@
 	*(Ureg**)(sp-BY2WD) = up->ureg;	/* word under Ureg is old up->ureg */
 	up->ureg = (void*)sp;
 	sp -= BY2WD+ERRMAX;
-	memmove((char*)sp, up->note[0].msg, ERRMAX);
+	memmove((char*)sp, msg, ERRMAX);
 	sp -= 3*BY2WD;
 	*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD;		/* arg 2 is string */
 	*(ulong*)(sp+1*BY2WD) = (ulong)up->ureg;	/* arg 1 is ureg* */
@@ -545,11 +525,6 @@
 	*(ulong*)(sp+0*BY2WD) = 0;			/* arg 0 is pc */
 	ureg->usp = sp;
 	ureg->pc = (ulong)up->notify;
-	up->notified = 1;
-	up->nnote--;
-	memmove(&up->lastnote, &up->note[0], sizeof(Note));
-	memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
-
 	qunlock(&up->debug);
 	splx(s);
 	return 1;
--- a/sys/src/9/zynq/trap.c
+++ b/sys/src/9/zynq/trap.c
@@ -285,9 +285,8 @@
 int
 notify(Ureg *ureg)
 {
-	int l;
 	ulong s, sp;
-	Note *n;
+	char *msg;
 
 	if(up->procctl)
 		procctl();
@@ -302,32 +301,13 @@
 
 	s = spllo();
 	qlock(&up->debug);
-	up->notepending = 0;
-	n = &up->note[0];
-	if(strncmp(n->msg, "sys:", 4) == 0){
-		l = strlen(n->msg);
-		if(l > ERRMAX-15)	/* " pc=0x12345678\0" */
-			l = ERRMAX-15;
-		sprint(n->msg+l, " pc=0x%.8lux", ureg->pc);
-	}
-
-	if(n->flag!=NUser && (up->notified || up->notify==0)){
+	msg = popnote(ureg);
+	if(msg == nil){
 		qunlock(&up->debug);
-		if(n->flag == NDebug)
-			pprint("suicide: %s\n", n->msg);
-		pexit(n->msg, n->flag!=NDebug);
-	}
-
-	if(up->notified){
-		qunlock(&up->debug);
 		splhi();
 		return 0;
 	}
 
-	if(!up->notify){
-		qunlock(&up->debug);
-		pexit(n->msg, n->flag!=NDebug);
-	}
 	sp = ureg->sp;
 	sp -= 256;	/* debugging: preserve context causing problem */
 	sp -= sizeof(Ureg);
@@ -345,7 +325,7 @@
 	*(Ureg**)(sp-BY2WD) = up->ureg;	/* word under Ureg is old up->ureg */
 	up->ureg = (void*)sp;
 	sp -= BY2WD+ERRMAX;
-	memmove((char*)sp, up->note[0].msg, ERRMAX);
+	memmove((char*)sp, msg, ERRMAX);
 	sp -= 3*BY2WD;
 	*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD;
 	*(ulong*)(sp+1*BY2WD) = (ulong)up->ureg;
@@ -353,11 +333,6 @@
 	ureg->sp = sp;
 	ureg->pc = (uintptr) up->notify;
 	ureg->r14 = 0;
-	up->notified = 1;
-	up->nnote--;
-	memmove(&up->lastnote, &up->note[0], sizeof(Note));
-	memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
-
 	qunlock(&up->debug);
 	splx(s);
 	return 1;