summaryrefslogtreecommitdiff
path: root/sys/arch/arm64
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2022-11-21 20:19:22 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2022-11-21 20:19:22 +0000
commitb97e55b25885b1e697f905a70ee587c2e360297f (patch)
tree509afb46e6554b1228710952c92ed887cb185793 /sys/arch/arm64
parent2dc931a096c8fe5f1a187f0a556e59d89ef03bf6 (diff)
Get rid of pmap_map_early(). This is part of my crusade against the use of
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@
Diffstat (limited to 'sys/arch/arm64')
-rw-r--r--sys/arch/arm64/arm64/machdep.c49
-rw-r--r--sys/arch/arm64/arm64/pmap.c37
-rw-r--r--sys/arch/arm64/include/pmap.h3
3 files changed, 35 insertions, 54 deletions
diff --git a/sys/arch/arm64/arm64/machdep.c b/sys/arch/arm64/arm64/machdep.c
index 31b0e2f472c..36d5070b0a2 100644
--- a/sys/arch/arm64/arm64/machdep.c
+++ b/sys/arch/arm64/arm64/machdep.c
@@ -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;
diff --git a/sys/arch/arm64/arm64/pmap.c b/sys/arch/arm64/arm64/pmap.c
index ef823084b81..47be3f1e216 100644
--- a/sys/arch/arm64/arm64/pmap.c
+++ b/sys/arch/arm64/arm64/pmap.c
@@ -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>
*
@@ -2260,41 +2260,6 @@ pmap_show_mapping(uint64_t va)
}
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)
{
struct cpu_info *ci = curcpu();
diff --git a/sys/arch/arm64/include/pmap.h b/sys/arch/arm64/include/pmap.h
index 73ce53b5ba0..cdb9685beb7 100644
--- a/sys/arch/arm64/include/pmap.h
+++ b/sys/arch/arm64/include/pmap.h
@@ -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