Commit 2478b1b2 authored by Sean Christopherson's avatar Sean Christopherson
Browse files

KVM: x86: Convert vcpu_run()'s immediate exit param into a generic bitmap

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: default avatarSean Christopherson <seanjc@google.com>
parent 7d390a9d
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -1674,6 +1674,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;

@@ -1755,7 +1759,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);
+2 −2
Original line number Diff line number Diff line
@@ -4389,9 +4389,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);

+3 −3
Original line number Diff line number Diff line
@@ -175,12 +175,12 @@ static int vt_vcpu_pre_run(struct kvm_vcpu *vcpu)
	return vmx_vcpu_pre_run(vcpu);
}

static fastpath_t vt_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit)
static fastpath_t vt_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags)
{
	if (is_td_vcpu(vcpu))
		return tdx_vcpu_run(vcpu, force_immediate_exit);
		return tdx_vcpu_run(vcpu, run_flags);

	return vmx_vcpu_run(vcpu, force_immediate_exit);
	return vmx_vcpu_run(vcpu, run_flags);
}

static int vt_handle_exit(struct kvm_vcpu *vcpu,
+9 −9
Original line number Diff line number Diff line
@@ -1025,20 +1025,20 @@ static void tdx_load_host_xsave_state(struct kvm_vcpu *vcpu)
				DEBUGCTLMSR_FREEZE_PERFMON_ON_PMI | \
				DEBUGCTLMSR_FREEZE_IN_SMM)

fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit)
fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags)
{
	struct vcpu_tdx *tdx = to_tdx(vcpu);
	struct vcpu_vt *vt = to_vt(vcpu);

	/*
	 * force_immediate_exit requires vCPU entering for events injection with
	 * an immediately exit followed. But The TDX module doesn't guarantee
	 * entry, it's already possible for KVM to _think_ it completely entry
	 * to the guest without actually having done so.
	 * Since KVM never needs to force an immediate exit for TDX, and can't
	 * do direct injection, just warn on force_immediate_exit.
	 * WARN if KVM wants to force an immediate exit, as the TDX module does
	 * not guarantee entry into the guest, i.e. it's possible for KVM to
	 * _think_ it completed entry to the guest and forced an immediate exit
	 * without actually having done so.  Luckily, KVM never needs to force
	 * an immediate exit for TDX (KVM can't do direct event injection, so
	 * just WARN and continue on.
	 */
	WARN_ON_ONCE(force_immediate_exit);
	WARN_ON_ONCE(run_flags);

	/*
	 * Wait until retry of SEPT-zap-related SEAMCALL completes before
@@ -1048,7 +1048,7 @@ fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit)
	if (unlikely(READ_ONCE(to_kvm_tdx(vcpu->kvm)->wait_for_sept_zap)))
		return EXIT_FASTPATH_EXIT_HANDLED;

	trace_kvm_entry(vcpu, force_immediate_exit);
	trace_kvm_entry(vcpu, run_flags & KVM_RUN_FORCE_IMMEDIATE_EXIT);

	if (pi_test_on(&vt->pi_desc)) {
		apic->send_IPI_self(POSTED_INTR_VECTOR);
+2 −1
Original line number Diff line number Diff line
@@ -7323,8 +7323,9 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu,
	guest_state_exit_irqoff();
}

fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit)
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;

Loading