diff options
author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2015-11-17 09:53:31 +0100 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2015-11-18 09:40:20 +0000 |
commit | 65da0a8e34a857f2ba9ccb91dc8f8f964cf938b7 (patch) | |
tree | 8dd46aee28e086b06249e65042b03db96631eca4 /arch/arm64/kernel/efi.c | |
parent | de818bd4522c40ea02a81b387d2fa86f989c9623 (diff) | |
download | linux-65da0a8e34a857f2ba9ccb91dc8f8f964cf938b7.tar.gz linux-65da0a8e34a857f2ba9ccb91dc8f8f964cf938b7.tar.bz2 linux-65da0a8e34a857f2ba9ccb91dc8f8f964cf938b7.zip |
arm64: use non-global mappings for UEFI runtime regions
As pointed out by Russell King in response to the proposed ARM version
of this code, the sequence to switch between the UEFI runtime mapping
and current's actual userland mapping (and vice versa) is potentially
unsafe, since it leaves a time window between the switch to the new
page tables and the TLB flush where speculative accesses may hit on
stale global TLB entries.
So instead, use non-global mappings, and perform the switch via the
ordinary ASID-aware context switch routines.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/kernel/efi.c')
-rw-r--r-- | arch/arm64/kernel/efi.c | 14 |
1 files changed, 5 insertions, 9 deletions
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index de46b50f4cdf..fc5508e0df57 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -224,6 +224,8 @@ 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) { u64 paddr, npages, size; pgprot_t prot; @@ -254,7 +256,8 @@ static bool __init efi_virtmap_init(void) else prot = PAGE_KERNEL; - create_pgd_mapping(&efi_mm, paddr, md->virt_addr, size, prot); + create_pgd_mapping(&efi_mm, paddr, md->virt_addr, size, + __pgprot(pgprot_val(prot) | PTE_NG)); } return true; } @@ -329,14 +332,7 @@ core_initcall(arm64_dmi_init); static void efi_set_pgd(struct mm_struct *mm) { - if (mm == &init_mm) - cpu_set_reserved_ttbr0(); - else - cpu_switch_mm(mm->pgd, mm); - - local_flush_tlb_all(); - if (icache_is_aivivt()) - __local_flush_icache_all(); + switch_mm(NULL, mm, NULL); } void efi_virtmap_load(void) |