From c42eb44c6d3a808ac425cbfbbaa2cf175b72cd55 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 2 Aug 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-08-02 --- gnot/devenv.c | 2 +- gnot/devincon.c | 2 ++ gnot/errno.h | 1 + gnot/fault.c | 8 +++++++- gnot/fns.h | 2 +- gnot/main.c | 1 + gnot/page.c | 47 ++++++++++++++++++++++++++++++++++++++--------- port/devenv.c | 2 +- port/fault.c | 8 +++++++- port/page.c | 48 +++++++++++++++++++++++++++++++++++++----------- power/clock.c | 2 +- power/errno.h | 1 + power/fns.h | 2 +- power/main.c | 7 ++++++- power/trap.c | 2 +- 15 files changed, 106 insertions(+), 29 deletions(-) diff --git a/gnot/devenv.c b/gnot/devenv.c index 1d6d78ba85e288b6b28d075847a734f383d5d22d..96f3af5ccf7fe927d25dbde4140b85dab426cf9f 100644 --- a/gnot/devenv.c +++ b/gnot/devenv.c @@ -143,7 +143,7 @@ compactenv(Env *e, ulong n) goto Free; } if(p2+p2->n > envalloc.end) - panic("compactpte copying too much"); + panic("compactenv copying too much"); memcpy(p1, p2, p2->n*sizeof(Envval)); p2e->val = p1; if(p2e != e) diff --git a/gnot/devincon.c b/gnot/devincon.c index b8cf9b0c8d6d8c4414eb3c1f3e2b853a3772435f..10bf3df2cdd9896d78629dd6c59f75c277358340 100644 --- a/gnot/devincon.c +++ b/gnot/devincon.c @@ -493,6 +493,8 @@ inconoput(Queue *q, Block *bp) chan = bp->rptr[0] | (bp->rptr[1]<<8); ctl = bp->rptr[2]; bp->rptr += 3; + if(chan<=0) + print("bad channel %d\n", chan); if(incondebug) print("->(%d)%uo %d\n", chan, ctl, bp->wptr - bp->rptr); diff --git a/gnot/errno.h b/gnot/errno.h index ee070d757d339a590130a6765dd747ff37150b39..4ac80562c89324daa3612a6731601e569e28c10f 100644 --- a/gnot/errno.h +++ b/gnot/errno.h @@ -55,5 +55,6 @@ enum{ Ebadmsg, /* format error or mismatch in message */ Ebadcnt, /* read count greater than requested */ Enofont, /* out of font descriptors */ + Enovmem, /* virtual memory allocation failed */ Egreg, /* it's all greg's fault */ }; diff --git a/gnot/fault.c b/gnot/fault.c index 6027cdfc1beb30e60341383a3ccc5a893479adc0..0f1cffb263f0022b03a59836520ca421cca5b6e6 100644 --- a/gnot/fault.c +++ b/gnot/fault.c @@ -108,9 +108,15 @@ fault(Ureg *ur, FFrame *f) /* grow stack */ o = s->o; n = o->npte; + lock(o); + if(waserror()){ + unlock(o); + pprint("can't allocate stack page\n"); + goto cant; + } growpte(o, (s->maxva-addr)>>PGSHIFT); + poperror(); /* stacks grown down, sigh */ - lock(o); memcpy(o->pte+(o->npte-n), o->pte, n*sizeof(PTE)); memset(o->pte, 0, (o->npte-n)*sizeof(PTE)); unlock(o); diff --git a/gnot/fns.h b/gnot/fns.h index d74b10897f92ef49423a5675bc3505cde05edb91..7a086ab0b8ad1098d637048bbde7989104ac5a2f 100644 --- a/gnot/fns.h +++ b/gnot/fns.h @@ -15,7 +15,7 @@ void close(Chan*); void closemount(Mount*); void closepgrp(Pgrp*); long clrfpintr(void); -void compactpte(Orig*, ulong); +int compactpte(Orig*, ulong); void confinit(void); Env *copyenv(Env*, int); int decref(Ref*); diff --git a/gnot/main.c b/gnot/main.c index 37c757e4711ec0c32847d6a3a3c29e38eee1d5ae..3cdaa1970e8a43d5be091bfe55c2b93bce455e7e 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -160,6 +160,7 @@ userinit(void) s->proc = p; s->o = neworig(UTZERO, 1, 0, 0); s->o->pte[0].page = newpage(0, 0, UTZERO); + s->o->npage = 1; k = kmap(s->o->pte[0].page); memcpy((ulong*)VA(k), initcode, sizeof initcode); kunmap(k); diff --git a/gnot/page.c b/gnot/page.c index e0164e6422dff0e2be3e66857d5b00669bd46ddf..469d9db07098a682e4e81f038ab2163c84a2e6dc 100644 --- a/gnot/page.c +++ b/gnot/page.c @@ -4,6 +4,7 @@ #include "dat.h" #include "fns.h" #include "ureg.h" +#include "errno.h" struct { @@ -310,7 +311,16 @@ loop: o->mqid = -1; o->mchan = 0; } + lock(o); + if(u && u->p && waserror()){ + unlock(o); + unlock(&origalloc); + nexterror(); + } growpte(o, npte); + if(u && u->p) + poperror(); + unlock(o); unlock(&origalloc); return o; } @@ -505,8 +515,15 @@ segaddr(Seg *s, ulong min, ulong max) * Grow */ /* BUG: check spill onto other segments */ + lock(o); + if(waserror()){ + unlock(o); + nexterror(); + } if(o->va+BY2PG*o->npte < max) growpte(o, (max-o->va)>>PGSHIFT); + unlock(o); + poperror(); s->maxva = max; return 1; } @@ -558,9 +575,9 @@ growpte(Orig *o, ulong n) ulong nfree; lock(&ptealloc); - lock(o); if(o->pte){ if(o->npte == n){ +if(u && u->p) print("%s: ", u->p->text); print("growpte pointless\n"); goto Return; } @@ -577,11 +594,13 @@ growpte(Orig *o, ulong n) }else{ n++; if(p+p->n == ptealloc.free){ - compactpte(o, n - p->n); + if(!compactpte(o, n - p->n)) + goto Trouble; p = (PTEA*)(o->pte - 1); ptealloc.free += n - p->n; }else{ - compactpte(o, n); + if(!compactpte(o, n)) + goto Trouble; p = ptealloc.free; ptealloc.free += n; memcpy(p+1, o->pte, o->npte*sizeof(PTE)); @@ -596,7 +615,8 @@ growpte(Orig *o, ulong n) goto Return; } n++; - compactpte(o, n); + if(!compactpte(o, n)) + goto Trouble; p = ptealloc.free; ptealloc.free += n; memset(p, 0, n*sizeof(PTE)); @@ -605,18 +625,24 @@ growpte(Orig *o, ulong n) o->pte = p+1; o->npte = n-1; Return: - unlock(o); unlock(&ptealloc); + return; + + Trouble: + unlock(&ptealloc); + if(u && u->p) + error(0, Enovmem); + panic("growpte fails %d %lux %d\n", n, o->va, o->npte); } -void +int compactpte(Orig *o, ulong n) { PTEA *p1, *p2; Orig *p2o; if(ptealloc.end-ptealloc.free >= n) - return; + return 1; p1 = ptealloc.arena; /* dest */ p2 = ptealloc.arena; /* source */ while(p2 < ptealloc.free){ @@ -645,8 +671,11 @@ compactpte(Orig *o, ulong n) } ptealloc.free = p1; if(ptealloc.end-ptealloc.free >= n) - return; + return 1; unlock(o); unlock(&ptealloc); - panic("compactpte %d %lux %d", n, o->va, o->npte); + if(u && u->p) + print("%s: %s: ", u->p->text, u->p->pgrp->user); + print("compactpte fails addr %lux\n", o->va+n*BY2PG); + return 0; } diff --git a/port/devenv.c b/port/devenv.c index 1d6d78ba85e288b6b28d075847a734f383d5d22d..96f3af5ccf7fe927d25dbde4140b85dab426cf9f 100644 --- a/port/devenv.c +++ b/port/devenv.c @@ -143,7 +143,7 @@ compactenv(Env *e, ulong n) goto Free; } if(p2+p2->n > envalloc.end) - panic("compactpte copying too much"); + panic("compactenv copying too much"); memcpy(p1, p2, p2->n*sizeof(Envval)); p2e->val = p1; if(p2e != e) diff --git a/port/fault.c b/port/fault.c index 086bf45030dc1be718a3bb1970e5ac02aeabf05d..0e3be17e8c00a0867acde479cbefaf58b86387d9 100644 --- a/port/fault.c +++ b/port/fault.c @@ -43,9 +43,15 @@ fault(Ureg *ur, int user, int code) /* grow stack */ o = s->o; n = o->npte; + lock(o); + if(waserror()){ + unlock(o); + pprint("can't allocate stack page\n"); + goto cant; + } growpte(o, (s->maxva-addr)>>PGSHIFT); + poperror(); /* stacks grown down, sigh */ - lock(o); memcpy(o->pte+(o->npte-n), o->pte, n*sizeof(PTE)); memset(o->pte, 0, (o->npte-n)*sizeof(PTE)); unlock(o); diff --git a/port/page.c b/port/page.c index eb85fb0dfeece75d5c97d96fd17632600972ad1c..b8f270c6a3c70ae7ba79f64c4905b8aefb95553c 100644 --- a/port/page.c +++ b/port/page.c @@ -4,6 +4,7 @@ #include "dat.h" #include "fns.h" #include "ureg.h" +#include "errno.h" struct { @@ -257,7 +258,6 @@ usepage(Page *p, int dolock) void unusepage(Page *p, int dolock) { -return; if(dolock) lock(&palloc); /* @@ -339,7 +339,16 @@ o->nmod = 0; o->mqid = -1; o->mchan = 0; } + lock(o); + if(u && u->p && waserror()){ + unlock(o); + unlock(&origalloc); + nexterror(); + } growpte(o, npte); + if(u && u->p) + poperror(); + unlock(o); unlock(&origalloc); return o; } @@ -527,7 +536,6 @@ segaddr(Seg *s, ulong min, ulong max) if(max < min) return 0; -if(max > 20*1024*1024) {pprint("segaddr %lux\n", max);print("segaddr %lux\n", max);} if(min != s->minva) /* can't grow down yet (stacks: fault.c) */ return 0; max = (max+(BY2PG-1)) & ~(BY2PG-1); @@ -539,8 +547,15 @@ if(max > 20*1024*1024) {pprint("segaddr %lux\n", max);print("segaddr %lux\n", ma * Grow */ /* BUG: check spill onto other segments */ + lock(o); + if(waserror()){ + unlock(o); + nexterror(); + } if(o->va+BY2PG*o->npte < max) growpte(o, (max-o->va)>>PGSHIFT); + unlock(o); + poperror(); s->maxva = max; return 1; } @@ -593,7 +608,6 @@ growpte(Orig *o, ulong n) ulong nfree; lock(&ptealloc); - lock(o); if(o->pte){ if(o->npte == n){ if(u && u->p) print("%s: ", u->p->text); @@ -613,11 +627,13 @@ if(u && u->p) print("%s: ", u->p->text); }else{ n++; if(p+p->n == ptealloc.free){ - compactpte(o, n - p->n); + if(!compactpte(o, n - p->n)) + goto Trouble; p = (PTEA*)(o->pte - 1); ptealloc.free += n - p->n; }else{ - compactpte(o, n); + if(!compactpte(o, n)) + goto Trouble; p = ptealloc.free; ptealloc.free += n; memcpy(p+1, o->pte, o->npte*sizeof(PTE)); @@ -632,7 +648,8 @@ if(u && u->p) print("%s: ", u->p->text); goto Return; } n++; - compactpte(o, n); + if(!compactpte(o, n)) + goto Trouble; p = ptealloc.free; ptealloc.free += n; memset(p, 0, n*sizeof(PTE)); @@ -641,18 +658,24 @@ if(u && u->p) print("%s: ", u->p->text); o->pte = p+1; o->npte = n-1; Return: - unlock(o); unlock(&ptealloc); + return; + + Trouble: + unlock(&ptealloc); + if(u && u->p) + error(0, Enovmem); + panic("growpte fails %d %lux %d\n", n, o->va, o->npte); } -void +int compactpte(Orig *o, ulong n) { PTEA *p1, *p2; Orig *p2o; if(ptealloc.end-ptealloc.free >= n) - return; + return 1; p1 = ptealloc.arena; /* dest */ p2 = ptealloc.arena; /* source */ while(p2 < ptealloc.free){ @@ -681,8 +704,11 @@ compactpte(Orig *o, ulong n) } ptealloc.free = p1; if(ptealloc.end-ptealloc.free >= n) - return; + return 1; unlock(o); unlock(&ptealloc); - panic("compactpte %d %lux %d", n, o->va, o->npte); + if(u && u->p) + print("%s: %s: ", u->p->text, u->p->pgrp->user); + print("compactpte fails addr %lux\n", o->va+n*BY2PG); + return 0; } diff --git a/power/clock.c b/power/clock.c index a5f3d37e4ad4a9e7b76165973da9db67e97f00fb..78671a3e57cfa808d99f21b098066ffd6ad56811 100644 --- a/power/clock.c +++ b/power/clock.c @@ -116,7 +116,7 @@ struct Timer{ #define MODE2 0x04 /* interval timer */ -#define PROFILING +/* #define PROFILING /**/ #ifdef PROFILING #undef TIME1 #define TIME1 211 /* profiling clock; prime; about 10ms per tick */ diff --git a/power/errno.h b/power/errno.h index beb69e232b20047a1a19bc943fe8a21cbb9b369b..f83ad0c595e287bcafe0cd5e8fa214ef5c0f002f 100644 --- a/power/errno.h +++ b/power/errno.h @@ -50,5 +50,6 @@ enum{ Ebadmsg, /* format error or mismatch in message */ Ebadcnt, /* read count greater than requested */ Enoannounce, /* listening on an unannounced network connection */ + Enovmem, /* virtual memory allocation failed */ Egreg, /* it's all greg's fault */ }; diff --git a/power/fns.h b/power/fns.h index e546eae3c81842b1370da7087c1bc1b3b07674a8..4cfdc937dca57fc266b77c3410cd0c72e3e5f7c7 100644 --- a/power/fns.h +++ b/power/fns.h @@ -16,7 +16,7 @@ void close(Chan*); void closemount(Mount*); void closepgrp(Pgrp*); long clrfpintr(void); -void compactpte(Orig*, ulong); +int compactpte(Orig*, ulong); ulong confeval(char*); void confprint(void); void confinit(void); diff --git a/power/main.c b/power/main.c index c738d35e607f7992bfb1b441c1fde6b79c8e6b11..897688ab0c309f1c95e6f1dc5ad1a53ab57f8749 100644 --- a/power/main.c +++ b/power/main.c @@ -246,8 +246,13 @@ userinit(void) */ s = &p->seg[TSEG]; s->proc = p; - s->o = neworig(UTZERO, 1, 0, 0); + /* + * On the mips, init text must be OCACHED to avoid reusing page + * and getting in trouble with the hardware instruction cache. + */ + s->o = neworig(UTZERO, 1, OCACHED, 0); s->o->pte[0].page = newpage(0, 0, UTZERO); + s->o->npage = 1; k = kmap(s->o->pte[0].page); memcpy((ulong*)VA(k), initcode, sizeof initcode); kunmap(k); diff --git a/power/trap.c b/power/trap.c index 77cad73217f6c1828fff025347541a4220affdcd..741f4eb2b262ed51983af215889d35a6582625b8 100644 --- a/power/trap.c +++ b/power/trap.c @@ -113,7 +113,7 @@ trap(Ureg *ur) case CTLBL: case CTLBS: if(u == 0) - panic("fault"); + panic("fault u==0 pc %lux addr %lux", ur->pc, ur->badvaddr); if(u->p->fpstate == FPactive) { savefpregs(&u->fpsave); u->p->fpstate = FPinactive;