mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-04 15:40:44 +00:00
thread: Add a return value to cpu_set_upcall()
Some implementations copy data to userspace, an operation which can in principle fail. In preparation for adding a __result_use_check annotation to copyin() and related functions, let implementations of cpu_set_upcall() return an error, and check for errors when copying data to user memory. Reviewed by: kib, jhb MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D43100
This commit is contained in:
parent
4f35450ce5
commit
7b68fb5ab2
|
@ -611,7 +611,7 @@ cpu_copy_thread(struct thread *td, struct thread *td0)
|
|||
* 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 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg,
|
|||
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 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg,
|
|||
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
|
||||
|
|
|
@ -224,7 +224,7 @@ cpu_copy_thread(struct thread *td, struct thread *td0)
|
|||
* 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 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg,
|
|||
tf->tf_spsr = PSR_USR32_MODE;
|
||||
if ((register_t)entry & 1)
|
||||
tf->tf_spsr |= PSR_T;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -205,7 +205,7 @@ cpu_copy_thread(struct thread *td, struct thread *td0)
|
|||
* 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 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg,
|
|||
tf->tf_x[0] = (register_t)arg;
|
||||
tf->tf_x[29] = 0;
|
||||
tf->tf_lr = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -486,7 +486,7 @@ cpu_copy_thread(struct thread *td, struct thread *td0)
|
|||
* 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 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg,
|
|||
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
|
||||
|
|
|
@ -146,6 +146,7 @@ thr_new_initthr(struct thread *td, void *thunk)
|
|||
{
|
||||
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 @@ thr_new_initthr(struct thread *td, void *thunk)
|
|||
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));
|
||||
}
|
||||
|
|
|
@ -1149,7 +1149,7 @@ cpu_copy_thread(struct thread *td, struct thread *td0)
|
|||
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 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg,
|
|||
|
||||
td->td_retval[0] = (register_t)entry;
|
||||
td->td_retval[1] = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -178,7 +178,7 @@ cpu_copy_thread(struct thread *td, struct thread *td0)
|
|||
* 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 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg,
|
|||
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
|
||||
|
|
|
@ -1257,7 +1257,7 @@ void cpu_fork_kthread_handler(struct thread *, void (*)(void *), void *);
|
|||
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 *);
|
||||
|
|
Loading…
Reference in a new issue