diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-07-06 21:41:57 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-07-06 21:41:57 +0000 |
commit | 4e526a6aa77e6abcee3f8ea6ff3eab4e57605701 (patch) | |
tree | 813a28608d0736413ca426ea31ffbb47338f58e2 | |
parent | efa5c8fd0130d682124e5b29408493892e55174b (diff) |
Wire down the timekeep page. If we don't do this, the pagedaemon may
page it out and bad things will happen when we try to page it back in
from within the clock interrupt handler.
While there, make sure we set timekeep_object back to NULL if we fail
to make the timekeep page into kernel space.
ok deraadt@ (who had a very similar diff)
-rw-r--r-- | sys/kern/kern_exec.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 863686de932..24d0d97a3be 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exec.c,v 1.214 2020/07/06 13:33:09 pirofti Exp $ */ +/* $OpenBSD: kern_exec.c,v 1.215 2020/07/06 21:41:56 kettenis Exp $ */ /* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */ /*- @@ -881,7 +881,7 @@ exec_sigcode_map(struct process *pr, struct emul *e) int exec_timekeep_map(struct process *pr) { - size_t timekeep_sz = sizeof(struct timekeep); + size_t timekeep_sz = round_page(sizeof(struct timekeep)); /* * Similar to the sigcode object, except that there is a single @@ -893,10 +893,18 @@ exec_timekeep_map(struct process *pr) timekeep_object = uao_create(timekeep_sz, 0); uao_reference(timekeep_object); - if (uvm_map(kernel_map, &va, round_page(timekeep_sz), timekeep_object, + if (uvm_map(kernel_map, &va, timekeep_sz, timekeep_object, 0, 0, UVM_MAPFLAG(PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE, MAP_INHERIT_SHARE, MADV_RANDOM, 0))) { uao_detach(timekeep_object); + timekeep_object = NULL; + return (ENOMEM); + } + if (uvm_fault_wire(kernel_map, va, va + timekeep_sz, + PROT_READ | PROT_WRITE)) { + uvm_unmap(kernel_map, va, va + timekeep_sz); + uao_detach(timekeep_object); + timekeep_object = NULL; return (ENOMEM); } |