summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2022-07-17 17:59:36 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2022-07-17 17:59:36 +0000
commit30e640d319bd5941a611a8609433b492ab10ee92 (patch)
tree89fdedb36eea7a1c2931b163bd95573b3b41fd5e /sys
parentc521013206b8e64eb6bdc62ea66389c55733467c (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.c30
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);