For armv6(VIPT), change the rules for mapping via kenter_pa. Allow readonly
pages to be mapped by different cache color indexes.
This commit is contained in:
parent
52956f334c
commit
6a96a3909c
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: pmap.c,v 1.178 2008/06/24 22:00:32 scw Exp $ */
|
/* $NetBSD: pmap.c,v 1.179 2008/07/03 06:13:41 matt Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2003 Wasabi Systems, Inc.
|
* Copyright 2003 Wasabi Systems, Inc.
|
||||||
@ -211,7 +211,7 @@
|
|||||||
#include <machine/param.h>
|
#include <machine/param.h>
|
||||||
#include <arm/arm32/katelib.h>
|
#include <arm/arm32/katelib.h>
|
||||||
|
|
||||||
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.178 2008/06/24 22:00:32 scw Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.179 2008/07/03 06:13:41 matt Exp $");
|
||||||
|
|
||||||
#ifdef PMAP_DEBUG
|
#ifdef PMAP_DEBUG
|
||||||
|
|
||||||
@ -1811,11 +1811,17 @@ pmap_vac_me_harder(struct vm_page *pg, pmap_t pm, vaddr_t va)
|
|||||||
tst_mask = pv->pv_va;
|
tst_mask = pv->pv_va;
|
||||||
pv = pv->pv_next;
|
pv = pv->pv_next;
|
||||||
}
|
}
|
||||||
tst_mask &= arm_cache_prefer_mask;
|
/*
|
||||||
for (; pv && !bad_alias; pv = pv->pv_next) {
|
* Only check for a bad alias if we have writable mappings.
|
||||||
/* if there's a bad alias, stop checking. */
|
*/
|
||||||
if (tst_mask != (pv->pv_va & arm_cache_prefer_mask))
|
if (pg->mdpage.urw_mappings + pg->mdpage.krw_mappings > 0
|
||||||
bad_alias = true;
|
|| (pg->mdpage.pvh_attrs & PVF_KENTRY)) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* If no conflicting colors, set everything back to cached */
|
/* If no conflicting colors, set everything back to cached */
|
||||||
if (!bad_alias) {
|
if (!bad_alias) {
|
||||||
@ -1847,7 +1853,13 @@ 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_COLORED
|
||||||
| (va & arm_cache_prefer_mask);
|
| (va & arm_cache_prefer_mask);
|
||||||
return;
|
return;
|
||||||
} else if (!((pg->mdpage.pvh_attrs ^ va) & arm_cache_prefer_mask)) {
|
} else if (!((pg->mdpage.pvh_attrs ^ va) & arm_cache_prefer_mask)
|
||||||
|
/*
|
||||||
|
* If the VA matches the existing color or if all the mappings
|
||||||
|
* are read-only, don't do anything.
|
||||||
|
*/
|
||||||
|
|| (pg->mdpage.urw_mappings + pg->mdpage.krw_mappings == 0
|
||||||
|
&& (pg->mdpage.pvh_attrs & PVF_KENTRY) == 0)) {
|
||||||
if (pm == NULL) {
|
if (pm == NULL) {
|
||||||
pg->mdpage.pvh_attrs &= PAGE_SIZE - 1;
|
pg->mdpage.pvh_attrs &= PAGE_SIZE - 1;
|
||||||
pg->mdpage.pvh_attrs |= va;
|
pg->mdpage.pvh_attrs |= va;
|
||||||
@ -3094,9 +3106,21 @@ pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot)
|
|||||||
#ifdef PMAP_CACHE_VIPT
|
#ifdef PMAP_CACHE_VIPT
|
||||||
if (pg) {
|
if (pg) {
|
||||||
simple_lock(&pg->mdpage.pvh_slock);
|
simple_lock(&pg->mdpage.pvh_slock);
|
||||||
KASSERT((pg->mdpage.pvh_attrs & PVF_KENTRY) == 0);
|
if (prot & VM_PROT_WRITE) {
|
||||||
pg->mdpage.pvh_attrs |= PVF_KENTRY;
|
/*
|
||||||
pmap_vac_me_harder(pg, NULL, va);
|
* If they want a writeable page, make sure it
|
||||||
|
* isn't already mapped in the kernel.
|
||||||
|
*/
|
||||||
|
KASSERT((pg->mdpage.pvh_attrs & PVF_KENTRY) == 0);
|
||||||
|
KASSERT(pg->mdpage.kro_mappings == 0);
|
||||||
|
pg->mdpage.pvh_attrs |= PVF_KENTRY;
|
||||||
|
pmap_vac_me_harder(pg, NULL, va);
|
||||||
|
} else {
|
||||||
|
KASSERT(pg->mdpage.krw_mappings == 0);
|
||||||
|
KASSERT(pg->mdpage.urw_mappings == 0);
|
||||||
|
KASSERT((pg->mdpage.pvh_attrs & PVF_NC) == 0);
|
||||||
|
pg->mdpage.kro_mappings++;
|
||||||
|
}
|
||||||
simple_unlock(&pg->mdpage.pvh_slock);
|
simple_unlock(&pg->mdpage.pvh_slock);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -3137,7 +3161,6 @@ pmap_kremove(vaddr_t va, vsize_t len)
|
|||||||
opg = PHYS_TO_VM_PAGE(l2pte_pa(opte));
|
opg = PHYS_TO_VM_PAGE(l2pte_pa(opte));
|
||||||
if (opg) {
|
if (opg) {
|
||||||
simple_lock(&opg->mdpage.pvh_slock);
|
simple_lock(&opg->mdpage.pvh_slock);
|
||||||
KASSERT(opg->mdpage.pvh_attrs & PVF_KENTRY);
|
|
||||||
if (PV_IS_EXEC_P(opg->mdpage.pvh_attrs)
|
if (PV_IS_EXEC_P(opg->mdpage.pvh_attrs)
|
||||||
&& !(opg->mdpage.pvh_attrs & PVF_NC)) {
|
&& !(opg->mdpage.pvh_attrs & PVF_NC)) {
|
||||||
if (opg->mdpage.pvh_list == NULL) {
|
if (opg->mdpage.pvh_list == NULL) {
|
||||||
@ -3150,8 +3173,14 @@ pmap_kremove(vaddr_t va, vsize_t len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
KASSERT(opg->mdpage.pvh_attrs & (PVF_COLORED|PVF_NC));
|
KASSERT(opg->mdpage.pvh_attrs & (PVF_COLORED|PVF_NC));
|
||||||
opg->mdpage.pvh_attrs &= ~PVF_KENTRY;
|
if (L2_AP(AP_W) & opte) {
|
||||||
pmap_vac_me_harder(opg, NULL, 0);
|
KASSERT(opg->mdpage.pvh_attrs & PVF_KENTRY);
|
||||||
|
opg->mdpage.pvh_attrs &= ~PVF_KENTRY;
|
||||||
|
pmap_vac_me_harder(opg, NULL, 0);
|
||||||
|
} else {
|
||||||
|
KASSERT(opg->mdpage.kro_mappings > 0);
|
||||||
|
opg->mdpage.kro_mappings--;
|
||||||
|
}
|
||||||
simple_unlock(&opg->mdpage.pvh_slock);
|
simple_unlock(&opg->mdpage.pvh_slock);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user