summarylogtreecommitdiffstats
path: root/0002-x86-setup-Consolidate-early-memory-reservations.patch
diff options
context:
space:
mode:
Diffstat (limited to '0002-x86-setup-Consolidate-early-memory-reservations.patch')
-rw-r--r--0002-x86-setup-Consolidate-early-memory-reservations.patch188
1 files changed, 188 insertions, 0 deletions
diff --git a/0002-x86-setup-Consolidate-early-memory-reservations.patch b/0002-x86-setup-Consolidate-early-memory-reservations.patch
new file mode 100644
index 00000000000..20c38079761
--- /dev/null
+++ b/0002-x86-setup-Consolidate-early-memory-reservations.patch
@@ -0,0 +1,188 @@
+From 56e6bb0fe2b790adda81851794409faa533e521c Mon Sep 17 00:00:00 2001
+From: Mike Rapoport <rppt@linux.ibm.com>
+Date: Tue, 2 Mar 2021 12:04:05 +0200
+Subject: [PATCH 2/8] x86/setup: Consolidate early memory reservations
+
+The early reservations of memory areas used by the firmware, bootloader,
+kernel text and data are spread over setup_arch(). Moreover, some of them
+happen *after* memblock allocations, e.g trim_platform_memory_ranges() and
+trim_low_memory_range() are called after reserve_real_mode() that allocates
+memory.
+
+There was no corruption of these memory regions because memblock always
+allocates memory either from the end of memory (in top-down mode) or above
+the kernel image (in bottom-up mode). However, the bottom up mode is going
+to be updated to span the entire memory [1] to avoid limitations caused by
+KASLR.
+
+Consolidate early memory reservations in a dedicated function to improve
+robustness against future changes. Having the early reservations in one
+place also makes it clearer what memory must be reserved before memblock
+allocations are allowed.
+
+Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Baoquan He <bhe@redhat.com>
+Acked-by: Borislav Petkov <bp@suse.de>
+Acked-by: David Hildenbrand <david@redhat.com>
+Link: [1] https://lore.kernel.org/lkml/20201217201214.3414100-2-guro@fb.com
+Link: https://lkml.kernel.org/r/20210302100406.22059-2-rppt@kernel.org
+---
+ arch/x86/kernel/setup.c | 92 ++++++++++++++++++++---------------------
+ 1 file changed, 44 insertions(+), 48 deletions(-)
+
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
+index e79f21d13a0d..420d881da2bd 100644
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -646,18 +646,6 @@ static void __init trim_snb_memory(void)
+ }
+ }
+
+-/*
+- * Here we put platform-specific memory range workarounds, i.e.
+- * memory known to be corrupt or otherwise in need to be reserved on
+- * specific platforms.
+- *
+- * If this gets used more widely it could use a real dispatch mechanism.
+- */
+-static void __init trim_platform_memory_ranges(void)
+-{
+- trim_snb_memory();
+-}
+-
+ static void __init trim_bios_range(void)
+ {
+ /*
+@@ -730,7 +718,38 @@ static void __init trim_low_memory_range(void)
+ {
+ memblock_reserve(0, ALIGN(reserve_low, PAGE_SIZE));
+ }
+-
++
++static void __init early_reserve_memory(void)
++{
++ /*
++ * Reserve the memory occupied by the kernel between _text and
++ * __end_of_kernel_reserve symbols. Any kernel sections after the
++ * __end_of_kernel_reserve symbol must be explicitly reserved with a
++ * separate memblock_reserve() or they will be discarded.
++ */
++ memblock_reserve(__pa_symbol(_text),
++ (unsigned long)__end_of_kernel_reserve - (unsigned long)_text);
++
++ /*
++ * Make sure page 0 is always reserved because on systems with
++ * L1TF its contents can be leaked to user processes.
++ */
++ memblock_reserve(0, PAGE_SIZE);
++
++ early_reserve_initrd();
++
++ if (efi_enabled(EFI_BOOT))
++ efi_memblock_x86_reserve_range();
++
++ memblock_x86_reserve_range_setup_data();
++
++ reserve_ibft_region();
++ reserve_bios_regions();
++
++ trim_snb_memory();
++ trim_low_memory_range();
++}
++
+ /*
+ * Dump out kernel offset information on panic.
+ */
+@@ -765,29 +784,6 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p)
+
+ void __init setup_arch(char **cmdline_p)
+ {
+- /*
+- * Reserve the memory occupied by the kernel between _text and
+- * __end_of_kernel_reserve symbols. Any kernel sections after the
+- * __end_of_kernel_reserve symbol must be explicitly reserved with a
+- * separate memblock_reserve() or they will be discarded.
+- */
+- memblock_reserve(__pa_symbol(_text),
+- (unsigned long)__end_of_kernel_reserve - (unsigned long)_text);
+-
+- /*
+- * Make sure page 0 is always reserved because on systems with
+- * L1TF its contents can be leaked to user processes.
+- */
+- memblock_reserve(0, PAGE_SIZE);
+-
+- early_reserve_initrd();
+-
+- /*
+- * At this point everything still needed from the boot loader
+- * or BIOS or kernel text should be early reserved or marked not
+- * RAM in e820. All other memory is free game.
+- */
+-
+ #ifdef CONFIG_X86_32
+ memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
+
+@@ -911,8 +907,18 @@ void __init setup_arch(char **cmdline_p)
+
+ parse_early_param();
+
+- if (efi_enabled(EFI_BOOT))
+- efi_memblock_x86_reserve_range();
++ /*
++ * Do some memory reservations *before* memory is added to
++ * memblock, so memblock allocations won't overwrite it.
++ * Do it after early param, so we could get (unlikely) panic from
++ * serial.
++ *
++ * After this point everything still needed from the boot loader or
++ * firmware or kernel text should be early reserved or marked not
++ * RAM in e820. All other memory is free game.
++ */
++ early_reserve_memory();
++
+ #ifdef CONFIG_MEMORY_HOTPLUG
+ /*
+ * Memory used by the kernel cannot be hot-removed because Linux
+@@ -939,9 +945,6 @@ void __init setup_arch(char **cmdline_p)
+
+ x86_report_nx();
+
+- /* after early param, so could get panic from serial */
+- memblock_x86_reserve_range_setup_data();
+-
+ if (acpi_mps_check()) {
+ #ifdef CONFIG_X86_LOCAL_APIC
+ disable_apic = 1;
+@@ -1033,8 +1036,6 @@ void __init setup_arch(char **cmdline_p)
+ */
+ find_smp_config();
+
+- reserve_ibft_region();
+-
+ early_alloc_pgt_buf();
+
+ /*
+@@ -1055,8 +1056,6 @@ void __init setup_arch(char **cmdline_p)
+ */
+ sev_setup_arch();
+
+- reserve_bios_regions();
+-
+ efi_fake_memmap();
+ efi_find_mirror();
+ efi_esrt_init();
+@@ -1082,9 +1081,6 @@ void __init setup_arch(char **cmdline_p)
+
+ reserve_real_mode();
+
+- trim_platform_memory_ranges();
+- trim_low_memory_range();
+-
+ init_mem_mapping();
+
+ idt_setup_early_pf();
+--
+2.32.0
+