[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
i386 pmap diff to test
this fixes the pmap by fetching only the pte we want, not returning a
pointer of mostly meaningless use.
test it by booting a new kernel and running make build on i386.
Index: pmap.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/pmap.c,v
retrieving revision 1.75
diff -u -r1.75 pmap.c
--- pmap.c 2004/02/01 12:26:45 1.75
+++ pmap.c 2004/06/03 05:47:49
@@ -389,7 +389,7 @@
static void pmap_free_pvpage(void);
static struct vm_page *pmap_get_ptp(struct pmap *, int, boolean_t);
static boolean_t pmap_is_curpmap(struct pmap *);
-static pt_entry_t *pmap_map_ptes(struct pmap *);
+static pt_entry_t *pmap_get_pte(struct pmap *, vaddr_t);
static struct pv_entry *pmap_remove_pv(struct pv_head *, struct pmap *,
vaddr_t);
static boolean_t pmap_remove_pte(struct pmap *, struct vm_page *,
@@ -407,8 +407,6 @@
static boolean_t pmap_try_steal_pv(struct pv_head *,
struct pv_entry *,
struct pv_entry *);
-static void pmap_unmap_ptes(struct pmap *);
-
void pmap_pinit(pmap_t);
void pmap_release(pmap_t);
@@ -510,65 +508,32 @@
}
/*
- * pmap_map_ptes: map a pmap's PTEs into KVM and lock them in
- *
- * => we lock enough pmaps to keep things locked in
- * => must be undone with pmap_unmap_ptes before returning
+ * pmap_get_pte: find the PTE for the VA
*/
-__inline static pt_entry_t *
-pmap_map_ptes(pmap)
- struct pmap *pmap;
+static pt_entry_t *
+pmap_get_pte(struct pmap *pmap, vaddr_t va)
{
pd_entry_t opde;
+ pt_entry_t *ptes;
- /* the kernel's pmap is always accessible */
- if (pmap == pmap_kernel()) {
- return(PTE_BASE);
- }
-
- /* if curpmap then we are always mapped */
- if (pmap_is_curpmap(pmap)) {
- simple_lock(&pmap->pm_obj.vmobjlock);
- return(PTE_BASE);
- }
-
- /* need to lock both curpmap and pmap: use ordered locking */
- if ((unsigned) pmap < (unsigned) curpcb->pcb_pmap) {
- simple_lock(&pmap->pm_obj.vmobjlock);
- simple_lock(&curpcb->pcb_pmap->pm_obj.vmobjlock);
- } else {
- simple_lock(&curpcb->pcb_pmap->pm_obj.vmobjlock);
- simple_lock(&pmap->pm_obj.vmobjlock);
- }
-
- /* need to load a new alternate pt space into curpmap? */
- opde = *APDP_PDE;
- if (!pmap_valid_entry(opde) || (opde & PG_FRAME) != pmap->pm_pdirpa) {
- *APDP_PDE = (pd_entry_t) (pmap->pm_pdirpa | PG_RW | PG_V);
- if (pmap_valid_entry(opde))
- tlbflush();
- }
- return(APTE_BASE);
-}
-
-/*
- * pmap_unmap_ptes: unlock the PTE mapping of "pmap"
- */
-
-__inline static void
-pmap_unmap_ptes(pmap)
- struct pmap *pmap;
-{
if (pmap == pmap_kernel()) {
- return;
- }
- if (pmap_is_curpmap(pmap)) {
- simple_unlock(&pmap->pm_obj.vmobjlock);
+ /* the kernel's pmap is always accessible */
+ ptes = PTE_BASE;
+ } else if (pmap_is_curpmap(pmap)) {
+ /* if curpmap then we are always mapped */
+ ptes = PTE_BASE;
} else {
- simple_unlock(&pmap->pm_obj.vmobjlock);
- simple_unlock(&curpcb->pcb_pmap->pm_obj.vmobjlock);
+ /* need to load a new alternate pt space into curpmap? */
+ opde = *APDP_PDE;
+ if (!pmap_valid_entry(opde) || (opde & PG_FRAME) != pmap->pm_pdirpa) {
+ *APDP_PDE = (pd_entry_t) (pmap->pm_pdirpa | PG_RW | PG_V);
+ if (pmap_valid_entry(opde))
+ tlbflush();
+ }
+ ptes = APTE_BASE;
}
+ return (&ptes[i386_btop(va)]);
}
__inline static void
@@ -2030,12 +1995,11 @@
paddr_t *pap;
{
paddr_t retval;
- pt_entry_t *ptes;
+ pt_entry_t *pte;
if (pmap->pm_pdir[pdei(va)]) {
- ptes = pmap_map_ptes(pmap);
- retval = (paddr_t)(ptes[i386_btop(va)] & PG_FRAME);
- pmap_unmap_ptes(pmap);
+ pte = pmap_get_pte(pmap, va);
+ retval = (paddr_t)(*pte & PG_FRAME);
if (pap != NULL)
*pap = retval | (va & ~PG_FRAME);
return (TRUE);
@@ -2305,7 +2269,7 @@
panic("pmap_remove_pte: managed page without "
"PG_PVLIST for 0x%lx", va);
#endif
- return(TRUE);
+ goto out;
}
bank = vm_physseg_find(i386_btop(opte & PG_FRAME), &off);
@@ -2324,6 +2288,30 @@
if (pve)
pmap_free_pv(pmap, pve);
+
+out:
+ /*
+ * if mapping removed and the PTP is no longer
+ * being used, free it!
+ */
+
+ if (ptp && ptp->wire_count <= 1) {
+ pmap->pm_pdir[pdei(va)] = 0; /* zap! */
+#if defined(I386_CPU)
+ /* already dumped whole TLB on i386 */
+ if (cpu_class != CPUCLASS_386)
+#endif
+ {
+ pte = pmap_get_pte(pmap, 0);
+ pmap_update_pg(((vaddr_t) pte) +
+ ptp->offset);
+ }
+ pmap->pm_stats.resident_count--;
+ if (pmap->pm_ptphint == ptp)
+ pmap->pm_ptphint = TAILQ_FIRST(&pmap->pm_obj.memq);
+ ptp->wire_count = 0;
+ uvm_pagefree(ptp);
+ }
return(TRUE);
}
@@ -2338,8 +2326,7 @@
struct pmap *pmap;
vaddr_t sva, eva;
{
- pt_entry_t *ptes;
- boolean_t result;
+ pt_entry_t *pte;
paddr_t ptppa;
vaddr_t blkendva;
struct vm_page *ptp;
@@ -2350,7 +2337,6 @@
*/
PMAP_MAP_TO_HEAD_LOCK();
- ptes = pmap_map_ptes(pmap); /* locks pmap */
/*
* removing one page? take shortcut function.
@@ -2384,34 +2370,11 @@
}
/* do it! */
- result = pmap_remove_pte(pmap, ptp,
- &ptes[i386_btop(sva)], sva);
+ pte = pmap_get_pte(pmap, sva);
+ pmap_remove_pte(pmap, ptp, pte, sva);
- /*
- * if mapping removed and the PTP is no longer
- * being used, free it!
- */
-
- if (result && ptp && ptp->wire_count <= 1) {
- pmap->pm_pdir[pdei(sva)] = 0; /* zap! */
-#if defined(I386_CPU)
- /* already dumped whole TLB on i386 */
- if (cpu_class != CPUCLASS_386)
-#endif
- {
- pmap_update_pg(((vaddr_t) ptes) +
- ptp->offset);
- }
- pmap->pm_stats.resident_count--;
- if (pmap->pm_ptphint == ptp)
- pmap->pm_ptphint =
- TAILQ_FIRST(&pmap->pm_obj.memq);
- ptp->wire_count = 0;
- uvm_pagefree(ptp);
- }
}
- pmap_unmap_ptes(pmap); /* unlock pmap */
PMAP_MAP_TO_HEAD_UNLOCK();
return;
}
@@ -2479,13 +2442,14 @@
#endif
}
}
- pmap_remove_ptes(pmap, prr, ptp,
- (vaddr_t)&ptes[i386_btop(sva)], sva, blkendva);
+ pte = pmap_get_pte(pmap, sva);
+ pmap_remove_ptes(pmap, prr, ptp, (vaddr_t)pte, sva, blkendva);
/* if PTP is no longer being used, free it! */
if (ptp && ptp->wire_count <= 1) {
pmap->pm_pdir[pdei(sva)] = 0; /* zap! */
- pmap_update_pg( ((vaddr_t) ptes) + ptp->offset);
+ pmap_update_pg( ((vaddr_t) pmap_get_pte(pmap, 0)) +
+ ptp->offset);
#if defined(I386_CPU)
/* cancel possible pending pmap update on i386 */
if (cpu_class == CPUCLASS_386 && prr)
@@ -2521,7 +2485,6 @@
}
} /* not I386 */
}
- pmap_unmap_ptes(pmap);
PMAP_MAP_TO_HEAD_UNLOCK();
}
@@ -2539,7 +2502,7 @@
int bank, off;
struct pv_head *pvh;
struct pv_entry *pve;
- pt_entry_t *ptes, opte;
+ pt_entry_t *pte, opte;
#if defined(I386_CPU)
boolean_t needs_update = FALSE;
#endif
@@ -2563,8 +2526,6 @@
simple_lock(&pvh->pvh_lock);
for (pve = pvh->pvh_list ; pve != NULL ; pve = pve->pv_next) {
- ptes = pmap_map_ptes(pve->pv_pmap); /* locks pmap */
-
#ifdef DIAGNOSTIC
if (pve->pv_va >= uvm.pager_sva && pve->pv_va < uvm.pager_eva) {
printf("pmap_page_remove: found pager VA on pv_list\n");
@@ -2583,8 +2544,9 @@
}
#endif
- opte = ptes[i386_btop(pve->pv_va)];
- ptes[i386_btop(pve->pv_va)] = 0; /* zap! */
+ pte = pmap_get_pte(pve->pv_pmap, pve->pv_va);
+ opte = *pte;
+ *pte = 0; /* zap! */
if (opte & PG_W)
pve->pv_pmap->pm_stats.wired_count--;
@@ -2608,8 +2570,8 @@
if (pve->pv_ptp->wire_count <= 1) {
/* zap! */
pve->pv_pmap->pm_pdir[pdei(pve->pv_va)] = 0;
- pmap_update_pg(((vaddr_t)ptes) +
- pve->pv_ptp->offset);
+ pmap_update_pg(((vaddr_t)pmap_get_pte(
+ pve->pv_pmap, 0)) + pve->pv_ptp->offset);
#if defined(I386_CPU)
needs_update = FALSE;
#endif
@@ -2622,7 +2584,6 @@
uvm_pagefree(pve->pv_ptp);
}
}
- pmap_unmap_ptes(pve->pv_pmap); /* unlocks pmap */
}
pmap_free_pvs(NULL, pvh->pvh_list);
pvh->pvh_list = NULL;
@@ -2656,7 +2617,7 @@
char *myattrs;
struct pv_head *pvh;
struct pv_entry *pve;
- pt_entry_t *ptes, pte;
+ pt_entry_t *pte;
/* XXX: vm_page should either contain pv_head or have a pointer to it */
bank = vm_physseg_find(atop(VM_PAGE_TO_PHYS(pg)), &off);
@@ -2687,10 +2648,8 @@
for (pve = pvh->pvh_list; pve != NULL && (*myattrs & testbits) == 0;
pve = pve->pv_next) {
- ptes = pmap_map_ptes(pve->pv_pmap);
- pte = ptes[i386_btop(pve->pv_va)];
- pmap_unmap_ptes(pve->pv_pmap);
- *myattrs |= pte;
+ pte = pmap_get_pte(pve->pv_pmap, pve->pv_va);
+ *myattrs |= *pte;
}
/*
@@ -2719,7 +2678,7 @@
int bank, off;
struct pv_head *pvh;
struct pv_entry *pve;
- pt_entry_t *ptes, npte;
+ pt_entry_t *pte, npte;
char *myattrs;
#if defined(I386_CPU)
boolean_t needs_update = FALSE;
@@ -2748,12 +2707,12 @@
"detected");
#endif
- ptes = pmap_map_ptes(pve->pv_pmap); /* locks pmap */
- npte = ptes[i386_btop(pve->pv_va)];
+ pte = pmap_get_pte(pve->pv_pmap, pve->pv_va); /* locks pmap */
+ npte = *pte;
result |= (npte & clearbits);
npte = (npte | setbits) & ~clearbits;
- if (ptes[i386_btop(pve->pv_va)] != npte) {
- ptes[i386_btop(pve->pv_va)] = npte; /* zap! */
+ if (*pte != npte) {
+ *pte = npte; /* zap! */
if (pmap_is_curpmap(pve->pv_pmap)) {
#if defined(I386_CPU)
@@ -2764,7 +2723,6 @@
pmap_update_pg(pve->pv_va);
}
}
- pmap_unmap_ptes(pve->pv_pmap); /* unlocks pmap */
}
simple_unlock(&pvh->pvh_lock);
@@ -2813,8 +2771,6 @@
vaddr_t blockend, va;
u_int32_t md_prot;
- ptes = pmap_map_ptes(pmap); /* locks pmap */
-
/* need to worry about TLB? [TLB stores protection bits] */
if (pmap_is_curpmap(pmap)) {
prr = &pmap_rr;
@@ -2857,8 +2813,9 @@
/* XXX: write-prot our PTES? never! */
md_prot |= (PG_u | PG_RW);
- spte = &ptes[i386_btop(sva)];
- epte = &ptes[i386_btop(blockend)];
+ ptes = pmap_get_pte(pmap, 0);
+ spte = pmap_get_pte(pmap, sva);
+ epte = pmap_get_pte(pmap, blockend);
for (/*null */; spte < epte ; spte++, sva += PAGE_SIZE) {
@@ -2916,7 +2873,6 @@
}
} /* not I386 */
}
- pmap_unmap_ptes(pmap); /* unlocks pmap */
}
/*
@@ -2934,17 +2890,17 @@
struct pmap *pmap;
vaddr_t va;
{
- pt_entry_t *ptes;
+ pt_entry_t *pte;
if (pmap_valid_entry(pmap->pm_pdir[pdei(va)])) {
- ptes = pmap_map_ptes(pmap); /* locks pmap */
+ pte = pmap_get_pte(pmap, va);
#ifdef DIAGNOSTIC
- if (!pmap_valid_entry(ptes[i386_btop(va)]))
+ if (!pmap_valid_entry(*pte))
panic("pmap_unwire: invalid (unmapped) va 0x%lx", va);
#endif
- if ((ptes[i386_btop(va)] & PG_W) != 0) {
- ptes[i386_btop(va)] &= ~PG_W;
+ if ((*pte & PG_W) != 0) {
+ *pte &= ~PG_W;
pmap->pm_stats.wired_count--;
}
#ifdef DIAGNOSTIC
@@ -2953,7 +2909,6 @@
"didn't change!\n", pmap, va);
}
#endif
- pmap_unmap_ptes(pmap); /* unlocks map */
}
#ifdef DIAGNOSTIC
else {
@@ -3007,7 +2962,7 @@
vm_prot_t prot;
int flags;
{
- pt_entry_t *ptes, opte, npte;
+ pt_entry_t *pte, opte, npte;
struct vm_page *ptp;
struct pv_head *pvh;
struct pv_entry *pve;
@@ -3031,11 +2986,6 @@
/* get lock */
PMAP_MAP_TO_HEAD_LOCK();
- /*
- * map in ptes and get a pointer to our PTP (unless we are the kernel)
- */
-
- ptes = pmap_map_ptes(pmap); /* locks pmap */
if (pmap == pmap_kernel()) {
ptp = NULL;
} else {
@@ -3048,7 +2998,8 @@
panic("pmap_enter: get ptp failed");
}
}
- opte = ptes[i386_btop(va)]; /* old PTE */
+ pte = pmap_get_pte(pmap, va);
+ opte = *pte; /* old PTE */
/*
* is there currently a valid mapping at our VA?
@@ -3177,7 +3128,7 @@
if (pmap == pmap_kernel())
npte |= pmap_pg_g;
- ptes[i386_btop(va)] = npte; /* zap! */
+ *pte = npte; /* zap! */
if ((opte & ~(PG_M|PG_U)) != npte && pmap_is_curpmap(pmap))
pmap_update_pg(va);
@@ -3185,7 +3136,6 @@
error = 0;
out:
- pmap_unmap_ptes(pmap);
PMAP_MAP_TO_HEAD_UNLOCK();
return error;
@@ -3285,7 +3235,7 @@
struct pmap *pmap;
vaddr_t sva, eva;
{
- pt_entry_t *ptes, *pte;
+ pt_entry_t *pte;
vaddr_t blkendva;
/*
@@ -3301,7 +3251,6 @@
*/
PMAP_MAP_TO_HEAD_LOCK();
- ptes = pmap_map_ptes(pmap); /* locks pmap */
/*
* dumping a range of pages: we dump in PTP sized blocks (4MB)
@@ -3318,7 +3267,7 @@
if (!pmap_valid_entry(pmap->pm_pdir[pdei(sva)]))
continue;
- pte = &ptes[i386_btop(sva)];
+ pte = pmap_get_pte(pmap, sva);
for (/* null */; sva < blkendva ; sva += NBPG, pte++) {
if (!pmap_valid_entry(*pte))
continue;
@@ -3326,7 +3275,6 @@
sva, *pte, *pte & PG_FRAME);
}
}
- pmap_unmap_ptes(pmap);
PMAP_MAP_TO_HEAD_UNLOCK();
}
#endif
--
the only reason you're still alive
is because someone has decided to let you live