Page 1 of 1

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

Posted: Fri Feb 27, 2026 12:26 pm
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?

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

Posted: Fri Feb 27, 2026 12:58 pm
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.

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

Posted: Sat Feb 28, 2026 5:02 am
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?

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

Posted: Mon Mar 02, 2026 2:52 am
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.