## diffname port/fault.c 1990/0227
## diff -e /dev/null /n/bootesdump/1990/0227/sys/src/9/mips/fault.c
0a
#include "u.h"
#include "lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "ureg.h"
#include "errno.h"
void
fault(Ureg *ur, int user, int code)
{
ulong addr, mmuvirt, mmuphys, n;
extern char *excname[];
Seg *s;
PTE *opte, *pte, *npte;
Orig *o;
char *l;
Page *pg;
int zeroed = 0, head = 1;
int i;
addr = ur->badvaddr;
addr &= ~(BY2PG-1);
s = seg(u->p, addr);
if(s == 0){
if(addr>USTKTOP){
cant:
if(user){
pprint("user %s badvaddr=0x%lux\n", excname[code], ur->badvaddr);
pprint("status=0x%lux pc=0x%lux sp=0x%lux\n", ur->status, ur->pc, ur->sp);
pexit("Suicide", 0);
}
print("kernel %s badvaddr=0x%lux\n", excname[code], ur->badvaddr);
print("status=0x%lux pc=0x%lux sp=0x%lux\n", ur->status, ur->pc, ur->sp);
u->p->state = MMUing;
dumpregs(ur);
panic("fault");
}
s = &u->p->seg[SSEG];
if(s->o==0 || addr<s->maxva-4*1024*1024 || addr>=s->maxva)
goto cant;
/* grow stack */
o = s->o;
n = o->npte;
growpte(o, (s->maxva-addr)>>PGSHIFT);
/* 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);
s->minva = addr;
o->va = addr;
}else
o = s->o;
if((code==CTLBM || code==CTLBS) && (o->flag&OWRPERM)==0)
goto cant;
lock(o);
opte = &o->pte[(addr-o->va)>>PGSHIFT];
pte = opte;
if(s->mod){
while(pte = pte->nextmod) /* assign = */
if(pte->proc == u->p){
if(pte->page==0 || pte->page->va!=addr)
panic("bad page %lux", pte->page);
head = 0;
break;
}
if(pte == 0)
pte = opte;
}
if(pte->page == 0){
if(o->chan==0 || addr>(o->va+(o->maxca-o->minca))){
/*
* Zero fill page. If we are really doing a copy-on-write
* (e.g. into shared bss) we'll move the page later.
*/
pte->page = newpage(0, o, addr);
o->npage++;
zeroed = 1;
}else{
/*
* Demand load. Release o because it could take a while.
*/
unlock(o);
n = (o->va+(o->maxca-o->minca)) - addr;
if(n > BY2PG)
n = BY2PG;
pg = newpage(1, o, addr);
qlock(o->chan);
if(waserror()){
print("demand load i/o error %d\n", u->error.code);
qunlock(o->chan);
pg->o = 0;
pg->ref--;
goto cant;
}
o->chan->offset = (addr-o->va) + o->minca;
l = (char*)(pg->pa|KZERO);
if((*devtab[o->chan->type].read)(o->chan, l, n) != n)
error(0, Eioload);
qunlock(o->chan);
poperror();
/* BUG: if was first page of bss, move to data */
if(n<BY2PG)
memset(l+n, 0, BY2PG-n);
lock(o);
opte = &o->pte[(addr-s->minva)>>PGSHIFT]; /* could move */
pte = opte;
if(pte->page == 0){
pte->page = pg;
o->npage++;
}else{ /* someone beat us to it */
pg->o = 0;
pg->ref--;
}
}
}
/*
* Copy on reference
*/
if((o->flag & OWRPERM)
&& ((head && ((o->flag&OPURE) || o->nproc>1))
|| (!head && pte->page->ref>1))){
/*
* Look for the easy way out: are we the last non-modified?
*/
if(head && !(o->flag&OPURE)){
npte = opte;
for(i=0; npte; i++)
npte = npte->nextmod;
if(i == o->nproc)
goto easy;
}
if(head){
/*
* Add to mod list
*/
pte = newmod();
pte->proc = u->p;
pte->page = opte->page;
pte->page->ref++;
o->npage++;
/*
* Link into opte mod list (same va)
*/
pte->nextmod = opte->nextmod;
opte->nextmod = pte;
/*
* Link into proc mod list (increasing va)
*/
npte = s->mod;
if(npte == 0){
s->mod = pte;
pte->nextva = 0;
}else{
while(npte->nextva && npte->nextva->page->va<addr)
npte = npte->nextva;
pte->nextva = npte->nextva;
npte->nextva = pte;
}
head = 0;
}
pg = pte->page;
if(zeroed){ /* move page */
pg->ref--;
o->npage--;
opte->page = 0;
}else{ /* copy page */
pte->page = newpage(1, o, addr);
memcpy((void*)(pte->page->pa|KZERO), (void*)(pg->pa|KZERO), BY2PG);
if(pg->ref <= 1)
panic("pg->ref <= 1");
pg->ref--;
}
easy:
mmuphys = PTEWRITE;
}else{
mmuphys = 0;
if(o->flag & OWRPERM)
if(o->flag & OPURE){
if(!head && pte->page->ref==1)
mmuphys = PTEWRITE;
}else
if((head && o->nproc==1)
|| (!head && pte->page->ref==1))
mmuphys = PTEWRITE;
}
mmuvirt = addr;
mmuphys |= pte->page->pa | PTEVALID;
usepage(pte->page, 1);
if(pte->page->va != addr)
panic("wrong addr in tail %lux %lux", pte->page->va, addr);
if(pte->proc && pte->proc != u->p){
print("wrong proc in tail %d %s\n", head, u->p->text);
print("u->p %lux pte->proc %lux\n", u->p, pte->proc);
panic("addr %lux seg %d wrong proc in tail", addr, s-u->p->seg);
}
unlock(o);
putmmu(mmuvirt, mmuphys);
}
/*
* Called only in a system call
*/
void
validaddr(ulong addr, ulong len, int write)
{
Seg *s;
if((long)len < 0)
panic("validaddr len %lux\n", len);
s = seg(u->p, addr);
if(s==0 || addr+len>s->maxva || (write && (s->o->flag&OWRPERM)==0)){
pprint("invalid address in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp);
postnote(u->p, 1, "bad address", NDebug);
error(0, Ebadarg);
}
}
void
evenaddr(ulong addr)
{
if(addr & 3){
postnote(u->p, 1, "odd address", NDebug);
error(0, Ebadarg);
}
}
/*
* &s[0] is known to be a valid address.
*/
void*
vmemchr(void *s, int c, int n)
{
int m;
char *t;
ulong a;
a = (ulong)s;
m = BY2PG - (a & (BY2PG-1));
if(m < n){
t = vmemchr(s, c, m);
if(t)
return t;
if(!(a & KZERO))
validaddr(a+m, 1, 0);
return vmemchr((void*)(a+m), c, n-m);
}
/*
* All in one page
*/
return memchr(s, c, n);
}
Seg*
seg(Proc *p, ulong addr)
{
int i;
Seg *s;
for(i=0,s=p->seg; i<NSEG; i++,s++)
if(s->o && s->minva<=addr && addr<s->maxva)
return s;
return 0;
}
.
## diffname port/fault.c 1990/0312
## diff -e /n/bootesdump/1990/0227/sys/src/9/mips/fault.c /n/bootesdump/1990/0312/sys/src/9/mips/fault.c
215a
Err:
.
213c
goto Err;
.
140a
o->nmod++;
.
## diffname port/fault.c 1990/0617
## diff -e /n/bootesdump/1990/0312/sys/src/9/mips/fault.c /n/bootesdump/1990/0617/sys/src/9/mips/fault.c
220a
}
Again:
s = seg(u->p, addr);
if(s==0)
goto Err;
if(write && (s->o->flag&OWRPERM)==0)
goto Err;
if(addr+len > s->maxva){
len -= s->maxva - addr;
addr = s->maxva;
goto Again;
.
213,216c
if((long)len < 0){
.
211c
Seg *s, *ns;
.
## diffname port/fault.c 1990/0802
## diff -e /n/bootesdump/1990/0617/sys/src/9/mips/fault.c /n/bootesdump/1990/0802/sys/src/9/mips/fault.c
48d
46a
poperror();
.
45a
lock(o);
if(waserror()){
unlock(o);
pprint("can't allocate stack page\n");
goto cant;
}
.
## diffname port/fault.c 1990/0814
## diff -e /n/bootesdump/1990/0802/sys/src/9/mips/fault.c /n/bootesdump/1990/0814/sys/src/9/mips/fault.c
54a
lock(o);
.
48d
46d
## diffname port/fault.c 1990/0821
## diff -e /n/bootesdump/1990/0814/sys/src/9/mips/fault.c /n/bootesdump/1990/0821/sys/src/9/mips/fault.c
226,227c
if(s==0){
s = &u->p->seg[SSEG];
if(s->o==0 || addr<s->maxva-USTACKSIZE || addr>=s->maxva)
goto Err;
}
.
41c
if(s->o==0 || addr<s->maxva-USTACKSIZE || addr>=s->maxva)
.
## diffname port/fault.c 1990/1013
## diff -e /n/bootesdump/1990/0821/sys/src/9/mips/fault.c /n/bootesdump/1990/1013/sys/src/9/mips/fault.c
145c
pte = newmod(o);
.
## diffname port/fault.c 1990/1110
## diff -e /n/bootesdump/1990/1013/sys/src/9/mips/fault.c /n/bootesdump/1990/1110/sys/src/9/mips/fault.c
244c
postnote(u->p, 1, "sys: odd address", NDebug);
.
221c
postnote(u->p, 1, "sys: bad address", NDebug);
.
100a
if(user)
pexit("Interrupt", 0);
.
## diffname port/fault.c 1990/1113
## diff -e /n/bootesdump/1990/1110/sys/src/9/mips/fault.c /n/bootesdump/1990/1113/sys/src/9/mips/fault.c
101,103c
pexit("load i/o error", 0);
.
## diffname port/fault.c 1990/11211
## diff -e /n/bootesdump/1990/1113/sys/src/9/mips/fault.c /n/bootesdump/1990/11211/sys/src/9/mips/fault.c
245c
error(Ebadarg);
.
222c
error(Ebadarg);
.
146d
106c
error(Eioload);
.
97c
print("demand load i/o error %s\n", u->error);
.
## diffname port/fault.c 1990/1202
## diff -e /n/bootesdump/1990/11211/sys/src/9/mips/fault.c /n/bootesdump/1990/1202/sys/src/9/mips/fault.c
97d
## diffname port/fault.c 1990/1212
## diff -e /n/bootesdump/1990/1212/sys/src/9/mips/fault.c /n/bootesdump/1990/1212/sys/src/9/port/fault.c
235,243d
205a
return 0;
.
195c
mmuphys |= PPN(pte->page->pa) | PTEVALID;
.
184c
mmuphys = PTERONLY;
.
176c
k = kmap(pte->page);
k1 = kmap(pg);
memcpy((void*)VA(k), (void*)VA(k1), BY2PG);
kunmap(k);
kunmap(k1);
.
126c
if((o->flag & OWRPERM) && (conf.copymode || !read)
.
124c
* Copy on reference (conf.copymode==1) or write (conf.copymode==0)
.
111a
kunmap(k);
poperror();
.
107,108d
103c
l = (char*)VA(k);
.
96a
kunmap(k);
.
94a
k = kmap(pg);
.
61,62c
if(!read && (o->flag&OWRPERM)==0)
return -1;
.
48c
return -1;
.
42c
return -1;
.
27,39c
if(addr>USTKTOP)
return -1;
.
22,24d
20a
KMap *k, *k1;
.
12,13c
ulong mmuvirt, mmuphys, n;
.
9,10c
int
fault(ulong addr, int read)
.
## diffname port/fault.c 1991/0110
## diff -e /n/bootesdump/1990/1212/sys/src/9/port/fault.c /n/bootesdump/1991/0110/sys/src/9/port/fault.c
24c
if(addr > USTKTOP)
.
## diffname port/fault.c 1991/0115
## diff -e /n/bootesdump/1991/0110/sys/src/9/port/fault.c /n/bootesdump/1991/0115/sys/src/9/port/fault.c
211c
pprint("invalid address %lux in sys call pc %lux sp %lux\n", addr, ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp);
.
## diffname port/fault.c 1991/0312
## diff -e /n/bootesdump/1991/0115/sys/src/9/port/fault.c /n/bootesdump/1991/0312/sys/src/9/port/fault.c
93a
flushpage(pg->pa);
.
## diffname port/fault.c 1991/0318
## diff -e /n/bootesdump/1991/0312/sys/src/9/port/fault.c /n/bootesdump/1991/0318/sys/src/9/port/fault.c
167c
memmove((void*)VA(k), (void*)VA(k1), BY2PG);
.
40c
memmove(o->pte+(o->npte-n), o->pte, n*sizeof(PTE));
.
## diffname port/fault.c 1991/0411
## diff -e /n/bootesdump/1991/0318/sys/src/9/port/fault.c /n/bootesdump/1991/0411/sys/src/9/port/fault.c
95c
qunlock(&o->chan->rdl);
.
92c
if((*devtab[o->chan->type].read)(o->chan, l, n, (addr-o->va) + o->minca) != n)
.
90d
85c
qunlock(&o->chan->rdl);
.
82c
qlock(&o->chan->rdl);
.
## diffname port/fault.c 1991/0425
## diff -e /n/bootesdump/1991/0411/sys/src/9/port/fault.c /n/bootesdump/1991/0425/sys/src/9/port/fault.c
196a
if(touched == 0)
m->tlbfault++;
.
117c
touched = 1;
.
63a
touched = 1;
.
19c
int i, touched = 0;
.
## diffname port/fault.c 1991/0427
## diff -e /n/bootesdump/1991/0425/sys/src/9/port/fault.c /n/bootesdump/1991/0427/sys/src/9/port/fault.c
21a
m->pfault++;
.
## diffname port/fault.c 1991/0501
## diff -e /n/bootesdump/1991/0427/sys/src/9/port/fault.c /n/bootesdump/1991/0501/sys/src/9/port/fault.c
90c
pexit("demand load i/o error", 0);
.
## diffname port/fault.c 1991/0605
## diff -e /n/bootesdump/1991/0501/sys/src/9/port/fault.c /n/bootesdump/1991/0605/sys/src/9/port/fault.c
223c
if(s->o==0 || addr<s->maxva-USTKSIZE || addr>=s->maxva)
.
28c
if(s->o==0 || addr<s->maxva-USTKSIZE || addr>=s->maxva)
.
## diffname port/fault.c 1991/0606
## diff -e /n/bootesdump/1991/0605/sys/src/9/port/fault.c /n/bootesdump/1991/0606/sys/src/9/port/fault.c
267c
et = &p->seg[NSEG];
for(s=p->seg; s < et; s++)
.
264,265c
Seg *s, *et;
.
215c
pprint("invalid address %lux in sys call pc %lux sp %lux\n",
addr, ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp);
.
186c
mmuphys |= PTEWRITE;
.
182c
mmuphys |= PTEWRITE;
.
178c
mmuphys |= PTERONLY;
.
176c
mmuphys |= PTEWRITE;
.
174a
pg->ref--;
.
173d
160,161c
/* when creating pages in the bss which are zfod we create a double
* increment on the mod list which must be removed
*/
if(zeroed){
.
73a
o->npage++;
.
67,72c
/* Make a new bss or lock segment page */
if(s - u->p->seg == LSEG) {
pte->page = lkpage(o, addr);
mmuphys = PTEUNCACHE;
}
else
pte->page = newpage(0, o, addr);
.
12c
ulong mmuvirt, mmuphys = 0, n;
.
## diffname port/fault.c 1991/0607
## diff -e /n/bootesdump/1991/0606/sys/src/9/port/fault.c /n/bootesdump/1991/0607/sys/src/9/port/fault.c
205a
.
202a
.
194,195c
mmuphys |= PPN(pte->page->pa) | PTEVALID | uncache;
if(o->flag&OISMEM)
usepage(pte->page, 1);
.
191c
mmuphys = PTEWRITE;
.
187c
mmuphys = PTEWRITE;
.
183c
mmuphys = PTERONLY;
.
181c
mmuphys = PTEWRITE;
.
178d
176a
pg->ref--;
.
165a
pg->ref--;
.
120a
if(!(o->flag&OISMEM))
panic("copy on ref/wr to non memory");
.
118c
if((o->flag & (OWRPERM|OSHARED))==OWRPERM && (conf.copymode || !read)
.
70c
if(pte->page == 0) {
unlock(o);
return -1;
}
uncache = PTEUNCACHED;
.
12c
ulong mmuvirt, mmuphys, uncache = 0, n;
.
## diffname port/fault.c 1991/0608
## diff -e /n/bootesdump/1991/0607/sys/src/9/port/fault.c /n/bootesdump/1991/0608/sys/src/9/port/fault.c
218a
/*
if(s - u->p->seg == LSEG)
print("%d: f %lux v %lux p %lux\n", u->p->pid, o->flag, mmuvirt, mmuphys);
*/
.
204a
}else
mmuphys |= PPN(pte->page->pa) | PTEVALID | PTEUNCACHED;
.
202,203c
/* Non memory is always uncached */
if(o->flag&OISMEM) {
mmuphys |= PPN(pte->page->pa) | PTEVALID;
.
124a
/*
* Copy on reference (conf.copymode==1) or write (conf.copymode==0)
*/
.
119,122c
if(o->flag&OSHARED) {
/* BUG: Does not cover enough flag options to shared data */
mmuphys = PTERONLY;
if(o->flag & OWRPERM)
mmuphys = PTEWRITE;
}
else if((o->flag&OWRPERM) && (conf.copymode || !read)
.
74d
12c
ulong mmuvirt, mmuphys, n;
.
## diffname port/fault.c 1991/0611
## diff -e /n/bootesdump/1991/0608/sys/src/9/port/fault.c /n/bootesdump/1991/0611/sys/src/9/port/fault.c
301a
.
229,232d
## diffname port/fault.c 1991/0619
## diff -e /n/bootesdump/1991/0611/sys/src/9/port/fault.c /n/bootesdump/1991/0619/sys/src/9/port/fault.c
283,286c
return 0;
.
281c
n -= m;
a += m;
m = BY2PG;
.
278a
if(n == m)
return 0;
.
275,276c
while(n){
if(n < m)
m = n;
t = memchr(s, c, m);
.
267c
vmemchr(void *s, int c, ulong n)
.
## diffname port/fault.c 1991/0705
## diff -e /n/bootesdump/1991/0619/sys/src/9/port/fault.c /n/bootesdump/1991/0705/sys/src/9/port/fault.c
298,300c
for(s = p->seg; s < et; s++)
if(n = *s)
if(addr >= n->base && addr < n->top) {
if(dolock == 0)
return n;
qlock(&n->lk);
if(addr >= n->base && addr < n->top)
return n;
qunlock(&n->lk);
}
.
295c
Segment **s, **et, *n;
.
292,293c
Segment*
seg(Proc *p, ulong addr, int dolock)
.
289c
/*
* All in one page
*/
return memchr(s, c, n);
.
285,287c
return vmemchr((void*)(a+m), c, n-m);
.
281,282d
275,278c
if(m < n){
t = vmemchr(s, c, m);
.
267c
vmemchr(void *s, int c, int n)
.
262a
pprint("invalid address %lux in sys call pc %lux sp %lux\n",
addr, ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp);
postnote(u->p, 1, "sys: bad address", NDebug);
error(Ebadarg);
}
.
247,261d
240,245c
if((long)len >= 0) {
for(;;) {
s = seg(u->p, addr, 0);
if(s == 0 || (write && (s->type&SG_RONLY)))
break;
if(addr+len > s->top) {
len -= s->top - addr;
addr = s->top;
continue;
}
return;
}
.
238c
Segment *s;
.
228,229c
qunlock(&s->lk);
new = newpage(0, 0, addr);
k = kmap(new);
kaddr = (char*)VA(k);
if(loadrec == 0) { /* This is demand load */
c = s->image->c;
qlock(&c->rdl);
if(waserror()) {
qunlock(&c->rdl);
kunmap(k);
putpage(new);
qlock(&s->lk);
qunlock(&s->lk);
pexit("demand load I/O error", 0);
}
ask = s->flen-soff;
if(ask > BY2PG)
ask = BY2PG;
n = (*devtab[c->type].read)(c, kaddr, ask, daddr);
if(n != ask)
error(Eioload);
if(ask < BY2PG)
memset(kaddr+ask, 0, BY2PG-ask);
if((s->type&SG_TYPE) == SG_TEXT)
memset(new->cachectl, PG_TXTFLUSH, sizeof(new->cachectl));
poperror();
kunmap(k);
qunlock(&c->rdl);
qlock(&s->lk);
if(*p == 0) { /* Someone may have got there first */
new->daddr = daddr;
cachepage(new, s->image);
*p = new;
}
else
putpage(new);
}
else { /* This is paged out */
c = swapimage.c;
qlock(&c->rdl);
if(waserror()) {
qunlock(&c->rdl);
kunmap(k);
putpage(new);
qlock(&s->lk);
qunlock(&s->lk);
pexit("page in I/O error", 0);
}
n = (*devtab[c->type].read)(c, kaddr, BY2PG, daddr);
if(n != BY2PG)
error(Eioload);
poperror();
kunmap(k);
qunlock(&c->rdl);
qlock(&s->lk);
if(pagedout(*p)) {
new->daddr = daddr;
cachepage(new, &swapimage);
putswap(*p);
*p = new;
}
else
putpage(new);
}
.
224,226c
if(new) { /* Page found from cache */
*p = new;
return;
}
.
222a
else {
daddr = swapaddr(loadrec);
new = lookpage(&swapimage, daddr);
if(new)
putswap(loadrec);
}
.
216,221c
putmmu(addr, mmuphys, *pg);
return 0;
}
void
pio(Segment *s, ulong addr, ulong soff, Page **p)
{
Page *new;
KMap *k;
Chan *c;
int n, ask;
char *kaddr;
ulong daddr;
Page *loadrec;
loadrec = *p;
if(loadrec == 0) {
daddr = s->fstart+soff; /* Compute disc address */
new = lookpage(s->image, daddr);
.
209,214c
qunlock(&s->lk);
if(new)
putpage(new);
.
207d
194,205c
mmuphys = PPN((*pg)->pa) | PTEWRITE|PTEUNCACHED|PTEVALID;
(*pg)->modref = PG_MOD|PG_REF;
break;
default:
panic("fault");
.
192a
done:
mmuphys = PPN((*pg)->pa) | PTEWRITE|PTEVALID;
(*pg)->modref = PG_MOD|PG_REF;
break;
case SG_PHYSICAL:
if(*pg == 0)
*pg = (*s->pgalloc)(addr);
.
174,191c
else {
/* put a duplicate of a text page back onto the free list */
if(lkp->image)
duppage(lkp);
unlockpage(lkp);
.
145,172c
lkp = *pg;
lockpage(lkp);
if(lkp->ref > 1) {
unlockpage(lkp);
if(new == 0 && (new = newpage(0, &s, addr)) && s == 0)
goto again;
*pg = new;
new = 0;
copypage(lkp, *pg);
putpage(lkp);
.
132,143c
if(read && conf.copymode == 0) {
mmuphys = PPN((*pg)->pa) | PTERONLY|PTEVALID;
(*pg)->modref |= PG_REF;
break;
.
119,130c
if(type == SG_SHARED)
goto done;
.
117c
/* NO break */
case SG_DATA:
if(pagedout(*pg))
pio(s, addr, soff, pg);
.
64,115c
addr &= ~(BY2PG-1);
soff = addr-s->base;
p = &s->map[soff/PTEMAPMEM];
if(*p == 0)
*p = ptealloc();
pg = &(*p)->pages[(soff&(PTEMAPMEM-1))/BY2PG];
type = s->type&SG_TYPE;
switch(type) {
case SG_TEXT:
if(pagedout(*pg)) /* No data - must demand load */
pio(s, addr, soff, pg);
mmuphys = PPN((*pg)->pa) | PTERONLY|PTEVALID;
(*pg)->modref = PG_REF;
break;
case SG_SHARED:
case SG_BSS:
case SG_STACK:
/* Zero fill on demand */
if(*pg == 0) {
if(new == 0 && (new = newpage(1, &s, addr)) && s == 0)
goto again;
*pg = new;
new = 0;
.
50,62c
if(!read && (s->type&SG_RONLY)) {
qunlock(&s->lk);
return -1;
.
23,48c
again:
s = seg(u->p, addr, 1);
if(s == 0)
.
12,20c
ulong mmuphys=0, soff;
Segment *s;
Pte **p;
Page **pg, *lkp, *new = 0;
int type;
.
8a
#define DPRINT
.
## diffname port/fault.c 1991/0706
## diff -e /n/bootesdump/1991/0705/sys/src/9/port/fault.c /n/bootesdump/1991/0706/sys/src/9/port/fault.c
209a
if(s->flushme)
memset(new->cachectl, PG_TXTFLUSH, sizeof(new->cachectl));
.
178a
if(s->flushme)
memset(new->cachectl, PG_TXTFLUSH, sizeof(new->cachectl));
.
168,170d
## diffname port/fault.c 1991/0709
## diff -e /n/bootesdump/1991/0706/sys/src/9/port/fault.c /n/bootesdump/1991/0709/sys/src/9/port/fault.c
136c
if(new) { /* Page found from cache */
.
126c
daddr = s->fstart+soff; /* Compute disc address */
.
## diffname port/fault.c 1991/0718
## diff -e /n/bootesdump/1991/0709/sys/src/9/port/fault.c /n/bootesdump/1991/0718/sys/src/9/port/fault.c
106,107c
if(new) /* A race may provide a page we never used when
putpage(new); * a fault is fixed while process slept in newpage */
.
## diffname port/fault.c 1991/0719
## diff -e /n/bootesdump/1991/0718/sys/src/9/port/fault.c /n/bootesdump/1991/0719/sys/src/9/port/fault.c
106,107c
/*
* A race may provide a page we never used when
* a fault is fixed while process slept in newpage
*/
if(new)
putpage(new);
.
## diffname port/fault.c 1991/0906
## diff -e /n/bootesdump/1991/0719/sys/src/9/port/fault.c /n/bootesdump/1991/0906/sys/src/9/port/fault.c
159,160d
155c
/* We are unable to correctly error up throught the kernel
* during faults. Therefore note delivery is postponed until
* we leave the system. Read errors cause the process to die.
*/
while(waserror()) {
if(strcmp(u->error, errstrtab[Eintr]) == 0)
continue;
.
## diffname port/fault.c 1991/0926
## diff -e /n/bootesdump/1991/0906/sys/src/9/port/fault.c /n/bootesdump/1991/0926/sys/src/9/port/fault.c
114a
u->p->psstate = sps;
.
27a
u->p->psstate = sps;
.
24a
}
.
23c
if(s == 0) {
u->p->psstate = sps;
.
19a
sps = u->p->psstate;
u->p->psstate = "Fault";
.
18a
char *sps;
.
## diffname port/fault.c 1991/0927
## diff -e /n/bootesdump/1991/0926/sys/src/9/port/fault.c /n/bootesdump/1991/0927/sys/src/9/port/fault.c
297,305c
if(n = *s){
if(addr >= n->base && addr < n->top) {
if(dolock == 0)
return n;
qlock(&n->lk);
if(addr >= n->base && addr < n->top)
return n;
qunlock(&n->lk);
}
.
## diffname port/fault.c 1991/1105
## diff -e /n/bootesdump/1991/0927/sys/src/9/port/fault.c /n/bootesdump/1991/1105/sys/src/9/port/fault.c
231a
}
void
faultexit(char *s)
{
if(u->nerrlab) {
postnote(u->p, 1, s, NDebug);
errors(s);
}
pexit(s, 0);
.
209c
faultexit("sys: page in I/O error");
.
173c
faultexit("sys: demand load I/O error");
.
163,166d
10a
void faultexit(char*);
.
## diffname port/fault.c 1991/1109
## diff -e /n/bootesdump/1991/1105/sys/src/9/port/fault.c /n/bootesdump/1991/1109/sys/src/9/port/fault.c
123,124c
if(doputmmu)
putmmu(addr, mmuphys, *pg);
.
86c
return -1;
.
63c
return -1;
.
39a
u->p->psstate = sps;
return 0;
}
int
fixfault(Segment *s, ulong addr, int read, int doputmmu)
{
ulong mmuphys=0, soff;
Page **pg, *lkp, *new = 0;
Pte **p;
int type;
.
34,37c
if(!read && (s->type&SG_RONLY)) {
qunlock(&s->lk);
u->p->psstate = sps;
return -1;
}
if(fixfault(s, addr, read, 1) == 0)
break;
.
27,32c
for(;;) {
s = seg(u->p, addr, 1);
if(s == 0) {
u->p->psstate = sps;
return -1;
}
.
18,20d
16d
## diffname port/fault.c 1991/1110
## diff -e /n/bootesdump/1991/1109/sys/src/9/port/fault.c /n/bootesdump/1991/1110/sys/src/9/port/fault.c
237,238d
204,205d
125a
if(s->flushme)
memset((*pg)->cachectl, PG_TXTFLUSH, sizeof(new->cachectl));
.
## diffname port/fault.c 1991/1113
## diff -e /n/bootesdump/1991/1110/sys/src/9/port/fault.c /n/bootesdump/1991/1113/sys/src/9/port/fault.c
83c
.
79c
/* NO break */
.
## diffname port/fault.c 1991/1122
## diff -e /n/bootesdump/1991/1113/sys/src/9/port/fault.c /n/bootesdump/1991/1122/sys/src/9/port/fault.c
59a
if(pg < etp->first)
etp->first = pg;
if(pg > etp->last)
etp->last = pg;
.
58c
etp = *p;
pg = &etp->pages[(soff&(PTEMAPMEM-1))/BY2PG];
.
49c
Pte **p, *etp;
.
## diffname port/fault.c 1991/1219
## diff -e /n/bootesdump/1991/1122/sys/src/9/port/fault.c /n/bootesdump/1991/1219/sys/src/9/port/fault.c
283,285c
pprint("invalid address 0x%lux in sys call pc=0x%lux", addr, ((Ureg*)UREGADDR)->pc);
.
## diffname port/fault.c 1992/0103
## diff -e /n/bootesdump/1991/1219/sys/src/9/port/fault.c /n/bootesdump/1992/0103/sys/src/9/port/fault.c
79c
if(*pg == 0) {
.
## diffname port/fault.c 1992/0111
## diff -e /n/bootesdump/1992/0103/sys/src/9/port/fault.c /n/bootesdump/1992/0111/sys/src/9/port/fault.c
188c
if(strcmp(u->error, Eintr) == 0)
.
7c
#include "../port/error.h"
.
## diffname port/fault.c 1992/0114
## diff -e /n/bootesdump/1992/0111/sys/src/9/port/fault.c /n/bootesdump/1992/0114/sys/src/9/port/fault.c
255c
error(s);
.
251c
faulterror(char *s)
.
227c
faulterror("sys: page in I/O error");
.
193c
faulterror("sys: demand load I/O error");
.
11c
void faulterror(char*);
.
## diffname port/fault.c 1992/0120
## diff -e /n/bootesdump/1992/0114/sys/src/9/port/fault.c /n/bootesdump/1992/0120/sys/src/9/port/fault.c
283c
pprint("invalid address 0x%lux in sys call pc=0x%lux", addr, userpc());
.
6d
## diffname port/fault.c 1992/0226
## diff -e /n/bootesdump/1992/0120/sys/src/9/port/fault.c /n/bootesdump/1992/0226/sys/src/9/port/fault.c
283d
## diffname port/fault.c 1992/0302
## diff -e /n/bootesdump/1992/0226/sys/src/9/port/fault.c /n/bootesdump/1992/0302/sys/src/9/port/fault.c
126a
.
119a
.
102c
if(new == 0)
if(new = newpage(0, &s, addr))
if(s == 0)
.
85c
case SG_DATA: /* Demand load/page in/copy on write */
.
79c
if(new == 0)
if(new = newpage(1, &s, addr))
if(s == 0)
.
77d
74c
case SG_SHARED: /* Zero fill on demand */
.
68c
if(pagedout(*pg)) /* Demand load */
.
## diffname port/fault.c 1992/0303
## diff -e /n/bootesdump/1992/0302/sys/src/9/port/fault.c /n/bootesdump/1992/0303/sys/src/9/port/fault.c
223a
print("SWAPIN\n");
.
172a
print("reclaim\n");
.
## diffname port/fault.c 1992/0304
## diff -e /n/bootesdump/1992/0303/sys/src/9/port/fault.c /n/bootesdump/1992/0304/sys/src/9/port/fault.c
225d
173d
## diffname port/fault.c 1992/0307
## diff -e /n/bootesdump/1992/0304/sys/src/9/port/fault.c /n/bootesdump/1992/0307/sys/src/9/port/fault.c
133,135d
91c
.
88c
case SG_DATA: /* Demand load/pagein/copy on write */
.
82a
.
74a
case SG_SHDATA: /* Shared data */
if(pagedout(*pg))
pio(s, addr, soff, pg);
goto done;
.
66a
default:
panic("fault");
.
## diffname port/fault.c 1992/0319
## diff -e /n/bootesdump/1992/0307/sys/src/9/port/fault.c /n/bootesdump/1992/0319/sys/src/9/port/fault.c
211a
.
68a
break;
.
## diffname port/fault.c 1992/0321
## diff -e /n/bootesdump/1992/0319/sys/src/9/port/fault.c /n/bootesdump/1992/0321/sys/src/9/port/fault.c
2c
#include "../port/lib.h"
.
## diffname port/fault.c 1992/0430
## diff -e /n/bootesdump/1992/0321/sys/src/9/port/fault.c /n/bootesdump/1992/0430/sys/src/9/port/fault.c
106c
if(read)
if(conf.copymode == 0) {
.
99c
case SG_DATA: /* Demand load/pagein/copy on write */
.
86a
case SG_SHARED: /* Zero fill on demand */
.
85d
79c
case SG_SHDATA: /* Shared data */
.
72c
if(pagedout(*pg)) /* Demand load */
.
## diffname port/fault.c 1992/0602
## diff -e /n/bootesdump/1992/0430/sys/src/9/port/fault.c /n/bootesdump/1992/0602/sys/src/9/port/fault.c
19a
spllo();
.
## diffname port/fault.c 1992/0616
## diff -e /n/bootesdump/1992/0602/sys/src/9/port/fault.c /n/bootesdump/1992/0616/sys/src/9/port/fault.c
300,301c
if(!okaddr(addr, len, write))
pexit("Suicide", 0);
.
298a
pprint("suicide: invalid address 0x%lux in sys call pc=0x%.8lux\n", addr, userpc());
return 0;
}
void
validaddr(ulong addr, ulong len, int write)
{
Segment *s;
.
296c
return 1;
.
280,281c
int
okaddr(ulong addr, ulong len, int write)
.
## diffname port/fault.c 1992/0625
## diff -e /n/bootesdump/1992/0616/sys/src/9/port/fault.c /n/bootesdump/1992/0625/sys/src/9/port/fault.c
132c
unlock(lkp);
.
117c
unlock(lkp);
.
115c
lock(lkp);
.
## diffname port/fault.c 1992/0629
## diff -e /n/bootesdump/1992/0625/sys/src/9/port/fault.c /n/bootesdump/1992/0629/sys/src/9/port/fault.c
260a
/* print("l %lux %d\n", addr, daddr);*/
.
107,108c
if(read && conf.copymode == 0) {
.
8,9d
## diffname port/fault.c 1992/0711
## diff -e /n/bootesdump/1992/0629/sys/src/9/port/fault.c /n/bootesdump/1992/0711/sys/src/9/port/fault.c
304,305d
## diffname port/fault.c 1992/0805
## diff -e /n/bootesdump/1992/0711/sys/src/9/port/fault.c /n/bootesdump/1992/0805/sys/src/9/port/fault.c
258d
150,156d
120d
115,116c
new = newpage(0, &s, addr);
.
94d
88,89c
new = newpage(1, &s, addr);
.
46c
Page **pg, *lkp, *new;
.
## diffname port/fault.c 1992/0812
## diff -e /n/bootesdump/1992/0805/sys/src/9/port/fault.c /n/bootesdump/1992/0812/sys/src/9/port/fault.c
285c
pprint("suicide: invalid address 0x%lux in sys call pc=0x%lux\n", addr, userpc());
.
## diffname port/fault.c 1992/0825
## diff -e /n/bootesdump/1992/0812/sys/src/9/port/fault.c /n/bootesdump/1992/0825/sys/src/9/port/fault.c
239d
225d
222d
210d
192d
188d
## diffname port/fault.c 1992/0911
## diff -e /n/bootesdump/1992/0825/sys/src/9/port/fault.c /n/bootesdump/1992/0911/sys/src/9/port/fault.c
186a
if(u && strcmp(u->p->text, "rc") == 0)
print("dl: %d %s %lux\n", u->p->pid, u->p->text, addr);
.
## diffname port/fault.c 1992/0912
## diff -e /n/bootesdump/1992/0911/sys/src/9/port/fault.c /n/bootesdump/1992/0912/sys/src/9/port/fault.c
187,188d
## diffname port/fault.c 1992/1001
## diff -e /n/bootesdump/1992/0912/sys/src/9/port/fault.c /n/bootesdump/1992/1001/sys/src/9/port/fault.c
249a
print("faulterror %s\n", s);
.
## diffname port/fault.c 1992/1002
## diff -e /n/bootesdump/1992/1001/sys/src/9/port/fault.c /n/bootesdump/1992/1002/sys/src/9/port/fault.c
250d
## diffname port/fault.c 1992/1209
## diff -e /n/bootesdump/1992/1002/sys/src/9/port/fault.c /n/bootesdump/1992/1209/sys/src/9/port/fault.c
217c
else { /* This is paged out */
.
209c
if(*p == 0) { /* Someone may have got there first */
.
## diffname port/fault.c 1993/0120
## diff -e /n/bootesdump/1992/1209/sys/src/9/port/fault.c /n/bootesdump/1993/0120/sys/src/9/port/fault.c
134c
*pg = (*s->pgalloc)(s, addr);
.
## diffname port/fault.c 1993/0210
## diff -e /n/bootesdump/1993/0120/sys/src/9/port/fault.c /n/bootesdump/1993/0210/sys/src/9/port/fault.c
136c
mmuphys = PPN((*pg)->pa) |PTEWRITE|PTEUNCACHED|PTEVALID;
.
133,134c
if(*pg == 0) {
fn = s->pseg->pgalloc;
if(fn)
*pg = (*fn)(s, addr);
else {
new = smalloc(sizeof(Page));
new->va = addr;
new->pa = s->pseg->pa+(addr-s->base);
new->ref = 1;
*pg = new;
}
}
.
47,48c
Page *(*fn)(Segment*, ulong);
.
44a
int type;
Pte **p, *etp;
.
## diffname port/fault.c 1993/0211
## diff -e /n/bootesdump/1993/0210/sys/src/9/port/fault.c /n/bootesdump/1993/0211/sys/src/9/port/fault.c
148a
/* print("v %lux p %lux\n", addr, mmuphys); /**/
.
## diffname port/fault.c 1993/0415
## diff -e /n/bootesdump/1993/0211/sys/src/9/port/fault.c /n/bootesdump/1993/0415/sys/src/9/port/fault.c
82a
lkp = *pg;
lock(lkp);
if(lkp->image)
duppage(lkp);
unlock(lkp);
.
## diffname port/fault.c 1993/0501
## diff -e /n/bootesdump/1993/0415/sys/src/9/port/fault.c /n/fornaxdump/1993/0501/sys/src/brazil/port/fault.c
350a
}
.
345,349c
qlock(&n->lk);
if(addr >= n->base && addr < n->top)
return n;
qunlock(&n->lk);
.
339,343c
for(s = p->seg; s < et; s++) {
n = *s;
if(n == 0)
continue;
if(addr >= n->base && addr < n->top) {
if(dolock == 0)
return n;
.
284c
s = seg(up, addr, 0);
.
267,268c
if(up->nerrlab) {
postnote(up, 1, s, NDebug);
.
206c
if(strcmp(up->error, Eintr) == 0)
.
158,159c
if(s->flushme){
for(i = 0; i < MAXMACH; i++)
(*pg)->cachectl[i] |= PG_TXTFLUSH;
}
.
83,87d
45c
int i, type;
.
38c
up->psstate = sps;
.
30c
up->psstate = sps;
.
24c
up->psstate = sps;
.
22c
s = seg(up, addr, 1);
.
16,17c
sps = up->psstate;
up->psstate = "Fault";
.
## diffname port/fault.c 1993/0727
## diff -e /n/fornaxdump/1993/0501/sys/src/brazil/port/fault.c /n/fornaxdump/1993/0727/sys/src/brazil/port/fault.c
9a
ulong
getpte(ulong addr)
{
Pte **p, *etp;
Segment *s;
Page **pg;
ulong soff;
s = seg(up, addr, 1);
if(s == 0)
return -1;
addr &= ~(BY2PG-1);
soff = addr-s->base;
p = &s->map[soff/PTEMAPMEM];
if(*p == 0) {
qunlock(&s->lk);
return -1;
}
etp = *p;
pg = &etp->pages[(soff&(PTEMAPMEM-1))/BY2PG];
if(*pg == 0) {
qunlock(&s->lk);
return -1;
}
qunlock(&s->lk);
return (*pg)->pa;
}
.
## diffname port/fault.c 1993/0728
## diff -e /n/fornaxdump/1993/0727/sys/src/brazil/port/fault.c /n/fornaxdump/1993/0728/sys/src/brazil/port/fault.c
10,38d
## diffname port/fault.c 1993/0811
## diff -e /n/fornaxdump/1993/0728/sys/src/brazil/port/fault.c /n/fornaxdump/1993/0811/sys/src/brazil/port/fault.c
155c
(*pg)->cachectl[i] = PG_TXTFLUSH;
.
153c
if(s->flushme) {
.
## diffname port/fault.c 1993/0819
## diff -e /n/fornaxdump/1993/0811/sys/src/brazil/port/fault.c /n/fornaxdump/1993/0819/sys/src/brazil/port/fault.c
105c
mmuphys = PPN((*pg)->pa) | /*PTERONLY|*/PTEVALID;
.
## diffname port/fault.c 1993/0825
## diff -e /n/fornaxdump/1993/0819/sys/src/brazil/port/fault.c /n/fornaxdump/1993/0825/sys/src/brazil/port/fault.c
198a
if(s->flushme) {
for(n = 0; n < MAXMACH; n++)
new->cachectl[n] = PG_TXTFLUSH;
}
.
153,157d
## diffname port/fault.c 1993/0829
## diff -e /n/fornaxdump/1993/0825/sys/src/brazil/port/fault.c /n/fornaxdump/1993/0829/sys/src/brazil/port/fault.c
194,198d
152a
if(s->flushme) {
for(i = 0; i < MAXMACH; i++)
(*pg)->cachectl[i] = PG_TXTFLUSH;
}
.
## diffname port/fault.c 1993/0907
## diff -e /n/fornaxdump/1993/0829/sys/src/brazil/port/fault.c /n/fornaxdump/1993/0907/sys/src/brazil/port/fault.c
82a
lkp = *pg;
lock(lkp);
if(lkp->image)
duppage(lkp);
unlock(lkp);
.
## diffname port/fault.c 1993/1201
## diff -e /n/fornaxdump/1993/0907/sys/src/brazil/port/fault.c /n/fornaxdump/1993/1201/sys/src/brazil/port/fault.c
20a
up->counter[FAULTCNTR]++;
.
## diffname port/fault.c 1993/1212
## diff -e /n/fornaxdump/1993/1201/sys/src/brazil/port/fault.c /n/fornaxdump/1993/1212/sys/src/brazil/port/fault.c
264a
if(s->flushme)
memset((*p)->cachectl, PG_TXTFLUSH, sizeof((*p)->cachectl));
.
159,163d
155d
128c
/* put a duplicate of a text page back onto
* the free list
*/
.
111c
mmuphys = PPN((*pg)->pa)|PTERONLY|PTEVALID;
.
103c
case SG_DATA: /* Demand load/pagein/copy on write */
.
92c
case SG_SHARED: /* Zero fill on demand */
.
80c
case SG_SHDATA: /* Shared data */
.
72,73c
case SG_TEXT: /* Demand load */
if(pagedout(*pg))
.
46c
int type;
.
## diffname port/fault.c 1994/0406
## diff -e /n/fornaxdump/1993/1212/sys/src/brazil/port/fault.c /n/fornaxdump/1994/0406/sys/src/brazil/port/fault.c
159d
## diffname port/fault.c 1994/0612
## diff -e /n/fornaxdump/1994/0406/sys/src/brazil/port/fault.c /n/fornaxdump/1994/0612/sys/src/brazil/port/fault.c
21d
## diffname port/fault.c 1997/0327
## diff -e /n/fornaxdump/1994/0612/sys/src/brazil/port/fault.c /n/emeliedump/1997/0327/sys/src/brazil/port/fault.c
262,271d
242c
n = devtab[c->type]->read(c, kaddr, BY2PG, daddr);
.
214c
n = devtab[c->type]->read(c, kaddr, ask, daddr);
.
41a
static void
faulterror(char *s)
{
if(up->nerrlab) {
postnote(up, 1, s, NDebug);
error(s);
}
pexit(s, 0);
}
.
8,9d
## diffname port/fault.c 1997/0516
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/port/fault.c /n/emeliedump/1997/0516/sys/src/brazil/port/fault.c
101a
if(type == SG_MAP) {
sprint(buf, "map 0x%lux %c", va, read ? 'r' : 'w');
postnote(up, 1, buf, NDebug);
}
.
100c
case SG_STACK:
case SG_MAP:
.
58a
va = addr;
.
55c
char buf[ERRLEN];
ulong va, mmuphys=0, soff;
.
## diffname port/fault.c 1997/1102
## diff -e /n/emeliedump/1997/0516/sys/src/brazil/port/fault.c /n/emeliedump/1997/1102/sys/src/brazil/port/fault.c
259c
faulterror(Eioload);
.
231c
faulterror(Eioload);
.
## diffname port/fault.c 1998/0512
## diff -e /n/emeliedump/1997/1102/sys/src/brazil/port/fault.c /n/emeliedump/1998/0512/sys/src/brazil/port/fault.c
351c
.
311c
.
304c
.
243c
else
.
214c
.
145,147c
if(lkp->image)
duppage(lkp);
.
103c
case SG_MAP:
.
95,96c
if(lkp->image)
duppage(lkp);
.
84c
.
64c
if(*p == 0)
.
## diffname port/fault.c 1999/0108
## diff -e /n/emeliedump/1998/0512/sys/src/brazil/port/fault.c /n/emeliedump/1999/0108/sys/src/brazil/port/fault.c
265,272c
new->daddr = daddr;
putswap(*p);
cachepage(new, &swapimage);
*p = new;
qunlock(&swapimage.rdlock);
.
251a
qunlock(&swapimage.rdlock);
.
248a
new2 = lookpage(&swapimage, daddr);
if(new2 != nil){
putpage(new);
putswap(*p);
*p = new2;
qunlock(&swapimage.rdlock);
return;
}
.
247a
qlock(&swapimage.rdlock); /* mutex */
.
238c
/* race, we may have multiple simultaneous reads */
if(*p == 0) {
.
200c
if(new != nil)
.
184c
Page *new, *new2;
.
142c
/* uncache the current page (since we may be changing it)
* and, if a text page, put a duplicate back onto
.
132c
if(lkp->image == &swapimage && lkp->daddr)
ref = lkp->ref + swapcount(lkp->daddr);
else
ref = lkp->ref;
if(ref > 1) {
.
94a
/* uncache the current page (since we may be changing it)
* and, if a text page, put a duplicate back onto
* the free list
*/
.
53a
int ref;
.
## diffname port/fault.c 1999/0109
## diff -e /n/emeliedump/1999/0108/sys/src/brazil/port/fault.c /n/emeliedump/1999/0109/sys/src/brazil/port/fault.c
295a
done:
.
291a
putswap(loadrec);
.
289d
268c
goto done;
.
266a
putswap(loadrec);
.
265d
261a
/*
* multiple processes could be swapping in the
* same page for the same segment
*/
if(!pagedout(*p)){
putpage(new);
qunlock(&swapimage.rdlock);
goto done;
}
/*
* multiple processes could be swapping in the
* same page for different segments
*/
.
215c
if(new != nil) { /* Page found from cache */
.
208c
else { /* from a swap image */
.
204,205c
if(loadrec == 0) { /* from a text/data image */
daddr = s->fstart+soff;
.
156,157c
if(lkp->image){
if(lkp->image == &swapimage)
uncachepage(lkp);
else
duppage(lkp);
}
.
138c
if(lkp->image == &swapimage)
.
127,129d
123c
goto notshared;
case SG_DATA:
notshared: /* Demand load/pagein/copy on write */
.
121c
if(type == SG_SHARED)
goto shared;
.
97,102c
/* uncache the current swap image (since we may be changing it) */
if(lkp->image){
if(lkp->image == &swapimage)
uncachepage(lkp);
else
duppage(lkp);
}
.
90a
shared:
.
20c
s = seg(up, addr, 1); /* leaves s->lk qlocked if seg != nil */
.
## diffname port/fault.c 1999/0110
## diff -e /n/emeliedump/1999/0109/sys/src/brazil/port/fault.c /n/emeliedump/1999/0110/sys/src/brazil/port/fault.c
314,315d
309a
/*
* race, another proc may have gotten here first
* (and the pager may have run on that page) while
* s->lk was unlocked
*/
if(*p != loadrec){
if(!pagedout(*p)){
/* another process did it for me */
putpage(new);
goto done;
} else {
print("!");
/* another process and the pager got in */
putpage(new);
goto retry;
}
}
.
296d
268,292d
257c
/*
* race, another proc may have gotten here first while
* s->lk was unlocked
*/
.
223,226d
220a
*p = new;
return;
}
.
219c
if(new != nil) {
.
214a
if(new != nil) {
*p = new;
return;
}
.
210a
retry:
.
203c
Page *new;
.
156,165c
/* save a copy of the original for the image cache */
if(lkp->image)
duppage(lkp);
.
98,104c
/* save a copy of the original for the image cache */
if(lkp->image)
duppage(lkp);
.
## diffname port/fault.c 1999/0112
## diff -e /n/emeliedump/1999/0110/sys/src/brazil/port/fault.c /n/emeliedump/1999/0112/sys/src/brazil/port/fault.c
292d
158d
137a
.
126c
case SG_SHDATA:
common: /* Demand load/pagein/copy on write */
.
123,124d
120,121c
goto common;
.
90,104d
## diffname port/fault.c 1999/0120
## diff -e /n/emeliedump/1999/0112/sys/src/brazil/port/fault.c /n/emeliedump/1999/0120/sys/src/brazil/port/fault.c
258c
faulterror(Eioload, 0);
.
253c
faulterror("sys: page in I/O error", 0);
.
226c
faulterror(Eioload, 0);
.
217c
faulterror("sys: demand load I/O error", 0);
.
137c
if(lkp->image && !swapfull())
.
127a
if(swapfull()){
qunlock(&s->lk);
pprint("swap space full\n");
faulterror(Enoswap, 1);
}
.
47c
pexit(s, freemem);
.
41c
faulterror(char *s, int freemem)
.
## diffname port/fault.c 2000/0904
## diff -e /n/emeliedump/1999/0120/sys/src/brazil/port/fault.c /n/emeliedump/2000/0904/sys/src/9/port/fault.c
348c
if((a & KZERO) != KZERO)
.
## diffname port/fault.c 2001/0314
## diff -e /n/emeliedump/2000/0904/sys/src/9/port/fault.c /n/emeliedump/2001/0314/sys/src/9/port/fault.c
149c
mmuphys = PPN((*pg)->pa) | PTEWRITE | PTEVALID;
.
113c
/*
* It's only possible to copy on write if
* we're the only user of the segment.
*/
if(read && conf.copymode == 0 && s->ref == 1) {
.
## diffname port/fault.c 2001/0424
## diff -e /n/emeliedump/2001/0314/sys/src/9/port/fault.c /n/emeliedump/2001/0424/sys/src/9/port/fault.c
95,98d
93d
61d
56,57c
ulong mmuphys=0, soff;
.
## diffname port/fault.c 2001/0425
## diff -e /n/emeliedump/2001/0424/sys/src/9/port/fault.c /n/emeliedump/2001/0425/sys/src/9/port/fault.c
101d
## diffname port/fault.c 2001/0819
## diff -e /n/emeliedump/2001/0425/sys/src/9/port/fault.c /n/emeliedump/2001/0819/sys/src/9/port/fault.c
261c
faulterror(Eioload, c, 0);
.
256c
faulterror("sys: page in I/O error", c, 0);
.
229c
faulterror(Eioload, c, 0);
.
220c
faulterror("sys: demand load I/O error", c, 0);
.
128c
faulterror(Enoswap, nil, 1);
.
42a
char buf[ERRMAX];
if(c && c->name){
snprint(buf, sizeof buf, "%s accessing %s: %s", s, c->name->s, up->error);
s = buf;
}
.
41c
faulterror(char *s, Chan *c, int freemem)
.
## diffname port/fault.c 2001/0924
## diff -e /n/emeliedump/2001/0819/sys/src/9/port/fault.c /n/emeliedump/2001/0924/sys/src/9/port/fault.c
222c
if(strcmp(up->errstr, Eintr) == 0)
.
46c
snprint(buf, sizeof buf, "%s accessing %s: %s", s, c->name->s, up->errstr);
.
## diffname port/fault.c 2002/0426
## diff -e /n/emeliedump/2001/0924/sys/src/9/port/fault.c /n/emeliedump/2002/0426/sys/src/9/port/fault.c
352c
s = (void*)(a+m);
n -= m;
goto loop;
.
347c
t = memchr(s, c, m);
.
343a
loop:
.
## diffname port/fault.c 2002/0802
## diff -e /n/emeliedump/2002/0426/sys/src/9/port/fault.c /n/emeliedump/2002/0802/sys/src/9/port/fault.c
357,360c
/* fits in one page */
return memchr((void*)a, c, n);
.
355c
if((a & KZERO) != KZERO)
validaddr(a, 1, 0);
.
351,353c
a += m;
.
346,348c
while(PGROUND(a) != PGROUND(a+n-1)){
/* spans pages; handle this page */
m = BY2PG - (a & (BY2PG-1));
t = memchr((void*)a, c, m);
.
344d
342a
void *t;
.
341d
|