Commit 3bf31b57 authored by Isaku Yamahata's avatar Isaku Yamahata Committed by Paolo Bonzini
Browse files

KVM: TDX: Handle TDX PV CPUID hypercall



Handle TDX PV CPUID hypercall for the CPUIDs virtualized by VMM
according to TDX Guest Host Communication Interface (GHCI).

For TDX, most CPUID leaf/sub-leaf combinations are virtualized by
the TDX module while some trigger #VE.  On #VE, TDX guest can issue
TDG.VP.VMCALL<INSTRUCTION.CPUID> (same value as EXIT_REASON_CPUID)
to request VMM to emulate CPUID operation.

Morph PV CPUID hypercall to EXIT_REASON_CPUID and wire up  to the KVM
backend function.

Suggested-by: default avatarSean Christopherson <seanjc@google.com>
Signed-off-by: default avatarIsaku Yamahata <isaku.yamahata@intel.com>
[binbin: rewrite changelog]
Signed-off-by: default avatarBinbin Wu <binbin.wu@linux.intel.com>
Message-ID: <20250227012021.1778144-6-binbin.wu@linux.intel.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 4b2abc49
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -844,6 +844,7 @@ int tdx_vcpu_pre_run(struct kvm_vcpu *vcpu)
static __always_inline u32 tdcall_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
{
	switch (tdvmcall_leaf(vcpu)) {
	case EXIT_REASON_CPUID:
	case EXIT_REASON_IO_INSTRUCTION:
		return tdvmcall_leaf(vcpu);
	case EXIT_REASON_EPT_VIOLATION:
@@ -1238,6 +1239,25 @@ static int tdx_report_fatal_error(struct kvm_vcpu *vcpu)
	return 0;
}

static int tdx_emulate_cpuid(struct kvm_vcpu *vcpu)
{
	u32 eax, ebx, ecx, edx;
	struct vcpu_tdx *tdx = to_tdx(vcpu);

	/* EAX and ECX for cpuid is stored in R12 and R13. */
	eax = tdx->vp_enter_args.r12;
	ecx = tdx->vp_enter_args.r13;

	kvm_cpuid(vcpu, &eax, &ebx, &ecx, &edx, false);

	tdx->vp_enter_args.r12 = eax;
	tdx->vp_enter_args.r13 = ebx;
	tdx->vp_enter_args.r14 = ecx;
	tdx->vp_enter_args.r15 = edx;

	return 1;
}

static int tdx_complete_pio_out(struct kvm_vcpu *vcpu)
{
	vcpu->arch.pio.count = 0;
@@ -1912,6 +1932,8 @@ int tdx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t fastpath)
	case EXIT_REASON_EXTERNAL_INTERRUPT:
		++vcpu->stat.irq_exits;
		return 1;
	case EXIT_REASON_CPUID:
		return tdx_emulate_cpuid(vcpu);
	case EXIT_REASON_TDCALL:
		return handle_tdvmcall(vcpu);
	case EXIT_REASON_VMCALL: