2014-04-16 01:59:30 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2014-10-20 14:27:26 +00:00
|
|
|
#include <linux/atomic.h>
|
2014-10-04 15:46:43 +00:00
|
|
|
#include <linux/dmi.h>
|
2014-04-16 01:59:30 +00:00
|
|
|
#include <linux/efi.h>
|
|
|
|
#include <linux/export.h>
|
|
|
|
#include <linux/memblock.h>
|
2014-10-20 14:27:26 +00:00
|
|
|
#include <linux/mm_types.h>
|
2014-04-16 01:59:30 +00:00
|
|
|
#include <linux/bootmem.h>
|
|
|
|
#include <linux/of.h>
|
|
|
|
#include <linux/of_fdt.h>
|
2014-10-20 14:27:26 +00:00
|
|
|
#include <linux/preempt.h>
|
|
|
|
#include <linux/rbtree.h>
|
|
|
|
#include <linux/rwsem.h>
|
2014-04-16 01:59:30 +00:00
|
|
|
#include <linux/sched.h>
|
|
|
|
#include <linux/slab.h>
|
2014-10-20 14:27:26 +00:00
|
|
|
#include <linux/spinlock.h>
|
2014-04-16 01:59:30 +00:00
|
|
|
|
|
|
|
#include <asm/cacheflush.h>
|
|
|
|
#include <asm/efi.h>
|
|
|
|
#include <asm/tlbflush.h>
|
|
|
|
#include <asm/mmu_context.h>
|
2014-10-20 14:27:26 +00:00
|
|
|
#include <asm/mmu.h>
|
|
|
|
#include <asm/pgtable.h>
|
2014-04-16 01:59:30 +00:00
|
|
|
|
|
|
|
struct efi_memory_map memmap;
|
|
|
|
|
|
|
|
static u64 efi_system_table;
|
|
|
|
|
2015-01-22 10:01:40 +00:00
|
|
|
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),
|
|
|
|
};
|
|
|
|
|
2014-04-16 01:59:30 +00:00
|
|
|
static int __init is_normal_ram(efi_memory_desc_t *md)
|
|
|
|
{
|
|
|
|
if (md->attribute & EFI_MEMORY_WB)
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-10-20 14:27:26 +00:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
}
|
|
|
|
|
2014-04-16 01:59:30 +00:00
|
|
|
static int __init uefi_init(void)
|
|
|
|
{
|
|
|
|
efi_char16_t *c16;
|
2014-10-20 14:27:26 +00:00
|
|
|
void *config_tables;
|
|
|
|
u64 table_size;
|
2014-04-16 01:59:30 +00:00
|
|
|
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");
|
2014-08-14 09:15:29 +00:00
|
|
|
retval = -EINVAL;
|
|
|
|
goto out;
|
2014-04-16 01:59:30 +00:00
|
|
|
}
|
|
|
|
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 */
|
2014-10-20 14:27:26 +00:00
|
|
|
c16 = early_memremap(efi_to_phys(efi.systab->fw_vendor),
|
2015-07-26 12:59:00 +00:00
|
|
|
sizeof(vendor) * sizeof(efi_char16_t));
|
2014-04-16 01:59:30 +00:00
|
|
|
if (c16) {
|
|
|
|
for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i)
|
|
|
|
vendor[i] = c16[i];
|
|
|
|
vendor[i] = '\0';
|
2015-07-26 12:59:00 +00:00
|
|
|
early_memunmap(c16, sizeof(vendor) * sizeof(efi_char16_t));
|
2014-04-16 01:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pr_info("EFI v%u.%.02u by %s\n",
|
|
|
|
efi.systab->hdr.revision >> 16,
|
|
|
|
efi.systab->hdr.revision & 0xffff, vendor);
|
|
|
|
|
2014-10-20 14:27:26 +00:00
|
|
|
table_size = sizeof(efi_config_table_64_t) * efi.systab->nr_tables;
|
|
|
|
config_tables = early_memremap(efi_to_phys(efi.systab->tables),
|
|
|
|
table_size);
|
2015-11-23 07:43:23 +00:00
|
|
|
if (config_tables == NULL) {
|
|
|
|
pr_warn("Unable to map EFI config table array.\n");
|
|
|
|
retval = -ENOMEM;
|
|
|
|
goto out;
|
|
|
|
}
|
2014-10-20 14:27:26 +00:00
|
|
|
retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables,
|
|
|
|
sizeof(efi_config_table_64_t), NULL);
|
2014-04-16 01:59:30 +00:00
|
|
|
|
2014-10-20 14:27:26 +00:00
|
|
|
early_memunmap(config_tables, table_size);
|
2014-08-14 09:15:29 +00:00
|
|
|
out:
|
2014-04-16 01:59:30 +00:00
|
|
|
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)
|
|
|
|
{
|
2014-10-20 13:31:57 +00:00
|
|
|
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:
|
2015-04-03 16:05:28 +00:00
|
|
|
case EFI_PERSISTENT_MEMORY:
|
2014-04-16 01:59:30 +00:00
|
|
|
return 0;
|
2014-10-20 13:31:57 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return is_normal_ram(md);
|
2014-04-16 01:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static __init void reserve_regions(void)
|
|
|
|
{
|
|
|
|
efi_memory_desc_t *md;
|
|
|
|
u64 paddr, npages, size;
|
|
|
|
|
2015-08-26 13:24:57 +00:00
|
|
|
if (efi_enabled(EFI_DBG))
|
2014-04-16 01:59:30 +00:00
|
|
|
pr_info("Processing EFI memory map:\n");
|
|
|
|
|
|
|
|
for_each_efi_memory_desc(&memmap, md) {
|
|
|
|
paddr = md->phys_addr;
|
|
|
|
npages = md->num_pages;
|
|
|
|
|
2015-08-26 13:24:57 +00:00
|
|
|
if (efi_enabled(EFI_DBG)) {
|
2014-09-03 11:32:23 +00:00
|
|
|
char buf[64];
|
|
|
|
|
|
|
|
pr_info(" 0x%012llx-0x%012llx %s",
|
2014-04-16 01:59:30 +00:00
|
|
|
paddr, paddr + (npages << EFI_PAGE_SHIFT) - 1,
|
2014-09-03 11:32:23 +00:00
|
|
|
efi_md_typeattr_format(buf, sizeof(buf), md));
|
|
|
|
}
|
2014-04-16 01:59:30 +00:00
|
|
|
|
|
|
|
memrange_efi_to_native(&paddr, &npages);
|
|
|
|
size = npages << PAGE_SHIFT;
|
|
|
|
|
|
|
|
if (is_normal_ram(md))
|
|
|
|
early_init_dt_add_memory_arch(paddr, size);
|
|
|
|
|
2014-10-20 14:35:21 +00:00
|
|
|
if (is_reserve_region(md)) {
|
2015-11-30 12:28:17 +00:00
|
|
|
memblock_mark_nomap(paddr, size);
|
2015-08-26 13:24:57 +00:00
|
|
|
if (efi_enabled(EFI_DBG))
|
2014-04-16 01:59:30 +00:00
|
|
|
pr_cont("*");
|
|
|
|
}
|
|
|
|
|
2015-08-26 13:24:57 +00:00
|
|
|
if (efi_enabled(EFI_DBG))
|
2014-04-16 01:59:30 +00:00
|
|
|
pr_cont("\n");
|
|
|
|
}
|
2014-07-28 18:03:03 +00:00
|
|
|
|
|
|
|
set_bit(EFI_MEMMAP, &efi.flags);
|
2014-04-16 01:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void __init efi_init(void)
|
|
|
|
{
|
|
|
|
struct efi_fdt_params params;
|
|
|
|
|
|
|
|
/* Grab UEFI information placed in FDT by stub */
|
2015-08-26 13:24:58 +00:00
|
|
|
if (!efi_get_fdt_params(¶ms))
|
2014-04-16 01:59:30 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
efi_system_table = params.system_table;
|
|
|
|
|
2015-10-23 09:48:16 +00:00
|
|
|
memmap.phys_map = params.mmap;
|
2014-04-16 01:59:30 +00:00
|
|
|
memmap.map = early_memremap(params.mmap, params.mmap_size);
|
2015-11-23 07:43:23 +00:00
|
|
|
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");
|
|
|
|
}
|
2014-04-16 01:59:30 +00:00
|
|
|
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();
|
2015-01-22 10:01:40 +00:00
|
|
|
early_memunmap(memmap.map, params.mmap_size);
|
2015-11-30 12:28:17 +00:00
|
|
|
memblock_mark_nomap(params.mmap & PAGE_MASK,
|
|
|
|
PAGE_ALIGN(params.mmap_size +
|
|
|
|
(params.mmap & ~PAGE_MASK)));
|
2015-01-22 10:01:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static bool __init efi_virtmap_init(void)
|
|
|
|
{
|
|
|
|
efi_memory_desc_t *md;
|
|
|
|
|
2015-11-17 08:53:31 +00:00
|
|
|
init_new_context(NULL, &efi_mm);
|
|
|
|
|
2015-01-22 10:01:40 +00:00
|
|
|
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);
|
arm64/efi: Fix boot crash by not padding between EFI_MEMORY_RUNTIME regions
The new Properties Table feature introduced in UEFIv2.5 may
split memory regions that cover PE/COFF memory images into
separate code and data regions. Since these regions only differ
in the type (runtime code vs runtime data) and the permission
bits, but not in the memory type attributes (UC/WC/WT/WB), the
spec does not require them to be aligned to 64 KB.
Since the relative offset of PE/COFF .text and .data segments
cannot be changed on the fly, this means that we can no longer
pad out those regions to be mappable using 64 KB pages.
Unfortunately, there is no annotation in the UEFI memory map
that identifies data regions that were split off from a code
region, so we must apply this logic to all adjacent runtime
regions whose attributes only differ in the permission bits.
So instead of rounding each memory region to 64 KB alignment at
both ends, only round down regions that are not directly
preceded by another runtime region with the same type
attributes. Since the UEFI spec does not mandate that the memory
map be sorted, this means we also need to sort it first.
Note that this change will result in all EFI_MEMORY_RUNTIME
regions whose start addresses are not aligned to the OS page
size to be mapped with executable permissions (i.e., on kernels
compiled with 64 KB pages). However, since these mappings are
only active during the time that UEFI Runtime Services are being
invoked, the window for abuse is rather small.
Tested-by: Mark Salter <msalter@redhat.com>
Tested-by: Mark Rutland <mark.rutland@arm.com> [UEFI 2.4 only]
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Reviewed-by: Mark Salter <msalter@redhat.com>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Cc: <stable@vger.kernel.org> # v4.0+
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will.deacon@arm.com>
Cc: linux-kernel@vger.kernel.org
Link: http://lkml.kernel.org/r/1443218539-7610-3-git-send-email-matt@codeblueprint.co.uk
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2015-09-25 22:02:19 +00:00
|
|
|
else if (md->type == EFI_RUNTIME_SERVICES_CODE ||
|
|
|
|
!PAGE_ALIGNED(md->phys_addr))
|
2015-01-22 10:01:40 +00:00
|
|
|
prot = PAGE_KERNEL_EXEC;
|
|
|
|
else
|
|
|
|
prot = PAGE_KERNEL;
|
|
|
|
|
arm64: efi: correctly map runtime regions
The kernel may use a page granularity of 4K, 16K, or 64K depending on
configuration.
When mapping EFI runtime regions, we use memrange_efi_to_native to round
the physical base address of a region down to a kernel page boundary,
and round the size up to a kernel page boundary, adding the residue left
over from rounding down the physical base address. We do not round down
the virtual base address.
In __create_mapping we account for the offset of the virtual base from a
granule boundary, adding the residue to the size before rounding the
base down to said granule boundary.
Thus we account for the residue twice, and when the residue is non-zero
will cause __create_mapping to map an additional page at the end of the
region. Depending on the memory map, this page may be in a region we are
not intended/permitted to map, or may clash with a different region that
we wish to map. In typical cases, mapping the next item in the memory
map will overwrite the erroneously created entry, as we sort the memory
map in the stub.
As __create_mapping can cope with base addresses which are not page
aligned, we can instead rely on it to map the region appropriately, and
simplify efi_virtmap_init by removing the unnecessary code.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2015-11-23 11:09:11 +00:00
|
|
|
create_pgd_mapping(&efi_mm, md->phys_addr, md->virt_addr,
|
|
|
|
md->num_pages << EFI_PAGE_SHIFT,
|
2015-11-17 08:53:31 +00:00
|
|
|
__pgprot(pgprot_val(prot) | PTE_NG));
|
2015-01-22 10:01:40 +00:00
|
|
|
}
|
|
|
|
return true;
|
2014-04-16 01:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2014-10-20 14:27:26 +00:00
|
|
|
* 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.
|
2014-04-16 01:59:30 +00:00
|
|
|
*/
|
2014-10-20 14:27:26 +00:00
|
|
|
static int __init arm64_enable_runtime_services(void)
|
2014-04-16 01:59:30 +00:00
|
|
|
{
|
|
|
|
u64 mapsize;
|
|
|
|
|
|
|
|
if (!efi_enabled(EFI_BOOT)) {
|
|
|
|
pr_info("EFI services will not be available.\n");
|
2015-11-23 07:43:24 +00:00
|
|
|
return 0;
|
2014-04-16 01:59:30 +00:00
|
|
|
}
|
|
|
|
|
2014-08-18 01:30:07 +00:00
|
|
|
if (efi_runtime_disabled()) {
|
|
|
|
pr_info("EFI runtime services will be disabled.\n");
|
2015-11-23 07:43:24 +00:00
|
|
|
return 0;
|
2014-08-18 01:30:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pr_info("Remapping and enabling EFI services.\n");
|
2015-01-15 12:01:06 +00:00
|
|
|
|
|
|
|
mapsize = memmap.map_end - memmap.map;
|
2015-10-23 09:48:16 +00:00
|
|
|
memmap.map = (__force void *)ioremap_cache(memmap.phys_map,
|
2014-04-16 01:59:30 +00:00
|
|
|
mapsize);
|
2015-01-15 12:01:06 +00:00
|
|
|
if (!memmap.map) {
|
|
|
|
pr_err("Failed to remap EFI memory map\n");
|
2015-11-23 07:43:24 +00:00
|
|
|
return -ENOMEM;
|
2015-01-15 12:01:06 +00:00
|
|
|
}
|
2014-04-16 01:59:30 +00:00
|
|
|
memmap.map_end = memmap.map + mapsize;
|
|
|
|
efi.memmap = &memmap;
|
|
|
|
|
2014-10-20 14:27:26 +00:00
|
|
|
efi.systab = (__force void *)ioremap_cache(efi_system_table,
|
|
|
|
sizeof(efi_system_table_t));
|
2014-07-04 15:25:09 +00:00
|
|
|
if (!efi.systab) {
|
2014-10-20 14:27:26 +00:00
|
|
|
pr_err("Failed to remap EFI System Table\n");
|
2015-11-23 07:43:24 +00:00
|
|
|
return -ENOMEM;
|
2014-07-04 15:25:09 +00:00
|
|
|
}
|
|
|
|
set_bit(EFI_SYSTEM_TABLES, &efi.flags);
|
2014-04-16 01:59:30 +00:00
|
|
|
|
2015-01-22 10:01:40 +00:00
|
|
|
if (!efi_virtmap_init()) {
|
2014-10-20 14:27:26 +00:00
|
|
|
pr_err("No UEFI virtual mapping was installed -- runtime services will not be available\n");
|
2015-11-23 07:43:24 +00:00
|
|
|
return -ENOMEM;
|
2014-04-16 01:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set up runtime services function pointers */
|
2014-07-04 17:41:53 +00:00
|
|
|
efi_native_runtime_setup();
|
2014-04-16 01:59:30 +00:00
|
|
|
set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
|
|
|
|
|
2014-08-15 13:22:44 +00:00
|
|
|
efi.runtime_version = efi.systab->hdr.revision;
|
|
|
|
|
2014-04-16 01:59:30 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2014-10-20 14:27:26 +00:00
|
|
|
early_initcall(arm64_enable_runtime_services);
|
2014-10-04 15:46:43 +00:00
|
|
|
|
|
|
|
static int __init arm64_dmi_init(void)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* On arm64, DMI depends on UEFI, and dmi_scan_machine() needs to
|
|
|
|
* be called early because dmi_id_init(), which is an arch_initcall
|
|
|
|
* itself, depends on dmi_scan_machine() having been called already.
|
|
|
|
*/
|
|
|
|
dmi_scan_machine();
|
2014-10-15 07:36:50 +00:00
|
|
|
if (dmi_available)
|
|
|
|
dmi_set_dump_stack_arch_desc();
|
2014-10-04 15:46:43 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
core_initcall(arm64_dmi_init);
|
2014-10-20 14:27:26 +00:00
|
|
|
|
|
|
|
static void efi_set_pgd(struct mm_struct *mm)
|
|
|
|
{
|
2015-11-17 08:53:31 +00:00
|
|
|
switch_mm(NULL, mm, NULL);
|
2014-10-20 14:27:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
2015-03-06 14:49:24 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* UpdateCapsule() depends on the system being shutdown via
|
|
|
|
* ResetSystem().
|
|
|
|
*/
|
|
|
|
bool efi_poweroff_required(void)
|
|
|
|
{
|
|
|
|
return efi_enabled(EFI_RUNTIME_SERVICES);
|
|
|
|
}
|