mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Ashish Kalra <Ashish.Kalra@amd.com>
To: <tglx@kernel.org>, <mingo@redhat.com>, <bp@alien8.de>,
	<dave.hansen@linux.intel.com>, <x86@kernel.org>
Cc: <hpa@zytor.com>, <luto@kernel.org>, <peterz@infradead.org>,
	<ardb@kernel.org>, <rppt@kernel.org>, <akpm@linux-foundation.org>,
	<arnd@arndb.de>, <thomas.lendacky@amd.com>, <shivankg@amd.com>,
	<linux-kernel@vger.kernel.org>, <linux-coco@lists.linux.dev>
Subject: [PATCH] x86/sev: Apply the RMP table e820 fixups before memblock is populated
Date: Mon, 19 Oct 2026 18:47:24 +0000	[thread overview]
Message-ID: <20261019184724.358131-1-Ashish.Kalra@amd.com> (raw)

From: Ashish Kalra <ashish.kalra@amd.com>

When the start and/or end of the RMP table is not 2MB aligned,
snp_fixup_e820_tables() converts the 2MB chunk containing it from RAM to
reserved in the e820 tables, so that it is never used by the kernel (or
by a kexec-ed kernel) and SNP_INIT marks it HV-Fixed.

The fixups are done from mem_encrypt_setup_arch(), which runs after
max_pfn has been computed and after e820__memblock_setup() has populated
memblock from the e820 table. The RAM part of those chunks therefore
remains in memblock.memory. Commit 88a921aa3c6b ("x86/sev: Ensure that
RMP table fixups are reserved") dealt with one consequence of that, the
chunks still being allocatable, by additionally reserving them in
memblock, but memblock still describes them as memory.

That trips up the direct map setup. init_range_memory_mapping() maps the
memblock.memory ranges, so the RAM part of a chunk gets mapped. When a
subsequent, lower range is mapped, the trimming in phys_pmd_init() or
phys_pud_init() consults e820 instead, finds no RAM in the 2MB (or 1GB)
slot and clears the already populated entry. At boot this goes through
set_pmd_safe()/set_pud_safe() and triggers:

  SEV-SNP: RMP table physical range [0x000000bf77900000 - 0x000000c037efffff]
  SEV-SNP: Reserving start/end of RMP table on a 2MB boundary [0x000000bf77800000]
  SEV-SNP: Reserving start/end of RMP table on a 2MB boundary [0x000000c037e00000]
  ...
  init_memory_mapping: [mem 0xbf60000000-0xbf778fffff]
   [mem 0xbf60000000-0xbf777fffff] page 2M
   [mem 0xbf77800000-0xbf778fffff] page 4k
  init_memory_mapping: [mem 0xbf40000000-0xbf5fffffff] page 2M
  WARNING: arch/x86/mm/init_64.c:89 at phys_pmd_init+0x389/0x4b0, CPU#0: swapper/0
  Call Trace:
   phys_pud_init
   phys_p4d_init
   __kernel_physical_mapping_init
   init_memory_mapping
   init_range_memory_mapping
   init_mem_mapping
   setup_arch
   start_kernel

and leaks the page table page that hung off the cleared entry.

None of the fixups depend on memblock: the RMP table is probed and
CC_ATTR_HOST_SEV_SNP is set from early_cpu_init(), and the segmented RMP
case only needs early_memremap(). They do depend on the e820 tables,
which are only built in e820__memory_setup() (which also populates
e820_table_kexec), so the fixups cannot run any earlier than that.

Do the fixups in setup_arch() right after trim_bios_range() and before
max_pfn is computed, like the other e820 trimming done there, so that
max_pfn and memblock are derived from the final e820 table, and finalize
the table with e820__update_table(). The memblock reservation is then no
longer needed and is removed.

Fixes: 400fea4b9651 ("x86/sev: Add callback to apply RMP table fixups for kexec")
Co-developed-by: Shivank Garg <shivankg@amd.com>
Signed-off-by: Shivank Garg <shivankg@amd.com>
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
---
 arch/x86/kernel/setup.c   |  4 ++++
 arch/x86/mm/mem_encrypt.c |  7 -------
 arch/x86/virt/svm/sev.c   | 12 +++++++-----
 3 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index cda6adb9f69c..668230a0b01d 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -56,6 +56,7 @@
 #include <asm/prom.h>
 #include <asm/proto.h>
 #include <asm/realmode.h>
+#include <asm/sev.h>
 #include <asm/thermal.h>
 #include <asm/unwind.h>
 #include <asm/vsyscall.h>
@@ -1029,6 +1030,9 @@ void __init setup_arch(char **cmdline_p)
 
 	e820_add_kernel_range();
 	trim_bios_range();
+
+	/* Do the RMP table fixups before max_pfn and memblock use e820. */
+	snp_fixup_e820_tables();
 #ifdef CONFIG_X86_32
 	if (ppro_with_ram_bug()) {
 		pr_info("Applying PPro RAM bug workaround: punching 256 kB hole at 1.75 GB physical.\n");
diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c
index 95bae74fdab2..558e61a983c6 100644
--- a/arch/x86/mm/mem_encrypt.c
+++ b/arch/x86/mm/mem_encrypt.c
@@ -104,13 +104,6 @@ void __init mem_encrypt_setup_arch(void)
 	phys_addr_t total_mem = memblock_phys_mem_size();
 	unsigned long size;
 
-	/*
-	 * Do RMP table fixups after the e820 tables have been setup by
-	 * e820__memory_setup().
-	 */
-	if (cc_platform_has(CC_ATTR_HOST_SEV_SNP))
-		snp_fixup_e820_tables();
-
 	if (!cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
 		return;
 
diff --git a/arch/x86/virt/svm/sev.c b/arch/x86/virt/svm/sev.c
index bd70c4d0b774..7cd77cb06728 100644
--- a/arch/x86/virt/svm/sev.c
+++ b/arch/x86/virt/svm/sev.c
@@ -207,8 +207,6 @@ static void __init __snp_fixup_e820_tables(u64 pa)
 		pr_info("Reserving start/end of RMP table on a 2MB boundary [0x%016llx]\n", pa);
 		e820__range_update(pa, PMD_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED);
 		e820__range_update_table(e820_table_kexec, pa, PMD_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED);
-		if (!memblock_is_region_reserved(pa, PMD_SIZE))
-			memblock_reserve(pa, PMD_SIZE);
 	}
 }
 
@@ -261,11 +259,15 @@ static void __init fixup_e820_tables_for_contiguous_rmp(void)
 
 void __init snp_fixup_e820_tables(void)
 {
-	if (rmp_cfg & MSR_AMD64_SEG_RMP_ENABLED) {
+	if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
+		return;
+
+	if (rmp_cfg & MSR_AMD64_SEG_RMP_ENABLED)
 		fixup_e820_tables_for_segmented_rmp();
-	} else {
+	else
 		fixup_e820_tables_for_contiguous_rmp();
-	}
+
+	e820__update_table(e820_table);
 }
 
 static void clear_rmp(void)

base-commit: 250ee734115bca1c1f7a38d838909aa83cce87ae
-- 
2.43.0


                 reply	other threads:[~2026-10-19 18:47 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261019184724.358131-1-Ashish.Kalra@amd.com \
    --to=ashish.kalra@amd.com \
    --cc=akpm@linux-foundation.org \
    --cc=ardb@kernel.org \
    --cc=arnd@arndb.de \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=linux-coco@lists.linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rppt@kernel.org \
    --cc=shivankg@amd.com \
    --cc=tglx@kernel.org \
    --cc=thomas.lendacky@amd.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®