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

1991/0606/port/fault.c (diff list | history)

1991/0605/sys/src/9/port/fault.c:9,151991/0606/sys/src/9/port/fault.c:9,15 (short | long | prev | next)
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; 


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