Many of you are probably familiar with the scheme where you set the last PDE to the physical address of the page directory itself, thus enabling easier page-ins. The range where the page tables lives, starts at 0xFFC00000.
I am now attempting the same in 64 bit (really 48 bit) space, but keep getting page faults. I wonder if someone could kindly confirm my maths, as I keep getting page not present PFE's, so I must be wrong somewhere!
Here are my 'table entry' variables:
Code: Select all
u16 pml4e = ((uptr)vptr >> 39) & 0x1FF;
u16 pdpte = ((uptr)vptr >> 30) & 0x1FF;
u16 pde = ((uptr)vptr >> 21) & 0x1FF;
u16 pte = ((uptr)vptr >> 12) & 0x1FF;
Next, my 'table base' variables:
Code: Select all
uptr *pdpt = (uptr*)((uptr)ptbase + (pdpte * 0x40000000) + (pdpte * 0x200000) + (pdpte * 0x1000));
uptr *pd = (uptr*)((uptr)ptbase + (pdpte * 0x40000000) + (pde * 0x200000) + (pde * 0x1000));
uptr *pt = (uptr*)((uptr)ptbase + (pdpte * 0x40000000) + (pde * 0x200000) + (pte * 0x1000));
Let me explain. uptr *pdpt here should point to the appropriate Page Directory Pointer Table in virtual RAM. *pd should point to the appropriate Page Directory and *pt should point to the page table. This means that I can then go through checking pml4[pml4e], then pdpt[pdpte], pd[pde] and pt[pde] for the page present flag, adding in the tables as necessary.
My page in function does not cause any PFE's itself - rather, the PFE I have does not seem to resolve after running the function. If I identity map the paging structures individually and page-in that way, it works nicely, but when I have a user process running in low RAM, I don't want to be doing that!
Can anyone spot a mistake / make a suggestion?
Cheers,
Adam