Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Jan 2008 01:29:12 GMT
From:      Kip Macy <kmacy@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 133516 for review
Message-ID:  <200801180129.m0I1TChU096363@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=133516

Change 133516 by kmacy@pandemonium:kmacy:xen31 on 2008/01/18 01:28:59

	- Be more aggressive about checking the valid bit when looking up ptes.
	- Release the shadow page directory pages when doing pmap_release.
	- Workaround the fact that xen loses the managed bit (OS reserved)
	  by checking against the VA being a user address.

Affected files ...

.. //depot/projects/xen31/sys/i386/xen/pmap.c#22 edit

Differences ...

==== //depot/projects/xen31/sys/i386/xen/pmap.c#22 (text+ko) ====

@@ -948,7 +948,7 @@
 		mtx_lock(&PMAP2mutex);
 		newpf = *pde & PG_FRAME;
 		if ((*PMAP2 & PG_FRAME) != newpf) {
-			*PMAP2 = newpf | PG_V | PG_A | PG_M;
+			*PMAP2 = newpf | PG_V | PG_A;
 			pmap_invalidate_page(kernel_pmap, (vm_offset_t)PADDR2);
 		}
 		return (PADDR2 + (i386_btop(va) & (NPTEPG - 1)));
@@ -1694,9 +1694,9 @@
 	vm_paddr_t ma;
 	int i;
 #ifdef PAE	
-	int npgptd = NPGPTD + 1;
+	int npgptd = 2*NPGPTD + 1;
 #else
-	int npgptd = NPGPTD;
+	int npgptd = 2*NPGPTD;
 #endif
 
 	KASSERT(pmap->pm_stats.resident_count == 0,
@@ -1709,19 +1709,17 @@
 	mtx_unlock_spin(&allpmaps_lock);
 
 	for (i = 0; i < NPGPTD; i++)
-		ptdpg[i] = PHYS_TO_VM_PAGE(PT_GET(&pmap->pm_pdir[PTDPTDI + i]) & PG_FRAME);
-	
+		ptdpg[i] = PHYS_TO_VM_PAGE(vtophys(pmap->pm_pdir_shadow + (i*NPDEPG)) & PG_FRAME);
+	for (i = 0; i < NPGPTD; i++)
+		ptdpg[NPGPTD + i] = PHYS_TO_VM_PAGE(vtophys(pmap->pm_pdir + (i*NPDEPG)) & PG_FRAME);
+
 #ifdef PAE
-	ptdpg[NPGPTD] = PHYS_TO_VM_PAGE(vtophys(pmap->pm_pdpt));
+	ptdpg[2*NPGPTD] = PHYS_TO_VM_PAGE(vtophys(pmap->pm_pdpt));
 #endif	
-	for (i = 0; i < nkpt + NPGPTD; i++) 
-		PD_CLEAR_VA(pmap, PTDPTDI + i, FALSE);
 
-	
-	bzero(pmap->pm_pdir + PTDPTDI, (nkpt + NPGPTD) *
-	    sizeof(*pmap->pm_pdir));
-
+	PT_UPDATES_FLUSH();
 	pmap_qremove((vm_offset_t)pmap->pm_pdir, NPGPTD);
+	pmap_qremove((vm_offset_t)pmap->pm_pdir_shadow, NPGPTD);	
 
 	for (i = 0; i < npgptd; i++) {
 		m = ptdpg[i];
@@ -1734,7 +1732,7 @@
 #endif
 		m->wire_count--;
 		atomic_subtract_int(&cnt.v_wire_count, 1);
-		vm_page_free_zero(m);
+		vm_page_free(m);
 	}
 	PMAP_LOCK_DESTROY(pmap);
 }
@@ -2157,7 +2155,13 @@
 	if (oldpte & PG_G)
 		pmap_invalidate_page(kernel_pmap, va);
 	pmap->pm_stats.resident_count -= 1;
-	if (oldpte & PG_MANAGED) {
+	/*
+	 * XXX This is not strictly correctly, but somewhere along the line
+	 * we are losing the managed bit on some pages. It is unclear to me
+	 * why, but I think the most likely explanation is that xen's writable
+	 * page table implementation doesn't respect the unused bits.
+	 */
+	if ((oldpte & PG_MANAGED) || ((oldpte & PG_V) && (va < VM_MAXUSER_ADDRESS))) {
 		m = PHYS_TO_VM_PAGE(xpmap_mtop(oldpte) & PG_FRAME);
 		if (oldpte & PG_M) {
 			KASSERT((oldpte & PG_RW),
@@ -2169,6 +2173,10 @@
 			vm_page_flag_set(m, PG_REFERENCED);
 		pmap_remove_entry(pmap, m, va);
 	}
+#ifdef DEBUG
+	else if (va < VM_MAXUSER_ADDRESS) 
+		printf("va=0x%x is unmanaged :-( \n", va);
+#endif	
 	return (pmap_unuse_pt(pmap, va, free));
 }
 
@@ -2183,7 +2191,7 @@
 	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
 	KASSERT(curthread->td_pinned > 0, ("curthread not pinned"));
 	PMAP_LOCK_ASSERT(pmap, MA_OWNED);
-	if ((pte = pmap_pte_quick(pmap, va)) == NULL || *pte == 0)
+	if ((pte = pmap_pte_quick(pmap, va)) == NULL || (*pte & PG_V) == 0)
 		return;
 	pmap_remove_pte(pmap, pte, va, free);
 	pmap_invalidate_page(pmap, va);
@@ -2270,7 +2278,7 @@
 
 		for (pte = pmap_pte_quick(pmap, sva); sva != pdnxt; pte++,
 		    sva += PAGE_SIZE) {
-			if (*pte == 0)
+			if ((*pte & PG_V) == 0)
 				continue;
 
 			/*
@@ -2602,7 +2610,9 @@
 		if (origpte & PG_MANAGED) {
 			om = PHYS_TO_VM_PAGE(opa);
 			pmap_remove_entry(pmap, om, va);
-		}
+		} else if (va < VM_MAXUSER_ADDRESS) 
+			printf("va=0x%x is unmanaged :-( \n", va);
+			
 		if (mpte != NULL) {
 			mpte->wire_count--;
 			KASSERT(mpte->wire_count > 0,
@@ -3278,6 +3288,7 @@
 					 * us a little bit of time as the list
 					 * on one of the pages is now corrupt
 					 */
+					allfree = 0;
 					goto skip;
 				}
 
@@ -3430,7 +3441,6 @@
 		PMAP_MARK_PRIV(xpmap_mtop(*pte));
 		pmap_pte_release(pte);
 	}
-	PT_UPDATES_FLUSH();
 }
 
 void
@@ -3444,7 +3454,6 @@
 		pte_store(pte, xpmap_mtop(*pte) | (PG_RW|PG_M));
 		pmap_pte_release(pte);
 	}
-	PT_UPDATES_FLUSH();
 }
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200801180129.m0I1TChU096363>