From c7da4ab2859d13adc8c72940338526ba0d1a8644 Mon Sep 17 00:00:00 2001 From: dv Date: Mon, 3 Jun 2024 20:53:00 +0000 Subject: [PATCH] Lock and unlock EPT pmaps before page table entry modification. ok mlarkin@ --- sys/arch/amd64/amd64/pmap.c | 43 ++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/sys/arch/amd64/amd64/pmap.c b/sys/arch/amd64/amd64/pmap.c index c66389d0f19..3a980ba1ce0 100644 --- a/sys/arch/amd64/amd64/pmap.c +++ b/sys/arch/amd64/amd64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.167 2024/05/03 13:48:29 dv Exp $ */ +/* $OpenBSD: pmap.c,v 1.168 2024/06/03 20:53:00 dv Exp $ */ /* $NetBSD: pmap.c,v 1.3 2003/05/08 18:13:13 thorpej Exp $ */ /* @@ -2408,6 +2408,8 @@ pmap_remove_ept(struct pmap *pmap, vaddr_t sgpa, vaddr_t egpa) struct vmx_invept_descriptor vid; #endif /* NVMM > 0 */ + mtx_enter(&pmap->pm_mtx); + DPRINTF("%s: sgpa=0x%llx egpa=0x%llx\n", __func__, (uint64_t)sgpa, (uint64_t)egpa); for (v = sgpa; v < egpa + PAGE_SIZE; v += PAGE_SIZE) @@ -2422,6 +2424,8 @@ pmap_remove_ept(struct pmap *pmap, vaddr_t sgpa, vaddr_t egpa) invept(IA32_VMX_INVEPT_SINGLE_CTX, &vid); } #endif /* NVMM > 0 */ + + mtx_leave(&pmap->pm_mtx); } void @@ -2433,6 +2437,8 @@ pmap_do_remove_ept(struct pmap *pmap, paddr_t gpa) pd_entry_t *pd4, *pd3, *pd2, *pd1; pd_entry_t *pptes; + MUTEX_ASSERT_LOCKED(&pmap->pm_mtx); + l4idx = (gpa & L4_MASK) >> L4_SHIFT; /* PML4E idx */ l3idx = (gpa & L3_MASK) >> L3_SHIFT; /* PDPTE idx */ l2idx = (gpa & L2_MASK) >> L2_SHIFT; /* PDE idx */ @@ -2510,6 +2516,7 @@ pmap_enter_ept(struct pmap *pmap, paddr_t gpa, paddr_t hpa, vm_prot_t prot) struct vm_page *ptp, *pptp; paddr_t npa; struct uvm_object *obj; + int ret = 0; if (gpa > MAXDSIZ) return ENOMEM; @@ -2519,11 +2526,15 @@ pmap_enter_ept(struct pmap *pmap, paddr_t gpa, paddr_t hpa, vm_prot_t prot) l2idx = (gpa & L2_MASK) >> L2_SHIFT; /* PDE idx */ l1idx = (gpa & L1_MASK) >> L1_SHIFT; /* PTE idx */ + mtx_enter(&pmap->pm_mtx); + /* Start at PML4 / top level */ pd = (pd_entry_t *)pmap->pm_pdir; - if (pd == NULL) - return ENOMEM; + if (pd == NULL) { + ret = ENOMEM; + goto unlock; + } /* npa = physaddr of PDPT */ npa = pd[l4idx] & PMAP_PA_MASK; @@ -2535,8 +2546,11 @@ pmap_enter_ept(struct pmap *pmap, paddr_t gpa, paddr_t hpa, vm_prot_t prot) ptp = uvm_pagealloc(obj, ptp_va2o(gpa, 3), NULL, UVM_PGA_USERESERVE|UVM_PGA_ZERO); - if (ptp == NULL) - return ENOMEM; + if (ptp == NULL) { + ret = ENOMEM; + goto unlock; + } + atomic_clearbits_int(&ptp->pg_flags, PG_BUSY); /* * New PDPT page - we are setting the first entry, so set @@ -2576,8 +2590,11 @@ pmap_enter_ept(struct pmap *pmap, paddr_t gpa, paddr_t hpa, vm_prot_t prot) ptp = uvm_pagealloc(obj, ptp_va2o(gpa, 2), NULL, UVM_PGA_USERESERVE|UVM_PGA_ZERO); - if (ptp == NULL) - return ENOMEM; + if (ptp == NULL) { + ret = ENOMEM; + goto unlock; + } + atomic_clearbits_int(&ptp->pg_flags, PG_BUSY); /* * New PD page - we are setting the first entry, so set @@ -2617,8 +2634,11 @@ pmap_enter_ept(struct pmap *pmap, paddr_t gpa, paddr_t hpa, vm_prot_t prot) ptp = uvm_pagealloc(obj, ptp_va2o(gpa, 1), NULL, UVM_PGA_USERESERVE|UVM_PGA_ZERO); - if (ptp == NULL) - return ENOMEM; + if (ptp == NULL) { + ret = ENOMEM; + goto unlock; + } + atomic_clearbits_int(&ptp->pg_flags, PG_BUSY); pptp->wire_count++; @@ -2661,7 +2681,10 @@ pmap_enter_ept(struct pmap *pmap, paddr_t gpa, paddr_t hpa, vm_prot_t prot) pd[l1idx] = npte; - return 0; +unlock: + mtx_leave(&pmap->pm_mtx); + + return ret; } /* -- 2.20.1