From owner-svn-src-all@FreeBSD.ORG Fri Jan 22 21:23:09 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7DFE11065693; Fri, 22 Jan 2010 21:23:09 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 6BF4E8FC22; Fri, 22 Jan 2010 21:23:09 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o0MLN9u0089386; Fri, 22 Jan 2010 21:23:09 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0MLN9VW089383; Fri, 22 Jan 2010 21:23:09 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201001222123.o0MLN9VW089383@svn.freebsd.org> From: John Baldwin Date: Fri, 22 Jan 2010 21:23:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202837 - in stable/7/sys: amd64/amd64 i386/i386 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 22 Jan 2010 21:23:09 -0000 Author: jhb Date: Fri Jan 22 21:23:09 2010 New Revision: 202837 URL: http://svn.freebsd.org/changeset/base/202837 Log: MFC 189698,192035: Optimize the inner loop of pmap_copy(). Correct a rare use-after-free error in pmap_copy(). This error was introduced in amd64 revision 1.540 and i386 revision 1.547. However, it had no harmful effects until after a recent change, r189698, on amd64. (In other words, the error is harmless in RELENG_7.) The error is triggered by the failure to allocate a pv entry for the one and only mapping in a page table page. I am addressing the error by changing pmap_copy() to abort if either pv entry allocation or page table page allocation fails. This is appropriate because the creation of mappings by pmap_copy() is optional. They are a (possible) optimization, and not a requirement. Correct a nearby whitespace error in the i386 pmap_copy(). Modified: stable/7/sys/amd64/amd64/pmap.c stable/7/sys/i386/i386/pmap.c Directory Properties: stable/7/sys/ (props changed) stable/7/sys/cddl/contrib/opensolaris/ (props changed) stable/7/sys/contrib/dev/acpica/ (props changed) stable/7/sys/contrib/pf/ (props changed) Modified: stable/7/sys/amd64/amd64/pmap.c ============================================================================== --- stable/7/sys/amd64/amd64/pmap.c Fri Jan 22 20:52:31 2010 (r202836) +++ stable/7/sys/amd64/amd64/pmap.c Fri Jan 22 21:23:09 2010 (r202837) @@ -3555,6 +3555,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pm src_pte = (pt_entry_t *)PHYS_TO_DMAP(srcptepaddr); src_pte = &src_pte[pmap_pte_index(addr)]; + dstmpte = NULL; while (addr < va_next) { pt_entry_t ptetemp; ptetemp = *src_pte; @@ -3562,10 +3563,12 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pm * we only virtual copy managed pages */ if ((ptetemp & PG_MANAGED) != 0) { - dstmpte = pmap_allocpte(dst_pmap, addr, - M_NOWAIT); - if (dstmpte == NULL) - break; + if (dstmpte != NULL && + dstmpte->pindex == pmap_pde_pindex(addr)) + dstmpte->wire_count++; + else if ((dstmpte = pmap_allocpte(dst_pmap, + addr, M_NOWAIT)) == NULL) + goto out; dst_pte = (pt_entry_t *) PHYS_TO_DMAP(VM_PAGE_TO_PHYS(dstmpte)); dst_pte = &dst_pte[pmap_pte_index(addr)]; @@ -3588,6 +3591,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pm addr); pmap_free_zero_pages(free); } + goto out; } if (dstmpte->wire_count >= srcmpte->wire_count) break; @@ -3596,6 +3600,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pm src_pte++; } } +out: vm_page_unlock_queues(); PMAP_UNLOCK(src_pmap); PMAP_UNLOCK(dst_pmap); Modified: stable/7/sys/i386/i386/pmap.c ============================================================================== --- stable/7/sys/i386/i386/pmap.c Fri Jan 22 20:52:31 2010 (r202836) +++ stable/7/sys/i386/i386/pmap.c Fri Jan 22 21:23:09 2010 (r202837) @@ -3673,7 +3673,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pm dstmpte = pmap_allocpte(dst_pmap, addr, M_NOWAIT); if (dstmpte == NULL) - break; + goto out; dst_pte = pmap_pte_quick(dst_pmap, addr); if (*dst_pte == 0 && pmap_try_insert_pv_entry(dst_pmap, addr, @@ -3688,12 +3688,13 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pm dst_pmap->pm_stats.resident_count++; } else { free = NULL; - if (pmap_unwire_pte_hold( dst_pmap, + if (pmap_unwire_pte_hold(dst_pmap, dstmpte, &free)) { pmap_invalidate_page(dst_pmap, addr); pmap_free_zero_pages(free); } + goto out; } if (dstmpte->wire_count >= srcmpte->wire_count) break; @@ -3702,6 +3703,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pm src_pte++; } } +out: sched_unpin(); vm_page_unlock_queues(); PMAP_UNLOCK(src_pmap);