Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/port/fault.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## 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

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.