M gnot/devenv.c => gnot/devenv.c +1 -1
@@ 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)
M gnot/devincon.c => gnot/devincon.c +2 -0
@@ 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);
M gnot/errno.h => gnot/errno.h +1 -0
@@ 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 */
};
M gnot/fault.c => gnot/fault.c +7 -1
@@ 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);
M gnot/fns.h => gnot/fns.h +1 -1
@@ 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*);
M gnot/main.c => gnot/main.c +1 -0
@@ 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);
M gnot/page.c => gnot/page.c +38 -9
@@ 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;
}
M port/devenv.c => port/devenv.c +1 -1
@@ 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)
M port/fault.c => port/fault.c +7 -1
@@ 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);
M port/page.c => port/page.c +37 -11
@@ 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;
}
M power/clock.c => power/clock.c +1 -1
@@ 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 */
M power/errno.h => power/errno.h +1 -0
@@ 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 */
};
M power/fns.h => power/fns.h +1 -1
@@ 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);
M power/main.c => power/main.c +6 -1
@@ 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);
M power/trap.c => power/trap.c +1 -1
@@ 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;