Confirmation of my Maths Requested
Posted: Mon Jan 21, 2008 9:48 am
Hello,
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:
This should be fairly self-explanatory to anyone who can help me! VPTR is the address of the pointer I want to page in (in Canonical form) and the variables are ones I have declared for PML4 entry, PDPT entry and so on... (uptr) has been typedef'd to be the same width as the pointer size of the processor (in this case, a 64 bit unsigned integer). u16 should be self explanatory.
Next, my 'table base' variables:
So, ptbase here is the start of the range of page tables (because pml4[0x1ff] = itself | flags;, this is 0xFFFF FF80 0000 0000, the last area represented by a PML4 entry in the 48 bit paging scheme - made canonical, of course).
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
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