Get rid of pmap_map_early(). This is part of my crusade against the use of
authorkettenis <kettenis@openbsd.org>
Mon, 21 Nov 2022 20:19:21 +0000 (20:19 +0000)
committerkettenis <kettenis@openbsd.org>
Mon, 21 Nov 2022 20:19:21 +0000 (20:19 +0000)
1G mappings for the PA = VA identity mapping used in the early boot phase
of the kernel and when spinning up CPUs.  The mappings are dangerous since
they might (unintentially) covering address ranges that should not be
mapped (i.e. secure memory) which is dangerous on arm64 since the
architecture allows speculative access to any address for which a valid
mapping exists and even speculative access may cause the machine to
misbehave.

So instead of relying on the PA = VA identity mapping, call pmap_bootstrap()
earlier such that we can use pmap_kenter_cache() to enter mappings for the
FDT.

ok miod@

sys/arch/arm64/arm64/machdep.c
sys/arch/arm64/arm64/pmap.c
sys/arch/arm64/include/pmap.h

index 31b0e2f..36d5070 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.75 2022/10/30 17:43:39 guenther Exp $ */
+/* $OpenBSD: machdep.c,v 1.76 2022/11/21 20:19:21 kettenis Exp $ */
 /*
  * Copyright (c) 2014 Patrick Wildt <patrick@blueri.se>
  * Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org>
@@ -781,7 +781,9 @@ initarm(struct arm64_bootparams *abp)
        long kernbase = (long)_start & ~PAGE_MASK;
        long kvo = abp->kern_delta;
        paddr_t memstart, memend;
-       vaddr_t vstart;
+       paddr_t startpa, endpa, pa;
+       vaddr_t vstart, va;
+       struct fdt_head *fh;
        void *config = abp->arg2;
        void *fdt = NULL;
        struct fdt_reg reg;
@@ -798,10 +800,35 @@ initarm(struct arm64_bootparams *abp)
        __asm volatile("mov x18, %0\n"
            "msr tpidr_el1, %0" :: "r"(&cpu_info_primary));
 
-       pmap_map_early((paddr_t)config, PAGE_SIZE);
-       if (!fdt_init(config) || fdt_get_size(config) == 0)
-               panic("initarm: no FDT");
-       pmap_map_early((paddr_t)config, round_page(fdt_get_size(config)));
+       cache_setup();
+
+       /* The bootloader has loaded us into a 64MB block. */
+       memstart = KERNBASE + kvo;
+       memend = memstart + 64 * 1024 * 1024;
+
+       /* Bootstrap enough of pmap to enter the kernel proper. */
+       vstart = pmap_bootstrap(kvo, abp->kern_l1pt,
+           kernbase, esym, memstart, memend);
+
+       /* Map the FDT header to determine its size. */
+       va = vstart;
+       startpa = trunc_page((paddr_t)config);
+       endpa = round_page((paddr_t)config + sizeof(struct fdt_head));
+       for (pa = startpa; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE)
+               pmap_kenter_cache(va, pa, PROT_READ, PMAP_CACHE_WB);
+       fh = (void *)(vstart + ((paddr_t)config - startpa));
+       if (betoh32(fh->fh_magic) != FDT_MAGIC || betoh32(fh->fh_size) == 0)
+               panic("%s: no FDT", __func__);
+
+       /* Map the remainder of the FDT. */
+       endpa = round_page((paddr_t)config + betoh32(fh->fh_size));
+       for (; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE)
+               pmap_kenter_cache(va, pa, PROT_READ, PMAP_CACHE_WB);
+       config = (void *)(vstart + ((paddr_t)config - startpa));
+       vstart = va;
+
+       if (!fdt_init(config))
+               panic("%s: corrupt FDT", __func__);
 
        node = fdt_find_node("/chosen");
        if (node != NULL) {
@@ -867,18 +894,8 @@ initarm(struct arm64_bootparams *abp)
                }
        }
 
-       cache_setup();
-
        process_kernel_args();
 
-       /* The bootloader has loaded us into a 64MB block. */
-       memstart = KERNBASE + kvo;
-       memend = memstart + 64 * 1024 * 1024;
-
-       /* Bootstrap enough of pmap to enter the kernel proper. */
-       vstart = pmap_bootstrap(kvo, abp->kern_l1pt,
-           kernbase, esym, memstart, memend);
-
        proc0paddr = (struct user *)abp->kern_stack;
 
        msgbufaddr = (caddr_t)vstart;
index ef82308..47be3f1 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.88 2022/11/12 12:58:34 kettenis Exp $ */
+/* $OpenBSD: pmap.c,v 1.89 2022/11/21 20:19:21 kettenis Exp $ */
 /*
  * Copyright (c) 2008-2009,2014-2016 Dale Rahn <drahn@dalerahn.com>
  *
@@ -2259,41 +2259,6 @@ pmap_show_mapping(uint64_t va)
                pted, vp3->l3[VP_IDX3(va)], VP_IDX3(va)*8);
 }
 
-void
-pmap_map_early(paddr_t spa, psize_t len)
-{
-       extern pd_entry_t pagetable_l0_ttbr0[];
-       extern pd_entry_t pagetable_l1_ttbr0[];
-       extern uint64_t pagetable_l1_ttbr0_idx[];
-       extern uint64_t pagetable_l1_ttbr0_num;
-       extern uint64_t pagetable_l1_ttbr0_pa;
-       paddr_t pa, epa = spa + len;
-       uint64_t i, idx = ~0;
-
-       for (pa = spa & ~(L1_SIZE - 1); pa < epa; pa += L1_SIZE) {
-               for (i = 0; i < pagetable_l1_ttbr0_num; i++) {
-                       if (pagetable_l1_ttbr0_idx[i] == ~0)
-                               break;
-                       if (pagetable_l1_ttbr0_idx[i] == VP_IDX0(pa))
-                               break;
-               }
-               if (i == pagetable_l1_ttbr0_num)
-                       panic("%s: outside existing L0 entries", __func__);
-               if (pagetable_l1_ttbr0_idx[i] == ~0) {
-                       pagetable_l0_ttbr0[VP_IDX0(pa)] =
-                           (pagetable_l1_ttbr0_pa + i * PAGE_SIZE) | L0_TABLE;
-                       pagetable_l1_ttbr0_idx[i] = VP_IDX0(pa);
-               }
-
-               idx = i * (PAGE_SIZE / sizeof(uint64_t)) + VP_IDX1(pa);
-               pagetable_l1_ttbr0[idx] = pa | L1_BLOCK |
-                   ATTR_IDX(PTE_ATTR_WB) | ATTR_SH(SH_INNER) |
-                   ATTR_nG | ATTR_UXN | ATTR_AF | ATTR_AP(0);
-       }
-       __asm volatile("dsb sy" ::: "memory");
-       __asm volatile("isb");
-}
-
 void
 pmap_setttb(struct proc *p)
 {
index 73ce53b..cdb9685 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.h,v 1.20 2022/11/07 09:43:04 mpi Exp $ */
+/* $OpenBSD: pmap.h,v 1.21 2022/11/21 20:19:21 kettenis Exp $ */
 /*
  * Copyright (c) 2008,2009,2014 Dale Rahn <drahn@dalerahn.com>
  *
@@ -111,7 +111,6 @@ struct pv_entry;
 #define pmap_unuse_final(p)            do { /* nothing */ } while (0)
 int    pmap_fault_fixup(pmap_t, vaddr_t, vm_prot_t);
 void pmap_postinit(void);
-void   pmap_map_early(paddr_t, psize_t);
 
 #define __HAVE_PMAP_MPSAFE_ENTER_COW