I am writing a custom hypervisor implementation which intercepts NPF for some pages initially marked as "Not Present" or the "P" field is 0, and those pages happen to be mapped by the OS as .text section in some user mode programs. The intention is to get an "Execution Fault" when the I/D field of the faulting nested PTE will become 1 indicating that the physical page accessed is not present when a program is trying to execute it. Everything works as expected except for the EXITINFO2 value which gives me the faulting guest PA. The implementation I've been working on relies on the lower 12 bits of the EXITINFO2 or the offset of a faulting physical page (which is being executed) and in rare cases the offset happen to be 0 even when the page offset of the guest RIP is not 0. Given the development manual "Volume 2: System Programming" my understanding is that the page offset of guest RIP should always be same as the page offset of EXITINFO2 should an "Execution Fault" occures on that page. Additionally what I've discovered is that this happens when the instruction which caused the fault happen to be following a CALL instruction, something looks like the following:
CALL function
MOV reg1, reg2 ;<- guest RIP during the NPF, page offset of EXITINFO2 is always 0
;even when the virtual page offset of this instruction is not.
My configuration only use 4K physical pages. This gets really technical regarding SVM, hope I'm explaining everything clearly.