diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -611,7 +611,7 @@ * Set that machine state for performing an upcall that starts * the entry function with the given argument. */ -void +int cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg, stack_t *stack) { @@ -637,13 +637,15 @@ td->td_frame->tf_rip = (uintptr_t)entry; /* Return address sentinel value to stop stack unwinding. */ - suword32((void *)td->td_frame->tf_rsp, 0); + if (suword32((void *)td->td_frame->tf_rsp, 0) != 0) + return (EFAULT); /* Pass the argument to the entry point. */ - suword32((void *)(td->td_frame->tf_rsp + sizeof(int32_t)), - (uint32_t)(uintptr_t)arg); - - return; + if (suword32( + (void *)(td->td_frame->tf_rsp + sizeof(int32_t)), + (uint32_t)(uintptr_t)arg) != 0) + return (EFAULT); + return (0); } #endif @@ -663,10 +665,13 @@ td->td_frame->tf_flags = TF_HASSEGS; /* Return address sentinel value to stop stack unwinding. */ - suword((void *)td->td_frame->tf_rsp, 0); + if (suword((void *)td->td_frame->tf_rsp, 0) != 0) + return (EFAULT); /* Pass the argument to the entry point. */ td->td_frame->tf_rdi = (register_t)arg; + + return (0); } int diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c --- a/sys/arm/arm/vm_machdep.c +++ b/sys/arm/arm/vm_machdep.c @@ -224,7 +224,7 @@ * Set that machine state for performing an upcall that starts * the entry function with the given argument. */ -void +int cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg, stack_t *stack) { @@ -236,6 +236,7 @@ tf->tf_spsr = PSR_USR32_MODE; if ((register_t)entry & 1) tf->tf_spsr |= PSR_T; + return (0); } int diff --git a/sys/arm64/arm64/vm_machdep.c b/sys/arm64/arm64/vm_machdep.c --- a/sys/arm64/arm64/vm_machdep.c +++ b/sys/arm64/arm64/vm_machdep.c @@ -205,7 +205,7 @@ * Set that machine state for performing an upcall that starts * the entry function with the given argument. */ -void +int cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg, stack_t *stack) { @@ -224,6 +224,7 @@ tf->tf_x[0] = (register_t)arg; tf->tf_x[29] = 0; tf->tf_lr = 0; + return (0); } int diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -486,7 +486,7 @@ * Set that machine state for performing an upcall that starts * the entry function with the given argument. */ -void +int cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg, stack_t *stack) { @@ -510,11 +510,14 @@ td->td_frame->tf_eip = (int)entry; /* Return address sentinel value to stop stack unwinding. */ - suword((void *)td->td_frame->tf_esp, 0); + if (suword((void *)td->td_frame->tf_esp, 0) != 0) + return (EFAULT); /* Pass the argument to the entry point. */ - suword((void *)(td->td_frame->tf_esp + sizeof(void *)), - (int)arg); + if (suword((void *)(td->td_frame->tf_esp + sizeof(void *)), + (int)arg) != 0) + return (EFAULT); + return (0); } int diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c --- a/sys/kern/kern_thr.c +++ b/sys/kern/kern_thr.c @@ -146,6 +146,7 @@ { stack_t stack; struct thr_param *param; + int error; /* * Here we copy out tid to two places, one for child and one @@ -165,7 +166,9 @@ stack.ss_sp = param->stack_base; stack.ss_size = param->stack_size; /* Set upcall address to user thread entry function. */ - cpu_set_upcall(td, param->start_func, param->arg, &stack); + error = cpu_set_upcall(td, param->start_func, param->arg, &stack); + if (error != 0) + return (error); /* Setup user TLS address and TLS pointer register. */ return (cpu_set_user_tls(td, param->tls_base)); } diff --git a/sys/powerpc/powerpc/exec_machdep.c b/sys/powerpc/powerpc/exec_machdep.c --- a/sys/powerpc/powerpc/exec_machdep.c +++ b/sys/powerpc/powerpc/exec_machdep.c @@ -1149,7 +1149,7 @@ td->td_md.md_saved_msr = psl_kernset; } -void +int cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg, stack_t *stack) { @@ -1201,6 +1201,7 @@ td->td_retval[0] = (register_t)entry; td->td_retval[1] = 0; + return (0); } static int diff --git a/sys/riscv/riscv/vm_machdep.c b/sys/riscv/riscv/vm_machdep.c --- a/sys/riscv/riscv/vm_machdep.c +++ b/sys/riscv/riscv/vm_machdep.c @@ -178,7 +178,7 @@ * Set that machine state for performing an upcall that starts * the entry function with the given argument. */ -void +int cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg, stack_t *stack) { @@ -189,6 +189,7 @@ tf->tf_sp = STACKALIGN((uintptr_t)stack->ss_sp + stack->ss_size); tf->tf_sepc = (register_t)entry; tf->tf_a[0] = (register_t)arg; + return (0); } int diff --git a/sys/sys/proc.h b/sys/sys/proc.h --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1257,7 +1257,7 @@ int cpu_procctl(struct thread *td, int idtype, id_t id, int com, void *data); void cpu_set_syscall_retval(struct thread *, int); -void cpu_set_upcall(struct thread *, void (*)(void *), void *, +int cpu_set_upcall(struct thread *, void (*)(void *), void *, stack_t *); int cpu_set_user_tls(struct thread *, void *tls_base); void cpu_thread_alloc(struct thread *);