--- /dev/null
+From a7a6a01f88e87dec4bf2365571dd2dc7403d52d0 Mon Sep 17 00:00:00 2001
+From: Ard Biesheuvel <ardb@kernel.org>
+Date: Fri, 26 Jan 2024 12:14:30 +0100
+Subject: x86/efistub: Give up if memory attribute protocol returns an error
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+commit a7a6a01f88e87dec4bf2365571dd2dc7403d52d0 upstream.
+
+The recently introduced EFI memory attributes protocol should be used
+if it exists to ensure that the memory allocation created for the kernel
+permits execution. This is needed for compatibility with tightened
+requirements related to Windows logo certification for x86 PCs.
+
+Currently, we simply strip the execute protect (XP) attribute from the
+entire range, but this might be rejected under some firmware security
+policies, and so in a subsequent patch, this will be changed to only
+strip XP from the executable region that runs early, and make it
+read-only (RO) as well.
+
+In order to catch any issues early, ensure that the memory attribute
+protocol works as intended, and give up if it produces spurious errors.
+
+Note that the DXE services based fallback was always based on best
+effort, so don't propagate any errors returned by that API.
+
+Fixes: a1b87d54f4e4 ("x86/efistub: Avoid legacy decompressor when doing EFI boot")
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/firmware/efi/libstub/x86-stub.c | 24 ++++++++++++++----------
+ drivers/firmware/efi/libstub/x86-stub.h | 4 ++--
+ 2 files changed, 16 insertions(+), 12 deletions(-)
+
+--- a/drivers/firmware/efi/libstub/x86-stub.c
++++ b/drivers/firmware/efi/libstub/x86-stub.c
+@@ -212,8 +212,8 @@ static void retrieve_apple_device_proper
+ }
+ }
+
+-void efi_adjust_memory_range_protection(unsigned long start,
+- unsigned long size)
++efi_status_t efi_adjust_memory_range_protection(unsigned long start,
++ unsigned long size)
+ {
+ efi_status_t status;
+ efi_gcd_memory_space_desc_t desc;
+@@ -225,13 +225,17 @@ void efi_adjust_memory_range_protection(
+ rounded_end = roundup(start + size, EFI_PAGE_SIZE);
+
+ if (memattr != NULL) {
+- efi_call_proto(memattr, clear_memory_attributes, rounded_start,
+- rounded_end - rounded_start, EFI_MEMORY_XP);
+- return;
++ status = efi_call_proto(memattr, clear_memory_attributes,
++ rounded_start,
++ rounded_end - rounded_start,
++ EFI_MEMORY_XP);
++ if (status != EFI_SUCCESS)
++ efi_warn("Failed to clear EFI_MEMORY_XP attribute\n");
++ return status;
+ }
+
+ if (efi_dxe_table == NULL)
+- return;
++ return EFI_SUCCESS;
+
+ /*
+ * Don't modify memory region attributes, they are
+@@ -244,7 +248,7 @@ void efi_adjust_memory_range_protection(
+ status = efi_dxe_call(get_memory_space_descriptor, start, &desc);
+
+ if (status != EFI_SUCCESS)
+- return;
++ break;
+
+ next = desc.base_address + desc.length;
+
+@@ -269,8 +273,10 @@ void efi_adjust_memory_range_protection(
+ unprotect_start,
+ unprotect_start + unprotect_size,
+ status);
++ break;
+ }
+ }
++ return EFI_SUCCESS;
+ }
+
+ static efi_char16_t *efistub_fw_vendor(void)
+@@ -800,9 +806,7 @@ static efi_status_t efi_decompress_kerne
+
+ *kernel_entry = addr + entry;
+
+- efi_adjust_memory_range_protection(addr, kernel_total_size);
+-
+- return EFI_SUCCESS;
++ return efi_adjust_memory_range_protection(addr, kernel_total_size);
+ }
+
+ static void __noreturn enter_kernel(unsigned long kernel_addr,
+--- a/drivers/firmware/efi/libstub/x86-stub.h
++++ b/drivers/firmware/efi/libstub/x86-stub.h
+@@ -5,8 +5,8 @@
+ extern void trampoline_32bit_src(void *, bool);
+ extern const u16 trampoline_ljmp_imm_offset;
+
+-void efi_adjust_memory_range_protection(unsigned long start,
+- unsigned long size);
++efi_status_t efi_adjust_memory_range_protection(unsigned long start,
++ unsigned long size);
+
+ #ifdef CONFIG_X86_64
+ efi_status_t efi_setup_5level_paging(void);