* [PATCH v4 04/13] arm64/efi: split off EFI init and runtime code for reuse by 32-bit ARM
[not found] ` <1448886507-3216-1-git-send-email-ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2015-11-30 12:28 ` Ard Biesheuvel
2015-11-30 12:28 ` [PATCH v4 06/13] ARM: add support for generic early_ioremap/early_memremap Ard Biesheuvel
` (7 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Ard Biesheuvel @ 2015-11-30 12:28 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
mark.rutland-5wv7dgnIgG8, linux-efi-u79uwXL29TY76Z2rM5mHXA,
leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
matt-mF/unelCI9GS6iBeEJttW/XRex20P6io,
linux-lFZ/pmaqli7XmaaqVzeoHQ
Cc: akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
kuleshovmail-Re5JQEeQqe8AvxtiuMwx3w,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
ryan.harkin-QSEj5FYQhm4dnm+yROfE0A,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
roy.franz-QSEj5FYQhm4dnm+yROfE0A, msalter-H+wXaHxf7aLQT0dZR+AlfA,
Ard Biesheuvel
This splits off the early EFI init and runtime code that
- discovers the EFI params and the memory map from the FDT, and installs
the memblocks and config tables.
- prepares and installs the EFI page tables so that UEFI Runtime Services
can be invoked at the virtual address installed by the stub.
This will allow it to be reused for 32-bit ARM.
Reviewed-by: Matt Fleming <matt-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
arch/arm64/kernel/efi.c | 326 +-------------------
drivers/firmware/efi/Makefile | 3 +
drivers/firmware/efi/arm-init.c | 208 +++++++++++++
drivers/firmware/efi/arm-runtime.c | 151 +++++++++
4 files changed, 363 insertions(+), 325 deletions(-)
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 04531d35f1df..bd3b2f5adf0c 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -11,318 +11,11 @@
*
*/
-#include <linux/atomic.h>
#include <linux/dmi.h>
#include <linux/efi.h>
-#include <linux/export.h>
-#include <linux/memblock.h>
-#include <linux/mm_types.h>
-#include <linux/bootmem.h>
-#include <linux/of.h>
-#include <linux/of_fdt.h>
-#include <linux/preempt.h>
-#include <linux/rbtree.h>
-#include <linux/rwsem.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
+#include <linux/init.h>
-#include <asm/cacheflush.h>
#include <asm/efi.h>
-#include <asm/tlbflush.h>
-#include <asm/mmu_context.h>
-#include <asm/mmu.h>
-#include <asm/pgtable.h>
-
-struct efi_memory_map memmap;
-
-static u64 efi_system_table;
-
-static pgd_t efi_pgd[PTRS_PER_PGD] __page_aligned_bss;
-
-static struct mm_struct efi_mm = {
- .mm_rb = RB_ROOT,
- .pgd = efi_pgd,
- .mm_users = ATOMIC_INIT(2),
- .mm_count = ATOMIC_INIT(1),
- .mmap_sem = __RWSEM_INITIALIZER(efi_mm.mmap_sem),
- .page_table_lock = __SPIN_LOCK_UNLOCKED(efi_mm.page_table_lock),
- .mmlist = LIST_HEAD_INIT(efi_mm.mmlist),
-};
-
-static int __init is_normal_ram(efi_memory_desc_t *md)
-{
- if (md->attribute & EFI_MEMORY_WB)
- return 1;
- return 0;
-}
-
-/*
- * Translate a EFI virtual address into a physical address: this is necessary,
- * as some data members of the EFI system table are virtually remapped after
- * SetVirtualAddressMap() has been called.
- */
-static phys_addr_t efi_to_phys(unsigned long addr)
-{
- efi_memory_desc_t *md;
-
- for_each_efi_memory_desc(&memmap, md) {
- if (!(md->attribute & EFI_MEMORY_RUNTIME))
- continue;
- if (md->virt_addr == 0)
- /* no virtual mapping has been installed by the stub */
- break;
- if (md->virt_addr <= addr &&
- (addr - md->virt_addr) < (md->num_pages << EFI_PAGE_SHIFT))
- return md->phys_addr + addr - md->virt_addr;
- }
- return addr;
-}
-
-static int __init uefi_init(void)
-{
- efi_char16_t *c16;
- void *config_tables;
- u64 table_size;
- char vendor[100] = "unknown";
- int i, retval;
-
- efi.systab = early_memremap(efi_system_table,
- sizeof(efi_system_table_t));
- if (efi.systab == NULL) {
- pr_warn("Unable to map EFI system table.\n");
- return -ENOMEM;
- }
-
- set_bit(EFI_BOOT, &efi.flags);
- set_bit(EFI_64BIT, &efi.flags);
-
- /*
- * Verify the EFI Table
- */
- if (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)
- 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_to_phys(efi.systab->fw_vendor),
- sizeof(vendor) * sizeof(efi_char16_t));
- if (c16) {
- for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i)
- vendor[i] = c16[i];
- vendor[i] = '\0';
- early_memunmap(c16, sizeof(vendor) * sizeof(efi_char16_t));
- }
-
- pr_info("EFI v%u.%.02u by %s\n",
- efi.systab->hdr.revision >> 16,
- efi.systab->hdr.revision & 0xffff, vendor);
-
- table_size = sizeof(efi_config_table_64_t) * efi.systab->nr_tables;
- config_tables = early_memremap(efi_to_phys(efi.systab->tables),
- table_size);
- if (config_tables == NULL) {
- pr_warn("Unable to map EFI config table array.\n");
- retval = -ENOMEM;
- goto out;
- }
- retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables,
- sizeof(efi_config_table_64_t), NULL);
-
- early_memunmap(config_tables, table_size);
-out:
- early_memunmap(efi.systab, sizeof(efi_system_table_t));
- return retval;
-}
-
-/*
- * Return true for RAM regions we want to permanently reserve.
- */
-static __init int is_reserve_region(efi_memory_desc_t *md)
-{
- switch (md->type) {
- case EFI_LOADER_CODE:
- case EFI_LOADER_DATA:
- case EFI_BOOT_SERVICES_CODE:
- case EFI_BOOT_SERVICES_DATA:
- case EFI_CONVENTIONAL_MEMORY:
- case EFI_PERSISTENT_MEMORY:
- return 0;
- default:
- break;
- }
- return is_normal_ram(md);
-}
-
-static __init void reserve_regions(void)
-{
- efi_memory_desc_t *md;
- u64 paddr, npages, size;
-
- if (efi_enabled(EFI_DBG))
- pr_info("Processing EFI memory map:\n");
-
- for_each_efi_memory_desc(&memmap, md) {
- paddr = md->phys_addr;
- npages = md->num_pages;
-
- if (efi_enabled(EFI_DBG)) {
- char buf[64];
-
- pr_info(" 0x%012llx-0x%012llx %s",
- paddr, paddr + (npages << EFI_PAGE_SHIFT) - 1,
- efi_md_typeattr_format(buf, sizeof(buf), md));
- }
-
- memrange_efi_to_native(&paddr, &npages);
- size = npages << PAGE_SHIFT;
-
- if (is_normal_ram(md))
- early_init_dt_add_memory_arch(paddr, size);
-
- if (is_reserve_region(md)) {
- memblock_mark_nomap(paddr, size);
- if (efi_enabled(EFI_DBG))
- pr_cont("*");
- }
-
- if (efi_enabled(EFI_DBG))
- pr_cont("\n");
- }
-
- set_bit(EFI_MEMMAP, &efi.flags);
-}
-
-void __init efi_init(void)
-{
- struct efi_fdt_params params;
-
- /* Grab UEFI information placed in FDT by stub */
- if (!efi_get_fdt_params(¶ms))
- return;
-
- efi_system_table = params.system_table;
-
- memmap.phys_map = params.mmap;
- memmap.map = early_memremap(params.mmap, params.mmap_size);
- if (memmap.map == NULL) {
- /*
- * If we are booting via UEFI, the UEFI memory map is the only
- * description of memory we have, so there is little point in
- * proceeding if we cannot access it.
- */
- panic("Unable to map EFI memory map.\n");
- }
- memmap.map_end = memmap.map + params.mmap_size;
- memmap.desc_size = params.desc_size;
- memmap.desc_version = params.desc_ver;
-
- if (uefi_init() < 0)
- return;
-
- reserve_regions();
- early_memunmap(memmap.map, params.mmap_size);
- memblock_mark_nomap(params.mmap & PAGE_MASK,
- PAGE_ALIGN(params.mmap_size +
- (params.mmap & ~PAGE_MASK)));
-}
-
-static bool __init efi_virtmap_init(void)
-{
- efi_memory_desc_t *md;
-
- init_new_context(NULL, &efi_mm);
-
- for_each_efi_memory_desc(&memmap, md) {
- pgprot_t prot;
-
- if (!(md->attribute & EFI_MEMORY_RUNTIME))
- continue;
- if (md->virt_addr == 0)
- return false;
-
- pr_info(" EFI remap 0x%016llx => %p\n",
- md->phys_addr, (void *)md->virt_addr);
-
- /*
- * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be
- * executable, everything else can be mapped with the XN bits
- * set.
- */
- if (!is_normal_ram(md))
- prot = __pgprot(PROT_DEVICE_nGnRE);
- else if (md->type == EFI_RUNTIME_SERVICES_CODE ||
- !PAGE_ALIGNED(md->phys_addr))
- prot = PAGE_KERNEL_EXEC;
- else
- prot = PAGE_KERNEL;
-
- create_pgd_mapping(&efi_mm, md->phys_addr, md->virt_addr,
- md->num_pages << EFI_PAGE_SHIFT,
- __pgprot(pgprot_val(prot) | PTE_NG));
- }
- return true;
-}
-
-/*
- * Enable the UEFI Runtime Services if all prerequisites are in place, i.e.,
- * non-early mapping of the UEFI system table and virtual mappings for all
- * EFI_MEMORY_RUNTIME regions.
- */
-static int __init arm64_enable_runtime_services(void)
-{
- u64 mapsize;
-
- if (!efi_enabled(EFI_BOOT)) {
- pr_info("EFI services will not be available.\n");
- return 0;
- }
-
- if (efi_runtime_disabled()) {
- pr_info("EFI runtime services will be disabled.\n");
- return 0;
- }
-
- pr_info("Remapping and enabling EFI services.\n");
-
- mapsize = memmap.map_end - memmap.map;
- memmap.map = (__force void *)ioremap_cache(memmap.phys_map,
- mapsize);
- if (!memmap.map) {
- pr_err("Failed to remap EFI memory map\n");
- return -ENOMEM;
- }
- memmap.map_end = memmap.map + mapsize;
- efi.memmap = &memmap;
-
- efi.systab = (__force void *)ioremap_cache(efi_system_table,
- sizeof(efi_system_table_t));
- if (!efi.systab) {
- pr_err("Failed to remap EFI System Table\n");
- return -ENOMEM;
- }
- set_bit(EFI_SYSTEM_TABLES, &efi.flags);
-
- if (!efi_virtmap_init()) {
- pr_err("No UEFI virtual mapping was installed -- runtime services will not be available\n");
- return -ENOMEM;
- }
-
- /* Set up runtime services function pointers */
- efi_native_runtime_setup();
- set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
-
- efi.runtime_version = efi.systab->hdr.revision;
-
- return 0;
-}
-early_initcall(arm64_enable_runtime_services);
static int __init arm64_dmi_init(void)
{
@@ -338,23 +31,6 @@ static int __init arm64_dmi_init(void)
}
core_initcall(arm64_dmi_init);
-static void efi_set_pgd(struct mm_struct *mm)
-{
- switch_mm(NULL, mm, NULL);
-}
-
-void efi_virtmap_load(void)
-{
- preempt_disable();
- efi_set_pgd(&efi_mm);
-}
-
-void efi_virtmap_unload(void)
-{
- efi_set_pgd(current->active_mm);
- preempt_enable();
-}
-
/*
* UpdateCapsule() depends on the system being shutdown via
* ResetSystem().
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index ec379a4164cc..f292917b00e7 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -18,3 +18,6 @@ obj-$(CONFIG_EFI_RUNTIME_MAP) += runtime-map.o
obj-$(CONFIG_EFI_RUNTIME_WRAPPERS) += runtime-wrappers.o
obj-$(CONFIG_EFI_STUB) += libstub/
obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_mem.o
+
+arm-obj-$(CONFIG_EFI) := arm-init.o arm-runtime.o
+obj-$(CONFIG_ARM64) += $(arm-obj-y)
diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c
new file mode 100644
index 000000000000..ffdd76a51929
--- /dev/null
+++ b/drivers/firmware/efi/arm-init.c
@@ -0,0 +1,208 @@
+/*
+ * Extensible Firmware Interface
+ *
+ * Based on Extensible Firmware Interface Specification version 2.4
+ *
+ * Copyright (C) 2013 - 2015 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/efi.h>
+#include <linux/init.h>
+#include <linux/memblock.h>
+#include <linux/mm_types.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+
+#include <asm/efi.h>
+
+struct efi_memory_map memmap;
+
+u64 efi_system_table;
+
+static int __init is_normal_ram(efi_memory_desc_t *md)
+{
+ if (md->attribute & EFI_MEMORY_WB)
+ return 1;
+ return 0;
+}
+
+/*
+ * Translate a EFI virtual address into a physical address: this is necessary,
+ * as some data members of the EFI system table are virtually remapped after
+ * SetVirtualAddressMap() has been called.
+ */
+static phys_addr_t efi_to_phys(unsigned long addr)
+{
+ efi_memory_desc_t *md;
+
+ for_each_efi_memory_desc(&memmap, md) {
+ if (!(md->attribute & EFI_MEMORY_RUNTIME))
+ continue;
+ if (md->virt_addr == 0)
+ /* no virtual mapping has been installed by the stub */
+ break;
+ if (md->virt_addr <= addr &&
+ (addr - md->virt_addr) < (md->num_pages << EFI_PAGE_SHIFT))
+ return md->phys_addr + addr - md->virt_addr;
+ }
+ return addr;
+}
+
+static int __init uefi_init(void)
+{
+ efi_char16_t *c16;
+ void *config_tables;
+ u64 table_size;
+ char vendor[100] = "unknown";
+ int i, retval;
+
+ efi.systab = early_memremap(efi_system_table,
+ sizeof(efi_system_table_t));
+ if (efi.systab == NULL) {
+ pr_warn("Unable to map EFI system table.\n");
+ return -ENOMEM;
+ }
+
+ set_bit(EFI_BOOT, &efi.flags);
+ set_bit(EFI_64BIT, &efi.flags);
+
+ /*
+ * Verify the EFI Table
+ */
+ if (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)
+ 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_to_phys(efi.systab->fw_vendor),
+ sizeof(vendor) * sizeof(efi_char16_t));
+ if (c16) {
+ for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i)
+ vendor[i] = c16[i];
+ vendor[i] = '\0';
+ early_memunmap(c16, sizeof(vendor) * sizeof(efi_char16_t));
+ }
+
+ pr_info("EFI v%u.%.02u by %s\n",
+ efi.systab->hdr.revision >> 16,
+ efi.systab->hdr.revision & 0xffff, vendor);
+
+ table_size = sizeof(efi_config_table_64_t) * efi.systab->nr_tables;
+ config_tables = early_memremap(efi_to_phys(efi.systab->tables),
+ table_size);
+ if (config_tables == NULL) {
+ pr_warn("Unable to map EFI config table array.\n");
+ retval = -ENOMEM;
+ goto out;
+ }
+ retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables,
+ sizeof(efi_config_table_64_t), NULL);
+
+ early_memunmap(config_tables, table_size);
+out:
+ early_memunmap(efi.systab, sizeof(efi_system_table_t));
+ return retval;
+}
+
+/*
+ * Return true for RAM regions we want to permanently reserve.
+ */
+static __init int is_reserve_region(efi_memory_desc_t *md)
+{
+ switch (md->type) {
+ case EFI_LOADER_CODE:
+ case EFI_LOADER_DATA:
+ case EFI_BOOT_SERVICES_CODE:
+ case EFI_BOOT_SERVICES_DATA:
+ case EFI_CONVENTIONAL_MEMORY:
+ case EFI_PERSISTENT_MEMORY:
+ return 0;
+ default:
+ break;
+ }
+ return is_normal_ram(md);
+}
+
+static __init void reserve_regions(void)
+{
+ efi_memory_desc_t *md;
+ u64 paddr, npages, size;
+
+ if (efi_enabled(EFI_DBG))
+ pr_info("Processing EFI memory map:\n");
+
+ for_each_efi_memory_desc(&memmap, md) {
+ paddr = md->phys_addr;
+ npages = md->num_pages;
+
+ if (efi_enabled(EFI_DBG)) {
+ char buf[64];
+
+ pr_info(" 0x%012llx-0x%012llx %s",
+ paddr, paddr + (npages << EFI_PAGE_SHIFT) - 1,
+ efi_md_typeattr_format(buf, sizeof(buf), md));
+ }
+
+ memrange_efi_to_native(&paddr, &npages);
+ size = npages << PAGE_SHIFT;
+
+ if (is_normal_ram(md))
+ early_init_dt_add_memory_arch(paddr, size);
+
+ if (is_reserve_region(md)) {
+ memblock_mark_nomap(paddr, size);
+ if (efi_enabled(EFI_DBG))
+ pr_cont("*");
+ }
+
+ if (efi_enabled(EFI_DBG))
+ pr_cont("\n");
+ }
+
+ set_bit(EFI_MEMMAP, &efi.flags);
+}
+
+void __init efi_init(void)
+{
+ struct efi_fdt_params params;
+
+ /* Grab UEFI information placed in FDT by stub */
+ if (!efi_get_fdt_params(¶ms))
+ return;
+
+ efi_system_table = params.system_table;
+
+ memmap.phys_map = params.mmap;
+ memmap.map = early_memremap(params.mmap, params.mmap_size);
+ if (memmap.map == NULL) {
+ /*
+ * If we are booting via UEFI, the UEFI memory map is the only
+ * description of memory we have, so there is little point in
+ * proceeding if we cannot access it.
+ */
+ panic("Unable to map EFI memory map.\n");
+ }
+ memmap.map_end = memmap.map + params.mmap_size;
+ memmap.desc_size = params.desc_size;
+ memmap.desc_version = params.desc_ver;
+
+ if (uefi_init() < 0)
+ return;
+
+ reserve_regions();
+ early_memunmap(memmap.map, params.mmap_size);
+ memblock_mark_nomap(params.mmap & PAGE_MASK,
+ PAGE_ALIGN(params.mmap_size +
+ (params.mmap & ~PAGE_MASK)));
+}
diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c
new file mode 100644
index 000000000000..974743e13a4d
--- /dev/null
+++ b/drivers/firmware/efi/arm-runtime.c
@@ -0,0 +1,151 @@
+/*
+ * Extensible Firmware Interface
+ *
+ * Based on Extensible Firmware Interface Specification version 2.4
+ *
+ * Copyright (C) 2013, 2014 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/efi.h>
+#include <linux/memblock.h>
+#include <linux/mm_types.h>
+#include <linux/preempt.h>
+#include <linux/rbtree.h>
+#include <linux/rwsem.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include <asm/cacheflush.h>
+#include <asm/efi.h>
+#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+
+static pgd_t efi_pgd[PTRS_PER_PGD] __page_aligned_bss;
+
+extern u64 efi_system_table;
+
+static struct mm_struct efi_mm = {
+ .mm_rb = RB_ROOT,
+ .pgd = efi_pgd,
+ .mm_users = ATOMIC_INIT(2),
+ .mm_count = ATOMIC_INIT(1),
+ .mmap_sem = __RWSEM_INITIALIZER(efi_mm.mmap_sem),
+ .page_table_lock = __SPIN_LOCK_UNLOCKED(efi_mm.page_table_lock),
+ .mmlist = LIST_HEAD_INIT(efi_mm.mmlist),
+};
+
+static bool __init efi_virtmap_init(void)
+{
+ efi_memory_desc_t *md;
+
+ init_new_context(NULL, &efi_mm);
+
+ for_each_efi_memory_desc(&memmap, md) {
+ pgprot_t prot;
+
+ if (!(md->attribute & EFI_MEMORY_RUNTIME))
+ continue;
+ if (md->virt_addr == 0)
+ return false;
+
+ pr_info(" EFI remap 0x%016llx => %p\n",
+ md->phys_addr, (void *)md->virt_addr);
+
+ /*
+ * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be
+ * executable, everything else can be mapped with the XN bits
+ * set.
+ */
+ if ((md->attribute & EFI_MEMORY_WB) == 0)
+ prot = __pgprot(PROT_DEVICE_nGnRE);
+ else if (md->type == EFI_RUNTIME_SERVICES_CODE ||
+ !PAGE_ALIGNED(md->phys_addr))
+ prot = PAGE_KERNEL_EXEC;
+ else
+ prot = PAGE_KERNEL;
+
+ create_pgd_mapping(&efi_mm, md->phys_addr, md->virt_addr,
+ md->num_pages << EFI_PAGE_SHIFT,
+ __pgprot(pgprot_val(prot) | PTE_NG));
+ }
+ return true;
+}
+
+/*
+ * Enable the UEFI Runtime Services if all prerequisites are in place, i.e.,
+ * non-early mapping of the UEFI system table and virtual mappings for all
+ * EFI_MEMORY_RUNTIME regions.
+ */
+static int __init arm64_enable_runtime_services(void)
+{
+ u64 mapsize;
+
+ if (!efi_enabled(EFI_BOOT)) {
+ pr_info("EFI services will not be available.\n");
+ return 0;
+ }
+
+ if (efi_runtime_disabled()) {
+ pr_info("EFI runtime services will be disabled.\n");
+ return 0;
+ }
+
+ pr_info("Remapping and enabling EFI services.\n");
+
+ mapsize = memmap.map_end - memmap.map;
+ memmap.map = (__force void *)ioremap_cache(memmap.phys_map,
+ mapsize);
+ if (!memmap.map) {
+ pr_err("Failed to remap EFI memory map\n");
+ return -ENOMEM;
+ }
+ memmap.map_end = memmap.map + mapsize;
+ efi.memmap = &memmap;
+
+ efi.systab = (__force void *)ioremap_cache(efi_system_table,
+ sizeof(efi_system_table_t));
+ if (!efi.systab) {
+ pr_err("Failed to remap EFI System Table\n");
+ return -ENOMEM;
+ }
+ set_bit(EFI_SYSTEM_TABLES, &efi.flags);
+
+ if (!efi_virtmap_init()) {
+ pr_err("No UEFI virtual mapping was installed -- runtime services will not be available\n");
+ return -ENOMEM;
+ }
+
+ /* Set up runtime services function pointers */
+ efi_native_runtime_setup();
+ set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
+
+ efi.runtime_version = efi.systab->hdr.revision;
+
+ return 0;
+}
+early_initcall(arm64_enable_runtime_services);
+
+static void efi_set_pgd(struct mm_struct *mm)
+{
+ switch_mm(NULL, mm, NULL);
+}
+
+void efi_virtmap_load(void)
+{
+ preempt_disable();
+ efi_set_pgd(&efi_mm);
+}
+
+void efi_virtmap_unload(void)
+{
+ efi_set_pgd(current->active_mm);
+ preempt_enable();
+}
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 06/13] ARM: add support for generic early_ioremap/early_memremap
[not found] ` <1448886507-3216-1-git-send-email-ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2015-11-30 12:28 ` [PATCH v4 04/13] arm64/efi: split off EFI init and runtime code for reuse by 32-bit ARM Ard Biesheuvel
@ 2015-11-30 12:28 ` Ard Biesheuvel
2015-11-30 12:28 ` [PATCH v4 07/13] ARM: split off core mapping logic from create_mapping Ard Biesheuvel
` (6 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Ard Biesheuvel @ 2015-11-30 12:28 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
mark.rutland-5wv7dgnIgG8, linux-efi-u79uwXL29TY76Z2rM5mHXA,
leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
matt-mF/unelCI9GS6iBeEJttW/XRex20P6io,
linux-lFZ/pmaqli7XmaaqVzeoHQ
Cc: akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
kuleshovmail-Re5JQEeQqe8AvxtiuMwx3w,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
ryan.harkin-QSEj5FYQhm4dnm+yROfE0A,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
roy.franz-QSEj5FYQhm4dnm+yROfE0A, msalter-H+wXaHxf7aLQT0dZR+AlfA,
Ard Biesheuvel
This enables the generic early_ioremap implementation for ARM.
It uses the fixmap region reserved for kmap. Since early_ioremap
is only supported before paging_init(), and kmap is only supported
afterwards, this is guaranteed not to cause any clashes.
Tested-by: Ryan Harkin <ryan.harkin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Matt Fleming <matt-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
arch/arm/Kconfig | 1 +
arch/arm/include/asm/Kbuild | 1 +
arch/arm/include/asm/fixmap.h | 29 +++++++++++++++++++-
arch/arm/kernel/setup.c | 7 +++--
arch/arm/mm/ioremap.c | 9 ++++++
arch/arm/mm/mmu.c | 2 +-
6 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 34e1569a11ee..446e49b56e6a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -20,6 +20,7 @@ config ARM
select GENERIC_ALLOCATOR
select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI)
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
+ select GENERIC_EARLY_IOREMAP
select GENERIC_IDLE_POLL_SETUP
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index bd425302c97a..16da6380eb85 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -3,6 +3,7 @@
generic-y += bitsperlong.h
generic-y += cputime.h
generic-y += current.h
+generic-y += early_ioremap.h
generic-y += emergency-restart.h
generic-y += errno.h
generic-y += exec.h
diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
index 58cfe9f1a687..5c17d2dec777 100644
--- a/arch/arm/include/asm/fixmap.h
+++ b/arch/arm/include/asm/fixmap.h
@@ -19,20 +19,47 @@ enum fixed_addresses {
FIX_TEXT_POKE0,
FIX_TEXT_POKE1,
- __end_of_fixed_addresses
+ __end_of_fixmap_region,
+
+ /*
+ * Share the kmap() region with early_ioremap(): this is guaranteed
+ * not to clash since early_ioremap() is only available before
+ * paging_init(), and kmap() only after.
+ */
+#define NR_FIX_BTMAPS 32
+#define FIX_BTMAPS_SLOTS 7
+#define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)
+
+ FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
+ FIX_BTMAP_BEGIN = FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1,
+ __end_of_early_ioremap_region
};
+static const enum fixed_addresses __end_of_fixed_addresses =
+ __end_of_fixmap_region > __end_of_early_ioremap_region ?
+ __end_of_fixmap_region : __end_of_early_ioremap_region;
+
#define FIXMAP_PAGE_COMMON (L_PTE_YOUNG | L_PTE_PRESENT | L_PTE_XN | L_PTE_DIRTY)
#define FIXMAP_PAGE_NORMAL (FIXMAP_PAGE_COMMON | L_PTE_MT_WRITEBACK)
+#define FIXMAP_PAGE_RO (FIXMAP_PAGE_NORMAL | L_PTE_RDONLY)
/* Used by set_fixmap_(io|nocache), both meant for mapping a device */
#define FIXMAP_PAGE_IO (FIXMAP_PAGE_COMMON | L_PTE_MT_DEV_SHARED | L_PTE_SHARED)
#define FIXMAP_PAGE_NOCACHE FIXMAP_PAGE_IO
+#define __early_set_fixmap __set_fixmap
+
+#ifdef CONFIG_MMU
+
void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot);
void __init early_fixmap_init(void);
#include <asm-generic/fixmap.h>
+#else
+
+static inline void early_fixmap_init(void) { }
+
+#endif
#endif
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 20edd349d379..5df2bca57c42 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -38,6 +38,7 @@
#include <asm/cpu.h>
#include <asm/cputype.h>
#include <asm/elf.h>
+#include <asm/early_ioremap.h>
#include <asm/fixmap.h>
#include <asm/procinfo.h>
#include <asm/psci.h>
@@ -956,8 +957,8 @@ void __init setup_arch(char **cmdline_p)
strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
*cmdline_p = cmd_line;
- if (IS_ENABLED(CONFIG_FIX_EARLYCON_MEM))
- early_fixmap_init();
+ early_fixmap_init();
+ early_ioremap_init();
parse_early_param();
@@ -968,6 +969,8 @@ void __init setup_arch(char **cmdline_p)
sanity_check_meminfo();
arm_memblock_init(mdesc);
+ early_ioremap_reset();
+
paging_init(mdesc);
request_standard_resources(mdesc);
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 0c81056c1dd7..66a978d05958 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -30,6 +30,7 @@
#include <asm/cp15.h>
#include <asm/cputype.h>
#include <asm/cacheflush.h>
+#include <asm/early_ioremap.h>
#include <asm/mmu_context.h>
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
@@ -469,3 +470,11 @@ int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr)
}
EXPORT_SYMBOL_GPL(pci_ioremap_io);
#endif
+
+/*
+ * Must be called after early_fixmap_init
+ */
+void __init early_ioremap_init(void)
+{
+ early_ioremap_setup();
+}
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 4867f5daf82c..de19f90221e2 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -390,7 +390,7 @@ void __init early_fixmap_init(void)
* The early fixmap range spans multiple pmds, for which
* we are not prepared:
*/
- BUILD_BUG_ON((__fix_to_virt(__end_of_permanent_fixed_addresses) >> PMD_SHIFT)
+ BUILD_BUG_ON((__fix_to_virt(__end_of_early_ioremap_region) >> PMD_SHIFT)
!= FIXADDR_TOP >> PMD_SHIFT);
pmd = fixmap_pmd(FIXADDR_TOP);
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 07/13] ARM: split off core mapping logic from create_mapping
[not found] ` <1448886507-3216-1-git-send-email-ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2015-11-30 12:28 ` [PATCH v4 04/13] arm64/efi: split off EFI init and runtime code for reuse by 32-bit ARM Ard Biesheuvel
2015-11-30 12:28 ` [PATCH v4 06/13] ARM: add support for generic early_ioremap/early_memremap Ard Biesheuvel
@ 2015-11-30 12:28 ` Ard Biesheuvel
2015-11-30 12:28 ` [PATCH v4 09/13] ARM: add support for non-global kernel mappings Ard Biesheuvel
` (5 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Ard Biesheuvel @ 2015-11-30 12:28 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
mark.rutland-5wv7dgnIgG8, linux-efi-u79uwXL29TY76Z2rM5mHXA,
leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
matt-mF/unelCI9GS6iBeEJttW/XRex20P6io,
linux-lFZ/pmaqli7XmaaqVzeoHQ
Cc: akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
kuleshovmail-Re5JQEeQqe8AvxtiuMwx3w,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
ryan.harkin-QSEj5FYQhm4dnm+yROfE0A,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
roy.franz-QSEj5FYQhm4dnm+yROfE0A, msalter-H+wXaHxf7aLQT0dZR+AlfA,
Ard Biesheuvel
In order to be able to reuse the core mapping logic of create_mapping
for mapping the UEFI Runtime Services into a private set of page tables,
split it off from create_mapping() into a separate function
__create_mapping which we will wire up in a subsequent patch.
Tested-by: Ryan Harkin <ryan.harkin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Matt Fleming <matt-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
arch/arm/mm/mmu.c | 56 +++++++++++---------
1 file changed, 31 insertions(+), 25 deletions(-)
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index de19f90221e2..3100de92148b 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -818,7 +818,8 @@ static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
}
#ifndef CONFIG_ARM_LPAE
-static void __init create_36bit_mapping(struct map_desc *md,
+static void __init create_36bit_mapping(struct mm_struct *mm,
+ struct map_desc *md,
const struct mem_type *type)
{
unsigned long addr, length, end;
@@ -859,7 +860,7 @@ static void __init create_36bit_mapping(struct map_desc *md,
*/
phys |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20);
- pgd = pgd_offset_k(addr);
+ pgd = pgd_offset(mm, addr);
end = addr + length;
do {
pud_t *pud = pud_offset(pgd, addr);
@@ -876,33 +877,13 @@ static void __init create_36bit_mapping(struct map_desc *md,
}
#endif /* !CONFIG_ARM_LPAE */
-/*
- * Create the page directory entries and any necessary
- * page tables for the mapping specified by `md'. We
- * are able to cope here with varying sizes and address
- * offsets, and we take full advantage of sections and
- * supersections.
- */
-static void __init create_mapping(struct map_desc *md)
+static void __init __create_mapping(struct mm_struct *mm, struct map_desc *md)
{
unsigned long addr, length, end;
phys_addr_t phys;
const struct mem_type *type;
pgd_t *pgd;
- if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
- pr_warn("BUG: not creating mapping for 0x%08llx at 0x%08lx in user region\n",
- (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
- return;
- }
-
- if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
- md->virtual >= PAGE_OFFSET && md->virtual < FIXADDR_START &&
- (md->virtual < VMALLOC_START || md->virtual >= VMALLOC_END)) {
- pr_warn("BUG: mapping for 0x%08llx at 0x%08lx out of vmalloc space\n",
- (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
- }
-
type = &mem_types[md->type];
#ifndef CONFIG_ARM_LPAE
@@ -910,7 +891,7 @@ static void __init create_mapping(struct map_desc *md)
* Catch 36-bit addresses
*/
if (md->pfn >= 0x100000) {
- create_36bit_mapping(md, type);
+ create_36bit_mapping(mm, md, type);
return;
}
#endif
@@ -925,7 +906,7 @@ static void __init create_mapping(struct map_desc *md)
return;
}
- pgd = pgd_offset_k(addr);
+ pgd = pgd_offset(mm, addr);
end = addr + length;
do {
unsigned long next = pgd_addr_end(addr, end);
@@ -938,6 +919,31 @@ static void __init create_mapping(struct map_desc *md)
}
/*
+ * Create the page directory entries and any necessary
+ * page tables for the mapping specified by `md'. We
+ * are able to cope here with varying sizes and address
+ * offsets, and we take full advantage of sections and
+ * supersections.
+ */
+static void __init create_mapping(struct map_desc *md)
+{
+ if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
+ pr_warn("BUG: not creating mapping for 0x%08llx at 0x%08lx in user region\n",
+ (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
+ return;
+ }
+
+ if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
+ md->virtual >= PAGE_OFFSET && md->virtual < FIXADDR_START &&
+ (md->virtual < VMALLOC_START || md->virtual >= VMALLOC_END)) {
+ pr_warn("BUG: mapping for 0x%08llx at 0x%08lx out of vmalloc space\n",
+ (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
+ }
+
+ __create_mapping(&init_mm, md);
+}
+
+/*
* Create the architecture specific mappings
*/
void __init iotable_init(struct map_desc *io_desc, int nr)
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 09/13] ARM: add support for non-global kernel mappings
[not found] ` <1448886507-3216-1-git-send-email-ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
` (2 preceding siblings ...)
2015-11-30 12:28 ` [PATCH v4 07/13] ARM: split off core mapping logic from create_mapping Ard Biesheuvel
@ 2015-11-30 12:28 ` Ard Biesheuvel
2015-11-30 12:28 ` [PATCH v4 11/13] ARM: only consider memblocks with NOMAP cleared for linear mapping Ard Biesheuvel
` (4 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Ard Biesheuvel @ 2015-11-30 12:28 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
mark.rutland-5wv7dgnIgG8, linux-efi-u79uwXL29TY76Z2rM5mHXA,
leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
matt-mF/unelCI9GS6iBeEJttW/XRex20P6io,
linux-lFZ/pmaqli7XmaaqVzeoHQ
Cc: akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
kuleshovmail-Re5JQEeQqe8AvxtiuMwx3w,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
ryan.harkin-QSEj5FYQhm4dnm+yROfE0A,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
roy.franz-QSEj5FYQhm4dnm+yROfE0A, msalter-H+wXaHxf7aLQT0dZR+AlfA,
Ard Biesheuvel
Add support to the kernel translation table population routines for
creating non-global mappings. This will be used by the UEFI runtime
services, which will use temporary mappings in the userland range.
Reviewed-by: Matt Fleming <matt-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
arch/arm/mm/mmu.c | 35 +++++++++++---------
1 file changed, 20 insertions(+), 15 deletions(-)
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 87dc49dbe231..2d9f628a7fe8 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -745,18 +745,20 @@ static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr,
static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
unsigned long end, unsigned long pfn,
const struct mem_type *type,
- void *(*alloc)(unsigned long sz))
+ void *(*alloc)(unsigned long sz),
+ bool ng)
{
pte_t *pte = pte_alloc(pmd, addr, type->prot_l1, alloc);
do {
- set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), 0);
+ set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)),
+ ng ? PTE_EXT_NG : 0);
pfn++;
} while (pte++, addr += PAGE_SIZE, addr != end);
}
static void __init __map_init_section(pmd_t *pmd, unsigned long addr,
unsigned long end, phys_addr_t phys,
- const struct mem_type *type)
+ const struct mem_type *type, bool ng)
{
pmd_t *p = pmd;
@@ -774,7 +776,7 @@ static void __init __map_init_section(pmd_t *pmd, unsigned long addr,
pmd++;
#endif
do {
- *pmd = __pmd(phys | type->prot_sect);
+ *pmd = __pmd(phys | type->prot_sect | (ng ? PMD_SECT_nG : 0));
phys += SECTION_SIZE;
} while (pmd++, addr += SECTION_SIZE, addr != end);
@@ -784,7 +786,7 @@ static void __init __map_init_section(pmd_t *pmd, unsigned long addr,
static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
unsigned long end, phys_addr_t phys,
const struct mem_type *type,
- void *(*alloc)(unsigned long sz))
+ void *(*alloc)(unsigned long sz), bool ng)
{
pmd_t *pmd = pmd_offset(pud, addr);
unsigned long next;
@@ -802,10 +804,10 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
*/
if (type->prot_sect &&
((addr | next | phys) & ~SECTION_MASK) == 0) {
- __map_init_section(pmd, addr, next, phys, type);
+ __map_init_section(pmd, addr, next, phys, type, ng);
} else {
alloc_init_pte(pmd, addr, next,
- __phys_to_pfn(phys), type, alloc);
+ __phys_to_pfn(phys), type, alloc, ng);
}
phys += next - addr;
@@ -816,14 +818,14 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
unsigned long end, phys_addr_t phys,
const struct mem_type *type,
- void *(*alloc)(unsigned long sz))
+ void *(*alloc)(unsigned long sz), bool ng)
{
pud_t *pud = pud_offset(pgd, addr);
unsigned long next;
do {
next = pud_addr_end(addr, end);
- alloc_init_pmd(pud, addr, next, phys, type, alloc);
+ alloc_init_pmd(pud, addr, next, phys, type, alloc, ng);
phys += next - addr;
} while (pud++, addr = next, addr != end);
}
@@ -831,7 +833,8 @@ static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
#ifndef CONFIG_ARM_LPAE
static void __init create_36bit_mapping(struct mm_struct *mm,
struct map_desc *md,
- const struct mem_type *type)
+ const struct mem_type *type,
+ bool ng)
{
unsigned long addr, length, end;
phys_addr_t phys;
@@ -879,7 +882,8 @@ static void __init create_36bit_mapping(struct mm_struct *mm,
int i;
for (i = 0; i < 16; i++)
- *pmd++ = __pmd(phys | type->prot_sect | PMD_SECT_SUPER);
+ *pmd++ = __pmd(phys | type->prot_sect | PMD_SECT_SUPER |
+ (ng ? PMD_SECT_nG : 0));
addr += SUPERSECTION_SIZE;
phys += SUPERSECTION_SIZE;
@@ -889,7 +893,8 @@ static void __init create_36bit_mapping(struct mm_struct *mm,
#endif /* !CONFIG_ARM_LPAE */
static void __init __create_mapping(struct mm_struct *mm, struct map_desc *md,
- void *(*alloc)(unsigned long sz))
+ void *(*alloc)(unsigned long sz),
+ bool ng)
{
unsigned long addr, length, end;
phys_addr_t phys;
@@ -903,7 +908,7 @@ static void __init __create_mapping(struct mm_struct *mm, struct map_desc *md,
* Catch 36-bit addresses
*/
if (md->pfn >= 0x100000) {
- create_36bit_mapping(mm, md, type);
+ create_36bit_mapping(mm, md, type, ng);
return;
}
#endif
@@ -923,7 +928,7 @@ static void __init __create_mapping(struct mm_struct *mm, struct map_desc *md,
do {
unsigned long next = pgd_addr_end(addr, end);
- alloc_init_pud(pgd, addr, next, phys, type, alloc);
+ alloc_init_pud(pgd, addr, next, phys, type, alloc, ng);
phys += next - addr;
addr = next;
@@ -952,7 +957,7 @@ static void __init create_mapping(struct map_desc *md)
(long long)__pfn_to_phys((u64)md->pfn), md->virtual);
}
- __create_mapping(&init_mm, md, early_alloc);
+ __create_mapping(&init_mm, md, early_alloc, false);
}
/*
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 11/13] ARM: only consider memblocks with NOMAP cleared for linear mapping
[not found] ` <1448886507-3216-1-git-send-email-ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
` (3 preceding siblings ...)
2015-11-30 12:28 ` [PATCH v4 09/13] ARM: add support for non-global kernel mappings Ard Biesheuvel
@ 2015-11-30 12:28 ` Ard Biesheuvel
2015-11-30 12:28 ` [PATCH v4 12/13] ARM: wire up UEFI init and runtime support Ard Biesheuvel
` (3 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Ard Biesheuvel @ 2015-11-30 12:28 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
mark.rutland-5wv7dgnIgG8, linux-efi-u79uwXL29TY76Z2rM5mHXA,
leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
matt-mF/unelCI9GS6iBeEJttW/XRex20P6io,
linux-lFZ/pmaqli7XmaaqVzeoHQ
Cc: akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
kuleshovmail-Re5JQEeQqe8AvxtiuMwx3w,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
ryan.harkin-QSEj5FYQhm4dnm+yROfE0A,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
roy.franz-QSEj5FYQhm4dnm+yROfE0A, msalter-H+wXaHxf7aLQT0dZR+AlfA,
Ard Biesheuvel
Take the new memblock attribute MEMBLOCK_NOMAP into account when
deciding whether a certain region is or should be covered by the
kernel direct mapping.
Tested-by: Ryan Harkin <ryan.harkin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Matt Fleming <matt-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
arch/arm/mm/init.c | 5 ++++-
arch/arm/mm/mmu.c | 3 +++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 8a63b4cdc0f2..16104b1e2661 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -191,7 +191,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max_low,
#ifdef CONFIG_HAVE_ARCH_PFN_VALID
int pfn_valid(unsigned long pfn)
{
- return memblock_is_memory(__pfn_to_phys(pfn));
+ return memblock_is_map_memory(__pfn_to_phys(pfn));
}
EXPORT_SYMBOL(pfn_valid);
#endif
@@ -432,6 +432,9 @@ static void __init free_highpages(void)
if (end <= max_low)
continue;
+ if (memblock_is_nomap(mem))
+ continue;
+
/* Truncate partial highmem entries */
if (start < max_low)
start = max_low;
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 8c69830e791a..c615d2eb9232 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1435,6 +1435,9 @@ static void __init map_lowmem(void)
phys_addr_t end = start + reg->size;
struct map_desc map;
+ if (memblock_is_nomap(reg))
+ continue;
+
if (end > arm_lowmem_limit)
end = arm_lowmem_limit;
if (start >= end)
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 12/13] ARM: wire up UEFI init and runtime support
[not found] ` <1448886507-3216-1-git-send-email-ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
` (4 preceding siblings ...)
2015-11-30 12:28 ` [PATCH v4 11/13] ARM: only consider memblocks with NOMAP cleared for linear mapping Ard Biesheuvel
@ 2015-11-30 12:28 ` Ard Biesheuvel
2015-11-30 12:28 ` [PATCH v4 13/13] ARM: add UEFI stub support Ard Biesheuvel
` (2 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Ard Biesheuvel @ 2015-11-30 12:28 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
mark.rutland-5wv7dgnIgG8, linux-efi-u79uwXL29TY76Z2rM5mHXA,
leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
matt-mF/unelCI9GS6iBeEJttW/XRex20P6io,
linux-lFZ/pmaqli7XmaaqVzeoHQ
Cc: akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
kuleshovmail-Re5JQEeQqe8AvxtiuMwx3w,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
ryan.harkin-QSEj5FYQhm4dnm+yROfE0A,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
roy.franz-QSEj5FYQhm4dnm+yROfE0A, msalter-H+wXaHxf7aLQT0dZR+AlfA,
Ard Biesheuvel
This adds support to the kernel proper for booting via UEFI. It shares
most of the code with arm64, so this patch mostly just wires it up for
use with ARM.
Note that this does not include the EFI stub, it is added in a subsequent
patch.
Tested-by: Ryan Harkin <ryan.harkin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Matt Fleming <matt-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
arch/arm/include/asm/efi.h | 60 ++++++++++++++++++++
arch/arm/include/asm/mmu_context.h | 2 +-
arch/arm/kernel/Makefile | 1 +
arch/arm/kernel/efi.c | 38 +++++++++++++
arch/arm/kernel/setup.c | 3 +
drivers/firmware/efi/Makefile | 1 +
6 files changed, 104 insertions(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
new file mode 100644
index 000000000000..c91e330616ad
--- /dev/null
+++ b/arch/arm/include/asm/efi.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_EFI_H
+#define __ASM_ARM_EFI_H
+
+#include <asm/cacheflush.h>
+#include <asm/cachetype.h>
+#include <asm/early_ioremap.h>
+#include <asm/fixmap.h>
+#include <asm/highmem.h>
+#include <asm/mach/map.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+
+#ifdef CONFIG_EFI
+void efi_init(void);
+
+int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
+
+#define efi_call_virt(f, ...) \
+({ \
+ efi_##f##_t *__f; \
+ efi_status_t __s; \
+ \
+ efi_virtmap_load(); \
+ __f = efi.systab->runtime->f; \
+ __s = __f(__VA_ARGS__); \
+ efi_virtmap_unload(); \
+ __s; \
+})
+
+#define __efi_call_virt(f, ...) \
+({ \
+ efi_##f##_t *__f; \
+ \
+ efi_virtmap_load(); \
+ __f = efi.systab->runtime->f; \
+ __f(__VA_ARGS__); \
+ efi_virtmap_unload(); \
+})
+
+static inline void efi_set_pgd(struct mm_struct *mm)
+{
+ check_and_switch_context(mm, NULL);
+}
+
+void efi_virtmap_load(void);
+void efi_virtmap_unload(void);
+
+#else
+#define efi_init()
+#endif /* CONFIG_EFI */
+
+#endif /* _ASM_ARM_EFI_H */
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
index 9b32f76bb0dd..432ce8176498 100644
--- a/arch/arm/include/asm/mmu_context.h
+++ b/arch/arm/include/asm/mmu_context.h
@@ -26,7 +26,7 @@ void __check_vmalloc_seq(struct mm_struct *mm);
#ifdef CONFIG_CPU_HAS_ASID
void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk);
-#define init_new_context(tsk,mm) ({ atomic64_set(&mm->context.id, 0); 0; })
+#define init_new_context(tsk,mm) ({ atomic64_set(&(mm)->context.id, 0); 0; })
#ifdef CONFIG_ARM_ERRATA_798181
void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm,
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index af9e59bf3831..c90f4a70d646 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -77,6 +77,7 @@ CFLAGS_pj4-cp0.o := -marm
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
obj-$(CONFIG_VDSO) += vdso.o
+obj-$(CONFIG_EFI) += efi.o
ifneq ($(CONFIG_ARCH_EBSA110),y)
obj-y += io.o
diff --git a/arch/arm/kernel/efi.c b/arch/arm/kernel/efi.c
new file mode 100644
index 000000000000..ff8a9d8acfac
--- /dev/null
+++ b/arch/arm/kernel/efi.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/efi.h>
+#include <asm/efi.h>
+#include <asm/mach/map.h>
+#include <asm/mmu_context.h>
+
+int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
+{
+ struct map_desc desc = {
+ .virtual = md->virt_addr,
+ .pfn = __phys_to_pfn(md->phys_addr),
+ .length = md->num_pages * EFI_PAGE_SIZE,
+ };
+
+ /*
+ * Order is important here: memory regions may have all of the
+ * bits below set (and usually do), so we check them in order of
+ * preference.
+ */
+ if (md->attribute & EFI_MEMORY_WB)
+ desc.type = MT_MEMORY_RWX;
+ else if (md->attribute & EFI_MEMORY_WT)
+ desc.type = MT_MEMORY_RWX_NONCACHED;
+ else if (md->attribute & EFI_MEMORY_WC)
+ desc.type = MT_DEVICE_WC;
+ else
+ desc.type = MT_DEVICE;
+
+ create_mapping_late(mm, &desc, true);
+ return 0;
+}
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 5df2bca57c42..b341b1c3b2fa 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -7,6 +7,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/efi.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/stddef.h>
@@ -37,6 +38,7 @@
#include <asm/cp15.h>
#include <asm/cpu.h>
#include <asm/cputype.h>
+#include <asm/efi.h>
#include <asm/elf.h>
#include <asm/early_ioremap.h>
#include <asm/fixmap.h>
@@ -966,6 +968,7 @@ void __init setup_arch(char **cmdline_p)
early_paging_init(mdesc);
#endif
setup_dma_zone(mdesc);
+ efi_init();
sanity_check_meminfo();
arm_memblock_init(mdesc);
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index f292917b00e7..62e654f255f4 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -20,4 +20,5 @@ obj-$(CONFIG_EFI_STUB) += libstub/
obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_mem.o
arm-obj-$(CONFIG_EFI) := arm-init.o arm-runtime.o
+obj-$(CONFIG_ARM) += $(arm-obj-y)
obj-$(CONFIG_ARM64) += $(arm-obj-y)
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 13/13] ARM: add UEFI stub support
[not found] ` <1448886507-3216-1-git-send-email-ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
` (5 preceding siblings ...)
2015-11-30 12:28 ` [PATCH v4 12/13] ARM: wire up UEFI init and runtime support Ard Biesheuvel
@ 2015-11-30 12:28 ` Ard Biesheuvel
2015-12-02 14:53 ` [PATCH v4 00/13] UEFI boot and runtime services support for 32-bit ARM Ard Biesheuvel
2015-12-03 10:18 ` Will Deacon
8 siblings, 0 replies; 21+ messages in thread
From: Ard Biesheuvel @ 2015-11-30 12:28 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
mark.rutland-5wv7dgnIgG8, linux-efi-u79uwXL29TY76Z2rM5mHXA,
leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
matt-mF/unelCI9GS6iBeEJttW/XRex20P6io,
linux-lFZ/pmaqli7XmaaqVzeoHQ
Cc: akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
kuleshovmail-Re5JQEeQqe8AvxtiuMwx3w,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
ryan.harkin-QSEj5FYQhm4dnm+yROfE0A,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
roy.franz-QSEj5FYQhm4dnm+yROfE0A, msalter-H+wXaHxf7aLQT0dZR+AlfA,
Ard Biesheuvel
From: Roy Franz <roy.franz-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
This patch adds EFI stub support for the ARM Linux kernel.
The EFI stub operates similarly to the x86 and arm64 stubs: it is a
shim between the EFI firmware and the normal zImage entry point, and
sets up the environment that the zImage is expecting. This includes
optionally loading the initrd and device tree from the system partition
based on the kernel command line.
Signed-off-by: Roy Franz <roy.franz-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Tested-by: Ryan Harkin <ryan.harkin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Matt Fleming <matt-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
arch/arm/Kconfig | 19 +++
arch/arm/boot/compressed/Makefile | 4 +-
| 130 ++++++++++++++++++++
arch/arm/boot/compressed/head.S | 54 +++++++-
arch/arm/boot/compressed/vmlinux.lds.S | 7 ++
arch/arm/include/asm/efi.h | 23 ++++
drivers/firmware/efi/libstub/Makefile | 9 ++
drivers/firmware/efi/libstub/arm-stub.c | 4 +-
drivers/firmware/efi/libstub/arm32-stub.c | 85 +++++++++++++
9 files changed, 331 insertions(+), 4 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 446e49b56e6a..67f8303d513d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2041,6 +2041,25 @@ config AUTO_ZRELADDR
0xf8000000. This assumes the zImage being placed in the first 128MB
from start of memory.
+config EFI_STUB
+ bool
+
+config EFI
+ bool "UEFI runtime support"
+ depends on OF && !CPU_BIG_ENDIAN && MMU && AUTO_ZRELADDR && !XIP_KERNEL
+ select UCS2_STRING
+ select EFI_PARAMS_FROM_FDT
+ select EFI_STUB
+ select EFI_ARMSTUB
+ select EFI_RUNTIME_WRAPPERS
+ ---help---
+ This option provides support for runtime services provided
+ by UEFI firmware (such as non-volatile variables, realtime
+ clock, and platform reset). A UEFI stub is also provided to
+ allow the kernel to be booted as an EFI application. This
+ is only useful for kernels that may run on systems that have
+ UEFI firmware.
+
endmenu
menu "CPU Power Management"
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 3f9a9ebc77c3..4c23a68a0917 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -167,9 +167,11 @@ if [ $(words $(ZRELADDR)) -gt 1 -a "$(CONFIG_AUTO_ZRELADDR)" = "" ]; then \
false; \
fi
+efi-obj-$(CONFIG_EFI_STUB) := $(objtree)/drivers/firmware/efi/libstub/lib.a
+
$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) \
- $(bswapsdi2) FORCE
+ $(bswapsdi2) $(efi-obj-y) FORCE
@$(check_for_multiple_zreladdr)
$(call if_changed,ld)
@$(check_for_bad_syms)
--git a/arch/arm/boot/compressed/efi-header.S b/arch/arm/boot/compressed/efi-header.S
new file mode 100644
index 000000000000..9d5dc4fda3c1
--- /dev/null
+++ b/arch/arm/boot/compressed/efi-header.S
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2013-2015 Linaro Ltd
+ * Authors: Roy Franz <roy.franz-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+ * Ard Biesheuvel <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+ .macro __nop
+#ifdef CONFIG_EFI_STUB
+ @ This is almost but not quite a NOP, since it does clobber the
+ @ condition flags. But it is the best we can do for EFI, since
+ @ PE/COFF expects the magic string "MZ" at offset 0, while the
+ @ ARM/Linux boot protocol expects an executable instruction
+ @ there.
+ .inst 'M' | ('Z' << 8) | (0x1310 << 16) @ tstne r0, #0x4d000
+#else
+ mov r0, r0
+#endif
+ .endm
+
+ .macro __EFI_HEADER
+#ifdef CONFIG_EFI_STUB
+ b __efi_start
+
+ .set start_offset, __efi_start - start
+ .org start + 0x3c
+ @
+ @ The PE header can be anywhere in the file, but for
+ @ simplicity we keep it together with the MSDOS header
+ @ The offset to the PE/COFF header needs to be at offset
+ @ 0x3C in the MSDOS header.
+ @ The only 2 fields of the MSDOS header that are used are this
+ @ PE/COFF offset, and the "MZ" bytes at offset 0x0.
+ @
+ .long pe_header - start @ Offset to the PE header.
+
+pe_header:
+ .ascii "PE\0\0"
+
+coff_header:
+ .short 0x01c2 @ ARM or Thumb
+ .short 2 @ nr_sections
+ .long 0 @ TimeDateStamp
+ .long 0 @ PointerToSymbolTable
+ .long 1 @ NumberOfSymbols
+ .short section_table - optional_header
+ @ SizeOfOptionalHeader
+ .short 0x306 @ Characteristics.
+ @ IMAGE_FILE_32BIT_MACHINE |
+ @ IMAGE_FILE_DEBUG_STRIPPED |
+ @ IMAGE_FILE_EXECUTABLE_IMAGE |
+ @ IMAGE_FILE_LINE_NUMS_STRIPPED
+
+optional_header:
+ .short 0x10b @ PE32 format
+ .byte 0x02 @ MajorLinkerVersion
+ .byte 0x14 @ MinorLinkerVersion
+ .long _end - __efi_start @ SizeOfCode
+ .long 0 @ SizeOfInitializedData
+ .long 0 @ SizeOfUninitializedData
+ .long efi_stub_entry - start @ AddressOfEntryPoint
+ .long start_offset @ BaseOfCode
+ .long 0 @ data
+
+extra_header_fields:
+ .long 0 @ ImageBase
+ .long 0x200 @ SectionAlignment
+ .long 0x200 @ FileAlignment
+ .short 0 @ MajorOperatingSystemVersion
+ .short 0 @ MinorOperatingSystemVersion
+ .short 0 @ MajorImageVersion
+ .short 0 @ MinorImageVersion
+ .short 0 @ MajorSubsystemVersion
+ .short 0 @ MinorSubsystemVersion
+ .long 0 @ Win32VersionValue
+
+ .long _end - start @ SizeOfImage
+ .long start_offset @ SizeOfHeaders
+ .long 0 @ CheckSum
+ .short 0xa @ Subsystem (EFI application)
+ .short 0 @ DllCharacteristics
+ .long 0 @ SizeOfStackReserve
+ .long 0 @ SizeOfStackCommit
+ .long 0 @ SizeOfHeapReserve
+ .long 0 @ SizeOfHeapCommit
+ .long 0 @ LoaderFlags
+ .long 0x6 @ NumberOfRvaAndSizes
+
+ .quad 0 @ ExportTable
+ .quad 0 @ ImportTable
+ .quad 0 @ ResourceTable
+ .quad 0 @ ExceptionTable
+ .quad 0 @ CertificationTable
+ .quad 0 @ BaseRelocationTable
+
+section_table:
+ @
+ @ The EFI application loader requires a relocation section
+ @ because EFI applications must be relocatable. This is a
+ @ dummy section as far as we are concerned.
+ @
+ .ascii ".reloc\0\0"
+ .long 0 @ VirtualSize
+ .long 0 @ VirtualAddress
+ .long 0 @ SizeOfRawData
+ .long 0 @ PointerToRawData
+ .long 0 @ PointerToRelocations
+ .long 0 @ PointerToLineNumbers
+ .short 0 @ NumberOfRelocations
+ .short 0 @ NumberOfLineNumbers
+ .long 0x42100040 @ Characteristics
+
+ .ascii ".text\0\0\0"
+ .long _end - __efi_start @ VirtualSize
+ .long __efi_start @ VirtualAddress
+ .long _edata - __efi_start @ SizeOfRawData
+ .long __efi_start @ PointerToRawData
+ .long 0 @ PointerToRelocations
+ .long 0 @ PointerToLineNumbers
+ .short 0 @ NumberOfRelocations
+ .short 0 @ NumberOfLineNumbers
+ .long 0xe0500020 @ Characteristics
+
+ .align 9
+__efi_start:
+#endif
+ .endm
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 06e983f59980..af11c2f8f3b7 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -12,6 +12,8 @@
#include <asm/assembler.h>
#include <asm/v7m.h>
+#include "efi-header.S"
+
AR_CLASS( .arch armv7-a )
M_CLASS( .arch armv7-m )
@@ -126,7 +128,7 @@
start:
.type start,#function
.rept 7
- mov r0, r0
+ __nop
.endr
ARM( mov r0, r0 )
ARM( b 1f )
@@ -139,7 +141,8 @@ start:
.word 0x04030201 @ endianness flag
THUMB( .thumb )
-1:
+1: __EFI_HEADER
+
ARM_BE8( setend be ) @ go BE8 if compiled for BE8
AR_CLASS( mrs r9, cpsr )
#ifdef CONFIG_ARM_VIRT_EXT
@@ -1353,6 +1356,53 @@ __enter_kernel:
reloc_code_end:
+#ifdef CONFIG_EFI_STUB
+ .align 2
+_start: .long start - .
+
+ENTRY(efi_stub_entry)
+ @ allocate space on stack for passing current zImage address
+ @ and for the EFI stub to return of new entry point of
+ @ zImage, as EFI stub may copy the kernel. Pointer address
+ @ is passed in r2. r0 and r1 are passed through from the
+ @ EFI firmware to efi_entry
+ adr ip, _start
+ ldr r3, [ip]
+ add r3, r3, ip
+ stmfd sp!, {r3, lr}
+ mov r2, sp @ pass zImage address in r2
+ bl efi_entry
+
+ @ Check for error return from EFI stub. r0 has FDT address
+ @ or error code.
+ cmn r0, #1
+ beq efi_load_fail
+
+ @ Preserve return value of efi_entry() in r4
+ mov r4, r0
+ bl cache_clean_flush
+ bl cache_off
+
+ @ Set parameters for booting zImage according to boot protocol
+ @ put FDT address in r2, it was returned by efi_entry()
+ @ r1 is the machine type, and r0 needs to be 0
+ mov r0, #0
+ mov r1, #0xFFFFFFFF
+ mov r2, r4
+
+ @ Branch to (possibly) relocated zImage that is in [sp]
+ ldr lr, [sp]
+ ldr ip, =start_offset
+ add lr, lr, ip
+ mov pc, lr @ no mode switch
+
+efi_load_fail:
+ @ Return EFI_LOAD_ERROR to EFI firmware on error.
+ ldr r0, =0x80000001
+ ldmfd sp!, {ip, pc}
+ENDPROC(efi_stub_entry)
+#endif
+
.align
.section ".stack", "aw", %nobits
.L_user_stack: .space 4096
diff --git a/arch/arm/boot/compressed/vmlinux.lds.S b/arch/arm/boot/compressed/vmlinux.lds.S
index 2b60b843ac5e..81c493156ce8 100644
--- a/arch/arm/boot/compressed/vmlinux.lds.S
+++ b/arch/arm/boot/compressed/vmlinux.lds.S
@@ -48,6 +48,13 @@ SECTIONS
*(.rodata)
*(.rodata.*)
}
+ .data : {
+ /*
+ * The EFI stub always executes from RAM, and runs strictly before the
+ * decompressor, so we can make an exception for its r/w data, and keep it
+ */
+ *(.data.efistub)
+ }
.piggydata : {
*(.piggydata)
}
diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
index c91e330616ad..e0eea72deb87 100644
--- a/arch/arm/include/asm/efi.h
+++ b/arch/arm/include/asm/efi.h
@@ -57,4 +57,27 @@ void efi_virtmap_unload(void);
#define efi_init()
#endif /* CONFIG_EFI */
+/* arch specific definitions used by the stub code */
+
+#define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__)
+
+/*
+ * A reasonable upper bound for the uncompressed kernel size is 32 MBytes,
+ * so we will reserve that amount of memory. We have no easy way to tell what
+ * the actuall size of code + data the uncompressed kernel will use.
+ * If this is insufficient, the decompressor will relocate itself out of the
+ * way before performing the decompression.
+ */
+#define MAX_UNCOMP_KERNEL_SIZE SZ_32M
+
+/*
+ * The kernel zImage should preferably be located between 32 MB and 128 MB
+ * from the base of DRAM. The min address leaves space for a maximal size
+ * uncompressed image, and the max address is due to how the zImage decompressor
+ * picks a destination address.
+ */
+#define ZIMAGE_OFFSET_LIMIT SZ_128M
+#define MIN_ZIMAGE_OFFSET MAX_UNCOMP_KERNEL_SIZE
+#define MAX_FDT_OFFSET ZIMAGE_OFFSET_LIMIT
+
#endif /* _ASM_ARM_EFI_H */
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index 3c0467d3688c..8cf9ccbf42d5 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -34,6 +34,7 @@ $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
lib-$(CONFIG_EFI_ARMSTUB) += arm-stub.o fdt.o string.o \
$(patsubst %.c,lib-%.o,$(arm-deps))
+lib-$(CONFIG_ARM) += arm32-stub.o
lib-$(CONFIG_ARM64) += arm64-stub.o
CFLAGS_arm64-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
@@ -67,3 +68,11 @@ quiet_cmd_stubcopy = STUBCPY $@
$(OBJDUMP) -r $@ | grep $(STUBCOPY_RELOC-y) \
&& (echo >&2 "$@: absolute symbol references not allowed in the EFI stub"; \
rm -f $@; /bin/false); else /bin/false; fi
+
+#
+# ARM discards the .data section because it disallows r/w data in the
+# decompressor. So move our .data to .data.efistub, which is preserved
+# explicitly by the decompressor linker script.
+#
+STUBCOPY_FLAGS-$(CONFIG_ARM) += --rename-section .data=.data.efistub
+STUBCOPY_RELOC-$(CONFIG_ARM) := R_ARM_ABS
diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c
index 950c87f5d279..3397902e4040 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -303,8 +303,10 @@ fail:
* The value chosen is the largest non-zero power of 2 suitable for this purpose
* both on 32-bit and 64-bit ARM CPUs, to maximize the likelihood that it can
* be mapped efficiently.
+ * Since 32-bit ARM could potentially execute with a 1G/3G user/kernel split,
+ * map everything below 1 GB.
*/
-#define EFI_RT_VIRTUAL_BASE 0x40000000
+#define EFI_RT_VIRTUAL_BASE SZ_512M
static int cmp_mem_desc(const void *l, const void *r)
{
diff --git a/drivers/firmware/efi/libstub/arm32-stub.c b/drivers/firmware/efi/libstub/arm32-stub.c
new file mode 100644
index 000000000000..495ebd657e38
--- /dev/null
+++ b/drivers/firmware/efi/libstub/arm32-stub.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2013 Linaro Ltd; <roy.franz-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/efi.h>
+#include <asm/efi.h>
+
+efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
+ unsigned long *image_addr,
+ unsigned long *image_size,
+ unsigned long *reserve_addr,
+ unsigned long *reserve_size,
+ unsigned long dram_base,
+ efi_loaded_image_t *image)
+{
+ unsigned long nr_pages;
+ efi_status_t status;
+ /* Use alloc_addr to tranlsate between types */
+ efi_physical_addr_t alloc_addr;
+
+ /*
+ * Verify that the DRAM base address is compatible with the ARM
+ * boot protocol, which determines the base of DRAM by masking
+ * off the low 27 bits of the address at which the zImage is
+ * loaded. These assumptions are made by the decompressor,
+ * before any memory map is available.
+ */
+ dram_base = round_up(dram_base, SZ_128M);
+
+ /*
+ * Reserve memory for the uncompressed kernel image. This is
+ * all that prevents any future allocations from conflicting
+ * with the kernel. Since we can't tell from the compressed
+ * image how much DRAM the kernel actually uses (due to BSS
+ * size uncertainty) we allocate the maximum possible size.
+ * Do this very early, as prints can cause memory allocations
+ * that may conflict with this.
+ */
+ alloc_addr = dram_base;
+ *reserve_size = MAX_UNCOMP_KERNEL_SIZE;
+ nr_pages = round_up(*reserve_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
+ status = sys_table->boottime->allocate_pages(EFI_ALLOCATE_ADDRESS,
+ EFI_LOADER_DATA,
+ nr_pages, &alloc_addr);
+ if (status != EFI_SUCCESS) {
+ *reserve_size = 0;
+ pr_efi_err(sys_table, "Unable to allocate memory for uncompressed kernel.\n");
+ return status;
+ }
+ *reserve_addr = alloc_addr;
+
+ /*
+ * Relocate the zImage, so that it appears in the lowest 128 MB
+ * memory window.
+ */
+ *image_size = image->image_size;
+ status = efi_relocate_kernel(sys_table, image_addr, *image_size,
+ *image_size,
+ dram_base + MAX_UNCOMP_KERNEL_SIZE, 0);
+ if (status != EFI_SUCCESS) {
+ pr_efi_err(sys_table, "Failed to relocate kernel.\n");
+ efi_free(sys_table, *reserve_size, *reserve_addr);
+ *reserve_size = 0;
+ return status;
+ }
+
+ /*
+ * Check to see if we were able to allocate memory low enough
+ * in memory. The kernel determines the base of DRAM from the
+ * address at which the zImage is loaded.
+ */
+ if (*image_addr + *image_size > dram_base + ZIMAGE_OFFSET_LIMIT) {
+ pr_efi_err(sys_table, "Failed to relocate kernel, no low memory available.\n");
+ efi_free(sys_table, *reserve_size, *reserve_addr);
+ *reserve_size = 0;
+ efi_free(sys_table, *image_size, *image_addr);
+ *image_size = 0;
+ return EFI_LOAD_ERROR;
+ }
+ return EFI_SUCCESS;
+}
--
1.9.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v4 00/13] UEFI boot and runtime services support for 32-bit ARM
[not found] ` <1448886507-3216-1-git-send-email-ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
` (6 preceding siblings ...)
2015-11-30 12:28 ` [PATCH v4 13/13] ARM: add UEFI stub support Ard Biesheuvel
@ 2015-12-02 14:53 ` Ard Biesheuvel
2015-12-03 10:18 ` Will Deacon
8 siblings, 0 replies; 21+ messages in thread
From: Ard Biesheuvel @ 2015-12-02 14:53 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
Catalin Marinas, Will Deacon, Mark Rutland,
linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Leif Lindholm,
Matt Fleming, Russell King - ARM Linux
Cc: Andrew Morton, Alexander Kuleshov,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org, Ryan Harkin,
Grant Likely, Roy Franz, Mark Salter, Ard Biesheuvel
On 30 November 2015 at 13:28, Ard Biesheuvel <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> This series adds support for booting the 32-bit ARM kernel directly from
> UEFI firmware using a builtin UEFI stub. It mostly reuses refactored arm64
> code, and the differences (primarily the PE/COFF header and entry point and
> the efi_create_mapping() implementation) are split out into arm64 and ARM
> versions.
>
> Since I did not receive any further comments in reply to v3 from the people who
> commented on v2, I think this series in now in sufficient shape to be pulled.
> Note that patch #1 touches mm/memblock.c and include/linux/memblock.h, for which
> get_maintainer.pl does not provide a maintainer, so it has been cc'ed to various
> past editors of those files, and to the linux-mm mailing list.
>
> Since the series affects both arm64 and ARM, it is up to the maintainers to let
> me know how and when they wish to proceed with this. My suggestion would be to
> send out pull request for patches #1 - #5 to the arm64 maintainer, and for the
> whole series to the ARM maintainer. This should keep any conflicts on either
> side confined to the respective maintainer tree, rather then propagating all the
> way to -next.
>
> For the result of regression testing against these patches, please refer to the
> following links for build and boot reports (respectively) generated by
> kernelci.org (thanks guys).
>
> http://kernelci.org/build/ardb/kernel/v4.4-rc3-13-g9e4dc4695ba0/
> http://kernelci.org/boot/all/job/ardb/kernel/v4.4-rc3-13-g9e4dc4695ba0/
>
> Note that the above is regression testing only, as kernelci does not yet support
> booting 32-bit ARM targets in EFI mode. This functionality has been verified
> independently (on actual hardware) by Ryan Harkin <ryan.harkin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>, who
> has kindly given his Tested-by for the ARM patches in this series (#6 - #13)
>
> Please find instructions for duplicating the EFI boot testing using QEMU at the
> end of this email.
>
> Changes since v3:
> - rebased onto v4.4-rc3
> - minor change in #13: use 'dram_base + MAX_UNCOMP_KERNEL_SIZE' as preferred
> base for the allocation that holds the relocated compressed kernel image
> (the former value of 0x0 is usually not covered by DRAM, resulting in the
> value above to be used anyway)
> - added Reviewed-by from Matt Fleming
> - added Tested-by from Ryan Harkin (#6 - #13)
>
> Changes since v2:
> - Some issues pointed out by Russell and Matt that were not introduced by this
> series but merely became apparent due to the code movement in patch #4 have
> been addressed in a separate 2-piece series I sent out this morning. This v3
> is rebased on top of those patches.
> - Added a patch (#9) that adds support for creating non-global mappings. This
> addresses a concern raised by Russell in response to v2 where the use of
> global mappings combined with a flawed context switch and TBL flush sequence
> could result in memory corruption.
> - Rebased onto v4.4-rc2
>
> Changes since v1:
> - The primary difference between this version and the first one is that all
> prerequisites have either been merged, dropped for now (early FDT handling)
> or folded into this series (MEMBLOCK_NOMAP). IOW, this series can be applied
> on top of v4.4-rc1 directly.
> - Dropped handling of UEFI permission bits. The reason is that the UEFIv2.5
> approach (EFI_PROPERTIES_TABLE) is flawed, and will be replaced by something
> better in the next version of the spec.
>
> Patch #1 adds support for the MEMBLOCK_NOMAP attribute to the generic memblock
> code. Its purpose is to annotate memory regions as normal memory even if they
> are removed from the kernel direct mapping.
>
> Patch #2 implements MEMBLOCK_NOMAP support for arm64
>
> Patch #3 updates the EFI init code to remove UEFI reserved regions and regions
> used by runtime services from the kernel direct mapping
>
> Patch #4 splits off most of arch/arm64/kernel/efi.c into arch agnostic files
> arm-init.c and arm-runtime.c under drivers/firmware/efi.
>
> Patch #5 refactors the code split off in patch #1 to isolate the arm64 specific
> pieces, and change a couple of arm64-isms that ARM handles slightly differently.
>
> Patch #6 enables the generic early_ioremap and early_memremap implementations
> for ARM. It reuses the kmap fixmap region, which is not used that early anyway.
>
> Patch #7 splits off the core functionality of create_mapping() into a new
> function __create_mapping() that we can reuse for mapping UEFI runtime regions.
>
> Patch #8 factors out the early_alloc() routine so we can invoke __create_mapping
> using another (late) allocator.
>
> Patch #9 adds support to __create_mapping() for creating non-global translation
> table entries. (new in v3)
>
> Patch #10 implements create_mapping_late() that uses a late allocator.
>
> Patch #11 implements MEMBLOCK_NOMAP support for ARM
>
> Patch #12 implements the UEFI support in the kernel proper to probe the UEFI
> memory map and map the runtime services.
>
> Patch #13 ties together all of the above, by implementing the UEFI stub, and
> introducing the Kconfig symbols that allow all of this to be built.
>
>
> Ard Biesheuvel (12):
> mm/memblock: add MEMBLOCK_NOMAP attribute to memblock memory table
> arm64: only consider memblocks with NOMAP cleared for linear mapping
> arm64/efi: mark UEFI reserved regions as MEMBLOCK_NOMAP
> arm64/efi: split off EFI init and runtime code for reuse by 32-bit ARM
> arm64/efi: refactor EFI init and runtime code for reuse by 32-bit ARM
> ARM: add support for generic early_ioremap/early_memremap
> ARM: split off core mapping logic from create_mapping
> ARM: factor out allocation routine from __create_mapping()
> ARM: add support for non-global kernel mappings
> ARM: implement create_mapping_late() for EFI use
> ARM: only consider memblocks with NOMAP cleared for linear mapping
> ARM: wire up UEFI init and runtime support
>
> Roy Franz (1):
> ARM: add UEFI stub support
>
> arch/arm/Kconfig | 20 ++
> arch/arm/boot/compressed/Makefile | 4 +-
> arch/arm/boot/compressed/efi-header.S | 130 ++++++++
> arch/arm/boot/compressed/head.S | 54 +++-
> arch/arm/boot/compressed/vmlinux.lds.S | 7 +
> arch/arm/include/asm/Kbuild | 1 +
> arch/arm/include/asm/efi.h | 83 +++++
> arch/arm/include/asm/fixmap.h | 29 +-
> arch/arm/include/asm/mach/map.h | 2 +
> arch/arm/include/asm/mmu_context.h | 2 +-
> arch/arm/kernel/Makefile | 1 +
> arch/arm/kernel/efi.c | 38 +++
> arch/arm/kernel/setup.c | 10 +-
> arch/arm/mm/init.c | 5 +-
> arch/arm/mm/ioremap.c | 9 +
> arch/arm/mm/mmu.c | 128 +++++---
> arch/arm64/include/asm/efi.h | 9 +
> arch/arm64/kernel/efi.c | 334 +-------------------
> arch/arm64/mm/init.c | 2 +-
> arch/arm64/mm/mmu.c | 2 +
> drivers/firmware/efi/Makefile | 4 +
> drivers/firmware/efi/arm-init.c | 209 ++++++++++++
> drivers/firmware/efi/arm-runtime.c | 135 ++++++++
> drivers/firmware/efi/efi.c | 2 +
> drivers/firmware/efi/libstub/Makefile | 9 +
> drivers/firmware/efi/libstub/arm-stub.c | 4 +-
> drivers/firmware/efi/libstub/arm32-stub.c | 85 +++++
> include/linux/memblock.h | 8 +
> mm/memblock.c | 28 ++
> 29 files changed, 986 insertions(+), 368 deletions(-)
> create mode 100644 arch/arm/boot/compressed/efi-header.S
> create mode 100644 arch/arm/include/asm/efi.h
> create mode 100644 arch/arm/kernel/efi.c
> create mode 100644 drivers/firmware/efi/arm-init.c
> create mode 100644 drivers/firmware/efi/arm-runtime.c
> create mode 100644 drivers/firmware/efi/libstub/arm32-stub.c
>
>
> Testing instructions
> ====================
>
> 1. Download a prebuilt firmware binary:
> http://snapshots.linaro.org/components/kernel/leg-virt-tianocore-edk2-upstream/latest/QEMU-ARM/RELEASE_GCC49/QEMU_EFI.img.gz
>
> 2. Unzip it
> gunzip QEMU_EFI.img.gz
>
> 3. Download a prebuilt kernel binary (non-LPAE or LPAE, respectively):
> http://storage.kernelci.org/ardb/v4.4-rc3-13-g9e4dc4695ba0/arm-multi_v7_defconfig+CONFIG_EFI=y/zImage
> http://storage.kernelci.org/ardb/v4.4-rc3-13-g9e4dc4695ba0/arm-multi_v7_defconfig+CONFIG_EFI=y+CONFIG_ARM_LPAE=y/zImage
>
> 4. Run it
> qemu-system-arm -M virt -m 512 -nographic \
> -bios QEMU_EFI.img -kernel zImage \
> -append 'earlycon efi=debug console=ttyAMA0'
>
> (Ctrl-A Ctrl-X to quit)
Please note that combining -bios and -kernel as I do above requires
QEMU v2.3 or later.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 00/13] UEFI boot and runtime services support for 32-bit ARM
[not found] ` <1448886507-3216-1-git-send-email-ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
` (7 preceding siblings ...)
2015-12-02 14:53 ` [PATCH v4 00/13] UEFI boot and runtime services support for 32-bit ARM Ard Biesheuvel
@ 2015-12-03 10:18 ` Will Deacon
8 siblings, 0 replies; 21+ messages in thread
From: Will Deacon @ 2015-12-03 10:18 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
catalin.marinas-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
linux-efi-u79uwXL29TY76Z2rM5mHXA,
leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
matt-mF/unelCI9GS6iBeEJttW/XRex20P6io,
linux-lFZ/pmaqli7XmaaqVzeoHQ,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
kuleshovmail-Re5JQEeQqe8AvxtiuMwx3w,
linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
ryan.harkin-QSEj5FYQhm4dnm+yROfE0A,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
roy.franz-QSEj5FYQhm4dnm+yROfE0A, msalter-H+wXaHxf7aLQT0dZR+AlfA
Hi Ard,
On Mon, Nov 30, 2015 at 01:28:14PM +0100, Ard Biesheuvel wrote:
> This series adds support for booting the 32-bit ARM kernel directly from
> UEFI firmware using a builtin UEFI stub. It mostly reuses refactored arm64
> code, and the differences (primarily the PE/COFF header and entry point and
> the efi_create_mapping() implementation) are split out into arm64 and ARM
> versions.
>
> Since I did not receive any further comments in reply to v3 from the people who
> commented on v2, I think this series in now in sufficient shape to be pulled.
> Note that patch #1 touches mm/memblock.c and include/linux/memblock.h, for which
> get_maintainer.pl does not provide a maintainer, so it has been cc'ed to various
> past editors of those files, and to the linux-mm mailing list.
>
> Since the series affects both arm64 and ARM, it is up to the maintainers to let
> me know how and when they wish to proceed with this. My suggestion would be to
> send out pull request for patches #1 - #5 to the arm64 maintainer, and for the
> whole series to the ARM maintainer. This should keep any conflicts on either
> side confined to the respective maintainer tree, rather then propagating all the
> way to -next.
For the arm64 bits (patches 2-5):
Acked-by: Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>
I'd really like an ack from the mm crowd on patch 1 before I queue it.
Will
^ permalink raw reply [flat|nested] 21+ messages in thread