Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 17 Jan 2008 04:15:10 GMT
From:      Kip Macy <kmacy@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 133450 for review
Message-ID:  <200801170415.m0H4FAKk010896@repoman.freebsd.org>

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

Change 133450 by kmacy@pandemonium:kmacy:xen31 on 2008/01/17 04:14:24

	This change works around an apparent flakiness in page table updating 
	hypercalls by switching to "writable" page tables.
	
	This appears to introduce a new bug (albeit a much more deterministic one) 
	in which the wire count on a page table isn't appropriately set. This causes
	the  page table to be prematurely freed losing any information about the pages 
	still being mapped leaving the pv list on the md page corrupt.

Affected files ...

.. //depot/projects/xen31/sys/i386/i386/vm_machdep.c#6 edit
.. //depot/projects/xen31/sys/i386/include/pmap.h#10 edit
.. //depot/projects/xen31/sys/i386/xen/pmap.c#16 edit
.. //depot/projects/xen31/sys/i386/xen/xen_machdep.c#15 edit

Differences ...

==== //depot/projects/xen31/sys/i386/i386/vm_machdep.c#6 (text+ko) ====

@@ -779,7 +779,7 @@
 	ptep = vtopte(sf->kva);
 	opte = *ptep;
 #ifdef XEN
-	PT_SET_MA(sf->kva, xpmap_ptom(VM_PAGE_TO_PHYS(m)) | pgeflag | PG_RW | PG_V);
+	*ptep = xpmap_ptom(VM_PAGE_TO_PHYS(m)) | pgeflag | PG_RW | PG_V;
 #else	
 	*ptep = VM_PAGE_TO_PHYS(m) | pgeflag | PG_RW | PG_V;
 #endif

==== //depot/projects/xen31/sys/i386/include/pmap.h#10 (text+ko) ====

@@ -232,32 +232,58 @@
 void    pmap_map_readonly(struct pmap *pmap, vm_offset_t va, int len);
 void    pmap_map_readwrite(struct pmap *pmap, vm_offset_t va, int len);
 
