If we are running a BE kernel, we need to byte reverse all data that UEFI keeps,
as UEFI is strictly little endian.

Signed-off-by: Ard Biesheuvel <ard.biesheu...@linaro.org>
---
 arch/arm64/kernel/efi.c        | 53 +++++++++++++++++++++++-------------------
 drivers/firmware/efi/efi.c     | 26 ++++++++++++---------
 drivers/firmware/efi/efivars.c |  2 +-
 3 files changed, 45 insertions(+), 36 deletions(-)

diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index e72f3100958f..96df58824189 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -42,7 +42,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;
 }
@@ -58,10 +58,11 @@ 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);
@@ -87,27 +88,27 @@ 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");
                return -EINVAL;
        }
-       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';
        }
 
        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);
        if (retval == 0)
@@ -144,11 +145,11 @@ static __init int is_reserve_region(efi_memory_desc_t *md)
        if (!is_normal_ram(md))
                return 0;
 
-       if (md->attribute & EFI_MEMORY_RUNTIME)
+       if (le64_to_cpu(md->attribute) & EFI_MEMORY_RUNTIME)
                return 1;
 
-       if (md->type == EFI_ACPI_RECLAIM_MEMORY ||
-           md->type == EFI_RESERVED_TYPE)
+       if (le32_to_cpu(md->type) == EFI_ACPI_RECLAIM_MEMORY ||
+           le32_to_cpu(md->type) == EFI_RESERVED_TYPE)
                return 1;
 
        return 0;
@@ -163,13 +164,15 @@ 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)
                        pr_info("  0x%012llx-0x%012llx [%s]",
                                paddr, paddr + (npages << EFI_PAGE_SHIFT) - 1,
-                               memory_type_name[md->type]);
+                               memory_type_name[md_type]);
 
                memrange_efi_to_native(&paddr, &npages);
                size = npages << PAGE_SHIFT;
@@ -178,8 +181,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("*");
@@ -258,17 +261,18 @@ 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;
                }
@@ -276,8 +280,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;
 
@@ -475,3 +479,4 @@ err_unmap:
        return -1;
 }
 early_initcall(arm64_enter_virtual_mode);
+
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 64ecbb501c50..24cb61b72d06 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -270,18 +270,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;
@@ -289,21 +294,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
@@ -318,7 +322,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 f256ecd8a176..e33181a779ab 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.         */
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-efi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to