[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