]> www.infradead.org Git - linux-platform-drivers-x86.git/commitdiff
x86/sev: Do RMP memory coverage check after max_pfn has been set
authorTom Lendacky <thomas.lendacky@amd.com>
Fri, 21 Jun 2024 15:42:05 +0000 (10:42 -0500)
committerBorislav Petkov (AMD) <bp@alien8.de>
Thu, 11 Jul 2024 10:03:23 +0000 (12:03 +0200)
The RMP table is probed early in the boot process before max_pfn has been
set, so the logic to check if the RMP covers all of system memory is not
valid.

Move the RMP memory coverage check from snp_probe_rmptable_info() into
snp_rmptable_init(), which is well after max_pfn has been set. Also, fix
the calculation to use PFN_UP instead of PHYS_PFN, in order to compute
the required RMP size properly.

Fixes: 216d106c7ff7 ("x86/sev: Add SEV-SNP host initialization support")
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/bec4364c7e34358cc576f01bb197a7796a109169.1718984524.git.thomas.lendacky@amd.com
arch/x86/virt/svm/sev.c

index 0ae10535c699982e15f20026a3e8012e52c41f32..0ce17766c0e5230821cd77cf430a838772cfe1f6 100644 (file)
@@ -120,7 +120,7 @@ static __init void snp_enable(void *arg)
 
 bool snp_probe_rmptable_info(void)
 {
-       u64 max_rmp_pfn, calc_rmp_sz, rmp_sz, rmp_base, rmp_end;
+       u64 rmp_sz, rmp_base, rmp_end;
 
        rdmsrl(MSR_AMD64_RMP_BASE, rmp_base);
        rdmsrl(MSR_AMD64_RMP_END, rmp_end);
@@ -137,28 +137,11 @@ bool snp_probe_rmptable_info(void)
 
        rmp_sz = rmp_end - rmp_base + 1;
 
-       /*
-        * Calculate the amount the memory that must be reserved by the BIOS to
-        * address the whole RAM, including the bookkeeping area. The RMP itself
-        * must also be covered.
-        */
-       max_rmp_pfn = max_pfn;
-       if (PHYS_PFN(rmp_end) > max_pfn)
-               max_rmp_pfn = PHYS_PFN(rmp_end);
-
-       calc_rmp_sz = (max_rmp_pfn << 4) + RMPTABLE_CPU_BOOKKEEPING_SZ;
-
-       if (calc_rmp_sz > rmp_sz) {
-               pr_err("Memory reserved for the RMP table does not cover full system RAM (expected 0x%llx got 0x%llx)\n",
-                      calc_rmp_sz, rmp_sz);
-               return false;
-       }
-
        probed_rmp_base = rmp_base;
        probed_rmp_size = rmp_sz;
 
        pr_info("RMP table physical range [0x%016llx - 0x%016llx]\n",
-               probed_rmp_base, probed_rmp_base + probed_rmp_size - 1);
+               rmp_base, rmp_end);
 
        return true;
 }
@@ -206,9 +189,8 @@ void __init snp_fixup_e820_tables(void)
  */
 static int __init snp_rmptable_init(void)
 {
+       u64 max_rmp_pfn, calc_rmp_sz, rmptable_size, rmp_end, val;
        void *rmptable_start;
-       u64 rmptable_size;
-       u64 val;
 
        if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
                return 0;
@@ -219,10 +201,28 @@ static int __init snp_rmptable_init(void)
        if (!probed_rmp_size)
                goto nosnp;
 
+       rmp_end = probed_rmp_base + probed_rmp_size - 1;
+
+       /*
+        * Calculate the amount the memory that must be reserved by the BIOS to
+        * address the whole RAM, including the bookkeeping area. The RMP itself
+        * must also be covered.
+        */
+       max_rmp_pfn = max_pfn;
+       if (PFN_UP(rmp_end) > max_pfn)
+               max_rmp_pfn = PFN_UP(rmp_end);
+
+       calc_rmp_sz = (max_rmp_pfn << 4) + RMPTABLE_CPU_BOOKKEEPING_SZ;
+       if (calc_rmp_sz > probed_rmp_size) {
+               pr_err("Memory reserved for the RMP table does not cover full system RAM (expected 0x%llx got 0x%llx)\n",
+                      calc_rmp_sz, probed_rmp_size);
+               goto nosnp;
+       }
+
        rmptable_start = memremap(probed_rmp_base, probed_rmp_size, MEMREMAP_WB);
        if (!rmptable_start) {
                pr_err("Failed to map RMP table\n");
-               return 1;
+               goto nosnp;
        }
 
        /*