plan 9 kernel history: overview | file list | diff list

1992/1001/port/fault.c (diff list | history)

1990/0227/sys/src/9/port/fault.c:138,1431990/0312/sys/src/9/port/fault.c:138,144 (short | long)
1990/0227    
			 * Add to mod list 
			 */ 
			pte = newmod(); 
1990/0312    
o->nmod++; 
1990/0227    
			pte->proc = u->p; 
			pte->page = opte->page; 
			pte->page->ref++; 
1990/0227/sys/src/9/port/fault.c:210,2181990/0312/sys/src/9/port/fault.c:211,220
1990/0227    
	Seg *s; 
 
	if((long)len < 0) 
		panic("validaddr len %lux\n", len); 
1990/0312    
		goto Err; 
1990/0227    
	s = seg(u->p, addr); 
	if(s==0 || addr+len>s->maxva || (write && (s->o->flag&OWRPERM)==0)){ 
1990/0312    
    Err: 
1990/0227    
		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); 
1990/0312/sys/src/9/port/fault.c:208,2231990/0617/sys/src/9/port/fault.c:208,231 (short | long)
1990/0227    
void 
validaddr(ulong addr, ulong len, int write) 
{ 
	Seg *s; 
1990/0617    
	Seg *s, *ns; 
1990/0227    
 
	if((long)len < 0) 
1990/0312    
		goto Err; 
1990/0227    
	s = seg(u->p, addr); 
	if(s==0 || addr+len>s->maxva || (write && (s->o->flag&OWRPERM)==0)){ 
1990/0617    
	if((long)len < 0){ 
1990/0312    
    Err: 
1990/0227    
		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); 
1990/0617    
	} 
    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; 
1990/0227    
	} 
} 
 
1990/0617/sys/src/9/port/fault.c:43,511990/0802/sys/src/9/port/fault.c:43,57 (short | long)
1990/0227    
		/* grow stack */ 
		o = s->o; 
		n = o->npte; 
1990/0802    
		lock(o); 
		if(waserror()){ 
			unlock(o); 
			pprint("can't allocate stack page\n"); 
			goto cant; 
		} 
1990/0227    
		growpte(o, (s->maxva-addr)>>PGSHIFT); 
1990/0802    
		poperror(); 
1990/0227    
		/* 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); 
1990/0802/sys/src/9/port/fault.c:43,511990/0814/sys/src/9/port/fault.c:43,49 (short | long)
1990/0227    
		/* grow stack */ 
		o = s->o; 
		n = o->npte; 
1990/0802    
		lock(o); 
		if(waserror()){ 
			unlock(o); 
			pprint("can't allocate stack page\n"); 
			goto cant; 
		} 
1990/0802/sys/src/9/port/fault.c:52,571990/0814/sys/src/9/port/fault.c:50,56
1990/0227    
		growpte(o, (s->maxva-addr)>>PGSHIFT); 
1990/0802    
		poperror(); 
1990/0227    
		/* stacks grown down, sigh */ 
1990/0814    
		lock(o); 
1990/0227    
		memcpy(o->pte+(o->npte-n), o->pte, n*sizeof(PTE)); 
		memset(o->pte, 0, (o->npte-n)*sizeof(PTE)); 
		unlock(o); 
1990/0814/sys/src/9/port/fault.c:38,441990/0821/sys/src/9/port/fault.c:38,44 (short | long)
1990/0227    
			panic("fault"); 
		} 
		s = &u->p->seg[SSEG]; 
		if(s->o==0 || addr<s->maxva-4*1024*1024 || addr>=s->maxva) 
1990/0821    
		if(s->o==0 || addr<s->maxva-USTACKSIZE || addr>=s->maxva) 
1990/0227    
			goto cant; 
		/* grow stack */ 
		o = s->o; 
1990/0814/sys/src/9/port/fault.c:223,2301990/0821/sys/src/9/port/fault.c:223,233
1990/0617    
	} 
    Again: 
	s = seg(u->p, addr); 
	if(s==0) 
		goto Err; 
1990/0821    
	if(s==0){ 
		s = &u->p->seg[SSEG]; 
		if(s->o==0 || addr<s->maxva-USTACKSIZE || addr>=s->maxva) 
			goto Err; 
	} 
1990/0617    
	if(write && (s->o->flag&OWRPERM)==0) 
		goto Err; 
	if(addr+len > s->maxva){ 
1990/0821/sys/src/9/port/fault.c:142,1481990/1013/sys/src/9/port/fault.c:142,148 (short | long)
1990/0227    
			/* 
			 * Add to mod list 
			 */ 
			pte = newmod(); 
1990/1013    
			pte = newmod(o); 
1990/0312    
o->nmod++; 
1990/0227    
			pte->proc = u->p; 
			pte->page = opte->page; 
1990/1013/sys/src/9/port/fault.c:98,1031990/1110/sys/src/9/port/fault.c:98,105 (short | long)
1990/0227    
				qunlock(o->chan); 
				pg->o = 0; 
				pg->ref--; 
1990/1110    
				if(user) 
					pexit("Interrupt", 0); 
1990/0227    
				goto cant; 
			} 
			o->chan->offset = (addr-o->va) + o->minca; 
