Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/arm32 Apply a bunch of break-before-make, i.e. ...
details: https://anonhg.NetBSD.org/src/rev/849f7f7fab31
branches: trunk
changeset: 333346:849f7f7fab31
user: skrll <skrll%NetBSD.org@localhost>
date: Wed Oct 29 22:52:21 2014 +0000
description:
Apply a bunch of break-before-make, i.e. set PTEs to zero, flush the TLB
(across all CPUs) and set new PTE value. Mostly from matt@ with some
updates from me.
Flush the branch predictor in pmap_update.
diffstat:
sys/arch/arm/arm32/pmap.c | 110 ++++++++++++++++++++++++++++++++-------------
1 files changed, 78 insertions(+), 32 deletions(-)
diffs (truncated from 338 to 300 lines):
diff -r 15ec55df4dbd -r 849f7f7fab31 sys/arch/arm/arm32/pmap.c
--- a/sys/arch/arm/arm32/pmap.c Wed Oct 29 22:11:34 2014 +0000
+++ b/sys/arch/arm/arm32/pmap.c Wed Oct 29 22:52:21 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.306 2014/10/29 22:11:34 skrll Exp $ */
+/* $NetBSD: pmap.c,v 1.307 2014/10/29 22:52:21 skrll Exp $ */
/*
* Copyright 2003 Wasabi Systems, Inc.
@@ -215,7 +215,7 @@
#include <arm/locore.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.306 2014/10/29 22:11:34 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.307 2014/10/29 22:52:21 skrll Exp $");
//#define PMAP_DEBUG
#ifdef PMAP_DEBUG
@@ -2496,11 +2496,14 @@
}
if (npte != opte) {
- l2pte_set(ptep, npte, opte);
+ l2pte_reset(ptep);
PTE_SYNC(ptep);
/* Flush the TLB entry if a current pmap. */
pmap_tlb_flush_SE(pm, va, oflags);
+
+ l2pte_set(ptep, npte, 0);
+ PTE_SYNC(ptep);
}
pmap_release_pmap_lock(pm);
@@ -2655,6 +2658,9 @@
for (size_t i = 0, j = 0; i < way_size;
i += PAGE_SIZE, j += PAGE_SIZE / L2_S_SIZE) {
+ l2pte_reset(ptep + j);
+ PTE_SYNC(ptep + j);
+
pmap_tlb_flush_SE(kpm, dstp + i, PVF_REF | PVF_EXEC);
/*
* Set up a PTE with to flush these cache lines.
@@ -2883,10 +2889,6 @@
pmap_release_page_lock(md);
pmap_acquire_pmap_lock(pm);
-#ifdef ARM_MMU_EXTENDED
- pmap_tlb_invalidate_addr(pm, pv->pv_va);
-#endif
-
l2b = pmap_get_l2_bucket(pm, pv->pv_va);
KASSERTMSG(l2b != NULL, "%#lx", pv->pv_va);
@@ -2908,7 +2910,14 @@
*/
l2pte_reset(ptep);
PTE_SYNC_CURRENT(pm, ptep);
+
+#ifdef ARM_MMU_EXTENDED
+ /* XXXNH pmap_tlb_flush_SE()? */
+ pmap_tlb_invalidate_addr(pm, pv->pv_va);
+#endif
+
pmap_free_l2_bucket(pm, l2b, PAGE_SIZE / L2_S_SIZE);
+
pmap_release_pmap_lock(pm);
pool_put(&pmap_pv_pool, pv);
@@ -3307,8 +3316,11 @@
* identical, so there's no need to update the page table.
*/
if (npte != opte) {
-
- l2pte_set(ptep, npte, opte);
+ l2pte_reset(ptep);
+ PTE_SYNC(ptep);
+ pmap_tlb_flush_SE(pm, va, oflags);
+
+ l2pte_set(ptep, npte, 0);
PTE_SYNC(ptep);
#ifndef ARM_MMU_EXTENDED
bool is_cached = pmap_is_cached(pm);
@@ -3336,8 +3348,6 @@
}
#endif /* !ARM_MMU_EXTENDED */
- pmap_tlb_flush_SE(pm, va, oflags);
-
#ifndef ARM_MMU_EXTENDED
UVMHIST_LOG(maphist, " is_cached %d cs 0x%08x\n",
is_cached, pm->pm_cstate.cs_all, 0, 0);
@@ -3481,6 +3491,7 @@
*/
l2pte_reset(ptep);
PTE_SYNC_CURRENT(pm, ptep);
+ pmap_tlb_flush_SE(pm, sva, flags);
continue;
}
@@ -3488,7 +3499,7 @@
if (pm == pmap_kernel()) {
l2pte_reset(ptep);
PTE_SYNC(ptep);
- pmap_tlb_flush_SE(pm, sva, flags);
+ pmap_tlb_flush_SE(pm, sva, flags);
continue;
}
#endif
@@ -3531,6 +3542,8 @@
if (cleanlist_idx <= PMAP_REMOVE_CLEAN_LIST_SIZE) {
total += cleanlist_idx;
for (cnt = 0; cnt < cleanlist_idx; cnt++) {
+ l2pte_reset(cleanlist[cnt].ptep);
+ PTE_SYNC_CURRENT(pm, cleanlist[cnt].ptep);
#ifdef ARM_MMU_EXTENDED
vaddr_t clva = cleanlist[cnt].va;
pmap_tlb_flush_SE(pm, clva, PVF_REF);
@@ -3547,8 +3560,6 @@
PVF_REF | flags);
}
#endif /* ARM_MMU_EXTENDED */
- l2pte_reset(cleanlist[cnt].ptep);
- PTE_SYNC_CURRENT(pm, cleanlist[cnt].ptep);
}
/*
@@ -3682,6 +3693,8 @@
}
#endif
if (l2pte_valid_p(opte)) {
+ l2pte_reset(ptep);
+ PTE_SYNC(ptep);
#ifdef PMAP_CACHE_VIVT
cpu_dcache_wbinv_range(va, PAGE_SIZE);
#endif
@@ -3699,7 +3712,7 @@
if (prot & VM_PROT_EXECUTE)
npte &= ~L2_XS_XN;
#endif
- l2pte_set(ptep, npte, opte);
+ l2pte_set(ptep, npte, 0);
PTE_SYNC(ptep);
if (pg) {
@@ -3790,7 +3803,8 @@
if (next_bucket > eva)
next_bucket = eva;
- struct l2_bucket * const l2b = pmap_get_l2_bucket(pmap_kernel(), va);
+ pmap_t kpm = pmap_kernel();
+ struct l2_bucket * const l2b = pmap_get_l2_bucket(kpm, va);
KDASSERT(l2b != NULL);
pt_entry_t * const sptep = &l2b->l2b_kva[l2pte_index(va)];
@@ -3825,13 +3839,13 @@
}
}
if (l2pte_valid_p(opte)) {
+ l2pte_reset(ptep);
+ PTE_SYNC(ptep);
#ifdef PMAP_CACHE_VIVT
cpu_dcache_wbinv_range(va, PAGE_SIZE);
#endif
cpu_tlb_flushD_SE(va);
- }
- if (opte) {
- l2pte_reset(ptep);
+
mappings += PAGE_SIZE / L2_S_SIZE;
}
va += PAGE_SIZE;
@@ -3840,7 +3854,7 @@
KDASSERTMSG(mappings <= l2b->l2b_occupancy, "%u %u",
mappings, l2b->l2b_occupancy);
l2b->l2b_occupancy -= mappings;
- PTE_SYNC_RANGE(sptep, (u_int)(ptep - sptep));
+ //PTE_SYNC_RANGE(sptep, (u_int)(ptep - sptep));
#ifdef UVMHIST
total_mappings += mappings;
#endif
@@ -3939,9 +3953,11 @@
pmap_acquire_pmap_lock(pm);
+#ifndef ARM_MMU_EXTENDED
const bool flush = eva - sva >= PAGE_SIZE * 4;
+ u_int flags = 0;
+#endif
u_int clr_mask = PVF_WRITE | ((prot & VM_PROT_EXECUTE) ? 0 : PVF_EXEC);
- u_int flags = 0;
while (sva < eva) {
next_bucket = L2_NEXT_BUCKET_VA(sva);
@@ -3960,7 +3976,9 @@
const pt_entry_t opte = *ptep;
if (l2pte_valid_p(opte) && l2pte_writable_p(opte)) {
struct vm_page *pg;
+#ifndef ARM_MMU_EXTENDED
u_int f;
+#endif
#ifdef PMAP_CACHE_VIVT
/*
@@ -3974,7 +3992,12 @@
pg = PHYS_TO_VM_PAGE(l2pte_pa(opte));
pt_entry_t npte = l2pte_set_readonly(opte);
- l2pte_set(ptep, npte, opte);
+ l2pte_reset(ptep);
+ PTE_SYNC(ptep);
+#ifdef ARM_MMU_EXTENDED
+ pmap_tlb_flush_SE(pm, sva, PVF_REF);
+#endif
+ l2pte_set(ptep, npte, 0);
PTE_SYNC(ptep);
if (pg != NULL) {
@@ -3982,10 +4005,14 @@
paddr_t pa = VM_PAGE_TO_PHYS(pg);
pmap_acquire_page_lock(md);
- f = pmap_modify_pv(md, pa, pm, sva,
- clr_mask, 0);
+#ifndef ARM_MMU_EXTENDED
+ f =
+#endif
+ pmap_modify_pv(md, pa, pm, sva,
+ clr_mask, 0);
pmap_vac_me_harder(md, pa, pm, sva);
pmap_release_page_lock(md);
+#ifndef ARM_MMU_EXTENDED
} else {
f = PVF_REF | PVF_EXEC;
}
@@ -3994,6 +4021,7 @@
flags |= f;
} else {
pmap_tlb_flush_SE(pm, sva, f);
+#endif
}
}
@@ -4002,6 +4030,7 @@
}
}
+#ifndef ARM_MMU_EXTENDED
if (flush) {
if (PV_BEEN_EXECD(flags)) {
pmap_tlb_flushID(pm);
@@ -4009,6 +4038,7 @@
pmap_tlb_flushD(pm);
}
}
+#endif
pmap_release_pmap_lock(pm);
}
@@ -4207,12 +4237,15 @@
KASSERT(pv != NULL);
if (PV_IS_EXEC_P(pv->pv_flags)) {
+ l2pte_reset(ptep);
+ PTE_SYNC(ptep);
+ pmap_tlb_flush_SE(pm, va, PVF_EXEC | PVF_REF);
if (!PV_IS_EXEC_P(md->pvh_attrs)) {
pmap_syncicache_page(md, pa);
}
rv = ABORT_FIXUP_RETURN;
- l2pte_set(ptep, opte & ~L2_XS_XN, opte);
- pmap_tlb_flush_SE(pm, va, PVF_EXEC | PVF_REF);
+ l2pte_set(ptep, opte & ~L2_XS_XN, 0);
+ PTE_SYNC(ptep);
}
pmap_release_page_lock(md);
@@ -4358,7 +4391,11 @@
| (pm != pmap_kernel() ? L2_XS_nG : 0)
#endif
| 0;
- l2pte_set(ptep, npte, opte);
+ l2pte_reset(ptep);
+ PTE_SYNC(ptep);
+ pmap_tlb_flush_SE(pm, va,
+ (ftype & VM_PROT_EXECUTE) ? PVF_EXEC | PVF_REF : PVF_REF);
+ l2pte_set(ptep, npte, 0);
PTE_SYNC(ptep);
PMAPCOUNT(fixup_mod);
rv = 1;
@@ -4425,7 +4462,11 @@
}
#endif /* ARM_MMU_EXTENDED */
pmap_release_page_lock(md);
- l2pte_set(ptep, npte, opte);
+ l2pte_reset(ptep);
+ PTE_SYNC(ptep);
+ pmap_tlb_flush_SE(pm, va,
+ (ftype & VM_PROT_EXECUTE) ? PVF_EXEC | PVF_REF : PVF_REF);
Home |
Main Index |
Thread Index |
Old Index