| From 36f7addde5e161c3ad08eccfdaaf6d318b6e6461 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 14 Aug 2025 17:11:59 -0700 |
| Subject: KVM: x86: Convert vcpu_run()'s immediate exit param into a generic |
| bitmap |
| |
| From: Sean Christopherson <seanjc@google.com> |
| |
| [ Upstream commit 2478b1b220c49d25cb1c3f061ec4f9b351d9a131 ] |
| |
| Convert kvm_x86_ops.vcpu_run()'s "force_immediate_exit" boolean parameter |
| into an a generic bitmap so that similar "take action" information can be |
| passed to vendor code without creating a pile of boolean parameters. |
| |
| This will allow dropping kvm_x86_ops.set_dr6() in favor of a new flag, and |
| will also allow for adding similar functionality for re-loading debugctl |
| in the active VMCS. |
| |
| Opportunistically massage the TDX WARN and comment to prepare for adding |
| more run_flags, all of which are expected to be mutually exclusive with |
| TDX, i.e. should be WARNed on. |
| |
| No functional change intended. |
| |
| Cc: stable@vger.kernel.org |
| Link: https://lore.kernel.org/r/20250610232010.162191-3-seanjc@google.com |
| Signed-off-by: Sean Christopherson <seanjc@google.com> |
| [sean: drop TDX crud, account for lack of kvm_x86_call()] |
| Signed-off-by: Sean Christopherson <seanjc@google.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| arch/x86/include/asm/kvm_host.h | 6 +++++- |
| arch/x86/kvm/svm/svm.c | 4 ++-- |
| arch/x86/kvm/vmx/vmx.c | 3 ++- |
| arch/x86/kvm/x86.c | 10 ++++++++-- |
| 4 files changed, 17 insertions(+), 6 deletions(-) |
| |
| diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h |
| index 86f3bd6601e7..1383f5e5238a 100644 |
| --- a/arch/x86/include/asm/kvm_host.h |
| +++ b/arch/x86/include/asm/kvm_host.h |
| @@ -1456,6 +1456,10 @@ static inline u16 kvm_lapic_irq_dest_mode(bool dest_mode_logical) |
| return dest_mode_logical ? APIC_DEST_LOGICAL : APIC_DEST_PHYSICAL; |
| } |
| |
| +enum kvm_x86_run_flags { |
| + KVM_RUN_FORCE_IMMEDIATE_EXIT = BIT(0), |
| +}; |
| + |
| struct kvm_x86_ops { |
| const char *name; |
| |
| @@ -1529,7 +1533,7 @@ struct kvm_x86_ops { |
| |
| int (*vcpu_pre_run)(struct kvm_vcpu *vcpu); |
| enum exit_fastpath_completion (*vcpu_run)(struct kvm_vcpu *vcpu, |
| - bool force_immediate_exit); |
| + u64 run_flags); |
| int (*handle_exit)(struct kvm_vcpu *vcpu, |
| enum exit_fastpath_completion exit_fastpath); |
| int (*skip_emulated_instruction)(struct kvm_vcpu *vcpu); |
| diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c |
| index 12de50db401f..dc8a1b72d8ec 100644 |
| --- a/arch/x86/kvm/svm/svm.c |
| +++ b/arch/x86/kvm/svm/svm.c |
| @@ -4008,9 +4008,9 @@ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu, bool spec_ctrl_in |
| guest_state_exit_irqoff(); |
| } |
| |
| -static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu, |
| - bool force_immediate_exit) |
| +static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags) |
| { |
| + bool force_immediate_exit = run_flags & KVM_RUN_FORCE_IMMEDIATE_EXIT; |
| struct vcpu_svm *svm = to_svm(vcpu); |
| bool spec_ctrl_intercepted = msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL); |
| |
| diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c |
| index 179747d04edc..382f42200688 100644 |
| --- a/arch/x86/kvm/vmx/vmx.c |
| +++ b/arch/x86/kvm/vmx/vmx.c |
| @@ -7204,8 +7204,9 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu, |
| guest_state_exit_irqoff(); |
| } |
| |
| -static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit) |
| +static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags) |
| { |
| + bool force_immediate_exit = run_flags & KVM_RUN_FORCE_IMMEDIATE_EXIT; |
| struct vcpu_vmx *vmx = to_vmx(vcpu); |
| unsigned long cr3, cr4; |
| |
| diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c |
| index 400a6e9fb0be..83e5e823cbae 100644 |
| --- a/arch/x86/kvm/x86.c |
| +++ b/arch/x86/kvm/x86.c |
| @@ -10591,6 +10591,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) |
| dm_request_for_irq_injection(vcpu) && |
| kvm_cpu_accept_dm_intr(vcpu); |
| fastpath_t exit_fastpath; |
| + u64 run_flags; |
| |
| bool req_immediate_exit = false; |
| |
| @@ -10811,8 +10812,11 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) |
| goto cancel_injection; |
| } |
| |
| - if (req_immediate_exit) |
| + run_flags = 0; |
| + if (req_immediate_exit) { |
| + run_flags |= KVM_RUN_FORCE_IMMEDIATE_EXIT; |
| kvm_make_request(KVM_REQ_EVENT, vcpu); |
| + } |
| |
| fpregs_assert_state_consistent(); |
| if (test_thread_flag(TIF_NEED_FPU_LOAD)) |
| @@ -10848,7 +10852,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) |
| WARN_ON_ONCE((kvm_vcpu_apicv_activated(vcpu) != kvm_vcpu_apicv_active(vcpu)) && |
| (kvm_get_apic_mode(vcpu) != LAPIC_MODE_DISABLED)); |
| |
| - exit_fastpath = static_call(kvm_x86_vcpu_run)(vcpu, req_immediate_exit); |
| + exit_fastpath = static_call(kvm_x86_vcpu_run)(vcpu, run_flags); |
| if (likely(exit_fastpath != EXIT_FASTPATH_REENTER_GUEST)) |
| break; |
| |
| @@ -10860,6 +10864,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) |
| break; |
| } |
| |
| + run_flags = 0; |
| + |
| /* Note, VM-Exits that go down the "slow" path are accounted below. */ |
| ++vcpu->stat.exits; |
| } |
| -- |
| 2.50.1 |
| |