+
+static __inline pt_entry_t
+pte_load_store(pt_entry_t *ptep, pt_entry_t v)
+{
+	pt_entry_t r;
+
+	v = xpmap_ptom(v);
+	r = *ptep;
+	__asm __volatile(
+	    "1:\n"
+	    "\tlock; cmpxchg8b %1\n"
+	    "\tjnz 1b"
+	    : "+A" (r)
+	    : "m" (*ptep), "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)));
+	return (r);
+}
+
 static __inline pt_entry_t
-pte_load_clear(pt_entry_t *ptep)
+pte_load_store_ma(pt_entry_t *ptep, pt_entry_t v)
 {
 	pt_entry_t r;
 
-	r = PT_GET(ptep);
-	PT_CLEAR_VA(ptep, TRUE);
+	r = *ptep;
+	__asm __volatile(
+	    "1:\n"
+	    "\tlock; cmpxchg8b %1\n"
+	    "\tjnz 1b"
+	    : "+A" (r)
+	    : "m" (*ptep), "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)));
 	return (r);
 }
+
+
+#else 
+
+
 static __inline pt_entry_t
 pte_load_store(pt_entry_t *ptep, pt_entry_t v)
 {
 	pt_entry_t r;
-	r = PT_GET(ptep);
-	PT_SET_VA(ptep, v, TRUE);
+
+	r = *ptep;
+	__asm __volatile(
+	    "1:\n"
+	    "\tlock; cmpxchg8b %1\n"
+	    "\tjnz 1b"
+	    : "+A" (r)
+	    : "m" (*ptep), "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)));
 	return (r);
 }
 
-#define	pte_store(ptep, pte)	pte_load_store((ptep), (pt_entry_t)pte)
-#define	pte_clear(ptep)	pte_load_store((ptep), (pt_entry_t)0ULL)
-
-#ifdef PAE
-extern pt_entry_t pg_nx;
-#endif
 
-#else
 /*
  *	Routine:	pmap_kextract
  *	Function:
@@ -278,6 +304,8 @@
 	return pa;
 }
 
+#endif
+
 #ifdef PAE
 
 static __inline pt_entry_t
@@ -292,21 +320,6 @@
 	return (r);
 }
 
-static __inline pt_entry_t
-pte_load_store(pt_entry_t *ptep, pt_entry_t v)
-{
-	pt_entry_t r;
-
-	r = *ptep;
-	__asm __volatile(
-	    "1:\n"
-	    "\tlock; cmpxchg8b %1\n"
-	    "\tjnz 1b"
-	    : "+A" (r)
-	    : "m" (*ptep), "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)));
-	return (r);
-}
-
 /* XXXRU move to atomic.h? */
 static __inline int
 atomic_cmpset_64(volatile uint64_t *dst, uint64_t exp, uint64_t src)
@@ -332,6 +345,8 @@
 
 #define	pte_store(ptep, pte)	pte_load_store((ptep), (pt_entry_t)pte)
 
+#define	pte_store_ma(ptep, pte)	pte_load_store_ma((ptep), (pt_entry_t)pte)
+
 extern pt_entry_t pg_nx;
 
 #else /* PAE */
@@ -373,8 +388,6 @@
 #define	pte_clear(ptep)		pte_store((ptep), (pt_entry_t)0ULL)
 
 #define	pde_store(pdep, pde)	pte_store((pdep), (pde))
-#endif /* !XEN */
-
 #endif /* _KERNEL */
 
 /*

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

@@ -193,12 +193,8 @@
 #define pmap_pte_u(pte)		((*(int *)pte & PG_A) != 0)
 #define pmap_pte_v(pte)		((*(int *)pte & PG_V) != 0)
 
-#define pmap_pte_set_w(pte, v)  {				\
-    if (v)							\
-	PT_SET_VA_MA(pte, *pte | PG_W, TRUE); 			\
-    else 							\
-	PT_SET_VA_MA(pte, *pte & ~PG_W, TRUE); 			\
-}
+#define pmap_pte_set_w(pte, v)	((v) ? atomic_set_int((u_int *)(pte), PG_W) : \
+    atomic_clear_int((u_int *)(pte), PG_W))
 #define pmap_pte_set_prot(pte, v) ((*(int *)pte &= ~PG_PROT), (*(int *)pte |= (v)))
 
 struct pmap kernel_pmap_store;
@@ -257,7 +253,6 @@
 #endif
 static pt_entry_t *PMAP1 = 0, *PMAP2;
 static pt_entry_t *PADDR1 = 0, *PADDR2;
-static int PMAP1_inuse = 0, PMAP2_inuse = 0;
 #ifdef SMP
 static int PMAP1cpu;
 static int PMAP1changedcpu;
@@ -419,8 +414,9 @@
 	}
 	SYSMAP(caddr_t, CMAP1, CADDR1, 1)
 	SYSMAP(caddr_t, CMAP3, CADDR3, 1)
-	PT_CLEAR_VA(CMAP3, TRUE);
-
+	*CMAP3 = 0;
+	
+	
 	/*
 	 * Crashdump maps.
 	 */
@@ -445,7 +441,7 @@
 	mtx_init(&PMAP2mutex, "PMAP2", NULL, MTX_DEF);
 
 	virtual_avail = va;
-	PT_CLEAR_VA(CMAP1, TRUE);
+	*CMAP1 = 0;
 	
 	/*
 	 * Leave in place an identity mapping (virt == phys) for the low 1 MB
@@ -938,7 +934,7 @@
 		mtx_lock(&PMAP2mutex);
 		newpf = *pde & PG_FRAME;
 		if ((*PMAP2 & PG_FRAME) != newpf) {
-			PT_SET_VA_MA(PMAP2, newpf | PG_V | PG_A | PG_M, TRUE);
+			*PMAP2 = newpf | PG_V | PG_A | PG_M;
 			pmap_invalidate_page(kernel_pmap, (vm_offset_t)PADDR2);
 		}
 		return (PADDR2 + (i386_btop(va) & (NPTEPG - 1)));
@@ -992,8 +988,8 @@
 		mtx_assert(&vm_page_queue_mtx, MA_OWNED);
 		KASSERT(curthread->td_pinned > 0, ("curthread not pinned"));
 		newpf = *pde & PG_FRAME;
-		if ((PT_GET(PMAP1) & PG_FRAME) != newpf) {
-			PT_SET_VA_MA(PMAP1, newpf | PG_V | PG_A, TRUE);
+		if ((*PMAP1 & PG_FRAME) != newpf) {
+			*PMAP1 = newpf | PG_V | PG_A;
 #ifdef SMP
 			PMAP1cpu = PCPU_GET(cpuid);
 #endif
@@ -1038,10 +1034,9 @@
 		pte = pmap_pte(pmap, va);
 		rtval = (PT_GET(pte) & PG_FRAME) | (va & PAGE_MASK);
 		pmap_pte_release(pte);
-		if (PMAP2_inuse) {
-			PT_CLEAR_VA(PMAP2, TRUE);
-			PMAP2_inuse = 0;
-		}
+
+		if (*PMAP2)
+			*PMAP2 = 0;
 	}
 	PMAP_UNLOCK(pmap);
 	return (rtval);
@@ -1072,10 +1067,8 @@
 		rtval = (*pte & PG_FRAME) | (va & PAGE_MASK);
 		pmap_pte_release(pte);
 #ifdef XEN
-		if (PMAP2_inuse) {
-			PT_CLEAR_VA(PMAP2, TRUE);
-			PMAP2_inuse = 0;
-		}
+		if (*PMAP2)
+			*PMAP2 = 0;
 #endif
 	}
 	PMAP_UNLOCK(pmap);
@@ -1110,10 +1103,8 @@
 		} else {
 			sched_pin();
 			pte = PT_GET(pmap_pte_quick(pmap, va));
-			if (PMAP1_inuse) {
-				PT_CLEAR_VA(PMAP1, TRUE);
-				PMAP1_inuse = 0;
-			}
+			if (*PMAP1)
+				*PMAP1 = 0;
 			if (pte != 0 &&
 			    ((pte & PG_RW) || (prot & VM_PROT_WRITE) == 0)) {
 				m = PHYS_TO_VM_PAGE(pte & PG_FRAME);
@@ -1150,7 +1141,7 @@
 	pt_entry_t *pte;
 
 	pte = vtopte(va);
-	PT_SET_VA_MA(pte, ma | PG_RW | PG_V | pgeflag, TRUE);
+	pte_store_ma(pte, ma | PG_RW | PG_V | pgeflag);
 }
 
 
@@ -1459,7 +1450,7 @@
 	for (i = KPTDI; i < KPTDI + nkpt; i++)
 		pmap->pm_pdir_shadow[i] = PTD[i] & ~(PG_RW|PG_M|PG_A);
 	for (i = 0; i < NPGPTD; i++) {
-		vm_paddr_t *pd;
+		pt_entry_t *pd;
 
 		pd = pmap->pm_pdir + (i * NPDEPG);
 		PT_SET_MA(pd, *vtopte((vm_offset_t)pd) & ~(PG_M|PG_A|PG_U|PG_RW));
@@ -2102,11 +2093,12 @@
 pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t m)
 {
 	pv_entry_t pv;
-
 	PMAP_LOCK_ASSERT(pmap, MA_OWNED);
 	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+
 	pv = get_pv_entry(pmap, FALSE);
 	pv->pv_va = va;
+
 	TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
 }
 
@@ -2151,7 +2143,7 @@
 		pmap_invalidate_page(kernel_pmap, va);
 	pmap->pm_stats.resident_count -= 1;
 	if (oldpte & PG_MANAGED) {
-		m = PHYS_TO_VM_PAGE(oldpte & PG_FRAME);
+		m = PHYS_TO_VM_PAGE(xpmap_mtop(oldpte) & PG_FRAME);
 		if (oldpte & PG_M) {
 			KASSERT((oldpte & PG_RW),
 	("pmap_remove_pte: modified page not writable: va: %#x, pte: %#jx",
@@ -2180,10 +2172,9 @@
 		return;
 	pmap_remove_pte(pmap, pte, va, free);
 	pmap_invalidate_page(pmap, va);
-	if (PMAP1_inuse) {
-		PT_CLEAR_VA(PMAP1, TRUE);
-		PMAP1_inuse = 0;
-	}
+	if (*PMAP1)
+		*PMAP1 = 0;
+
 }
 
 /*
@@ -2277,10 +2268,8 @@
 				break;
 		}
 	}
-	if (PMAP1_inuse) {
-		PT_CLEAR_VA(PMAP1, TRUE);
-		PMAP1_inuse = 0;
-	}
+	if (*PMAP1)
+		*PMAP1 = 0;
 out:
 	sched_unpin();
 	if (anyvalid)
@@ -2351,10 +2340,8 @@
 		PMAP_UNLOCK(pmap);
 	}
 	vm_page_flag_clear(m, PG_WRITEABLE);
-	if (PMAP1_inuse) {
-		PT_CLEAR_VA(PMAP1, TRUE);
-		PMAP1_inuse = 0;
-	}
+	if (*PMAP1)
+		*PMAP1 = 0;
 	sched_unpin();
 }
 
@@ -2426,27 +2413,25 @@
 		    sva += PAGE_SIZE) {
 			vm_page_t m;
 
-#ifndef XEN
 retry:
-#endif			
 			/*
 			 * Regardless of whether a pte is 32 or 64 bits in
 			 * size, PG_RW, PG_A, and PG_M are among the least
 			 * significant 32 bits.
 			 */
-			obits = pbits = PT_GET(pte);
+			obits = pbits = *pte;
 			if ((pbits & PG_V) == 0)
 				continue;
 			if (pbits & PG_MANAGED) {
 				m = NULL;
 				if (pbits & PG_A) {
-					m = PHYS_TO_VM_PAGE(pbits & PG_FRAME);
+					m = PHYS_TO_VM_PAGE(xpmap_mtop(pbits) & PG_FRAME);
 					vm_page_flag_set(m, PG_REFERENCED);
 					pbits &= ~PG_A;
 				}
 				if ((pbits & PG_M) != 0) {
 					if (m == NULL)
-						m = PHYS_TO_VM_PAGE(pbits & PG_FRAME);
+						m = PHYS_TO_VM_PAGE(xpmap_mtop(pbits) & PG_FRAME);
 					vm_page_dirty(m);
 				}
 			}
@@ -2459,7 +2444,6 @@
 #endif
 
 			if (pbits != obits) {
-#ifndef XEN				
 #ifdef PAE
 				if (!atomic_cmpset_64(pte, obits, pbits))
 					goto retry;
@@ -2468,9 +2452,6 @@
 				    pbits))
 					goto retry;
 #endif
-#else
-				PT_SET_VA(pte, pbits, FALSE);
-#endif				
 				if (obits & PG_G)
 					pmap_invalidate_page(pmap, sva);
 				else
@@ -2478,10 +2459,8 @@
 			}
 		}
 	}
