tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Status of current on ARM?
What is the general status of netbsd-current on ARM?
evbarm on OMAP 2420 has been broken since August 6th. Imre Deak brought
up the issues on port-arm, and later a pr was failed
http://www.netbsd.org/cgi-bin/query-pr-single.pl?number=39791 .
An obvious workaround on OMAP 2420 is to undo a few changes, attached
patches, but I'm willing to test if anyone has better fixes around.
I would like to test and the post some thumb mode fixes to the kernel
which are working with OMAP 2420 on a branch from current, taken August
5th. But the failing kernel from current is blocking that work.
Thanks,
-Mikko
>From 26766c0a6a57834ade49058d234abed1bffb4bec Mon Sep 17 00:00:00 2001
From: Mikko Rapeli <mikko.rapeli%teleca.com@localhost>
Date: Fri, 31 Oct 2008 12:01:52 +0200
Subject: [PATCH] Revert "Fix a few more corner cases. Always KMPAGE or pages
with unmanaged writeable"
This reverts commit 1d3900d66f829eae25037a99917d2f6de341f6e1.
---
sys/arch/arm/arm32/pmap.c | 128 +++++++++++++++++--------------------
sys/arch/arm/include/arm32/pmap.h | 3 -
2 files changed, 58 insertions(+), 73 deletions(-)
diff --git a/sys/arch/arm/arm32/pmap.c b/sys/arch/arm/arm32/pmap.c
index c6247a2..c77ff9f 100644
--- a/sys/arch/arm/arm32/pmap.c
+++ b/sys/arch/arm/arm32/pmap.c
@@ -855,26 +855,20 @@ pmap_enter_pv(struct vm_page *pg, struct pv_entry *pve,
pmap_t pm,
pvp = &SLIST_FIRST(&pg->mdpage.pvh_list);
#ifdef PMAP_CACHE_VIPT
/*
- * Insert unmanaged entries, writeable first, at the head of
- * the pv list.
+ * Insert unmapped entries at the head of the pv list.
*/
if (__predict_true((flags & PVF_KENTRY) == 0)) {
while (*pvp != NULL && (*pvp)->pv_flags & PVF_KENTRY)
pvp = &SLIST_NEXT(*pvp, pv_link);
- } else if ((flags & PVF_WRITE) == 0) {
- while (*pvp != NULL && (*pvp)->pv_flags & PVF_WRITE)
- pvp = &SLIST_NEXT(*pvp, pv_link);
}
#endif
SLIST_NEXT(pve, pv_link) = *pvp; /* add to ... */
*pvp = pve; /* ... locked list */
- pg->mdpage.pvh_attrs |= flags & (PVF_REF | PVF_MOD);
#ifdef PMAP_CACHE_VIPT
- if ((pve->pv_flags & PVF_KWRITE) == PVF_KWRITE)
- pg->mdpage.pvh_attrs |= PVF_KMOD;
- if ((pg->mdpage.pvh_attrs & (PVF_DMOD|PVF_NC)) != PVF_NC)
+ pg->mdpage.pvh_attrs |= flags & (PVF_REF | PVF_MOD | PVF_KENTRY);
+ if ((flags & PVF_MOD) && (pg->mdpage.pvh_attrs & PVF_NC) == 0)
pg->mdpage.pvh_attrs |= PVF_DIRTY;
- KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 || (pg->mdpage.pvh_attrs
& (PVF_DIRTY|PVF_NC)));
+ KASSERT((pg->mdpage.pvh_attrs & PVF_MOD) == 0 || (pg->mdpage.pvh_attrs
& (PVF_DIRTY|PVF_NC)));
#endif
if (pm == pmap_kernel()) {
PMAPCOUNT(kernel_mappings);
@@ -958,6 +952,18 @@ pmap_remove_pv(struct vm_page *pg, pmap_t pm, vaddr_t va,
int skip_wired)
return (NULL);
--pm->pm_stats.wired_count;
}
+#ifdef PMAP_CACHE_VIPT
+ /*
+ * If we are removing the first pv entry and its
+ * a KENTRY, if the next one isn't also a KENTER,
+ * clear KENTRY from the page attributes.
+ */
+ if (SLIST_FIRST(&pg->mdpage.pvh_list) == pve
+ && (pve->pv_flags & PVF_KENTRY)
+ && (SLIST_NEXT(pve, pv_link) == NULL
+ || (SLIST_NEXT(pve, pv_link)->pv_flags &
PVF_KENTRY) == 0))
+ pg->mdpage.pvh_attrs &= ~PVF_KENTRY;
+#endif
*prevptr = SLIST_NEXT(pve, pv_link); /* remove it! */
if (pm == pmap_kernel()) {
PMAPCOUNT(kernel_unmappings);
@@ -998,21 +1004,18 @@ pmap_remove_pv(struct vm_page *pg, pmap_t pm, vaddr_t
va, int skip_wired)
#ifdef PMAP_CACHE_VIPT
/*
- * If we no longer have a WRITEABLE KENTRY at the head of list,
- * clear the KMOD attribute from the page.
- */
- if (SLIST_FIRST(&pg->mdpage.pvh_list) == NULL
- || (SLIST_FIRST(&pg->mdpage.pvh_list)->pv_flags & PVF_KWRITE) ==
PVF_KWRITE)
- pg->mdpage.pvh_attrs &= ~PVF_KMOD;
-
- /*
* If this was a writeable page and there are no more writeable
* mappings (ignoring KMPAGE), clear the WRITE flag and writeback
* the contents to memory.
*/
- if (pg->mdpage.krw_mappings + pg->mdpage.urw_mappings == 0)
+ if ((pg->mdpage.pvh_attrs & PVF_WRITE)
+ && pg->mdpage.krw_mappings + pg->mdpage.urw_mappings == 0) {
pg->mdpage.pvh_attrs &= ~PVF_WRITE;
- KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 || (pg->mdpage.pvh_attrs
& (PVF_DIRTY|PVF_NC)));
+#if 0 /* XYY */
+ if ((pg->mdpage.pvh_attrs & PVF_NC) == 0)
+ pmap_flush_page(pg, false);
+#endif
+ }
#endif /* PMAP_CACHE_VIPT */
return(pve); /* return removed pve */
@@ -1037,9 +1040,6 @@ pmap_modify_pv(struct vm_page *pg, pmap_t pm, vaddr_t va,
struct pv_entry *npv;
u_int flags, oflags;
- KASSERT((clr_mask & PVF_KENTRY) == 0);
- KASSERT((set_mask & PVF_KENTRY) == 0);
-
if ((npv = pmap_find_pv(pg, pm, va)) == NULL)
return (0);
@@ -1053,9 +1053,9 @@ pmap_modify_pv(struct vm_page *pg, pmap_t pm, vaddr_t va,
if (clr_mask & (PVF_REF | PVF_MOD)) {
pg->mdpage.pvh_attrs |= set_mask & (PVF_REF | PVF_MOD);
#ifdef PMAP_CACHE_VIPT
- if ((pg->mdpage.pvh_attrs & (PVF_DMOD|PVF_NC)) != PVF_NC)
+ if ((set_mask & PVF_MOD) && !(pg->mdpage.pvh_attrs & PVF_NC))
pg->mdpage.pvh_attrs |= PVF_DIRTY;
- KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 ||
(pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
+ KASSERT((pg->mdpage.pvh_attrs & PVF_MOD) == 0 ||
(pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
#endif
}
@@ -1102,7 +1102,6 @@ pmap_modify_pv(struct vm_page *pg, pmap_t pm, vaddr_t va,
pmap_syncicache_page(pg);
PMAPCOUNT(exec_synced_remap);
}
- KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 || (pg->mdpage.pvh_attrs
& (PVF_DIRTY|PVF_NC)));
#endif
PMAPCOUNT(remappings);
@@ -1851,7 +1850,6 @@ pmap_vac_me_harder(struct vm_page *pg, pmap_t pm, vaddr_t
va)
#endif
KASSERT(!va || pm);
- KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 || (pg->mdpage.pvh_attrs
& (PVF_DIRTY|PVF_NC)));
/* Already a conflict? */
if (__predict_false(pg->mdpage.pvh_attrs & PVF_NC)) {
@@ -1899,19 +1897,17 @@ pmap_vac_me_harder(struct vm_page *pg, pmap_t pm,
vaddr_t va)
}
#endif
+ if (ro_mappings > 1
+ && (pg->mdpage.pvh_attrs & PVF_DIRTY))
+ pmap_flush_page(pg, false);
+
pg->mdpage.pvh_attrs &= (PAGE_SIZE - 1) & ~PVF_NC;
pg->mdpage.pvh_attrs |= tst_mask | PVF_COLORED;
- /*
- * Restore DIRTY bit if page is modified
- */
- if (pg->mdpage.pvh_attrs & PVF_DMOD)
- pg->mdpage.pvh_attrs |= PVF_DIRTY;
PMAPCOUNT(vac_color_restore);
} else {
KASSERT(SLIST_FIRST(&pg->mdpage.pvh_list) != NULL);
KASSERT(SLIST_NEXT(SLIST_FIRST(&pg->mdpage.pvh_list),
pv_link) != NULL);
}
- KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 ||
(pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs &
PVF_WRITE));
} else if (!va) {
KASSERT(pmap_is_page_colored_p(pg));
@@ -1919,7 +1915,6 @@ pmap_vac_me_harder(struct vm_page *pg, pmap_t pm, vaddr_t
va)
|| (pg->mdpage.pvh_attrs & PVF_DIRTY));
if (rw_mappings == 0)
pg->mdpage.pvh_attrs &= ~PVF_WRITE;
- KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 ||
(pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs &
PVF_WRITE));
return;
} else if (!pmap_is_page_colored_p(pg)) {
@@ -1930,7 +1925,6 @@ pmap_vac_me_harder(struct vm_page *pg, pmap_t pm, vaddr_t
va)
pg->mdpage.pvh_attrs |= PVF_COLORED
| (va & arm_cache_prefer_mask)
| (rw_mappings > 0 ? PVF_WRITE : 0);
- KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 ||
(pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs &
PVF_WRITE));
return;
} else if (((pg->mdpage.pvh_attrs ^ va) & arm_cache_prefer_mask) == 0) {
@@ -1971,7 +1965,6 @@ pmap_vac_me_harder(struct vm_page *pg, pmap_t pm, vaddr_t
va)
PMAPCOUNT(vac_color_ok);
/* matching color, just return */
- KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 ||
(pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs &
PVF_WRITE));
return;
}
@@ -1983,7 +1976,6 @@ pmap_vac_me_harder(struct vm_page *pg, pmap_t pm, vaddr_t
va)
pmap_flush_page(pg, true);
pg->mdpage.pvh_attrs &= ~PVF_COLORED;
pg->mdpage.pvh_attrs |= PVF_NC;
- KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 ||
(pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
PMAPCOUNT(vac_color_erase);
} else if (rw_mappings == 0
&& (pg->mdpage.pvh_attrs & PVF_KMPAGE) == 0) {
@@ -2009,7 +2001,6 @@ pmap_vac_me_harder(struct vm_page *pg, pmap_t pm, vaddr_t
va)
} else {
PMAPCOUNT(vac_color_blind);
}
- KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 ||
(pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs &
PVF_WRITE));
return;
} else {
@@ -2025,16 +2016,12 @@ pmap_vac_me_harder(struct vm_page *pg, pmap_t pm,
vaddr_t va)
KASSERT(pv);
/*
* If there's only one mapped page, change color to the
- * page's new color and return. Restore the DIRTY bit
- * that was erased by pmap_flush_page.
+ * page's new color and return.
*/
if (SLIST_NEXT(pv, pv_link) == NULL) {
pg->mdpage.pvh_attrs &= PAGE_SIZE - 1;
pg->mdpage.pvh_attrs |= (va &
arm_cache_prefer_mask);
- if (pg->mdpage.pvh_attrs & PVF_DMOD)
- pg->mdpage.pvh_attrs |= PVF_DIRTY;
PMAPCOUNT(vac_color_change);
- KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0
|| (pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
KASSERT((rw_mappings == 0) ==
!(pg->mdpage.pvh_attrs & PVF_WRITE));
return;
}
@@ -2043,7 +2030,6 @@ pmap_vac_me_harder(struct vm_page *pg, pmap_t pm, vaddr_t
va)
pg->mdpage.pvh_attrs &= ~PVF_COLORED;
pg->mdpage.pvh_attrs |= PVF_NC;
PMAPCOUNT(vac_color_erase);
- KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 ||
(pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
}
fixup:
@@ -2146,11 +2132,6 @@ pmap_clearbit(struct vm_page *pg, u_int maskbits)
va = pv->pv_va;
pm = pv->pv_pmap;
oflags = pv->pv_flags;
- /*
- * Kernel entries are unmanaged and as such not to be changed.
- */
- if (oflags & PVF_KENTRY)
- continue;
pv->pv_flags &= ~maskbits;
pmap_acquire_pmap_lock(pm);
@@ -2294,6 +2275,10 @@ pmap_clearbit(struct vm_page *pg, u_int maskbits)
if (need_vac_me_harder) {
if (pg->mdpage.pvh_attrs & PVF_NC)
pmap_vac_me_harder(pg, NULL, 0);
+#if 0 /* XYY */
+ else
+ pmap_flush_page(pg, false);
+#endif
}
#endif
@@ -2465,17 +2450,16 @@ pmap_flush_page(struct vm_page *pg, bool flush)
/*
* Flush it.
*/
- if (flush) {
+ if (flush)
cpu_idcache_wbinv_range(cdstp + va_offset, PAGE_SIZE);
- pg->mdpage.pvh_attrs &= ~PVF_DIRTY;
- } else {
+ else
cpu_dcache_wb_range(cdstp + va_offset, PAGE_SIZE);
- /*
- * Mark that the page is no longer dirty.
- */
- if ((pg->mdpage.pvh_attrs & PVF_DMOD) == 0)
- pg->mdpage.pvh_attrs &= ~PVF_DIRTY;
- }
+
+ /*
+ * Mark that the page is no longer dirty.
+ */
+ if ((pg->mdpage.pvh_attrs & PVF_MOD) == 0)
+ pg->mdpage.pvh_attrs &= ~PVF_DIRTY;
/*
* Restore the page table entry since we might have interrupted
@@ -2526,6 +2510,9 @@ pmap_page_remove(struct vm_page *pg)
PMAPCOUNT(exec_discarded_page_protect);
pg->mdpage.pvh_attrs &= ~PVF_EXEC;
KASSERT((pg->mdpage.urw_mappings + pg->mdpage.krw_mappings ==
0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
+#if 0 /* XYY */
+ pmap_flush_page(pg, true); /* wbinv the contents */
+#endif
#endif
simple_unlock(&pg->mdpage.pvh_slock);
PMAP_HEAD_TO_MAP_UNLOCK();
@@ -2628,6 +2615,16 @@ pmap_page_remove(struct vm_page *pg)
pg->mdpage.pvh_attrs &= ~PVF_EXEC;
KASSERT(pg->mdpage.urw_mappings == 0);
KASSERT(pg->mdpage.uro_mappings == 0);
+#if 0 /* XYY */
+ if ((pg->mdpage.pvh_attrs & PMAP_KMPAGE) == 0) {
+ if (SLIST_EMPTY(&pg->mdpage.pvh_list)) {
+ pmap_flush_page(pg, true); /* wbinv the contents */
+ } else if ((pg->mdpage.pvh_attrs & PVF_WRITE)
+ && pg->mdpage.krw_mappings == 0) {
+ pmap_flush_page(pg, false); /* wb the contents */
+ }
+ }
+#endif
if (pg->mdpage.krw_mappings == 0)
pg->mdpage.pvh_attrs &= ~PVF_WRITE;
KASSERT((pg->mdpage.urw_mappings + pg->mdpage.krw_mappings == 0) ==
!(pg->mdpage.pvh_attrs & PVF_WRITE));
@@ -2979,11 +2976,9 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t
prot, int flags)
simple_unlock(&pg->mdpage.pvh_slock);
}
}
-#if defined(PMAP_CACHE_VIPT) && defined(DIAGNOSTIC)
- simple_lock(&pg->mdpage.pvh_slock);
- KASSERT((pg->mdpage.pvh_attrs & PVF_DMOD) == 0 || (pg->mdpage.pvh_attrs
& (PVF_DIRTY|PVF_NC)));
+#ifdef PMAP_CACHE_VIPT
+ KASSERT((pg->mdpage.pvh_attrs & PVF_MOD) == 0 || (pg->mdpage.pvh_attrs
& (PVF_DIRTY|PVF_NC)));
KASSERT(((pg->mdpage.pvh_attrs & PVF_WRITE) == 0) ==
(pg->mdpage.urw_mappings + pg->mdpage.krw_mappings == 0));
- simple_unlock(&pg->mdpage.pvh_slock);
#endif
pmap_release_pmap_lock(pm);
@@ -3808,15 +3803,8 @@ pmap_fault_fixup(pmap_t pm, vaddr_t va, vm_prot_t ftype,
int user)
printf("pmap_fault_fixup: mod emul. pm %p, va 0x%08lx, pa
0x%08lx\n",
pm, va, VM_PAGE_TO_PHYS(pg)));
- pg->mdpage.pvh_attrs |= PVF_REF | PVF_MOD;
+ pg->mdpage.pvh_attrs |= PVF_REF | PVF_MOD | PVF_DIRTY;
pv->pv_flags |= PVF_REF | PVF_MOD;
-#ifdef PMAP_CACHE_VIPT
- /*
- * If there are cacheable mappings for this page, mark it dirty.
- */
- if ((pg->mdpage.pvh_attrs & PVF_NC) == 0)
- pg->mdpage.pvh_attrs |= PVF_DIRTY;
-#endif
simple_unlock(&pg->mdpage.pvh_slock);
/*
diff --git a/sys/arch/arm/include/arm32/pmap.h
b/sys/arch/arm/include/arm32/pmap.h
index 9c8c9ef..e6f8cc1 100644
--- a/sys/arch/arm/include/arm32/pmap.h
+++ b/sys/arch/arm/include/arm32/pmap.h
@@ -238,9 +238,6 @@ extern pv_addr_t kernel_l1pt;
#define PVF_KENTRY 0x0100 /* page entered via
pmap_kenter_pa */
#define PVF_KMPAGE 0x0200 /* page is used for kmem */
#define PVF_DIRTY 0x0400 /* page may have dirty cache
lines */
-#define PVF_KMOD 0x0800 /* unmanaged page is modified
*/
-#define PVF_KWRITE (PVF_KENTRY|PVF_WRITE)
-#define PVF_DMOD (PVF_MOD|PVF_KMOD|PVF_KMPAGE)
#define PVF_NC (PVF_UNC|PVF_KNC)
/*
--
1.5.6.5
>From ddc01ca017fdf2c1f593e61bcc89f96376147012 Mon Sep 17 00:00:00 2001
From: Mikko Rapeli <mikko.rapeli%teleca.com@localhost>
Date: Fri, 31 Oct 2008 13:25:44 +0200
Subject: [PATCH] Revert "Change pv_entries to use SLIST."
This reverts commit d794d1a2a0f8d2e8aac026e5527e6ca13455f35c.
Conflicts:
sys/arch/arm/arm32/pmap.c
---
sys/arch/arm/arm32/pmap.c | 327 +++++++++++-----------------------
sys/arch/arm/include/arm32/vmparam.h | 4 +-
2 files changed, 106 insertions(+), 225 deletions(-)
diff --git a/sys/arch/arm/arm32/pmap.c b/sys/arch/arm/arm32/pmap.c
index c77ff9f..3ff70f6 100644
--- a/sys/arch/arm/arm32/pmap.c
+++ b/sys/arch/arm/arm32/pmap.c
@@ -304,7 +304,7 @@ static struct pool_cache pmap_l2ptp_cache;
static vaddr_t pmap_kernel_l2ptp_kva;
static paddr_t pmap_kernel_l2ptp_phys;
-#ifdef PMAPCOUNTERS
+#ifdef PMAPCOUNT
#define PMAP_EVCNT_INITIALIZER(name) \
EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "pmap", name)
@@ -440,7 +440,7 @@ EVCNT_ATTACH_STATIC(pmap_ev_activations);
*/
static pt_entry_t *csrc_pte, *cdst_pte;
static vaddr_t csrcp, cdstp;
-vaddr_t memhook; /* used by mem.c */
+vaddr_t memhook;
extern void *msgbufaddr;
int pmap_kmpages;
/*
@@ -594,7 +594,7 @@ int pmap_needs_pte_sync;
* Real definition of pv_entry.
*/
struct pv_entry {
- SLIST_ENTRY(pv_entry) pv_link; /* next pv_entry */
+ struct pv_entry *pv_next; /* next pv_entry */
pmap_t pv_pmap; /* pmap where mapping lies */
vaddr_t pv_va; /* virtual address for mapping */
u_int pv_flags; /* flags */
@@ -653,7 +653,7 @@ static int pmap_clean_page(struct pv_entry *,
bool);
#endif
#ifdef PMAP_CACHE_VIPT
static void pmap_syncicache_page(struct vm_page *);
-static void pmap_flush_page(struct vm_page *, bool);
+static void pmap_flush_page(struct vm_page *);
#endif
static void pmap_page_remove(struct vm_page *);
@@ -852,24 +852,19 @@ pmap_enter_pv(struct vm_page *pg, struct pv_entry *pve,
pmap_t pm,
pve->pv_flags = flags;
simple_lock(&pg->mdpage.pvh_slock); /* lock vm_page */
- pvp = &SLIST_FIRST(&pg->mdpage.pvh_list);
+ pvp = &pg->mdpage.pvh_list;
#ifdef PMAP_CACHE_VIPT
/*
* Insert unmapped entries at the head of the pv list.
*/
if (__predict_true((flags & PVF_KENTRY) == 0)) {
while (*pvp != NULL && (*pvp)->pv_flags & PVF_KENTRY)
- pvp = &SLIST_NEXT(*pvp, pv_link);
+ pvp = &(*pvp)->pv_next;
}
#endif
- SLIST_NEXT(pve, pv_link) = *pvp; /* add to ... */
+ pve->pv_next = *pvp; /* add to ... */
*pvp = pve; /* ... locked list */
-#ifdef PMAP_CACHE_VIPT
pg->mdpage.pvh_attrs |= flags & (PVF_REF | PVF_MOD | PVF_KENTRY);
- if ((flags & PVF_MOD) && (pg->mdpage.pvh_attrs & PVF_NC) == 0)
- pg->mdpage.pvh_attrs |= PVF_DIRTY;
- KASSERT((pg->mdpage.pvh_attrs & PVF_MOD) == 0 || (pg->mdpage.pvh_attrs
& (PVF_DIRTY|PVF_NC)));
-#endif
if (pm == pmap_kernel()) {
PMAPCOUNT(kernel_mappings);
if (flags & PVF_WRITE)
@@ -914,7 +909,7 @@ pmap_find_pv(struct vm_page *pg, pmap_t pm, vaddr_t va)
{
struct pv_entry *pv;
- SLIST_FOREACH(pv, &pg->mdpage.pvh_list, pv_link) {
+ for (pv = pg->mdpage.pvh_list; pv; pv = pv->pv_next) {
if (pm == pv->pv_pmap && va == pv->pv_va)
break;
}
@@ -940,7 +935,7 @@ pmap_remove_pv(struct vm_page *pg, pmap_t pm, vaddr_t va,
int skip_wired)
NPDEBUG(PDB_PVDUMP,
printf("pmap_remove_pv: pm %p, pg %p, va 0x%08lx\n", pm, pg, va));
- prevptr = &SLIST_FIRST(&pg->mdpage.pvh_list); /* prev pv_entry ptr */
+ prevptr = &pg->mdpage.pvh_list; /* previous pv_entry pointer */
pve = *prevptr;
while (pve) {
@@ -958,13 +953,13 @@ pmap_remove_pv(struct vm_page *pg, pmap_t pm, vaddr_t va,
int skip_wired)
* a KENTRY, if the next one isn't also a KENTER,
* clear KENTRY from the page attributes.
*/
- if (SLIST_FIRST(&pg->mdpage.pvh_list) == pve
+ if (pg->mdpage.pvh_list == pve
&& (pve->pv_flags & PVF_KENTRY)
- && (SLIST_NEXT(pve, pv_link) == NULL
- || (SLIST_NEXT(pve, pv_link)->pv_flags &
PVF_KENTRY) == 0))
+ && (pve->pv_next == NULL
+ || (pve->pv_next->pv_flags & PVF_KENTRY) == 0))
pg->mdpage.pvh_attrs &= ~PVF_KENTRY;
#endif
- *prevptr = SLIST_NEXT(pve, pv_link); /* remove it! */
+ *prevptr = pve->pv_next; /* remove it! */
if (pm == pmap_kernel()) {
PMAPCOUNT(kernel_unmappings);
if (pve->pv_flags & PVF_WRITE)
@@ -987,7 +982,7 @@ pmap_remove_pv(struct vm_page *pg, pmap_t pm, vaddr_t va,
int skip_wired)
* otherwise sync the i-cache for this page.
*/
if (PV_IS_EXEC_P(pg->mdpage.pvh_attrs)) {
- if (SLIST_EMPTY(&pg->mdpage.pvh_list)) {
+ if (pg->mdpage.pvh_list == NULL) {
pg->mdpage.pvh_attrs &= ~PVF_EXEC;
PMAPCOUNT(exec_discarded_unmap);
} else {
@@ -998,24 +993,18 @@ pmap_remove_pv(struct vm_page *pg, pmap_t pm, vaddr_t va,
int skip_wired)
#endif /* PMAP_CACHE_VIPT */
break;
}
- prevptr = &SLIST_NEXT(pve, pv_link); /* previous pointer */
- pve = *prevptr; /* advance */
+ prevptr = &pve->pv_next; /* previous pointer */
+ pve = pve->pv_next; /* advance */
}
#ifdef PMAP_CACHE_VIPT
/*
* If this was a writeable page and there are no more writeable
- * mappings (ignoring KMPAGE), clear the WRITE flag and writeback
- * the contents to memory.
+ * mappings (ignoring KMPAGE), clear the WRITE flag.
*/
if ((pg->mdpage.pvh_attrs & PVF_WRITE)
- && pg->mdpage.krw_mappings + pg->mdpage.urw_mappings == 0) {
+ && pg->mdpage.krw_mappings + pg->mdpage.urw_mappings == 0)
pg->mdpage.pvh_attrs &= ~PVF_WRITE;
-#if 0 /* XYY */
- if ((pg->mdpage.pvh_attrs & PVF_NC) == 0)
- pmap_flush_page(pg, false);
-#endif
- }
#endif /* PMAP_CACHE_VIPT */
return(pve); /* return removed pve */
@@ -1050,14 +1039,8 @@ pmap_modify_pv(struct vm_page *pg, pmap_t pm, vaddr_t va,
* There is at least one VA mapping this page.
*/
- if (clr_mask & (PVF_REF | PVF_MOD)) {
+ if (clr_mask & (PVF_REF | PVF_MOD))
pg->mdpage.pvh_attrs |= set_mask & (PVF_REF | PVF_MOD);
-#ifdef PMAP_CACHE_VIPT
- if ((set_mask & PVF_MOD) && !(pg->mdpage.pvh_attrs & PVF_NC))
- pg->mdpage.pvh_attrs |= PVF_DIRTY;
- KASSERT((pg->mdpage.pvh_attrs & PVF_MOD) == 0 ||
(pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
-#endif
- }
oflags = npv->pv_flags;
npv->pv_flags = flags = (oflags & ~clr_mask) | set_mask;
@@ -1605,7 +1588,7 @@ pmap_vac_me_kpmap(struct vm_page *pg, pmap_t pm, vaddr_t
va)
* kernel-writable pages.
*/
u_cacheable = 0;
- SLIST_FOREACH(pv, &pg->mdpage.pvh_list, pv_link) {
+ for (pv = pg->mdpage.pvh_list; pv; pv = pv->pv_next) {
if (pv->pv_pmap != pm && (pv->pv_flags & PVF_NC) == 0)
u_cacheable++;
}
@@ -1626,7 +1609,7 @@ pmap_vac_me_kpmap(struct vm_page *pg, pmap_t pm, vaddr_t
va)
* might not be set correctly, call pmap_vac_me_user
* to recalculate the settings.
*/
- SLIST_FOREACH(pv, &pg->mdpage.pvh_list, pv_link) {
+ for (pv = pg->mdpage.pvh_list; pv; pv = pv->pv_next) {
/*
* We know kernel mappings will get set
* correctly in other calls. We also know
@@ -1689,7 +1672,7 @@ pmap_vac_me_user(struct vm_page *pg, pmap_t pm, vaddr_t
va)
* Include kernel mappings as part of our own.
* Keep a pointer to the first one.
*/
- SLIST_FOREACH(pv, &pg->mdpage.pvh_list, pv_link) {
+ for (pv = npv = pg->mdpage.pvh_list; pv; pv = pv->pv_next) {
/* Count mappings in the same pmap */
if (pm == pv->pv_pmap || kpmap == pv->pv_pmap) {
if (entries++ == 0)
@@ -1721,7 +1704,7 @@ pmap_vac_me_user(struct vm_page *pg, pmap_t pm, vaddr_t
va)
if (cacheable_entries == 0)
return;
- for (pv = npv; pv; pv = SLIST_NEXT(pv, pv_link)) {
+ for (pv = npv; pv; pv = pv->pv_next) {
if ((pm != pv->pv_pmap && kpmap != pv->pv_pmap) ||
(pv->pv_flags & PVF_NC))
continue;
@@ -1763,7 +1746,7 @@ pmap_vac_me_user(struct vm_page *pg, pmap_t pm, vaddr_t
va)
* Turn cacheing back on for some pages. If it is a kernel
* page, only do so if there are no other writable pages.
*/
- for (pv = npv; pv; pv = SLIST_NEXT(pv, pv_link)) {
+ for (pv = npv; pv; pv = pv->pv_next) {
if (!(pv->pv_flags & PVF_NC) || (pm != pv->pv_pmap &&
(kpmap != pv->pv_pmap || other_writable)))
continue;
@@ -1831,9 +1814,6 @@ pmap_vac_me_harder(struct vm_page *pg, pmap_t pm, vaddr_t
va)
bool bad_alias;
struct l2_bucket *l2b;
pt_entry_t *ptep, pte, opte;
- const u_int
- rw_mappings = pg->mdpage.urw_mappings + pg->mdpage.krw_mappings,
- ro_mappings = pg->mdpage.uro_mappings + pg->mdpage.kro_mappings;
/* do we need to do anything? */
if (arm_cache_prefer_mask == 0)
@@ -1854,177 +1834,130 @@ pmap_vac_me_harder(struct vm_page *pg, pmap_t pm,
vaddr_t va)
/* Already a conflict? */
if (__predict_false(pg->mdpage.pvh_attrs & PVF_NC)) {
/* just an add, things are already non-cached */
- KASSERT(!(pg->mdpage.pvh_attrs & PVF_DIRTY));
bad_alias = false;
if (va) {
PMAPCOUNT(vac_color_none);
bad_alias = true;
- KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs &
PVF_WRITE));
+ KASSERT((pg->mdpage.urw_mappings +
pg->mdpage.krw_mappings == 0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
goto fixup;
}
- pv = SLIST_FIRST(&pg->mdpage.pvh_list);
+ pv = pg->mdpage.pvh_list;
/* the list can't be empty because it would be cachable */
if (pg->mdpage.pvh_attrs & PVF_KMPAGE) {
tst_mask = pg->mdpage.pvh_attrs;
} else {
KASSERT(pv);
tst_mask = pv->pv_va;
- pv = SLIST_NEXT(pv, pv_link);
+ pv = pv->pv_next;
}
/*
* Only check for a bad alias if we have writable mappings.
*/
- tst_mask &= arm_cache_prefer_mask;
- if (rw_mappings > 0 && arm_cache_prefer_mask) {
- for (; pv && !bad_alias; pv = SLIST_NEXT(pv, pv_link)) {
+ if (pg->mdpage.urw_mappings + pg->mdpage.krw_mappings > 0) {
+ tst_mask &= arm_cache_prefer_mask;
+ for (; pv && !bad_alias; pv = pv->pv_next) {
/* if there's a bad alias, stop checking. */
if (tst_mask != (pv->pv_va &
arm_cache_prefer_mask))
bad_alias = true;
}
pg->mdpage.pvh_attrs |= PVF_WRITE;
- if (!bad_alias)
- pg->mdpage.pvh_attrs |= PVF_DIRTY;
- } else {
- pg->mdpage.pvh_attrs &= ~PVF_WRITE;
}
/* If no conflicting colors, set everything back to cached */
if (!bad_alias) {
-#ifdef DEBUG
- if ((pg->mdpage.pvh_attrs & PVF_WRITE)
- || ro_mappings < 2) {
- SLIST_FOREACH(pv, &pg->mdpage.pvh_list, pv_link)
- KDASSERT(((tst_mask ^ pv->pv_va) &
arm_cache_prefer_mask) == 0);
- }
-
-#endif
- if (ro_mappings > 1
- && (pg->mdpage.pvh_attrs & PVF_DIRTY))
- pmap_flush_page(pg, false);
-
+ PMAPCOUNT(vac_color_restore);
pg->mdpage.pvh_attrs &= (PAGE_SIZE - 1) & ~PVF_NC;
pg->mdpage.pvh_attrs |= tst_mask | PVF_COLORED;
- PMAPCOUNT(vac_color_restore);
} else {
- KASSERT(SLIST_FIRST(&pg->mdpage.pvh_list) != NULL);
- KASSERT(SLIST_NEXT(SLIST_FIRST(&pg->mdpage.pvh_list),
pv_link) != NULL);
+ KASSERT(pg->mdpage.pvh_list != NULL);
+ KASSERT(pg->mdpage.pvh_list->pv_next != NULL);
}
- KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs &
PVF_WRITE));
+ KASSERT((pg->mdpage.urw_mappings + pg->mdpage.krw_mappings ==
0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
} else if (!va) {
KASSERT(pmap_is_page_colored_p(pg));
- KASSERT(!(pg->mdpage.pvh_attrs & PVF_WRITE)
- || (pg->mdpage.pvh_attrs & PVF_DIRTY));
- if (rw_mappings == 0)
+ pg->mdpage.pvh_attrs &= (PAGE_SIZE - 1) | arm_cache_prefer_mask;
+ if (pg->mdpage.urw_mappings + pg->mdpage.krw_mappings == 0)
pg->mdpage.pvh_attrs &= ~PVF_WRITE;
- KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs &
PVF_WRITE));
+ KASSERT((pg->mdpage.urw_mappings + pg->mdpage.krw_mappings ==
0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
return;
} else if (!pmap_is_page_colored_p(pg)) {
/* not colored so we just use its color */
- KASSERT(pg->mdpage.pvh_attrs & (PVF_WRITE|PVF_DIRTY));
PMAPCOUNT(vac_color_new);
pg->mdpage.pvh_attrs &= PAGE_SIZE - 1;
pg->mdpage.pvh_attrs |= PVF_COLORED
- | (va & arm_cache_prefer_mask)
- | (rw_mappings > 0 ? PVF_WRITE : 0);
- KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs &
PVF_WRITE));
+ | (va & arm_cache_prefer_mask);
+ if (pg->mdpage.urw_mappings + pg->mdpage.krw_mappings > 0)
+ pg->mdpage.pvh_attrs |= PVF_WRITE;
+ KASSERT((pg->mdpage.urw_mappings + pg->mdpage.krw_mappings ==
0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
return;
} else if (((pg->mdpage.pvh_attrs ^ va) & arm_cache_prefer_mask) == 0) {
bad_alias = false;
- if (rw_mappings > 0) {
+ if (pg->mdpage.urw_mappings + pg->mdpage.krw_mappings > 0) {
/*
* We now have writeable mappings and more than one
* readonly mapping, verify the colors don't clash
* and mark the page as writeable.
*/
- if (ro_mappings > 1
- && (pg->mdpage.pvh_attrs & PVF_WRITE) == 0
- && arm_cache_prefer_mask) {
+ if (pg->mdpage.uro_mappings + pg->mdpage.kro_mappings >
1
+ && (pg->mdpage.pvh_attrs & PVF_WRITE) == 0) {
tst_mask = pg->mdpage.pvh_attrs &
arm_cache_prefer_mask;
- SLIST_FOREACH(pv, &pg->mdpage.pvh_list,
pv_link) {
+ for (pv = pg->mdpage.pvh_list;
+ pv && !bad_alias;
+ pv = pv->pv_next) {
/* if there's a bad alias, stop
checking. */
- if (((tst_mask ^ pv->pv_va) &
arm_cache_prefer_mask) == 0) {
+ if (tst_mask != (pv->pv_va &
arm_cache_prefer_mask))
bad_alias = true;
- break;
- }
}
}
pg->mdpage.pvh_attrs |= PVF_WRITE;
}
/* If no conflicting colors, set everything back to cached */
if (!bad_alias) {
-#ifdef DEBUG
- if (rw_mappings > 0
- || (pg->mdpage.pvh_attrs & PMAP_KMPAGE)) {
- tst_mask = pg->mdpage.pvh_attrs &
arm_cache_prefer_mask;
- SLIST_FOREACH(pv, &pg->mdpage.pvh_list, pv_link)
- KDASSERT(((tst_mask ^ pv->pv_va) &
arm_cache_prefer_mask) == 0);
- }
-#endif
- if (SLIST_EMPTY(&pg->mdpage.pvh_list))
+ if (pg->mdpage.pvh_list)
PMAPCOUNT(vac_color_reuse);
else
PMAPCOUNT(vac_color_ok);
-
/* matching color, just return */
- KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs &
PVF_WRITE));
+ KASSERT((pg->mdpage.urw_mappings +
pg->mdpage.krw_mappings == 0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
return;
}
- KASSERT(SLIST_FIRST(&pg->mdpage.pvh_list) != NULL);
- KASSERT(SLIST_NEXT(SLIST_FIRST(&pg->mdpage.pvh_list), pv_link)
!= NULL);
+ KASSERT(pg->mdpage.pvh_list != NULL);
+ KASSERT(pg->mdpage.pvh_list->pv_next != NULL);
/* color conflict. evict from cache. */
- pmap_flush_page(pg, true);
+ pmap_flush_page(pg);
pg->mdpage.pvh_attrs &= ~PVF_COLORED;
pg->mdpage.pvh_attrs |= PVF_NC;
- PMAPCOUNT(vac_color_erase);
- } else if (rw_mappings == 0
+ } else if (pg->mdpage.urw_mappings + pg->mdpage.krw_mappings == 0
&& (pg->mdpage.pvh_attrs & PVF_KMPAGE) == 0) {
KASSERT((pg->mdpage.pvh_attrs & PVF_WRITE) == 0);
-
/*
- * If the page has dirty cache lines, clean it.
+ * If all the mappings are read-only, don't do anything.
*/
- if (pg->mdpage.pvh_attrs & PVF_DIRTY)
- pmap_flush_page(pg, false);
-
- /*
- * If this is the first remapping (we know that there are no
- * writeable mappings), then this is a simple color change.
- * Otherwise this is a seconary r/o mapping, which means
- * we don't have to do anything.
- */
- if (ro_mappings == 1) {
- KASSERT(((pg->mdpage.pvh_attrs ^ va) &
arm_cache_prefer_mask) != 0);
- pg->mdpage.pvh_attrs &= PAGE_SIZE - 1;
- pg->mdpage.pvh_attrs |= (va & arm_cache_prefer_mask);
- PMAPCOUNT(vac_color_change);
- } else {
- PMAPCOUNT(vac_color_blind);
- }
- KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs &
PVF_WRITE));
+ PMAPCOUNT(vac_color_blind);
+ KASSERT((pg->mdpage.urw_mappings + pg->mdpage.krw_mappings ==
0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
return;
} else {
- if (rw_mappings > 0)
+ if (pg->mdpage.urw_mappings + pg->mdpage.krw_mappings > 0)
pg->mdpage.pvh_attrs |= PVF_WRITE;
/* color conflict. evict from cache. */
- pmap_flush_page(pg, true);
+ pmap_flush_page(pg);
/* the list can't be empty because this was a enter/modify */
- pv = SLIST_FIRST(&pg->mdpage.pvh_list);
- if ((pg->mdpage.pvh_attrs & PVF_KMPAGE) == 0) {
- KASSERT(pv);
- /*
- * If there's only one mapped page, change color to the
- * page's new color and return.
- */
- if (SLIST_NEXT(pv, pv_link) == NULL) {
- pg->mdpage.pvh_attrs &= PAGE_SIZE - 1;
- pg->mdpage.pvh_attrs |= (va &
arm_cache_prefer_mask);
- PMAPCOUNT(vac_color_change);
- KASSERT((rw_mappings == 0) ==
!(pg->mdpage.pvh_attrs & PVF_WRITE));
- return;
- }
+ pv = pg->mdpage.pvh_list;
+ KASSERT(pv);
+
+ /*
+ * If there's only one mapped page, change color to the
+ * page's new color and return.
+ */
+ if (pv->pv_next == NULL) {
+ PMAPCOUNT(vac_color_change);
+ pg->mdpage.pvh_attrs &= PAGE_SIZE - 1;
+ pg->mdpage.pvh_attrs |= (va & arm_cache_prefer_mask);
+ KASSERT((pg->mdpage.urw_mappings +
pg->mdpage.krw_mappings == 0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
+ return;
}
bad_alias = true;
pg->mdpage.pvh_attrs &= ~PVF_COLORED;
@@ -2033,12 +1966,12 @@ pmap_vac_me_harder(struct vm_page *pg, pmap_t pm,
vaddr_t va)
}
fixup:
- KASSERT((rw_mappings == 0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
+ KASSERT((pg->mdpage.urw_mappings + pg->mdpage.krw_mappings == 0) ==
!(pg->mdpage.pvh_attrs & PVF_WRITE));
/*
* Turn cacheing on/off for all pages.
*/
- SLIST_FOREACH(pv, &pg->mdpage.pvh_list, pv_link) {
+ for (pv = pg->mdpage.pvh_list; pv; pv = pv->pv_next) {
l2b = pmap_get_l2_bucket(pv->pv_pmap, pv->pv_va);
ptep = &l2b->l2b_kva[l2pte_index(pv->pv_va)];
opte = *ptep;
@@ -2049,7 +1982,6 @@ pmap_vac_me_harder(struct vm_page *pg, pmap_t pm, vaddr_t
va)
pv->pv_flags &= ~PVF_NC;
pte |= pte_l2_s_cache_mode;
}
-
if (opte == pte) /* only update is there's a change */
continue;
@@ -2086,7 +2018,6 @@ pmap_clearbit(struct vm_page *pg, u_int maskbits)
const bool want_syncicache = PV_IS_EXEC_P(pg->mdpage.pvh_attrs);
bool need_syncicache = false;
bool did_syncicache = false;
- bool need_vac_me_harder = false;
#endif
NPDEBUG(PDB_BITS,
@@ -2109,7 +2040,7 @@ pmap_clearbit(struct vm_page *pg, u_int maskbits)
*/
pg->mdpage.pvh_attrs &= ~(maskbits & (PVF_MOD | PVF_REF));
- if (SLIST_EMPTY(&pg->mdpage.pvh_list)) {
+ if (pg->mdpage.pvh_list == NULL) {
#ifdef PMAP_CACHE_VIPT
if (need_syncicache) {
/*
@@ -2128,7 +2059,7 @@ pmap_clearbit(struct vm_page *pg, u_int maskbits)
/*
* Loop over all current mappings setting/clearing as appropos
*/
- SLIST_FOREACH(pv, &pg->mdpage.pvh_list, pv_link) {
+ for (pv = pg->mdpage.pvh_list; pv; pv = pv->pv_next) {
va = pv->pv_va;
pm = pv->pv_pmap;
oflags = pv->pv_flags;
@@ -2204,16 +2135,15 @@ pmap_clearbit(struct vm_page *pg, u_int maskbits)
pg->mdpage.pvh_attrs &= ~PVF_WRITE;
if (want_syncicache)
need_syncicache = true;
- need_vac_me_harder = true;
#endif
}
}
if (maskbits & PVF_REF) {
+#ifdef PMAP_CACHE_VIVT
if ((pv->pv_flags & PVF_NC) == 0 &&
(maskbits & (PVF_WRITE|PVF_MOD)) == 0 &&
l2pte_valid(npte)) {
-#ifdef PMAP_CACHE_VIVT
/*
* Check npte here; we may have already
* done the wbinv above, and the validity
@@ -2229,8 +2159,8 @@ pmap_clearbit(struct vm_page *pg, u_int maskbits)
pmap_dcache_wb_range(pm,
pv->pv_va, PAGE_SIZE,
true, true);
-#endif
}
+#endif
/*
* Make the PTE invalid so that we will take a
@@ -2267,19 +2197,6 @@ pmap_clearbit(struct vm_page *pg, u_int maskbits)
pmap_syncicache_page(pg);
PMAPCOUNT(exec_synced_clearbit);
}
- /*
- * If we are changing this to read-only, we need to call vac_me_harder
- * so we can change all the read-only pages to cacheable. We pretend
- * this as a page deletion.
- */
- if (need_vac_me_harder) {
- if (pg->mdpage.pvh_attrs & PVF_NC)
- pmap_vac_me_harder(pg, NULL, 0);
-#if 0 /* XYY */
- else
- pmap_flush_page(pg, false);
-#endif
- }
#endif
simple_unlock(&pg->mdpage.pvh_slock);
@@ -2328,7 +2245,7 @@ pmap_clean_page(struct pv_entry *pv, bool is_src)
*/
pm = curproc->p_vmspace->vm_map.pmap;
- for (npv = pv; npv; npv = SLIST_NEXT(npv, pv_link)) {
+ for (npv = pv; npv; npv = npv->pv_next) {
if (npv->pv_pmap == pmap_kernel() || npv->pv_pmap == pm) {
flags |= npv->pv_flags;
/*
@@ -2419,7 +2336,7 @@ pmap_syncicache_page(struct vm_page *pg)
}
void
-pmap_flush_page(struct vm_page *pg, bool flush)
+pmap_flush_page(struct vm_page *pg)
{
const vsize_t va_offset = pg->mdpage.pvh_attrs & arm_cache_prefer_mask;
const size_t pte_offset = va_offset >> PGSHIFT;
@@ -2450,16 +2367,7 @@ pmap_flush_page(struct vm_page *pg, bool flush)
/*
* Flush it.
*/
- if (flush)
- cpu_idcache_wbinv_range(cdstp + va_offset, PAGE_SIZE);
- else
- cpu_dcache_wb_range(cdstp + va_offset, PAGE_SIZE);
-
- /*
- * Mark that the page is no longer dirty.
- */
- if ((pg->mdpage.pvh_attrs & PVF_MOD) == 0)
- pg->mdpage.pvh_attrs &= ~PVF_DIRTY;
+ cpu_idcache_wbinv_range(cdstp + va_offset, PAGE_SIZE);
/*
* Restore the page table entry since we might have interrupted
@@ -2499,7 +2407,7 @@ pmap_page_remove(struct vm_page *pg)
PMAP_HEAD_TO_MAP_LOCK();
simple_lock(&pg->mdpage.pvh_slock);
- pv = SLIST_FIRST(&pg->mdpage.pvh_list);
+ pv = pg->mdpage.pvh_list;
if (pv == NULL) {
#ifdef PMAP_CACHE_VIPT
/*
@@ -2510,9 +2418,6 @@ pmap_page_remove(struct vm_page *pg)
PMAPCOUNT(exec_discarded_page_protect);
pg->mdpage.pvh_attrs &= ~PVF_EXEC;
KASSERT((pg->mdpage.urw_mappings + pg->mdpage.krw_mappings ==
0) == !(pg->mdpage.pvh_attrs & PVF_WRITE));
-#if 0 /* XYY */
- pmap_flush_page(pg, true); /* wbinv the contents */
-#endif
#endif
simple_unlock(&pg->mdpage.pvh_slock);
PMAP_HEAD_TO_MAP_UNLOCK();
@@ -2538,10 +2443,10 @@ pmap_page_remove(struct vm_page *pg)
pmap_clean_page(pv, false);
#endif
- pvp = &SLIST_FIRST(&pg->mdpage.pvh_list);
+ pvp = &pg->mdpage.pvh_list;
while (pv) {
pm = pv->pv_pmap;
- npv = SLIST_NEXT(pv, pv_link);
+ npv = pv->pv_next;
if (flush == false && (pm == curpm || pm == pmap_kernel()))
flush = true;
@@ -2554,7 +2459,7 @@ pmap_page_remove(struct vm_page *pg)
*/
if (pv->pv_flags & PVF_KENTRY) {
*pvp = pv;
- pvp = &SLIST_NEXT(pv, pv_link);
+ pvp = &pv->pv_next;
pv = npv;
continue;
}
@@ -2601,7 +2506,7 @@ pmap_page_remove(struct vm_page *pg)
*/
if (pv == NULL) {
*pvp = NULL;
- if (!SLIST_EMPTY(&pg->mdpage.pvh_list))
+ if (pg->mdpage.pvh_list != NULL)
pmap_vac_me_harder(pg, pm, 0);
}
pmap_release_pmap_lock(pm);
@@ -2613,19 +2518,7 @@ pmap_page_remove(struct vm_page *pg)
if (PV_IS_EXEC_P(pg->mdpage.pvh_attrs))
PMAPCOUNT(exec_discarded_page_protect);
pg->mdpage.pvh_attrs &= ~PVF_EXEC;
- KASSERT(pg->mdpage.urw_mappings == 0);
- KASSERT(pg->mdpage.uro_mappings == 0);
-#if 0 /* XYY */
- if ((pg->mdpage.pvh_attrs & PMAP_KMPAGE) == 0) {
- if (SLIST_EMPTY(&pg->mdpage.pvh_list)) {
- pmap_flush_page(pg, true); /* wbinv the contents */
- } else if ((pg->mdpage.pvh_attrs & PVF_WRITE)
- && pg->mdpage.krw_mappings == 0) {
- pmap_flush_page(pg, false); /* wb the contents */
- }
- }
-#endif
- if (pg->mdpage.krw_mappings == 0)
+ if (pg->mdpage.urw_mappings + pg->mdpage.krw_mappings == 0)
pg->mdpage.pvh_attrs &= ~PVF_WRITE;
KASSERT((pg->mdpage.urw_mappings + pg->mdpage.krw_mappings == 0) ==
!(pg->mdpage.pvh_attrs & PVF_WRITE));
#endif
@@ -2976,10 +2869,6 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t
prot, int flags)
simple_unlock(&pg->mdpage.pvh_slock);
}
}
-#ifdef PMAP_CACHE_VIPT
- KASSERT((pg->mdpage.pvh_attrs & PVF_MOD) == 0 || (pg->mdpage.pvh_attrs
& (PVF_DIRTY|PVF_NC)));
- KASSERT(((pg->mdpage.pvh_attrs & PVF_WRITE) == 0) ==
(pg->mdpage.urw_mappings + pg->mdpage.krw_mappings == 0));
-#endif
pmap_release_pmap_lock(pm);
PMAP_MAP_TO_HEAD_UNLOCK();
@@ -3228,7 +3117,7 @@ pmap_kremove_pg(struct vm_page *pg, vaddr_t va)
*/
if ((pg->mdpage.pvh_attrs & (PVF_NC|PVF_EXEC)) == PVF_EXEC
&& (pv->pv_flags & PVF_WRITE) != 0) {
- if (SLIST_EMPTY(&pg->mdpage.pvh_list)) {
+ if (pg->mdpage.pvh_list == NULL) {
pg->mdpage.pvh_attrs &= ~PVF_EXEC;
PMAPCOUNT(exec_discarded_kremove);
} else {
@@ -3316,13 +3205,11 @@ pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot)
KASSERT((pg->mdpage.pvh_attrs & PVF_NC) == 0);
/* if there is a color conflict, evict from cache. */
if (pmap_is_page_colored_p(pg)
- && ((va ^ pg->mdpage.pvh_attrs) &
arm_cache_prefer_mask)) {
- PMAPCOUNT(vac_color_change);
- pmap_flush_page(pg, true);
- }
+ && ((va ^ pg->mdpage.pvh_attrs) &
arm_cache_prefer_mask))
+ pmap_flush_page(pg);
pg->mdpage.pvh_attrs &= PAGE_SIZE - 1;
pg->mdpage.pvh_attrs |= PVF_KMPAGE
- | PVF_COLORED | PVF_DIRTY
+ | PVF_COLORED
| (va & arm_cache_prefer_mask);
#endif
#ifdef PMAP_CACHE_VIVT
@@ -3338,11 +3225,7 @@ pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot)
}
pmap_enter_pv(pg, pv, pmap_kernel(), va,
PVF_WIRED | PVF_KENTRY
- | (prot & VM_PROT_WRITE ? PVF_WRITE : 0));
- if ((prot & VM_PROT_WRITE)
- && !(pg->mdpage.pvh_attrs & PVF_NC))
- pg->mdpage.pvh_attrs |= PVF_DIRTY;
- KASSERT((prot & VM_PROT_WRITE) == 0 ||
(pg->mdpage.pvh_attrs & (PVF_DIRTY|PVF_NC)));
+ | (prot & VM_PROT_WRITE ? PVF_WRITE : 0));
simple_lock(&pg->mdpage.pvh_slock);
pmap_vac_me_harder(pg, pmap_kernel(), va);
simple_unlock(&pg->mdpage.pvh_slock);
@@ -3803,7 +3686,7 @@ pmap_fault_fixup(pmap_t pm, vaddr_t va, vm_prot_t ftype,
int user)
printf("pmap_fault_fixup: mod emul. pm %p, va 0x%08lx, pa
0x%08lx\n",
pm, va, VM_PAGE_TO_PHYS(pg)));
- pg->mdpage.pvh_attrs |= PVF_REF | PVF_MOD | PVF_DIRTY;
+ pg->mdpage.pvh_attrs |= PVF_REF | PVF_MOD;
pv->pv_flags |= PVF_REF | PVF_MOD;
simple_unlock(&pg->mdpage.pvh_slock);
@@ -4073,7 +3956,7 @@ pmap_activate(struct lwp *l)
}
/* No interrupts while we frob the TTB/DACR */
- oldirqstate = disable_interrupts(IF32_bits);
+ oldirqstate = disable_interrupts(I32_bit | F32_bit);
/*
* For ARM_VECTORS_LOW, we MUST, I repeat, MUST fix up the L1
@@ -4325,7 +4208,7 @@ pmap_zero_page_generic(paddr_t phys)
pt_entry_t * const ptep = &cdst_pte[va_offset >> PGSHIFT];
#ifdef DEBUG
- if (!SLIST_EMPTY(&pg->mdpage.pvh_list))
+ if (pg->mdpage.pvh_list != NULL)
panic("pmap_zero_page: page has mappings");
#endif
@@ -4363,7 +4246,6 @@ pmap_zero_page_generic(paddr_t phys)
pg->mdpage.pvh_attrs &= ~PVF_EXEC;
PMAPCOUNT(exec_discarded_zero);
}
- pg->mdpage.pvh_attrs |= PVF_DIRTY;
#endif
}
#endif /* (ARM_MMU_GENERIC + ARM_MMU_SA1 + ARM_MMU_V6) != 0 */
@@ -4375,7 +4257,7 @@ pmap_zero_page_xscale(paddr_t phys)
#ifdef DEBUG
struct vm_page *pg = PHYS_TO_VM_PAGE(phys);
- if (!SLIST_EMPTY(&pg->mdpage.pvh_list))
+ if (pg->mdpage.pvh_list != NULL)
panic("pmap_zero_page: page has mappings");
#endif
@@ -4421,7 +4303,7 @@ pmap_pageidlezero(paddr_t phys)
#ifdef DEBUG
- if (!SLIST_EMPTY(&pg->mdpage.pvh_list))
+ if (pg->mdpage.pvh_list != NULL)
panic("pmap_pageidlezero: page has mappings");
#endif
@@ -4509,7 +4391,7 @@ pmap_copy_page_generic(paddr_t src, paddr_t dst)
pt_entry_t * const dst_ptep = &cdst_pte[dst_va_offset >> PGSHIFT];
#ifdef DEBUG
- if (!SLIST_EMPTY(&dst_pg->mdpage.pvh_list))
+ if (dst_pg->mdpage.pvh_list != NULL)
panic("pmap_copy_page: dst page has mappings");
#endif
@@ -4526,7 +4408,7 @@ pmap_copy_page_generic(paddr_t src, paddr_t dst)
*/
simple_lock(&src_pg->mdpage.pvh_slock);
#ifdef PMAP_CACHE_VIVT
- (void) pmap_clean_page(SLIST_FIRST(&src_pg->mdpage.pvh_list), true);
+ (void) pmap_clean_page(src_pg->mdpage.pvh_list, true);
#endif
/*
@@ -4580,7 +4462,6 @@ pmap_copy_page_generic(paddr_t src, paddr_t dst)
dst_pg->mdpage.pvh_attrs &= ~PVF_EXEC;
PMAPCOUNT(exec_discarded_copy);
}
- dst_pg->mdpage.pvh_attrs |= PVF_DIRTY;
#endif
}
#endif /* (ARM_MMU_GENERIC + ARM_MMU_SA1 + ARM_MMU_V6) != 0 */
@@ -4593,7 +4474,7 @@ pmap_copy_page_xscale(paddr_t src, paddr_t dst)
#ifdef DEBUG
struct vm_page *dst_pg = PHYS_TO_VM_PAGE(dst);
- if (!SLIST_EMPTY(&dst_pg->mdpage.pvh_list))
+ if (dst_pg->mdpage.pvh_list != NULL)
panic("pmap_copy_page: dst page has mappings");
#endif
@@ -4607,7 +4488,7 @@ pmap_copy_page_xscale(paddr_t src, paddr_t dst)
*/
simple_lock(&src_pg->mdpage.pvh_slock);
#ifdef PMAP_CACHE_VIVT
- (void) pmap_clean_page(SLIST_FIRST(&src_pg->mdpage.pvh_list), true);
+ (void) pmap_clean_page(src_pg->mdpage.pvh_list, true);
#endif
/*
@@ -4683,7 +4564,7 @@ pmap_grow_map(vaddr_t va, pt_entry_t cache_mode, paddr_t
*pap)
* This new page must not have any mappings. Enter it via
* pmap_kenter_pa and let that routine do the hard work.
*/
- KASSERT(SLIST_EMPTY(&pg->mdpage.pvh_list));
+ KASSERT(pg->mdpage.pvh_list == NULL);
pmap_kenter_pa(va, pa, VM_PROT_READ|VM_PROT_WRITE|PMAP_KMPAGE);
#endif
}
@@ -5114,7 +4995,7 @@ pmap_bootstrap(vaddr_t vstart, vaddr_t vend)
pmap_set_pt_cache_mode(l1pt, (vaddr_t)csrc_pte);
pmap_alloc_specials(&virtual_avail, nptes, &cdstp, &cdst_pte);
pmap_set_pt_cache_mode(l1pt, (vaddr_t)cdst_pte);
- pmap_alloc_specials(&virtual_avail, nptes, &memhook, NULL);
+ pmap_alloc_specials(&virtual_avail, 1, (void *)&memhook, NULL);
pmap_alloc_specials(&virtual_avail, round_page(MSGBUFSIZE) / PAGE_SIZE,
(void *)&msgbufaddr, NULL);
@@ -6286,7 +6167,7 @@ pmap_dump_ncpg(pmap_t pm)
pg->mdpage.krw_mappings, pg->mdpage.kro_mappings,
pg->mdpage.urw_mappings, pg->mdpage.uro_mappings);
- SLIST_FOREACH(pv, &pg->mdpage.pvh_list, pv_link) {
+ for (pv = pg->mdpage.pvh_list; pv; pv = pv->pv_next) {
printf(" %c va 0x%08lx, flags 0x%x\n",
(pm == pv->pv_pmap) ? '*' : ' ',
pv->pv_va, pv->pv_flags);
diff --git a/sys/arch/arm/include/arm32/vmparam.h
b/sys/arch/arm/include/arm32/vmparam.h
index 892fca3..ba9644c 100644
--- a/sys/arch/arm/include/arm32/vmparam.h
+++ b/sys/arch/arm/include/arm32/vmparam.h
@@ -109,7 +109,7 @@ extern vaddr_t virtual_end;
*/
#define __HAVE_VM_PAGE_MD
struct vm_page_md {
- SLIST_HEAD(,pv_entry) pvh_list; /* pv_entry list */
+ struct pv_entry *pvh_list; /* pv_entry list */
struct simplelock pvh_slock; /* lock on this head */
int pvh_attrs; /* page attributes */
u_int uro_mappings;
@@ -137,7 +137,7 @@ struct vm_page_md {
#define VM_MDPAGE_INIT(pg)
\
do { \
- SLIST_INIT(&(pg)->mdpage.pvh_list); \
+ (pg)->mdpage.pvh_list = NULL; \
simple_lock_init(&(pg)->mdpage.pvh_slock); \
VM_MDPAGE_PVH_ATTRS_INIT(pg); \
(pg)->mdpage.uro_mappings = 0; \
--
1.5.6.5
Home |
Main Index |
Thread Index |
Old Index