Skip site navigation (1)Skip section navigation (2)
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>