linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] efi: Fix alignenment issues in unaccepted memory code
@ 2026-02-13 15:48 Kiryl Shutsemau (Meta)
  2026-02-13 15:48 ` [PATCH 1/2] efi: Fix reservation of unaccepted memory table Kiryl Shutsemau (Meta)
  2026-02-13 15:48 ` [PATCH 2/2] efi: Align unaccepted memory range to page boundary Kiryl Shutsemau (Meta)
  0 siblings, 2 replies; 14+ messages in thread
From: Kiryl Shutsemau (Meta) @ 2026-02-13 15:48 UTC (permalink / raw)
  To: Ard Biesheuvel, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, Tom Lendacky
  Cc: x86, linux-efi, linux-mm, linux-kernel, Moritz Sanft,
	Kiryl Shutsemau (Meta)

This series addresses two issues related to unaligned physical addresses
and sizes when handling EFI unaccepted memory. These issues were
identified as potential sources of kernel panics in Intel TDX
environments due to incomplete memory reservation or missing "guard page"
extensions.

The first patch fixes the reservation of the unaccepted memory table
itself in efi_config_parse_tables(). It ensures the entire page range
covering the table is reserved even if the table doesn't start on a
page boundary.

The second patch ensures that memory acceptance requests in
accept_memory() and range_contains_unaccepted_memory() are page-aligned
before performing the unit_size alignment check. This prevents skipping
the necessary "guard page" extension for unaligned ranges, which is
required to avoid crashes with load_unaligned_zeropad().

Kiryl Shutsemau (Meta) (2):
  efi: Fix reservation of unaccepted memory table
  efi: Align unaccepted memory range to page boundary

 drivers/firmware/efi/efi.c               |  8 ++++----
 drivers/firmware/efi/unaccepted_memory.c | 12 ++++++++++--
 2 files changed, 14 insertions(+), 6 deletions(-)

-- 
2.51.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/2] efi: Fix reservation of unaccepted memory table
  2026-02-13 15:48 [PATCH 0/2] efi: Fix alignenment issues in unaccepted memory code Kiryl Shutsemau (Meta)
@ 2026-02-13 15:48 ` Kiryl Shutsemau (Meta)
  2026-02-13 16:01   ` Dave Hansen
  2026-02-13 15:48 ` [PATCH 2/2] efi: Align unaccepted memory range to page boundary Kiryl Shutsemau (Meta)
  1 sibling, 1 reply; 14+ messages in thread
From: Kiryl Shutsemau (Meta) @ 2026-02-13 15:48 UTC (permalink / raw)
  To: Ard Biesheuvel, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, Tom Lendacky
  Cc: x86, linux-efi, linux-mm, linux-kernel, Moritz Sanft,
	Kiryl Shutsemau (Meta)

The reserve_unaccepted() function incorrectly calculates the size of the
memblock reservation for the unaccepted memory table. It aligns the
size of the table, but fails to account for cases where the table's
starting physical address (efi.unaccepted) is not page-aligned.

If the table starts at an offset within a page and its end crosses into
a subsequent page that the aligned size does not cover, the end of the
table will not be reserved. This can lead to the table being overwritten
or inaccessible, causing a kernel panic in accept_memory().

This issue was observed when starting Intel TDX VMs with specific memory
sizes (e.g., > 64GB).

Fix this by calculating the end address first (including the unaligned
start) and then aligning it up, ensuring the entire range is covered
by the reservation.

Fixes: 8dbe33956d96 ("efi/unaccepted: Make sure unaccepted table is mapped")
Reported-by: Moritz Sanft <ms@edgeless.systems>
Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
---
 drivers/firmware/efi/efi.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 111e87a618e5..56e9d73412fa 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -692,13 +692,13 @@ static __init int match_config_table(const efi_guid_t *guid,
 
 static __init void reserve_unaccepted(struct efi_unaccepted_memory *unaccepted)
 {
-	phys_addr_t start, size;
+	phys_addr_t start, end;
 
 	start = PAGE_ALIGN_DOWN(efi.unaccepted);
-	size = PAGE_ALIGN(sizeof(*unaccepted) + unaccepted->size);
+	end = PAGE_ALIGN(efi.unaccepted + sizeof(*unaccepted) + unaccepted->size);
 
-	memblock_add(start, size);
-	memblock_reserve(start, size);
+	memblock_add(start, end - start);
+	memblock_reserve(start, end - start);
 }
 
 int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
-- 
2.51.2



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 2/2] efi: Align unaccepted memory range to page boundary
  2026-02-13 15:48 [PATCH 0/2] efi: Fix alignenment issues in unaccepted memory code Kiryl Shutsemau (Meta)
  2026-02-13 15:48 ` [PATCH 1/2] efi: Fix reservation of unaccepted memory table Kiryl Shutsemau (Meta)