1990/1013/sys/src/9/port/fault.c:218,2241990/1110/sys/src/9/port/fault.c:220,226
1990/0617    
	if((long)len < 0){ 
1990/0312    
    Err: 
1990/0227    
		pprint("invalid address in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); 
		postnote(u->p, 1, "bad address", NDebug); 
1990/1110    
		postnote(u->p, 1, "sys: bad address", NDebug); 
1990/0227    
		error(0, Ebadarg); 
1990/0617    
	} 
    Again: 
1990/1013/sys/src/9/port/fault.c:241,2471990/1110/sys/src/9/port/fault.c:243,249
1990/0227    
evenaddr(ulong addr) 
{ 
	if(addr & 3){ 
		postnote(u->p, 1, "odd address", NDebug); 
1990/1110    
		postnote(u->p, 1, "sys: odd address", NDebug); 
1990/0227    
		error(0, Ebadarg); 
	} 
} 
1990/1110/sys/src/9/port/fault.c:98,1061990/1113/sys/src/9/port/fault.c:98,104 (short | long)
1990/0227    
				qunlock(o->chan); 
				pg->o = 0; 
				pg->ref--; 
1990/1110    
				if(user) 
					pexit("Interrupt", 0); 
1990/0227    
				goto cant; 
1990/1113    
				pexit("load i/o error", 0); 
1990/0227    
			} 
			o->chan->offset = (addr-o->va) + o->minca; 
			l = (char*)(pg->pa|KZERO); 
1990/1113/sys/src/9/port/fault.c:94,1001990/11211/sys/src/9/port/fault.c:94,100 (short | long)
1990/0227    
			pg = newpage(1, o, addr); 
			qlock(o->chan); 
			if(waserror()){ 
				print("demand load i/o error %d\n", u->error.code); 
1990/11211    
				print("demand load i/o error %s\n", u->error); 
1990/0227    
				qunlock(o->chan); 
				pg->o = 0; 
				pg->ref--; 
1990/1113/sys/src/9/port/fault.c:103,1091990/11211/sys/src/9/port/fault.c:103,109
1990/0227    
			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); 
1990/11211    
				error(Eioload); 
1990/0227    
			qunlock(o->chan); 
			poperror(); 
			/* BUG: if was first page of bss, move to data */ 
1990/1113/sys/src/9/port/fault.c:143,1491990/11211/sys/src/9/port/fault.c:143,148
1990/0227    
			 * Add to mod list 
			 */ 
1990/1013    
			pte = newmod(o); 
1990/0312    
o->nmod++; 
1990/0227    
			pte->proc = u->p; 
			pte->page = opte->page; 
			pte->page->ref++; 
1990/1113/sys/src/9/port/fault.c:219,2251990/11211/sys/src/9/port/fault.c:218,224
1990/0312    
    Err: 
1990/0227    
		pprint("invalid address in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); 
1990/1110    
		postnote(u->p, 1, "sys: bad address", NDebug); 
1990/0227    
		error(0, Ebadarg); 
1990/11211    
		error(Ebadarg); 
1990/0617    
	} 
    Again: 
	s = seg(u->p, addr); 
1990/1113/sys/src/9/port/fault.c:242,2481990/11211/sys/src/9/port/fault.c:241,247
1990/0227    
{ 
	if(addr & 3){ 
1990/1110    
		postnote(u->p, 1, "sys: odd address", NDebug); 
1990/0227    
		error(0, Ebadarg); 
1990/11211    
		error(Ebadarg); 
1990/0227    
	} 
} 
 
