Commit 0440feb0 authored by Tom Lendacky's avatar Tom Lendacky Committed by Borislav Petkov (AMD)

x86/sev: Do RMP memory coverage check after max_pfn has been set

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: 216d106c ("x86/sev: Add SEV-SNP host initialization support")
Signed-off-by: default avatarTom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/bec4364c7e34358cc576f01bb197a7796a109169.1718984524.git.thomas.lendacky@amd.com
parent 38918e0b
...@@ -120,7 +120,7 @@ static __init void snp_enable(void *arg) ...@@ -120,7 +120,7 @@ static __init void snp_enable(void *arg)
bool snp_probe_rmptable_info(void) 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_BASE, rmp_base);
rdmsrl(MSR_AMD64_RMP_END, rmp_end); rdmsrl(MSR_AMD64_RMP_END, rmp_end);
...@@ -137,28 +137,11 @@ bool snp_probe_rmptable_info(void) ...@@ -137,28 +137,11 @@ bool snp_probe_rmptable_info(void)
rmp_sz = rmp_end - rmp_base + 1; 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_base = rmp_base;
probed_rmp_size = rmp_sz; probed_rmp_size = rmp_sz;
pr_info("RMP table physical range [0x%016llx - 0x%016llx]\n", 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; return true;
} }
...@@ -206,9 +189,8 @@ void __init snp_fixup_e820_tables(void) ...@@ -206,9 +189,8 @@ void __init snp_fixup_e820_tables(void)
*/ */
static int __init snp_rmptable_init(void) static int __init snp_rmptable_init(void)
{ {
u64 max_rmp_pfn, calc_rmp_sz, rmptable_size, rmp_end, val;
void *rmptable_start; void *rmptable_start;
u64 rmptable_size;
u64 val;
if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP)) if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
return 0; return 0;
...@@ -219,10 +201,28 @@ static int __init snp_rmptable_init(void) ...@@ -219,10 +201,28 @@ static int __init snp_rmptable_init(void)
if (!probed_rmp_size) if (!probed_rmp_size)
goto nosnp; 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); rmptable_start = memremap(probed_rmp_base, probed_rmp_size, MEMREMAP_WB);
if (!rmptable_start) { if (!rmptable_start) {
pr_err("Failed to map RMP table\n"); pr_err("Failed to map RMP table\n");
return 1; goto nosnp;
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment