From owner-p4-projects@FreeBSD.ORG Thu Jan 17 04:15:10 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 9A71716A469; Thu, 17 Jan 2008 04:15:10 +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 4362816A418 for ; Thu, 17 Jan 2008 04:15:10 +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 365D113C442 for ; Thu, 17 Jan 2008 04:15:10 +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 m0H4FA2S010899 for ; Thu, 17 Jan 2008 04:15:10 GMT (envelope-from kmacy@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m0H4FAKk010896 for perforce@freebsd.org; Thu, 17 Jan 2008 04:15:10 GMT (envelope-from kmacy@freebsd.org) Date: Thu, 17 Jan 2008 04:15:10 GMT Message-Id: <200801170415.m0H4FAKk010896@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 133450 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: Thu, 17 Jan 2008 04:15:11 -0000 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;