1990/11211/sys/src/9/port/fault.c:94,1001990/1202/sys/src/9/port/fault.c:94,99 (short | long)
1990/0227    
			pg = newpage(1, o, addr); 
			qlock(o->chan); 
			if(waserror()){ 
1990/11211    
				print("demand load i/o error %s\n", u->error); 
1990/0227    
				qunlock(o->chan); 
				pg->o = 0; 
				pg->ref--; 
1990/1202/sys/src/9/port/fault.c:6,161990/1212/sys/src/9/port/fault.c:6,15 (short | long)
Created.
rsc Fri Mar 4 12:44:25 2005
1990/0227    
#include	"ureg.h" 
#include	"errno.h" 
 
void 
fault(Ureg *ur, int user, int code) 
1990/1212    
int 
fault(ulong addr, int read) 
1990/0227    
{ 
	ulong addr, mmuvirt, mmuphys, n; 
	extern char *excname[]; 
1990/1212    
	ulong mmuvirt, mmuphys, n; 
1990/0227    
	Seg *s; 
	PTE *opte, *pte, *npte; 
	Orig *o; 
1990/1202/sys/src/9/port/fault.c:18,511990/1212/sys/src/9/port/fault.c:17,37
1990/0227    
	Page *pg; 
	int zeroed = 0, head = 1; 
	int i; 
1990/1212    
	KMap *k, *k1; 
1990/0227    
 
	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"); 
		} 
1990/1212    
		if(addr>USTKTOP) 
			return -1; 
1990/0227    
		s = &u->p->seg[SSEG]; 
1990/0821    
		if(s->o==0 || addr<s->maxva-USTACKSIZE || addr>=s->maxva) 
1990/0227    
			goto cant; 
1990/1212    
			return -1; 
1990/0227    
		/* grow stack */ 
		o = s->o; 
		n = o->npte; 
1990/0802    
		if(waserror()){ 
			pprint("can't allocate stack page\n"); 
			goto cant; 
1990/1212    
			return -1; 
1990/0802    
		} 
1990/0227    
		growpte(o, (s->maxva-addr)>>PGSHIFT); 
1990/0802    
		poperror(); 
1990/1202/sys/src/9/port/fault.c:58,651990/1212/sys/src/9/port/fault.c:44,51
1990/0227    
		o->va = addr; 
	}else 
		o = s->o; 
	if((code==CTLBM || code==CTLBS) && (o->flag&OWRPERM)==0) 
		goto cant; 
1990/1212    
	if(!read && (o->flag&OWRPERM)==0) 
		return -1; 
1990/0227    
	lock(o); 
	opte = &o->pte[(addr-o->va)>>PGSHIFT]; 
	pte = opte; 
1990/1202/sys/src/9/port/fault.c:92,991990/1212/sys/src/9/port/fault.c:78,87
1990/0227    
			if(n > BY2PG) 
				n = BY2PG; 
			pg = newpage(1, o, addr); 
1990/1212    
			k = kmap(pg); 
1990/0227    
			qlock(o->chan); 
			if(waserror()){ 
1990/1212    
				kunmap(k); 
1990/0227    
				qunlock(o->chan); 
				pg->o = 0; 
				pg->ref--; 
1990/1202/sys/src/9/port/fault.c:100,1141990/1212/sys/src/9/port/fault.c:88,102
1990/1113    
				pexit("load i/o error", 0); 
1990/0227    
			} 
			o->chan->offset = (addr-o->va) + o->minca; 
			l = (char*)(pg->pa|KZERO); 
1990/1212    
			l = (char*)VA(k); 
1990/0227    
			if((*devtab[o->chan->type].read)(o->chan, l, n) != n) 
1990/11211    
				error(Eioload); 
1990/0227    
			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); 
1990/1212    
			kunmap(k); 
			poperror(); 
1990/0227    
			opte = &o->pte[(addr-s->minva)>>PGSHIFT];	/* could move */ 
			pte = opte; 
			if(pte->page == 0){ 
1990/1202/sys/src/9/port/fault.c:121,1291990/1212/sys/src/9/port/fault.c:109,117
1990/0227    
		} 
	} 
	/* 
	 * Copy on reference 
1990/1212    
	 * Copy on reference (conf.copymode==1) or write (conf.copymode==0) 
1990/0227    
	 */ 
	if((o->flag & OWRPERM) 
1990/1212    
	if((o->flag & OWRPERM) && (conf.copymode || !read) 
1990/0227    
	&& ((head && ((o->flag&OPURE) || o->nproc>1)) 
	    || (!head && pte->page->ref>1))){ 
 
1990/1202/sys/src/9/port/fault.c:173,1791990/1212/sys/src/9/port/fault.c:161,171
1990/0227    
			opte->page = 0; 
		}else{		/* copy page */ 
			pte->page = newpage(1, o, addr); 
			memcpy((void*)(pte->page->pa|KZERO), (void*)(pg->pa|KZERO), BY2PG); 
1990/1212    
			k = kmap(pte->page); 
			k1 = kmap(pg); 
			memcpy((void*)VA(k), (void*)VA(k1), BY2PG); 
			kunmap(k); 
			kunmap(k1); 
1990/0227    
			if(pg->ref <= 1) 
				panic("pg->ref <= 1"); 
			pg->ref--; 
1990/1202/sys/src/9/port/fault.c:181,1871990/1212/sys/src/9/port/fault.c:173,179
1990/0227    
    easy: 
		mmuphys = PTEWRITE; 
	}else{ 
		mmuphys = 0; 
1990/1212    
		mmuphys = PTERONLY; 
1990/0227    
		if(o->flag & OWRPERM) 
			if(o->flag & OPURE){ 
				if(!head && pte->page->ref==1) 
1990/1202/sys/src/9/port/fault.c:192,1981990/1212/sys/src/9/port/fault.c:184,190
1990/0227    
					mmuphys = PTEWRITE; 
	} 
	mmuvirt = addr; 
	mmuphys |= pte->page->pa | PTEVALID; 
1990/1212    
	mmuphys |= PPN(pte->page->pa) | PTEVALID; 
1990/0227    
	usepage(pte->page, 1); 
	if(pte->page->va != addr) 
		panic("wrong addr in tail %lux %lux", pte->page->va, addr); 
1990/1202/sys/src/9/port/fault.c:203,2081990/1212/sys/src/9/port/fault.c:195,201
1990/0227    
	} 
	unlock(o); 
	putmmu(mmuvirt, mmuphys); 
1990/1212    
	return 0; 
1990/0227    
} 
 
