Handling page faults via traps on x86 (32-bit): Implementation Details

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
bp4k
Posts: 1
Joined: Fri Feb 27, 2026 12:18 pm

Handling page faults via traps on x86 (32-bit): Implementation Details

Post by bp4k »

I'm having a bit of difficulty understanding the working of traps in x86, specifically trap 14 (page fault). I've already done some research, but none of the posts online go into enough detail for implementation.

Here are my questions:
  1. Which register is the address pushed to?
  2. Is this address virtual or physical?
  3. How does one "resolve" the page fault? For example, if it found that the page for address "X" was set to read only, what does the CPU do when the trap returns? I'd presume it just retries the request (i.e. if my trap fault handler did nothing about that, I'd be in an infinite loop).
  4. If the request is just retried, how do we "cancel" it? Is the only way to loop infinitely in a panic?
  5. Does the trap (specifically for page faults) have to "return" anything?
Octocontrabass
Member
Member
Posts: 6249
Joined: Mon Mar 25, 2013 7:01 pm

Re: Handling page faults via traps on x86 (32-bit): Implementation Details

Post by Octocontrabass »

bp4k wrote: Fri Feb 27, 2026 12:26 pmbut none of the posts online go into enough detail for implementation.
Some of your questions are answered by the Intel SDM and AMD APM, which is where you should always look first if you want to know how an x86 CPU will behave (unless it's a very old x86 CPU).
  1. CR2
  2. Virtual
  3. If your fault handler returns without changing the program's state, the program will retry the faulting access. If the access should be allowed, you adjust the page tables to allow that access (and make any other necessary changes, such as loading data from the disk) before returning.
  4. If the access shouldn't be allowed, you change the program's state. That might mean injecting a signal (like SIGSEGV) or starting a debugger or just killing the program.
  5. Page faults don't have to return anything, but they should do something if you don't want an infinite loop of page faults.
nullplan
Member
Member
Posts: 2040
Joined: Wed Aug 30, 2017 8:24 am

Re: Handling page faults via traps on x86 (32-bit): Implementation Details

Post by nullplan »

bp4k wrote: Fri Feb 27, 2026 12:26 pm If the request is just retried, how do we "cancel" it? Is the only way to loop infinitely in a panic?
Most operating systems have a way to crash userspace programs. If a bad page fault happens in kernel space (in a place where you really didn't expect it), then yes, a panic is the only resolution, but if it happens in userspace, then you crash the faulting process. On POSIX-like systems, the kernel forces a signal like SIGSEGV against the proceess. Forcing a signal is like sending a signal, but if it is blocked or ignored, the signal is atomically unblocked, reset to default handling, and then sent. Result is that the process ends and the parent process can learn that it is because of SIGSEGV.

Note that you can use page faults to tell if userspace is handing bad addresses to the kernel in a system call. The CPU is checking the access anyway, so may as well use it, right? Linux for example expects page faults and general protection faults to happen in userspace access functions, and if they do, it rewrites the IP part of the interrupt frame to go to a handler, that will generally return -EFAULT to its caller.
bp4k wrote: Fri Feb 27, 2026 12:26 pm Does the trap (specifically for page faults) have to "return" anything?
No, they should only either rectify the page table so the access will succeed or else kill or suspend the program. However, spurious page faults (page faults for no reason) are still possible, and in those cases you really do just return.

I wrote "suspend" in the previous paragraph, because what page faults were originally for was page swapping, where a program would access a page that was moved to some storage elsewhere, and now you have to load it back into RAM before the program can continue. In times of 32GB laptops, not really a huge concern anymore, especially for hobby OSes. How could you ever run out of RAM except by running Google Chrome?
Carpe diem!
User avatar
bellezzasolo
Member
Member
Posts: 163
Joined: Sun Feb 20, 2011 2:01 pm

Re: Handling page faults via traps on x86 (32-bit): Implementation Details

Post by bellezzasolo »

nullplan wrote: Sat Feb 28, 2026 5:02 am No, they should only either rectify the page table so the access will succeed or else kill or suspend the program. However, spurious page faults (page faults for no reason) are still possible, and in those cases you really do just return.
Well, to go into a bit more detail, those spurious faults happen due to old TLB entries that haven't been flushed saying that the access is invalid.

You could avoid them, but doing so would require more global TLB shootdown IPIs, which are expensive on SMP systems. It's generally more performant to just handle the special case.
Whoever said you can't do OS development on Windows?
https://github.com/ChaiSoft/ChaiOS
Post Reply