From: Greg Kroah-Hartman Date: Sun, 2 May 2021 11:11:17 +0000 (+0200) Subject: 4.19-stable patches X-Git-Tag: v4.19.190~60 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ddacf629b8e4fb3a01cd65c8f45408a93bf433a6;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: acpi-tables-x86-reserve-memory-occupied-by-acpi-tables.patch acpi-x86-call-acpi_boot_table_init-after-acpi_table_upgrade.patch --- diff --git a/queue-4.19/acpi-tables-x86-reserve-memory-occupied-by-acpi-tables.patch b/queue-4.19/acpi-tables-x86-reserve-memory-occupied-by-acpi-tables.patch new file mode 100644 index 00000000000..09055ac40ff --- /dev/null +++ b/queue-4.19/acpi-tables-x86-reserve-memory-occupied-by-acpi-tables.patch @@ -0,0 +1,225 @@ +From 1a1c130ab7575498eed5bcf7220037ae09cd1f8a Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Tue, 23 Mar 2021 20:26:52 +0100 +Subject: ACPI: tables: x86: Reserve memory occupied by ACPI tables + +From: Rafael J. Wysocki + +commit 1a1c130ab7575498eed5bcf7220037ae09cd1f8a upstream. + +The following problem has been reported by George Kennedy: + + Since commit 7fef431be9c9 ("mm/page_alloc: place pages to tail + in __free_pages_core()") the following use after free occurs + intermittently when ACPI tables are accessed. + + BUG: KASAN: use-after-free in ibft_init+0x134/0xc49 + Read of size 4 at addr ffff8880be453004 by task swapper/0/1 + CPU: 3 PID: 1 Comm: swapper/0 Not tainted 5.12.0-rc1-7a7fd0d #1 + Call Trace: + dump_stack+0xf6/0x158 + print_address_description.constprop.9+0x41/0x60 + kasan_report.cold.14+0x7b/0xd4 + __asan_report_load_n_noabort+0xf/0x20 + ibft_init+0x134/0xc49 + do_one_initcall+0xc4/0x3e0 + kernel_init_freeable+0x5af/0x66b + kernel_init+0x16/0x1d0 + ret_from_fork+0x22/0x30 + + ACPI tables mapped via kmap() do not have their mapped pages + reserved and the pages can be "stolen" by the buddy allocator. + +Apparently, on the affected system, the ACPI table in question is +not located in "reserved" memory, like ACPI NVS or ACPI Data, that +will not be used by the buddy allocator, so the memory occupied by +that table has to be explicitly reserved to prevent the buddy +allocator from using it. + +In order to address this problem, rearrange the initialization of the +ACPI tables on x86 to locate the initial tables earlier and reserve +the memory occupied by them. + +The other architectures using ACPI should not be affected by this +change. + +Link: https://lore.kernel.org/linux-acpi/1614802160-29362-1-git-send-email-george.kennedy@oracle.com/ +Reported-by: George Kennedy +Tested-by: George Kennedy +Signed-off-by: Rafael J. Wysocki +Reviewed-by: Mike Rapoport +Cc: 5.10+ # 5.10+ +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/acpi/boot.c | 25 ++++++++++++------------- + arch/x86/kernel/setup.c | 8 +++----- + drivers/acpi/tables.c | 42 +++++++++++++++++++++++++++++++++++++++--- + include/linux/acpi.h | 9 ++++++++- + 4 files changed, 62 insertions(+), 22 deletions(-) + +--- a/arch/x86/kernel/acpi/boot.c ++++ b/arch/x86/kernel/acpi/boot.c +@@ -1565,10 +1565,18 @@ void __init acpi_boot_table_init(void) + /* + * Initialize the ACPI boot-time table parser. + */ +- if (acpi_table_init()) { ++ if (acpi_locate_initial_tables()) + disable_acpi(); +- return; +- } ++ else ++ acpi_reserve_initial_tables(); ++} ++ ++int __init early_acpi_boot_init(void) ++{ ++ if (acpi_disabled) ++ return 1; ++ ++ acpi_table_init_complete(); + + acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); + +@@ -1581,18 +1589,9 @@ void __init acpi_boot_table_init(void) + } else { + printk(KERN_WARNING PREFIX "Disabling ACPI support\n"); + disable_acpi(); +- return; ++ return 1; + } + } +-} +- +-int __init early_acpi_boot_init(void) +-{ +- /* +- * If acpi_disabled, bail out +- */ +- if (acpi_disabled) +- return 1; + + /* + * Process the Multiple APIC Description Table (MADT), if present +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -1097,6 +1097,9 @@ void __init setup_arch(char **cmdline_p) + + cleanup_highmap(); + ++ /* Look for ACPI tables and reserve memory occupied by them. */ ++ acpi_boot_table_init(); ++ + memblock_set_current_limit(ISA_END_ADDRESS); + e820__memblock_setup(); + +@@ -1183,11 +1186,6 @@ void __init setup_arch(char **cmdline_p) + + early_platform_quirks(); + +- /* +- * Parse the ACPI tables for possible boot-time SMP configuration. +- */ +- acpi_boot_table_init(); +- + early_acpi_boot_init(); + + initmem_init(); +--- a/drivers/acpi/tables.c ++++ b/drivers/acpi/tables.c +@@ -732,7 +732,7 @@ acpi_os_table_override(struct acpi_table + } + + /* +- * acpi_table_init() ++ * acpi_locate_initial_tables() + * + * find RSDP, find and checksum SDT/XSDT. + * checksum all tables, print SDT/XSDT +@@ -740,7 +740,7 @@ acpi_os_table_override(struct acpi_table + * result: sdt_entry[] is initialized + */ + +-int __init acpi_table_init(void) ++int __init acpi_locate_initial_tables(void) + { + acpi_status status; + +@@ -755,9 +755,45 @@ int __init acpi_table_init(void) + status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); + if (ACPI_FAILURE(status)) + return -EINVAL; +- acpi_table_initrd_scan(); + ++ return 0; ++} ++ ++void __init acpi_reserve_initial_tables(void) ++{ ++ int i; ++ ++ for (i = 0; i < ACPI_MAX_TABLES; i++) { ++ struct acpi_table_desc *table_desc = &initial_tables[i]; ++ u64 start = table_desc->address; ++ u64 size = table_desc->length; ++ ++ if (!start || !size) ++ break; ++ ++ pr_info("Reserving %4s table memory at [mem 0x%llx-0x%llx]\n", ++ table_desc->signature.ascii, start, start + size - 1); ++ ++ memblock_reserve(start, size); ++ } ++} ++ ++void __init acpi_table_init_complete(void) ++{ ++ acpi_table_initrd_scan(); + check_multiple_madt(); ++} ++ ++int __init acpi_table_init(void) ++{ ++ int ret; ++ ++ ret = acpi_locate_initial_tables(); ++ if (ret) ++ return ret; ++ ++ acpi_table_init_complete(); ++ + return 0; + } + +--- a/include/linux/acpi.h ++++ b/include/linux/acpi.h +@@ -230,10 +230,14 @@ void __iomem *__acpi_map_table(unsigned + void __acpi_unmap_table(void __iomem *map, unsigned long size); + int early_acpi_boot_init(void); + int acpi_boot_init (void); ++void acpi_boot_table_prepare (void); + void acpi_boot_table_init (void); + int acpi_mps_check (void); + int acpi_numa_init (void); + ++int acpi_locate_initial_tables (void); ++void acpi_reserve_initial_tables (void); ++void acpi_table_init_complete (void); + int acpi_table_init (void); + int acpi_table_parse(char *id, acpi_tbl_table_handler handler); + int __init acpi_table_parse_entries(char *id, unsigned long table_size, +@@ -734,9 +738,12 @@ static inline int acpi_boot_init(void) + return 0; + } + ++static inline void acpi_boot_table_prepare(void) ++{ ++} ++ + static inline void acpi_boot_table_init(void) + { +- return; + } + + static inline int acpi_mps_check(void) diff --git a/queue-4.19/acpi-x86-call-acpi_boot_table_init-after-acpi_table_upgrade.patch b/queue-4.19/acpi-x86-call-acpi_boot_table_init-after-acpi_table_upgrade.patch new file mode 100644 index 00000000000..06f0cc8b530 --- /dev/null +++ b/queue-4.19/acpi-x86-call-acpi_boot_table_init-after-acpi_table_upgrade.patch @@ -0,0 +1,49 @@ +From 6998a8800d73116187aad542391ce3b2dd0f9e30 Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Tue, 13 Apr 2021 16:01:00 +0200 +Subject: ACPI: x86: Call acpi_boot_table_init() after acpi_table_upgrade() + +From: Rafael J. Wysocki + +commit 6998a8800d73116187aad542391ce3b2dd0f9e30 upstream. + +Commit 1a1c130ab757 ("ACPI: tables: x86: Reserve memory occupied by +ACPI tables") attempted to address an issue with reserving the memory +occupied by ACPI tables, but it broke the initrd-based table override +mechanism relied on by multiple users. + +To restore the initrd-based ACPI table override functionality, move +the acpi_boot_table_init() invocation in setup_arch() on x86 after +the acpi_table_upgrade() one. + +Fixes: 1a1c130ab757 ("ACPI: tables: x86: Reserve memory occupied by ACPI tables") +Reported-by: Hans de Goede +Tested-by: Hans de Goede +Signed-off-by: Rafael J. Wysocki +Cc: George Kennedy +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/setup.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -1097,9 +1097,6 @@ void __init setup_arch(char **cmdline_p) + + cleanup_highmap(); + +- /* Look for ACPI tables and reserve memory occupied by them. */ +- acpi_boot_table_init(); +- + memblock_set_current_limit(ISA_END_ADDRESS); + e820__memblock_setup(); + +@@ -1179,6 +1176,8 @@ void __init setup_arch(char **cmdline_p) + reserve_initrd(); + + acpi_table_upgrade(); ++ /* Look for ACPI tables and reserve memory occupied by them. */ ++ acpi_boot_table_init(); + + vsmp_init(); +