git: bcced8754840 - stable/13 - thread: Add a return value to cpu_set_upcall()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 02 Jan 2024 01:13:00 UTC
The branch stable/13 has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=bcced8754840857be3fe86540de796db4832fe5b
commit bcced8754840857be3fe86540de796db4832fe5b
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2023-12-26 01:39:39 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2024-01-02 01:12:45 +0000
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
(cherry picked from commit 7b68fb5ab2a276ccd081cc1a43cebf0fb315e952)
---
sys/amd64/amd64/vm_machdep.c | 19 ++++++++++++-------
sys/arm/arm/vm_machdep.c | 3 ++-
sys/arm64/arm64/vm_machdep.c | 3 ++-
sys/i386/i386/vm_machdep.c | 11 +++++++----
sys/kern/kern_thr.c | 5 ++++-
sys/powerpc/powerpc/exec_machdep.c | 3 ++-
sys/riscv/riscv/vm_machdep.c | 3 ++-
sys/sys/proc.h | 2 +-
8 files changed, 32 insertions(+), 17 deletions(-)
diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
index 0bb75e18c5d8..4235ed1cd8e9 100644
--- a/sys/amd64/amd64/vm_machdep.c
+++ b/sys/amd64/amd64/vm_machdep.c
@@ -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
diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c
index 03816df5760f..b2ece47e621e 100644
--- a/sys/arm/arm/vm_machdep.c
+++ b/sys/arm/arm/vm_machdep.c
@@ -223,7 +223,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)
{
@@ -233,6 +233,7 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg,
tf->tf_pc = (int)entry;
tf->tf_r0 = (int)arg;
tf->tf_spsr = PSR_USR32_MODE;
+ return (0);
}
int
diff --git a/sys/arm64/arm64/vm_machdep.c b/sys/arm64/arm64/vm_machdep.c
index ea8e88b7201d..8f5343a0c6ef 100644
--- a/sys/arm64/arm64/vm_machdep.c
+++ b/sys/arm64/arm64/vm_machdep.c
@@ -203,7 +203,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)
{
@@ -216,6 +216,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_elr = (register_t)entry;
tf->tf_x[0] = (register_t)arg;
+ return (0);
}
int
diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index 8e0917eed1c2..e05791967fba 100644
--- a/sys/i386/i386/vm_machdep.c
+++ b/sys/i386/i386/vm_machdep.c
@@ -488,7 +488,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)
{
@@ -512,11 +512,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
diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c
index 5efdfea6235d..f5787c0be427 100644
--- a/sys/kern/kern_thr.c
+++ b/sys/kern/kern_thr.c
@@ -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));
}
diff --git a/sys/powerpc/powerpc/exec_machdep.c b/sys/powerpc/powerpc/exec_machdep.c
index d4bef747284f..341b78b018b6 100644
--- a/sys/powerpc/powerpc/exec_machdep.c
+++ b/sys/powerpc/powerpc/exec_machdep.c
@@ -1063,7 +1063,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)
{
@@ -1116,6 +1116,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
diff --git a/sys/riscv/riscv/vm_machdep.c b/sys/riscv/riscv/vm_machdep.c
index 58acf5df9e14..043093960edf 100644
--- a/sys/riscv/riscv/vm_machdep.c
+++ b/sys/riscv/riscv/vm_machdep.c
@@ -179,7 +179,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)
{
@@ -190,6 +190,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
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index a85ae239f46b..fb9bcfe1d746 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1184,7 +1184,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 *);