svn commit: r308029 - head/sys/i386/i386

Konstantin Belousov kib at FreeBSD.org
Fri Oct 28 11:53:23 UTC 2016


Author: kib
Date: Fri Oct 28 11:53:22 2016
New Revision: 308029
URL: https://svnweb.freebsd.org/changeset/base/308029

Log:
  Handle pmap_enter() over an existing 4/2M page in KVA on i386.
  
  The userspace case was already handled by pmap_allocpte().  For kernel
  VA, page table page must exist, and demote cannot fail, so we need to
  just call pmap_demote_pde().  Also note that due to the machine AS
  layout, promotions in the KVA on i386 are highly unlikely, so this
  change is mostly for completeness.
  
  Reviewed by:	alc, markj
  Tested by:	pho
  Sponsored by:	The FreeBSD Foundation
  MFC after:	2 weeks
  Differential revision:	https://reviews.freebsd.org/D8323

Modified:
  head/sys/i386/i386/pmap.c

Modified: head/sys/i386/i386/pmap.c
==============================================================================
--- head/sys/i386/i386/pmap.c	Fri Oct 28 11:46:39 2016	(r308028)
+++ head/sys/i386/i386/pmap.c	Fri Oct 28 11:53:22 2016	(r308029)
@@ -3466,11 +3466,14 @@ pmap_enter(pmap_t pmap, vm_offset_t va, 
 	PMAP_LOCK(pmap);
 	sched_pin();
 
-	/*
-	 * In the case that a page table page is not
-	 * resident, we are creating it here.
-	 */
+	pde = pmap_pde(pmap, va);
 	if (va < VM_MAXUSER_ADDRESS) {
+		/*
+		 * va is for UVA.
+		 * In the case that a page table page is not resident,
+		 * we are creating it here.  pmap_allocpte() handles
+		 * demotion.
+		 */
 		mpte = pmap_allocpte(pmap, va, flags);
 		if (mpte == NULL) {
 			KASSERT((flags & PMAP_ENTER_NOSLEEP) != 0,
@@ -3480,19 +3483,28 @@ pmap_enter(pmap_t pmap, vm_offset_t va, 
 			PMAP_UNLOCK(pmap);
 			return (KERN_RESOURCE_SHORTAGE);
 		}
+	} else {
+		/*
+		 * va is for KVA, so pmap_demote_pde() will never fail
+		 * to install a page table page.  PG_V is also
+		 * asserted by pmap_demote_pde().
+		 */
+		KASSERT(pde != NULL && (*pde & PG_V) != 0,
+		    ("KVA %#x invalid pde pdir %#jx", va,
+		    (uintmax_t)pmap->pm_pdir[PTDPTDI]));
+		if ((*pde & PG_PS) != 0)
+			pmap_demote_pde(pmap, pde, va);
 	}
-
-	pde = pmap_pde(pmap, va);
-	if ((*pde & PG_PS) != 0)
-		panic("pmap_enter: attempted pmap_enter on 4MB page");
 	pte = pmap_pte_quick(pmap, va);
 
 	/*
-	 * Page Directory table entry not valid, we need a new PT page
+	 * Page Directory table entry is not valid, which should not
+	 * happen.  We should have either allocated the page table
+	 * page or demoted the existing mapping above.
 	 */
 	if (pte == NULL) {
 		panic("pmap_enter: invalid page directory pdir=%#jx, va=%#x",
-			(uintmax_t)pmap->pm_pdir[PTDPTDI], va);
+		    (uintmax_t)pmap->pm_pdir[PTDPTDI], va);
 	}
 
 	pa = VM_PAGE_TO_PHYS(m);


More information about the svn-src-all mailing list