/* 
1990/1202/sys/src/9/port/fault.c:232,2461990/1212/sys/src/9/port/fault.c:225,230
1990/0617    
		len -= s->maxva - addr; 
		addr = s->maxva; 
		goto Again; 
1990/0227    
	} 
} 
                 
void 
evenaddr(ulong addr) 
{ 
	if(addr & 3){ 
1990/1110    
		postnote(u->p, 1, "sys: odd address", NDebug); 
1990/11211    
		error(Ebadarg); 
1990/0227    
	} 
} 
 
1990/1212/sys/src/9/port/fault.c:21,271991/0110/sys/src/9/port/fault.c:21,27 (short | long)
1990/0227    
 
	s = seg(u->p, addr); 
	if(s == 0){ 
1990/1212    
		if(addr>USTKTOP) 
1991/0110    
		if(addr > USTKTOP) 
1990/1212    
			return -1; 
1990/0227    
		s = &u->p->seg[SSEG]; 
1990/0821    
		if(s->o==0 || addr<s->maxva-USTACKSIZE || addr>=s->maxva) 
1991/0110/sys/src/9/port/fault.c:208,2141991/0115/sys/src/9/port/fault.c:208,214 (short | long)
1990/0227    
 
1990/0617    
	if((long)len < 0){ 
1990/0312    
    Err: 
1990/0227    
		pprint("invalid address in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); 
1991/0115    
		pprint("invalid address %lux in sys call pc %lux sp %lux\n", addr, ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); 
1990/1110    
		postnote(u->p, 1, "sys: bad address", NDebug); 
1990/11211    
		error(Ebadarg); 
1990/0617    
	} 
1991/0115/sys/src/9/port/fault.c:91,961991/0312/sys/src/9/port/fault.c:91,97 (short | long)
1990/1212    
			l = (char*)VA(k); 
1990/0227    
			if((*devtab[o->chan->type].read)(o->chan, l, n) != n) 
1990/11211    
				error(Eioload); 
1991/0312    
			flushpage(pg->pa); 
1990/0227    
			qunlock(o->chan); 
			if(n<BY2PG) 
				memset(l+n, 0, BY2PG-n); 
1991/0312/sys/src/9/port/fault.c:37,431991/0318/sys/src/9/port/fault.c:37,43 (short | long)
1990/0802    
		poperror(); 
1990/0227    
		/* stacks grown down, sigh */ 
1990/0814    
		lock(o); 
1990/0227    
		memcpy(o->pte+(o->npte-n), o->pte, n*sizeof(PTE)); 
1991/0318    
		memmove(o->pte+(o->npte-n), o->pte, n*sizeof(PTE)); 
1990/0227    
		memset(o->pte, 0, (o->npte-n)*sizeof(PTE)); 
		unlock(o); 
		s->minva = addr; 
1991/0312/sys/src/9/port/fault.c:164,1701991/0318/sys/src/9/port/fault.c:164,170
1990/0227    
			pte->page = newpage(1, o, addr); 
1990/1212    
			k = kmap(pte->page); 
			k1 = kmap(pg); 
			memcpy((void*)VA(k), (void*)VA(k1), BY2PG); 
1991/0318    
			memmove((void*)VA(k), (void*)VA(k1), BY2PG); 
1990/1212    
			kunmap(k); 
			kunmap(k1); 
1990/0227    
			if(pg->ref <= 1) 
1991/0318/sys/src/9/port/fault.c:79,981991/0411/sys/src/9/port/fault.c:79,97 (short | long)
1990/0227    
				n = BY2PG; 
			pg = newpage(1, o, addr); 
1990/1212    
			k = kmap(pg); 
1990/0227    
			qlock(o->chan); 
1991/0411    
			qlock(&o->chan->rdl); 
