All.
I am trying to print current PC value, when I allocate a new physical page. In linux kernel source, mm/memory.c is responsible for allocating pages, but it does not have information about PC value... Does anyone know where can I find this PC value and use it in memory.c file?
Making my comment into an answer.
What you're looking for is not the current PC (that changes all the time), but the PC of the instruction triggering the page fault. To understand where that is stored and how it can be retrieved, let's dig a little bit deeper.
When an exception (trap or interrupt) occurs in x86, the CPU will do the following:
#GP
fault (General Protection [ error ]); since that in itself is an exception ... if the gate for that is invalid as well ... #DF
(Double Fault) ... rinse repeat ... if invalid - Triple Fault (which resets the CPU hard).%cs
the kernel one, and the handler some low-level interrupt entry function).#DF
opportunity here ... happens if this fails, due to a corrupted kernel stack pointer, or a stack overflow into unmapped memory). The information written contains:
flags
registerstruct ptregs*
as argument - that's the exception frame, register state saved by trap entry (partially by HW/the CPU itself, partially by the entry stub code). This is what actually used to handle the trap/exception/interrupt.When returning from the trap / interrupt, the x86 iret
instruction is used to unwind the four/five words pushed onto the kernel stack by the CPU in order to resume / return.
This way, every exception-entry in the kernel is given the same data structure, struct ptregs *
- which, as said, for most traps/interrupts, amongst other information, contains the program counter / instruction pointer stating where the fault happened. struct pt_regs.ip
is the field you'll need to look at.
For page faults in particular, see do_page_fault()
and check where / how this is used.