Date: Fri, 20 Feb 2015 06:13:52 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r279044 - user/nwhitehorn/ppc64-pmap-rework/aim Message-ID: <201502200613.t1K6DqRb062223@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: nwhitehorn Date: Fri Feb 20 06:13:52 2015 New Revision: 279044 URL: https://svnweb.freebsd.org/changeset/base/279044 Log: Fix bug where pmap_qenter() could introduce double mappings in the page table, resulting in either machine checks (best case, since they are loud) or the CPU using physical memory from either the old or new mapping at random (worst case). Modified: user/nwhitehorn/ppc64-pmap-rework/aim/mmu_oea64.c Modified: user/nwhitehorn/ppc64-pmap-rework/aim/mmu_oea64.c ============================================================================== --- user/nwhitehorn/ppc64-pmap-rework/aim/mmu_oea64.c Fri Feb 20 05:40:39 2015 (r279043) +++ user/nwhitehorn/ppc64-pmap-rework/aim/mmu_oea64.c Fri Feb 20 06:13:52 2015 (r279044) @@ -1684,7 +1684,7 @@ void moea64_kenter_attr(mmu_t mmu, vm_offset_t va, vm_offset_t pa, vm_memattr_t ma) { int error; - struct pvo_entry *pvo; + struct pvo_entry *pvo, *oldpvo; pvo = alloc_pvo_entry(0); pvo->pvo_pte.prot = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE; @@ -1692,10 +1692,21 @@ moea64_kenter_attr(mmu_t mmu, vm_offset_ pvo->pvo_vaddr |= PVO_WIRED; PMAP_LOCK(kernel_pmap); + oldpvo = moea64_pvo_find_va(kernel_pmap, va); + if (oldpvo != NULL) + moea64_pvo_remove_from_pmap(mmu, oldpvo); init_pvo_entry(pvo, kernel_pmap, va); error = moea64_pvo_enter(mmu, pvo, NULL); PMAP_UNLOCK(kernel_pmap); + /* Free any dead pages */ + if (oldpvo != NULL) { + PV_LOCK(oldpvo->pvo_pte.pa & LPTE_RPGN); + moea64_pvo_remove_from_page(mmu, oldpvo); + PV_UNLOCK(oldpvo->pvo_pte.pa & LPTE_RPGN); + free_pvo_entry(oldpvo); + } + if (error != 0 && error != ENOENT) panic("moea64_kenter: failed to enter va %#zx pa %#zx: %d", va, pa, error); @@ -2237,6 +2248,8 @@ moea64_pvo_enter(mmu_t mmu, struct pvo_e int first, err; PMAP_LOCK_ASSERT(pvo->pvo_pmap, MA_OWNED); + KASSERT(moea64_pvo_find_va(pvo->pvo_pmap, PVO_VADDR(pvo)) == NULL, + ("Existing mapping for VA %#zx", PVO_VADDR(pvo))); moea64_pvo_enter_calls++;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201502200613.t1K6DqRb062223>