All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Pankaj Gupta" <pankaj.gupta@amd.com>,
	"Thomas Gleixner" <tglx@kernel.org>,
	"Ingo Molnar" <mingo@redhat.com>,
	"Borislav Petkov" <bp@alien8.de>,
	"Dave Hansen" <dave.hansen@linux.intel.com>,
	x86@kernel.org
Cc: "H . Peter Anvin" <hpa@zytor.com>,
	"Tom Lendacky" <thomas.lendacky@amd.com>,
	"Ard Biesheuvel" <ardb@kernel.org>,
	"Kiryl Shutsemau" <kas@kernel.org>,
	"Mike Rapoport" <rppt@kernel.org>,
	linux-mm@kvack.org
Subject: Re: [PATCH] x86/unaccepted_memory: Do not accept ranges that are no longer E820 RAM
Date: Tue, 03 Nov 2026 11:31:44 +0000	[thread overview]
Message-ID: <sashiko-outbox-195153@kernel.org> (raw)
In-Reply-To: <20261102113127.161823-1-pankaj.gupta@amd.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] x86/unaccepted_memory: arch_accept_memory() desynchronizes unaccepted bitmap
- [High] x86/unaccepted_memory: unaligned E820 bounds passed to __arch_accept_memory()
--

commit f56630bdf157fa53e09d29e75f1fc454adb6cd1e
Author: Pankaj Gupta <pankaj.gupta@amd.com>

x86/unaccepted_memory: Do not accept ranges that are no longer E820 RAM

This commit updates arch_accept_memory() on x86 to iterate over e820_table
and only accept subranges that are marked as E820_TYPE_RAM. This avoids
attempting to accept memory holes removed via the memmap= command-line
parameter.

