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

Mark Johnston markj at FreeBSD.org
Mon Sep 21 22:19:25 UTC 2020


Author: markj
Date: Mon Sep 21 22:19:21 2020
New Revision: 365976
URL: https://svnweb.freebsd.org/changeset/base/365976

Log:
  Weaken assertions in pmap_l1_to_l2() and pmap_l2_to_l3().
  
  pmap_update_entry() will temporarily clear the valid bit of page table
  entries in order to satisfy the arm64 pmap's break-before-make
  constraint.  pmap_kextract() may operate concurrently on kernel page
  table pages, introducing windows where the assertions added in r365879
  may fail incorrectly since they implicitly assert that the valid bit is
  set.  Modify the assertions to handle this.
  
  Reviewed by:	andrew, mmel (previous version)
  Reviewed by:	alc, kib
  Reported by:	mmel, scottph
  MFC with:	r365879

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

Modified: head/sys/arm64/arm64/pmap.c
==============================================================================
--- head/sys/arm64/arm64/pmap.c	Mon Sep 21 22:19:12 2020	(r365975)
+++ head/sys/arm64/arm64/pmap.c	Mon Sep 21 22:19:21 2020	(r365976)
@@ -438,8 +438,15 @@ pmap_l1_to_l2(pd_entry_t *l1p, vm_offset_t va)
 	pd_entry_t l1, *l2p;
 
 	l1 = pmap_load(l1p);
-	KASSERT((l1 & ATTR_DESCR_MASK) == L1_TABLE,
-	    ("%s: L1 entry %#lx is a leaf", __func__, l1));
+
+	/*
+	 * The valid bit may be clear if pmap_update_entry() is concurrently
+	 * modifying the entry, so for KVA only the entry type may be checked.
+	 */
+	KASSERT(va >= VM_MAX_USER_ADDRESS || (l1 & ATTR_DESCR_VALID) != 0,
+	    ("%s: L1 entry %#lx for %#lx is invalid", __func__, l1, va));
+	KASSERT((l1 & ATTR_DESCR_TYPE_MASK) == ATTR_DESCR_TYPE_TABLE,
+	    ("%s: L1 entry %#lx for %#lx is a leaf", __func__, l1, va));
 	l2p = (pd_entry_t *)PHYS_TO_DMAP(l1 & ~ATTR_MASK);
 	return (&l2p[pmap_l2_index(va)]);
 }
@@ -463,8 +470,15 @@ pmap_l2_to_l3(pd_entry_t *l2p, vm_offset_t va)
 	pt_entry_t *l3p;
 
 	l2 = pmap_load(l2p);
-	KASSERT((l2 & ATTR_DESCR_MASK) == L2_TABLE,
-	    ("%s: L2 entry %#lx is a leaf", __func__, l2));
+
+	/*
+	 * The valid bit may be clear if pmap_update_entry() is concurrently
+	 * modifying the entry, so for KVA only the entry type may be checked.
+	 */
+	KASSERT(va >= VM_MAX_USER_ADDRESS || (l2 & ATTR_DESCR_VALID) != 0,
+	    ("%s: L2 entry %#lx for %#lx is invalid", __func__, l2, va));
+	KASSERT((l2 & ATTR_DESCR_TYPE_MASK) == ATTR_DESCR_TYPE_TABLE,
+	    ("%s: L2 entry %#lx for %#lx is a leaf", __func__, l2, va));
 	l3p = (pt_entry_t *)PHYS_TO_DMAP(l2 & ~ATTR_MASK);
 	return (&l3p[pmap_l3_index(va)]);
 }


More information about the svn-src-head mailing list