I'm trying to loop through all pages for a process in xv6.
I've looked at this diagram to understand how it works:
but my code is getting:
unexpected trap 14 from cpu 0 eip 801045ff (cr2=0xdfbb000)
Code:
pde_t * physPgDir = (void *)V2P(p->pgdir);
int c = 0;
for(unsigned int i =0; i<NPDENTRIES;i++){
pde_t * pde = &physPgDir[i];
if(*pde & PTE_P){//page directory valid entry
int pde_ppn = (int)((PTE_ADDR(*pde)) >> PTXSHIFT);
pte_t * physPgtab = (void *)(PTE_ADDR(*pde));//grab 20 MSB for inner page table phys pointer;
// go through inner page table
for(unsigned int j =0;j<NPDENTRIES;j++){
pte_t * pte = &physPgtab[j];
if(*pte & PTE_P){//valid entry
c++;
unsigned int pte_ppn = (PTE_ADDR(*pte)) >> PTXSHIFT;//grab 20 MSB for inner page table phys pointer;
//do thing
}
}
}
}
This is in some custom function in proc.c that gets called elsewhere. p is a process pointer. As far as I understand, cr3 contains the physical address of the current process. However in my case I need to get the page table for a given process pointer. The xv6 code seems to load V2P(p->pgdir) in cr3. That is why I tried to get V2P(p->pgdir). However,the trap happens before pde is dereferenced. Which means there is a problem there. Am I not supposed to use the physical address?
Edit: As Brendan answered, the virtual address p->pgdir is what should be dereferenced. Additionally, the PPN from the Page directory should also be converted via P2V to properly dereference into the page table. If someone else also gets confused about this aspect of xv6 in the future, I hope that helps.