Code: Select all
[0x00100000, 0x00100000 + kernel_size] -> [0xC000000000000000, 0xC000000000000000 + kernel_size]
[Everything else] -> [Unmapped]
3. The VMM marks the 4MB area as allocated and calls it good.
4. The kernel calls kmalloc, triggering a page fault.
5. The page fault handler calls PMM and gets a physical page, tries to map it to 0xF000000000000000, however the page table does not exist, the page fault handler then calls kmalloc to allocate a 4k-aligned trunk for the page table.
6. The kmalloc triggers a page fault.
7. The page fault calls PMM and gets a physical page, tries to map it to, presumably, 0xF000000000001000, however the page table does not exist, the page fault handler then calls kmalloc to allocate a 4k-aligned trunk for the page table.
.....
I don't think I need to keep going and you should see the problem here.
One way I can think of to solve the problem is to reserve enough space for all possible page tables (PML4, PDPT, PDE, PTE) for the complete virtual address space somewhere in the virtual address space (like Windows does) and then pre-allocate page tables for that area (only allocate page tables, does not actually map) to guarantee that when page fault happens, page fault handler does not need to allocate a page for a page table.
So what happens if you are trying to map a page to a virtual address but the page table for the virtual address does not exist?