1990/0227    
			if(waserror()){ 
1990/1212    
				kunmap(k); 
1990/0227    
				qunlock(o->chan); 
1991/0411    
				qunlock(&o->chan->rdl); 
1990/0227    
				pg->o = 0; 
				pg->ref--; 
1990/1113    
				pexit("load i/o error", 0); 
1990/0227    
			} 
			o->chan->offset = (addr-o->va) + o->minca; 
1990/1212    
			l = (char*)VA(k); 
1990/0227    
			if((*devtab[o->chan->type].read)(o->chan, l, n) != n) 
1991/0411    
			if((*devtab[o->chan->type].read)(o->chan, l, n, (addr-o->va) + o->minca) != n) 
1990/11211    
				error(Eioload); 
1991/0312    
			flushpage(pg->pa); 
1990/0227    
			qunlock(o->chan); 
1991/0411    
			qunlock(&o->chan->rdl); 
1990/0227    
			if(n<BY2PG) 
				memset(l+n, 0, BY2PG-n); 
			lock(o); 
1991/0411/sys/src/9/port/fault.c:16,221991/0425/sys/src/9/port/fault.c:16,22 (short | long)
1990/0227    
	char *l; 
	Page *pg; 
	int zeroed = 0, head = 1; 
	int i; 
1991/0425    
	int i, touched = 0; 
1990/1212    
	KMap *k, *k1; 
1990/0227    
 
	s = seg(u->p, addr); 
1991/0411/sys/src/9/port/fault.c:61,661991/0425/sys/src/9/port/fault.c:61,67
1990/0227    
			pte = opte; 
	} 
	if(pte->page == 0){ 
1991/0425    
		touched = 1; 
1990/0227    
		if(o->chan==0 || addr>(o->va+(o->maxca-o->minca))){ 
			/* 
			 * Zero fill page.  If we are really doing a copy-on-write 
1991/0411/sys/src/9/port/fault.c:114,1201991/0425/sys/src/9/port/fault.c:115,121
1990/1212    
	if((o->flag & OWRPERM) && (conf.copymode || !read) 
1990/0227    
	&& ((head && ((o->flag&OPURE) || o->nproc>1)) 
	    || (!head && pte->page->ref>1))){ 
                 
1991/0425    
		touched = 1; 
1990/0227    
		/* 
		 * Look for the easy way out: are we the last non-modified? 
		 */ 
1991/0411/sys/src/9/port/fault.c:194,1991991/0425/sys/src/9/port/fault.c:195,202
1990/0227    
		panic("addr %lux seg %d wrong proc in tail", addr, s-u->p->seg); 
	} 
	unlock(o); 
1991/0425    
	if(touched == 0) 
		m->tlbfault++; 
1990/0227    
	putmmu(mmuvirt, mmuphys); 
1990/1212    
	return 0; 
1990/0227    
} 
1991/0425/sys/src/9/port/fault.c:19,241991/0427/sys/src/9/port/fault.c:19,25 (short | long)
1991/0425    
	int i, touched = 0; 
1990/1212    
	KMap *k, *k1; 
1990/0227    
 
1991/0427    
	m->pfault++; 
1990/0227    
	s = seg(u->p, addr); 
	if(s == 0){ 
1991/0110    
		if(addr > USTKTOP) 
1991/0427/sys/src/9/port/fault.c:87,931991/0501/sys/src/9/port/fault.c:87,93 (short | long)
1991/0411    
				qunlock(&o->chan->rdl); 
1990/0227    
				pg->o = 0; 
				pg->ref--; 
1990/1113    
				pexit("load i/o error", 0); 
1991/0501    
				pexit("demand load i/o error", 0); 
1990/0227    
			} 
1990/1212    
			l = (char*)VA(k); 
1991/0411    
			if((*devtab[o->chan->type].read)(o->chan, l, n, (addr-o->va) + o->minca) != n) 
1991/0501/sys/src/9/port/fault.c:25,311991/0605/sys/src/9/port/fault.c:25,31 (short | long)
1991/0110    
		if(addr > USTKTOP) 
1990/1212    
			return -1; 
1990/0227    
		s = &u->p->seg[SSEG]; 
1990/0821    
		if(s->o==0 || addr<s->maxva-USTACKSIZE || addr>=s->maxva) 
1991/0605    
		if(s->o==0 || addr<s->maxva-USTKSIZE || addr>=s->maxva) 
1990/1212    
			return -1; 
1990/0227    
		/* grow stack */ 
		o = s->o; 
1991/0501/sys/src/9/port/fault.c:220,2261991/0605/sys/src/9/port/fault.c:220,226
1990/0617    
	s = seg(u->p, addr); 
