Commit 90e66ce9 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'x86_boot_for_v5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 boot updates from Borislav Petkov:
 "Consolidation and cleanup of the early memory reservations, along with
  a couple of gcc11 warning fixes"

* tag 'x86_boot_for_v5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/setup: Move trim_snb_memory() later in setup_arch() to fix boot hangs
  x86/setup: Merge several reservations of start of memory
  x86/setup: Consolidate early memory reservations
  x86/boot/compressed: Avoid gcc-11 -Wstringop-overread warning
  x86/boot/tboot: Avoid Wstringop-overread-warning
parents 81a48979 c361e5d4
...@@ -430,8 +430,6 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, ...@@ -430,8 +430,6 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
error("Destination address too large"); error("Destination address too large");
#endif #endif
#ifndef CONFIG_RELOCATABLE #ifndef CONFIG_RELOCATABLE
if ((unsigned long)output != LOAD_PHYSICAL_ADDR)
error("Destination address does not match LOAD_PHYSICAL_ADDR");
if (virt_addr != LOAD_PHYSICAL_ADDR) if (virt_addr != LOAD_PHYSICAL_ADDR)
error("Destination virtual address changed when not relocatable"); error("Destination virtual address changed when not relocatable");
#endif #endif
......
...@@ -633,8 +633,13 @@ static void __init trim_snb_memory(void) ...@@ -633,8 +633,13 @@ static void __init trim_snb_memory(void)
printk(KERN_DEBUG "reserving inaccessible SNB gfx pages\n"); printk(KERN_DEBUG "reserving inaccessible SNB gfx pages\n");
/* /*
* Reserve all memory below the 1 MB mark that has not * SandyBridge integrated graphics devices have a bug that prevents
* already been reserved. * them from accessing certain memory ranges, namely anything below
* 1M and in the pages listed in bad_pages[] above.
*
* To avoid these pages being ever accessed by SNB gfx devices
* reserve all memory below the 1 MB mark and bad_pages that have
* not already been reserved at boot time.
*/ */
memblock_reserve(0, 1<<20); memblock_reserve(0, 1<<20);
...@@ -645,18 +650,6 @@ static void __init trim_snb_memory(void) ...@@ -645,18 +650,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) static void __init trim_bios_range(void)
{ {
/* /*
...@@ -725,9 +718,39 @@ static int __init parse_reservelow(char *p) ...@@ -725,9 +718,39 @@ static int __init parse_reservelow(char *p)
early_param("reservelow", parse_reservelow); early_param("reservelow", parse_reservelow);
static void __init trim_low_memory_range(void) 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);
/*
* The first 4Kb of memory is a BIOS owned area, but generally it is
* not listed as such in the E820 table.
*
* Reserve the first memory page and typically some additional
* memory (64KiB by default) since some BIOSes are known to corrupt
* low memory. See the Kconfig help text for X86_RESERVE_LOW.
*
* In addition, make sure page 0 is always reserved because on
* systems with L1TF its contents can be leaked to user processes.
*/
memblock_reserve(0, ALIGN(reserve_low, PAGE_SIZE)); memblock_reserve(0, ALIGN(reserve_low, 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();
} }
/* /*
...@@ -764,29 +787,6 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p) ...@@ -764,29 +787,6 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p)
void __init setup_arch(char **cmdline_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 #ifdef CONFIG_X86_32
memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
...@@ -910,8 +910,18 @@ void __init setup_arch(char **cmdline_p) ...@@ -910,8 +910,18 @@ void __init setup_arch(char **cmdline_p)
parse_early_param(); 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 #ifdef CONFIG_MEMORY_HOTPLUG
/* /*
* Memory used by the kernel cannot be hot-removed because Linux * Memory used by the kernel cannot be hot-removed because Linux
...@@ -938,9 +948,6 @@ void __init setup_arch(char **cmdline_p) ...@@ -938,9 +948,6 @@ void __init setup_arch(char **cmdline_p)
x86_report_nx(); x86_report_nx();
/* after early param, so could get panic from serial */
memblock_x86_reserve_range_setup_data();
if (acpi_mps_check()) { if (acpi_mps_check()) {
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_LOCAL_APIC
disable_apic = 1; disable_apic = 1;
...@@ -1032,8 +1039,6 @@ void __init setup_arch(char **cmdline_p) ...@@ -1032,8 +1039,6 @@ void __init setup_arch(char **cmdline_p)
*/ */
find_smp_config(); find_smp_config();
reserve_ibft_region();
early_alloc_pgt_buf(); early_alloc_pgt_buf();
/* /*
...@@ -1054,8 +1059,6 @@ void __init setup_arch(char **cmdline_p) ...@@ -1054,8 +1059,6 @@ void __init setup_arch(char **cmdline_p)
*/ */
sev_setup_arch(); sev_setup_arch();
reserve_bios_regions();
efi_fake_memmap(); efi_fake_memmap();
efi_find_mirror(); efi_find_mirror();
efi_esrt_init(); efi_esrt_init();
...@@ -1081,8 +1084,12 @@ void __init setup_arch(char **cmdline_p) ...@@ -1081,8 +1084,12 @@ void __init setup_arch(char **cmdline_p)
reserve_real_mode(); reserve_real_mode();
trim_platform_memory_ranges(); /*
trim_low_memory_range(); * Reserving memory causing GPU hangs on Sandy Bridge integrated
* graphics devices should be done after we allocated memory under
* 1M for the real mode trampoline.
*/
trim_snb_memory();
init_mem_mapping(); init_mem_mapping();
......
...@@ -49,6 +49,30 @@ bool tboot_enabled(void) ...@@ -49,6 +49,30 @@ bool tboot_enabled(void)
return tboot != NULL; return tboot != NULL;
} }
/* noinline to prevent gcc from warning about dereferencing constant fixaddr */
static noinline __init bool check_tboot_version(void)
{
if (memcmp(&tboot_uuid, &tboot->uuid, sizeof(tboot->uuid))) {
pr_warn("tboot at 0x%llx is invalid\n", boot_params.tboot_addr);
return false;
}
if (tboot->version < 5) {
pr_warn("tboot version is invalid: %u\n", tboot->version);
return false;
}
pr_info("found shared page at phys addr 0x%llx:\n",
boot_params.tboot_addr);
pr_debug("version: %d\n", tboot->version);
pr_debug("log_addr: 0x%08x\n", tboot->log_addr);
pr_debug("shutdown_entry: 0x%x\n", tboot->shutdown_entry);
pr_debug("tboot_base: 0x%08x\n", tboot->tboot_base);
pr_debug("tboot_size: 0x%x\n", tboot->tboot_size);
return true;
}
void __init tboot_probe(void) void __init tboot_probe(void)
{ {
/* Look for valid page-aligned address for shared page. */ /* Look for valid page-aligned address for shared page. */
...@@ -66,25 +90,9 @@ void __init tboot_probe(void) ...@@ -66,25 +90,9 @@ void __init tboot_probe(void)
/* Map and check for tboot UUID. */ /* Map and check for tboot UUID. */
set_fixmap(FIX_TBOOT_BASE, boot_params.tboot_addr); set_fixmap(FIX_TBOOT_BASE, boot_params.tboot_addr);
tboot = (struct tboot *)fix_to_virt(FIX_TBOOT_BASE); tboot = (void *)fix_to_virt(FIX_TBOOT_BASE);
if (memcmp(&tboot_uuid, &tboot->uuid, sizeof(tboot->uuid))) { if (!check_tboot_version())
pr_warn("tboot at 0x%llx is invalid\n", boot_params.tboot_addr);
tboot = NULL; tboot = NULL;
return;
}
if (tboot->version < 5) {
pr_warn("tboot version is invalid: %u\n", tboot->version);
tboot = NULL;
return;
}
pr_info("found shared page at phys addr 0x%llx:\n",
boot_params.tboot_addr);
pr_debug("version: %d\n", tboot->version);
pr_debug("log_addr: 0x%08x\n", tboot->log_addr);
pr_debug("shutdown_entry: 0x%x\n", tboot->shutdown_entry);
pr_debug("tboot_base: 0x%08x\n", tboot->tboot_base);
pr_debug("tboot_size: 0x%x\n", tboot->tboot_size);
} }
static pgd_t *tboot_pg_dir; static pgd_t *tboot_pg_dir;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment