An interesting paper (via Muli Ben-Yehuda) that describes, in particular, VM organization of several platforms. A bit I didn't knew: ULTRIX uses two level page tables that are traversed bottom-up: leaf level of the tree lives in the virtual space and is contiguous in it. As a result, to handle TLB miss at the virtual address A it's enough to do:
phys_address = LEAF_TABLE[A >> PTABLE_SHIFT_LEAF];
Obviously it is somewhat more involved in reality, because appropriate portion of LEAF_TABLE can be not in the TLB itself. In the latter case, root node of the tree is consulted:
if (tlb_miss(LEAF_TABLE + (A >> PTABLE_SHIFT_LEAF)) tlb_load(ROOT_NODE[A >> PTABLE_SHIFT_ROOT], LEAF_TABLE + (A >> PTABLE_SHIFT_LEAF)); phys_address = LEAF_TABLE[A >> PTABLE_SHIFT_LEAF];
Root node is wired down into unmapped (physical) memory.
This design provides following advantages:
- TLB miss handling requires one memory access in the best case, and two in the worst. In top-to-bottom page tables a la Intel, two (or three) accesses are necessary for every TLB refill;
- This integrates nicely with virtually indexed processor caches;
- This allows parts of page tables to be paged out easily.