1990/0821    
	if(s==0){ 
		s = &u->p->seg[SSEG]; 
		if(s->o==0 || addr<s->maxva-USTACKSIZE || addr>=s->maxva) 
1991/0605    
		if(s->o==0 || addr<s->maxva-USTKSIZE || addr>=s->maxva) 
1990/0821    
			goto Err; 
	} 
1990/0617    
	if(write && (s->o->flag&OWRPERM)==0) 
1991/0605/sys/src/9/port/fault.c:9,151991/0606/sys/src/9/port/fault.c:9,15 (short | long)
1990/1212    
int 
fault(ulong addr, int read) 
1990/0227    
{ 
1990/1212    
	ulong mmuvirt, mmuphys, n; 
1991/0606    
	ulong mmuvirt, mmuphys = 0, n; 
1990/0227    
	Seg *s; 
	PTE *opte, *pte, *npte; 
	Orig *o; 
1991/0605/sys/src/9/port/fault.c:64,761991/0606/sys/src/9/port/fault.c:64,78
1990/0227    
	if(pte->page == 0){ 
1991/0425    
		touched = 1; 
1990/0227    
		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++; 
1991/0606    
			/* 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); 
1990/0227    
			zeroed = 1; 
1991/0606    
			o->npage++; 
1990/0227    
		}else{ 
			/* 
			 * Demand load.  Release o because it could take a while. 
1991/0605/sys/src/9/port/fault.c:157,1641991/0606/sys/src/9/port/fault.c:159,168
1990/0227    
			head = 0; 
		} 
		pg = pte->page; 
		if(zeroed){	/* move page */ 
			pg->ref--; 
1991/0606    
		/* when creating pages in the bss which are zfod we create a double 
		 * increment on the mod list which must be removed 
		 */ 
		if(zeroed){ 
1990/0227    
			o->npage--; 
			opte->page = 0; 
		}else{		/* copy page */ 
1991/0605/sys/src/9/port/fault.c:170,1891991/0606/sys/src/9/port/fault.c:174,194
1990/1212    
			kunmap(k1); 
1990/0227    
			if(pg->ref <= 1) 
				panic("pg->ref <= 1"); 
			pg->ref--; 
		} 
1991/0606    
		pg->ref--; 
 
1990/0227    
    easy: 
		mmuphys = PTEWRITE; 
1991/0606    
		mmuphys |= PTEWRITE; 
1990/0227    
	}else{ 
1990/1212    
		mmuphys = PTERONLY; 
1991/0606    
		mmuphys |= PTERONLY; 
1990/0227    
		if(o->flag & OWRPERM) 
			if(o->flag & OPURE){ 
				if(!head && pte->page->ref==1) 
					mmuphys = PTEWRITE; 
1991/0606    
					mmuphys |= PTEWRITE; 
1990/0227    
			}else 
				if((head && o->nproc==1) 
	  			  || (!head && pte->page->ref==1)) 
					mmuphys = PTEWRITE; 
1991/0606    
					mmuphys |= PTEWRITE; 
1990/0227    
	} 
	mmuvirt = addr; 
1990/1212    
	mmuphys |= PPN(pte->page->pa) | PTEVALID; 
1991/0605/sys/src/9/port/fault.c:212,2181991/0606/sys/src/9/port/fault.c:217,224
1990/0227    
 
1990/0617    
	if((long)len < 0){ 
1990/0312    
    Err: 
1991/0115    
		pprint("invalid address %lux in sys call pc %lux sp %lux\n", addr, ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); 
1991/0606    
		pprint("invalid address %lux in sys call pc %lux sp %lux\n",  
			addr, ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); 
1990/1110    
		postnote(u->p, 1, "sys: bad address", NDebug); 
1990/11211    
		error(Ebadarg); 
1990/0617    
	} 
1991/0605/sys/src/9/port/fault.c:261,2701991/0606/sys/src/9/port/fault.c:267,276
1990/0227    
Seg* 
seg(Proc *p, ulong addr) 
{ 
	int i; 
	Seg *s; 
1991/0606    
	Seg *s, *et; 
1990/0227    
 
	for(i=0,s=p->seg; i<NSEG; i++,s++) 
1991/0606    
	et = &p->seg[NSEG]; 
	for(s=p->seg; s < et; s++) 
1990/0227    
		if(s->o && s->minva<=addr && addr<s->maxva) 
			return s; 
	return 0; 
1991/0606/sys/src/9/port/fault.c:9,151991/0607/sys/src/9/port/fault.c:9,15 (short | long)
1990/1212    
int 
fault(ulong addr, int read) 
1990/0227    
{ 
1991/0606    
	ulong mmuvirt, mmuphys = 0, n; 
1991/0607    
	ulong mmuvirt, mmuphys, uncache = 0, n; 
1990/0227    
	Seg *s; 
	PTE *opte, *pte, *npte; 
	Orig *o; 
1991/0606/sys/src/9/port/fault.c:67,731991/0607/sys/src/9/port/fault.c:67,77
1991/0606    
			/* Make a new bss or lock segment page */ 
			if(s - u->p->seg == LSEG) { 
				pte->page = lkpage(o, addr); 
				mmuphys = PTEUNCACHE; 
1991/0607    
				if(pte->page == 0) { 
					unlock(o); 
					return -1; 
				} 
				uncache = PTEUNCACHED; 
1991/0606    
			} 
			else 
				pte->page = newpage(0, o, addr); 
1991/0606/sys/src/9/port/fault.c:115,1231991/0607/sys/src/9/port/fault.c:119,130
1990/0227    
	/* 
1990/1212    
	 * Copy on reference (conf.copymode==1) or write (conf.copymode==0) 
1990/0227    
	 */ 
1990/1212    
	if((o->flag & OWRPERM) && (conf.copymode || !read) 
1991/0607    
	if((o->flag & (OWRPERM|OSHARED))==OWRPERM && (conf.copymode || !read) 
1990/0227    
	&& ((head && ((o->flag&OPURE) || o->nproc>1)) 
	    || (!head && pte->page->ref>1))){ 
1991/0607    
 
		if(!(o->flag&OISMEM)) 
			panic("copy on ref/wr to non memory"); 
1991/0425    
		touched = 1; 
1990/0227    
		/* 
		 * Look for the easy way out: are we the last non-modified? 
1991/0606/sys/src/9/port/fault.c:163,1681991/0607/sys/src/9/port/fault.c:170,176
1991/0606    
		 * increment on the mod list which must be removed 
		 */ 
		if(zeroed){ 
1991/0607    
			pg->ref--; 
1990/0227    
			o->npage--; 
			opte->page = 0; 
		}else{		/* copy page */ 
1991/0606/sys/src/9/port/fault.c:174,1981991/0607/sys/src/9/port/fault.c:182,208
1990/1212    
			kunmap(k1); 
1990/0227    
			if(pg->ref <= 1) 
				panic("pg->ref <= 1"); 
1991/0607    
			pg->ref--; 
1990/0227    
		} 
1991/0606    
		pg->ref--; 
 
1990/0227    
    easy: 
1991/0606    
		mmuphys |= PTEWRITE; 
1991/0607    
		mmuphys = PTEWRITE; 
1990/0227    
	}else{ 
1991/0606    
		mmuphys |= PTERONLY; 
1991/0607    
		mmuphys = PTERONLY; 
1990/0227    
		if(o->flag & OWRPERM) 
			if(o->flag & OPURE){ 
				if(!head && pte->page->ref==1) 
1991/0606    
					mmuphys |= PTEWRITE; 
1991/0607    
					mmuphys = PTEWRITE; 
1990/0227    
			}else 
				if((head && o->nproc==1) 
	  			  || (!head && pte->page->ref==1)) 
1991/0606    
					mmuphys |= PTEWRITE; 
1991/0607    
					mmuphys = PTEWRITE; 
1990/0227    
	} 
	mmuvirt = addr; 
1990/1212    
	mmuphys |= PPN(pte->page->pa) | PTEVALID; 
1990/0227    
	usepage(pte->page, 1); 
1991/0607    
	mmuphys |= PPN(pte->page->pa) | PTEVALID | uncache; 
	if(o->flag&OISMEM) 
		usepage(pte->page, 1); 
 
1990/0227    
	if(pte->page->va != addr) 
		panic("wrong addr in tail %lux %lux", pte->page->va, addr); 
	if(pte->proc && pte->proc != u->p){ 
1991/0606/sys/src/9/port/fault.c:200,2081991/0607/sys/src/9/port/fault.c:210,220
1990/0227    
		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); 
	} 
1991/0607    
 
1990/0227    
	unlock(o); 
1991/0425    
	if(touched == 0) 
		m->tlbfault++; 
1991/0607    
 
1990/0227    
	putmmu(mmuvirt, mmuphys); 
1990/1212    
	return 0; 
1990/0227    
} 
1991/0607/sys/src/9/port/fault.c:9,151991/0608/sys/src/9/port/fault.c:9,15 (short | long)
1990/1212    
int 
fault(ulong addr, int read) 
1990/0227    
{ 
1991/0607    
	ulong mmuvirt, mmuphys, uncache = 0, n; 
1991/0608    
	ulong mmuvirt, mmuphys, n; 
1990/0227    
	Seg *s; 
	PTE *opte, *pte, *npte; 
	Orig *o; 
1991/0607/sys/src/9/port/fault.c:71,771991/0608/sys/src/9/port/fault.c:71,76
1991/0607    
					unlock(o); 
					return -1; 
				} 
				uncache = PTEUNCACHED; 
1991/0606    
			} 
			else 
				pte->page = newpage(0, o, addr); 
1991/0607/sys/src/9/port/fault.c:116,1271991/0608/sys/src/9/port/fault.c:115,133
1990/0227    
			} 
		} 
	} 
	/* 
1990/1212    
	 * Copy on reference (conf.copymode==1) or write (conf.copymode==0) 
1990/0227    
	 */ 
