aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2021-03-27 11:08:52 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2021-03-27 18:16:27 +0000
commitc7b913aa47bac8b35b6a0679497ad28e561318c2 (patch)
treef3ec7bb091ae103eb04c48a36ea39e838060097c
parent410556f1f10fd35b350102725fd8504c3cb0afc8 (diff)
downloadsrc-c7b913aa47bac8b35b6a0679497ad28e561318c2.tar.gz
src-c7b913aa47bac8b35b6a0679497ad28e561318c2.zip
vm_fault: handle KERN_PROTECTION_FAILURE
pmap_enter(PMAP_ENTER_LARGEPAGE) may return KERN_PROTECTION_FAILURE due to PKRU inconsistency. Handle it in the call place from vm_fault_populate(), and in places which decode errors from vm_fault_populate()/ vm_fault_allocate(). Reviewed by: jah, markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D29442
-rw-r--r--sys/vm/vm_fault.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index da7b1f1d2d8e..585e1544415d 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -506,6 +506,8 @@ vm_fault_populate(struct faultstate *fs)
PMAP_ENTER_LARGEPAGE, bdry_idx);
VM_OBJECT_WLOCK(fs->first_object);
vm_page_xunbusy(m);
+ if (rv != KERN_SUCCESS)
+ goto out;
if ((fs->fault_flags & VM_FAULT_WIRE) != 0) {
for (i = 0; i < atop(pagesizes[bdry_idx]); i++)
vm_page_wire(m + i);
@@ -586,7 +588,7 @@ vm_fault_populate(struct faultstate *fs)
}
out:
curthread->td_ru.ru_majflt++;
- return (KERN_SUCCESS);
+ return (rv);
}
static int prot_fault_translation;
@@ -1073,6 +1075,7 @@ vm_fault_allocate(struct faultstate *fs)
switch (rv) {
case KERN_SUCCESS:
case KERN_FAILURE:
+ case KERN_PROTECTION_FAILURE:
case KERN_RESTART:
return (rv);
case KERN_NOT_RECEIVER:
@@ -1343,6 +1346,7 @@ RetryFault:
goto RetryFault;
case KERN_SUCCESS:
case KERN_FAILURE:
+ case KERN_PROTECTION_FAILURE:
case KERN_OUT_OF_BOUNDS:
unlock_and_deallocate(&fs);
return (rv);
@@ -1410,6 +1414,7 @@ RetryFault:
goto RetryFault;
case KERN_SUCCESS:
case KERN_FAILURE:
+ case KERN_PROTECTION_FAILURE:
case KERN_OUT_OF_BOUNDS:
unlock_and_deallocate(&fs);
return (rv);