-	if (PMAP1_inuse) {
-		PT_CLEAR_VA(PMAP1, TRUE);
-		PMAP1_inuse = 0;
-	}	
+	if (*PMAP1)
+		*PMAP1 = 0;
 	sched_unpin();
 	if (anychanged)
 		pmap_invalidate_all(pmap);
@@ -2685,10 +2664,8 @@
 		} else
 			pte_store(pte, newpte | PG_A);
 	}
-	if (PMAP1_inuse) {
-		PT_CLEAR_VA(PMAP1, TRUE);
-		PMAP1_inuse = 0;
-	}	
+	if (*PMAP1)
+		*PMAP1 = 0;
 	sched_unpin();
 	vm_page_unlock_queues();
 	PMAP_UNLOCK(pmap);
@@ -2964,10 +2941,8 @@
 	 */
 	pmap_pte_set_w(pte, wired);
 	pmap_pte_release(pte);
-	if (PMAP2_inuse) {
-		PT_CLEAR_VA(PMAP2, TRUE);
-		PMAP2_inuse = 0;
-	}
+	if (*PMAP2)
+		*PMAP2 = 0;
 	PMAP_UNLOCK(pmap);
 }
 
@@ -3040,7 +3015,7 @@
 		src_pte = vtopte(addr);
 		while (addr < pdnxt) {
 			pt_entry_t ptetemp;
-			ptetemp = PT_GET(src_pte);
+			ptetemp = *src_pte;
 			/*
 			 * we only virtual copy managed pages
 			 */
@@ -3052,13 +3027,13 @@
 				dst_pte = pmap_pte_quick(dst_pmap, addr);
 				if (*dst_pte == 0 &&
 				    pmap_try_insert_pv_entry(dst_pmap, addr,
-				    PHYS_TO_VM_PAGE(ptetemp & PG_FRAME))) {
+					PHYS_TO_VM_PAGE(xpmap_mtop(ptetemp) & PG_FRAME))) {
 					/*
 					 * Clear the wired, modified, and
 					 * accessed (referenced) bits
 					 * during the copy.
 					 */
-					PT_SET_VA(dst_pte, ptetemp & ~(PG_W | PG_M | PG_A), FALSE);	
+					*dst_pte = ptetemp & ~(PG_W | PG_M | PG_A);	
 
 					dst_pmap->pm_stats.resident_count++;
 	 			} else {
@@ -3077,10 +3052,8 @@
 			src_pte++;
 		}
 	}
