| 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,15 – 1991/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 |
| |
| 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,76 – 1991/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))){ | |
| 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,164 – 1991/0606/sys/src/9/port/fault.c:159,168 | ||
| 1990/0227 | head = 0; } pg = pte->page; | |
| 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,189 – 1991/0606/sys/src/9/port/fault.c:174,194 | ||
| 1990/1212 | kunmap(k1); | |
| 1990/0227 | if(pg->ref <= 1) panic("pg->ref <= 1"); | |
| 1991/0606 | pg->ref--; | |
| 1990/0227 | easy: | |
| 1991/0606 | mmuphys |= PTEWRITE; | |
| 1990/0227 | }else{ | |
| 1990/1212 |
| |
| 1991/0606 | mmuphys |= PTERONLY; | |
| 1990/0227 | if(o->flag & OWRPERM) if(o->flag & OPURE){ if(!head && pte->page->ref==1) | |
| 1991/0606 | mmuphys |= PTEWRITE; | |
| 1990/0227 | }else if((head && o->nproc==1) || (!head && pte->page->ref==1)) | |
| 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,218 – 1991/0606/sys/src/9/port/fault.c:217,224 | ||
| 1990/0227 | ||
| 1990/0617 | if((long)len < 0){ | |
| 1990/0312 | Err: | |
| 1991/0115 |
| |
| 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,270 – 1991/0606/sys/src/9/port/fault.c:267,276 | ||
| 1990/0227 | Seg* seg(Proc *p, ulong addr) { | |
| 1991/0606 | Seg *s, *et; | |
| 1990/0227 |
| |
| 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; | |