I know a return instruction will transfer "program control to a return address located on the top of the stack" (page 1205).
Is the stack for the current process always in memory?
Assuming I return to a function in my own program (a near return?), then am I guaranteed no page fault?
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)?
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.