| plan 9 kernel history: overview | file list | diff list |
1991/1110/port/fault.c (diff list | history)
| 1990/0227/sys/src/9/port/fault.c:138,143 – 1990/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,218 – 1990/0312/sys/src/9/port/fault.c:211,220 | ||
| 1990/0227 | Seg *s; 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/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,223 – 1990/0617/sys/src/9/port/fault.c:208,231 (short | long) | ||
| 1990/0227 | void validaddr(ulong addr, ulong len, int write) { | |
| 1990/0617 | Seg *s, *ns; | |
| 1990/0227 |
| |
| 1990/0312 |
| |
| 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); 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,51 – 1990/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 */ | |
| 1990/0802/sys/src/9/port/fault.c:43,51 – 1990/0814/sys/src/9/port/fault.c:43,49 (short | long) | ||
| 1990/0227 | /* grow stack */ o = s->o; n = o->npte; | |
| 1990/0802 |
| |
| 1990/0802/sys/src/9/port/fault.c:52,57 – 1990/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,44 – 1990/0821/sys/src/9/port/fault.c:38,44 (short | long) | ||
| 1990/0227 | panic("fault"); } s = &u->p->seg[SSEG]; | |
| 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,230 – 1990/0821/sys/src/9/port/fault.c:223,233 | ||
| 1990/0617 | } Again: 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) 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,148 – 1990/1013/sys/src/9/port/fault.c:142,148 (short | long) | ||
| 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; | |
| 1990/1013/sys/src/9/port/fault.c:98,103 – 1990/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,224 – 1990/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); | |
| 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,247 – 1990/1110/sys/src/9/port/fault.c:243,249 | ||
| 1990/0227 | evenaddr(ulong addr) { if(addr & 3){ | |
| 1990/1110 | postnote(u->p, 1, "sys: odd address", NDebug); | |
| 1990/0227 | error(0, Ebadarg); } } | |
| 1990/1110/sys/src/9/port/fault.c:98,106 – 1990/1113/sys/src/9/port/fault.c:98,104 (short | long) | ||
| 1990/0227 | qunlock(o->chan); pg->o = 0; pg->ref--; | |
| 1990/1110 |
| |
| 1990/0227 |
| |
| 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,100 – 1990/11211/sys/src/9/port/fault.c:94,100 (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/1113/sys/src/9/port/fault.c:103,109 – 1990/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) | |
| 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,149 – 1990/11211/sys/src/9/port/fault.c:143,148 | ||
| 1990/0227 | * Add to mod list */ | |
| 1990/1013 | pte = newmod(o); | |
| 1990/0312 |
| |
| 1990/0227 | pte->proc = u->p; pte->page = opte->page; pte->page->ref++; | |
| 1990/1113/sys/src/9/port/fault.c:219,225 – 1990/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 |
| |
| 1990/11211 | error(Ebadarg); | |
| 1990/0617 | } Again: s = seg(u->p, addr); | |
| 1990/1113/sys/src/9/port/fault.c:242,248 – 1990/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 |
| |
| 1990/11211 | error(Ebadarg); | |
| 1990/0227 | } } | |
| 1990/11211/sys/src/9/port/fault.c:94,100 – 1990/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 |
| |
| 1990/0227 | qunlock(o->chan); pg->o = 0; pg->ref--; | |
| 1990/1202/sys/src/9/port/fault.c:6,16 – 1990/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" | |
| 1990/1212 | int fault(ulong addr, int read) | |
| 1990/0227 | { | |
| 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,51 – 1990/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 |
| |
| 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 |
| |
| 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"); | |
| 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,65 – 1990/1212/sys/src/9/port/fault.c:44,51 | ||
| 1990/0227 | o->va = addr; }else o = s->o; | |
| 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,99 – 1990/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,114 – 1990/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; | |
| 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); | |
| 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,129 – 1990/1212/sys/src/9/port/fault.c:109,117 | ||
| 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) | |
| 1990/0227 | && ((head && ((o->flag&OPURE) || o->nproc>1)) || (!head && pte->page->ref>1))){ | |
| 1990/1202/sys/src/9/port/fault.c:173,179 – 1990/1212/sys/src/9/port/fault.c:161,171 | ||
| 1990/0227 | opte->page = 0; }else{ /* copy page */ pte->page = newpage(1, o, addr); | |
| 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,187 – 1990/1212/sys/src/9/port/fault.c:173,179 | ||
| 1990/0227 | easy: mmuphys = PTEWRITE; }else{ | |
| 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,198 – 1990/1212/sys/src/9/port/fault.c:184,190 | ||
| 1990/0227 | mmuphys = PTEWRITE; } mmuvirt = addr; | |
| 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,208 – 1990/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,246 – 1990/1212/sys/src/9/port/fault.c:225,230 | ||
| 1990/0617 | len -= s->maxva - addr; addr = s->maxva; goto Again; | |
| 1990/0227 |
| |
| 1990/1110 |
| |
| 1990/11211 |
| |
| 1990/0227 | } } | |
| 1990/1212/sys/src/9/port/fault.c:21,27 – 1991/0110/sys/src/9/port/fault.c:21,27 (short | long) | ||
| 1990/0227 | s = seg(u->p, addr); if(s == 0){ | |
| 1990/1212 |
| |
| 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,214 – 1991/0115/sys/src/9/port/fault.c:208,214 (short | long) | ||
| 1990/0227 | ||
| 1990/0617 | if((long)len < 0){ | |
| 1990/0312 | Err: | |
| 1990/0227 |
| |
| 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,96 – 1991/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,43 – 1991/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 |
| |
| 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,170 – 1991/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); | |
| 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,98 – 1991/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 |
| |
| 1991/0411 | qlock(&o->chan->rdl); | |
| 1990/0227 | if(waserror()){ | |
| 1990/1212 | kunmap(k); | |
| 1990/0227 |
| |
| 1991/0411 | qunlock(&o->chan->rdl); | |
| 1990/0227 | pg->o = 0; pg->ref--; | |
| 1990/1113 | pexit("load i/o error", 0); | |
| 1990/0227 | } | |
| 1990/1212 | l = (char*)VA(k); | |
| 1990/0227 |
| |
| 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 |
| |
| 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,22 – 1991/0425/sys/src/9/port/fault.c:16,22 (short | long) | ||
| 1990/0227 | char *l; Page *pg; int zeroed = 0, head = 1; | |
| 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,66 – 1991/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,120 – 1991/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,199 – 1991/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,24 – 1991/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,93 – 1991/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 |
| |
| 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,31 – 1991/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 |
| |
| 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,226 – 1991/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]; | |
| 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,15 – 1991/0606/sys/src/9/port/fault.c:9,15 (short | long) | ||
| 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; | |
| 1991/0606/sys/src/9/port/fault.c:9,15 – 1991/0607/sys/src/9/port/fault.c:9,15 (short | long) | ||
| 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 | } | |
| 1991/0607/sys/src/9/port/fault.c:9,15 – 1991/0608/sys/src/9/port/fault.c:9,15 (short | long) | ||
| 1990/1212 | int fault(ulong addr, int read) | |
| 1990/0227 | { | |
| 1991/0607 |
| |
| 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,77 – 1991/0608/sys/src/9/port/fault.c:71,76 | ||
| 1991/0607 | unlock(o); return -1; } | |
| 1991/0606 | } else pte->page = newpage(0, o, addr); | |
| 1991/0607/sys/src/9/port/fault.c:116,127 – 1991/0608/sys/src/9/port/fault.c:115,133 | ||
| 1990/0227 | } } } | |
| 1990/1212 |
| |
| 1990/0227 |
| |
| 1991/0607 |
| |
| 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,207 – 1991/0608/sys/src/9/port/fault.c:205,217 | ||
| 1991/0607 | mmuphys = PTEWRITE; | |
| 1990/0227 | } mmuvirt = addr; | |
| 1991/0607 |
| |
| 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,221 – 1991/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,235 – 1991/0611/sys/src/9/port/fault.c:226,231 (short | long) | ||
| 1991/0425 | m->tlbfault++; | |
| 1991/0607 | ||
| 1990/0227 | putmmu(mmuvirt, mmuphys); | |
| 1991/0608 |
| |
| 1990/1212 | return 0; | |
| 1990/0227 | } | |
| 1991/0608/sys/src/9/port/fault.c:299,303 – 1991/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,270 – 1991/0619/sys/src/9/port/fault.c:264,270 (short | long) | ||
| 1990/0227 | * &s[0] is known to be a valid address. */ void* | |
| 1991/0619 | vmemchr(void *s, int c, ulong n) | |
| 1990/0227 | { int m; char *t; | |
| 1991/0611/sys/src/9/port/fault.c:272,289 – 1991/0619/sys/src/9/port/fault.c:272,292 | ||
| 1990/0227 | a = (ulong)s; m = BY2PG - (a & (BY2PG-1)); | |
| 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); | |
| 1991/0619 | n -= m; a += m; m = BY2PG; | |
| 1990/0227 | } | |
| 1991/0619 | return 0; | |
| 1990/0227 | } Seg* | |
| Too many diffs (26 > 25). Stopping. | ||