-	if (PMAP1_inuse) {
-		PT_CLEAR_VA(PMAP1, FALSE);
-		PMAP1_inuse = 0;
-	}
+	if (*PMAP1)
+		*PMAP1 = 0;
 	sched_unpin();
 	vm_page_unlock_queues();
 	PT_UPDATES_FLUSH();
@@ -3118,17 +3091,13 @@
 	if (*sysmaps->CMAP2)
 		panic("pmap_zero_page: CMAP2 busy");
 	sched_pin();
-#ifdef XEN
-	PT_SET_VA(sysmaps->CMAP2, PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M, TRUE);
-#else	
-	*sysmaps->CMAP2 = PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M;
-#endif
+	*sysmaps->CMAP2 = PG_V | PG_RW | xpmap_ptom(VM_PAGE_TO_PHYS(m)) | PG_A | PG_M;
 	KASSERT(*sysmaps->CMAP2 == (PG_V | PG_RW | xpmap_ptom(VM_PAGE_TO_PHYS(m)) | PG_A | PG_M),
 	    ("CMAP2 did not get set is %llx", *sysmaps->CMAP2));
 	
 	invlcaddr(sysmaps->CADDR2);
 	pagezero(sysmaps->CADDR2);
-	PT_CLEAR_VA(sysmaps->CMAP2, TRUE);
+	*sysmaps->CMAP2 = 0;
 	sched_unpin();
 	mtx_unlock(&sysmaps->lock);
 }
