[PATCH v2] x86/boot/e820: Re-enable fallback if e820 table is empty

David Gow posted 1 patch 2 months ago
arch/x86/kernel/e820.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
[PATCH v2] x86/boot/e820: Re-enable fallback if e820 table is empty
Posted by David Gow 2 months ago
In commit 157266edcc56 ("x86/boot/e820: Simplify append_e820_table() and
remove restriction on single-entry tables"), the check that the number of
entries in the e820 table was removed. The intention was to support
single-entry maps, but by removing the check entirely, we also skip the
fallback (to, e.g., the BIOS 88h function).

This means that if no E820 map is passed in from the bootloader (which is
the case on some bootloaders, like linld), we end up with an empty memory
map, and the kernel fails to boot (either by deadlocking on OOM, or by
failing to allocate the real mode trampoline, or similar).

Re-instate the check in append_e820_table(), but only check nr_entries is
non-zero. This allows e820__memory_setup_default() to fall back to other
memory size sources, and doesn't affect e820__memory_setup_extended(), as
the latter ignores the return value from append_e820_table().

In so doing, we also update the return values to be proper error codes,
with -ENOENT for this case (there are no entries), and -EINVAL for the case
where an entry appears invalid. Given none of the callers check the actual
value -- just whether it's nonzero -- this is largely aesthetic in
practice.

Tested against linld, and the kernel boots again fine.

Fixes: 157266edcc56 ("x86/boot/e820: Simplify append_e820_table() and remove restriction on single-entry tables")
Signed-off-by: David Gow <david@davidgow.net>
---

Changes since v2:
https://lore.kernel.org/lkml/20260415003021.1543723-1-david@davidgow.net/
- Return -ENOENT instead of -1
- Return -EINVAL instead of -1 for the case where an entry looks invalid due to
  an overflow (Thanks, Andy)

---
 arch/x86/kernel/e820.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 2a9992758933..3db9c364b833 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -450,6 +450,10 @@ __init static int append_e820_table(struct boot_e820_entry *entries, u32 nr_entr
 {
 	struct boot_e820_entry *entry = entries;
 
+	/* If there aren't any entries, we'll want to fall-back to another source. */
+	if (!nr_entries)
+		return -ENOENT;
+
 	while (nr_entries) {
 		u64 start = entry->addr;
 		u64 size  = entry->size;
@@ -458,7 +462,7 @@ __init static int append_e820_table(struct boot_e820_entry *entries, u32 nr_entr
 
 		/* Ignore the remaining entries on 64-bit overflow: */
 		if (start > end && likely(size))
-			return -1;
+			return -EINVAL;
 
 		e820__range_add(start, size, type);
 
-- 
2.53.0
Re: [PATCH v2] x86/boot/e820: Re-enable fallback if e820 table is empty
Posted by Andy Shevchenko 2 months ago
On Thu, Apr 16, 2026 at 02:57:43PM +0800, David Gow wrote:
> In commit 157266edcc56 ("x86/boot/e820: Simplify append_e820_table() and
> remove restriction on single-entry tables"), the check that the number of
> entries in the e820 table was removed. The intention was to support
> single-entry maps, but by removing the check entirely, we also skip the
> fallback (to, e.g., the BIOS 88h function).
> 
> This means that if no E820 map is passed in from the bootloader (which is
> the case on some bootloaders, like linld), we end up with an empty memory
> map, and the kernel fails to boot (either by deadlocking on OOM, or by
> failing to allocate the real mode trampoline, or similar).
> 
> Re-instate the check in append_e820_table(), but only check nr_entries is
> non-zero. This allows e820__memory_setup_default() to fall back to other
> memory size sources, and doesn't affect e820__memory_setup_extended(), as
> the latter ignores the return value from append_e820_table().
> 
> In so doing, we also update the return values to be proper error codes,
> with -ENOENT for this case (there are no entries), and -EINVAL for the case
> where an entry appears invalid. Given none of the callers check the actual
> value -- just whether it's nonzero -- this is largely aesthetic in
> practice.
> 
> Tested against linld, and the kernel boots again fine.

...

> Changes since v2:
> https://lore.kernel.org/lkml/20260415003021.1543723-1-david@davidgow.net/
> - Return -ENOENT instead of -1
> - Return -EINVAL instead of -1 for the case where an entry looks invalid due to
>   an overflow (Thanks, Andy)

Oh, I didn't noticed it's overflow condition, so -ERANGE may suit better.
Whatever, the change looks good enough and it's up to you to follow the above.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>

-- 
With Best Regards,
Andy Shevchenko
Re: [PATCH v2] x86/boot/e820: Re-enable fallback if e820 table is empty
Posted by Ingo Molnar 1 month, 1 week ago
* Andy Shevchenko <andriy.shevchenko@intel.com> wrote:

> On Thu, Apr 16, 2026 at 02:57:43PM +0800, David Gow wrote:
> > In commit 157266edcc56 ("x86/boot/e820: Simplify append_e820_table() and
> > remove restriction on single-entry tables"), the check that the number of
> > entries in the e820 table was removed. The intention was to support
> > single-entry maps, but by removing the check entirely, we also skip the
> > fallback (to, e.g., the BIOS 88h function).
> > 
> > This means that if no E820 map is passed in from the bootloader (which is
> > the case on some bootloaders, like linld), we end up with an empty memory
> > map, and the kernel fails to boot (either by deadlocking on OOM, or by
> > failing to allocate the real mode trampoline, or similar).
> > 
> > Re-instate the check in append_e820_table(), but only check nr_entries is
> > non-zero. This allows e820__memory_setup_default() to fall back to other
> > memory size sources, and doesn't affect e820__memory_setup_extended(), as
> > the latter ignores the return value from append_e820_table().
> > 
> > In so doing, we also update the return values to be proper error codes,
> > with -ENOENT for this case (there are no entries), and -EINVAL for the case
> > where an entry appears invalid. Given none of the callers check the actual
> > value -- just whether it's nonzero -- this is largely aesthetic in
> > practice.
> > 
> > Tested against linld, and the kernel boots again fine.
> 
> ...
> 
> > Changes since v2:
> > https://lore.kernel.org/lkml/20260415003021.1543723-1-david@davidgow.net/
> > - Return -ENOENT instead of -1
> > - Return -EINVAL instead of -1 for the case where an entry looks invalid due to
> >   an overflow (Thanks, Andy)
> 
> Oh, I didn't noticed it's overflow condition, so -ERANGE may suit better.
> Whatever, the change looks good enough and it's up to you to follow the above.
> 
> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>

Applied, thanks!

	Ingo
[tip: x86/urgent] x86/boot/e820: Re-enable BIOS fallback if e820 table is empty
Posted by tip-bot2 for David Gow 1 month, 1 week ago
The following commit has been merged into the x86/urgent branch of tip:

Commit-ID:     5772f6535227ebd104065d80afa8ed3478d34c5c
Gitweb:        https://git.kernel.org/tip/5772f6535227ebd104065d80afa8ed3478d34c5c
Author:        David Gow <david@davidgow.net>
AuthorDate:    Thu, 16 Apr 2026 14:57:43 +08:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Thu, 07 May 2026 10:04:54 +02:00

x86/boot/e820: Re-enable BIOS fallback if e820 table is empty

In commit:

  157266edcc56 ("x86/boot/e820: Simplify append_e820_table() and remove restriction on single-entry tables")

the check on the number of entries in the e820 table was removed. The intention
was to support single-entry maps, but by removing the check entirely, we also
skip the fallback (to, e.g., the BIOS 88h function).

This means that if no E820 map is passed in from the bootloader (which is the
case on some bootloaders, like linld), we end up with an empty memory map, and
the kernel fails to boot (either by deadlocking on OOM, or by failing to
allocate the real mode trampoline, or similar).

Re-instate the check in append_e820_table(), but only check that nr_entries is
non-zero. This allows e820__memory_setup_default() to fall back to other memory
size sources, and doesn't affect e820__memory_setup_extended(), as the latter
ignores the return value from append_e820_table().

In doing so, we also update the return values to be proper error codes, with
-ENOENT for this case (there are no entries), and -EINVAL for the case where an
entry appears invalid. Given none of the callers check the actual value -- just
whether it's nonzero -- this is largely aesthetic in practice.

Tested against linld, and the kernel boots again fine.

[ mingo: Readability edits to the comment and the changelog. ]

Fixes: 157266edcc56 ("x86/boot/e820: Simplify append_e820_table() and remove restriction on single-entry tables")
Signed-off-by: David Gow <david@davidgow.net>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: stable@vger.kernel.org
Cc: Arnd Bergmann <arnd@kernel.org>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Link: https://patch.msgid.link/20260416065746.1896647-1-david@davidgow.net
---
 arch/x86/kernel/e820.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 2a99927..eb72537 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -450,6 +450,10 @@ __init static int append_e820_table(struct boot_e820_entry *entries, u32 nr_entr
 {
 	struct boot_e820_entry *entry = entries;
 
+	/* If there aren't any entries, we'll want to fall back to another source: */
+	if (!nr_entries)
+		return -ENOENT;
+
 	while (nr_entries) {
 		u64 start = entry->addr;
 		u64 size  = entry->size;
@@ -458,7 +462,7 @@ __init static int append_e820_table(struct boot_e820_entry *entries, u32 nr_entr
 
 		/* Ignore the remaining entries on 64-bit overflow: */
 		if (start > end && likely(size))
-			return -1;
+			return -EINVAL;
 
 		e820__range_add(start, size, type);