linux-kernelkernelx86-64disassemblypage-fault

Can x86-64 return instruction cause a page fault in linux? Is the current process stack always in main memory?


I know a return instruction will transfer "program control to a return address located on the top of the stack" (page 1205).

  1. Is the stack for the current process always in memory?

  2. Assuming I return to a function in my own program (a near return?), then am I guaranteed no page fault?

  3. Do far returns cause a page fault if return passes control back to code in another segment that is not in memory (like for a context switch maybe)?


Solution

  • Nothing about ret or call/return in general is special as far as the CPU is concerned, or as far as kernel page-eviction algorithms. (CPUs do have a special branch predictor for call/ret, but that won't affect OS decisions about page eviction.)


    User-space stack memory is demand-paged just like any other user-space memory (unless you use mlock). ret pops a return address from the stack as [rsp]; this is the memory access that could make ret itself fault. (Or of course if code fetch of the ret instruction itself faulted).

    After ret successfully executes, code-fetch from the new RIP could also/instead page-fault if it happens to have been evicted. (Or if a call instruction was at the very end of a page, the page being returned to might never have been touched.)

    (And of course it's possible in hand-written asm, or with retpolines, to have mismatched call/ret. e.g. something like push/ret as an equivalent to jmp. Obviously you can jump to a page that's previously untouched or hasn't been for a while, leading to a hard or soft page fault.)


    Nothing about ret or call/return in general is special as far as the CPU is concerned, or as far as kernel page-eviction algorithms. The page containing [rsp] tends to be hot and not get evicted, but returning from a long sleep(100) system call, would give the kernel plenty of time to evict a page. Especially if there was significant memory pressure. Or if functions use significant stack space, they might be keeping a lower page hot, and eventually returning back up the call tree could be loading the return address from a page that hasn't been touched for a while even if the process hasn't been sleeping.