> diff --git a/arch/x86/include/asm/unaccepted_memory.h b/arch/x86/include/asm/unaccepted_memory.h
> index f5937e9866ac1..744f1a993352c 100644
> --- a/arch/x86/include/asm/unaccepted_memory.h
> +++ b/arch/x86/include/asm/unaccepted_memory.h
> @@ -2,10 +2,11 @@
>  #define _ASM_X86_UNACCEPTED_MEMORY_H
>  
>  #include <linux/efi.h>
> +#include <asm/e820/api.h>
>  #include <asm/tdx.h>
>  #include <asm/sev.h>
>  
> -static inline void arch_accept_memory(phys_addr_t start, phys_addr_t end)
> +static inline void __arch_accept_memory(phys_addr_t start, phys_addr_t end)
>  {
>  	/* Platform-specific memory-acceptance call goes here */
>  	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) {
> @@ -18,6 +19,26 @@ static inline void arch_accept_memory(phys_addr_t start, phys_addr_t end)
>  	}
>  }
>  
> +static inline void arch_accept_memory(phys_addr_t start, phys_addr_t end)
> +{
> +	u32 i;
> +
> +	for (i = 0; i < e820_table->nr_entries; i++) {
> +		struct e820_entry *entry = &e820_table->entries[i];
> +		phys_addr_t s, e;
> +
> +		if (entry->type != E820_TYPE_RAM)
> +			continue;

[Severity: High]
Does skipping non-E820_TYPE_RAM ranges here desynchronize unaccepted->bitmap
from the actual hardware page acceptance state across kdump and kexec?

In drivers/firmware/efi/unaccepted_memory.c:accept_memory(), unit_size-aligned
range ends are extended by an extra unit_size to act as a guard page for
load_unaligned_zeropad(), and the bits in unaccepted->bitmap are cleared
unconditionally after arch_accept_memory() returns:

drivers/firmware/efi/unaccepted_memory.c:accept_memory() {
	...
	/*
	 * load_unaligned_zeropad() can lead to unwanted loads across page
	 * boundaries. The unwanted loads are typically harmless. Map an
	 * extra unit if the end of the requested range is aligned to
	 * unit_size to avoid page faults on unaccepted memory.
	 */
	if (!(end % unit_size))
		end += unit_size;
	...
		arch_accept_memory(phys_start, phys_end);

		spin_lock(&unaccepted_memory_lock);
		bitmap_clear(unaccepted->bitmap, range_start, len);
	...
}

When arch_accept_memory() skips a range that is not E820_TYPE_RAM in
e820_table, accept_memory() still clears its bit in unaccepted->bitmap even
though the pages were never accepted in hardware.

In a kdump kernel, e820_table only contains the crashkernel reservation as
E820_TYPE_RAM while the panicked kernel's remaining RAM is omitted from
e820_table. When the crash kernel accepts memory up to the 2 MiB-aligned end
of crashk_res, accept_memory() extends end by unit_size into the panicked
kernel's adjacent unaccepted RAM. arch_accept_memory() skips that range, but
accept_memory() clears its bit in unaccepted->bitmap. Later, when /proc/vmcore
is read, unaccepted_memory_vmcore_pfn_is_ram() checks
!pfn_is_unaccepted_memory(pfn), sees the cleared bit, and reads the
unaccepted page via read_from_oldmem(), crashing the kdump kernel.

A similar mismatch occurs with kexec: e820__memory_setup() populates
e820_table_kexec before parse_early_param() applies memmap= or mem= options
to e820_table, andarch/x86/kernel/kexec-bzimage64.c:setup_e820_entries()
passes e820_table_kexec to the next kernel while sharing the physical
efi.unaccepted table. Both kernel/kexec_core.c:sanity_check_segment_list()
(which calls accept_memory() on kexec segment destinations placed in
e820_table_kexec RAM) and the unit_size extension at the boundary before a
memmap= hole will clear bits in unaccepted->bitmap without accepting the
memory in hardware, causing the kexec load or the next kernel to fault on
those pages.

> +
> +		s = max_t(phys_addr_t, start, entry->addr);
> +		e = min_t(phys_addr_t, end, entry->addr + entry->size);
> +		if (s >= e)
> +			continue;
> +
> +		__arch_accept_memory(s, e);

[Severity: High]
What happens if entry->addr or entry->addr + entry->size is not aligned to
PAGE_SIZE?

Entries in e820_table can have byte-granular boundaries from firmware or
command-line options such as memmap= and mem=. When memblock is set up in
arch/x86/kernel/e820.c:e820__memblock_setup(), partial pages are trimmed via
memblock_trim_memory(PAGE_SIZE) and left unmapped in the direct map, whereas
e820_table retains the unaligned addresses.

Clamping s and e directly to entry->addr and entry->addr + entry->size can
therefore pass non-page-aligned boundaries to __arch_accept_memory(s, e):

1. On TDX, tdx_accept_memory() -> try_accept_one() requires start to be
   aligned to at least PG_LEVEL_4K and len to be at least PAGE_SIZE:

   arch/x86/coco/tdx/tdx-shared.c:try_accept_one() {
   	...
   	if (!IS_ALIGNED(start, accept_size))
   		return 0;

   	if (len < accept_size)
   		return 0;
   	...
   }

   An unaligned s or a trailing sub-page remainder causes tdx_accept_memory()
   to return false and __arch_accept_memory() to call
   panic("TDX: Failed to accept memory\n").

2. On SEV-SNP, snp_accept_memory() passes vaddr = (unsigned long)__va(start)
   and npages = (end - start) >> PAGE_SHIFT to set_pages_state(), which
   masks vaddr with PAGE_MASK. If s is not page-aligned, vaddr & PAGE_MASK
   rounds down into the unmapped partial page trimmed by
   memblock_trim_memory(PAGE_SIZE) and faults in pvalidate_pages(), while
   (e - s) >> PAGE_SHIFT can truncate npages and leave the last full page
   unaccepted.

Should s be rounded up with PAGE_ALIGN(s) and e rounded down with
PAGE_ALIGN_DOWN(e) before checking s >= e?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261102113127.161823-1-pankaj.gupta@amd.com?part=1


  parent reply	other threads:[~2026-11-03 11:31 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-02 11:31 [PATCH] x86/unaccepted_memory: Do not accept ranges that are no longer E820 RAM Pankaj Gupta
2026-11-02 11:41 ` Ard Biesheuvel
2026-11-02 11:51   ` Gupta, Pankaj
2026-11-02 12:01     ` Gupta, Pankaj
2026-11-02 12:11       ` Ard Biesheuvel
2026-11-03 11:31         ` Gupta, Pankaj
2026-11-03 11:31 ` sashiko-bot [this message]
2026-11-04 11:41   ` Gupta, Pankaj

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=sashiko-outbox-195153@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=ardb@kernel.org \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=kas@kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mingo@redhat.com \
    --cc=pankaj.gupta@amd.com \
    --cc=rppt@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.