Commit 65da0a8e authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Catalin Marinas

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: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Acked-by: default avatarWill Deacon <will.deacon@arm.com>
Reviewed-by: default avatarMark Rutland <mark.rutland@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent de818bd4
...@@ -101,7 +101,7 @@ static inline void cpu_set_default_tcr_t0sz(void) ...@@ -101,7 +101,7 @@ static inline void cpu_set_default_tcr_t0sz(void)
#define destroy_context(mm) do { } while(0) #define destroy_context(mm) do { } while(0)
void check_and_switch_context(struct mm_struct *mm, unsigned int cpu); void check_and_switch_context(struct mm_struct *mm, unsigned int cpu);
#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; })
/* /*
* This is called when "tsk" is about to enter lazy TLB mode. * This is called when "tsk" is about to enter lazy TLB mode.
......
...@@ -224,6 +224,8 @@ static bool __init efi_virtmap_init(void) ...@@ -224,6 +224,8 @@ static bool __init efi_virtmap_init(void)
{ {
efi_memory_desc_t *md; efi_memory_desc_t *md;
init_new_context(NULL, &efi_mm);
for_each_efi_memory_desc(&memmap, md) { for_each_efi_memory_desc(&memmap, md) {
u64 paddr, npages, size; u64 paddr, npages, size;
pgprot_t prot; pgprot_t prot;
...@@ -254,7 +256,8 @@ static bool __init efi_virtmap_init(void) ...@@ -254,7 +256,8 @@ static bool __init efi_virtmap_init(void)
else else
prot = PAGE_KERNEL; 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; return true;
} }
...@@ -329,14 +332,7 @@ core_initcall(arm64_dmi_init); ...@@ -329,14 +332,7 @@ core_initcall(arm64_dmi_init);
static void efi_set_pgd(struct mm_struct *mm) static void efi_set_pgd(struct mm_struct *mm)
{ {
if (mm == &init_mm) switch_mm(NULL, mm, NULL);
cpu_set_reserved_ttbr0();
else
cpu_switch_mm(mm->pgd, mm);
local_flush_tlb_all();
if (icache_is_aivivt())
__local_flush_icache_all();
} }
void efi_virtmap_load(void) void efi_virtmap_load(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment