From 5ad4406f22c558cc84162dbf4baca6fa353a9425 Mon Sep 17 00:00:00 2001 From: kettenis Date: Sun, 17 Jul 2022 17:59:35 +0000 Subject: [PATCH] Revert the changes made in rev 1.82. It is important to use pmap_enter(9) and pmap_remove(9) here since we're dealing with managed pages here. Found out the hard way by deraadt@ on landisk where we're running into issues with virtual cache aliases because multiple mappings exist for the pages we're dealing with here. The pmap_enter(9) and pmap_remove(9) functions handle conflicting cache aliases, whereas pmap_map_direct(9) and pmap_kenter_pa(9) assume that the pages is exclusively mapped in the kernel pmap. ok deraadt@ --- sys/uvm/uvm_pager.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/sys/uvm/uvm_pager.c b/sys/uvm/uvm_pager.c index f01df5a3301..6e0ad7552ac 100644 --- a/sys/uvm/uvm_pager.c +++ b/sys/uvm/uvm_pager.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_pager.c,v 1.83 2022/07/11 11:33:17 mpi Exp $ */ +/* $OpenBSD: uvm_pager.c,v 1.84 2022/07/17 17:59:35 kettenis Exp $ */ /* $NetBSD: uvm_pager.c,v 1.36 2000/11/27 18:26:41 chs Exp $ */ /* @@ -258,16 +258,6 @@ uvm_pagermapin(struct vm_page **pps, int npages, int flags) vsize_t size; struct vm_page *pp; -#ifdef __HAVE_PMAP_DIRECT - /* use direct mappings for single page */ - if (npages == 1) { - KASSERT(pps[0]); - KASSERT(pps[0]->pg_flags & PG_BUSY); - kva = pmap_map_direct(pps[0]); - return kva; - } -#endif - prot = PROT_READ; if (flags & UVMPAGER_MAPIN_READ) prot |= PROT_WRITE; @@ -283,7 +273,14 @@ uvm_pagermapin(struct vm_page **pps, int npages, int flags) pp = *pps++; KASSERT(pp); KASSERT(pp->pg_flags & PG_BUSY); - pmap_kenter_pa(cva, VM_PAGE_TO_PHYS(pp), prot); + /* Allow pmap_enter to fail. */ + if (pmap_enter(pmap_kernel(), cva, VM_PAGE_TO_PHYS(pp), + prot, PMAP_WIRED | PMAP_CANFAIL | prot) != 0) { + pmap_remove(pmap_kernel(), kva, cva); + pmap_update(pmap_kernel()); + uvm_pseg_release(kva); + return 0; + } } pmap_update(pmap_kernel()); return kva; @@ -297,15 +294,8 @@ uvm_pagermapin(struct vm_page **pps, int npages, int flags) void uvm_pagermapout(vaddr_t kva, int npages) { -#ifdef __HAVE_PMAP_DIRECT - /* use direct mappings for single page */ - if (npages == 1) { - pmap_unmap_direct(kva); - return; - } -#endif - pmap_kremove(kva, (vsize_t)npages << PAGE_SHIFT); + pmap_remove(pmap_kernel(), kva, kva + ((vsize_t)npages << PAGE_SHIFT)); pmap_update(pmap_kernel()); uvm_pseg_release(kva); -- 2.20.1