ref: 78c2dfe8087d4808e13aeabb6a0e3d1dc696d728
parent: 4d99c9c4c14b9bec61773bd7c84f296b8aa1ec2b
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Jul 6 16:33:51 EDT 2025
kernel: move core of note handling logic into port/sysproc.c I believe holding up->debug qlock while touching the stack is a problem if the fault handler runs into trouble, as it would not be able to deliver any notes. To address this, lets simplify what has to be done per arch for notify() and noted() and provide a donotify() wrapper and do most of the checking in sysnoted(). The per-arch notify() function now just needs to push the note on the stack and prepare registers for the note handler. The per-arch notify() function now gets previous note ureg passed in and just needs to restore it (by calling setregisters() function) and check validity. The chaining needed for NSAVE/NRSTR is handled by donotify() and sysnoted() now, per arch doesnt needs to care other than reserve a pointer sized slot before the Ureg returned by notify(). Fpu state handling is now exposed: each arch needs to provide fpunotify() and fpunoted() functions. They'r called with up->debug qlock held and interrupts off. Rename Proc.ureg to Proc.noteureg (shouldnt be touched by arch specific part).
--- a/sys/src/9/arm64/fns.h
+++ b/sys/src/9/arm64/fns.h
@@ -95,8 +95,6 @@
extern void fpuprocrestore(Proc*);
extern void fpukenter(Ureg*);
extern void fpukexit(Ureg*);
-extern void fpunotify(Proc*);
-extern void fpunoted(Proc*);
extern void mathtrap(Ureg*);
/* trap */
--- a/sys/src/9/arm64/trap.c
+++ b/sys/src/9/arm64/trap.c
@@ -176,7 +176,7 @@
splhi();
if(user){
if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
kexit(ureg);
}
if(type != 0x07 && type != 0x2C)
@@ -197,7 +197,7 @@
returnto(noteret);
if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
if(up->delaysched)
sched();
@@ -206,126 +206,68 @@
fpukexit(ureg);
}
-int
-notify(Ureg *ureg)
+Ureg*
+notify(Ureg *ureg, char *msg)
{
+ Ureg *nureg;
uintptr sp;
- char *msg;
- if(up->procctl)
- procctl();
- if(up->nnote == 0)
- return 0;
-
- spllo();
- qlock(&up->debug);
- msg = popnote(ureg);
- if(msg == nil){
- qunlock(&up->debug);
- splhi();
- return 0;
- }
-
sp = ureg->sp;
sp -= 256; /* debugging: preserve context causing problem */
sp -= sizeof(Ureg);
sp = STACKALIGN(sp);
- if(!okaddr((uintptr)up->notify, 1, 0)
- || !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)
+ if(!okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)
|| ((uintptr) up->notify & 3) != 0
- || (sp & 7) != 0){
- qunlock(&up->debug);
- pprint("suicide: bad address in notify: handler=%#p sp=%#p\n",
- up->notify, sp);
- pexit("Suicide", 0);
- }
+ || (sp & 7) != 0)
+ return nil;
- memmove((Ureg*)sp, ureg, sizeof(Ureg));
- *(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */
- up->ureg = (void*)sp;
+ nureg = (Ureg*)sp;
+ memmove(nureg, ureg, sizeof(Ureg));
sp -= BY2WD+ERRMAX;
memmove((char*)sp, msg, ERRMAX);
sp -= 3*BY2WD;
*(uintptr*)(sp+2*BY2WD) = sp+3*BY2WD;
- *(uintptr*)(sp+1*BY2WD) = (uintptr)up->ureg;
- ureg->r0 = (uintptr) up->ureg;
+ *(uintptr*)(sp+1*BY2WD) = (uintptr)nureg;
+ ureg->r0 = (uintptr)nureg;
ureg->sp = sp;
- ureg->pc = (uintptr) up->notify;
+ ureg->pc = (uintptr)up->notify;
ureg->link = 0;
- splhi();
- fpunotify(up);
- qunlock(&up->debug);
-
- return 1;
+ return nureg;
}
-void
-noted(Ureg *ureg, int arg0)
+int
+noted(Ureg *ureg, Ureg *nureg, int arg0)
{
- Ureg *nureg;
uintptr oureg, sp;
- qlock(&up->debug);
- if(up->notified){
- up->notified = 0;
- splhi();
- fpunoted(up);
- spllo();
- } else if(arg0!=NRSTR){
- qunlock(&up->debug);
- pprint("call to noted() when not notified\n");
- pexit("Suicide", 0);
- }
-
- nureg = up->ureg;
-
oureg = (uintptr) nureg;
- if(!okaddr(oureg - BY2WD, BY2WD + sizeof(Ureg), 0) || (oureg & 7) != 0){
- qunlock(&up->debug);
- pprint("bad ureg in noted or call to noted when not notified\n");
- pexit("Suicide", 0);
- }
+ if((oureg & 7) != 0)
+ return -1;
setregisters(ureg, (char*)ureg, (char*)nureg, sizeof(Ureg));
switch(arg0){
case NCONT: case NRSTR:
- if(!okaddr(ureg->pc, BY2WD, 0) || !okaddr(ureg->sp, BY2WD, 0) ||
- (ureg->pc & 3) != 0 || (ureg->sp & 7) != 0){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- up->ureg = (Ureg *) (*(uintptr*) (oureg - BY2WD));
- qunlock(&up->debug);
+ if(!okaddr(ureg->pc, BY2WD, 0)
+ || !okaddr(ureg->sp, BY2WD, 0)
+ || (ureg->pc & 3) != 0 || (ureg->sp & 7) != 0)
+ return -1;
break;
-
case NSAVE:
sp = oureg - 4 * BY2WD - ERRMAX;
- if(!okaddr(ureg->pc, BY2WD, 0) || !okaddr(sp, 4 * BY2WD, 1) ||
- (nureg->pc & 3) != 0 || (sp & 7) != 0){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- qunlock(&up->debug);
+ if(!okaddr(ureg->pc, BY2WD, 0)
+ || !okaddr(sp, 4 * BY2WD, 1)
+ || (nureg->pc & 3) != 0 || (sp & 7) != 0)
+ return -1;
ureg->sp = sp;
ureg->r0 = (uintptr) oureg;
((uintptr *) sp)[1] = oureg;
((uintptr *) sp)[0] = 0;
break;
-
- default:
- up->lastnote->flag = NDebug;
-
- case NDFLT:
- qunlock(&up->debug);
- if(up->lastnote->flag == NDebug)
- pprint("suicide: %s\n", up->lastnote->msg);
- pexit(up->lastnote->msg, up->lastnote->flag != NDebug);
}
+ return 0;
}
void
--- a/sys/src/9/bcm/fns.h
+++ b/sys/src/9/bcm/fns.h
@@ -111,8 +111,6 @@
extern int fpudevprocio(Proc*, void*, long, uintptr, int);
extern FPalloc *fpalloc(void);
extern void fpuinit(void);
-extern void fpunoted(void);
-extern void fpunotify(void);
extern void fpuprocrestore(Proc*);
extern void fpuprocsave(Proc*);
extern void fpuprocfork(Proc*);
--- a/sys/src/9/bcm/trap.c
+++ b/sys/src/9/bcm/trap.c
@@ -36,7 +36,6 @@
};
extern int irq(Ureg*);
-extern int notify(Ureg*);
/*
* set up for exceptions
@@ -259,7 +258,7 @@
if(user){
if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
kexit(ureg);
}
}
--- a/sys/src/9/bcm/vfp3.c
+++ b/sys/src/9/bcm/vfp3.c
@@ -236,13 +236,13 @@
* checked in the Device Not Available handler.
*/
void
-fpunotify(void)
+fpunotify(Proc *p)
{
- if(up->fpstate == FPactive){
- fpsave(up->fpsave);
- up->fpstate = up->fpsave->fpstate = FPinactive;
+ if(p->fpstate == FPactive){
+ fpsave(p->fpsave);
+ p->fpstate = p->fpsave->fpstate = FPinactive;
}
- up->fpstate |= FPnotify;
+ p->fpstate |= FPnotify;
}
/*
@@ -251,22 +251,22 @@
* Clear the flag set above in fpunotify().
*/
void
-fpunoted(void)
+fpunoted(Proc *p)
{
- if(up->fpstate & FPnotify){
- up->fpstate &= ~FPnotify;
+ if(p->fpstate & FPnotify){
+ p->fpstate &= ~FPnotify;
} else {
FPalloc *o;
- if(up->fpstate == FPactive)
+ if(p->fpstate == FPactive)
fpoff();
- if((o = up->ofpsave) != nil) {
- up->ofpsave = nil;
- free(up->fpsave);
- up->fpsave = o;
- up->fpstate = o->fpstate;
+ if((o = p->ofpsave) != nil) {
+ p->ofpsave = nil;
+ free(p->fpsave);
+ p->fpsave = o;
+ p->fpstate = o->fpstate;
} else {
- up->fpstate = FPinit;
+ p->fpstate = FPinit;
}
}
}
--- a/sys/src/9/bcm64/fns.h
+++ b/sys/src/9/bcm64/fns.h
@@ -94,8 +94,6 @@
extern void fpuprocrestore(Proc*);
extern void fpukenter(Ureg*);
extern void fpukexit(Ureg*);
-extern void fpunotify(Proc*);
-extern void fpunoted(Proc*);
extern void mathtrap(Ureg*);
/* trap */
--- a/sys/src/9/cycv/trap.c
+++ b/sys/src/9/cycv/trap.c
@@ -179,7 +179,7 @@
splhi();
if(user){
if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
kexit(ureg);
}
}
@@ -194,7 +194,7 @@
scallnr = ureg->r0;
dosyscall(scallnr, (Sargs*)(ureg->sp + BY2WD), &ureg->r0);
if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
if(up->delaysched)
sched();
kexit(ureg);
@@ -201,19 +201,19 @@
}
void
-fpunotify(void)
+fpunotify(Proc *p)
{
- if(up->fpstate == FPactive){
- fpsave(up->fpsave);
- up->fpstate = FPinactive;
+ if(p->fpstate == FPactive){
+ fpsave(p->fpsave);
+ p->fpstate = FPinactive;
}
- up->fpstate |= FPnotify;
+ p->fpstate |= FPnotify;
}
void
-fpunoted(void)
+fpunoted(Proc *p)
{
- up->fpstate &= ~FPnotify;
+ p->fpstate &= ~FPnotify;
}
FPsave*
@@ -222,96 +222,52 @@
return nil;
}
-int
-notify(Ureg *ureg)
+Ureg*
+notify(Ureg *ureg, char *msg)
{
+ Ureg *nureg;
ulong sp;
- char *msg;
- if(up->procctl)
- procctl();
- if(up->nnote == 0)
- return 0;
-
- spllo();
- qlock(&up->debug);
- msg = popnote(ureg);
- if(msg == nil){
- qunlock(&up->debug);
- splhi();
- return 0;
- }
-
sp = ureg->sp;
sp -= 256; /* debugging: preserve context causing problem */
sp -= sizeof(Ureg);
- if(!okaddr((uintptr)up->notify, 1, 0)
- || !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)
+ if(!okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)
|| ((uintptr) up->notify & 3) != 0
- || (sp & 3) != 0){
- qunlock(&up->debug);
- pprint("suicide: bad address in notify\n");
- pexit("Suicide", 0);
- }
+ || (sp & 3) != 0)
+ return nil;
- memmove((Ureg*)sp, ureg, sizeof(Ureg));
- *(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */
- up->ureg = (void*)sp;
+ nureg = (Ureg*)sp;
+ memmove(nureg, ureg, sizeof(Ureg));
sp -= BY2WD+ERRMAX;
memmove((char*)sp, msg, ERRMAX);
sp -= 3*BY2WD;
*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD;
- *(ulong*)(sp+1*BY2WD) = (ulong)up->ureg;
- ureg->r0 = (uintptr) up->ureg;
+ *(ulong*)(sp+1*BY2WD) = (ulong)nureg;
+ ureg->r0 = (uintptr)nureg;
ureg->sp = sp;
- ureg->pc = (uintptr) up->notify;
+ ureg->pc = (uintptr)up->notify;
ureg->r14 = 0;
-
- splhi();
- fpunotify();
- qunlock(&up->debug);
- return 1;
+ return nureg;
}
-void
-noted(Ureg *ureg, int arg0)
+int
+noted(Ureg *ureg, Ureg *nureg, int arg0)
{
- Ureg *nureg;
ulong oureg, sp;
- qlock(&up->debug);
- if(up->notified){
- up->notified = 0;
- splhi();
- fpunoted();
- spllo();
- } else if(arg0!=NRSTR){
- qunlock(&up->debug);
- pprint("call to noted() when not notified\n");
- pexit("Suicide", 0);
- }
-
- nureg = up->ureg;
oureg = (ulong) nureg;
- if(!okaddr(oureg - BY2WD, BY2WD + sizeof(Ureg), 0) || (oureg & 3) != 0){
- qunlock(&up->debug);
- pprint("bad ureg in noted or call to noted when not notified\n");
- pexit("Suicide", 0);
- }
+ if((oureg & 3) != 0)
+ return -1;
setregisters(ureg, (char*)ureg, (char*)nureg, sizeof(Ureg));
switch(arg0){
case NCONT: case NRSTR:
- if(!okaddr(ureg->pc, BY2WD, 0) || !okaddr(ureg->sp, BY2WD, 0) ||
- (ureg->pc & 3) != 0 || (ureg->sp & 3) != 0){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- up->ureg = (Ureg *) (*(ulong *) (oureg - BY2WD));
- qunlock(&up->debug);
+ if(!okaddr(ureg->pc, BY2WD, 0)
+ || !okaddr(ureg->sp, BY2WD, 0)
+ || (ureg->pc & 3) != 0 || (ureg->sp & 3) != 0)
+ return -1;
break;
case NSAVE:
@@ -318,26 +274,15 @@
sp = oureg - 4 * BY2WD - ERRMAX;
ureg->sp = sp;
ureg->r0 = (uintptr) oureg;
- if(!okaddr(ureg->pc, BY2WD, 0) || !okaddr(ureg->sp, 4*BY2WD, 1) ||
- (ureg->pc & 3) != 0 || (ureg->sp & 3) != 0){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- qunlock(&up->debug);
+ if(!okaddr(ureg->pc, BY2WD, 0)
+ || !okaddr(ureg->sp, 4*BY2WD, 1)
+ || (ureg->pc & 3) != 0 || (ureg->sp & 3) != 0)
+ return -1;
((ulong *) sp)[1] = oureg;
((ulong *) sp)[0] = 0;
break;
-
- default:
- up->lastnote->flag = NDebug;
-
- case NDFLT:
- qunlock(&up->debug);
- if(up->lastnote->flag == NDebug)
- pprint("suicide: %s\n", up->lastnote->msg);
- pexit(up->lastnote->msg, up->lastnote->flag != NDebug);
}
+ return 0;
}
--- a/sys/src/9/imx8/fns.h
+++ b/sys/src/9/imx8/fns.h
@@ -97,8 +97,6 @@
extern void fpuprocrestore(Proc*);
extern void fpukenter(Ureg*);
extern void fpukexit(Ureg*);
-extern void fpunotify(Proc*);
-extern void fpunoted(Proc*);
extern void mathtrap(Ureg*);
/* trap */
--- a/sys/src/9/kw/fns.h
+++ b/sys/src/9/kw/fns.h
@@ -90,8 +90,6 @@
extern int fpiarm(Ureg*);
extern int fpudevprocio(Proc*, void*, long, uintptr, int);
extern void fpuinit(void);
-extern void fpunoted(void);
-extern void fpunotify(void);
extern void fpuprocrestore(Proc*);
extern void fpuprocsave(Proc*);
extern void fpusysprocsetup(Proc*);
--- a/sys/src/9/kw/trap.c
+++ b/sys/src/9/kw/trap.c
@@ -17,8 +17,6 @@
Nvecs = 256,
};
-extern int notify(Ureg*);
-
extern int ldrexvalid;
typedef struct Vctl Vctl;
@@ -468,7 +466,7 @@
if(user){
if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
kexit(ureg);
}
}
--- a/sys/src/9/lx2k/fns.h
+++ b/sys/src/9/lx2k/fns.h
@@ -97,8 +97,6 @@
extern void fpuprocrestore(Proc*);
extern void fpukenter(Ureg*);
extern void fpukexit(Ureg*);
-extern void fpunotify(Proc*);
-extern void fpunoted(Proc*);
extern void mathtrap(Ureg*);
/* trap */
--- a/sys/src/9/mt7688/syscall.c
+++ b/sys/src/9/mt7688/syscall.c
@@ -24,7 +24,7 @@
if(dosyscall(scallnr, (Sargs*)ur->sp, &ur->r1) == 0)
ur->pc += 4;
if(up->procctl || up->nnote)
- notify(ur);
+ donotify(ur);
/* if we delayed sched because we held a lock, sched now */
if(up->delaysched)
sched();
@@ -34,15 +34,15 @@
}
void
-fpunotify(void)
+fpunotify(Proc *p)
{
- up->fpstate |= FPnotify;
+ p->fpstate |= FPnotify;
}
void
-fpunoted(void)
+fpunoted(Proc *p)
{
- up->fpstate &= ~FPnotify;
+ p->fpstate &= ~FPnotify;
}
FPsave*
@@ -51,38 +51,19 @@
return nil;
}
-int
-notify(Ureg *ur)
+Ureg*
+notify(Ureg *ur, char *msg)
{
+ Ureg *nur;
ulong sp;
- char *msg;
- if(up->procctl)
- procctl();
- if(up->nnote == 0)
- return 0;
-
- spllo();
- qlock(&up->debug);
- msg = popnote(ur);
- if(msg == nil){
- qunlock(&up->debug);
- splhi();
- return 0;
- }
-
sp = ur->usp - sizeof(Ureg) - BY2WD; /* spim libc */
- if(!okaddr((ulong)up->notify, BY2WD, 0) ||
- !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)) {
- iprint("suicide: bad address or sp in notify\n");
- qunlock(&up->debug);
- pexit("Suicide", 0);
- }
+ if(!okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1))
+ return nil;
- memmove((Ureg*)sp, ur, sizeof(Ureg)); /* push user regs */
- *(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */
- up->ureg = (void*)sp;
+ nur = (Ureg*)sp;
+ memmove(nur, ur, sizeof(Ureg)); /* push user regs */
sp -= BY2WD+ERRMAX;
memmove((char*)sp, msg, ERRMAX); /* push err string */
@@ -89,8 +70,8 @@
sp -= 3*BY2WD;
*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */
- ur->r1 = (long)up->ureg; /* arg 1 is ureg* */
- ((ulong*)sp)[1] = (ulong)up->ureg; /* arg 1 0(FP) is ureg* */
+ ur->r1 = (long)nur; /* arg 1 is ureg* */
+ ((ulong*)sp)[1] = (ulong)nur; /* arg 1 0(FP) is ureg* */
((ulong*)sp)[0] = 0; /* arg 0 is pc */
ur->usp = sp;
/*
@@ -98,11 +79,7 @@
* were being called.
*/
ur->pc = (ulong)up->notify;
-
- fpunotify();
- qunlock(&up->debug);
- splhi();
- return 1;
+ return nur;
}
@@ -109,30 +86,14 @@
/*
* Return user to state before notify(); called from user's handler.
*/
-void
-noted(Ureg *kur, int arg0)
+int
+noted(Ureg *kur, Ureg *nur, int arg0)
{
- Ureg *nur;
ulong oureg, sp;
- qlock(&up->debug);
- if(up->notified){
- up->notified = 0;
- fpunoted();
- } else if(arg0!=NRSTR){
- qunlock(&up->debug);
- pprint("call to noted() when not notified\n");
- pexit("Suicide", 0);
- }
-
- nur = up->ureg;
-
oureg = (ulong)nur;
- if((oureg & (BY2WD-1)) || !okaddr((ulong)oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
- qunlock(&up->debug);
- pprint("bad up->ureg in noted or call to noted() when not notified\n");
- pexit("Suicide", 0);
- }
+ if(oureg & (BY2WD-1))
+ return -1;
setregisters(kur, (char*)kur, (char*)nur, sizeof(Ureg));
@@ -139,13 +100,8 @@
switch(arg0) {
case NCONT:
case NRSTR: /* only used by APE */
- if(!okaddr(kur->pc, BY2WD, 0) || !okaddr(kur->usp, BY2WD, 0)){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- up->ureg = (Ureg*)(*(ulong*)(oureg-BY2WD));
- qunlock(&up->debug);
+ if(!okaddr(kur->pc, BY2WD, 0) || !okaddr(kur->usp, BY2WD, 0))
+ return -1;
break;
case NSAVE: /* only used by APE */
@@ -152,26 +108,13 @@
sp = oureg-4*BY2WD-ERRMAX;
kur->r1 = oureg; /* arg 1 is ureg* */
kur->usp = sp;
- if(!okaddr(kur->pc, BY2WD, 0) || !okaddr(kur->usp, 4*BY2WD, 1)){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- qunlock(&up->debug);
+ if(!okaddr(kur->pc, BY2WD, 0) || !okaddr(kur->usp, 4*BY2WD, 1))
+ return -1;
((ulong*)sp)[1] = oureg; /* arg 1 0(FP) is ureg* */
((ulong*)sp)[0] = 0; /* arg 0 is pc */
break;
-
- default:
- up->lastnote->flag = NDebug;
- /* fall through */
-
- case NDFLT:
- qunlock(&up->debug);
- if(up->lastnote->flag == NDebug)
- pprint("suicide: %s\n", up->lastnote->msg);
- pexit(up->lastnote->msg, up->lastnote->flag!=NDebug);
}
+ return 0;
}
--- a/sys/src/9/mt7688/trap.c
+++ b/sys/src/9/mt7688/trap.c
@@ -243,7 +243,7 @@
splhi();
if(user){
- notify(ur);
+ donotify(ur);
/* replicate fpstate to ureg status */
// if(up->fpstate != FPactive)
// ur->status &= ~CU1;
--- a/sys/src/9/mtx/trap.c
+++ b/sys/src/9/mtx/trap.c
@@ -614,51 +614,28 @@
* Call user, if necessary, with note.
* Pass user the Ureg struct and the note on his stack.
*/
-int
-notify(Ureg* ur)
+Ureg*
+notify(Ureg* ur, char *msg)
{
+ Ureg *nur;
ulong s, sp;
- char *msg;
- if(up->procctl)
- procctl();
- if(up->nnote == 0)
- return 0;
-
- s = spllo();
- qlock(&up->debug);
- msg = popnote(ur);
- if(msg == nil){
- qunlock(&up->debug);
- splhi();
- return 0;
- }
-
sp = ur->usp & ~(BY2V-1);
sp -= sizeof(Ureg);
-
- if(!okaddr((uintptr)up->notify, BY2WD, 0) ||
- !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)) {
- qunlock(&up->debug);
- pprint("suicide: bad address or sp in notify\n");
- pexit("Suicide", 0);
- }
-
- memmove((Ureg*)sp, ur, sizeof(Ureg));
- *(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */
- up->ureg = (void*)sp;
+ if(!okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1))
+ return nil;
+ nur = (Ureg*)sp;
+ memmove(nur, ur, sizeof(Ureg));
sp -= BY2WD+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* */
- ((ulong*)sp)[1] = (ulong)up->ureg; /* arg 1 0(FP) is ureg* */
+ ur->r1 = (long)nur; /* arg 1 is ureg* */
+ ((ulong*)sp)[1] = (ulong)nur; /* arg 1 0(FP) is ureg* */
((ulong*)sp)[0] = 0; /* arg 0 is pc */
ur->usp = sp;
ur->pc = (ulong)up->notify;
- qunlock(&up->debug);
- splx(s);
- return 1;
+ return nur;
}
@@ -665,67 +642,30 @@
/*
* Return user to state before notify()
*/
-void
-noted(Ureg* ureg, int arg0)
+int
+noted(Ureg *ureg, Ureg *nureg, int arg0)
{
- Ureg *nureg;
ulong oureg, sp;
- qlock(&up->debug);
- if(arg0!=NRSTR && !up->notified) {
- qunlock(&up->debug);
- pprint("call to noted() when not notified\n");
- pexit("Suicide", 0);
- }
- up->notified = 0;
-
- nureg = up->ureg; /* pointer to user returned Ureg struct */
-
- /* sanity clause */
oureg = (ulong)nureg;
- if(!okaddr(oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
- qunlock(&up->debug);
- pprint("bad ureg in noted or call to noted when not notified\n");
- pexit("Suicide", 0);
- }
- memmove(ureg, nureg, sizeof(Ureg));
+ setregisters(ureg, (char*)ureg, (char*)nureg, sizeof(Ureg));
switch(arg0){
case NCONT:
case NRSTR:
- if(!okaddr(nureg->pc, 1, 0) || !okaddr(nureg->usp, BY2WD, 0)){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- up->ureg = (Ureg*)(*(ulong*)(oureg-BY2WD));
- qunlock(&up->debug);
+ if(!okaddr(nureg->pc, 1, 0) || !okaddr(nureg->usp, BY2WD, 0))
+ return -1;
break;
-
case NSAVE:
if(!okaddr(nureg->pc, BY2WD, 0)
- || !okaddr(nureg->usp, BY2WD, 0)){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- qunlock(&up->debug);
+ || !okaddr(nureg->usp, BY2WD, 0))
+ return -1;
sp = oureg-4*BY2WD-ERRMAX;
- splhi();
ureg->sp = sp;
((ulong*)sp)[1] = oureg; /* arg 1 0(FP) is ureg* */
((ulong*)sp)[0] = 0; /* arg 0 is pc */
break;
-
- default:
- up->lastnote->flag = NDebug;
- /* fall through */
-
- case NDFLT:
- qunlock(&up->debug);
- if(up->lastnote->flag == NDebug)
- pprint("suicide: %s\n", up->lastnote->msg);
- pexit(up->lastnote->msg, up->lastnote->flag!=NDebug);
}
+ return 0;
}
--- a/sys/src/9/omap/fns.h
+++ b/sys/src/9/omap/fns.h
@@ -105,8 +105,6 @@
extern int fpiarm(Ureg*);
extern int fpudevprocio(Proc*, void*, long, uintptr, int);
extern void fpuinit(void);
-extern void fpunoted(void);
-extern void fpunotify(void);
extern void fpuprocrestore(Proc*);
extern void fpuprocsave(Proc*);
extern void fpusysprocsetup(Proc*);
--- a/sys/src/9/omap/softfpu.c
+++ b/sys/src/9/omap/softfpu.c
@@ -20,7 +20,7 @@
}
void
-fpunotify(void)
+fpunotify(Proc*)
{
/*
* Called when a note is about to be delivered to a
@@ -32,7 +32,7 @@
}
void
-fpunoted(void)
+fpunoted(Proc*)
{
/*
* Called from sysnoted() via the machine-dependent
--- a/sys/src/9/omap/syscall.c
+++ b/sys/src/9/omap/syscall.c
@@ -10,137 +10,71 @@
#include "arm.h"
-typedef struct {
- uintptr ip;
- Ureg* arg0;
- char* arg1;
- char msg[ERRMAX];
- Ureg* old;
- Ureg ureg;
-} NFrame;
-
/*
* Return user to state before notify()
*/
-void
-noted(Ureg* cur, int arg0)
+int
+noted(Ureg* ureg, Ureg *nureg, int arg0)
{
- NFrame *nf;
+ ulong oureg, sp;
+
+ oureg = (ulong) nureg;
+ if((oureg & 3) != 0)
+ return -1;
- qlock(&up->debug);
- if(up->notified){
- up->notified = 0;
- splhi();
- fpunoted();
- spllo();
- } else if(arg0!=NRSTR){
- qunlock(&up->debug);
- pprint("call to noted() when not notified\n");
- pexit("Suicide", 0);
- }
-
- nf = up->ureg;
-
- /* sanity clause */
- if(!okaddr((uintptr)nf, sizeof(NFrame), 0)){
- qunlock(&up->debug);
- pprint("bad ureg in noted %#p\n", nf);
- pexit("Suicide", 0);
- }
-
- setregisters(cur, (char*)cur, (char*)&nf->ureg, sizeof(Ureg));
-
- switch((int)arg0){
- case NCONT:
- case NRSTR:
- if(!okaddr(cur->pc, BY2WD, 0) || !okaddr(cur->sp, BY2WD, 0)){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- up->ureg = nf->old;
- qunlock(&up->debug);
+ setregisters(ureg, (char*)ureg, (char*)nureg, sizeof(Ureg));
+
+ switch(arg0){
+ case NCONT: case NRSTR:
+ if(!okaddr(ureg->pc, BY2WD, 0)
+ || !okaddr(ureg->sp, BY2WD, 0)
+ || (ureg->pc & 3) != 0 || (ureg->sp & 3) != 0)
+ return -1;
break;
+
case NSAVE:
- cur->sp = (uintptr)nf;
- cur->r0 = (uintptr)&nf->ureg;
- if(!okaddr(cur->pc, BY2WD, 0) || !okaddr(cur->sp, sizeof(NFrame), 1)){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- qunlock(&up->debug);
- nf->arg1 = nf->msg;
- nf->arg0 = &nf->ureg;
- nf->ip = 0;
+ sp = oureg - 4 * BY2WD - ERRMAX;
+ if(!okaddr(ureg->pc, BY2WD, 0)
+ || !okaddr(sp, 4 * BY2WD, 1)
+ || (ureg->pc & 3) != 0 || (sp & 3) != 0)
+ return -1;
+ ureg->sp = sp;
+ ureg->r0 = (uintptr) oureg;
+ ((ulong *) sp)[1] = oureg;
+ ((ulong *) sp)[0] = 0;
break;
- default:
- up->lastnote->flag = NDebug;
- /*FALLTHROUGH*/
- case NDFLT:
- qunlock(&up->debug);
- if(up->lastnote->flag == NDebug)
- pprint("suicide: %s\n", up->lastnote->msg);
- pexit(up->lastnote->msg, up->lastnote->flag != NDebug);
}
+ return 0;
}
-/*
- * Call user, if necessary, with note.
- * Pass user the Ureg struct and the note on his stack.
- */
-int
-notify(Ureg* ureg)
+Ureg*
+notify(Ureg *ureg, char *msg)
{
- uintptr sp;
- NFrame *nf;
- char *msg;
+ Ureg *nureg;
+ ulong sp;
- if(up->procctl)
- procctl();
- if(up->nnote == 0)
- return 0;
+ sp = ureg->sp;
+ sp -= 256; /* debugging: preserve context causing problem */
+ sp -= sizeof(Ureg);
- spllo();
- qlock(&up->debug);
- msg = popnote(ureg);
- if(msg == nil){
- qunlock(&up->debug);
- splhi();
- return 0;
- }
+ if(!okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)
+ || ((uintptr) up->notify & 3) != 0
+ || (sp & 3) != 0)
+ return nil;
- if(!okaddr((uintptr)up->notify, 1, 0)){
- qunlock(&up->debug);
- pprint("suicide: notify function address %#p\n", up->notify);
- pexit("Suicide", 0);
- }
-
- sp = ureg->sp - sizeof(NFrame);
- if(!okaddr(sp, sizeof(NFrame), 1)){
- qunlock(&up->debug);
- pprint("suicide: notify stack address %#p\n", sp);
- pexit("Suicide", 0);
- }
-
- nf = (void*)sp;
- memmove(&nf->ureg, ureg, sizeof(Ureg));
- nf->old = up->ureg;
- up->ureg = nf;
- memmove(nf->msg, msg, ERRMAX);
- nf->arg1 = nf->msg;
- nf->arg0 = &nf->ureg;
- nf->ip = 0;
-
+ nureg = (Ureg*)sp;
+ memmove(nureg, ureg, sizeof(Ureg));
+ sp -= BY2WD+ERRMAX;
+ memmove((char*)sp, msg, ERRMAX);
+ sp -= 3*BY2WD;
+ *(ulong*)(sp+2*BY2WD) = sp+3*BY2WD;
+ *(ulong*)(sp+1*BY2WD) = (ulong)nureg;
+ ureg->r0 = (uintptr)nureg;
ureg->sp = sp;
ureg->pc = (uintptr)up->notify;
- ureg->r0 = (uintptr)nf->arg0;
+ ureg->r14 = 0;
- splhi();
- fpunotify();
- qunlock(&up->debug);
-
- return 1;
+ return nureg;
}
void
@@ -154,7 +88,7 @@
scallnr = ureg->r0;
dosyscall(scallnr, (Sargs*)(ureg->sp + BY2WD), &ureg->r0);
if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
/* if we delayed sched because we held a lock, sched now */
if(up->delaysched)
sched();
--- a/sys/src/9/omap/trap.c
+++ b/sys/src/9/omap/trap.c
@@ -17,8 +17,6 @@
Bi2long = BI2BY * sizeof(long),
};
-extern int notify(Ureg*);
-
extern int ldrexvalid;
/* omap35x intc (aka mpu_intc) */
@@ -587,7 +585,7 @@
splhi();
if(user){
if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
kexit(ureg);
}
}
--- a/sys/src/9/pc/fns.h
+++ b/sys/src/9/pc/fns.h
@@ -20,8 +20,6 @@
void fpuprocfork(Proc*);
void fpuprocsave(Proc*);
void fpuprocrestore(Proc*);
-void fpunotify(Proc*);
-void fpunoted(Proc*);
int cpuidentify(void);
void cpuidprint(void);
void (*cycles)(uvlong*);
--- a/sys/src/9/pc/trap.c
+++ b/sys/src/9/pc/trap.c
@@ -206,7 +206,7 @@
if(user){
if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
kexit(ureg);
}
}
@@ -444,7 +444,7 @@
scallnr = ureg->ax;
dosyscall(scallnr, (Sargs*)(ureg->sp + BY2WD), &ureg->ax);
if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
/* if we delayed sched because we held a lock, sched now */
if(up->delaysched)
sched();
@@ -455,47 +455,26 @@
* Call user, if necessary, with note.
* Pass user the Ureg struct and the note on his stack.
*/
-int
-notify(Ureg* ureg)
+Ureg*
+notify(Ureg* ureg, char *msg)
{
+ Ureg *nureg;
ulong sp;
- char *msg;
- if(up->procctl)
- procctl();
- if(up->nnote == 0)
- return 0;
-
- spllo();
- qlock(&up->debug);
- msg = popnote(ureg);
- if(msg == nil){
- qunlock(&up->debug);
- splhi();
- return 0;
- }
-
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, msg);
- if(!okaddr((uintptr)up->notify, 1, 0)
- || !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)){
- qunlock(&up->debug);
- pprint("suicide: bad address in notify\n");
- pexit("Suicide", 0);
- }
+ if(!okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1))
+ return nil;
- memmove((Ureg*)sp, ureg, sizeof(Ureg));
- *(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */
- up->ureg = (void*)sp;
+ nureg = (Ureg*)sp;
+ memmove(nureg, ureg, sizeof(Ureg));
sp -= BY2WD+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* */
+ *(ulong*)(sp+1*BY2WD) = (ulong)nureg; /* arg 1 is ureg* */
*(ulong*)(sp+0*BY2WD) = 0; /* arg 0 is pc */
ureg->usp = sp;
ureg->pc = (ulong)up->notify;
@@ -502,42 +481,18 @@
ureg->cs = UESEL;
ureg->ss = ureg->ds = ureg->es = UDSEL;
- splhi();
- fpunotify(up);
- qunlock(&up->debug);
- return 1;
+ return nureg;
}
/*
* Return user to state before notify()
*/
-void
-noted(Ureg* ureg, int arg0)
+int
+noted(Ureg* ureg, Ureg *nureg, int arg0)
{
- Ureg *nureg;
ulong oureg, sp;
- qlock(&up->debug);
- if(up->notified){
- up->notified = 0;
- splhi();
- fpunoted(up);
- spllo();
- } else if(arg0!=NRSTR){
- qunlock(&up->debug);
- pprint("call to noted() when not notified\n");
- pexit("Suicide", 0);
- }
-
- nureg = up->ureg; /* pointer to user returned Ureg struct */
-
- /* sanity clause */
oureg = (ulong)nureg;
- if(!okaddr(oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
- qunlock(&up->debug);
- pprint("bad ureg in noted or call to noted when not notified\n");
- pexit("Suicide", 0);
- }
setregisters(ureg, (char*)ureg, (char*)nureg, sizeof(Ureg));
@@ -545,38 +500,21 @@
case NCONT:
case NRSTR:
if(0) print("%s %lud: noted %#p %#p\n", up->text, up->pid, ureg->pc, ureg->usp);
- if(!okaddr(ureg->pc, 1, 0) || !okaddr(ureg->usp, BY2WD, 0)){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- up->ureg = (Ureg*)(*(ulong*)(oureg-BY2WD));
- qunlock(&up->debug);
+ if(!okaddr(ureg->pc, 1, 0) || !okaddr(ureg->usp, BY2WD, 0))
+ return -1;
break;
case NSAVE:
sp = oureg-4*BY2WD-ERRMAX;
- if(!okaddr(ureg->pc, 1, 0) || !okaddr(sp, 4*BY2WD, 1)){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- qunlock(&up->debug);
+ if(!okaddr(ureg->pc, 1, 0) || !okaddr(sp, 4*BY2WD, 1))
+ return -1;
ureg->usp = sp;
((ulong*)sp)[1] = oureg; /* arg 1 0(FP) is ureg* */
((ulong*)sp)[0] = 0; /* arg 0 is pc */
break;
-
- default:
- up->lastnote->flag = NDebug;
- /* fall through */
-
- case NDFLT:
- qunlock(&up->debug);
- if(up->lastnote->flag == NDebug)
- pprint("suicide: %s\n", up->lastnote->msg);
- pexit(up->lastnote->msg, up->lastnote->flag!=NDebug);
}
+
+ return 0;
}
uintptr
--- a/sys/src/9/pc64/fns.h
+++ b/sys/src/9/pc64/fns.h
@@ -41,8 +41,6 @@
void fpuprocrestore(Proc*);
void fpuprocsave(Proc*);
void fpuprocsetup(Proc*);
-void fpunotify(Proc*);
-void fpunoted(Proc*);
u64int getcr0(void);
u64int getcr2(void);
u64int getcr3(void);
--- a/sys/src/9/pc64/trap.c
+++ b/sys/src/9/pc64/trap.c
@@ -177,7 +177,7 @@
splhi();
if(user){
if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
kexit(ureg);
}
if(vno != VectorCNA)
@@ -424,7 +424,7 @@
scallnr = ureg->bp; /* RARG */
if(dosyscall(scallnr, (Sargs*)(ureg->sp+BY2WD), &ureg->ax))
((void**)&ureg)[-1] = (void*)noteret; /* loads RARG */
- if((up->procctl || up->nnote) && notify(ureg))
+ if((up->procctl || up->nnote) && donotify(ureg))
((void**)&ureg)[-1] = (void*)noteret; /* loads RARG */
/* if we delayed sched because we held a lock, sched now */
if(up->delaysched)
@@ -433,95 +433,46 @@
fpukexit(ureg);
}
-/*
- * Call user, if necessary, with note.
- * Pass user the Ureg struct and the note on his stack.
- */
-int
-notify(Ureg* ureg)
+Ureg*
+notify(Ureg *ureg, char *msg)
{
+ Ureg *nureg;
uintptr sp;
- char *msg;
- if(up->procctl)
- procctl();
- if(up->nnote == 0)
- return 0;
-
- spllo();
- qlock(&up->debug);
- msg = popnote(ureg);
- if(msg == nil){
- qunlock(&up->debug);
- splhi();
- return 0;
- }
-
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, msg);
- if(!okaddr((uintptr)up->notify, 1, 0)
- || !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)){
- qunlock(&up->debug);
- pprint("suicide: bad address in notify\n");
- pexit("Suicide", 0);
- }
+ if(!okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1))
+ return nil;
- memmove((Ureg*)sp, ureg, sizeof(Ureg));
- *(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */
- up->ureg = (void*)sp;
+ nureg = (void*)sp;
+ memmove(nureg, ureg, sizeof(Ureg));
sp -= BY2WD+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* */
+ ((uintptr*)sp)[1] = (uintptr)nureg; /* arg1 is ureg* */
((uintptr*)sp)[0] = 0; /* arg0 is pc */
+
ureg->sp = sp;
ureg->pc = (uintptr)up->notify;
- ureg->bp = (uintptr)up->ureg; /* arg1 passed in RARG */
+ ureg->bp = (uintptr)nureg; /* arg1 passed in RARG */
ureg->cs = UESEL;
ureg->ss = UDSEL;
- splhi();
- fpunotify(up);
- qunlock(&up->debug);
-
- return 1;
+ return nureg;
}
/*
* Return user to state before notify()
*/
-void
-noted(Ureg* ureg, int arg0)
+int
+noted(Ureg *ureg, Ureg *nureg, int arg0)
{
- Ureg *nureg;
uintptr oureg, sp;
- qlock(&up->debug);
- if(up->notified){
- up->notified = 0;
- splhi();
- fpunoted(up);
- spllo();
- } else if(arg0!=NRSTR){
- qunlock(&up->debug);
- pprint("call to noted() when not notified\n");
- pexit("Suicide", 0);
- }
-
- nureg = up->ureg; /* pointer to user returned Ureg struct */
-
- /* sanity clause */
oureg = (uintptr)nureg;
- if(!okaddr(oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
- qunlock(&up->debug);
- pprint("bad ureg in noted or call to noted when not notified\n");
- pexit("Suicide", 0);
- }
/* don't let user change system flags or segment registers */
setregisters(ureg, (char*)ureg, (char*)nureg, sizeof(Ureg));
@@ -529,40 +480,21 @@
switch(arg0){
case NCONT:
case NRSTR:
-if(0) print("%s %lud: noted %#p %#p\n", up->text, up->pid, ureg->pc, ureg->sp);
- if(!okaddr(ureg->pc, 1, 0) || !okaddr(ureg->sp, BY2WD, 0)){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- up->ureg = (Ureg*)(*(uintptr*)(oureg-BY2WD));
- qunlock(&up->debug);
+ if(!okaddr(ureg->pc, 1, 0) || !okaddr(ureg->sp, BY2WD, 0))
+ return -1;
break;
case NSAVE:
sp = oureg-4*BY2WD-ERRMAX;
- if(!okaddr(ureg->pc, 1, 0) || !okaddr(sp, 4 * BY2WD, 1)){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- qunlock(&up->debug);
+ if(!okaddr(ureg->pc, 1, 0) || !okaddr(sp, 4 * BY2WD, 1))
+ return -1;
ureg->sp = sp;
ureg->bp = oureg; /* arg 1 passed in RARG */
((uintptr*)sp)[1] = oureg; /* arg 1 0(FP) is ureg* */
((uintptr*)sp)[0] = 0; /* arg 0 is pc */
break;
-
- default:
- up->lastnote->flag = NDebug;
- /* fall through */
-
- case NDFLT:
- qunlock(&up->debug);
- if(up->lastnote->flag == NDebug)
- pprint("suicide: %s\n", up->lastnote->msg);
- pexit(up->lastnote->msg, up->lastnote->flag!=NDebug);
}
+ return 0;
}
uintptr
--- a/sys/src/9/port/portdat.h
+++ b/sys/src/9/port/portdat.h
@@ -789,7 +789,7 @@
uintptr qpc; /* pc calling last blocking qlock */
QLock *eql; /* interruptable eqlock */
- void *ureg; /* User registers for notes */
+ void *noteureg; /* User registers for notes */
void *dbgreg; /* User registers for devproc */
PFPU; /* machine specific fpu state */
--- a/sys/src/9/port/portfns.h
+++ b/sys/src/9/port/portfns.h
@@ -82,6 +82,7 @@
Walkqid* devwalk(Chan*, Chan*, char**, int, Dirtab*, int, Devgen*);
int devwstat(Chan*, uchar*, int);
Dir* dirchanstat(Chan *);
+int donotify(Ureg*);
int dosyscall(ulong, Sargs*, uintptr*);
void drawactive(int);
void drawcmap(void);
@@ -121,6 +122,8 @@
void forceclosefgrp(void);
void forkchild(Proc*, Ureg*);
void forkret(void);
+void fpunotify(Proc*);
+void fpunoted(Proc*);
void free(void*);
void freeb(Block*);
void freeblist(Block*);
@@ -224,8 +227,8 @@
Rgrp* newrgrp(void);
Proc* newproc(void);
_Noreturn void nexterror(void);
-int notify(Ureg*);
-void noted(Ureg*, int);
+Ureg* notify(Ureg*, char*);
+int noted(Ureg*, Ureg*, int);
FPsave* notefpsave(Proc*);
ulong nkpages(Confmem*);
uvlong ns2fastticks(uvlong);
--- a/sys/src/9/port/portmkfile
+++ b/sys/src/9/port/portmkfile
@@ -85,6 +85,7 @@
sdvirtio10.$O: ../port/sd.h ../port/pci.h /$objtype/include/ureg.h
trap.$O: /$objtype/include/ureg.h
proc.$O: /$objtype/include/ureg.h
+sysproc.$O: /$objtype/include/ureg.h
devproc.$O: /$objtype/include/ureg.h
portclock.$O: /$objtype/include/ureg.h
userinit.$O: initcode.i
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -715,7 +715,7 @@
p->kfpstate = FPinit;
#endif
p->procctl = 0;
- p->ureg = nil;
+ p->noteureg = nil;
p->dbgreg = nil;
p->nerrlab = 0;
p->errstr = p->errbuf0;
@@ -1362,7 +1362,7 @@
freenote(up->lastnote);
up->lastnote = nil;
up->notified = 0;
- up->ureg = nil;
+ up->noteureg = nil;
up->dbgreg = nil;
/* release debuggers */
--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -4,6 +4,7 @@
#include "mem.h"
#include "dat.h"
#include "fns.h"
+#include "ureg.h"
#include "../port/error.h"
#include "edf.h"
@@ -665,7 +666,7 @@
up->lastnote = nil;
up->notify = nil;
up->notified = 0;
- up->ureg = nil;
+ up->noteureg = nil;
up->privatemem = 0;
up->noswap = 0;
up->pcycles = -up->kentry;
@@ -847,15 +848,94 @@
return 0;
}
+int
+donotify(Ureg *ureg)
+{
+ Ureg *nureg;
+ char *msg;
+
+ if(up->procctl)
+ procctl();
+ if(up->nnote == 0)
+ return 0;
+
+ spllo();
+ qlock(&up->debug);
+ msg = popnote(ureg);
+ if(msg == nil){
+ qunlock(&up->debug);
+ splhi();
+ return 0;
+ }
+ splhi();
+ fpunotify(up);
+ spllo();
+ qunlock(&up->debug);
+
+ if(up->notify == nil
+ || (nureg = notify(ureg, msg)) == nil){
+ if(up->lastnote->flag == NDebug)
+ pprint("suicide: %s\n", msg);
+ pexit(msg, up->lastnote->flag!=NDebug);
+ }
+
+ /* word under Ureg is old ureg */
+ *(Ureg**)((uintptr)nureg-BY2WD) = up->noteureg;
+ up->noteureg = nureg;
+
+ splhi();
+ return 1;
+}
+
uintptr
sysnoted(va_list list)
{
+ Ureg *nureg;
int arg;
arg = va_arg(list, int);
- if(arg != NRSTR && !up->notified)
- error(Egreg);
- noted(up->dbgreg, arg);
+
+ qlock(&up->debug);
+ if(up->notified){
+ splhi();
+ fpunoted(up);
+ spllo();
+ } else if(arg!=NRSTR){
+ qunlock(&up->debug);
+ error(Ebadarg);
+ }
+ qunlock(&up->debug);
+
+ nureg = up->noteureg;
+ if(!okaddr((uintptr)nureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
+ pprint("suicide: bad ureg in noted or call to noted when not notified\n");
+ pexit("Suicide", 0);
+ }
+
+ switch(arg){
+ case NCONT:
+ case NRSTR:
+ /* word under Ureg is old ureg */
+ up->noteureg = *(Ureg**)((uintptr)nureg-BY2WD);
+ /* wet floor */
+ case NSAVE:
+ if(noted(up->dbgreg, nureg, arg)){
+ pprint("suicide: trap in noted\n");
+ pexit("Suicide", 0);
+ }
+ break;
+ default:
+ up->lastnote->flag = NDebug;
+ /* fall through */
+ case NDFLT:
+ if(up->lastnote->flag == NDebug)
+ pprint("suicide: %s\n", up->lastnote->msg);
+ pexit(up->lastnote->msg, up->lastnote->flag!=NDebug);
+ }
+
+ /* allow next note */
+ up->notified = 0;
+
return 0;
}
--- a/sys/src/9/ppc/trap.c
+++ b/sys/src/9/ppc/trap.c
@@ -279,7 +279,7 @@
splhi();
if(user) {
- notify(ureg);
+ donotify(ureg);
if(up->fpstate != FPactive)
ureg->srr1 &= ~MSR_FP;
kexit(ureg);
@@ -573,7 +573,7 @@
scallnr = ureg->r3;
dosyscall(scallnr, (Sargs*)(ureg->usp+BY2WD), &ureg->r3);
if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
/* if we delayed sched because we held a lock, sched now */
if(up->delaysched)
sched();
@@ -590,57 +590,28 @@
* Call user, if necessary, with note.
* Pass user the Ureg struct and the note on his stack.
*/
-int
-notify(Ureg* ur)
+Ureg*
+notify(Ureg* ur, char *msg)
{
+ Ureg *nur;
ulong s, sp;
- char *msg;
- if(up->procctl)
- procctl();
- if(up->nnote == 0)
- return 0;
-
- if(up->fpstate == FPactive){
- fpsave(up->fpsave);
- up->fpstate = FPinactive;
- }
- up->fpstate |= FPnotify;
-
- s = spllo();
- qlock(&up->debug);
- msg = popnote(ur);
- if(msg == nil){
- qunlock(&up->debug);
- splhi();
- return 0;
- }
-
sp = ur->usp & ~(BY2V-1);
sp -= sizeof(Ureg);
-
- if(!okaddr((uintptr)up->notify, BY2WD, 0) ||
- !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)) {
- qunlock(&up->debug);
- pprint("suicide: bad address or sp in notify\n");
- pexit("Suicide", 0);
- }
-
- memmove((Ureg*)sp, ur, sizeof(Ureg));
- *(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */
- up->ureg = (void*)sp;
+ if(!okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1))
+ return nil;
+ nur = (Ureg*)sp;
+ memmove(nur, ur, sizeof(Ureg));
sp -= BY2WD+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* */
- ((ulong*)sp)[1] = (ulong)up->ureg; /* arg 1 0(FP) is ureg* */
+ ur->r1 = (long)nur; /* arg 1 is ureg* */
+ ((ulong*)sp)[1] = (ulong)nur; /* arg 1 0(FP) is ureg* */
((ulong*)sp)[0] = 0; /* arg 0 is pc */
ur->usp = sp;
ur->pc = (ulong)up->notify;
- qunlock(&up->debug);
- splx(s);
- return 1;
+ return nur;
}
@@ -647,68 +618,30 @@
/*
* Return user to state before notify()
*/
-void
-noted(Ureg* ureg, int arg0)
+int
+noted(Ureg *ureg, Ureg *nureg, int arg0)
{
- Ureg *nureg;
ulong oureg, sp;
- qlock(&up->debug);
- if(arg0!=NRSTR && !up->notified) {
- qunlock(&up->debug);
- pprint("call to noted() when not notified\n");
- pexit("Suicide", 0);
- }
- up->notified = 0;
-
- nureg = up->ureg; /* pointer to user returned Ureg struct */
-
- /* sanity clause */
oureg = (ulong)nureg;
- if(!okaddr(oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
- qunlock(&up->debug);
- pprint("bad ureg in noted or call to noted when not notified\n");
- pexit("Suicide", 0);
- }
- memmove(ureg, nureg, sizeof(Ureg));
+ setregisters(ureg, (char*)ureg, (char*)nureg, sizeof(Ureg));
switch(arg0){
case NCONT:
case NRSTR:
- if(!okaddr(nureg->pc, 1, 0) || !okaddr(nureg->usp, BY2WD, 0)){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- up->ureg = (Ureg*)(*(ulong*)(oureg-BY2WD));
- qunlock(&up->debug);
+ if(!okaddr(nureg->pc, 1, 0) || !okaddr(nureg->usp, BY2WD, 0))
+ return -1;
break;
-
case NSAVE:
if(!okaddr(nureg->pc, BY2WD, 0)
- || !okaddr(nureg->usp, BY2WD, 0)){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- qunlock(&up->debug);
+ || !okaddr(nureg->usp, BY2WD, 0))
+ return -1;
sp = oureg-4*BY2WD-ERRMAX;
- splhi();
ureg->sp = sp;
((ulong*)sp)[1] = oureg; /* arg 1 0(FP) is ureg* */
((ulong*)sp)[0] = 0; /* arg 0 is pc */
break;
-
- default:
- up->lastnote->flag = NDebug;
- /* fall through */
-
- case NDFLT:
- qunlock(&up->debug);
- if(up->lastnote->flag == NDebug)
- pprint("suicide: %s\n", up->lastnote->msg);
- pexit(up->lastnote->msg, up->lastnote->flag!=NDebug);
}
up->fpstate &= ~FPnotify;
if (up->fpstate == FPactive)
@@ -715,4 +648,5 @@
ureg->srr1 |= MSR_FP;
else
ureg->srr1 &= ~MSR_FP;
+ return 0;
}
--- a/sys/src/9/sgi/trap.c
+++ b/sys/src/9/sgi/trap.c
@@ -258,7 +258,7 @@
splhi();
if(user){
- notify(ur);
+ donotify(ur);
/* replicate fpstate to ureg status */
if(up->fpstate != FPactive)
ur->status &= ~CU1;
@@ -439,19 +439,19 @@
}
void
-fpunotify(void)
+fpunotify(Proc *p)
{
- if(up->fpstate == FPactive){
- savefpregs(up->fpsave);
- up->fpstate = FPinactive;
+ if(p->fpstate == FPactive){
+ savefpregs(p->fpsave);
+ p->fpstate = FPinactive;
}
- up->fpstate |= FPnotify;
+ p->fpstate |= FPnotify;
}
void
-fpunoted(void)
+fpunoted(Proc *p)
{
- up->fpstate &= ~FPnotify;
+ p->fpstate &= ~FPnotify;
}
FPsave*
@@ -460,39 +460,20 @@
return nil;
}
-int
-notify(Ureg *ur)
+Ureg*
+notify(Ureg *ur, char *msg)
{
+ Ureg *nur;
ulong sp;
- char *msg;
- if(up->procctl)
- procctl();
- if(up->nnote == 0)
- return 0;
-
- spllo();
- qlock(&up->debug);
- msg = popnote(ur);
- if(msg == nil){
- qunlock(&up->debug);
- splhi();
- return 0;
- }
-
sp = ur->usp & ~(BY2V-1);
sp -= sizeof(Ureg);
- if(!okaddr((ulong)up->notify, BY2WD, 0) ||
- !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)) {
- pprint("suicide: bad address or sp in notify\n");
- qunlock(&up->debug);
- pexit("Suicide", 0);
- }
+ if(!okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1))
+ return nil;
- memmove((Ureg*)sp, ur, sizeof(Ureg)); /* push user regs */
- *(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */
- up->ureg = (void*)sp;
+ nur = (Ureg*)sp;
+ memmove(nur, ur, sizeof(Ureg)); /* push user regs */
sp -= BY2WD+ERRMAX;
memmove((char*)sp, msg, ERRMAX); /* push err string */
@@ -499,8 +480,8 @@
sp -= 3*BY2WD;
*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */
- ur->r1 = (long)up->ureg; /* arg 1 is ureg* */
- ((ulong*)sp)[1] = (ulong)up->ureg; /* arg 1 0(FP) is ureg* */
+ ur->r1 = (long)nur; /* arg 1 is ureg* */
+ ((ulong*)sp)[1] = (ulong)nur; /* arg 1 0(FP) is ureg* */
((ulong*)sp)[0] = 0; /* arg 0 is pc */
ur->usp = sp;
/*
@@ -509,40 +490,20 @@
*/
ur->pc = (ulong)up->notify;
- splhi();
- fpunotify();
- qunlock(&up->debug);
- return 1;
+ return nur;
}
/*
* Return user to state before notify(); called from user's handler.
*/
-void
-noted(Ureg *kur, int arg0)
+int
+noted(Ureg *kur, Ureg *nur, int arg0)
{
- Ureg *nur;
ulong oureg, sp;
- qlock(&up->debug);
- if(up->notified){
- up->notified = 0;
- splhi();
- fpunoted();
- spllo();
- } else if(arg0!=NRSTR){
- qunlock(&up->debug);
- pprint("call to noted() when not notified\n");
- pexit("Suicide", 0);
- }
-
- nur = up->ureg;
oureg = (ulong)nur;
- if((oureg & (BY2WD-1)) || !okaddr((ulong)oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
- qunlock(&up->debug);
- pprint("bad up->ureg in noted or call to noted() when not notified\n");
- pexit("Suicide", 0);
- }
+ if(oureg & (BY2WD-1))
+ return -1;
setregisters(kur, (char*)kur, (char*)nur, sizeof(Ureg));
@@ -549,39 +510,22 @@
switch(arg0) {
case NCONT:
case NRSTR: /* only used by APE */
- if(!okaddr(kur->pc, BY2WD, 0) || !okaddr(kur->usp, BY2WD, 0)){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- up->ureg = (Ureg*)(*(ulong*)(oureg-BY2WD));
- qunlock(&up->debug);
+ if(!okaddr(kur->pc, BY2WD, 0) || !okaddr(kur->usp, BY2WD, 0))
+ return -1;
break;
case NSAVE: /* only used by APE */
sp = oureg-4*BY2WD-ERRMAX;
- if(!okaddr(kur->pc, BY2WD, 0) || !okaddr(sp, 4*BY2WD, 1)){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- qunlock(&up->debug);
+ if(!okaddr(kur->pc, BY2WD, 0) || !okaddr(sp, 4*BY2WD, 1))
+ return -1;
kur->r1 = oureg; /* arg 1 is ureg* */
kur->usp = sp;
((ulong*)sp)[1] = oureg; /* arg 1 0(FP) is ureg* */
((ulong*)sp)[0] = 0; /* arg 0 is pc */
break;
-
- default:
- up->lastnote->flag = NDebug;
- /* fall through */
-
- case NDFLT:
- qunlock(&up->debug);
- if(up->lastnote->flag == NDebug)
- pprint("suicide: %s\n", up->lastnote->msg);
- pexit(up->lastnote->msg, up->lastnote->flag!=NDebug);
}
+
+ return 0;
}
/*
@@ -599,7 +543,7 @@
if(dosyscall(scallnr, (Sargs*)(ur->sp+BY2WD), &ur->r1) == 0)
ur->pc += 4;
if(up->procctl || up->nnote)
- notify(ur);
+ donotify(ur);
/* if we delayed sched because we held a lock, sched now */
if(up->delaysched)
sched();
--- a/sys/src/9/teg2/fns.h
+++ b/sys/src/9/teg2/fns.h
@@ -144,8 +144,6 @@
extern int fpudevprocio(Proc*, void*, long, uintptr, int);
extern FPalloc *fpalloc(void);
extern void fpuinit(void);
-extern void fpunoted(void);
-extern void fpunotify(void);
extern void fpuprocrestore(Proc*);
extern void fpuprocsave(Proc*);
extern void fpusysprocsetup(Proc*);
--- a/sys/src/9/teg2/trap.c
+++ b/sys/src/9/teg2/trap.c
@@ -172,8 +172,6 @@
static ulong shadena[32]; /* copy of enable bits, saved by intcmaskall */
static Lock distlock, nintrlock;
-extern int notify(Ureg*);
-
static void dumpstackwithureg(Ureg *ureg);
void
@@ -863,7 +861,7 @@
if(user){
if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
kexit(ureg);
}
}
--- a/sys/src/9/xen/fns.h
+++ b/sys/src/9/xen/fns.h
@@ -15,9 +15,7 @@
void fpuprocfork(Proc*);
void fpuprocsave(Proc*);
void fpuprocrestore(Proc*);
-void fpunotify(Proc*);
-void fpunoted(Proc*);
-int cpuidentify(void);
+int cpuidentify(void);
void cpuidprint(void);
void (*cycles)(uvlong*);
void delay(int);
--- a/sys/src/9/xen/trap.c
+++ b/sys/src/9/xen/trap.c
@@ -166,7 +166,7 @@
if(user){
if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
kexit(ureg);
}
@@ -359,7 +359,7 @@
scallnr = ureg->ax;
dosyscall(scallnr, (Sargs*)(ureg->sp + BY2WD), &ureg->ax);
if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
/* if we delayed sched because we held a lock, sched now */
if(up->delaysched)
sched();
@@ -370,84 +370,40 @@
* Call user, if necessary, with note.
* Pass user the Ureg struct and the note on his stack.
*/
-int
-notify(Ureg* ureg)
+Ureg*
+notify(Ureg* ureg, char *msg)
{
+ Ureg *nureg;
ulong sp;
- char *msg;
- if(up->procctl)
- procctl();
- if(up->nnote == 0)
- return 0;
-
- spllo();
- qlock(&up->debug);
- msg = popnote(ureg);
- if(msg == nil){
- qunlock(&up->debug);
- splhi();
- return 0;
- }
-
sp = ureg->usp;
sp -= sizeof(Ureg);
- if(!okaddr((ulong)up->notify, 1, 0)
- || !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)){
- qunlock(&up->debug);
- pprint("suicide: bad address in notify\n");
- pexit("Suicide", 0);
- }
+ if(!okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1))
+ return nil;
- up->ureg = (void*)sp;
- memmove((Ureg*)sp, ureg, sizeof(Ureg));
- *(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */
- up->ureg = (void*)sp;
+ nureg = (Ureg*)sp;
+ memmove(nureg, ureg, sizeof(Ureg));
sp -= BY2WD+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* */
+ *(ulong*)(sp+1*BY2WD) = (ulong)nureg; /* arg 1 is ureg* */
*(ulong*)(sp+0*BY2WD) = 0; /* arg 0 is pc */
ureg->usp = sp;
ureg->pc = (ulong)up->notify;
- splhi();
- fpunotify(up);
- qunlock(&up->debug);
- return 1;
+ return nureg;
}
/*
* Return user to state before notify()
*/
-void
-noted(Ureg* ureg, int arg0)
+int
+noted(Ureg *ureg, Ureg *nureg, int arg0)
{
- Ureg *nureg;
ulong oureg, sp;
- qlock(&up->debug);
- if(up->notified){
- up->notified = 0;
- splhi();
- fpunoted(up);
- spllo();
- } else if(arg0!=NRSTR){
- qunlock(&up->debug);
- pprint("call to noted() when not notified\n");
- pexit("Suicide", 0);
- }
-
- nureg = up->ureg; /* pointer to user returned Ureg struct */
-
- /* sanity clause */
oureg = (ulong)nureg;
- if(!okaddr((ulong)oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
- qunlock(&up->debug);
- pprint("bad ureg in noted or call to noted when not notified\n");
- pexit("Suicide", 0);
- }
/*
* Check the segment selectors are all valid, otherwise
@@ -459,14 +415,13 @@
if((nureg->cs & 0xFFFF) != UESEL || (nureg->ss & 0xFFFF) != UDSEL
|| (nureg->ds & 0xFFFF) != UDSEL || (nureg->es & 0xFFFF) != UDSEL
|| (nureg->fs & 0xFFFF) != UDSEL || (nureg->gs & 0xFFFF) != UDSEL){
+
pprint("bad segment selector in noted\n");
pprint("cs is %#lux, wanted %#ux\n", nureg->cs, UESEL);
pprint("ds is %#lux, wanted %#ux\n", nureg->ds, UDSEL);
pprint("es is %#lux, fs is %#lux, gs %#lux, wanted %#ux\n",
ureg->es, ureg->fs, ureg->gs, UDSEL);
- qunlock(&up->debug);
- pprint("ss is %#lux, wanted %#ux\n", nureg->ss, UDSEL);
- pexit("Suicide", 0);
+ return -1;
}
setregisters(ureg, (char*)ureg, (char*)nureg, sizeof(Ureg));
@@ -474,38 +429,19 @@
switch(arg0){
case NCONT:
case NRSTR:
- if(!okaddr(ureg->pc, 1, 0) || !okaddr(ureg->usp, BY2WD, 0)){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- up->ureg = (Ureg*)(*(ulong*)(oureg-BY2WD));
- qunlock(&up->debug);
+ if(!okaddr(ureg->pc, 1, 0) || !okaddr(ureg->usp, BY2WD, 0))
+ return -1;
break;
-
case NSAVE:
sp = oureg-4*BY2WD-ERRMAX;
- if(!okaddr(ureg->pc, 1, 0) || !okaddr(sp, 4*BY2WD, 1)){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- qunlock(&up->debug);
+ if(!okaddr(ureg->pc, 1, 0) || !okaddr(sp, 4*BY2WD, 1))
+ return -1;
ureg->usp = sp;
((ulong*)sp)[1] = oureg; /* arg 1 0(FP) is ureg* */
((ulong*)sp)[0] = 0; /* arg 0 is pc */
break;
-
- default:
- up->lastnote->flag = NDebug;
- /* fall through */
-
- case NDFLT:
- qunlock(&up->debug);
- if(up->lastnote->flag == NDebug)
- pprint("suicide: %s\n", up->lastnote->msg);
- pexit(up->lastnote->msg, up->lastnote->flag!=NDebug);
}
+ return 0;
}
uintptr
--- a/sys/src/9/zynq/trap.c
+++ b/sys/src/9/zynq/trap.c
@@ -201,7 +201,7 @@
splhi();
if(user){
if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
kexit(ureg);
}
}
@@ -216,39 +216,39 @@
scallnr = ureg->r0;
dosyscall(scallnr, (Sargs*)(ureg->sp + BY2WD), &ureg->r0);
if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
if(up->delaysched)
sched();
kexit(ureg);
}
-static void
-fpunotify(void)
+void
+fpunotify(Proc *p)
{
- if(up->fpstate == FPactive){
- fpsave(up->fpsave);
- up->fpstate = FPinactive;
+ if(p->fpstate == FPactive){
+ fpsave(p->fpsave);
+ p->fpstate = FPinactive;
}
- up->fpstate |= FPnotify;
+ p->fpstate |= FPnotify;
}
-static void
-fpunoted(void)
+void
+fpunoted(Proc *p)
{
- if(up->fpstate & FPnotify){
- up->fpstate &= ~FPnotify;
+ if(p->fpstate & FPnotify){
+ p->fpstate &= ~FPnotify;
} else {
FPsave *o;
- if(up->fpstate == FPactive)
+ if(p->fpstate == FPactive)
fpclear();
- if((o = up->ofpsave) != nil) {
- up->ofpsave = nil;
- fpfree(up->fpsave);
- up->fpsave = o;
- up->fpstate = FPinactive;
+ if((o = p->ofpsave) != nil) {
+ p->ofpsave = nil;
+ fpfree(p->fpsave);
+ p->fpsave = o;
+ p->fpstate = FPinactive;
} else {
- up->fpstate = FPinit;
+ p->fpstate = FPinit;
}
}
}
@@ -264,121 +264,68 @@
return p->ofpsave;
}
-int
-notify(Ureg *ureg)
+Ureg*
+notify(Ureg *ureg, char *msg)
{
+ Ureg *nureg;
ulong sp;
- char *msg;
- if(up->procctl)
- procctl();
- if(up->nnote == 0)
- return 0;
-
- spllo();
- qlock(&up->debug);
- msg = popnote(ureg);
- if(msg == nil){
- qunlock(&up->debug);
- splhi();
- return 0;
- }
-
sp = ureg->sp;
sp -= 256; /* debugging: preserve context causing problem */
sp -= sizeof(Ureg);
- if(!okaddr((uintptr)up->notify, 1, 0)
- || !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)
+ if(!okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)
|| ((uintptr) up->notify & 3) != 0
- || (sp & 3) != 0){
- qunlock(&up->debug);
- pprint("suicide: bad address in notify\n");
- pexit("Suicide", 0);
- }
+ || (sp & 3) != 0)
+ return nil;
- memmove((Ureg*)sp, ureg, sizeof(Ureg));
- *(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */
- up->ureg = (void*)sp;
+ nureg = (Ureg*)sp;
+ memmove(nureg, ureg, sizeof(Ureg));
sp -= BY2WD+ERRMAX;
memmove((char*)sp, msg, ERRMAX);
sp -= 3*BY2WD;
*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD;
- *(ulong*)(sp+1*BY2WD) = (ulong)up->ureg;
- ureg->r0 = (uintptr) up->ureg;
+ *(ulong*)(sp+1*BY2WD) = (ulong)nureg;
+ ureg->r0 = (uintptr)nureg;
ureg->sp = sp;
- ureg->pc = (uintptr) up->notify;
+ ureg->pc = (uintptr)up->notify;
ureg->r14 = 0;
- splhi();
- fpunotify();
- qunlock(&up->debug);
- return 1;
+ return nureg;
}
-void
-noted(Ureg *ureg, int arg0)
+int
+noted(Ureg *ureg, Ureg *nureg, int arg0)
{
- Ureg *nureg;
ulong oureg, sp;
- qlock(&up->debug);
- if(up->notified){
- up->notified = 0;
- splhi();
- fpunoted();
- spllo();
- } else if(arg0!=NRSTR){
- qunlock(&up->debug);
- pprint("call to noted() when not notified\n");
- pexit("Suicide", 0);
- }
-
- nureg = up->ureg;
oureg = (ulong) nureg;
- if(!okaddr(oureg - BY2WD, BY2WD + sizeof(Ureg), 0) || (oureg & 3) != 0){
- qunlock(&up->debug);
- pprint("bad ureg in noted or call to noted when not notified\n");
- pexit("Suicide", 0);
- }
+ if((oureg & 3) != 0)
+ return -1;
setregisters(ureg, (char*)ureg, (char*)nureg, sizeof(Ureg));
switch(arg0){
case NCONT: case NRSTR:
- if(!okaddr(ureg->pc, BY2WD, 0) || !okaddr(ureg->sp, BY2WD, 0) ||
- (ureg->pc & 3) != 0 || (ureg->sp & 3) != 0){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- up->ureg = (Ureg *) (*(ulong *) (oureg - BY2WD));
- qunlock(&up->debug);
+ if(!okaddr(ureg->pc, BY2WD, 0)
+ || !okaddr(ureg->sp, BY2WD, 0)
+ || (ureg->pc & 3) != 0 || (ureg->sp & 3) != 0)
+ return -1;
break;
case NSAVE:
sp = oureg - 4 * BY2WD - ERRMAX;
- if(!okaddr(ureg->pc, BY2WD, 0) || !okaddr(sp, 4 * BY2WD, 1) || (ureg->pc & 3) != 0 || (sp & 3) != 0){
- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
- qunlock(&up->debug);
+ if(!okaddr(ureg->pc, BY2WD, 0)
+ || !okaddr(sp, 4 * BY2WD, 1)
+ || (ureg->pc & 3) != 0 || (sp & 3) != 0)
+ return -1;
ureg->sp = sp;
ureg->r0 = (uintptr) oureg;
((ulong *) sp)[1] = oureg;
((ulong *) sp)[0] = 0;
break;
-
- default:
- up->lastnote->flag = NDebug;
-
- case NDFLT:
- qunlock(&up->debug);
- if(up->lastnote->flag == NDebug)
- pprint("suicide: %s\n", up->lastnote->msg);
- pexit(up->lastnote->msg, up->lastnote->flag != NDebug);
}
+ return 0;
}
--
⑨