| plan 9 kernel history: overview | file list | diff list |
1991/0607/port/fault.c (diff list | history)
| 1991/0606/sys/src/9/port/fault.c:9,15 – 1991/0607/sys/src/9/port/fault.c:9,15 (short | long | prev | next) | ||
| 1990/1212 | int fault(ulong addr, int read) | |
| 1990/0227 | { | |
| 1991/0606 |
| |
| 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,73 – 1991/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); | |
| 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,123 – 1991/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 |
| |
| 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,168 – 1991/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,198 – 1991/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 |
| |
| 1990/0227 | easy: | |
| 1991/0606 |
| |
| 1991/0607 | mmuphys = PTEWRITE; | |
| 1990/0227 | }else{ | |
| 1991/0606 |
| |
| 1991/0607 | mmuphys = PTERONLY; | |
| 1990/0227 | if(o->flag & OWRPERM) if(o->flag & OPURE){ if(!head && pte->page->ref==1) | |
| 1991/0606 |
| |
| 1991/0607 | mmuphys = PTEWRITE; | |
| 1990/0227 | }else if((head && o->nproc==1) || (!head && pte->page->ref==1)) | |
| 1991/0606 |
| |
| 1991/0607 | mmuphys = PTEWRITE; | |
| 1990/0227 | } mmuvirt = addr; | |
| 1990/1212 |
| |
| 1990/0227 |
| |
| 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,208 – 1991/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 | } | |