@@ -3149,7 +3118,7 @@
 	if (*sysmaps->CMAP2)
 		panic("pmap_zero_page: CMAP2 busy");
 	sched_pin();
-	PT_SET_VA(sysmaps->CMAP2, PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M, TRUE); 
+	*sysmaps->CMAP2 = PG_V | PG_RW | xpmap_ptom(VM_PAGE_TO_PHYS(m)) | PG_A | PG_M;
 
 	invlcaddr(sysmaps->CADDR2);
 	if (off == 0 && size == PAGE_SIZE) 
@@ -3157,7 +3126,7 @@
 	else
 		bzero((char *)sysmaps->CADDR2 + off, size);
 
-	PT_CLEAR_VA(sysmaps->CMAP2, TRUE);
+	*sysmaps->CMAP2 = 0;
 	sched_unpin();
 	mtx_unlock(&sysmaps->lock);
 }
@@ -3175,10 +3144,9 @@
 	if (*CMAP3)
 		panic("pmap_zero_page: CMAP3 busy");
 	sched_pin();
-	PT_SET_VA(CMAP3, PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M, TRUE);
+	*CMAP3 =  PG_V | PG_RW | xpmap_ptom(VM_PAGE_TO_PHYS(m)) | PG_A | PG_M;
 	invlcaddr(CADDR3);
 	pagezero(CADDR3);
