git: c6d092b5107d - main - pmap: Keep PTI page table pages busy

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Wed, 15 Jun 2022 15:39:24 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=c6d092b5107d1a3acefa977828b8130c0505fe7b

commit c6d092b5107d1a3acefa977828b8130c0505fe7b
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2022-06-15 14:19:01 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2022-06-15 15:38:04 +0000

    pmap: Keep PTI page table pages busy
    
    PTI page table pages are allocated from a VM object, so must be
    exclusively busied when they are freed, e.g., when a thread loses a race
    in pmap_pti_pde().  Simply keep PTPs busy at all times, as was done for
    some other kernel allocators in commit
    e9ceb9dd110e04fc19729b4e9fb1c8bfbb8398a3.
    
    Also remove some redundant assertions on "ref_count":
    vm_page_unwire_noq() already asserts that the page's reference count is
    greater than zero.
    
    Reported by:    syzkaller
    Reviewed by:    kib
    MFC after:      2 weeks
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D35466
---
 sys/amd64/amd64/pmap.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 5350bff2fef4..a4e796becc73 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -10867,18 +10867,16 @@ pmap_pti_alloc_page(void)
 	vm_page_t m;
 
 	VM_OBJECT_ASSERT_WLOCKED(pti_obj);
-	m = vm_page_grab(pti_obj, pti_pg_idx++, VM_ALLOC_NOBUSY |
-	    VM_ALLOC_WIRED | VM_ALLOC_ZERO);
+	m = vm_page_grab(pti_obj, pti_pg_idx++, VM_ALLOC_WIRED | VM_ALLOC_ZERO);
 	return (m);
 }
 
 static bool
 pmap_pti_free_page(vm_page_t m)
 {
-
-	KASSERT(m->ref_count > 0, ("page %p not referenced", m));
 	if (!vm_page_unwire_noq(m))
 		return (false);
+	vm_page_xbusy_claim(m);
 	vm_page_free_zero(m);
 	return (true);
 }
@@ -10984,7 +10982,6 @@ pmap_pti_unwire_pde(void *pde, bool only_ref)
 
 	VM_OBJECT_ASSERT_WLOCKED(pti_obj);
 	m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((uintptr_t)pde));
-	MPASS(m->ref_count > 0);
 	MPASS(only_ref || m->ref_count > 1);
 	pmap_pti_free_page(m);
 }
@@ -10997,7 +10994,6 @@ pmap_pti_unwire_pte(void *pte, vm_offset_t va)
 
 	VM_OBJECT_ASSERT_WLOCKED(pti_obj);
 	m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((uintptr_t)pte));
-	MPASS(m->ref_count > 0);
 	if (pmap_pti_free_page(m)) {
 		pde = pmap_pti_pde(va);
 		MPASS((*pde & (X86_PG_PS | X86_PG_V)) == X86_PG_V);