linux/arch/x86/entry
Matthew Schwartz 93f53499d0 x86/fred: Reconstruct the #GP context for rejected INT instructions
FRED event delivery does not use the IDT, so the gate DPL check that
rejects a user INT n falls to software (Intel FRED specification [1],
section 8.3). fred_intx() rejects the same vectors as IDT delivery, but
reports a zero error code and the IP after the INT. This breaks the
signal ABI. Wine uses the error code to recognize INT 0x2d, so the
changed context turns a handled breakpoint into an access violation in
Elden Ring.

Rewind IP using the instruction length in the augmented SS and
synthesize the IDT selector error code, (vector << 3) | 2. Set RF in the
saved flags, as the CPU does for a #GP fault. Section 5.2.1 defines the
saved vector, instruction length and RF state. The supplied length
handles prefixes without reading user memory. Limit the changes to
already-rejected software interrupts, preserving the accepted INT3, INT4
and enabled INT80 paths and hardware exceptions. With IA32 emulation
disabled, INT 0x80 now reports the same #GP as the DPL 0 gate IDT
installs there. The rewound IP also stops fixup_iopl_exception() from
inspecting the byte after the INT.

Also clear the software event flag. Section 6.2.3 specifies that ERETU
with this flag and TF set traps before executing any user instruction. A
tracer that suppresses SIGSEGV and resumes with TF set expects the next
instruction to run first, as after IRET. The sigreturn path clears the
same flag for this reason in prevent_single_step_upon_eretu().

[1] Intel Flexible Return and Event Delivery (FRED) Specification,
revision 9.0 (346446-009US), sections 5.2.1, 6.2.3 and 8.3.

Fixes: 14619d912b ("x86/fred: FRED entry/exit and dispatch code")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/work_items/15745
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/work_items/16132
Reported-by: Paul Gofman <pgofman@codeweavers.com>
Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: H. Peter Anvin <hpa@zytor.com>
Link: https://cdrdv2.intel.com/v1/dl/getContent/678938 # [1]
Link: https://patch.msgid.link/20260917230907.2080792-2-matthew.schwartz@linux.dev
2026-09-18 12:33:17 +02:00
..
syscalls arch: hookup fchroot() system call 2026-07-27 17:18:00 +02:00
vdso x86/vdso: Respect COMPAT_32BIT_TIME 2026-07-07 23:52:53 +02:00
vsyscall seccomp, treewide: Rename and convert __secure_computing() to return boolean 2026-07-12 12:38:02 +02:00
calling.h x86/fred: Play nice with invoking asm_fred_entry_from_kvm() on non-FRED hardware 2025-08-18 14:23:08 +02:00
common.c x86/kvm/vmx: Fix x86_64 CFI build 2026-05-28 11:31:50 +02:00
entry_32.S x86/percpu: Move top_of_stack to percpu hot section 2025-03-04 20:30:33 +01:00
entry_64_compat.S x86/percpu: Move top_of_stack to percpu hot section 2025-03-04 20:30:33 +01:00
entry_64_fred.S x86/entry/fred: Encode frame pointer on entry 2026-07-14 11:08:12 -07:00
entry_64.S x86/bugs: Make Safe-RET robust against interrupt injection 2026-07-26 07:21:37 -07:00
entry_fred.c x86/fred: Reconstruct the #GP context for rejected INT instructions 2026-09-18 12:33:17 +02:00
entry.S x86/kvm/vmx: Fix x86_64 CFI build 2026-05-28 11:31:50 +02:00
Makefile x86/kvm/vmx: Move IRQ/NMI dispatch from KVM into x86 core 2026-05-19 20:25:51 +02:00
syscall_32.c entry, treewide: Make syscall_enter_from_user_mode[_work]() indicate syscall execution 2026-07-20 20:38:40 +02:00
syscall_64.c entry, treewide: Make syscall_enter_from_user_mode[_work]() indicate syscall execution 2026-07-20 20:38:40 +02:00
thunk.S x86/entry: Merge thunk_64.S and thunk_32.S into thunk.S 2024-04-09 09:57:56 +02:00