aboutsummaryrefslogtreecommitdiffstats
path: root/meta-seattle/recipes-kernel/linux/files/01-arm64-boot-BE-kernels-from-UEFI.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-seattle/recipes-kernel/linux/files/01-arm64-boot-BE-kernels-from-UEFI.patch')
-rw-r--r--meta-seattle/recipes-kernel/linux/files/01-arm64-boot-BE-kernels-from-UEFI.patch999
1 files changed, 0 insertions, 999 deletions
diff --git a/meta-seattle/recipes-kernel/linux/files/01-arm64-boot-BE-kernels-from-UEFI.patch b/meta-seattle/recipes-kernel/linux/files/01-arm64-boot-BE-kernels-from-UEFI.patch
deleted file mode 100644
index 35b25249..00000000
--- a/meta-seattle/recipes-kernel/linux/files/01-arm64-boot-BE-kernels-from-UEFI.patch
+++ /dev/null
@@ -1,999 +0,0 @@
-From c55fa726d3e67da11a7ccd16ca367e9094265e4e Mon Sep 17 00:00:00 2001
-From: Adrian Calianu <adrian.calianu@enea.com>
-Date: Mon, 16 Feb 2015 13:56:36 +0100
-Subject: [PATCH 1/1] arm64: boot BE kernels from UEFI
-
-Adds support for booting BE kernels from UEFI. As UEFI is defined to
-be strictly little endian, some workarounds are required to combine a little
-endian EFI stub with a big endian kernel. Also, runtime services need to be
-wrapped so they can be executed in little endian mode.
-
-Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-
-This patch is the resulting of porting on 3.19 kernel of a patch set
-([RFC PATCH 00/10] arm64: boot BE kernels from UEFI) provided by
-Ard Biesheuvel ard.biesheuvel at linaro.org for 3.17 kernel.
-
-http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/274208.html
-
-Upstream-Status: Pending
-
-Signed-off-by: Adrian Calianu <adrian.calianu@enea.com>
----
- arch/arm64/Kconfig | 10 ++-
- arch/arm64/include/asm/assembler.h | 18 +++++
- arch/arm64/include/asm/efi.h | 2 +
- arch/arm64/kernel/Makefile | 7 +-
- arch/arm64/kernel/efi-be-call.S | 55 +++++++++++++++
- arch/arm64/kernel/efi-be-runtime.c | 104 ++++++++++++++++++++++++++++
- arch/arm64/kernel/efi-entry.S | 43 +++++++++---
- arch/arm64/kernel/efi-stub.c | 10 +--
- arch/arm64/kernel/efi.c | 64 ++++++++++-------
- arch/arm64/kernel/efistub-le/Makefile | 52 ++++++++++++++
- arch/arm64/kernel/efistub-le/efi-le-entry.S | 12 ++++
- arch/arm64/kernel/efistub-le/efistub-le.lds | 35 ++++++++++
- arch/arm64/kernel/efistub-le/le.h | 12 ++++
- arch/arm64/kernel/efistub-le/strstr.c | 20 ++++++
- arch/arm64/kernel/head.S | 48 +++++++------
- arch/arm64/kernel/image.h | 16 ++++-
- drivers/firmware/efi/efi.c | 26 ++++---
- drivers/firmware/efi/efivars.c | 2 +-
- drivers/firmware/efi/libstub/fdt.c | 4 ++
- 19 files changed, 459 insertions(+), 81 deletions(-)
- create mode 100644 arch/arm64/kernel/efi-be-call.S
- create mode 100644 arch/arm64/kernel/efi-be-runtime.c
- create mode 100644 arch/arm64/kernel/efistub-le/Makefile
- create mode 100644 arch/arm64/kernel/efistub-le/efi-le-entry.S
- create mode 100644 arch/arm64/kernel/efistub-le/efistub-le.lds
- create mode 100644 arch/arm64/kernel/efistub-le/le.h
- create mode 100644 arch/arm64/kernel/efistub-le/strstr.c
-
-diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
-index 3f08727..d35a06c 100644
---- a/arch/arm64/Kconfig
-+++ b/arch/arm64/Kconfig
-@@ -573,16 +573,20 @@ config CMDLINE_FORCE
- config EFI_STUB
- bool
-
-+config EFI_LE_STUB
-+ bool
-+
- config EFI
- bool "UEFI runtime support"
-- depends on OF && !CPU_BIG_ENDIAN
-+ depends on OF
- select LIBFDT
- select UCS2_STRING
- select EFI_PARAMS_FROM_FDT
- select EFI_RUNTIME_WRAPPERS
-- select EFI_STUB
-+ select EFI_STUB if !CPU_BIG_ENDIAN
-+ select EFI_LE_STUB if CPU_BIG_ENDIAN
- select EFI_ARMSTUB
-- default y
-+ default y if !CPU_BIG_ENDIAN
- help
- This option provides support for runtime services provided
- by UEFI firmware (such as non-volatile variables, realtime
-diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
-index 5901480..ad3aa92 100644
---- a/arch/arm64/include/asm/assembler.h
-+++ b/arch/arm64/include/asm/assembler.h
-@@ -155,3 +155,21 @@ lr .req x30 // link register
- #endif
- orr \rd, \lbits, \hbits, lsl #32
- .endm
-+
-+ /*
-+ * Define LE constants
-+ */
-+ .macro le16, x
-+ .byte \x & 0xff
-+ .byte (\x >> 8) & 0xff
-+ .endm
-+
-+ .macro le32, x
-+ le16 \x
-+ le16 \x >> 16
-+ .endm
-+
-+ .macro le64, x
-+ le32 \x
-+ le32 \x >> 32
-+ .endm
-diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
-index a34fd3b..44e642b 100644
---- a/arch/arm64/include/asm/efi.h
-+++ b/arch/arm64/include/asm/efi.h
-@@ -44,4 +44,6 @@ extern void efi_idmap_init(void);
-
- #define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__)
-
-+extern void efi_be_runtime_setup(void);
-+
- #endif /* _ASM_EFI_H */
-diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
-index 79bdd3b..1ab3ff4 100644
---- a/arch/arm64/kernel/Makefile
-+++ b/arch/arm64/kernel/Makefile
-@@ -32,7 +32,12 @@ arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o
- arm64-obj-$(CONFIG_CPU_IDLE) += cpuidle.o
- arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o
- arm64-obj-$(CONFIG_KGDB) += kgdb.o
--arm64-obj-$(CONFIG_EFI) += efi.o efi-stub.o efi-entry.o
-+arm64-efi-obj-y := efi.o
-+arm64-efi-obj-$(CONFIG_EFI_STUB) += efi-stub.o efi-entry.o
-+arm64-efi-obj-$(CONFIG_EFI_LE_STUB) += efistub-le/
-+arm64-efi-obj-$(CONFIG_CPU_BIG_ENDIAN) += efi-be-runtime.o efi-be-call.o
-+arm64-obj-$(CONFIG_EFI) += $(arm64-efi-obj-y)
-+
- arm64-obj-$(CONFIG_PCI) += pci.o
- arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o
- arm64-obj-$(CONFIG_ACPI) += acpi.o
-diff --git a/arch/arm64/kernel/efi-be-call.S b/arch/arm64/kernel/efi-be-call.S
-new file mode 100644
-index 0000000..b395c8c
---- /dev/null
-+++ b/arch/arm64/kernel/efi-be-call.S
-@@ -0,0 +1,55 @@
-+
-+#include <linux/linkage.h>
-+
-+ .text
-+ .align 3
-+ENTRY(efi_be_phys_call)
-+ /*
-+ * Entered at physical address with 1:1 mapping enabled.
-+ */
-+ stp x29, x30, [sp, #-96]!
-+ mov x29, sp
-+ str x27, [sp, #16]
-+
-+ ldr x8, =efi_be_phys_call // virt address of this function
-+ adr x9, efi_be_phys_call // phys address of this function
-+ sub x9, x8, x9 // calculate virt to phys offset in x9
-+
-+ /* preserve all inputs */
-+ stp x0, x1, [sp, #32]
-+ stp x2, x3, [sp, #48]
-+ stp x4, x5, [sp, #64]
-+ stp x6, x7, [sp, #80]
-+
-+ /* get phys address of stack */
-+ sub sp, sp, x9
-+
-+ /* switch to LE, disable MMU and D-cache but leave I-cache enabled */
-+ mrs x27, sctlr_el1
-+ bic x8, x27, #1 << 2 // clear SCTLR.C
-+ msr sctlr_el1, x8
-+
-+ bl flush_cache_all
-+
-+ /* restore inputs but rotated by 1 register */
-+ ldp x7, x0, [sp, #32]
-+ ldp x1, x2, [sp, #48]
-+ ldp x3, x4, [sp, #64]
-+ ldp x5, x6, [sp, #80]
-+
-+ bic x8, x27, #1 << 2 // clear SCTLR.C
-+ bic x8, x8, #1 << 0 // clear SCTLR.M
-+ bic x8, x8, #1 << 25 // clear SCTLR.EE
-+ msr sctlr_el1, x8
-+ isb
-+
-+ blr x7
-+
-+ /* switch back to BE and reenable MMU and D-cache */
-+ msr sctlr_el1, x27
-+
-+ mov sp, x29
-+ ldr x27, [sp, #16]
-+ ldp x29, x30, [sp], #96
-+ ret
-+ENDPROC(efi_be_phys_call)
-diff --git a/arch/arm64/kernel/efi-be-runtime.c b/arch/arm64/kernel/efi-be-runtime.c
-new file mode 100644
-index 0000000..28d7406
---- /dev/null
-+++ b/arch/arm64/kernel/efi-be-runtime.c
-@@ -0,0 +1,104 @@
-+
-+#include <linux/efi.h>
-+#include <linux/spinlock.h>
-+#include <asm/efi.h>
-+#include <asm/neon.h>
-+#include <asm/tlbflush.h>
-+
-+static efi_runtime_services_t *runtime;
-+static efi_status_t (*efi_be_call)(phys_addr_t func, ...);
-+
-+static DEFINE_SPINLOCK(efi_be_rt_lock);
-+
-+static unsigned long efi_be_call_pre(void)
-+{
-+ unsigned long flags;
-+
-+ kernel_neon_begin();
-+ spin_lock_irqsave(&efi_be_rt_lock, flags);
-+ cpu_switch_mm(idmap_pg_dir, &init_mm);
-+ flush_tlb_all();
-+ return flags;
-+}
-+
-+static void efi_be_call_post(unsigned long flags)
-+{
-+ cpu_switch_mm(current, current->active_mm);
-+ flush_tlb_all();
-+ spin_unlock_irqrestore(&efi_be_rt_lock, flags);
-+ kernel_neon_end();
-+}
-+
-+static efi_status_t efi_be_get_variable(efi_char16_t *name,
-+ efi_guid_t *vendor,
-+ u32 *attr,
-+ unsigned long *data_size,
-+ void *data)
-+{
-+ unsigned long flags;
-+ efi_status_t status;
-+
-+ *data_size = cpu_to_le64(*data_size);
-+ flags = efi_be_call_pre();
-+ status = efi_be_call(le64_to_cpu(runtime->get_variable),
-+ virt_to_phys(name), virt_to_phys(vendor),
-+ virt_to_phys(attr), virt_to_phys(data_size),
-+ virt_to_phys(data));
-+ efi_be_call_post(flags);
-+ *attr = le32_to_cpu(*attr);
-+ *data_size = le64_to_cpu(*data_size);
-+ return status;
-+}
-+
-+static efi_status_t efi_be_get_next_variable(unsigned long *name_size,
-+ efi_char16_t *name,
-+ efi_guid_t *vendor)
-+{
-+ unsigned long flags;
-+ efi_status_t status;
-+
-+ *name_size = cpu_to_le64(*name_size);
-+ flags = efi_be_call_pre();
-+ status = efi_be_call(le64_to_cpu(runtime->get_next_variable),
-+ virt_to_phys(name_size), virt_to_phys(name),
-+ virt_to_phys(vendor));
-+ efi_be_call_post(flags);
-+ *name_size = le64_to_cpu(*name_size);
-+ return status;
-+}
-+
-+static efi_status_t efi_be_set_variable(efi_char16_t *name,
-+ efi_guid_t *vendor,
-+ u32 attr,
-+ unsigned long data_size,
-+ void *data)
-+{
-+ unsigned long flags;
-+ efi_status_t status;
-+
-+ flags = efi_be_call_pre();
-+ status = efi_be_call(le64_to_cpu(runtime->set_variable),
-+ virt_to_phys(name), virt_to_phys(vendor),
-+ cpu_to_le32(attr), cpu_to_le64(data_size),
-+ virt_to_phys(data));
-+ efi_be_call_post(flags);
-+ return status;
-+}
-+
-+void efi_be_runtime_setup(void)
-+{
-+ extern u8 efi_be_phys_call[];
-+
-+ runtime = ioremap_cache(le64_to_cpu(efi.systab->runtime),
-+ sizeof(efi_runtime_services_t));
-+ if (!runtime) {
-+ pr_err("Failed to set up BE wrappers for UEFI Runtime Services!\n");
-+ return;
-+ }
-+
-+ efi_be_call = (void *)virt_to_phys(efi_be_phys_call);
-+
-+ efi.get_variable = efi_be_get_variable;
-+ efi.get_next_variable = efi_be_get_next_variable;
-+ efi.set_variable = efi_be_set_variable;
-+}
-diff --git a/arch/arm64/kernel/efi-entry.S b/arch/arm64/kernel/efi-entry.S
-index 8ce9b05..760fbb5 100644
---- a/arch/arm64/kernel/efi-entry.S
-+++ b/arch/arm64/kernel/efi-entry.S
-@@ -34,7 +34,34 @@ ENTRY(efi_stub_entry)
- * Create a stack frame to save FP/LR with extra space
- * for image_addr variable passed to efi_entry().
- */
-- stp x29, x30, [sp, #-32]!
-+ stp x29, x30, [sp, #-48]!
-+ stp x22, x23, [sp, #32]
-+
-+#ifdef CONFIG_EFI_LE_STUB
-+ adr x4, efi_stub_entry
-+ ldp w8, w9, [x4, #-32]
-+STUB_BE(rev w8, w8 )
-+STUB_BE(rev w9, w9 )
-+ add x8, x4, w8, sxtw // x8: base of Image
-+ add x9, x4, w9, sxtw // x9: offset of linux_banner
-+
-+ ldp x22, x23, [x4, #-24] // x22: size of Image
-+STUB_BE(rev x23, x23 ) // x23: stext offset
-+
-+ /*
-+ * Get a pointer to linux_banner in the outer image and store it
-+ * in this image.
-+ */
-+ adrp x4, le_linux_banner
-+ str x9, [x4, #:lo12:le_linux_banner]
-+#else
-+ adrp x8, _text
-+ add x8, x8, #:lo12:_text // x8: base of Image
-+ adrp x9, _edata
-+ add x9, x9, #:lo12:_edata
-+ sub x22, x9, x8 // x22: size of Image
-+ ldr x23, =stext_offset // x23: stext offset
-+#endif
-
- /*
- * Call efi_entry to do the real work.
-@@ -45,8 +72,6 @@ ENTRY(efi_stub_entry)
- * efi_system_table_t *sys_table,
- * unsigned long *image_addr) ;
- */
-- adrp x8, _text
-- add x8, x8, #:lo12:_text
- add x2, sp, 16
- str x8, [x2]
- bl efi_entry
-@@ -61,17 +86,12 @@ ENTRY(efi_stub_entry)
- */
- mov x20, x0 // DTB address
- ldr x0, [sp, #16] // relocated _text address
-- ldr x21, =stext_offset
-- add x21, x0, x21
-+ add x21, x0, x23
-
- /*
- * Calculate size of the kernel Image (same for original and copy).
- */
-- adrp x1, _text
-- add x1, x1, #:lo12:_text
-- adrp x2, _edata
-- add x2, x2, #:lo12:_edata
-- sub x1, x2, x1
-+ mov x1, x22
-
- /*
- * Flush the copied Image to the PoC, and ensure it is not shadowed by
-@@ -117,7 +137,8 @@ ENTRY(efi_stub_entry)
-
- efi_load_fail:
- mov x0, #EFI_LOAD_ERROR
-- ldp x29, x30, [sp], #32
-+ ldp x22, x23, [sp, #32]
-+ ldp x29, x30, [sp], #48
- ret
-
- efi_stub_entry_end:
-diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
-index d27dd98..dd6d6bc 100644
---- a/arch/arm64/kernel/efi-stub.c
-+++ b/arch/arm64/kernel/efi-stub.c
-@@ -11,7 +11,6 @@
- */
- #include <linux/efi.h>
- #include <asm/efi.h>
--#include <asm/sections.h>
-
- efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
- unsigned long *image_addr,
-@@ -22,22 +21,19 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
- efi_loaded_image_t *image)
- {
- efi_status_t status;
-- unsigned long kernel_size, kernel_memsize = 0;
-
- /* Relocate the image, if required. */
-- kernel_size = _edata - _text;
- if (*image_addr != (dram_base + TEXT_OFFSET)) {
-- kernel_memsize = kernel_size + (_end - _edata);
-- status = efi_low_alloc(sys_table, kernel_memsize + TEXT_OFFSET,
-+ status = efi_low_alloc(sys_table, image->image_size + TEXT_OFFSET,
- SZ_2M, reserve_addr);
- if (status != EFI_SUCCESS) {
- pr_efi_err(sys_table, "Failed to relocate kernel\n");
- return status;
- }
- memcpy((void *)*reserve_addr + TEXT_OFFSET, (void *)*image_addr,
-- kernel_size);
-+ image->image_size);
- *image_addr = *reserve_addr + TEXT_OFFSET;
-- *reserve_size = kernel_memsize + TEXT_OFFSET;
-+ *reserve_size = image->image_size + TEXT_OFFSET;
- }
-
-
-diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
-index 4178e9e..133c599 100644
---- a/arch/arm64/kernel/efi.c
-+++ b/arch/arm64/kernel/efi.c
-@@ -43,7 +43,7 @@ early_param("uefi_debug", uefi_debug_setup);
-
- static int __init is_normal_ram(efi_memory_desc_t *md)
- {
-- if (md->attribute & EFI_MEMORY_WB)
-+ if (le64_to_cpu(md->attribute) & EFI_MEMORY_WB)
- return 1;
- return 0;
- }
-@@ -59,10 +59,10 @@ static void __init efi_setup_idmap(void)
-
- /* map runtime io spaces */
- for_each_efi_memory_desc(&memmap, md) {
-- if (!(md->attribute & EFI_MEMORY_RUNTIME) || is_normal_ram(md))
-+ if (!(le64_to_cpu(md->attribute) & EFI_MEMORY_RUNTIME) || is_normal_ram(md))
- continue;
-- paddr = md->phys_addr;
-- npages = md->num_pages;
-+ paddr = le64_to_cpu(md->phys_addr);
-+ npages = le64_to_cpu(md->num_pages);
- memrange_efi_to_native(&paddr, &npages);
- size = npages << PAGE_SHIFT;
- create_id_mapping(paddr, size, 1);
-@@ -88,29 +88,29 @@ static int __init uefi_init(void)
- /*
- * Verify the EFI Table
- */
-- if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) {
-+ if (le64_to_cpu(efi.systab->hdr.signature) != EFI_SYSTEM_TABLE_SIGNATURE) {
- pr_err("System table signature incorrect\n");
- retval = -EINVAL;
- goto out;
- }
-- if ((efi.systab->hdr.revision >> 16) < 2)
-+ if ((le32_to_cpu(efi.systab->hdr.revision) >> 16) < 2)
- pr_warn("Warning: EFI system table version %d.%02d, expected 2.00 or greater\n",
- efi.systab->hdr.revision >> 16,
- efi.systab->hdr.revision & 0xffff);
-
- /* Show what we know for posterity */
-- c16 = early_memremap(efi.systab->fw_vendor,
-+ c16 = early_memremap(le64_to_cpu(efi.systab->fw_vendor),
- sizeof(vendor));
- if (c16) {
- for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i)
-- vendor[i] = c16[i];
-+ vendor[i] = le16_to_cpu(c16[i]);
- vendor[i] = '\0';
- early_memunmap(c16, sizeof(vendor));
- }
-
- pr_info("EFI v%u.%.02u by %s\n",
-- efi.systab->hdr.revision >> 16,
-- efi.systab->hdr.revision & 0xffff, vendor);
-+ le32_to_cpu(efi.systab->hdr.revision) >> 16,
-+ le32_to_cpu(efi.systab->hdr.revision) & 0xffff, vendor);
-
- retval = efi_config_init(NULL);
-
-@@ -124,7 +124,7 @@ out:
- */
- static __init int is_reserve_region(efi_memory_desc_t *md)
- {
-- switch (md->type) {
-+ switch (le32_to_cpu(md->type)) {
- case EFI_LOADER_CODE:
- case EFI_LOADER_DATA:
- case EFI_BOOT_SERVICES_CODE:
-@@ -146,8 +146,9 @@ static __init void reserve_regions(void)
- pr_info("Processing EFI memory map:\n");
-
- for_each_efi_memory_desc(&memmap, md) {
-- paddr = md->phys_addr;
-- npages = md->num_pages;
-+ u32 md_type = le32_to_cpu(md->type);
-+ paddr = le64_to_cpu(md->phys_addr);
-+ npages = le64_to_cpu(md->num_pages);
-
- if (uefi_debug) {
- char buf[64];
-@@ -164,8 +165,8 @@ static __init void reserve_regions(void)
- early_init_dt_add_memory_arch(paddr, size);
-
- if (is_reserve_region(md) ||
-- md->type == EFI_BOOT_SERVICES_CODE ||
-- md->type == EFI_BOOT_SERVICES_DATA) {
-+ md_type == EFI_BOOT_SERVICES_CODE ||
-+ md_type == EFI_BOOT_SERVICES_DATA) {
- memblock_reserve(paddr, size);
- if (uefi_debug)
- pr_cont("*");
-@@ -246,17 +247,17 @@ static void __init free_boot_services(void)
- */
- if (free_start) {
- /* adjust free_end then free region */
-- if (free_end > md->phys_addr)
-+ if (free_end > le64_to_cpu(md->phys_addr))
- free_end -= PAGE_SIZE;
- total_freed += free_region(free_start, free_end);
- free_start = 0;
- }
-- keep_end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
-+ keep_end = le64_to_cpu(md->phys_addr) + (le64_to_cpu(md->num_pages) << EFI_PAGE_SHIFT);
- continue;
- }
-
-- if (md->type != EFI_BOOT_SERVICES_CODE &&
-- md->type != EFI_BOOT_SERVICES_DATA) {
-+ if (le32_to_cpu(md->type) != EFI_BOOT_SERVICES_CODE &&
-+ le32_to_cpu(md->type) != EFI_BOOT_SERVICES_DATA) {
- /* no need to free this region */
- continue;
- }
-@@ -264,8 +265,8 @@ static void __init free_boot_services(void)
- /*
- * We want to free memory from this region.
- */
-- paddr = md->phys_addr;
-- npages = md->num_pages;
-+ paddr = le64_to_cpu(md->phys_addr);
-+ npages = le64_to_cpu(md->num_pages);
- memrange_efi_to_native(&paddr, &npages);
- size = npages << PAGE_SHIFT;
-
-@@ -333,8 +334,8 @@ static int __init remap_region(efi_memory_desc_t *md, void **new)
- {
- u64 paddr, vaddr, npages, size;
-
-- paddr = md->phys_addr;
-- npages = md->num_pages;
-+ paddr = le64_to_cpu(md->phys_addr);
-+ npages = le64_to_cpu(md->num_pages);
- memrange_efi_to_native(&paddr, &npages);
- size = npages << PAGE_SHIFT;
-
-@@ -350,7 +351,7 @@ static int __init remap_region(efi_memory_desc_t *md, void **new)
- }
-
- /* adjust for any rounding when EFI and system pagesize differs */
-- md->virt_addr = vaddr + (md->phys_addr - paddr);
-+ md->virt_addr = vaddr + (le64_to_cpu(md->phys_addr) - paddr);
-
- if (uefi_debug)
- pr_info(" EFI remap 0x%012llx => %p\n",
-@@ -395,6 +396,21 @@ static int __init arm64_enter_virtual_mode(void)
-
- efi.memmap = &memmap;
-
-+ if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) {
-+ efi.systab = ioremap_cache(efi_system_table,
-+ sizeof(efi_system_table_t));
-+ if (!efi.systab) {
-+ pr_err("Failed to remap EFI system table!\n");
-+ return -1;
-+ }
-+ free_boot_services();
-+ efi_be_runtime_setup();
-+
-+ set_bit(EFI_SYSTEM_TABLES, &efi.flags);
-+ set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
-+ return 0;
-+ }
-+
- /* Map the runtime regions */
- virtmap = kmalloc(mapsize, GFP_KERNEL);
- if (!virtmap) {
-diff --git a/arch/arm64/kernel/efistub-le/Makefile b/arch/arm64/kernel/efistub-le/Makefile
-new file mode 100644
-index 0000000..8a1c2a8
---- /dev/null
-+++ b/arch/arm64/kernel/efistub-le/Makefile
-@@ -0,0 +1,52 @@
-+
-+#
-+# Build a little endian EFI stub and wrap it into a single .o
-+#
-+
-+# the LE objects making up the LE efi stub
-+le-objs := efi-entry.o efi-stub.o strstr.o cache.o \
-+ lib-memchr.o lib-memcmp.o lib-memcpy.o lib-memmove.o \
-+ lib-memset.o lib-strchr.o lib-strlen.o lib-strncmp.o \
-+ fdt-fdt.o fdt-fdt_ro.o fdt-fdt_rw.o fdt-fdt_sw.o \
-+ fdt-fdt_wip.o fdt-fdt_empty_tree.o \
-+ libstub-fdt.o libstub-arm-stub.o libstub-efi-stub-helper.o
-+
-+extra-y := efi-le-stub.bin efi-le-stub.elf $(le-objs)
-+
-+KBUILD_CFLAGS := $(subst -pg,,$(KBUILD_CFLAGS)) -fno-stack-protector \
-+ -mlittle-endian -I$(srctree)/scripts/dtc/libfdt
-+
-+le-targets := $(addprefix $(obj)/, $(le-objs))
-+$(le-targets): KBUILD_AFLAGS += -mlittle-endian -include $(srctree)/$(src)/le.h
-+
-+$(obj)/efi-entry.o: $(obj)/../efi-entry.S FORCE
-+ $(call if_changed_dep,as_o_S)
-+
-+CFLAGS_efi-stub.o += -DTEXT_OFFSET=$(TEXT_OFFSET)
-+$(obj)/efi-stub.o: $(obj)/../efi-stub.c FORCE
-+ $(call if_changed_dep,cc_o_c)
-+
-+$(obj)/cache.o: $(src)/../../mm/cache.S FORCE
-+ $(call if_changed_dep,as_o_S)
-+
-+$(obj)/lib-%.o: $(src)/../../lib/%.S FORCE
-+ $(call if_changed_dep,as_o_S)
-+
-+$(obj)/fdt-%.o: $(srctree)/lib/%.c FORCE
-+ $(call if_changed_dep,cc_o_c)
-+
-+$(obj)/libstub-%.o: $(srctree)/drivers/firmware/efi/libstub/%.c FORCE
-+ $(call if_changed_dep,cc_o_c)
-+
-+$(obj)/efi-le-stub.elf: LDFLAGS=-EL -Map $@.map -T
-+$(obj)/efi-le-stub.elf: $(src)/efistub-le.lds $(le-targets) FORCE
-+ $(call if_changed,ld)
-+
-+$(obj)/efi-le-stub.bin: OBJCOPYFLAGS=-O binary
-+$(obj)/efi-le-stub.bin: $(obj)/efi-le-stub.elf FORCE
-+ $(call if_changed,objcopy)
-+
-+# the BE object containing the entire LE stub
-+obj-y := efi-le-entry.o
-+
-+$(obj)/efi-le-entry.o: $(obj)/efi-le-stub.bin
-diff --git a/arch/arm64/kernel/efistub-le/efi-le-entry.S b/arch/arm64/kernel/efistub-le/efi-le-entry.S
-new file mode 100644
-index 0000000..755364c
---- /dev/null
-+++ b/arch/arm64/kernel/efistub-le/efi-le-entry.S
-@@ -0,0 +1,12 @@
-+#include <linux/linkage.h>
-+
-+ .text
-+ .align 12
-+ .long _text - efi_stub_entry
-+ .long linux_banner - efi_stub_entry
-+ .quad _kernel_size_le
-+ .quad stext_offset
-+ .quad 0
-+ENTRY(efi_stub_entry)
-+ .incbin "arch/arm64/kernel/efistub-le/efi-le-stub.bin"
-+ENDPROC(efi_stub_entry)
-diff --git a/arch/arm64/kernel/efistub-le/efistub-le.lds b/arch/arm64/kernel/efistub-le/efistub-le.lds
-new file mode 100644
-index 0000000..f64d542
---- /dev/null
-+++ b/arch/arm64/kernel/efistub-le/efistub-le.lds
-@@ -0,0 +1,35 @@
-+
-+ENTRY(efi_stub_entry)
-+
-+SECTIONS {
-+ /*
-+ * The inner and outer alignment of this chunk of code need to be the
-+ * same so that PC relative references using adrp/add or adrp/ldr pairs
-+ * will work correctly.
-+ * Skip 32 bytes here, so we can put the binary blob at an offset of
-+ * 4k + 0x20 in the outer image, and use the gap to share constants
-+ * emitted by the outer linker but required in the stub.
-+ */
-+ .text 0x20 : {
-+ arch/arm64/kernel/efistub-le/efi-entry.o(.init.text)
-+ *(.init.text)
-+ *(.text)
-+ *(.text*)
-+ }
-+ .rodata : {
-+ . = ALIGN(16);
-+ *(.rodata)
-+ *(.rodata*)
-+ *(.init.rodata)
-+ }
-+ .data : {
-+ . = ALIGN(16);
-+ *(.data)
-+ *(.data*)
-+ le_linux_banner = .;
-+ . += 8;
-+ }
-+ /DISCARD/ : {
-+ *(__ex_table)
-+ }
-+}
-diff --git a/arch/arm64/kernel/efistub-le/le.h b/arch/arm64/kernel/efistub-le/le.h
-new file mode 100644
-index 0000000..a9f6dfc
---- /dev/null
-+++ b/arch/arm64/kernel/efistub-le/le.h
-@@ -0,0 +1,12 @@
-+
-+/*
-+ * This is a bit of a hack, but it is necessary to correctly compile .S files
-+ * that contain CPU_LE()/CPU_BE() statements, as these are defined to depend on
-+ * CONFIG_ symbols and not on the endianness of the compiler.
-+ */
-+#ifdef CONFIG_CPU_BIG_ENDIAN
-+#define STUB_BE(code...) code
-+#else
-+#define STUB_BE(code...)
-+#endif
-+#undef CONFIG_CPU_BIG_ENDIAN
-diff --git a/arch/arm64/kernel/efistub-le/strstr.c b/arch/arm64/kernel/efistub-le/strstr.c
-new file mode 100644
-index 0000000..bd16094
---- /dev/null
-+++ b/arch/arm64/kernel/efistub-le/strstr.c
-@@ -0,0 +1,20 @@
-+
-+#include <linux/types.h>
-+#include <linux/string.h>
-+
-+char *strstr(const char *s1, const char *s2)
-+{
-+ size_t l1, l2;
-+
-+ l2 = strlen(s2);
-+ if (!l2)
-+ return (char *)s1;
-+ l1 = strlen(s1);
-+ while (l1 >= l2) {
-+ l1--;
-+ if (!memcmp(s1, s2, l2))
-+ return (char *)s1;
-+ s1++;
-+ }
-+ return NULL;
-+}
-diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
-index 8ce88e0..8b1eba5 100644
---- a/arch/arm64/kernel/head.S
-+++ b/arch/arm64/kernel/head.S
-@@ -126,7 +126,10 @@ efi_head:
- .byte 0x4d
- .byte 0x64
- #ifdef CONFIG_EFI
-- .long pe_header - efi_head // Offset to the PE header.
-+ .byte pe_header - efi_head // Offset to the PE header.
-+ .byte 0
-+ .byte 0
-+ .byte 0
- #else
- .word 0 // reserved
- #endif
-@@ -139,30 +142,31 @@ pe_header:
- .ascii "PE"
- .short 0
- coff_header:
-- .short 0xaa64 // AArch64
-- .short 2 // nr_sections
-+ le16 0xaa64 // AArch64
-+ le16 2 // nr_sections
- .long 0 // TimeDateStamp
- .long 0 // PointerToSymbolTable
-- .long 1 // NumberOfSymbols
-- .short section_table - optional_header // SizeOfOptionalHeader
-- .short 0x206 // Characteristics.
-+ le32 1 // NumberOfSymbols
-+ .byte section_table - optional_header // SizeOfOptionalHeader
-+ .byte 0
-+ le16 0x206 // Characteristics.
- // IMAGE_FILE_DEBUG_STRIPPED |
- // IMAGE_FILE_EXECUTABLE_IMAGE |
- // IMAGE_FILE_LINE_NUMS_STRIPPED
- optional_header:
-- .short 0x20b // PE32+ format
-+ le16 0x20b // PE32+ format
- .byte 0x02 // MajorLinkerVersion
- .byte 0x14 // MinorLinkerVersion
-- .long _end - stext // SizeOfCode
-+ .long _efi_code_virtsize_le // SizeOfCode
- .long 0 // SizeOfInitializedData
- .long 0 // SizeOfUninitializedData
-- .long efi_stub_entry - efi_head // AddressOfEntryPoint
-- .long stext_offset // BaseOfCode
-+ .long _efi_entry_point_le // AddressOfEntryPoint
-+ .long _efi_stext_offset_le // BaseOfCode
-
- extra_header_fields:
- .quad 0 // ImageBase
-- .long 0x1000 // SectionAlignment
-- .long PECOFF_FILE_ALIGNMENT // FileAlignment
-+ le32 0x1000 // SectionAlignment
-+ le32 0x200 // FileAlignment
- .short 0 // MajorOperatingSystemVersion
- .short 0 // MinorOperatingSystemVersion
- .short 0 // MajorImageVersion
-@@ -171,19 +175,19 @@ extra_header_fields:
- .short 0 // MinorSubsystemVersion
- .long 0 // Win32VersionValue
-
-- .long _end - efi_head // SizeOfImage
-+ .long _efi_image_size_le // SizeOfImage
-
- // Everything before the kernel image is considered part of the header
-- .long stext_offset // SizeOfHeaders
-+ .long _efi_stext_offset_le // SizeOfHeaders
- .long 0 // CheckSum
-- .short 0xa // Subsystem (EFI application)
-+ le16 0xa // Subsystem (EFI application)
- .short 0 // DllCharacteristics
- .quad 0 // SizeOfStackReserve
- .quad 0 // SizeOfStackCommit
- .quad 0 // SizeOfHeapReserve
- .quad 0 // SizeOfHeapCommit
- .long 0 // LoaderFlags
-- .long 0x6 // NumberOfRvaAndSizes
-+ le32 0x6 // NumberOfRvaAndSizes
-
- .quad 0 // ExportTable
- .quad 0 // ImportTable
-@@ -211,23 +215,23 @@ section_table:
- .long 0 // PointerToLineNumbers
- .short 0 // NumberOfRelocations
- .short 0 // NumberOfLineNumbers
-- .long 0x42100040 // Characteristics (section flags)
-+ le32 0x42100040 // Characteristics (section flags)
-
-
- .ascii ".text"
- .byte 0
- .byte 0
- .byte 0 // end of 0 padding of section name
-- .long _end - stext // VirtualSize
-- .long stext_offset // VirtualAddress
-- .long _edata - stext // SizeOfRawData
-- .long stext_offset // PointerToRawData
-+ .long _efi_code_virtsize_le // VirtualSize
-+ .long _efi_stext_offset_le // VirtualAddress
-+ .long _efi_code_rawsize_le // SizeOfRawData
-+ .long _efi_stext_offset_le // PointerToRawData
-
- .long 0 // PointerToRelocations (0 for executables)
- .long 0 // PointerToLineNumbers (0 for executables)
- .short 0 // NumberOfRelocations (0 for executables)
- .short 0 // NumberOfLineNumbers (0 for executables)
-- .long 0xe0500020 // Characteristics (section flags)
-+ le32 0xe0500020 // Characteristics (section flags)
-
- /*
- * EFI will load stext onwards at the 4k section alignment
-diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h
-index 8fae075..d08ce56 100644
---- a/arch/arm64/kernel/image.h
-+++ b/arch/arm64/kernel/image.h
-@@ -37,8 +37,10 @@
- (((data) & 0x0000ff0000000000) >> 24) | \
- (((data) & 0x00ff000000000000) >> 40) | \
- (((data) & 0xff00000000000000) >> 56))
-+#define DATA_LE32(data) (DATA_LE64(data) >> 32)
- #else
- #define DATA_LE64(data) ((data) & 0xffffffffffffffff)
-+#define DATA_LE32(data) ((data) & 0xffffffff)
- #endif
-
- #ifdef CONFIG_CPU_BIG_ENDIAN
-@@ -57,6 +59,18 @@
- #define HEAD_SYMBOLS \
- _kernel_size_le = DATA_LE64(_end - _text); \
- _kernel_offset_le = DATA_LE64(TEXT_OFFSET); \
-- _kernel_flags_le = DATA_LE64(__HEAD_FLAGS);
-+ _kernel_flags_le = DATA_LE64(__HEAD_FLAGS); \
-+ EFI_HEAD_SYMBOLS
-+
-+#ifdef CONFIG_EFI
-+#define EFI_HEAD_SYMBOLS \
-+ _efi_stext_offset_le = DATA_LE32(stext_offset); \
-+ _efi_code_virtsize_le = DATA_LE32(_end - _text - stext_offset); \
-+ _efi_code_rawsize_le = DATA_LE32(_edata - _text - stext_offset); \
-+ _efi_image_size_le = DATA_LE32(_end - _text); \
-+ _efi_entry_point_le = DATA_LE32(efi_stub_entry - _text);
-+#else
-+#define EFI_HEAD_SYMBOLS
-+#endif
-
- #endif /* __ASM_IMAGE_H */
-diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
-index 9035c1b..4e98daa 100644
---- a/drivers/firmware/efi/efi.c
-+++ b/drivers/firmware/efi/efi.c
-@@ -296,18 +296,23 @@ static __init int match_config_table(efi_guid_t *guid,
- int __init efi_config_init(efi_config_table_type_t *arch_tables)
- {
- void *config_tables, *tablep;
-- int i, sz;
-+ unsigned long __tables;
-+ int i, sz, nr_tables;
-
-- if (efi_enabled(EFI_64BIT))
-+ if (efi_enabled(EFI_64BIT)) {
- sz = sizeof(efi_config_table_64_t);
-- else
-+ nr_tables = le64_to_cpu((__force __le64)efi.systab->nr_tables);
-+ __tables = le64_to_cpu((__force __le64)efi.systab->tables);
-+ } else {
- sz = sizeof(efi_config_table_32_t);
-+ nr_tables = le32_to_cpu((__force __le32)efi.systab->nr_tables);
-+ __tables = le32_to_cpu((__force __le32)efi.systab->tables);
-+ }
-
- /*
- * Let's see what config tables the firmware passed to us.
- */
-- config_tables = early_memremap(efi.systab->tables,
-- efi.systab->nr_tables * sz);
-+ config_tables = early_memremap(__tables, nr_tables * sz);
- if (config_tables == NULL) {
- pr_err("Could not map Configuration table!\n");
- return -ENOMEM;
-@@ -315,21 +320,20 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
-
- tablep = config_tables;
- pr_info("");
-- for (i = 0; i < efi.systab->nr_tables; i++) {
-+ for (i = 0; i < nr_tables; i++) {
- efi_guid_t guid;
- unsigned long table;
-
- if (efi_enabled(EFI_64BIT)) {
- u64 table64;
- guid = ((efi_config_table_64_t *)tablep)->guid;
-- table64 = ((efi_config_table_64_t *)tablep)->table;
-- table = table64;
-+ table = table64 = le64_to_cpu((__force __le64)
-+ ((efi_config_table_64_t *)tablep)->table);
- #ifndef CONFIG_64BIT
- if (table64 >> 32) {
- pr_cont("\n");
- pr_err("Table located above 4GB, disabling EFI.\n");
-- early_memunmap(config_tables,
-- efi.systab->nr_tables * sz);
-+ early_memunmap(config_tables, nr_tables * sz);
- return -EINVAL;
- }
- #endif
-@@ -344,7 +348,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
- tablep += sz;
- }
- pr_cont("\n");
-- early_memunmap(config_tables, efi.systab->nr_tables * sz);
-+ early_memunmap(config_tables, nr_tables * sz);
-
- set_bit(EFI_CONFIG_TABLES, &efi.flags);
-
-diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
-index f256ecd..2b1c8be 100644
---- a/drivers/firmware/efi/efivars.c
-+++ b/drivers/firmware/efi/efivars.c
-@@ -563,7 +563,7 @@ efivar_create_sysfs_entry(struct efivar_entry *new_var)
- /* Convert Unicode to normal chars (assume top bits are 0),
- ala UTF-8 */
- for (i=0; i < (int)(variable_name_size / sizeof(efi_char16_t)); i++) {
-- short_name[i] = variable_name[i] & 0xFF;
-+ short_name[i] = le16_to_cpu((__force __le16)variable_name[i]);
- }
- /* This is ugly, but necessary to separate one vendor's
- private variables from another's. */
-diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
-index c846a96..f0f9d54 100644
---- a/drivers/firmware/efi/libstub/fdt.c
-+++ b/drivers/firmware/efi/libstub/fdt.c
-@@ -22,6 +22,10 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
- unsigned long map_size, unsigned long desc_size,
- u32 desc_ver)
- {
-+#ifdef CONFIG_EFI_LE_STUB
-+ extern char const *le_linux_banner;
-+ char const *linux_banner = le_linux_banner;
-+#endif
- int node, prev, num_rsv;
- int status;
- u32 fdt_val32;
---
-1.9.1
-