@ 2026-02-13 15:48 ` Kiryl Shutsemau (Meta)
  2026-02-16 14:51   ` Tom Lendacky
  1 sibling, 1 reply; 14+ messages in thread
From: Kiryl Shutsemau (Meta) @ 2026-02-13 15:48 UTC (permalink / raw)
  To: Ard Biesheuvel, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, Tom Lendacky
  Cc: x86, linux-efi, linux-mm, linux-kernel, Moritz Sanft,
	Kiryl Shutsemau (Meta)

The accept_memory() and range_contains_unaccepted_memory() functions
employ a "guard page" logic to prevent crashes with load_unaligned_zeropad().
This logic extends the range to be accepted (or checked) by one unit_size
if the end of the range is aligned to a unit_size boundary.

However, if the caller passes a range that is not page-aligned, the
'end' of the range might not be numerically aligned to unit_size, even
if it covers the last page of a unit. This causes the "if (!(end % unit_size))"
check to fail, skipping the necessary extension and leaving the next
unit unaccepted, which can lead to a kernel panic when accessed by
load_unaligned_zeropad().

Align the start address down and the size up to the nearest page
boundary before performing the unit_size alignment check. This ensures
that the guard unit is correctly added when the range effectively ends
on a unit boundary.

Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
---
 drivers/firmware/efi/unaccepted_memory.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/efi/unaccepted_memory.c b/drivers/firmware/efi/unaccepted_memory.c
index c2c067eff634..9ddf3dedd514 100644
--- a/drivers/firmware/efi/unaccepted_memory.c
+++ b/drivers/firmware/efi/unaccepted_memory.c
@@ -35,14 +35,18 @@ void accept_memory(phys_addr_t start, unsigned long size)
 	struct efi_unaccepted_memory *unaccepted;
 	unsigned long range_start, range_end;
 	struct accept_range range, *entry;
-	phys_addr_t end = start + size;
 	unsigned long flags;
+	phys_addr_t end;
 	u64 unit_size;
 
 	unaccepted = efi_get_unaccepted_table();
 	if (!unaccepted)
 		return;
 
