linux/arch/x86/kvm
Omar Sandoval 53903ac9ca KVM: SVM: Don't skip unrelated instruction if INT3/INTO is replaced
commit 4da3768e18 upstream.

When re-injecting a soft interrupt from an INT3, INT0, or (select) INTn
instruction, discard the exception and retry the instruction if the code
stream is changed (e.g. by a different vCPU) between when the CPU
executes the instruction and when KVM decodes the instruction to get the
next RIP.

As effectively predicted by commit 6ef88d6e36 ("KVM: SVM: Re-inject
INT3/INTO instead of retrying the instruction"), failure to verify that
the correct INTn instruction was decoded can effectively clobber guest
state due to decoding the wrong instruction and thus specifying the
wrong next RIP.

The bug most often manifests as "Oops: int3" panics on static branch
checks in Linux guests.  Enabling or disabling a static branch in Linux
uses the kernel's "text poke" code patching mechanism.  To modify code
while other CPUs may be executing that code, Linux (temporarily)
replaces the first byte of the original instruction with an int3 (opcode
0xcc), then patches in the new code stream except for the first byte,
and finally replaces the int3 with the first byte of the new code
stream.  If a CPU hits the int3, i.e. executes the code while it's being
modified, then the guest kernel must look up the RIP to determine how to
handle the #BP, e.g. by emulating the new instruction.  If the RIP is
incorrect, then this lookup fails and the guest kernel panics.

The bug reproduces almost instantly by hacking the guest kernel to
repeatedly check a static branch[1] while running a drgn script[2] on
the host to constantly swap out the memory containing the guest's TSS.

[1]: https://gist.github.com/osandov/44d17c51c28c0ac998ea0334edf90b5a
[2]: https://gist.github.com/osandov/10e45e45afa29b11e0c7209247afc00b

Fixes: 6ef88d6e36 ("KVM: SVM: Re-inject INT3/INTO instead of retrying the instruction")
Cc: stable@vger.kernel.org
Co-developed-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Omar Sandoval <osandov@fb.com>
Link: https://patch.msgid.link/1cc6dcdf36e3add7ee7c8d90ad58414eeb6c3d34.1762278762.git.osandov@fb.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2025-12-12 18:42:45 +01:00
..
mmu KVM: x86: Export KVM-internal symbols for sub-modules only 2025-09-30 13:40:02 -04:00
svm KVM: SVM: Don't skip unrelated instruction if INT3/INTO is replaced 2025-12-12 18:42:45 +01:00
vmx KVM: VMX: Fix check for valid GVA on an EPT violation 2025-11-06 06:06:18 -08:00
.gitignore KVM: x86: use a separate asm-offsets.c file 2022-11-09 12:10:17 -05:00
cpuid.c KVM: x86: Export KVM-internal symbols for sub-modules only 2025-09-30 13:40:02 -04:00
cpuid.h Merge branch 'kvm-tdx-initial' into HEAD 2025-04-07 07:36:33 -04:00
debugfs.c KVM: Get rid of return value from kvm_arch_create_vm_debugfs() 2024-02-23 21:44:58 +00:00
emulate.c - Remove a bunch of asm implementing condition flags testing in KVM's 2025-10-11 11:19:16 -07:00
fpu.h KVM: x86: Move FPU register accessors into fpu.h 2021-06-17 13:09:24 -04:00
hyperv.c KVM: x86: Export KVM-internal symbols for sub-modules only 2025-09-30 13:40:02 -04:00
hyperv.h KVM: x86: Drop superfluous kvm_hv_set_sint() => kvm_hv_synic_set_irq() wrapper 2025-06-20 13:52:43 -07:00
i8254.c Significant patch series in this pull request: 2025-08-03 16:23:09 -07:00
i8254.h KVM: x86: Move IRQ mask notifier infrastructure to I/O APIC emulation 2025-06-20 13:52:52 -07:00
i8259.c KVM: x86: Move IRQ mask notifier infrastructure to I/O APIC emulation 2025-06-20 13:52:52 -07:00
ioapic.c arch/x86/kvm/ioapic: Remove license boilerplate with bad FSF address 2025-08-19 11:59:29 -07:00
ioapic.h KVM: x86: Move IRQ mask notifier infrastructure to I/O APIC emulation 2025-06-20 13:52:52 -07:00
irq.c KVM: x86: Export KVM-internal symbols for sub-modules only 2025-09-30 13:40:02 -04:00
irq.h KVM: x86: Move kvm_irq_delivery_to_apic() from irq.c to lapic.c 2025-09-10 12:05:09 -07:00
Kconfig - Remove a bunch of asm implementing condition flags testing in KVM's 2025-10-11 11:19:16 -07:00
kvm-asm-offsets.c KVM: SVM: move MSR_IA32_SPEC_CTRL save/restore to assembly 2022-11-09 12:25:53 -05:00
kvm_cache_regs.h KVM: VMX: Make CR4.CET a guest owned bit 2025-09-23 10:03:09 -07:00
kvm_emulate.h KVM: x86: Don't (re)check L1 intercepts when completing userspace I/O 2025-08-19 10:53:40 -07:00
kvm_onhyperv.c KVM: x86: Export KVM-internal symbols for sub-modules only 2025-09-30 13:40:02 -04:00
kvm_onhyperv.h KVM: x86: Move Hyper-V partition assist page out of Hyper-V emulation context 2023-12-07 09:34:01 -08:00
lapic.c KVM: x86: Export KVM-internal symbols for sub-modules only 2025-09-30 13:40:02 -04:00
lapic.h KVM: x86: Move kvm_intr_is_single_vcpu() to lapic.c 2025-09-30 13:40:02 -04:00
Makefile KVM: x86: Fold irq_comm.c into irq.c 2025-06-20 13:52:52 -07:00
mmu.h KVM: x86/mmu: WARN on attempt to check permissions for Shadow Stack #PF 2025-09-23 09:16:53 -07:00
mtrr.c KVM: x86: drop x86.h include from cpuid.h 2024-11-01 09:22:23 -07:00
pmu.c KVM: x86/pmu: Don't try to get perf capabilities for hybrid CPUs 2025-10-10 14:25:12 -07:00
pmu.h Generic: 2025-10-06 12:37:34 -07:00
reverse_cpuid.h KVM: x86: Advertise support for the immediate form of MSR instructions 2025-08-19 11:59:47 -07:00
smm.c KVM: x86: Export KVM-internal symbols for sub-modules only 2025-09-30 13:40:02 -04:00
smm.h KVM: x86: Save and reload SSP to/from SMRAM 2025-09-23 09:11:22 -07:00
trace.h KVM: x86: Define AMD's #HV, #VC, and #SX exception vectors 2025-09-23 09:29:03 -07:00
tss.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
x86.c KVM: SVM: Don't skip unrelated instruction if INT3/INTO is replaced 2025-12-12 18:42:45 +01:00
x86.h KVM: x86: Allow setting CR4.CET if IBT or SHSTK is supported 2025-09-23 09:17:48 -07:00
xen.c KVM: x86/xen: Fix cleanup logic in emulation of Xen schedop poll hypercalls 2025-07-23 23:48:54 +02:00
xen.h KVM: x86: Update Xen TSC leaves during CPUID emulation 2025-02-25 07:09:55 -08:00