-	PT_CLEAR_VA(CMAP3, TRUE);
 	sched_unpin();
 }
 
@@ -3202,15 +3170,16 @@
 	sched_pin();
 	invlpg((u_int)sysmaps->CADDR1);
 	invlpg((u_int)sysmaps->CADDR2);
-	PT_SET_VA(sysmaps->CMAP1, PG_V | VM_PAGE_TO_PHYS(src) | PG_A, TRUE);
-	PT_SET_VA(sysmaps->CMAP2, PG_V | PG_RW | VM_PAGE_TO_PHYS(dst) | PG_A | PG_M, TRUE);
+	*sysmaps->CMAP1 =  PG_V | xpmap_ptom(VM_PAGE_TO_PHYS(src)) | PG_A;
+	*sysmaps->CMAP2 = PG_V | PG_RW | xpmap_ptom(VM_PAGE_TO_PHYS(dst)) | PG_A | PG_M;
+
 	KASSERT(*sysmaps->CMAP1 == (PG_V | xpmap_ptom(VM_PAGE_TO_PHYS(src)) | PG_A ),
 	    ("CMAP1 did not get set is %llx", *sysmaps->CMAP1));
 	KASSERT(*sysmaps->CMAP2 == (PG_V | PG_RW | xpmap_ptom(VM_PAGE_TO_PHYS(dst)) | PG_A | PG_M),
 	    ("CMAP2 did not get set is %llx", *sysmaps->CMAP2));	
 	bcopy(sysmaps->CADDR1, sysmaps->CADDR2, PAGE_SIZE);
-	PT_CLEAR_VA(sysmaps->CMAP1, FALSE);
-	PT_CLEAR_VA(sysmaps->CMAP2, TRUE);
+	*sysmaps->CMAP1 = 0;
+	*sysmaps->CMAP2 = 0;
 	if (*sysmaps->CMAP1)
 		panic("pmap_copy_page: CMAP1 busy, CMAP1=%llx", *sysmaps->CMAP1);
 	if (*sysmaps->CMAP2)
@@ -3318,7 +3287,12 @@
 
 				if (pmap->pm_pdir_shadow[pv->pv_va >> PDRSHIFT] == 0) {
 					printf("PDIR IS ZERO @ VA %08x\n", pv->pv_va);
-					panic("bad pte");					
+					/* workaround insufficient wired count
+					 * on page directory - this only buys
+					 * us a little bit of time as the list
+					 * on one of the pages is now corrupt
+					 */
+					goto skip;
 				}
 
 				pte = vtopte(pv->pv_va);
@@ -3348,7 +3322,6 @@
 					("pmap_remove_pages: bad tpte %#jx",
 					(uintmax_t)tpte));
 
-				pmap->pm_stats.resident_count--;
 
 				pte_clear(pte);
 
@@ -3358,16 +3331,19 @@
 				if (tpte & PG_M)
 					vm_page_dirty(m);
 
