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