Consolidation and cleanup of the early memory reservations, along with a

couple of gcc11 warning fixes.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAmCGmBgACgkQEsHwGGHe
 VUox6xAAus7u9Bpyu4UCr93j4PmkfLf0du7A7mfuxfATFFNTy+lQWq+tuJJsFMSI
 ShbRNKxE1clDtCpWHI9hi9B0GmrMlgjii2YtNfM7pkZYom3aA6IeXDedE3Ot1KwI
 Ox7DsUjgdwwF2O/pYHL4Jg6Vra5daNHYOSlAe7Rk78kcECFlXj77CJYiPtvtkYHD
 JH2tu2vaNcbp11vrWbbx7St4w+vDB37Y3NczatbqXMS4Uiwoyfjzyi4qmf97p92u
 9aDNq+hj+90b/PYUzd9wyCWc0S6TcQo3OYfZq1/hHdS8UE8kq4AY3FFnzFGIKi7k
 IcQDJivkKjXOURD8Btjgbp9dkcbZtiuKS7RcjDuBbmH/q8iBIRYK8GfMxyna0TpE
 VKC9Wdn/LvNPS8t0vyB6fK+vt7uxvBXscRA0GtCva3WWSORdI3bFV9n998ArSVZa
 Itj0GBQXx4zNIjfg4U+aDsqICKmxGZqoKHm8pDVJUDrZi9A1kWxmhivMSQg58+as
 pDKPArtXN2NzN+DCU+UWyFk9qvMSVQh+t3204w4PM0PiHpOyFh7jRXCvzn3ulVJP
 LBm3L/Bj7m7qwfmB0iWOGvhwGFIOG0jUk2abudBn864TFuMqEPRadQUwMNC+ezOT
 1bp5LWh2s71n610I5LPBYF1diwwxwmx5jhfhXjjfejzCcEy/Xp0=
 =PLgK
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2021-04-26 09:24:06 -07:00
commit 90e66ce9e8
3 changed files with 84 additions and 71 deletions

View File

@ -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

View File

@ -633,11 +633,16 @@ 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);
for (i = 0; i < ARRAY_SIZE(bad_pages); i++) { for (i = 0; i < ARRAY_SIZE(bad_pages); i++) {
if (memblock_reserve(bad_pages[i], PAGE_SIZE)) if (memblock_reserve(bad_pages[i], PAGE_SIZE))
printk(KERN_WARNING "failed to reserve 0x%08lx\n", printk(KERN_WARNING "failed to reserve 0x%08lx\n",
@ -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,11 +718,41 @@ 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();
} }
/* /*
* Dump out kernel offset information on panic. * Dump out kernel offset information on panic.
*/ */
@ -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)
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)
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)
*/ */
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)
*/ */
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)
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();

View File

@ -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)
/* 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;