From aa6d6eba80c84385108fbb034f0eea348c18c311 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 13 Jan 2023 14:56:39 -0500 Subject: [PATCH 35/52] mips: Fix a couple of bugs in the pmap_enter(psind=1) implementation - Don't overwrite an existing mapping. Just bail if we encounter one. - Don't create writeable mappings when prefaulting. --- sys/mips/mips/pmap_mips64.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/sys/mips/mips/pmap_mips64.c b/sys/mips/mips/pmap_mips64.c index e97ec62f97e1..ac00d9dc99f2 100644 --- a/sys/mips/mips/pmap_mips64.c +++ b/sys/mips/mips/pmap_mips64.c @@ -3163,7 +3163,6 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, goto out; } if (psind == 1) { - /* XXX-MJ needs more review */ KASSERT((va & PDRMASK) == 0, ("pmap_enter: va unaligned")); KASSERT(m->psind > 0, ("pmap_enter: m->psind < psind")); rv = pmap_enter_pde(pmap, va, m, prot, flags, &lock); @@ -3608,11 +3607,11 @@ retry: /* * Tries to create the specified 2MB page mapping. Returns KERN_SUCCESS if the * mapping was created, and either KERN_FAILURE or KERN_RESOURCE_SHORTAGE - * otherwise. Returns KERN_FAILURE if PMAP_ENTER_NOREPLACE was specified and a - * mapping already exists at the specified virtual address XXX-MJ notyet. - * Returns KERN_RESOURCE_SHORTAGE if PMAP_ENTER_NOSLEEP was specified and a page - * table page allocation failed. Returns KERN_RESOURCE_SHORTAGE if - * PMAP_ENTER_NORECLAIM was specified and a PV entry allocation failed. + * otherwise. Returns KERN_FAILURE if a mapping already exists at the specified + * virtual address. Returns KERN_RESOURCE_SHORTAGE if PMAP_ENTER_NOSLEEP was + * specified and a page table page allocation failed. Returns + * KERN_RESOURCE_SHORTAGE if PMAP_ENTER_NORECLAIM was specified and a PV entry + * allocation failed. */ static int pmap_enter_pde(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, @@ -3641,6 +3640,12 @@ pmap_enter_pde(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, } pde = (pd_entry_t *)MIPS_PHYS_TO_DIRECT(VM_PAGE_TO_PHYS(mpde)); pde = &pde[pmap_pde_index(va)]; + if (*pde != NULL) { + mpde->wire_count--; + CTR3(KTR_PMAP, "%s: failure for va %#lx in pmap %p", __func__, + va, pmap); + return (KERN_FAILURE); + } pa = VM_PAGE_TO_PHYS(m); newpde = TLBLO_PA_TO_PFN(pa) | PTE_PS_1M | init_pte_prot(m, flags, prot); @@ -3733,8 +3738,9 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end, va = start + ptoa(diff); if ((va & PDRMASK) == 0 && va + NBPDR <= end && m->psind == 1 && pg_ps_enabled && - pmap_enter_pde(pmap, va, m, prot, PMAP_ENTER_NOSLEEP | - PMAP_ENTER_NORECLAIM, &lock) == KERN_SUCCESS) + pmap_enter_pde(pmap, va, m, prot & ~VM_PROT_WRITE, + PMAP_ENTER_NOSLEEP | PMAP_ENTER_NORECLAIM, &lock) == + KERN_SUCCESS) m = &m[NBPDR / PAGE_SIZE - 1]; else mpte = pmap_enter_quick_locked(pmap, va, m, prot, -- 2.41.0