1991/0607    
	if((o->flag & (OWRPERM|OSHARED))==OWRPERM && (conf.copymode || !read) 
1991/0608    
 
	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) 
1990/0227    
	&& ((head && ((o->flag&OPURE) || o->nproc>1)) 
	    || (!head && pte->page->ref>1))){ 
1991/0608    
		/* 
		 * Copy on reference (conf.copymode==1) or write (conf.copymode==0) 
		 */ 
1991/0607    
 
		if(!(o->flag&OISMEM)) 
			panic("copy on ref/wr to non memory"); 
1991/0607/sys/src/9/port/fault.c:199,2071991/0608/sys/src/9/port/fault.c:205,217
1991/0607    
					mmuphys = PTEWRITE; 
1990/0227    
	} 
	mmuvirt = addr; 
1991/0607    
	mmuphys |= PPN(pte->page->pa) | PTEVALID | uncache; 
	if(o->flag&OISMEM) 
1991/0608    
 
	/* Non memory is always uncached */ 
	if(o->flag&OISMEM) { 
		mmuphys |= PPN(pte->page->pa) | PTEVALID; 
1991/0607    
		usepage(pte->page, 1); 
1991/0608    
	}else 
		mmuphys |= PPN(pte->page->pa) | PTEVALID | PTEUNCACHED; 
