From f83717f4f574f79a7780f0c3df2e5fd0f3aa149d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 16 Jan 2023 15:51:44 +0100 Subject: [PATCH] 5.4-stable patches added patches: mm-always-release-pages-to-the-buddy-allocator-in-memblock_free_late.patch --- ...fi-fix-null-deref-in-init-error-path.patch | 9 +- ...uddy-allocator-in-memblock_free_late.patch | 90 +++++++++++++++++++ queue-5.4/series | 1 + 3 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 queue-5.4/mm-always-release-pages-to-the-buddy-allocator-in-memblock_free_late.patch diff --git a/queue-5.4/efi-fix-null-deref-in-init-error-path.patch b/queue-5.4/efi-fix-null-deref-in-init-error-path.patch index 4483f487ddc..8fcabff84fd 100644 --- a/queue-5.4/efi-fix-null-deref-in-init-error-path.patch +++ b/queue-5.4/efi-fix-null-deref-in-init-error-path.patch @@ -21,11 +21,9 @@ Signed-off-by: Johan Hovold Signed-off-by: Ard Biesheuvel Signed-off-by: Sasha Levin --- - drivers/firmware/efi/efi.c | 9 ++++++--- + drivers/firmware/efi/efi.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) -diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c -index ac9fb336c80f..eb98018ab420 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -345,8 +345,8 @@ static int __init efisubsys_init(void) @@ -39,7 +37,7 @@ index ac9fb336c80f..eb98018ab420 100644 } error = generic_ops_register(); -@@ -382,7 +382,10 @@ static int __init efisubsys_init(void) +@@ -382,7 +382,10 @@ err_unregister: generic_ops_unregister(); err_put: kobject_put(efi_kobj); @@ -51,6 +49,3 @@ index ac9fb336c80f..eb98018ab420 100644 return error; } --- -2.35.1 - diff --git a/queue-5.4/mm-always-release-pages-to-the-buddy-allocator-in-memblock_free_late.patch b/queue-5.4/mm-always-release-pages-to-the-buddy-allocator-in-memblock_free_late.patch new file mode 100644 index 00000000000..ca3ed018c2c --- /dev/null +++ b/queue-5.4/mm-always-release-pages-to-the-buddy-allocator-in-memblock_free_late.patch @@ -0,0 +1,90 @@ +From 115d9d77bb0f9152c60b6e8646369fa7f6167593 Mon Sep 17 00:00:00 2001 +From: Aaron Thompson +Date: Fri, 6 Jan 2023 22:22:44 +0000 +Subject: mm: Always release pages to the buddy allocator in memblock_free_late(). + +From: Aaron Thompson + +commit 115d9d77bb0f9152c60b6e8646369fa7f6167593 upstream. + +If CONFIG_DEFERRED_STRUCT_PAGE_INIT is enabled, memblock_free_pages() +only releases pages to the buddy allocator if they are not in the +deferred range. This is correct for free pages (as defined by +for_each_free_mem_pfn_range_in_zone()) because free pages in the +deferred range will be initialized and released as part of the deferred +init process. memblock_free_pages() is called by memblock_free_late(), +which is used to free reserved ranges after memblock_free_all() has +run. All pages in reserved ranges have been initialized at that point, +and accordingly, those pages are not touched by the deferred init +process. This means that currently, if the pages that +memblock_free_late() intends to release are in the deferred range, they +will never be released to the buddy allocator. They will forever be +reserved. + +In addition, memblock_free_pages() calls kmsan_memblock_free_pages(), +which is also correct for free pages but is not correct for reserved +pages. KMSAN metadata for reserved pages is initialized by +kmsan_init_shadow(), which runs shortly before memblock_free_all(). + +For both of these reasons, memblock_free_pages() should only be called +for free pages, and memblock_free_late() should call __free_pages_core() +directly instead. + +One case where this issue can occur in the wild is EFI boot on +x86_64. The x86 EFI code reserves all EFI boot services memory ranges +via memblock_reserve() and frees them later via memblock_free_late() +(efi_reserve_boot_services() and efi_free_boot_services(), +respectively). If any of those ranges happens to fall within the +deferred init range, the pages will not be released and that memory will +be unavailable. + +For example, on an Amazon EC2 t3.micro VM (1 GB) booting via EFI: + +v6.2-rc2: + # grep -E 'Node|spanned|present|managed' /proc/zoneinfo + Node 0, zone DMA + spanned 4095 + present 3999 + managed 3840 + Node 0, zone DMA32 + spanned 246652 + present 245868 + managed 178867 + +v6.2-rc2 + patch: + # grep -E 'Node|spanned|present|managed' /proc/zoneinfo + Node 0, zone DMA + spanned 4095 + present 3999 + managed 3840 + Node 0, zone DMA32 + spanned 246652 + present 245868 + managed 222816 # +43,949 pages + +Fixes: 3a80a7fa7989 ("mm: meminit: initialise a subset of struct pages if CONFIG_DEFERRED_STRUCT_PAGE_INIT is set") +Signed-off-by: Aaron Thompson +Link: https://lore.kernel.org/r/01010185892de53e-e379acfb-7044-4b24-b30a-e2657c1ba989-000000@us-west-2.amazonses.com +Signed-off-by: Mike Rapoport (IBM) +Signed-off-by: Greg Kroah-Hartman +--- + mm/memblock.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/mm/memblock.c ++++ b/mm/memblock.c +@@ -1546,7 +1546,13 @@ void __init __memblock_free_late(phys_ad + end = PFN_DOWN(base + size); + + for (; cursor < end; cursor++) { +- memblock_free_pages(pfn_to_page(cursor), cursor, 0); ++ /* ++ * Reserved pages are always initialized by the end of ++ * memblock_free_all() (by memmap_init() and, if deferred ++ * initialization is enabled, memmap_init_reserved_pages()), so ++ * these pages can be released directly to the buddy allocator. ++ */ ++ __free_pages_core(pfn_to_page(cursor), 0); + totalram_pages_inc(); + } + } diff --git a/queue-5.4/series b/queue-5.4/series index e8622c251b8..52fa752abe9 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -651,3 +651,4 @@ arm64-atomics-format-whitespace-consistently.patch arm64-atomics-remove-ll-sc-trampolines.patch arm64-cmpxchg_double-hazard-against-entire-exchange-.patch efi-fix-null-deref-in-init-error-path.patch +mm-always-release-pages-to-the-buddy-allocator-in-memblock_free_late.patch -- 2.47.3