aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuergen Gross <jgross@suse.com>2019-02-14 05:42:39 -0500
committerJuergen Gross <jgross@suse.com>2019-02-18 00:50:34 -0500
commit357b4da50a62e2fd70eacee21cdbd22d4c7a7b60 (patch)
tree67ddf0b7850cf8fa134d97cf00ba7647bf627591
parent068e79f4a9d613f4327cb4062a1e49c0eaca7149 (diff)
x86: respect memory size limiting via mem= parameter
When limiting memory size via kernel parameter "mem=" this should be respected even in case of memory made accessible via a PCI card. Today this kind of memory won't be made usable in initial memory setup as the memory won't be visible in E820 map, but it might be added when adding PCI devices due to corresponding ACPI table entries. Not respecting "mem=" can be corrected by adding a global max_mem_size variable set by parse_memopt() which will result in rejecting adding memory areas resulting in a memory size above the allowed limit. Signed-off-by: Juergen Gross <jgross@suse.com> Acked-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: William Kucharski <william.kucharski@oracle.com> Signed-off-by: Juergen Gross <jgross@suse.com>
-rw-r--r--arch/x86/kernel/e820.c5
-rw-r--r--include/linux/memory_hotplug.h2
-rw-r--r--mm/memory_hotplug.c6
3 files changed, 13 insertions, 0 deletions
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 50895c2f937d..e67513e2cbbb 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -14,6 +14,7 @@
14#include <linux/acpi.h> 14#include <linux/acpi.h>
15#include <linux/firmware-map.h> 15#include <linux/firmware-map.h>
16#include <linux/sort.h> 16#include <linux/sort.h>
17#include <linux/memory_hotplug.h>
17 18
18#include <asm/e820/api.h> 19#include <asm/e820/api.h>
19#include <asm/setup.h> 20#include <asm/setup.h>
@@ -881,6 +882,10 @@ static int __init parse_memopt(char *p)
881 882
882 e820__range_remove(mem_size, ULLONG_MAX - mem_size, E820_TYPE_RAM, 1); 883 e820__range_remove(mem_size, ULLONG_MAX - mem_size, E820_TYPE_RAM, 1);
883 884
885#ifdef CONFIG_MEMORY_HOTPLUG
886 max_mem_size = mem_size;
887#endif
888
884 return 0; 889 return 0;
885} 890}
886early_param("mem", parse_memopt); 891early_param("mem", parse_memopt);
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index 368267c1b71b..cfd12078172a 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -100,6 +100,8 @@ extern void __online_page_free(struct page *page);
100 100
101extern int try_online_node(int nid); 101extern int try_online_node(int nid);
102 102
103extern u64 max_mem_size;
104
103extern bool memhp_auto_online; 105extern bool memhp_auto_online;
104/* If movable_node boot option specified */ 106/* If movable_node boot option specified */
105extern bool movable_node_enabled; 107extern bool movable_node_enabled;
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 124e794867c5..519f9db063ff 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -96,10 +96,16 @@ void mem_hotplug_done(void)
96 cpus_read_unlock(); 96 cpus_read_unlock();
97} 97}
98 98
99u64 max_mem_size = U64_MAX;
100
99/* add this memory to iomem resource */ 101/* add this memory to iomem resource */
100static struct resource *register_memory_resource(u64 start, u64 size) 102static struct resource *register_memory_resource(u64 start, u64 size)
101{ 103{
102 struct resource *res, *conflict; 104 struct resource *res, *conflict;
105
106 if (start + size > max_mem_size)
107 return ERR_PTR(-E2BIG);
108
103 res = kzalloc(sizeof(struct resource), GFP_KERNEL); 109 res = kzalloc(sizeof(struct resource), GFP_KERNEL);
104 if (!res) 110 if (!res)
105 return ERR_PTR(-ENOMEM); 111 return ERR_PTR(-ENOMEM);