summaryrefslogtreecommitdiffstats
path: root/sys/arm64
diff options
context:
space:
mode:
authorandrew <andrew@FreeBSD.org>2016-04-14 10:43:28 +0000
committerandrew <andrew@FreeBSD.org>2016-04-14 10:43:28 +0000
commit6d3c93b78f97448511c80efa6ac07fae0c315c3d (patch)
treec62f2fe9975437bdef02b7fa0a652ce2bb72ec2f /sys/arm64
parent19f97c184f0cadbfe6eaf32e2c3f2b84103ebe81 (diff)
downloadFreeBSD-src-6d3c93b78f97448511c80efa6ac07fae0c315c3d.zip
FreeBSD-src-6d3c93b78f97448511c80efa6ac07fae0c315c3d.tar.gz
Set the upper limit of the DMAP region to the limit of RAM as was found in
the physmap. This will reduce the likelihood of an issue where we have device memory mapped in the DMAP. This can only happen if it is within the same 1G block of normal memory. Reviewed by: kib Obtained from: ABT Systems Ltd Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D5938
Diffstat (limited to 'sys/arm64')
-rw-r--r--sys/arm64/arm64/pmap.c21
-rw-r--r--sys/arm64/include/vmparam.h8
2 files changed, 19 insertions, 10 deletions
diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
index f8a7fdd..2cf3c33 100644
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -221,6 +221,8 @@ struct msgbuf *msgbufp = NULL;
static struct rwlock_padalign pvh_global_lock;
vm_paddr_t dmap_phys_base; /* The start of the dmap region */
+vm_paddr_t dmap_phys_max; /* The limit of the dmap region */
+vm_offset_t dmap_max_addr; /* The virtual address limit of the dmap */
/* This code assumes all L1 DMAP entries will be used */
CTASSERT((DMAP_MIN_ADDRESS & ~L0_OFFSET) == DMAP_MIN_ADDRESS);
@@ -550,15 +552,15 @@ pmap_early_vtophys(vm_offset_t l1pt, vm_offset_t va)
}
static void
-pmap_bootstrap_dmap(vm_offset_t kern_l1, vm_paddr_t kernstart)
+pmap_bootstrap_dmap(vm_offset_t kern_l1, vm_paddr_t min_pa, vm_paddr_t max_pa)
{
vm_offset_t va;
vm_paddr_t pa;
u_int l1_slot;
- pa = dmap_phys_base = kernstart & ~L1_OFFSET;
+ pa = dmap_phys_base = min_pa & ~L1_OFFSET;
va = DMAP_MIN_ADDRESS;
- for (; va < DMAP_MAX_ADDRESS;
+ for (; va < DMAP_MAX_ADDRESS && pa < max_pa;
pa += L1_SIZE, va += L1_SIZE, l1_slot++) {
l1_slot = ((va - DMAP_MIN_ADDRESS) >> L1_SHIFT);
@@ -567,6 +569,10 @@ pmap_bootstrap_dmap(vm_offset_t kern_l1, vm_paddr_t kernstart)
ATTR_IDX(CACHED_MEMORY) | L1_BLOCK);
}
+ /* Set the upper limit of the DMAP region */
+ dmap_phys_max = pa;
+ dmap_max_addr = va;
+
cpu_dcache_wb_range((vm_offset_t)pagetable_dmap,
PAGE_SIZE * DMAP_TABLES);
cpu_tlb_flushID();
@@ -651,7 +657,7 @@ pmap_bootstrap(vm_offset_t l0pt, vm_offset_t l1pt, vm_paddr_t kernstart,
pt_entry_t *l2;
vm_offset_t va, freemempos;
vm_offset_t dpcpu, msgbufpv;
- vm_paddr_t pa, min_pa;
+ vm_paddr_t pa, max_pa, min_pa;
int i;
kern_delta = KERNBASE - kernstart;
@@ -671,7 +677,7 @@ pmap_bootstrap(vm_offset_t l0pt, vm_offset_t l1pt, vm_paddr_t kernstart,
rw_init(&pvh_global_lock, "pmap pv global");
/* Assume the address we were loaded to is a valid physical address */
- min_pa = KERNBASE - kern_delta;
+ min_pa = max_pa = KERNBASE - kern_delta;
/*
* Find the minimum physical address. physmap is sorted,
@@ -682,11 +688,12 @@ pmap_bootstrap(vm_offset_t l0pt, vm_offset_t l1pt, vm_paddr_t kernstart,
continue;
if (physmap[i] <= min_pa)
min_pa = physmap[i];
- break;
+ if (physmap[i + 1] > max_pa)
+ max_pa = physmap[i + 1];
}
/* Create a direct map region early so we can use it for pa -> va */
- pmap_bootstrap_dmap(l1pt, min_pa);
+ pmap_bootstrap_dmap(l1pt, min_pa, max_pa);
va = KERNBASE;
pa = KERNBASE - kern_delta;
diff --git a/sys/arm64/include/vmparam.h b/sys/arm64/include/vmparam.h
index 8dc8809..3d46ece 100644
--- a/sys/arm64/include/vmparam.h
+++ b/sys/arm64/include/vmparam.h
@@ -162,19 +162,19 @@
#define VM_MIN_KERNEL_ADDRESS (0xffff000000000000UL)
#define VM_MAX_KERNEL_ADDRESS (0xffff008000000000UL)
-/* 2TiB for the direct map region */
+/* 2 TiB maximum for the direct map region */
#define DMAP_MIN_ADDRESS (0xfffffd0000000000UL)
#define DMAP_MAX_ADDRESS (0xffffff0000000000UL)
#define DMAP_MIN_PHYSADDR (dmap_phys_base)
-#define DMAP_MAX_PHYSADDR (dmap_phys_base + (DMAP_MAX_ADDRESS - DMAP_MIN_ADDRESS))
+#define DMAP_MAX_PHYSADDR (dmap_phys_max)
/* True if pa is in the dmap range */
#define PHYS_IN_DMAP(pa) ((pa) >= DMAP_MIN_PHYSADDR && \
(pa) < DMAP_MAX_PHYSADDR)
/* True if va is in the dmap range */
#define VIRT_IN_DMAP(va) ((va) >= DMAP_MIN_ADDRESS && \
- (va) < DMAP_MAX_ADDRESS)
+ (va) < (dmap_max_addr))
#define PHYS_TO_DMAP(pa) \
({ \
@@ -237,6 +237,8 @@
#ifndef LOCORE
extern vm_paddr_t dmap_phys_base;
+extern vm_paddr_t dmap_phys_max;
+extern vm_offset_t dmap_max_addr;
extern u_int tsb_kernel_ldd_phys;
extern vm_offset_t vm_max_kernel_address;
extern vm_offset_t init_pt_va;
OpenPOWER on IntegriCloud