+				TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
+				if (TAILQ_EMPTY(&m->md.pv_list))
+					vm_page_flag_clear(m, PG_WRITEABLE);
+
+				pmap_unuse_pt(pmap, pv->pv_va, &free);
+			skip:
+
 				/* Mark free */
 				PV_STAT(pv_entry_frees++);
 				PV_STAT(pv_entry_spare++);
 				pv_entry_count--;
 				pc->pc_map[field] |= bitmask;
-				TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
-				if (TAILQ_EMPTY(&m->md.pv_list))
-					vm_page_flag_clear(m, PG_WRITEABLE);
-
-				pmap_unuse_pt(pmap, pv->pv_va, &free);
+				pmap->pm_stats.resident_count--;			
 			}
 		}
 		if (allfree) {
@@ -3382,10 +3358,8 @@
 			pmap_ptelist_free(&pv_vafree, (vm_offset_t)pc);
 		}
 	}
-	if (PMAP1_inuse) {
-		PT_CLEAR_VA(PMAP1, TRUE);
-		PMAP1_inuse = 0;
-	}
+	if (*PMAP1) 
+		*PMAP1 = 0;
 	sched_unpin();
 	pmap_invalidate_all(pmap);
 	vm_page_unlock_queues();
@@ -3422,10 +3396,8 @@
 		if (rv)
 			break;
 	}
-	if (PMAP1_inuse) {
-		PT_CLEAR_VA(PMAP1, TRUE);
-		PMAP1_inuse = 0;
-	}
+	if (*PMAP1)
+		*PMAP1 = 0;
 	sched_unpin();
 	return (rv);
 }
@@ -3472,10 +3444,8 @@
 		pmap_pte_release(pte);
 	}
 	PT_UPDATES_FLUSH();
-	if (PMAP2_inuse) {
-		PT_CLEAR_VA(PMAP2, TRUE);
-		PMAP2_inuse = 0;
-	}
+	if (*PMAP2)
+		*PMAP2 = 0;
 }
 
 void
@@ -3490,10 +3460,8 @@
 		pmap_pte_release(pte);
 	}
 	PT_UPDATES_FLUSH();
-	if (PMAP2_inuse) {
-		PT_CLEAR_VA(PMAP2, TRUE);
-		PMAP2_inuse = 0;
-	}
+	if (*PMAP2)
+		*PMAP2 = 0;
 }
 
 /*
@@ -3515,23 +3483,17 @@
 		pmap = PV_PMAP(pv);
 		PMAP_LOCK(pmap);
 		pte = pmap_pte_quick(pmap, pv->pv_va);
-#ifndef XEN
 retry:
-#endif		
-		oldpte = PT_GET(pte);
+		oldpte = *pte;
 		if ((oldpte & PG_RW) != 0) {
 			/*
 			 * Regardless of whether a pte is 32 or 64 bits
 			 * in size, PG_RW and PG_M are among the least
 			 * significant 32 bits.
 			 */
-#ifndef XEN			
 			if (!atomic_cmpset_int((u_int *)pte, oldpte,
 			    oldpte & ~(PG_RW | PG_M)))
 				goto retry;
-#else
-			PT_SET_VA(pte, oldpte & ~(PG_RW|PG_M), TRUE);
-#endif
 			if ((oldpte & PG_M) != 0)
 				vm_page_dirty(m);
 			pmap_invalidate_page(pmap, pv->pv_va);
@@ -3539,10 +3501,8 @@
 		PMAP_UNLOCK(pmap);
 	}
 	vm_page_flag_clear(m, PG_WRITEABLE);
-	if (PMAP1_inuse) {
-		PT_CLEAR_VA(PMAP1, TRUE);
-		PMAP1_inuse = 0;
-	}
+	if (*PMAP1)
+		*PMAP1 = 0;
 	sched_unpin();
 }
 
@@ -3581,13 +3541,8 @@
 			pmap = PV_PMAP(pv);
 			PMAP_LOCK(pmap);
 			pte = pmap_pte_quick(pmap, pv->pv_va);
