[RFC PATCH 08/10] arm64/efi: use LE accessors to access UEFI data
Ard Biesheuvel
ard.biesheuvel at linaro.org
Mon Jul 21 08:16:23 PDT 2014
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.biesheuvel at 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
More information about the linux-arm-kernel
mailing list