+	start = PAGE_ALIGN_DOWN(start);
+	size = PAGE_ALIGN(size);
+	end = start + size;
+
 	unit_size = unaccepted->unit_size;
 
 	/*
@@ -160,15 +164,19 @@ void accept_memory(phys_addr_t start, unsigned long size)
 bool range_contains_unaccepted_memory(phys_addr_t start, unsigned long size)
 {
 	struct efi_unaccepted_memory *unaccepted;
-	phys_addr_t end = start + size;
 	unsigned long flags;
 	bool ret = false;
+	phys_addr_t end;
 	u64 unit_size;
 
 	unaccepted = efi_get_unaccepted_table();
 	if (!unaccepted)
 		return false;
 
+	start = PAGE_ALIGN_DOWN(start);
+	size = PAGE_ALIGN(size);
+	end = start + size;
+
 	unit_size = unaccepted->unit_size;
 
 	/*
-- 
2.51.2



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] efi: Fix reservation of unaccepted memory table
  2026-02-13 15:48 ` [PATCH 1/2] efi: Fix reservation of unaccepted memory table Kiryl Shutsemau (Meta)
@ 2026-02-13 16:01   ` Dave Hansen
  2026-02-13 16:14     ` Kiryl Shutsemau
  0 siblings, 1 reply; 14+ messages in thread
From: Dave Hansen @ 2026-02-13 16:01 UTC (permalink / raw)
  To: Kiryl Shutsemau (Meta),
	Ard Biesheuvel, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, Tom Lendacky
  Cc: x86, linux-efi, linux-mm, linux-kernel, Moritz Sanft

On 2/13/26 07:48, Kiryl Shutsemau (Meta) wrote:
>  static __init void reserve_unaccepted(struct efi_unaccepted_memory *unaccepted)
>  {
> -	phys_addr_t start, size;
> +	phys_addr_t start, end;
>  
>  	start = PAGE_ALIGN_DOWN(efi.unaccepted);

Why are we even aligning the start? Isn't *that* the bug?

The memblock code seems to be able to handle arbitrary alignment just fine.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] efi: Fix reservation of unaccepted memory table
  2026-02-13 16:01   ` Dave Hansen
@ 2026-02-13 16:14     ` Kiryl Shutsemau
  2026-02-13 16:46       ` Dave Hansen
  0 siblings, 1 reply; 14+ messages in thread
From: Kiryl Shutsemau @ 2026-02-13 16:14 UTC (permalink / raw)
  To: Dave Hansen
  Cc: Ard Biesheuvel, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, Tom Lendacky, x86, linux-efi, linux-mm,
	linux-kernel, Moritz Sanft

On Fri, Feb 13, 2026 at 08:01:55AM -0800, Dave Hansen wrote:
> On 2/13/26 07:48, Kiryl Shutsemau (Meta) wrote:
> >  static __init void reserve_unaccepted(struct efi_unaccepted_memory *unaccepted)
> >  {
> > -	phys_addr_t start, size;
> > +	phys_addr_t start, end;
> >  
> >  	start = PAGE_ALIGN_DOWN(efi.unaccepted);
> 
> Why are we even aligning the start? Isn't *that* the bug?

How so? It is up to EFI how the table is allocated. We need to be sure
that this memory is mapped and not overwritten.

> The memblock code seems to be able to handle arbitrary alignment just fine.

Memblock will track it, but, as the comment says, anything smaller than
page size will not be mapped, but we need the table to be accessible by
kernel.

-- 
  Kiryl Shutsemau / Kirill A. Shutemov


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] efi: Fix reservation of unaccepted memory table
  2026-02-13 16:14     ` Kiryl Shutsemau
@ 2026-02-13 16:46       ` Dave Hansen
  2026-02-13 17:20         ` Kiryl Shutsemau
  0 siblings, 1 reply; 14+ messages in thread
From: Dave Hansen @ 2026-02-13 16:46 UTC (permalink / raw)
  To: Kiryl Shutsemau
  Cc: Ard Biesheuvel, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, Tom Lendacky, x86, linux-efi, linux-mm,
	linux-kernel, Moritz Sanft

On 2/13/26 08:14, Kiryl Shutsemau wrote:
>> The memblock code seems to be able to handle arbitrary alignment just fine.
> Memblock will track it, but, as the comment says, anything smaller than
> page size will not be mapped, but we need the table to be accessible by
> kernel.

That seems really, really fragile.

We should first make sure this is intentional memblock behavior and not
a bug before we go add more hacks on top of it.

Why would you even present a byte-level reservation interface if it is
free to just silently ignore some of the ranges by rounding them off later?


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] efi: Fix reservation of unaccepted memory table
  2026-02-13 16:46       ` Dave Hansen
@ 2026-02-13 17:20         ` Kiryl Shutsemau
  2026-02-14 15:51           ` Mike Rapoport
  0 siblings, 1 reply; 14+ messages in thread
From: Kiryl Shutsemau @ 2026-02-13 17:20 UTC (permalink / raw)
  To: Dave Hansen, Mike Rapoport
  Cc: Ard Biesheuvel, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, Tom Lendacky, x86, linux-efi, linux-mm,
	linux-kernel, Moritz Sanft

On Fri, Feb 13, 2026 at 08:46:55AM -0800, Dave Hansen wrote:
> On 2/13/26 08:14, Kiryl Shutsemau wrote:
> >> The memblock code seems to be able to handle arbitrary alignment just fine.
> > Memblock will track it, but, as the comment says, anything smaller than
> > page size will not be mapped, but we need the table to be accessible by
> > kernel.
> 
> That seems really, really fragile.
> 
> We should first make sure this is intentional memblock behavior and not
> a bug before we go add more hacks on top of it.
> 
> Why would you even present a byte-level reservation interface if it is
> free to just silently ignore some of the ranges by rounding them off later?

+Mike.

My guess that multiple memblock_add() calls might add up to the full
page size.

-- 
  Kiryl Shutsemau / Kirill A. Shutemov


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] efi: Fix reservation of unaccepted memory table
  2026-02-13 17:20         ` Kiryl Shutsemau
@ 2026-02-14 15:51           ` Mike Rapoport
  2026-02-16 14:22             ` Kiryl Shutsemau
  2026-02-16 15:53             ` Dave Hansen
  0 siblings, 2 replies; 14+ messages in thread
From: Mike Rapoport @ 2026-02-14 15:51 UTC (permalink / raw)
  To: Kiryl Shutsemau
  Cc: Dave Hansen, Ard Biesheuvel, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, Tom Lendacky, x86, linux-efi,
	linux-mm, linux-kernel, Moritz Sanft

On Fri, Feb 13, 2026 at 05:20:14PM +0000, Kiryl Shutsemau wrote:
> On Fri, Feb 13, 2026 at 08:46:55AM -0800, Dave Hansen wrote:
> > On 2/13/26 08:14, Kiryl Shutsemau wrote:
> > >> The memblock code seems to be able to handle arbitrary alignment just fine.
> > > Memblock will track it, but, as the comment says, anything smaller than
> > > page size will not be mapped, but we need the table to be accessible by
> > > kernel.
> > 
> > That seems really, really fragile.
> > 
> > We should first make sure this is intentional memblock behavior and not
> > a bug before we go add more hacks on top of it.
> > 
> > Why would you even present a byte-level reservation interface if it is
> > free to just silently ignore some of the ranges by rounding them off later?

Heh, it's x86's choice of memblock iterator that's rounding the ranges ;)

Maybe I miss some context, but my understanding is that for crash kernels
the unaccepted table is E820_TYPE_RESERVED and those are never added to
memblock.memory by e820 code, hence the call to memblock_add() in
reserve_unaccepted().

When x86 creates page tables, init_range_memory_mapping() walks
memblock.memory with for_each_mem_pfn_range() that rounds ranges that are
not page-aligned, which is normally fine, because it would mean that we
miss some partial pages that are divided between E820_RAM and
E820_SOMETHING_ELSE.

And Kiryl's intention to round up unaccepted to page boundary seems correct
to me.

> My guess that multiple memblock_add() calls might add up to the full
> page size.

I'm not following here. Can you explain what do you mean?

Multiple memblock_add() calls to adjacent ranges will coalesce into one
larger range. But I don't see how is that related.

> 
> -- 
>   Kiryl Shutsemau / Kirill A. Shutemov

-- 
Sincerely yours,
Mike.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] efi: Fix reservation of unaccepted memory table
  2026-02-14 15:51           ` Mike Rapoport
@ 2026-02-16 14:22             ` Kiryl Shutsemau
  2026-02-16 14:51               ` Mike Rapoport
  2026-02-16 15:53             ` Dave Hansen
  1 sibling, 1 reply; 14+ messages in thread
From: Kiryl Shutsemau @ 2026-02-16 14:22 UTC (permalink / raw)
  To: Mike Rapoport
  Cc: Dave Hansen, Ard Biesheuvel, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, Tom Lendacky, x86, linux-efi,
	linux-mm, linux-kernel, Moritz Sanft

On Sat, Feb 14, 2026 at 05:51:47PM +0200, Mike Rapoport wrote:
> > My guess that multiple memblock_add() calls might add up to the full
> > page size.
> 
> I'm not following here. Can you explain what do you mean?
> 
> Multiple memblock_add() calls to adjacent ranges will coalesce into one
> larger range. But I don't see how is that related.

I tried to find justification for the byte-level tracking by memblock.
Not in relation to this case, but in general.

-- 
  Kiryl Shutsemau / Kirill A. Shutemov


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/2] efi: Align unaccepted memory range to page boundary
  2026-02-13 15:48 ` [PATCH 2/2] efi: Align unaccepted memory range to page boundary Kiryl Shutsemau (Meta)
@ 2026-02-16 14:51   ` Tom Lendacky
  2026-02-16 15:33     ` Kiryl Shutsemau
  0 siblings, 1 reply; 14+ messages in thread
From: Tom Lendacky @ 2026-02-16 14:51 UTC (permalink / raw)
  To: Kiryl Shutsemau (Meta),
	Ard Biesheuvel, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen
  Cc: x86, linux-efi, linux-mm, linux-kernel, Moritz Sanft

On 2/13/26 09:48, Kiryl Shutsemau (Meta) wrote:
> The accept_memory() and range_contains_unaccepted_memory() functions
> employ a "guard page" logic to prevent crashes with load_unaligned_zeropad().
> This logic extends the range to be accepted (or checked) by one unit_size
> if the end of the range is aligned to a unit_size boundary.
> 
> However, if the caller passes a range that is not page-aligned, the
> 'end' of the range might not be numerically aligned to unit_size, even
> if it covers the last page of a unit. This causes the "if (!(end % unit_size))"
> check to fail, skipping the necessary extension and leaving the next
> unit unaccepted, which can lead to a kernel panic when accessed by
> load_unaligned_zeropad().
> 
> Align the start address down and the size up to the nearest page
> boundary before performing the unit_size alignment check. This ensures
> that the guard unit is correctly added when the range effectively ends
> on a unit boundary.
> 
> Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
> ---
>  drivers/firmware/efi/unaccepted_memory.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/firmware/efi/unaccepted_memory.c b/drivers/firmware/efi/unaccepted_memory.c
> index c2c067eff634..9ddf3dedd514 100644
> --- a/drivers/firmware/efi/unaccepted_memory.c
> +++ b/drivers/firmware/efi/unaccepted_memory.c
> @@ -35,14 +35,18 @@ void accept_memory(phys_addr_t start, unsigned long size)
>  	struct efi_unaccepted_memory *unaccepted;
>  	unsigned long range_start, range_end;
>  	struct accept_range range, *entry;
> -	phys_addr_t end = start + size;
>  	unsigned long flags;
> +	phys_addr_t end;
>  	u64 unit_size;
>  
>  	unaccepted = efi_get_unaccepted_table();
>  	if (!unaccepted)
>  		return;
>  
> +	start = PAGE_ALIGN_DOWN(start);
> +	size = PAGE_ALIGN(size);
> +	end = start + size;

Should this really be:

	end = PAGE_ALIGN(start + size);
	start = PAGE_ALIGN_DOWN(start);

?

Thanks,
Tom

> +
>  	unit_size = unaccepted->unit_size;
>  
>  	/*
> @@ -160,15 +164,19 @@ void accept_memory(phys_addr_t start, unsigned long size)
>  bool range_contains_unaccepted_memory(phys_addr_t start, unsigned long size)
>  {
>  	struct efi_unaccepted_memory *unaccepted;
> -	phys_addr_t end = start + size;
>  	unsigned long flags;
>  	bool ret = false;
> +	phys_addr_t end;
>  	u64 unit_size;
>  
>  	unaccepted = efi_get_unaccepted_table();
>  	if (!unaccepted)
>  		return false;
>  
> +	start = PAGE_ALIGN_DOWN(start);
> +	size = PAGE_ALIGN(size);
> +	end = start + size;
> +
>  	unit_size = unaccepted->unit_size;
>  
>  	/*



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] efi: Fix reservation of unaccepted memory table
  2026-02-16 14:22             ` Kiryl Shutsemau
@ 2026-02-16 14:51               ` Mike Rapoport
  0 siblings, 0 replies; 14+ messages in thread
From: Mike Rapoport @ 2026-02-16 14:51 UTC (permalink / raw)
  To: Kiryl Shutsemau
  Cc: Dave Hansen, Ard Biesheuvel, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, Tom Lendacky, x86, linux-efi,
	linux-mm, linux-kernel, Moritz Sanft

On Mon, Feb 16, 2026 at 02:22:49PM +0000, Kiryl Shutsemau wrote:
> On Sat, Feb 14, 2026 at 05:51:47PM +0200, Mike Rapoport wrote:
> > > My guess that multiple memblock_add() calls might add up to the full
> > > page size.
> > 
> > I'm not following here. Can you explain what do you mean?
> > 
> > Multiple memblock_add() calls to adjacent ranges will coalesce into one
> > larger range. But I don't see how is that related.
> 
> I tried to find justification for the byte-level tracking by memblock.
> Not in relation to this case, but in general.

Probably somewhere deep in git archaeology :)

I presume to not waste a page for every small allocation.
 
> -- 
>   Kiryl Shutsemau / Kirill A. Shutemov

-- 
Sincerely yours,
Mike.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/2] efi: Align unaccepted memory range to page boundary
  2026-02-16 14:51   ` Tom Lendacky
@ 2026-02-16 15:33     ` Kiryl Shutsemau
  0 siblings, 0 replies; 14+ messages in thread
From: Kiryl Shutsemau @ 2026-02-16 15:33 UTC (permalink / raw)
  To: Tom Lendacky
  Cc: Ard Biesheuvel, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, x86, linux-efi, linux-mm, linux-kernel,
	Moritz Sanft

On Mon, Feb 16, 2026 at 08:51:17AM -0600, Tom Lendacky wrote:
> On 2/13/26 09:48, Kiryl Shutsemau (Meta) wrote:
> > The accept_memory() and range_contains_unaccepted_memory() functions
> > employ a "guard page" logic to prevent crashes with load_unaligned_zeropad().
> > This logic extends the range to be accepted (or checked) by one unit_size
> > if the end of the range is aligned to a unit_size boundary.
> > 
> > However, if the caller passes a range that is not page-aligned, the
> > 'end' of the range might not be numerically aligned to unit_size, even
> > if it covers the last page of a unit. This causes the "if (!(end % unit_size))"
> > check to fail, skipping the necessary extension and leaving the next
> > unit unaccepted, which can lead to a kernel panic when accessed by
> > load_unaligned_zeropad().
> > 
> > Align the start address down and the size up to the nearest page
> > boundary before performing the unit_size alignment check. This ensures
> > that the guard unit is correctly added when the range effectively ends
> > on a unit boundary.
> > 
> > Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
> > ---
> >  drivers/firmware/efi/unaccepted_memory.c | 12 ++++++++++--
> >  1 file changed, 10 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/firmware/efi/unaccepted_memory.c b/drivers/firmware/efi/unaccepted_memory.c
> > index c2c067eff634..9ddf3dedd514 100644
> > --- a/drivers/firmware/efi/unaccepted_memory.c
> > +++ b/drivers/firmware/efi/unaccepted_memory.c
> > @@ -35,14 +35,18 @@ void accept_memory(phys_addr_t start, unsigned long size)
> >  	struct efi_unaccepted_memory *unaccepted;
> >  	unsigned long range_start, range_end;
> >  	struct accept_range range, *entry;
> > -	phys_addr_t end = start + size;
> >  	unsigned long flags;
> > +	phys_addr_t end;
> >  	u64 unit_size;
> >  
> >  	unaccepted = efi_get_unaccepted_table();
> >  	if (!unaccepted)
> >  		return;
> >  
> > +	start = PAGE_ALIGN_DOWN(start);
> > +	size = PAGE_ALIGN(size);
> > +	end = start + size;
> 
> Should this really be:
> 
> 	end = PAGE_ALIGN(start + size);
> 	start = PAGE_ALIGN_DOWN(start);
> 
> ?

Doh! Yes, you are right.

-- 
  Kiryl Shutsemau / Kirill A. Shutemov


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] efi: Fix reservation of unaccepted memory table
  2026-02-14 15:51           ` Mike Rapoport
  2026-02-16 14:22             ` Kiryl Shutsemau
@ 2026-02-16 15:53             ` Dave Hansen
  2026-02-16 16:19               ` Mike Rapoport
  1 sibling, 1 reply; 14+ messages in thread
From: Dave Hansen @ 2026-02-16 15:53 UTC (permalink / raw)
  To: Mike Rapoport, Kiryl Shutsemau
  Cc: Ard Biesheuvel, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, Tom Lendacky, x86, linux-efi, linux-mm,
	linux-kernel, Moritz Sanft

On 2/14/26 07:51, Mike Rapoport wrote:
> Heh, it's x86's choice of memblock iterator that's rounding the ranges 😉

Ahh, good point. I was just assuming that the memblock iteration _had_
to be over PFNs. Silly me.

> Maybe I miss some context, but my understanding is that for crash kernels
> the unaccepted table is E820_TYPE_RESERVED and those are never added to
> memblock.memory by e820 code, hence the call to memblock_add() in
> reserve_unaccepted().
> 
> When x86 creates page tables, init_range_memory_mapping() walks
> memblock.memory with for_each_mem_pfn_range() that rounds ranges that are
> not page-aligned, which is normally fine, because it would mean that we
> miss some partial pages that are divided between E820_RAM and
> E820_SOMETHING_ELSE.
> 
> And Kiryl's intention to round up unaccepted to page boundary seems correct
> to me.

It fixes the bug for sure.

I'm more worried about the next feature, or the existing features that
also only working because memory is page-aligned somewhere (even though
it isn't guaranteed to remain that way).

There are two choices for fixing this: One, we do Kiryl's fix plus
checks to ensure that all the memblocks that generate direct mappings
(is it _just_ the "memory" type?) are padded out to page-aligned boundaries.

The other alternative is to do for_each_mem_range() and do the padding
universally when creating the mappings. Maybe _also_ with warnings or
maybe a pr_debug().

I do still think it's a little wonky for memblock_add()'s management of
the "memory" type to allow unaligned arguments when that type is also
used to create page-aligned mapping structures. Memblocks themselves
obviously need to be byte-level, but I'm not sure it's the right thing
for the "memory" type API.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] efi: Fix reservation of unaccepted memory table
  2026-02-16 15:53             ` Dave Hansen
@ 2026-02-16 16:19               ` Mike Rapoport
  0 siblings, 0 replies; 14+ messages in thread
From: Mike Rapoport @ 2026-02-16 16:19 UTC (permalink / raw)
  To: Dave Hansen
  Cc: Kiryl Shutsemau, Ard Biesheuvel, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, Tom Lendacky, x86, linux-efi,
	linux-mm, linux-kernel, Moritz Sanft

On Mon, Feb 16, 2026 at 07:53:24AM -0800, Dave Hansen wrote:
> On 2/14/26 07:51, Mike Rapoport wrote:
> > Heh, it's x86's choice of memblock iterator that's rounding the ranges 😉
> 
> Ahh, good point. I was just assuming that the memblock iteration _had_
> to be over PFNs. Silly me.
> 
> > Maybe I miss some context, but my understanding is that for crash kernels
> > the unaccepted table is E820_TYPE_RESERVED and those are never added to
> > memblock.memory by e820 code, hence the call to memblock_add() in
> > reserve_unaccepted().
> > 
> > When x86 creates page tables, init_range_memory_mapping() walks
> > memblock.memory with for_each_mem_pfn_range() that rounds ranges that are
> > not page-aligned, which is normally fine, because it would mean that we
> > miss some partial pages that are divided between E820_RAM and
> > E820_SOMETHING_ELSE.
> > 
> > And Kiryl's intention to round up unaccepted to page boundary seems correct
> > to me.
> 
> It fixes the bug for sure.
> 
> I'm more worried about the next feature, or the existing features that
> also only working because memory is page-aligned somewhere (even though
> it isn't guaranteed to remain that way).
> 
> There are two choices for fixing this: One, we do Kiryl's fix plus
> checks to ensure that all the memblocks that generate direct mappings
> (is it _just_ the "memory" type?) are padded out to page-aligned boundaries.
> 
> The other alternative is to do for_each_mem_range() and do the padding
> universally when creating the mappings. Maybe _also_ with warnings or
> maybe a pr_debug().
> 
> I do still think it's a little wonky for memblock_add()'s management of
> the "memory" type to allow unaligned arguments when that type is also
> used to create page-aligned mapping structures. Memblocks themselves
> obviously need to be byte-level, but I'm not sure it's the right thing
> for the "memory" type API.

Well, we could make memblock_add() implicitly cut down the edges when it's
adding to memblock.memory and make everything there page aligned, but I
truly have no idea what will break and I'm sure something will :)

Another thing that's more on x86 side, is that translation from e820 to
memblock only adds E820_TYPE_RAM to memblock. And since in e820 these are
mutually exclusive with other e820 types, this could create non-aligned
chunks when firmware reservations are not page aligned. It also creates
unnecessary holes in memblock.memory that slow down memblock interation a
bit and more interestingly, everything that's not in E820_TYPE_RAM is
treated as IO and requires ioremap/memremap for access, even it is in DRAM.

If these reserved regions were added to memblock.memory along with being
memblock_reserve()ed we wouldn't hit the bug with unaccepted I believe some
others as well.

-- 
Sincerely yours,
Mike.


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-02-16 16:19 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-02-13 15:48 [PATCH 0/2] efi: Fix alignenment issues in unaccepted memory code Kiryl Shutsemau (Meta)
2026-02-13 15:48 ` [PATCH 1/2] efi: Fix reservation of unaccepted memory table Kiryl Shutsemau (Meta)
2026-02-13 16:01   ` Dave Hansen
2026-02-13 16:14     ` Kiryl Shutsemau
2026-02-13 16:46       ` Dave Hansen
2026-02-13 17:20         ` Kiryl Shutsemau
2026-02-14 15:51           ` Mike Rapoport
2026-02-16 14:22             ` Kiryl Shutsemau
2026-02-16 14:51               ` Mike Rapoport
2026-02-16 15:53             ` Dave Hansen
2026-02-16 16:19               ` Mike Rapoport
2026-02-13 15:48 ` [PATCH 2/2] efi: Align unaccepted memory range to page boundary Kiryl Shutsemau (Meta)
2026-02-16 14:51   ` Tom Lendacky
2026-02-16 15:33     ` Kiryl Shutsemau

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox