From owner-p4-projects@FreeBSD.ORG Fri Jan 18 01:29:15 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id E8BB116A46E; Fri, 18 Jan 2008 01:29:14 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9442016A46B for ; Fri, 18 Jan 2008 01:29:14 +0000 (UTC) (envelope-from kmacy@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 72CE713C4DD for ; Fri, 18 Jan 2008 01:29:14 +0000 (UTC) (envelope-from kmacy@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m0I1TDP5096366 for ; Fri, 18 Jan 2008 01:29:13 GMT (envelope-from kmacy@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m0I1TChU096363 for perforce@freebsd.org; Fri, 18 Jan 2008 01:29:12 GMT (envelope-from kmacy@freebsd.org) Date: Fri, 18 Jan 2008 01:29:12 GMT Message-Id: <200801180129.m0I1TChU096363@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to kmacy@freebsd.org using -f From: Kip Macy To: Perforce Change Reviews Cc: Subject: PERFORCE change 133516 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Jan 2008 01:29:15 -0000 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(); } /*