[PATCH v3] x86/e820: apply user defined memory limit in e820__finish_early_params()

From: Byungchul Park
Date: Fri Apr 26 2024 - 02:10:35 EST


Limiting memory by 'mem=' or 'memmap=' boot command doesn't work in some
systems that keep overwriting the memory map during booting process.

In such a system, there's no way to limit the memory size e.g. for test
purpose or someting. Thus, this patch made the restriction applied in
e820__finish_early_params() rather than the phase parsing boot command,
that is the very end of considering early params of e820.

Signed-off-by: Byungchul Park <byungchul@xxxxxx>
---
arch/x86/kernel/e820.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 6f1b379e3b38..3bc593235b76 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -879,6 +879,7 @@ static void __init early_panic(char *msg)
}

static int userdef __initdata;
+static u64 userdef_mem_limit;

/* The "mem=nopentium" boot option disables 4MB page tables on 32-bit kernels: */
static int __init parse_memopt(char *p)
@@ -905,7 +906,10 @@ static int __init parse_memopt(char *p)
if (mem_size == 0)
return -EINVAL;

- e820__range_remove(mem_size, ULLONG_MAX - mem_size, E820_TYPE_RAM, 1);
+ if (userdef_mem_limit)
+ userdef_mem_limit = min(userdef_mem_limit, mem_size);
+ else
+ userdef_mem_limit = mem_size;

#ifdef CONFIG_MEMORY_HOTPLUG
max_mem_size = mem_size;
@@ -966,7 +970,10 @@ static int __init parse_memmap_one(char *p)
else
e820__range_remove(start_at, mem_size, 0, 0);
} else {
- e820__range_remove(mem_size, ULLONG_MAX - mem_size, E820_TYPE_RAM, 1);
+ if (userdef_mem_limit)
+ userdef_mem_limit = min(userdef_mem_limit, mem_size);
+ else
+ userdef_mem_limit = mem_size;
}

return *p == '\0' ? 0 : -EINVAL;
@@ -1050,6 +1057,11 @@ void __init e820__reserve_setup_data(void)
void __init e820__finish_early_params(void)
{
if (userdef) {
+ if (userdef_mem_limit)
+ e820__range_remove(userdef_mem_limit,
+ ULLONG_MAX - userdef_mem_limit,
+ E820_TYPE_RAM, 1);
+
if (e820__update_table(e820_table) < 0)
early_panic("Invalid user supplied memory map");

--
2.17.1