Commit 20d91372 authored by Xiaoyao Li's avatar Xiaoyao Li Committed by Paolo Bonzini
Browse files

KVM: x86/mmu: Taking guest pa into consideration when calculate tdp level



For TDX, the maxpa (CPUID.0x80000008.EAX[7:0]) is fixed as native and
the max_gpa (CPUID.0x80000008.EAX[23:16]) is configurable and used
to configure the EPT level and GPAW.

Use max_gpa to determine the TDP level.

Signed-off-by: default avatarXiaoyao Li <xiaoyao.li@intel.com>
Signed-off-by: default avatarRick Edgecombe <rick.p.edgecombe@intel.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 488808e6
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -463,6 +463,20 @@ int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu)
	return 36;
}

int cpuid_query_maxguestphyaddr(struct kvm_vcpu *vcpu)
{
	struct kvm_cpuid_entry2 *best;

	best = kvm_find_cpuid_entry(vcpu, 0x80000000);
	if (!best || best->eax < 0x80000008)
		goto not_found;
	best = kvm_find_cpuid_entry(vcpu, 0x80000008);
	if (best)
		return (best->eax >> 16) & 0xff;
not_found:
	return 0;
}

/*
 * This "raw" version returns the reserved GPA bits without any adjustments for
 * encryption technologies that usurp bits.  The raw mask should be used if and
+1 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ void __init kvm_init_xstate_sizes(void);
u32 xstate_required_size(u64 xstate_bv, bool compacted);

int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu);
int cpuid_query_maxguestphyaddr(struct kvm_vcpu *vcpu);
u64 kvm_vcpu_reserved_gpa_bits_raw(struct kvm_vcpu *vcpu);

static inline int cpuid_maxphyaddr(struct kvm_vcpu *vcpu)
+8 −1
Original line number Diff line number Diff line
@@ -5416,12 +5416,19 @@ void __kvm_mmu_refresh_passthrough_bits(struct kvm_vcpu *vcpu,

static inline int kvm_mmu_get_tdp_level(struct kvm_vcpu *vcpu)
{
	int maxpa;

	if (vcpu->kvm->arch.vm_type == KVM_X86_TDX_VM)
		maxpa = cpuid_query_maxguestphyaddr(vcpu);
	else
		maxpa = cpuid_maxphyaddr(vcpu);

	/* tdp_root_level is architecture forced level, use it if nonzero */
	if (tdp_root_level)
		return tdp_root_level;

	/* Use 5-level TDP if and only if it's useful/necessary. */
	if (max_tdp_level == 5 && cpuid_maxphyaddr(vcpu) <= 48)
	if (max_tdp_level == 5 && maxpa <= 48)
		return 4;

	return max_tdp_level;