svn commit: r340678 - head/sys/arm64/arm64

Mark Johnston markj at FreeBSD.org
Tue Nov 20 15:12:38 UTC 2018


Author: markj
Date: Tue Nov 20 15:12:37 2018
New Revision: 340678
URL: https://svnweb.freebsd.org/changeset/base/340678

Log:
  Handle kernel superpage mappings in pmap_remove_l2().
  
  PR:		233088
  Reviewed by:	alc, andrew, kib
  Tested by:	sbruno
  MFC after:	3 days
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D17981

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

Modified: head/sys/arm64/arm64/pmap.c
==============================================================================
--- head/sys/arm64/arm64/pmap.c	Tue Nov 20 14:59:27 2018	(r340677)
+++ head/sys/arm64/arm64/pmap.c	Tue Nov 20 15:12:37 2018	(r340678)
@@ -2382,8 +2382,40 @@ pmap_pv_insert_l2(pmap_t pmap, vm_offset_t va, pd_entr
 	return (true);
 }
 
+static void
+pmap_remove_kernel_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t va)
+{
+	pt_entry_t newl2, oldl2;
+	vm_page_t ml3;
+	vm_paddr_t ml3pa;
+
+	KASSERT(!VIRT_IN_DMAP(va), ("removing direct mapping of %#lx", va));
+	KASSERT(pmap == kernel_pmap, ("pmap %p is not kernel_pmap", pmap));
+	PMAP_LOCK_ASSERT(pmap, MA_OWNED);
+
+	ml3 = pmap_remove_pt_page(pmap, va);
+	if (ml3 == NULL)
+		panic("pmap_remove_kernel_l2: Missing pt page");
+
+	ml3pa = VM_PAGE_TO_PHYS(ml3);
+	newl2 = ml3pa | L2_TABLE;
+
+	/*
+	 * Initialize the page table page.
+	 */
+	pagezero((void *)PHYS_TO_DMAP(ml3pa));
+
+	/*
+	 * Demote the mapping.  The caller must have already invalidated the
+	 * mapping (i.e., the "break" in break-before-make).
+	 */
+	oldl2 = pmap_load_store(l2, newl2);
+	KASSERT(oldl2 == 0, ("%s: found existing mapping at %p: %#lx",
+	    __func__, l2, oldl2));
+}
+
 /*
- * pmap_remove_l2: do the things to unmap a level 2 superpage in a process
+ * pmap_remove_l2: Do the things to unmap a level 2 superpage.
  */
 static int
 pmap_remove_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t sva,
@@ -2419,16 +2451,18 @@ pmap_remove_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_
 				vm_page_aflag_clear(m, PGA_WRITEABLE);
 		}
 	}
-	KASSERT(pmap != kernel_pmap,
-	    ("Attempting to remove an l2 kernel page"));
-	ml3 = pmap_remove_pt_page(pmap, sva);
-	if (ml3 != NULL) {
-		pmap_resident_count_dec(pmap, 1);
-		KASSERT(ml3->wire_count == NL3PG,
-		    ("pmap_remove_l2: l3 page wire count error"));
-		ml3->wire_count = 1;
-		vm_page_unwire_noq(ml3);
-		pmap_add_delayed_free_list(ml3, free, FALSE);
+	if (pmap == kernel_pmap) {
+		pmap_remove_kernel_l2(pmap, l2, sva);
+	} else {
+		ml3 = pmap_remove_pt_page(pmap, sva);
+		if (ml3 != NULL) {
+			pmap_resident_count_dec(pmap, 1);
+			KASSERT(ml3->wire_count == NL3PG,
+			    ("pmap_remove_l2: l3 page wire count error"));
+			ml3->wire_count = 1;
+			vm_page_unwire_noq(ml3);
+			pmap_add_delayed_free_list(ml3, free, FALSE);
+		}
 	}
 	return (pmap_unuse_pt(pmap, sva, l1e, free));
 }


More information about the svn-src-all mailing list