target/i386: fix missing PF_INSTR in SIGSEGV context
When running linux-user emulation, the SIGSEGV handler does not correctly set the 4th bit (PF_INSTR) in the error_code variable of the context argument (context->uc_mcontext.gregs[REG_ERR]). Because this bit is never set, guest applications cannot distinguish if a fault was due to missing executable permissions. This patch ensures that when a page fault occurs during an instruction fetch, the PF_INSTR flag is properly populated in the signal context. Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3384 Signed-off-by: Simon Scherer <scherer.simon89@gmail.com> Link: https://lore.kernel.org/r/20260413115622.160212-1-scherer.simon89@gmail.com Cc: qemu-stable@nongnu.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Simon Scherer committed
Apr 13, 2026 at 13:56 UTC
3eae91a8b93a35f194a39ab5b894ae405def9270
1 file changed
+4
-3
target/i386/tcg/user/excp_helper.c
+4
-3
@@ -36,9 +36,10 @@ void x86_cpu_record_sigsegv(CPUState *cs, vaddr addr,
36
* signal and set exception_index to EXCP_INTERRUPT.
37
*/
38
env->cr[2] = addr;
39
- env->error_code = ((access_type == MMU_DATA_STORE) << PG_ERROR_W_BIT)
40
- | (maperr ? 0 : PG_ERROR_P_MASK)
41
- | PG_ERROR_U_MASK;
39
+ env->error_code = (maperr ? 0 : PG_ERROR_P_MASK)
40
+ | ((access_type == MMU_DATA_STORE) << PG_ERROR_W_BIT)
41
+ | PG_ERROR_U_MASK
42
+ | ((access_type == MMU_INST_FETCH) ? PG_ERROR_I_D_MASK : 0);
43
cs->exception_index = EXCP0E_PAGE;
44
45
/* Disable do_interrupt_user. */