diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2022-07-17 17:59:36 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2022-07-17 17:59:36 +0000 |
commit | 30e640d319bd5941a611a8609433b492ab10ee92 (patch) | |
tree | 89fdedb36eea7a1c2931b163bd95573b3b41fd5e /sys | |
parent | c521013206b8e64eb6bdc62ea66389c55733467c (diff) |
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@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/uvm/uvm_pager.c | 30 |
1 files 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); |