]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: selftests: x86: Prioritize getting max_gfn from GuestPhysBits
authorTao Su <tao1.su@linux.intel.com>
Mon, 13 May 2024 01:40:03 +0000 (09:40 +0800)
committerSean Christopherson <seanjc@google.com>
Wed, 5 Jun 2024 13:16:10 +0000 (06:16 -0700)
Use the max mappable GPA via GuestPhysBits advertised by KVM to calculate
max_gfn. Currently some selftests (e.g. access_tracking_perf_test,
dirty_log_test...) add RAM regions close to max_gfn, so guest may access
GPA beyond its mappable range and cause infinite loop.

Adjust max_gfn in vm_compute_max_gfn() since x86 selftests already
overrides vm_compute_max_gfn() specifically to deal with goofy edge cases.

Reported-by: Yi Lai <yi1.lai@intel.com>
Signed-off-by: Tao Su <tao1.su@linux.intel.com>
Tested-by: Yi Lai <yi1.lai@intel.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Link: https://lore.kernel.org/r/20240513014003.104593-1-tao1.su@linux.intel.com
[sean: tweak name, add comment and sanity check]
Signed-off-by: Sean Christopherson <seanjc@google.com>
tools/testing/selftests/kvm/include/x86_64/processor.h
tools/testing/selftests/kvm/lib/x86_64/processor.c

index 8eb57de0b5876db37d79508f28d1cee3c205df1b..c0c7c1fe93f987a83ab366416b011a78641deed6 100644 (file)
@@ -277,6 +277,7 @@ struct kvm_x86_cpu_property {
 #define X86_PROPERTY_MAX_EXT_LEAF              KVM_X86_CPU_PROPERTY(0x80000000, 0, EAX, 0, 31)
 #define X86_PROPERTY_MAX_PHY_ADDR              KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 0, 7)
 #define X86_PROPERTY_MAX_VIRT_ADDR             KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 8, 15)
+#define X86_PROPERTY_GUEST_MAX_PHY_ADDR                KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 16, 23)
 #define X86_PROPERTY_SEV_C_BIT                 KVM_X86_CPU_PROPERTY(0x8000001F, 0, EBX, 0, 5)
 #define X86_PROPERTY_PHYS_ADDR_REDUCTION       KVM_X86_CPU_PROPERTY(0x8000001F, 0, EBX, 6, 11)
 
index c664e446136bc6eb02dd2d9101c885cb1dad85d4..594b061aef52174186b81d9f2c243d5aa000d7ad 100644 (file)
@@ -1247,9 +1247,20 @@ unsigned long vm_compute_max_gfn(struct kvm_vm *vm)
 {
        const unsigned long num_ht_pages = 12 << (30 - vm->page_shift); /* 12 GiB */
        unsigned long ht_gfn, max_gfn, max_pfn;
-       uint8_t maxphyaddr;
+       uint8_t maxphyaddr, guest_maxphyaddr;
 
-       max_gfn = (1ULL << (vm->pa_bits - vm->page_shift)) - 1;
+       /*
+        * Use "guest MAXPHYADDR" from KVM if it's available.  Guest MAXPHYADDR
+        * enumerates the max _mappable_ GPA, which can be less than the raw
+        * MAXPHYADDR, e.g. if MAXPHYADDR=52, KVM is using TDP, and the CPU
+        * doesn't support 5-level TDP.
+        */
+       guest_maxphyaddr = kvm_cpu_property(X86_PROPERTY_GUEST_MAX_PHY_ADDR);
+       guest_maxphyaddr = guest_maxphyaddr ?: vm->pa_bits;
+       TEST_ASSERT(guest_maxphyaddr <= vm->pa_bits,
+                   "Guest MAXPHYADDR should never be greater than raw MAXPHYADDR");
+
+       max_gfn = (1ULL << (guest_maxphyaddr - vm->page_shift)) - 1;
 
        /* Avoid reserved HyperTransport region on AMD processors.  */
        if (!host_cpu_is_amd)