Add some code, conditional on PMAP_ALIAS_DEBUG, that can be used to
hunt for virtual aliases between managed (pmap_enter) and non-managed (pmap_kenter_pa) mappings.
This commit is contained in:
parent
3834238acd
commit
884bc64586
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pmap.c,v 1.104 2002/08/06 21:43:51 thorpej Exp $ */
|
||||
/* $NetBSD: pmap.c,v 1.105 2002/08/09 18:22:59 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 Wasabi Systems, Inc.
|
||||
|
@ -143,7 +143,7 @@
|
|||
#include <machine/param.h>
|
||||
#include <arm/arm32/katelib.h>
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.104 2002/08/06 21:43:51 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.105 2002/08/09 18:22:59 thorpej Exp $");
|
||||
#ifdef PMAP_DEBUG
|
||||
#define PDEBUG(_lev_,_stat_) \
|
||||
if (pmap_debug_level >= (_lev_)) \
|
||||
|
@ -756,6 +756,22 @@ pmap_enter_pv(struct vm_page *pg, struct pv_entry *pve, struct pmap *pmap,
|
|||
simple_unlock(&pg->mdpage.pvh_slock); /* unlock, done! */
|
||||
if (pve->pv_flags & PVF_WIRED)
|
||||
++pmap->pm_stats.wired_count;
|
||||
#ifdef PMAP_ALIAS_DEBUG
|
||||
{
|
||||
int s = splhigh();
|
||||
if (pve->pv_flags & PVF_WRITE)
|
||||
pg->mdpage.rw_mappings++;
|
||||
else
|
||||
pg->mdpage.ro_mappings++;
|
||||
if (pg->mdpage.rw_mappings != 0 &&
|
||||
(pg->mdpage.kro_mappings != 0 || pg->mdpage.krw_mappings != 0)) {
|
||||
printf("pmap_enter_pv: rw %u, kro %u, krw %u\n",
|
||||
pg->mdpage.rw_mappings, pg->mdpage.kro_mappings,
|
||||
pg->mdpage.krw_mappings);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
#endif /* PMAP_ALIAS_DEBUG */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -781,6 +797,19 @@ pmap_remove_pv(struct vm_page *pg, struct pmap *pmap, vaddr_t va)
|
|||
*prevptr = pve->pv_next; /* remove it! */
|
||||
if (pve->pv_flags & PVF_WIRED)
|
||||
--pmap->pm_stats.wired_count;
|
||||
#ifdef PMAP_ALIAS_DEBUG
|
||||
{
|
||||
int s = splhigh();
|
||||
if (pve->pv_flags & PVF_WRITE) {
|
||||
KASSERT(pg->mdpage.rw_mappings != 0);
|
||||
pg->mdpage.rw_mappings--;
|
||||
} else {
|
||||
KASSERT(pg->mdpage.ro_mappings != 0);
|
||||
pg->mdpage.ro_mappings--;
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
#endif /* PMAP_ALIAS_DEBUG */
|
||||
break;
|
||||
}
|
||||
prevptr = &pve->pv_next; /* previous pointer */
|
||||
|
@ -824,6 +853,31 @@ pmap_modify_pv(struct pmap *pmap, vaddr_t va, struct vm_page *pg,
|
|||
else
|
||||
--pmap->pm_stats.wired_count;
|
||||
}
|
||||
#ifdef PMAP_ALIAS_DEBUG
|
||||
{
|
||||
int s = splhigh();
|
||||
if ((flags ^ oflags) & PVF_WRITE) {
|
||||
if (flags & PVF_WRITE) {
|
||||
pg->mdpage.rw_mappings++;
|
||||
pg->mdpage.ro_mappings--;
|
||||
if (pg->mdpage.rw_mappings != 0 &&
|
||||
(pg->mdpage.kro_mappings != 0 ||
|
||||
pg->mdpage.krw_mappings != 0)) {
|
||||
printf("pmap_modify_pv: rw %u, "
|
||||
"kro %u, krw %u\n",
|
||||
pg->mdpage.rw_mappings,
|
||||
pg->mdpage.kro_mappings,
|
||||
pg->mdpage.krw_mappings);
|
||||
}
|
||||
} else {
|
||||
KASSERT(pg->mdpage.rw_mappings != 0);
|
||||
pg->mdpage.rw_mappings--;
|
||||
pg->mdpage.ro_mappings++;
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
#endif /* PMAP_ALIAS_DEBUG */
|
||||
return (oflags);
|
||||
}
|
||||
}
|
||||
|
@ -1239,6 +1293,13 @@ pmap_alloc_ptpt(struct pmap *pmap)
|
|||
|
||||
*pte = L2_S_PROTO | pmap->pm_pptpt |
|
||||
L2_S_PROT(PTE_KERNEL, VM_PROT_READ|VM_PROT_WRITE);
|
||||
#ifdef PMAP_ALIAS_DEBUG
|
||||
{
|
||||
int s = splhigh();
|
||||
pg->mdpage.krw_mappings++;
|
||||
splx(s);
|
||||
}
|
||||
#endif /* PMAP_ALIAS_DEBUG */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -2707,10 +2768,44 @@ void
|
|||
pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot)
|
||||
{
|
||||
pt_entry_t *pte;
|
||||
|
||||
|
||||
pte = vtopte(va);
|
||||
KASSERT(!pmap_pte_v(pte));
|
||||
|
||||
#ifdef PMAP_ALIAS_DEBUG
|
||||
{
|
||||
struct vm_page *pg;
|
||||
int s;
|
||||
|
||||
pg = PHYS_TO_VM_PAGE(pa);
|
||||
if (pg != NULL) {
|
||||
s = splhigh();
|
||||
if (pg->mdpage.ro_mappings == 0 &&
|
||||
pg->mdpage.rw_mappings == 0 &&
|
||||
pg->mdpage.kro_mappings == 0 &&
|
||||
pg->mdpage.krw_mappings == 0) {
|
||||
/* This case is okay. */
|
||||
} else if (pg->mdpage.rw_mappings == 0 &&
|
||||
pg->mdpage.krw_mappings == 0 &&
|
||||
(prot & VM_PROT_WRITE) == 0) {
|
||||
/* This case is okay. */
|
||||
} else {
|
||||
/* Something is awry. */
|
||||
printf("pmap_kenter_pa: ro %u, rw %u, kro %u, krw %u "
|
||||
"prot 0x%x\n", pg->mdpage.ro_mappings,
|
||||
pg->mdpage.rw_mappings, pg->mdpage.kro_mappings,
|
||||
pg->mdpage.krw_mappings, prot);
|
||||
Debugger();
|
||||
}
|
||||
if (prot & VM_PROT_WRITE)
|
||||
pg->mdpage.krw_mappings++;
|
||||
else
|
||||
pg->mdpage.kro_mappings++;
|
||||
splx(s);
|
||||
}
|
||||
}
|
||||
#endif /* PMAP_ALIAS_DEBUG */
|
||||
|
||||
*pte = L2_S_PROTO | pa |
|
||||
L2_S_PROT(PTE_KERNEL, prot) | pte_l2_s_cache_mode;
|
||||
}
|
||||
|
@ -2729,6 +2824,25 @@ pmap_kremove(vaddr_t va, vsize_t len)
|
|||
|
||||
KASSERT(pmap_pde_page(pmap_pde(pmap_kernel(), va)));
|
||||
pte = vtopte(va);
|
||||
#ifdef PMAP_ALIAS_DEBUG
|
||||
{
|
||||
struct vm_page *pg;
|
||||
int s;
|
||||
|
||||
if ((*pte & L2_TYPE_MASK) != L2_TYPE_INV &&
|
||||
(pg = PHYS_TO_VM_PAGE(*pte & L2_S_FRAME)) != NULL) {
|
||||
s = splhigh();
|
||||
if (*pte & L2_S_PROT_W) {
|
||||
KASSERT(pg->mdpage.krw_mappings != 0);
|
||||
pg->mdpage.krw_mappings--;
|
||||
} else {
|
||||
KASSERT(pg->mdpage.kro_mappings != 0);
|
||||
pg->mdpage.kro_mappings--;
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
}
|
||||
#endif /* PMAP_ALIAS_DEBUG */
|
||||
cpu_idcache_wbinv_range(va, PAGE_SIZE);
|
||||
*pte = 0;
|
||||
cpu_tlb_flushID_SE(va);
|
||||
|
@ -2993,6 +3107,18 @@ pmap_clearbit(struct vm_page *pg, u_int maskbits)
|
|||
* Loop over all current mappings setting/clearing as appropos
|
||||
*/
|
||||
for (pv = pg->mdpage.pvh_list; pv; pv = pv->pv_next) {
|
||||
#ifdef PMAP_ALIAS_DEBUG
|
||||
{
|
||||
int s = splhigh();
|
||||
if ((maskbits & PVF_WRITE) != 0 &&
|
||||
(pv->pv_flags & PVF_WRITE) != 0) {
|
||||
KASSERT(pg->mdpage.rw_mappings != 0);
|
||||
pg->mdpage.rw_mappings--;
|
||||
pg->mdpage.ro_mappings++;
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
#endif /* PMAP_ALIAS_DEBUG */
|
||||
va = pv->pv_va;
|
||||
pv->pv_flags &= ~maskbits;
|
||||
ptes = pmap_map_ptes(pv->pv_pmap); /* locks pmap */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vmparam.h,v 1.9 2002/03/23 19:38:30 thorpej Exp $ */
|
||||
/* $NetBSD: vmparam.h,v 1.10 2002/08/09 18:23:00 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001, 2002 Wasabi Systems, Inc.
|
||||
|
@ -111,6 +111,12 @@ struct vm_page_md {
|
|||
struct pv_entry *pvh_list; /* pv_entry list */
|
||||
struct simplelock pvh_slock; /* lock on this head */
|
||||
int pvh_attrs; /* page attributes */
|
||||
#ifdef PMAP_ALIAS_DEBUG
|
||||
u_int ro_mappings;
|
||||
u_int rw_mappings;
|
||||
u_int kro_mappings;
|
||||
u_int krw_mappings;
|
||||
#endif /* PMAP_ALIAS_DEBUG */
|
||||
};
|
||||
|
||||
#define VM_MDPAGE_INIT(pg) \
|
||||
|
|
Loading…
Reference in New Issue