From b73e35c1decbee5d23ff469df61d6a190cd4545f Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 15 Jan 1995 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1995-01-15 --- carrera/dat.h | 2 +- carrera/mem.h | 5 +++- carrera/trap.c | 70 ++++++++++++++++++++++++++++++++++++++++++-------- pc/devastar.c | 2 +- pc/trap.c | 1 + port/lib.h | 2 ++ port/proc.c | 1 + port/sysproc.c | 11 +++----- 8 files changed, 73 insertions(+), 21 deletions(-) diff --git a/carrera/dat.h b/carrera/dat.h index f42b3dee1419f5700342cad066464e72954b1818..2b8301825343046ce61feb74f06a2d2e19768559 100644 --- a/carrera/dat.h +++ b/carrera/dat.h @@ -79,7 +79,7 @@ struct PMMU */ struct Notsave { - ulong svstatus; + ulong UNUSED; }; #include "../port/portdat.h" diff --git a/carrera/mem.h b/carrera/mem.h index ff79914f3a8a7bc5e98544f20162446066758800..722e002aae78ace52d537e9b9a58c4157c7bfb3b 100644 --- a/carrera/mem.h +++ b/carrera/mem.h @@ -66,7 +66,10 @@ #define ERL 0x00000004 #define KSUPER 0x00000008 #define KUSER 0x00000010 +#define KSU 0x00000018 #define UX 0x00000020 +#define SX 0x00000040 +#define KX 0x00000080 #define INTMASK 0x0000ff00 #define INTR0 0x00000100 #define INTR1 0x00000200 @@ -93,7 +96,7 @@ * Magic registers */ #define USER 24 /* R24 is up-> */ -#define MACH 25 /* R25 is m-> */ +#define MACH 25 /* R25 is m-> */ /* * Fundamental addresses diff --git a/carrera/trap.c b/carrera/trap.c index 3f26113a63eaefcebc62248f3e650b5118c85937..10675cc0d2f84cff4dd8d0f69b4316202d1184ea 100644 --- a/carrera/trap.c +++ b/carrera/trap.c @@ -7,7 +7,7 @@ #include "io.h" #include "../port/error.h" -void noted(Ureg**, ulong); +void noted(Ureg*, Ureg**, ulong); void rfnote(Ureg**); void kernfault(Ureg*, int); @@ -527,20 +527,20 @@ notify(Ureg *ur) qunlock(&up->debug); pexit(n->msg, n->flag!=NDebug); } - up->svstatus = ur->status; sp = ur->usp & ~(BY2V-1); sp -= sizeof(Ureg); if(!okaddr((ulong)up->notify, BY2WD, 0) || - !okaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 1)) { + !okaddr(sp-ERRLEN-4*BY2WD, sizeof(Ureg)+ERRLEN-4*BY2WD, 1)) { pprint("suicide: bad address or sp in notify\n"); qunlock(&up->debug); pexit("Suicide", 0); } - up->ureg = (void*)sp; memmove((Ureg*)sp, ur, sizeof(Ureg)); - sp -= ERRLEN; + *(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */ + up->ureg = (void*)sp; + sp -= BY2WD+ERRLEN; memmove((char*)sp, up->note[0].msg, ERRLEN); sp -= 3*BY2WD; *(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */ @@ -562,16 +562,32 @@ notify(Ureg *ur) return 1; } +/* + * Check that status is OK to return from note. + */ +int +validstatus(ulong kstatus, ulong ustatus) +{ + if((kstatus & (INTMASK|KX|SX|UX)) != (ustatus & (INTMASK|KX|SX|UX))) + return 0; + if((ustatus&(KSU|ERL|EXL|IE)) != (KUSER|EXL|IE)) + return 0; + if(ustatus & (0xFFFF0000&~CU1)) /* no CU3, CU2, CU0, RP, FR, RE, DS */ + return 0; + return 1; +} + /* * Return user to state before notify() */ void -noted(Ureg **urp, ulong arg0) +noted(Ureg *kur, Ureg **urp, ulong arg0) { Ureg *nur; + ulong oureg, sp; qlock(&up->debug); - if(!up->notified) { + if(arg0!=NRSTR && !up->notified) { qunlock(&up->debug); pprint("call to noted() when not notified\n"); pexit("Suicide", 0); @@ -579,22 +595,54 @@ noted(Ureg **urp, ulong arg0) up->notified = 0; nur = up->ureg; - if(nur->status!=up->svstatus) { + if(!validstatus(kur->status, nur->status)) { qunlock(&up->debug); pprint("bad noted ureg status %lux\n", nur->status); pexit("Suicide", 0); } + oureg = (ulong)up->ureg; + if(oureg){ + if(oureg>=USTKTOP || ouregureg in noted\n"); + qunlock(&up->debug); + pexit("Suicide", 0); + } + } + memmove(*urp, up->ureg, sizeof(Ureg)); switch(arg0) { case NCONT: - if(!okaddr(nur->pc, 1, 0) || !okaddr(nur->usp, BY2WD, 0)){ + case NRSTR: + if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->usp, BY2WD, 0)){ + pprint("suicide: trap in noted\n"); + qunlock(&up->debug); + pexit("Suicide", 0); + } + up->ureg = (Ureg*)(*(ulong*)(oureg-BY2WD)); + qunlock(&up->debug); + splhi(); + rfnote(urp); + break; + + case NSAVE: + if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->usp, BY2WD, 0)){ pprint("suicide: trap in noted\n"); qunlock(&up->debug); pexit("Suicide", 0); } qunlock(&up->debug); + sp = oureg-4*BY2WD-ERRLEN; splhi(); + (*urp)->sp = sp; + ((ulong*)sp)[1] = (ulong)up->ureg; /* arg 1 0(FP) is ureg* */ + ((ulong*)sp)[0] = 0; /* arg 0 is pc */ + (*urp)->r1 = oureg; /* arg 1 is ureg* */ + (*urp)->hr1 = 0; + if(oureg < 0) + (*urp)->hr1 = ~0; rfnote(urp); break; @@ -672,8 +720,8 @@ error: up->nerrlab = 0; up->psstate = 0; up->insyscall = 0; - if(up->scallnr == NOTED) /* ugly hack */ - noted(&aur, *(ulong*)(sp+BY2WD)); /* doesn't return */ + if(up->scallnr == NOTED) /* ugly hack */ + noted(ur, &aur, *(ulong*)(sp+BY2WD)); /* doesn't return */ splhi(); if(up->scallnr!=RFORK && (up->procctl || up->nnote)){ diff --git a/pc/devastar.c b/pc/devastar.c index 30c90138518c9b0d1112be8709a2f5585bfe750d..3073e45ec73035411450c9dd9cc8d6f60cb05b1b 100644 --- a/pc/devastar.c +++ b/pc/devastar.c @@ -418,7 +418,7 @@ astarreset(void) a->mem = getisa(a->mem, Pagesize, Pagesize); if(a->mem == 0) panic("astarreset: %lux", a->mem); - a->mem & ~KZERO; + a->mem &= ~KZERO; if(astarsetup(a) < 0){ xfree(a); diff --git a/pc/trap.c b/pc/trap.c index a540217af7aa1f58fdfc47d86b5de2a9a331e5b8..f66f235d0b68ad5f9ed66cfd6b5e2a0363968275 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -472,6 +472,7 @@ syscall(Ureg *ur, void *arg) if(up->scallnr!=RFORK && (up->procctl || up->nnote)) notify(ur); + } /* diff --git a/port/lib.h b/port/lib.h index 9a625ae094e0d0e775cf84a18ec6b3a963b25b35..a714672185d5847803daa6cdd9a8994c32b2d258 100644 --- a/port/lib.h +++ b/port/lib.h @@ -93,6 +93,8 @@ extern char end[]; #define NCONT 0 /* continue after note */ #define NDFLT 1 /* terminate after note */ +#define NSAVE 2 /* clear note but hold state */ +#define NRSTR 3 /* restore saved state */ typedef struct Qid Qid; typedef struct Dir Dir; diff --git a/port/proc.c b/port/proc.c index f11a2305cbc1352f7288c72e1213a718ebdbbcfe..523c31e1efbdbdc4af8ed5cc4494318f9bd84e8b 100644 --- a/port/proc.c +++ b/port/proc.c @@ -313,6 +313,7 @@ newproc(void) p->mp = 0; p->movetime = 0; p->wired = 0; + p->ureg = 0; memset(p->seg, 0, sizeof p->seg); p->pid = incref(&pidalloc); p->noteid = incref(¬eidalloc); diff --git a/port/sysproc.c b/port/sysproc.c index 1aea815bac0e54295ad6f135e9d8df5a12c1d259..9ff311bb21eeeedda08506895f57aeec56a9c2b3 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -92,7 +92,7 @@ sysrfork(ulong *arg) p->notified = 0; p->lastnote = up->lastnote; p->notify = up->notify; - p->ureg = 0; + p->ureg = up->ureg; p->dbgreg = 0; /* Make a new set of memory segments */ @@ -126,10 +126,8 @@ sysrfork(ulong *arg) incref(p->pgrp); } - if(flag & RFREND) { - closergrp(up->rgrp); - up->rgrp = newrgrp(); - } + if(flag & RFREND) + p->rgrp = newrgrp(); else { incref(up->rgrp); p->rgrp = up->rgrp; @@ -549,8 +547,7 @@ sysnotify(ulong *arg) long sysnoted(ulong *arg) { - USED(arg); - if(up->notified == 0) + if(arg[0]!=NRSTR && !up->notified) error(Egreg); return 0; }