summaryrefslogtreecommitdiff
path: root/sys/uvm
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2024-11-02 10:23:35 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2024-11-02 10:23:35 +0000
commit39fbdf2f8fdb2cd52d5b70cfaf7b0b09793263b4 (patch)
treed3548841b7c02715f996434789a2767e8229d7b6 /sys/uvm
parente5fbe6bf3dfd04c3a74eeb4005e5c976a2bd2eb0 (diff)
Handle faults on wired map entries similarly to VM_FAULT_WIRE faults.
It is valid to fault on wired mappings if the object was truncated then grown again. Adapted from NetBSD r1.207, ok miod@
Diffstat (limited to 'sys/uvm')
-rw-r--r--sys/uvm/uvm_fault.c23
1 files changed, 10 insertions, 13 deletions
diff --git a/sys/uvm/uvm_fault.c b/sys/uvm/uvm_fault.c
index 1ae20b5af75..06b1c8b9198 100644
--- a/sys/uvm/uvm_fault.c
+++ b/sys/uvm/uvm_fault.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_fault.c,v 1.135 2023/09/05 05:08:26 guenther Exp $ */
+/* $OpenBSD: uvm_fault.c,v 1.136 2024/11/02 10:23:34 mpi Exp $ */
/* $NetBSD: uvm_fault.c,v 1.51 2000/08/06 00:22:53 thorpej Exp $ */
/*
@@ -552,7 +552,7 @@ struct uvm_faultctx {
int uvm_fault_check(
struct uvm_faultinfo *, struct uvm_faultctx *,
- struct vm_anon ***);
+ struct vm_anon ***, vm_fault_t);
int uvm_fault_upper(
struct uvm_faultinfo *, struct uvm_faultctx *,
@@ -585,19 +585,14 @@ uvm_fault(vm_map_t orig_map, vaddr_t vaddr, vm_fault_t fault_type,
ufi.orig_map = orig_map;
ufi.orig_rvaddr = trunc_page(vaddr);
ufi.orig_size = PAGE_SIZE; /* can't get any smaller than this */
- if (fault_type == VM_FAULT_WIRE)
- flt.narrow = TRUE; /* don't look for neighborhood
- * pages on wire */
- else
- flt.narrow = FALSE; /* normal fault */
flt.access_type = access_type;
-
+ flt.narrow = FALSE; /* assume normal fault for now */
error = ERESTART;
while (error == ERESTART) { /* ReFault: */
anons = anons_store;
- error = uvm_fault_check(&ufi, &flt, &anons);
+ error = uvm_fault_check(&ufi, &flt, &anons, fault_type);
if (error != 0)
continue;
@@ -660,7 +655,7 @@ uvm_fault(vm_map_t orig_map, vaddr_t vaddr, vm_fault_t fault_type,
*/
int
uvm_fault_check(struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
- struct vm_anon ***ranons)
+ struct vm_anon ***ranons, vm_fault_t fault_type)
{
struct vm_amap *amap;
struct uvm_object *uobj;
@@ -694,12 +689,14 @@ uvm_fault_check(struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
* be more strict than ufi->entry->protection. "wired" means either
* the entry is wired or we are fault-wiring the pg.
*/
-
flt->enter_prot = ufi->entry->protection;
flt->pa_flags = UVM_ET_ISWC(ufi->entry) ? PMAP_WC : 0;
- flt->wired = VM_MAPENT_ISWIRED(ufi->entry) || (flt->narrow == TRUE);
- if (flt->wired)
+ if (VM_MAPENT_ISWIRED(ufi->entry) || (fault_type == VM_FAULT_WIRE)) {
+ flt->wired = TRUE;
flt->access_type = flt->enter_prot; /* full access for wired */
+ /* don't look for neighborhood * pages on "wire" fault */
+ flt->narrow = TRUE;
+ }
/* handle "needs_copy" case. */
if (UVM_ET_ISNEEDSCOPY(ufi->entry)) {