-			if (pte && ((v = PT_GET(pte)) & PG_A) != 0) {
-#ifndef XEN				
+			if (pte && ((v = *pte) & PG_A) != 0) {
 				atomic_clear_int((u_int *)pte, PG_A);
-#else
-				PT_SET_VA(pte, v & ~PG_A, TRUE);
-#endif
-				
 				pmap_invalidate_page(pmap, pv->pv_va);
 				rtval++;
 				if (rtval > 4)
@@ -3596,10 +3551,8 @@
 			PMAP_UNLOCK(pmap);
 		} while ((pv = pvn) != NULL && pv != pvf);
 	}
-	if (PMAP1_inuse) {
-		PT_CLEAR_VA(PMAP1, TRUE);
-		PMAP1_inuse = 0;
-	}
+	if (*PMAP1)
+		*PMAP1 = 0;
 	sched_unpin();
 	return (rtval);
 }
@@ -3631,11 +3584,7 @@
 			 * in size, PG_M is among the least significant
 			 * 32 bits. 
 			 */
-#ifndef XEN			
 			atomic_clear_int((u_int *)pte, PG_M);
-#else
-			PT_SET_MA(pv->pv_va, val & ~PG_M);
-#endif			
 			pmap_invalidate_page(pmap, pv->pv_va);
 		}
 		PMAP_UNLOCK(pmap);
@@ -3671,11 +3620,7 @@
 			 * in size, PG_A is among the least significant
 			 * 32 bits. 
 			 */
-#ifndef XEN			
 			atomic_clear_int((u_int *)pte, PG_A);
-#else			
-			PT_SET_MA(pv->pv_va, val & ~PG_A);
-#endif			
 			pmap_invalidate_page(pmap, pv->pv_va);
 		}
 		PMAP_UNLOCK(pmap);
@@ -3797,19 +3742,12 @@
 		 * The cache mode bits are all in the low 32-bits of the
 		 * PTE, so we can just spin on updating the low 32-bits.
 		 */
-#ifndef XEN		
 		do {
 			opte = *(u_int *)pte;
 			npte = opte & ~(PG_PTE_PAT | PG_NC_PCD | PG_NC_PWT);
 			npte |= pmap_cache_bits(mode, 0);
 		} while (npte != opte &&
 		    !atomic_cmpset_int((u_int *)pte, opte, npte));
-#else
-		opte = *pte;
-		npte = opte & ~(PG_PTE_PAT | PG_NC_PCD | PG_NC_PWT);
-		npte |= pmap_cache_bits(mode, 0);
-		PT_SET_MA(tmpva, npte);
-#endif
 		tmpva += PAGE_SIZE;
 		size -= PAGE_SIZE;
 	}
@@ -3841,10 +3779,8 @@
 	pte = (ptep != NULL) ? PT_GET(ptep) : 0;
 	pmap_pte_release(ptep);
 	PMAP_UNLOCK(pmap);
-	if (PMAP2_inuse) {
-		PT_CLEAR_VA(PMAP2, TRUE);
-		PMAP2_inuse = 0;
-	}	
+	if (*PMAP2)
+		*PMAP2 = 0;
 	if (pte != 0) {
 		vm_paddr_t pa;
 

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

@@ -259,7 +259,7 @@
 xen_invlpg(vm_offset_t va)
 {
 	struct mmuext_op op;
-	op.cmd = MMUEXT_INVLPG_LOCAL;
+	op.cmd = MMUEXT_INVLPG_ALL;
 	op.arg1.linear_addr = va & ~PAGE_MASK;
 	xen_flush_queue();
 	PANIC_IF(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
@@ -708,10 +708,9 @@
 #endif
 	unsigned long i;
 
-#ifdef WRITABLE_PAGETABLES
-	printk("using writable pagetables\n");
+
 	HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables);
-#endif
+
 	xen_start_info = startinfo;
 	xen_phys_machine = (xen_pfn_t *)startinfo->mfn_list;
 



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