The #PF is generated with an error code pushed on stack.
I would do something like:
Code:
align 16
INT0E:
pusha
mov eax, cr2
push dword [esp+32] ; error code
push eax
call PageFaultHandler
add esp, 8 ; cr2 and error code
popa
add esp, 4 ; error code
iret
The C handler looks like this:
void PageFaultHandler(uint32_t address, uint32_t code);
The handler would do:
* If page not present
- decide if a page should be allocated, I do this by marking a special bit on the PTE entry after page_alloc, so the handler know if the address has called page_alloc or is it really a fault.
- I specially handle the topmost 4MB so that a page will always be allocated for new PTE entry.
- do other validations and accounting
At the end if the handler decide to allocate page(s) for the fault, it request the page allocator, update the page table and invlpg(); otherwise terminate the application or panic.
* You may also implement other leet features like CoW in the handler