Page 1 of 1

Self Mapped PD in x86_64

Posted: Tue Apr 13, 2010 10:38 pm
by proxy
With x86, the self mapped PD trick is great. At a fixed address we effectively have an array of the current page tables directly accessible at all times.

My question is, is the trick still worth it in x86_64 long mode? Can you map the PML4 onto itself? Or do you need to do it for each of the 512 PDs? Also, how much of the total address space will this occupy?

Also, if I need to individually map each of the 512 PDs, can I still get a nice linear array representing things or will it be discontinuous?

Re: Self Mapped PD in x86_64

Posted: Tue Apr 13, 2010 10:58 pm
by Hangin10
It's still doable. It took me quite some time to get right though (not to mention an embarrassing error in my physical memory allocation :oops: ). You just need to set the last PML4 entry to the PML4. It takes up from 0xFFFFFF8000000000 onwards.

All of the page tables appear at the address above. Page directories start at 0xFFFFFFFFC0000000. Page directory pointer tables at 0xFFFFFFFFFFE00000, and the PML4 itself at 0xFFFFFFFFFFFFF000.

This then means that the PML4 can be addressed like a simple long array. The rest need to be added to as much of the top of the (non-canonical [ie without the top sign-extended bits]) address as can fit in between the lowest set bit and bit 11 (exclusive).

Code: Select all

PDPT += PML4_index << 12
PDEs += PML4_index << 21 | PDP_index << 12
PTABLE += PML4_index << 30 | PDP_index << 21  | DIR_index << 12
You could, of course, use a map of all usable RAM somewhere instead. It would take just as many memory lookups (assuming the map is flat). I actually map in all usable RAM at 0xFFFFE00000000000, but I don't use it for virtual allocation (the recursive paging actually helped to make the mapping much easier, however).

Edit: Is it time to steal the IPv6 address formating yet? Colons would make everything much easier to read. e.g. 0xFFFF:E000::. Instead of zeros, the colons could replace anything irrelevant.