From ef7d3a3f0caefd1abe2edf07bbca4833a9d75c49 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 2 Jul 2024 12:34:23 +0200 Subject: [PATCH] 5.15-stable patches added patches: drivers-fix-typo-in-firmware-efi-memmap.c.patch efi-correct-comment-on-efi_memmap_alloc.patch efi-memmap-move-manipulation-routines-into-x86-arch-tree.patch efi-x86-free-efi-memory-map-only-when-installing-a-new-one.patch efi-xen-set-efi_paravirt-for-xen-dom0-boot-on-all-architectures.patch --- ...rs-fix-typo-in-firmware-efi-memmap.c.patch | 32 + ...-correct-comment-on-efi_memmap_alloc.patch | 32 + ...pulation-routines-into-x86-arch-tree.patch | 591 ++++++++++++++++++ ...y-map-only-when-installing-a-new-one.patch | 111 ++++ ...r-xen-dom0-boot-on-all-architectures.patch | 97 +++ queue-5.15/series | 5 + 6 files changed, 868 insertions(+) create mode 100644 queue-5.15/drivers-fix-typo-in-firmware-efi-memmap.c.patch create mode 100644 queue-5.15/efi-correct-comment-on-efi_memmap_alloc.patch create mode 100644 queue-5.15/efi-memmap-move-manipulation-routines-into-x86-arch-tree.patch create mode 100644 queue-5.15/efi-x86-free-efi-memory-map-only-when-installing-a-new-one.patch create mode 100644 queue-5.15/efi-xen-set-efi_paravirt-for-xen-dom0-boot-on-all-architectures.patch diff --git a/queue-5.15/drivers-fix-typo-in-firmware-efi-memmap.c.patch b/queue-5.15/drivers-fix-typo-in-firmware-efi-memmap.c.patch new file mode 100644 index 00000000000..873c96a4b20 --- /dev/null +++ b/queue-5.15/drivers-fix-typo-in-firmware-efi-memmap.c.patch @@ -0,0 +1,32 @@ +From stable+bounces-56123-greg=kroah.com@vger.kernel.org Sat Jun 29 17:12:53 2024 +From: Ard Biesheuvel +Date: Sat, 29 Jun 2024 17:12:32 +0200 +Subject: drivers: fix typo in firmware/efi/memmap.c +To: stable@vger.kernel.org +Message-ID: <20240629151231.864706-6-ardb+git@google.com> + +From: Zheng Zhi Yuan + +[ Commit 1df4d1724baafa55e9803414ebcdf1ca702bc958 upstream ] + +This patch fixes the spelling error in firmware/efi/memmap.c, changing +it to the correct word. + +Signed-off-by: Zheng Zhi Yuan +Signed-off-by: Ard Biesheuvel +Signed-off-by: Greg Kroah-Hartman +--- + drivers/firmware/efi/memmap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/firmware/efi/memmap.c ++++ b/drivers/firmware/efi/memmap.c +@@ -245,7 +245,7 @@ int __init efi_memmap_install(struct efi + * @range: Address range (start, end) to split around + * + * Returns the number of additional EFI memmap entries required to +- * accomodate @range. ++ * accommodate @range. + */ + int __init efi_memmap_split_count(efi_memory_desc_t *md, struct range *range) + { diff --git a/queue-5.15/efi-correct-comment-on-efi_memmap_alloc.patch b/queue-5.15/efi-correct-comment-on-efi_memmap_alloc.patch new file mode 100644 index 00000000000..80fc2c8d52b --- /dev/null +++ b/queue-5.15/efi-correct-comment-on-efi_memmap_alloc.patch @@ -0,0 +1,32 @@ +From stable+bounces-56124-greg=kroah.com@vger.kernel.org Sat Jun 29 17:12:55 2024 +From: Ard Biesheuvel +Date: Sat, 29 Jun 2024 17:12:33 +0200 +Subject: efi: Correct comment on efi_memmap_alloc +To: stable@vger.kernel.org +Message-ID: <20240629151231.864706-7-ardb+git@google.com> + +From: Liu Zixian + +[ Commit db01ea882bf601252dad57242655da17fd9ad2f5 upstream ] + +Returning zero means success now. + +Signed-off-by: Liu Zixian +Signed-off-by: Ard Biesheuvel +Signed-off-by: Greg Kroah-Hartman +--- + drivers/firmware/efi/memmap.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/firmware/efi/memmap.c ++++ b/drivers/firmware/efi/memmap.c +@@ -59,8 +59,7 @@ static void __init efi_memmap_free(void) + * Depending on whether mm_init() has already been invoked or not, + * either memblock or "normal" page allocation is used. + * +- * Returns the physical address of the allocated memory map on +- * success, zero on failure. ++ * Returns zero on success, a negative error code on failure. + */ + int __init efi_memmap_alloc(unsigned int num_entries, + struct efi_memory_map_data *data) diff --git a/queue-5.15/efi-memmap-move-manipulation-routines-into-x86-arch-tree.patch b/queue-5.15/efi-memmap-move-manipulation-routines-into-x86-arch-tree.patch new file mode 100644 index 00000000000..ecd6893ffc4 --- /dev/null +++ b/queue-5.15/efi-memmap-move-manipulation-routines-into-x86-arch-tree.patch @@ -0,0 +1,591 @@ +From stable+bounces-56125-greg=kroah.com@vger.kernel.org Sat Jun 29 17:12:53 2024 +From: Ard Biesheuvel +Date: Sat, 29 Jun 2024 17:12:34 +0200 +Subject: efi: memmap: Move manipulation routines into x86 arch tree +To: stable@vger.kernel.org +Message-ID: <20240629151231.864706-8-ardb+git@google.com> + +From: Ard Biesheuvel + +[ Commit fdc6d38d64a20c542b1867ebeb8dd03b98829336 upstream ] + +The EFI memory map is a description of the memory layout as provided by +the firmware, and only x86 manipulates it in various different ways for +its own memory bookkeeping. So let's move the memmap routines that are +only used by x86 into the x86 arch tree. + +[ardb: s/memblock_phys_free/memblock_free for linux-5.15.y backport] +Signed-off-by: Ard Biesheuvel +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/include/asm/efi.h | 12 ++ + arch/x86/platform/efi/Makefile | 3 + arch/x86/platform/efi/memmap.c | 236 ++++++++++++++++++++++++++++++++++++++++ + drivers/firmware/efi/memmap.c | 240 +---------------------------------------- + include/linux/efi.h | 10 - + 5 files changed, 261 insertions(+), 240 deletions(-) + create mode 100644 arch/x86/platform/efi/memmap.c + +--- a/arch/x86/include/asm/efi.h ++++ b/arch/x86/include/asm/efi.h +@@ -386,6 +386,18 @@ static inline void efi_fake_memmap_early + } + #endif + ++extern int __init efi_memmap_alloc(unsigned int num_entries, ++ struct efi_memory_map_data *data); ++extern void __efi_memmap_free(u64 phys, unsigned long size, ++ unsigned long flags); ++#define __efi_memmap_free __efi_memmap_free ++ ++extern int __init efi_memmap_install(struct efi_memory_map_data *data); ++extern int __init efi_memmap_split_count(efi_memory_desc_t *md, ++ struct range *range); ++extern void __init efi_memmap_insert(struct efi_memory_map *old_memmap, ++ void *buf, struct efi_mem_range *mem); ++ + #define arch_ima_efi_boot_mode \ + ({ extern struct boot_params boot_params; boot_params.secure_boot; }) + +--- a/arch/x86/platform/efi/Makefile ++++ b/arch/x86/platform/efi/Makefile +@@ -3,5 +3,6 @@ OBJECT_FILES_NON_STANDARD_efi_thunk_$(BI + KASAN_SANITIZE := n + GCOV_PROFILE := n + +-obj-$(CONFIG_EFI) += quirks.o efi.o efi_$(BITS).o efi_stub_$(BITS).o ++obj-$(CONFIG_EFI) += memmap.o quirks.o efi.o efi_$(BITS).o \ ++ efi_stub_$(BITS).o + obj-$(CONFIG_EFI_MIXED) += efi_thunk_$(BITS).o +--- /dev/null ++++ b/arch/x86/platform/efi/memmap.c +@@ -0,0 +1,236 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Common EFI memory map functions. ++ */ ++ ++#define pr_fmt(fmt) "efi: " fmt ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static phys_addr_t __init __efi_memmap_alloc_early(unsigned long size) ++{ ++ return memblock_phys_alloc(size, SMP_CACHE_BYTES); ++} ++ ++static phys_addr_t __init __efi_memmap_alloc_late(unsigned long size) ++{ ++ unsigned int order = get_order(size); ++ struct page *p = alloc_pages(GFP_KERNEL, order); ++ ++ if (!p) ++ return 0; ++ ++ return PFN_PHYS(page_to_pfn(p)); ++} ++ ++void __init __efi_memmap_free(u64 phys, unsigned long size, unsigned long flags) ++{ ++ if (flags & EFI_MEMMAP_MEMBLOCK) { ++ if (slab_is_available()) ++ memblock_free_late(phys, size); ++ else ++ memblock_free(phys, size); ++ } else if (flags & EFI_MEMMAP_SLAB) { ++ struct page *p = pfn_to_page(PHYS_PFN(phys)); ++ unsigned int order = get_order(size); ++ ++ free_pages((unsigned long) page_address(p), order); ++ } ++} ++ ++/** ++ * efi_memmap_alloc - Allocate memory for the EFI memory map ++ * @num_entries: Number of entries in the allocated map. ++ * @data: efi memmap installation parameters ++ * ++ * Depending on whether mm_init() has already been invoked or not, ++ * either memblock or "normal" page allocation is used. ++ * ++ * Returns zero on success, a negative error code on failure. ++ */ ++int __init efi_memmap_alloc(unsigned int num_entries, ++ struct efi_memory_map_data *data) ++{ ++ /* Expect allocation parameters are zero initialized */ ++ WARN_ON(data->phys_map || data->size); ++ ++ data->size = num_entries * efi.memmap.desc_size; ++ data->desc_version = efi.memmap.desc_version; ++ data->desc_size = efi.memmap.desc_size; ++ data->flags &= ~(EFI_MEMMAP_SLAB | EFI_MEMMAP_MEMBLOCK); ++ data->flags |= efi.memmap.flags & EFI_MEMMAP_LATE; ++ ++ if (slab_is_available()) { ++ data->flags |= EFI_MEMMAP_SLAB; ++ data->phys_map = __efi_memmap_alloc_late(data->size); ++ } else { ++ data->flags |= EFI_MEMMAP_MEMBLOCK; ++ data->phys_map = __efi_memmap_alloc_early(data->size); ++ } ++ ++ if (!data->phys_map) ++ return -ENOMEM; ++ return 0; ++} ++ ++/** ++ * efi_memmap_install - Install a new EFI memory map in efi.memmap ++ * @ctx: map allocation parameters (address, size, flags) ++ * ++ * Unlike efi_memmap_init_*(), this function does not allow the caller ++ * to switch from early to late mappings. It simply uses the existing ++ * mapping function and installs the new memmap. ++ * ++ * Returns zero on success, a negative error code on failure. ++ */ ++int __init efi_memmap_install(struct efi_memory_map_data *data) ++{ ++ efi_memmap_unmap(); ++ ++ return __efi_memmap_init(data); ++} ++ ++/** ++ * efi_memmap_split_count - Count number of additional EFI memmap entries ++ * @md: EFI memory descriptor to split ++ * @range: Address range (start, end) to split around ++ * ++ * Returns the number of additional EFI memmap entries required to ++ * accommodate @range. ++ */ ++int __init efi_memmap_split_count(efi_memory_desc_t *md, struct range *range) ++{ ++ u64 m_start, m_end; ++ u64 start, end; ++ int count = 0; ++ ++ start = md->phys_addr; ++ end = start + (md->num_pages << EFI_PAGE_SHIFT) - 1; ++ ++ /* modifying range */ ++ m_start = range->start; ++ m_end = range->end; ++ ++ if (m_start <= start) { ++ /* split into 2 parts */ ++ if (start < m_end && m_end < end) ++ count++; ++ } ++ ++ if (start < m_start && m_start < end) { ++ /* split into 3 parts */ ++ if (m_end < end) ++ count += 2; ++ /* split into 2 parts */ ++ if (end <= m_end) ++ count++; ++ } ++ ++ return count; ++} ++ ++/** ++ * efi_memmap_insert - Insert a memory region in an EFI memmap ++ * @old_memmap: The existing EFI memory map structure ++ * @buf: Address of buffer to store new map ++ * @mem: Memory map entry to insert ++ * ++ * It is suggested that you call efi_memmap_split_count() first ++ * to see how large @buf needs to be. ++ */ ++void __init efi_memmap_insert(struct efi_memory_map *old_memmap, void *buf, ++ struct efi_mem_range *mem) ++{ ++ u64 m_start, m_end, m_attr; ++ efi_memory_desc_t *md; ++ u64 start, end; ++ void *old, *new; ++ ++ /* modifying range */ ++ m_start = mem->range.start; ++ m_end = mem->range.end; ++ m_attr = mem->attribute; ++ ++ /* ++ * The EFI memory map deals with regions in EFI_PAGE_SIZE ++ * units. Ensure that the region described by 'mem' is aligned ++ * correctly. ++ */ ++ if (!IS_ALIGNED(m_start, EFI_PAGE_SIZE) || ++ !IS_ALIGNED(m_end + 1, EFI_PAGE_SIZE)) { ++ WARN_ON(1); ++ return; ++ } ++ ++ for (old = old_memmap->map, new = buf; ++ old < old_memmap->map_end; ++ old += old_memmap->desc_size, new += old_memmap->desc_size) { ++ ++ /* copy original EFI memory descriptor */ ++ memcpy(new, old, old_memmap->desc_size); ++ md = new; ++ start = md->phys_addr; ++ end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1; ++ ++ if (m_start <= start && end <= m_end) ++ md->attribute |= m_attr; ++ ++ if (m_start <= start && ++ (start < m_end && m_end < end)) { ++ /* first part */ ++ md->attribute |= m_attr; ++ md->num_pages = (m_end - md->phys_addr + 1) >> ++ EFI_PAGE_SHIFT; ++ /* latter part */ ++ new += old_memmap->desc_size; ++ memcpy(new, old, old_memmap->desc_size); ++ md = new; ++ md->phys_addr = m_end + 1; ++ md->num_pages = (end - md->phys_addr + 1) >> ++ EFI_PAGE_SHIFT; ++ } ++ ++ if ((start < m_start && m_start < end) && m_end < end) { ++ /* first part */ ++ md->num_pages = (m_start - md->phys_addr) >> ++ EFI_PAGE_SHIFT; ++ /* middle part */ ++ new += old_memmap->desc_size; ++ memcpy(new, old, old_memmap->desc_size); ++ md = new; ++ md->attribute |= m_attr; ++ md->phys_addr = m_start; ++ md->num_pages = (m_end - m_start + 1) >> ++ EFI_PAGE_SHIFT; ++ /* last part */ ++ new += old_memmap->desc_size; ++ memcpy(new, old, old_memmap->desc_size); ++ md = new; ++ md->phys_addr = m_end + 1; ++ md->num_pages = (end - m_end) >> ++ EFI_PAGE_SHIFT; ++ } ++ ++ if ((start < m_start && m_start < end) && ++ (end <= m_end)) { ++ /* first part */ ++ md->num_pages = (m_start - md->phys_addr) >> ++ EFI_PAGE_SHIFT; ++ /* latter part */ ++ new += old_memmap->desc_size; ++ memcpy(new, old, old_memmap->desc_size); ++ md = new; ++ md->phys_addr = m_start; ++ md->num_pages = (end - md->phys_addr + 1) >> ++ EFI_PAGE_SHIFT; ++ md->attribute |= m_attr; ++ } ++ } ++} +--- a/drivers/firmware/efi/memmap.c ++++ b/drivers/firmware/efi/memmap.c +@@ -9,82 +9,15 @@ + #include + #include + #include +-#include + #include + #include + +-static phys_addr_t __init __efi_memmap_alloc_early(unsigned long size) +-{ +- return memblock_phys_alloc(size, SMP_CACHE_BYTES); +-} +- +-static phys_addr_t __init __efi_memmap_alloc_late(unsigned long size) +-{ +- unsigned int order = get_order(size); +- struct page *p = alloc_pages(GFP_KERNEL, order); +- +- if (!p) +- return 0; +- +- return PFN_PHYS(page_to_pfn(p)); +-} +- +-void __init __efi_memmap_free(u64 phys, unsigned long size, unsigned long flags) +-{ +- if (flags & EFI_MEMMAP_MEMBLOCK) { +- if (slab_is_available()) +- memblock_free_late(phys, size); +- else +- memblock_free(phys, size); +- } else if (flags & EFI_MEMMAP_SLAB) { +- struct page *p = pfn_to_page(PHYS_PFN(phys)); +- unsigned int order = get_order(size); +- +- free_pages((unsigned long) page_address(p), order); +- } +-} +- +-static void __init efi_memmap_free(void) +-{ +- __efi_memmap_free(efi.memmap.phys_map, +- efi.memmap.desc_size * efi.memmap.nr_map, +- efi.memmap.flags); +-} +- +-/** +- * efi_memmap_alloc - Allocate memory for the EFI memory map +- * @num_entries: Number of entries in the allocated map. +- * @data: efi memmap installation parameters +- * +- * Depending on whether mm_init() has already been invoked or not, +- * either memblock or "normal" page allocation is used. +- * +- * Returns zero on success, a negative error code on failure. +- */ +-int __init efi_memmap_alloc(unsigned int num_entries, +- struct efi_memory_map_data *data) +-{ +- /* Expect allocation parameters are zero initialized */ +- WARN_ON(data->phys_map || data->size); +- +- data->size = num_entries * efi.memmap.desc_size; +- data->desc_version = efi.memmap.desc_version; +- data->desc_size = efi.memmap.desc_size; +- data->flags &= ~(EFI_MEMMAP_SLAB | EFI_MEMMAP_MEMBLOCK); +- data->flags |= efi.memmap.flags & EFI_MEMMAP_LATE; +- +- if (slab_is_available()) { +- data->flags |= EFI_MEMMAP_SLAB; +- data->phys_map = __efi_memmap_alloc_late(data->size); +- } else { +- data->flags |= EFI_MEMMAP_MEMBLOCK; +- data->phys_map = __efi_memmap_alloc_early(data->size); +- } ++#include ++#include + +- if (!data->phys_map) +- return -ENOMEM; +- return 0; +-} ++#ifndef __efi_memmap_free ++#define __efi_memmap_free(phys, size, flags) do { } while (0) ++#endif + + /** + * __efi_memmap_init - Common code for mapping the EFI memory map +@@ -101,7 +34,7 @@ int __init efi_memmap_alloc(unsigned int + * + * Returns zero on success, a negative error code on failure. + */ +-static int __init __efi_memmap_init(struct efi_memory_map_data *data) ++int __init __efi_memmap_init(struct efi_memory_map_data *data) + { + struct efi_memory_map map; + phys_addr_t phys_map; +@@ -121,8 +54,10 @@ static int __init __efi_memmap_init(stru + return -ENOMEM; + } + +- /* NOP if data->flags & (EFI_MEMMAP_MEMBLOCK | EFI_MEMMAP_SLAB) == 0 */ +- efi_memmap_free(); ++ if (efi.memmap.flags & (EFI_MEMMAP_MEMBLOCK | EFI_MEMMAP_SLAB)) ++ __efi_memmap_free(efi.memmap.phys_map, ++ efi.memmap.desc_size * efi.memmap.nr_map, ++ efi.memmap.flags); + + map.phys_map = data->phys_map; + map.nr_map = data->size / data->desc_size; +@@ -220,158 +155,3 @@ int __init efi_memmap_init_late(phys_add + + return __efi_memmap_init(&data); + } +- +-/** +- * efi_memmap_install - Install a new EFI memory map in efi.memmap +- * @ctx: map allocation parameters (address, size, flags) +- * +- * Unlike efi_memmap_init_*(), this function does not allow the caller +- * to switch from early to late mappings. It simply uses the existing +- * mapping function and installs the new memmap. +- * +- * Returns zero on success, a negative error code on failure. +- */ +-int __init efi_memmap_install(struct efi_memory_map_data *data) +-{ +- efi_memmap_unmap(); +- +- return __efi_memmap_init(data); +-} +- +-/** +- * efi_memmap_split_count - Count number of additional EFI memmap entries +- * @md: EFI memory descriptor to split +- * @range: Address range (start, end) to split around +- * +- * Returns the number of additional EFI memmap entries required to +- * accommodate @range. +- */ +-int __init efi_memmap_split_count(efi_memory_desc_t *md, struct range *range) +-{ +- u64 m_start, m_end; +- u64 start, end; +- int count = 0; +- +- start = md->phys_addr; +- end = start + (md->num_pages << EFI_PAGE_SHIFT) - 1; +- +- /* modifying range */ +- m_start = range->start; +- m_end = range->end; +- +- if (m_start <= start) { +- /* split into 2 parts */ +- if (start < m_end && m_end < end) +- count++; +- } +- +- if (start < m_start && m_start < end) { +- /* split into 3 parts */ +- if (m_end < end) +- count += 2; +- /* split into 2 parts */ +- if (end <= m_end) +- count++; +- } +- +- return count; +-} +- +-/** +- * efi_memmap_insert - Insert a memory region in an EFI memmap +- * @old_memmap: The existing EFI memory map structure +- * @buf: Address of buffer to store new map +- * @mem: Memory map entry to insert +- * +- * It is suggested that you call efi_memmap_split_count() first +- * to see how large @buf needs to be. +- */ +-void __init efi_memmap_insert(struct efi_memory_map *old_memmap, void *buf, +- struct efi_mem_range *mem) +-{ +- u64 m_start, m_end, m_attr; +- efi_memory_desc_t *md; +- u64 start, end; +- void *old, *new; +- +- /* modifying range */ +- m_start = mem->range.start; +- m_end = mem->range.end; +- m_attr = mem->attribute; +- +- /* +- * The EFI memory map deals with regions in EFI_PAGE_SIZE +- * units. Ensure that the region described by 'mem' is aligned +- * correctly. +- */ +- if (!IS_ALIGNED(m_start, EFI_PAGE_SIZE) || +- !IS_ALIGNED(m_end + 1, EFI_PAGE_SIZE)) { +- WARN_ON(1); +- return; +- } +- +- for (old = old_memmap->map, new = buf; +- old < old_memmap->map_end; +- old += old_memmap->desc_size, new += old_memmap->desc_size) { +- +- /* copy original EFI memory descriptor */ +- memcpy(new, old, old_memmap->desc_size); +- md = new; +- start = md->phys_addr; +- end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1; +- +- if (m_start <= start && end <= m_end) +- md->attribute |= m_attr; +- +- if (m_start <= start && +- (start < m_end && m_end < end)) { +- /* first part */ +- md->attribute |= m_attr; +- md->num_pages = (m_end - md->phys_addr + 1) >> +- EFI_PAGE_SHIFT; +- /* latter part */ +- new += old_memmap->desc_size; +- memcpy(new, old, old_memmap->desc_size); +- md = new; +- md->phys_addr = m_end + 1; +- md->num_pages = (end - md->phys_addr + 1) >> +- EFI_PAGE_SHIFT; +- } +- +- if ((start < m_start && m_start < end) && m_end < end) { +- /* first part */ +- md->num_pages = (m_start - md->phys_addr) >> +- EFI_PAGE_SHIFT; +- /* middle part */ +- new += old_memmap->desc_size; +- memcpy(new, old, old_memmap->desc_size); +- md = new; +- md->attribute |= m_attr; +- md->phys_addr = m_start; +- md->num_pages = (m_end - m_start + 1) >> +- EFI_PAGE_SHIFT; +- /* last part */ +- new += old_memmap->desc_size; +- memcpy(new, old, old_memmap->desc_size); +- md = new; +- md->phys_addr = m_end + 1; +- md->num_pages = (end - m_end) >> +- EFI_PAGE_SHIFT; +- } +- +- if ((start < m_start && m_start < end) && +- (end <= m_end)) { +- /* first part */ +- md->num_pages = (m_start - md->phys_addr) >> +- EFI_PAGE_SHIFT; +- /* latter part */ +- new += old_memmap->desc_size; +- memcpy(new, old, old_memmap->desc_size); +- md = new; +- md->phys_addr = m_start; +- md->num_pages = (end - md->phys_addr + 1) >> +- EFI_PAGE_SHIFT; +- md->attribute |= m_attr; +- } +- } +-} +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -627,18 +627,10 @@ static inline efi_status_t efi_query_var + #endif + extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr); + +-extern int __init efi_memmap_alloc(unsigned int num_entries, +- struct efi_memory_map_data *data); +-extern void __efi_memmap_free(u64 phys, unsigned long size, +- unsigned long flags); ++extern int __init __efi_memmap_init(struct efi_memory_map_data *data); + extern int __init efi_memmap_init_early(struct efi_memory_map_data *data); + extern int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size); + extern void __init efi_memmap_unmap(void); +-extern int __init efi_memmap_install(struct efi_memory_map_data *data); +-extern int __init efi_memmap_split_count(efi_memory_desc_t *md, +- struct range *range); +-extern void __init efi_memmap_insert(struct efi_memory_map *old_memmap, +- void *buf, struct efi_mem_range *mem); + + #ifdef CONFIG_EFI_ESRT + extern void __init efi_esrt_init(void); diff --git a/queue-5.15/efi-x86-free-efi-memory-map-only-when-installing-a-new-one.patch b/queue-5.15/efi-x86-free-efi-memory-map-only-when-installing-a-new-one.patch new file mode 100644 index 00000000000..2248a4bd260 --- /dev/null +++ b/queue-5.15/efi-x86-free-efi-memory-map-only-when-installing-a-new-one.patch @@ -0,0 +1,111 @@ +From stable+bounces-56127-greg=kroah.com@vger.kernel.org Sat Jun 29 17:12:56 2024 +From: Ard Biesheuvel +Date: Sat, 29 Jun 2024 17:12:36 +0200 +Subject: efi/x86: Free EFI memory map only when installing a new one. +To: stable@vger.kernel.org +Message-ID: <20240629151231.864706-10-ardb+git@google.com> + +From: Ard Biesheuvel + +[ Commit 75dde792d6f6c2d0af50278bd374bf0c512fe196 upstream ] + +The logic in __efi_memmap_init() is shared between two different +execution flows: +- mapping the EFI memory map early or late into the kernel VA space, so + that its entries can be accessed; +- the x86 specific cloning of the EFI memory map in order to insert new + entries that are created as a result of making a memory reservation + via a call to efi_mem_reserve(). + +In the former case, the underlying memory containing the kernel's view +of the EFI memory map (which may be heavily modified by the kernel +itself on x86) is not modified at all, and the only thing that changes +is the virtual mapping of this memory, which is different between early +and late boot. + +In the latter case, an entirely new allocation is created that carries a +new, updated version of the kernel's view of the EFI memory map. When +installing this new version, the old version will no longer be +referenced, and if the memory was allocated by the kernel, it will leak +unless it gets freed. + +The logic that implements this freeing currently lives on the code path +that is shared between these two use cases, but it should only apply to +the latter. So move it to the correct spot. + +While at it, drop the dummy definition for non-x86 architectures, as +that is no longer needed. + +Cc: +Fixes: f0ef6523475f ("efi: Fix efi_memmap_alloc() leaks") +Tested-by: Ashish Kalra +Link: https://lore.kernel.org/all/36ad5079-4326-45ed-85f6-928ff76483d3@amd.com +Signed-off-by: Ard Biesheuvel +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/include/asm/efi.h | 1 - + arch/x86/platform/efi/memmap.c | 12 +++++++++++- + drivers/firmware/efi/memmap.c | 9 --------- + 3 files changed, 11 insertions(+), 11 deletions(-) + +--- a/arch/x86/include/asm/efi.h ++++ b/arch/x86/include/asm/efi.h +@@ -390,7 +390,6 @@ extern int __init efi_memmap_alloc(unsig + struct efi_memory_map_data *data); + extern void __efi_memmap_free(u64 phys, unsigned long size, + unsigned long flags); +-#define __efi_memmap_free __efi_memmap_free + + extern int __init efi_memmap_install(struct efi_memory_map_data *data); + extern int __init efi_memmap_split_count(efi_memory_desc_t *md, +--- a/arch/x86/platform/efi/memmap.c ++++ b/arch/x86/platform/efi/memmap.c +@@ -92,12 +92,22 @@ int __init efi_memmap_alloc(unsigned int + */ + int __init efi_memmap_install(struct efi_memory_map_data *data) + { ++ unsigned long size = efi.memmap.desc_size * efi.memmap.nr_map; ++ unsigned long flags = efi.memmap.flags; ++ u64 phys = efi.memmap.phys_map; ++ int ret; ++ + efi_memmap_unmap(); + + if (efi_enabled(EFI_PARAVIRT)) + return 0; + +- return __efi_memmap_init(data); ++ ret = __efi_memmap_init(data); ++ if (ret) ++ return ret; ++ ++ __efi_memmap_free(phys, size, flags); ++ return 0; + } + + /** +--- a/drivers/firmware/efi/memmap.c ++++ b/drivers/firmware/efi/memmap.c +@@ -15,10 +15,6 @@ + #include + #include + +-#ifndef __efi_memmap_free +-#define __efi_memmap_free(phys, size, flags) do { } while (0) +-#endif +- + /** + * __efi_memmap_init - Common code for mapping the EFI memory map + * @data: EFI memory map data +@@ -51,11 +47,6 @@ int __init __efi_memmap_init(struct efi_ + return -ENOMEM; + } + +- if (efi.memmap.flags & (EFI_MEMMAP_MEMBLOCK | EFI_MEMMAP_SLAB)) +- __efi_memmap_free(efi.memmap.phys_map, +- efi.memmap.desc_size * efi.memmap.nr_map, +- efi.memmap.flags); +- + map.phys_map = data->phys_map; + map.nr_map = data->size / data->desc_size; + map.map_end = map.map + data->size; diff --git a/queue-5.15/efi-xen-set-efi_paravirt-for-xen-dom0-boot-on-all-architectures.patch b/queue-5.15/efi-xen-set-efi_paravirt-for-xen-dom0-boot-on-all-architectures.patch new file mode 100644 index 00000000000..d2c0d82ee21 --- /dev/null +++ b/queue-5.15/efi-xen-set-efi_paravirt-for-xen-dom0-boot-on-all-architectures.patch @@ -0,0 +1,97 @@ +From stable+bounces-56126-greg=kroah.com@vger.kernel.org Sat Jun 29 17:12:57 2024 +From: Ard Biesheuvel +Date: Sat, 29 Jun 2024 17:12:35 +0200 +Subject: efi: xen: Set EFI_PARAVIRT for Xen dom0 boot on all architectures +To: stable@vger.kernel.org +Message-ID: <20240629151231.864706-9-ardb+git@google.com> + +From: Ard Biesheuvel + +[ Commit d85e3e34940788578eeffd94e8b7e1d28e7278e9 upstream ] + +Currently, the EFI_PARAVIRT flag is only used by Xen dom0 boot on x86, +even though other architectures also support pseudo-EFI boot, where the +core kernel is invoked directly and provided with a set of data tables +that resemble the ones constructed by the EFI stub, which never actually +runs in that case. + +Let's fix this inconsistency, and always set this flag when booting dom0 +via the EFI boot path. Note that Xen on x86 does not provide the EFI +memory map in this case, whereas other architectures do, so move the +associated EFI_PARAVIRT check into the x86 platform code. + +Signed-off-by: Ard Biesheuvel +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/platform/efi/efi.c | 8 +++++--- + arch/x86/platform/efi/memmap.c | 3 +++ + drivers/firmware/efi/fdtparams.c | 4 ++++ + drivers/firmware/efi/memmap.c | 3 --- + 4 files changed, 12 insertions(+), 6 deletions(-) + +--- a/arch/x86/platform/efi/efi.c ++++ b/arch/x86/platform/efi/efi.c +@@ -234,9 +234,11 @@ int __init efi_memblock_x86_reserve_rang + data.desc_size = e->efi_memdesc_size; + data.desc_version = e->efi_memdesc_version; + +- rv = efi_memmap_init_early(&data); +- if (rv) +- return rv; ++ if (!efi_enabled(EFI_PARAVIRT)) { ++ rv = efi_memmap_init_early(&data); ++ if (rv) ++ return rv; ++ } + + if (add_efi_memmap || do_efi_soft_reserve()) + do_add_efi_memmap(); +--- a/arch/x86/platform/efi/memmap.c ++++ b/arch/x86/platform/efi/memmap.c +@@ -94,6 +94,9 @@ int __init efi_memmap_install(struct efi + { + efi_memmap_unmap(); + ++ if (efi_enabled(EFI_PARAVIRT)) ++ return 0; ++ + return __efi_memmap_init(data); + } + +--- a/drivers/firmware/efi/fdtparams.c ++++ b/drivers/firmware/efi/fdtparams.c +@@ -30,11 +30,13 @@ static __initconst const char name[][22] + + static __initconst const struct { + const char path[17]; ++ u8 paravirt; + const char params[PARAMCOUNT][26]; + } dt_params[] = { + { + #ifdef CONFIG_XEN // <-------17------> + .path = "/hypervisor/uefi", ++ .paravirt = 1, + .params = { + [SYSTAB] = "xen,uefi-system-table", + [MMBASE] = "xen,uefi-mmap-start", +@@ -121,6 +123,8 @@ u64 __init efi_get_fdt_params(struct efi + pr_err("Can't find property '%s' in DT!\n", pname); + return 0; + } ++ if (dt_params[i].paravirt) ++ set_bit(EFI_PARAVIRT, &efi.flags); + return systab; + } + notfound: +--- a/drivers/firmware/efi/memmap.c ++++ b/drivers/firmware/efi/memmap.c +@@ -39,9 +39,6 @@ int __init __efi_memmap_init(struct efi_ + struct efi_memory_map map; + phys_addr_t phys_map; + +- if (efi_enabled(EFI_PARAVIRT)) +- return 0; +- + phys_map = data->phys_map; + + if (data->flags & EFI_MEMMAP_LATE) diff --git a/queue-5.15/series b/queue-5.15/series index 1a9c472050f..a8a7a339e21 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -378,3 +378,8 @@ nfs-leave-pages-in-the-pagecache-if-readpage-failed.patch ipv6-annotate-some-data-races-around-sk-sk_prot.patch ipv6-fix-data-races-around-sk-sk_prot.patch tcp-fix-data-races-around-icsk-icsk_af_ops.patch +drivers-fix-typo-in-firmware-efi-memmap.c.patch +efi-correct-comment-on-efi_memmap_alloc.patch +efi-memmap-move-manipulation-routines-into-x86-arch-tree.patch +efi-xen-set-efi_paravirt-for-xen-dom0-boot-on-all-architectures.patch +efi-x86-free-efi-memory-map-only-when-installing-a-new-one.patch -- 2.47.3