]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: x86: Exit to userspace if fastpath triggers one on instruction skip
authorSean Christopherson <seanjc@google.com>
Fri, 2 Aug 2024 19:51:18 +0000 (12:51 -0700)
committerSean Christopherson <seanjc@google.com>
Fri, 30 Aug 2024 02:50:21 +0000 (19:50 -0700)
Exit to userspace if a fastpath handler triggers such an exit, which can
happen when skipping the instruction, e.g. due to userspace
single-stepping the guest via KVM_GUESTDBG_SINGLESTEP or because of an
emulation failure.

Fixes: 404d5d7bff0d ("KVM: X86: Introduce more exit_fastpath_completion enum values")
Link: https://lore.kernel.org/r/20240802195120.325560-4-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/x86.c

index f9dfb2d62053ad9c503fc4cc4053b41c96c147a5..430a0d36932250521f70402fea16545b2df54a9b 100644 (file)
@@ -211,6 +211,7 @@ enum exit_fastpath_completion {
        EXIT_FASTPATH_NONE,
        EXIT_FASTPATH_REENTER_GUEST,
        EXIT_FASTPATH_EXIT_HANDLED,
+       EXIT_FASTPATH_EXIT_USERSPACE,
 };
 typedef enum exit_fastpath_completion fastpath_t;
 
index d392e9097d63347f53521f73f2ad76931557a91f..d6c81d59d4872363683d26d531b8979bdc50ff17 100644 (file)
@@ -2206,8 +2206,10 @@ fastpath_t handle_fastpath_set_msr_irqoff(struct kvm_vcpu *vcpu)
        }
 
        if (handled) {
-               kvm_skip_emulated_instruction(vcpu);
-               ret = EXIT_FASTPATH_REENTER_GUEST;
+               if (!kvm_skip_emulated_instruction(vcpu))
+                       ret = EXIT_FASTPATH_EXIT_USERSPACE;
+               else
+                       ret = EXIT_FASTPATH_REENTER_GUEST;
                trace_kvm_msr_write(msr, data);
        } else {
                ret = EXIT_FASTPATH_NONE;
@@ -11196,6 +11198,9 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
        if (vcpu->arch.apic_attention)
                kvm_lapic_sync_from_vapic(vcpu);
 
+       if (unlikely(exit_fastpath == EXIT_FASTPATH_EXIT_USERSPACE))
+               return 0;
+
        r = kvm_x86_call(handle_exit)(vcpu, exit_fastpath);
        return r;