Date: Sat, 13 Oct 2012 22:22:54 +0000 (UTC) From: Alan Cox <alc@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r241518 - in stable/9/sys/i386: i386 xen Message-ID: <201210132222.q9DMMsql020624@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: alc Date: Sat Oct 13 22:22:53 2012 New Revision: 241518 URL: http://svn.freebsd.org/changeset/base/241518 Log: MFC r241353, r241356, r241400 To avoid page table page corruption, change pmap_pv_reclaim()'s method of mapping page table pages. Add some assertions that were helpful in debugging the page table page corruption. Modified: stable/9/sys/i386/i386/pmap.c stable/9/sys/i386/xen/pmap.c Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/i386/i386/pmap.c ============================================================================== --- stable/9/sys/i386/i386/pmap.c Sat Oct 13 20:19:43 2012 (r241517) +++ stable/9/sys/i386/i386/pmap.c Sat Oct 13 22:22:53 2012 (r241518) @@ -482,7 +482,8 @@ pmap_bootstrap(vm_paddr_t firstaddr) KPTmap -= i386_btop(KPTDI << PDRSHIFT); /* - * ptemap is used for pmap_pte_quick + * PADDR1 and PADDR2 are used by pmap_pte_quick() and pmap_pte(), + * respectively. */ SYSMAP(pt_entry_t *, PMAP1, PADDR1, 1) SYSMAP(pt_entry_t *, PMAP2, PADDR2, 1) @@ -2235,7 +2236,6 @@ pmap_pv_reclaim(pmap_t locked_pmap) pmap = NULL; free = m_pc = NULL; TAILQ_INIT(&newtail); - sched_pin(); while ((pc = TAILQ_FIRST(&pv_chunks)) != NULL && (pv_vafree == 0 || free == NULL)) { TAILQ_REMOVE(&pv_chunks, pc, pc_lru); @@ -2269,10 +2269,16 @@ pmap_pv_reclaim(pmap_t locked_pmap) pde = pmap_pde(pmap, va); if ((*pde & PG_PS) != 0) continue; - pte = pmap_pte_quick(pmap, va); - if ((*pte & PG_W) != 0) + pte = pmap_pte(pmap, va); + tpte = *pte; + if ((tpte & PG_W) == 0) + tpte = pte_load_clear(pte); + pmap_pte_release(pte); + if ((tpte & PG_W) != 0) continue; - tpte = pte_load_clear(pte); + KASSERT(tpte != 0, + ("pmap_pv_reclaim: pmap %p va %x zero pte", + pmap, va)); if ((tpte & PG_G) != 0) pmap_invalidate_page(pmap, va); m = PHYS_TO_VM_PAGE(tpte & PG_FRAME); @@ -2330,7 +2336,6 @@ pmap_pv_reclaim(pmap_t locked_pmap) } } out: - sched_unpin(); TAILQ_CONCAT(&pv_chunks, &newtail, pc_lru); if (pmap != NULL) { pmap_invalidate_all(pmap); @@ -2870,6 +2875,8 @@ pmap_remove_pte(pmap_t pmap, pt_entry_t rw_assert(&pvh_global_lock, RA_WLOCKED); PMAP_LOCK_ASSERT(pmap, MA_OWNED); oldpte = pte_load_clear(ptq); + KASSERT(oldpte != 0, + ("pmap_remove_pte: pmap %p va %x zero pte", pmap, va)); if (oldpte & PG_W) pmap->pm_stats.wired_count -= 1; /* @@ -3074,6 +3081,8 @@ small_mappings: " a 4mpage in page %p's pv list", m)); pte = pmap_pte_quick(pmap, pv->pv_va); tpte = pte_load_clear(pte); + KASSERT(tpte != 0, ("pmap_remove_all: pmap %p va %x zero pte", + pmap, pv->pv_va)); if (tpte & PG_W) pmap->pm_stats.wired_count--; if (tpte & PG_A) @@ -4373,6 +4382,8 @@ pmap_remove_pages(pmap_t pmap) PMAP_LOCK(pmap); sched_pin(); TAILQ_FOREACH_SAFE(pc, &pmap->pm_pvchunk, pc_list, npc) { + KASSERT(pc->pc_pmap == pmap, ("Wrong pmap %p %p", pmap, + pc->pc_pmap)); allfree = 1; for (field = 0; field < _NPCM; field++) { inuse = ~pc->pc_map[field] & pc_freemask[field]; Modified: stable/9/sys/i386/xen/pmap.c ============================================================================== --- stable/9/sys/i386/xen/pmap.c Sat Oct 13 20:19:43 2012 (r241517) +++ stable/9/sys/i386/xen/pmap.c Sat Oct 13 22:22:53 2012 (r241518) @@ -437,7 +437,8 @@ pmap_bootstrap(vm_paddr_t firstaddr) SYSMAP(struct msgbuf *, unused, msgbufp, atop(round_page(msgbufsize))) /* - * ptemap is used for pmap_pte_quick + * PADDR1 and PADDR2 are used by pmap_pte_quick() and pmap_pte(), + * respectively. */ SYSMAP(pt_entry_t *, PMAP1, PADDR1, 1) SYSMAP(pt_entry_t *, PMAP2, PADDR2, 1) @@ -1986,7 +1987,6 @@ pmap_pv_reclaim(pmap_t locked_pmap) pmap = NULL; free = m_pc = NULL; TAILQ_INIT(&newtail); - sched_pin(); while ((pc = TAILQ_FIRST(&pv_chunks)) != NULL && (pv_vafree == 0 || free == NULL)) { TAILQ_REMOVE(&pv_chunks, pc, pc_lru); @@ -2017,10 +2017,16 @@ pmap_pv_reclaim(pmap_t locked_pmap) bit = bsfl(inuse); pv = &pc->pc_pventry[field * 32 + bit]; va = pv->pv_va; - pte = pmap_pte_quick(pmap, va); - if ((*pte & PG_W) != 0) + pte = pmap_pte(pmap, va); + tpte = *pte; + if ((tpte & PG_W) == 0) + tpte = pte_load_clear(pte); + pmap_pte_release(pte); + if ((tpte & PG_W) != 0) continue; - tpte = pte_load_clear(pte); + KASSERT(tpte != 0, + ("pmap_pv_reclaim: pmap %p va %x zero pte", + pmap, va)); if ((tpte & PG_G) != 0) pmap_invalidate_page(pmap, va); m = PHYS_TO_VM_PAGE(tpte & PG_FRAME); @@ -2072,7 +2078,6 @@ pmap_pv_reclaim(pmap_t locked_pmap) } } out: - sched_unpin(); TAILQ_CONCAT(&pv_chunks, &newtail, pc_lru); if (pmap != NULL) { pmap_invalidate_all(pmap); @@ -2294,6 +2299,8 @@ pmap_remove_pte(pmap_t pmap, pt_entry_t PMAP_LOCK_ASSERT(pmap, MA_OWNED); oldpte = *ptq; PT_SET_VA_MA(ptq, 0, TRUE); + KASSERT(oldpte != 0, + ("pmap_remove_pte: pmap %p va %x zero pte", pmap, va)); if (oldpte & PG_W) pmap->pm_stats.wired_count -= 1; /* @@ -2478,6 +2485,8 @@ pmap_remove_all(vm_page_t m) pte = pmap_pte_quick(pmap, pv->pv_va); tpte = *pte; PT_SET_VA_MA(pte, 0, TRUE); + KASSERT(tpte != 0, ("pmap_remove_all: pmap %p va %x zero pte", + pmap, pv->pv_va)); if (tpte & PG_W) pmap->pm_stats.wired_count--; if (tpte & PG_A) @@ -3541,6 +3550,8 @@ pmap_remove_pages(pmap_t pmap) PMAP_LOCK(pmap); sched_pin(); TAILQ_FOREACH_SAFE(pc, &pmap->pm_pvchunk, pc_list, npc) { + KASSERT(pc->pc_pmap == pmap, ("Wrong pmap %p %p", pmap, + pc->pc_pmap)); allfree = 1; for (field = 0; field < _NPCM; field++) { inuse = ~pc->pc_map[field] & pc_freemask[field];
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201210132222.q9DMMsql020624>