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

Byungchul Park posted 1 patch 1 year, 7 months ago
arch/x86/kernel/e820.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
[PATCH v3] x86/e820: apply user defined memory limit in e820__finish_early_params()
Posted by Byungchul Park 1 year, 7 months ago
I might miss something.  Please lemme know if I go wrong.  Thanks.

	Byungchul

Changes from v2
	1. Fix a bug using a wrong type, E820_TYPE_RESERVED_KERN so as
	   to use the correct type, E820_TYPE_RAM when limiting the
	   memory size.
	2. Make the patch more clear.  The current version just moves
	   the place to apply the memory limit, from the phase parsing
	   boot command to the very end of considering early params of
	   e820.

Changes from v1
	1. before - handle boot_mem_limit assuming the default is U64_MAX.
	   after  - handle boot_mem_limit assuming the default is 0.

--->8---
From 3d5a7eb5d7529cfc1449c8cf72dd23748640ae05 Mon Sep 17 00:00:00 2001
From: Byungchul Park <byungchul@sk.com>
Date: Fri, 26 Apr 2024 15:10:35 +0900
Subject: [PATCH v3] x86/e820: apply user defined memory limit in e820__finish_early_params()

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@sk.com>
---
 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