Fix some correctness issues in the lowelevel kernel bringup code.
authorkettenis <kettenis@openbsd.org>
Tue, 16 Mar 2021 10:57:47 +0000 (10:57 +0000)
committerkettenis <kettenis@openbsd.org>
Tue, 16 Mar 2021 10:57:47 +0000 (10:57 +0000)
- Make sure we install a dummy page table in TTBR0_EL1 before we change
  the size of the VA space in TCR_EL1.

- Flush the TLB after updating TCR_EL1.

- Flush TLB after installing the real kernel page table in TTBR1_EL1.

- Add some barriers around TLB flushes to make it consistent with
  other places where we do TLB flushes.

ok drahn@, patrick@

sys/arch/arm64/arm64/cpu.c
sys/arch/arm64/arm64/locore.S
sys/arch/arm64/arm64/pmap.c

index 6fa7d33..ed9498e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.c,v 1.51 2021/03/11 11:16:55 jsg Exp $    */
+/*     $OpenBSD: cpu.c,v 1.52 2021/03/16 10:57:47 kettenis Exp $       */
 
 /*
  * Copyright (c) 2016 Dale Rahn <drahn@dalerahn.com>
@@ -721,11 +721,14 @@ cpu_start_secondary(struct cpu_info *ci)
        while ((ci->ci_flags & CPUF_GO) == 0)
                __asm volatile("wfe");
 
+       WRITE_SPECIALREG(ttbr0_el1, pmap_kernel()->pm_pt0pa);
+       __asm volatile("isb");
        tcr = READ_SPECIALREG(tcr_el1);
        tcr &= ~TCR_T0SZ(0x3f);
        tcr |= TCR_T0SZ(64 - USER_SPACE_BITS);
        tcr |= TCR_A1;
        WRITE_SPECIALREG(tcr_el1, tcr);
+       cpu_tlb_flush();
 
        /* Enable PAN. */
        id_aa64mmfr1 = READ_SPECIALREG(id_aa64mmfr1_el1);
index 769724f..4a37fdc 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.35 2021/03/10 15:56:06 kettenis Exp $ */
+/* $OpenBSD: locore.S,v 1.36 2021/03/16 10:57:47 kettenis Exp $ */
 /*-
  * Copyright (c) 2012-2014 Andrew Turner
  * All rights reserved.
@@ -194,7 +194,10 @@ start_mmu:
        msr     mdscr_el1, xzr
 
        /* Invalidate the TLB */
+       dsb     ishst
        tlbi    vmalle1is
+       dsb     ish
+       isb
 
        ldr     x2, mair
        msr     mair_el1, x2
@@ -226,11 +229,17 @@ start_mmu:
 switch_mmu_kernel:
        RETGUARD_SETUP(switch_mmu_kernel, x15)
        dsb     sy
-       /* Invalidate the TLB */
-       tlbi    vmalle1is
+
        /* Load ttbr1 (kernel) */
        msr     ttbr1_el1, x0
        isb
+
+       /* Invalidate the TLB */
+       dsb     ishst
+       tlbi    vmalle1is
+       dsb     ish
+       isb
+
        RETGUARD_CHECK(switch_mmu_kernel, x15)
        ret
 
index 8c79446..054425d 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.74 2021/03/11 11:16:55 jsg Exp $ */
+/* $OpenBSD: pmap.c,v 1.75 2021/03/16 10:57:47 kettenis Exp $ */
 /*
  * Copyright (c) 2008-2009,2014-2016 Dale Rahn <drahn@dalerahn.com>
  *
@@ -1672,11 +1672,14 @@ pmap_init(void)
         * the identity mapping in TTBR0 and can set the TCR to a
         * more useful value.
         */
+       WRITE_SPECIALREG(ttbr0_el1, pmap_kernel()->pm_pt0pa);
+       __asm volatile("isb");
        tcr = READ_SPECIALREG(tcr_el1);
        tcr &= ~TCR_T0SZ(0x3f);
        tcr |= TCR_T0SZ(64 - USER_SPACE_BITS);
        tcr |= TCR_A1;
        WRITE_SPECIALREG(tcr_el1, tcr);
+       cpu_tlb_flush();
 
        pool_init(&pmap_pmap_pool, sizeof(struct pmap), 0, IPL_NONE, 0,
            "pmap", NULL);