summaryrefslogtreecommitdiff
path: root/sys/kern/kern_exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_exec.c')
-rw-r--r--sys/kern/kern_exec.c54
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);
+}