--- /sys/src/9k/k10/mmu.c +++ /sys/src/9k/k10/mmu.c @@ -617,3 +617,18 @@ pte[PTLX(KSEG1PML4, 3)] = m->pml4->pa|PteRW|PteP; mmuphysaddr(PTR2UINT(end)); } + +/* + * Double-check the user MMU. + * Error checking only. + */ +void +checkmmu(uintptr va, uintmem pa) +{ + uintmem mpa; + + mpa = mmuphysaddr(va); + if(mpa != ~(uintmem)0 && mpa != pa) + print("%d %s: va=%#p pa=%#P mmupa=%#P\n", + up->pid, up->text, va, pa, mpa); +} --- /sys/src/9k/port/fault.c +++ /sys/src/9k/port/fault.c @@ -342,3 +342,40 @@ seg(Proc *p, uintptr addr, int dolock) return 0; } + +extern void checkmmu(uintptr, uintmem); +void +checkpages(void) +{ + int checked; + uintptr addr, off; + Pte *p; + Page *pg; + Segment **sp, **ep, *s; + uint pgsize; + + if(up == nil) + return; + + checked = 0; + for(sp=up->seg, ep=&up->seg[NSEG]; splk); + pgsize = 1<lg2pgsize; + for(addr=s->base; addrtop; addr+=pgsize){ + off = addr - s->base; + p = s->map[off/s->ptemapmem]; + if(p == nil) + continue; + pg = p->pages[(off&(s->ptemapmem-1))/pgsize]; + if(pg == nil || pagedout(pg)) + continue; + checkmmu(addr, pg->pa); + checked++; + } + qunlock(&s->lk); + } + print("%d %s: checked %d page table entries\n", up->pid, up->text, checked); +}