diff options
Diffstat (limited to 'sys/kern/kern_exec.c')
-rw-r--r-- | sys/kern/kern_exec.c | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 20480c2fc28..863686de932 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exec.c,v 1.213 2020/02/15 09:35:48 anton Exp $ */ +/* $OpenBSD: kern_exec.c,v 1.214 2020/07/06 13:33:09 pirofti Exp $ */ /* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */ /*- @@ -64,6 +64,11 @@ #include <uvm/uvm_extern.h> #include <machine/tcb.h> +#include <sys/timetc.h> + +struct uvm_object *timekeep_object; +struct timekeep* timekeep; + void unveil_destroy(struct process *ps); const struct kmem_va_mode kv_exec = { @@ -77,6 +82,11 @@ const struct kmem_va_mode kv_exec = { int exec_sigcode_map(struct process *, struct emul *); /* + * Map the shared timekeep page. + */ +int exec_timekeep_map(struct process *); + +/* * If non-zero, stackgap_random specifies the upper limit of the random gap size * added to the fixed stack position. Must be n^2. */ @@ -670,6 +680,10 @@ sys_execve(struct proc *p, void *v, register_t *retval) */ KNOTE(&pr->ps_klist, NOTE_EXEC); + /* map the process's timekeep page, needs to be before e_fixup */ + if (exec_timekeep_map(pr)) + goto free_pack_abort; + /* setup new registers and do misc. setup. */ if (pack.ep_emul->e_fixup != NULL) { if ((*pack.ep_emul->e_fixup)(p, &pack) != 0) @@ -863,3 +877,41 @@ exec_sigcode_map(struct process *pr, struct emul *e) return (0); } + +int +exec_timekeep_map(struct process *pr) +{ + size_t timekeep_sz = sizeof(struct timekeep); + + /* + * Similar to the sigcode object, except that there is a single + * timekeep object, and not one per emulation. + */ + if (timekeep_object == NULL) { + vaddr_t va = 0; + + timekeep_object = uao_create(timekeep_sz, 0); + uao_reference(timekeep_object); + + if (uvm_map(kernel_map, &va, round_page(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); + return (ENOMEM); + } + + timekeep = (struct timekeep *)va; + timekeep->tk_version = TK_VERSION; + } + + pr->ps_timekeep = 0; /* no hint */ + uao_reference(timekeep_object); + if (uvm_map(&pr->ps_vmspace->vm_map, &pr->ps_timekeep, round_page(timekeep_sz), + timekeep_object, 0, 0, UVM_MAPFLAG(PROT_READ, PROT_READ, + MAP_INHERIT_COPY, MADV_RANDOM, 0))) { + uao_detach(timekeep_object); + return (ENOMEM); + } + + return (0); +} |