1991/0607    
 
1990/0227    
	if(pte->page->va != addr) 
		panic("wrong addr in tail %lux %lux", pte->page->va, addr); 
1991/0607/sys/src/9/port/fault.c:216,2211991/0608/sys/src/9/port/fault.c:226,235
1991/0425    
		m->tlbfault++; 
1991/0607    
 
1990/0227    
	putmmu(mmuvirt, mmuphys); 
1991/0608    
/* 
	if(s - u->p->seg == LSEG) 
		print("%d: f %lux v %lux p %lux\n", u->p->pid, o->flag, mmuvirt, mmuphys); 
*/ 
1990/1212    
	return 0; 
1990/0227    
} 
 
1991/0608/sys/src/9/port/fault.c:226,2351991/0611/sys/src/9/port/fault.c:226,231 (short | long)
1991/0425    
		m->tlbfault++; 
1991/0607    
 
1990/0227    
	putmmu(mmuvirt, mmuphys); 
1991/0608    
/* 
	if(s - u->p->seg == LSEG) 
		print("%d: f %lux v %lux p %lux\n", u->p->pid, o->flag, mmuvirt, mmuphys); 
*/ 
1990/1212    
	return 0; 
1990/0227    
} 
 
1991/0608/sys/src/9/port/fault.c:299,3031991/0611/sys/src/9/port/fault.c:295,300
1991/0606    
	for(s=p->seg; s < et; s++) 
1990/0227    
		if(s->o && s->minva<=addr && addr<s->maxva) 
			return s; 
1991/0611    
 
1990/0227    
	return 0; 
} 
1991/0611/sys/src/9/port/fault.c:264,2701991/0619/sys/src/9/port/fault.c:264,270 (short | long)
1990/0227    
 * &s[0] is known to be a valid address. 
 */ 
void* 
vmemchr(void *s, int c, int n) 
1991/0619    
vmemchr(void *s, int c, ulong n) 
1990/0227    
{ 
	int m; 
	char *t; 
1991/0611/sys/src/9/port/fault.c:272,2891991/0619/sys/src/9/port/fault.c:272,292
1990/0227    
 
	a = (ulong)s; 
	m = BY2PG - (a & (BY2PG-1)); 
	if(m < n){ 
		t = vmemchr(s, c, m); 
1991/0619    
	while(n){ 
		if(n < m) 
			m = n; 
		t = memchr(s, c, m); 
1990/0227    
		if(t) 
			return t; 
1991/0619    
		if(n == m) 
			return 0; 
1990/0227    
		if(!(a & KZERO)) 
			validaddr(a+m, 1, 0); 
		return vmemchr((void*)(a+m), c, n-m); 
1991/0619    
		n -= m; 
		a += m; 
		m = BY2PG; 
1990/0227    
	} 
	/* 
	 * All in one page 
	 */ 
	return memchr(s, c, n); 
1991/0619    
	return 0; 
1990/0227    
} 
 
Seg* 
Too many diffs (26 > 25). Stopping.


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)