svn commit: r279044 - user/nwhitehorn/ppc64-pmap-rework/aim

Nathan Whitehorn nwhitehorn at FreeBSD.org
Fri Feb 20 06:13:53 UTC 2015


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++;
 


More information about the svn-src-user mailing list