KVM: x86/mmu: Taking guest pa into consideration when calculate tdp level
authorXiaoyao Li <xiaoyao.li@intel.com>
Wed, 30 Oct 2024 19:00:38 +0000 (12:00 -0700)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 14 Mar 2025 18:20:51 +0000 (14:20 -0400)
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: Xiaoyao Li <xiaoyao.li@intel.com>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/cpuid.c
arch/x86/kvm/cpuid.h
arch/x86/kvm/mmu/mmu.c

index 45392cf42dbc5db8bbf38f8ea9468aa2c080404b..75a2f32eb26b204f3f18883a656f43d393377958 100644 (file)
@@ -463,6 +463,20 @@ not_found:
        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
index 69ae6768e830fe5d55efdfd2c6178af714741d9e..5c174421a4d977349c86dbfec483808b3d82744c 100644 (file)
@@ -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)
index 8160870398b9045998a18a92260657ae8bd2f700..a79bc15f31c6528051a6697237e72b91a4208bd0 100644 (file)
@@ -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;