--- /dev/null
+From ba69e0750b0362870294adab09339a0c39c3beaf Mon Sep 17 00:00:00 2001
+From: Ard Biesheuvel <ardb@kernel.org>
+Date: Sat, 1 Feb 2025 18:21:35 +0100
+Subject: efi: Avoid cold plugged memory for placing the kernel
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+commit ba69e0750b0362870294adab09339a0c39c3beaf upstream.
+
+UEFI 2.11 introduced EFI_MEMORY_HOT_PLUGGABLE to annotate system memory
+regions that are 'cold plugged' at boot, i.e., hot pluggable memory that
+is available from early boot, and described as system RAM by the
+firmware.
+
+Existing loaders and EFI applications running in the boot context will
+happily use this memory for allocating data structures that cannot be
+freed or moved at runtime, and this prevents the memory from being
+unplugged. Going forward, the new EFI_MEMORY_HOT_PLUGGABLE attribute
+should be tested, and memory annotated as such should be avoided for
+such allocations.
+
+In the EFI stub, there are a couple of occurrences where, instead of the
+high-level AllocatePages() UEFI boot service, a low-level code sequence
+is used that traverses the EFI memory map and carves out the requested
+number of pages from a free region. This is needed, e.g., for allocating
+as low as possible, or for allocating pages at random.
+
+While AllocatePages() should presumably avoid special purpose memory and
+cold plugged regions, this manual approach needs to incorporate this
+logic itself, in order to prevent the kernel itself from ending up in a
+hot unpluggable region, preventing it from being unplugged.
+
+So add the EFI_MEMORY_HOTPLUGGABLE macro definition, and check for it
+where appropriate.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/firmware/efi/efi.c | 6 ++++--
+ drivers/firmware/efi/libstub/randomalloc.c | 3 +++
+ drivers/firmware/efi/libstub/relocate.c | 3 +++
+ include/linux/efi.h | 1 +
+ 4 files changed, 11 insertions(+), 2 deletions(-)
+
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -774,13 +774,15 @@ char * __init efi_md_typeattr_format(cha
+ EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO |
+ EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP |
+ EFI_MEMORY_NV | EFI_MEMORY_SP | EFI_MEMORY_CPU_CRYPTO |
+- EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE))
++ EFI_MEMORY_MORE_RELIABLE | EFI_MEMORY_HOT_PLUGGABLE |
++ EFI_MEMORY_RUNTIME))
+ snprintf(pos, size, "|attr=0x%016llx]",
+ (unsigned long long)attr);
+ else
+ snprintf(pos, size,
+- "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
++ "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
+ attr & EFI_MEMORY_RUNTIME ? "RUN" : "",
++ attr & EFI_MEMORY_HOT_PLUGGABLE ? "HP" : "",
+ attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "",
+ attr & EFI_MEMORY_CPU_CRYPTO ? "CC" : "",
+ attr & EFI_MEMORY_SP ? "SP" : "",
+--- a/drivers/firmware/efi/libstub/randomalloc.c
++++ b/drivers/firmware/efi/libstub/randomalloc.c
+@@ -24,6 +24,9 @@ static unsigned long get_entry_num_slots
+ if (md->type != EFI_CONVENTIONAL_MEMORY)
+ return 0;
+
++ if (md->attribute & EFI_MEMORY_HOT_PLUGGABLE)
++ return 0;
++
+ if (efi_soft_reserve_enabled() &&
+ (md->attribute & EFI_MEMORY_SP))
+ return 0;
+--- a/drivers/firmware/efi/libstub/relocate.c
++++ b/drivers/firmware/efi/libstub/relocate.c
+@@ -62,6 +62,9 @@ efi_status_t efi_low_alloc_above(unsigne
+ if (desc->type != EFI_CONVENTIONAL_MEMORY)
+ continue;
+
++ if (desc->attribute & EFI_MEMORY_HOT_PLUGGABLE)
++ continue;
++
+ if (efi_soft_reserve_enabled() &&
+ (desc->attribute & EFI_MEMORY_SP))
+ continue;
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -125,6 +125,7 @@ typedef struct {
+ #define EFI_MEMORY_RO ((u64)0x0000000000020000ULL) /* read-only */
+ #define EFI_MEMORY_SP ((u64)0x0000000000040000ULL) /* soft reserved */
+ #define EFI_MEMORY_CPU_CRYPTO ((u64)0x0000000000080000ULL) /* supports encryption */
++#define EFI_MEMORY_HOT_PLUGGABLE BIT_ULL(20) /* supports unplugging at runtime */
+ #define EFI_MEMORY_RUNTIME ((u64)0x8000000000000000ULL) /* range requires runtime mapping */
+ #define EFI_MEMORY_DESCRIPTOR_VERSION 1
+