Skip to content

Commit

Permalink
riscv: stop preserving the tp register needlessly
Browse files Browse the repository at this point in the history
The tp (x4) register is neither caller nor callee saved according to
the RISC-V standard calling convention. It only has to be set on thread
context switching and is otherwise read-only.

To protect the kernel against a possible rogue user thread, the tp is
also re-set on exception entry from u-mode.

Signed-off-by: Nicolas Pitre <[email protected]>
  • Loading branch information
Nicolas Pitre authored and nashif committed Jun 23, 2022
1 parent 95b18c7 commit 3f8e326
Show file tree
Hide file tree
Showing 7 changed files with 11 additions and 17 deletions.
1 change: 0 additions & 1 deletion arch/riscv/core/fatal.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ FUNC_NORETURN void z_riscv_fatal_error(unsigned int reason,
#ifdef CONFIG_USERSPACE
LOG_ERR(" sp: " PR_REG, esf->sp);
#endif
LOG_ERR(" tp: " PR_REG, esf->tp);
LOG_ERR(" ra: " PR_REG, esf->ra);
LOG_ERR(" mepc: " PR_REG, esf->mepc);
LOG_ERR("mstatus: " PR_REG, esf->mstatus);
Expand Down
7 changes: 6 additions & 1 deletion arch/riscv/core/isr.S
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
RV_E( op a5, __z_arch_esf_t_a5_OFFSET(sp) );\
RV_I( op a6, __z_arch_esf_t_a6_OFFSET(sp) );\
RV_I( op a7, __z_arch_esf_t_a7_OFFSET(sp) );\
RV_E( op tp, __z_arch_esf_t_tp_OFFSET(sp) );\
RV_E( op ra, __z_arch_esf_t_ra_OFFSET(sp) )

#ifdef CONFIG_SMP
Expand Down Expand Up @@ -200,6 +199,12 @@ SECTION_FUNC(exception.entry, _isr_wrapper)
/* save stack value to be restored later */
sr t0, __z_arch_esf_t_sp_OFFSET(sp)

#if defined(CONFIG_THREAD_LOCAL_STORAGE)
/* Make sure tls pointer is sane */
lr t0, ___cpu_t_current_OFFSET(s0)
lr tp, _thread_offset_to_tls(t0)
#endif

#if !defined(CONFIG_SMP)
/* Clear user mode variable */
la t0, is_user_mode
Expand Down
3 changes: 0 additions & 3 deletions arch/riscv/core/offsets/offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
/* struct _callee_saved member offsets */
GEN_OFFSET_SYM(_callee_saved_t, sp);
GEN_OFFSET_SYM(_callee_saved_t, ra);
GEN_OFFSET_SYM(_callee_saved_t, tp);
GEN_OFFSET_SYM(_callee_saved_t, s0);
GEN_OFFSET_SYM(_callee_saved_t, s1);
#if !defined(CONFIG_RISCV_ISA_RV32E)
Expand Down Expand Up @@ -86,8 +85,6 @@ GEN_OFFSET_SYM(z_arch_esf_t, mstatus);

GEN_OFFSET_SYM(z_arch_esf_t, s0);

GEN_OFFSET_SYM(z_arch_esf_t, tp);

#ifdef CONFIG_USERSPACE
GEN_OFFSET_SYM(z_arch_esf_t, sp);
#endif
Expand Down
6 changes: 5 additions & 1 deletion arch/riscv/core/switch.S
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

#define DO_CALLEE_SAVED(op, reg) \
RV_E( op ra, _thread_offset_to_ra(reg) );\
RV_E( op tp, _thread_offset_to_tp(reg) );\
RV_E( op s0, _thread_offset_to_s0(reg) );\
RV_E( op s1, _thread_offset_to_s1(reg) );\
RV_I( op s2, _thread_offset_to_s2(reg) );\
Expand Down Expand Up @@ -75,6 +74,11 @@ skip_store_fp_callee_saved:
/* Get the new thread's stack pointer */
lr sp, _thread_offset_to_sp(a0)

#if defined(CONFIG_THREAD_LOCAL_STORAGE)
/* Get the new thread's tls pointer */
lr tp, _thread_offset_to_tls(a0)
#endif

#if defined(CONFIG_PMP_STACK_GUARD)
/*
* Stack guard has priority over user space for PMP usage.
Expand Down
9 changes: 0 additions & 9 deletions arch/riscv/core/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack,
stack_init->a2 = (ulong_t)p2;
stack_init->a3 = (ulong_t)p3;

#ifdef CONFIG_THREAD_LOCAL_STORAGE
thread->callee_saved.tp = (ulong_t)thread->tls;
#endif

/*
* Following the RISC-V architecture,
* the MSTATUS register (used to globally enable/disable interrupt),
Expand Down Expand Up @@ -90,11 +86,6 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack,
stack_init->sp = (ulong_t)(stack_init + 1);
#endif /* CONFIG_USERSPACE */

#if defined(CONFIG_THREAD_LOCAL_STORAGE)
stack_init->tp = thread->tls;
thread->callee_saved.tp = thread->tls;
#endif

/* Assign thread entry point and mstatus.MPRV mode. */
if (IS_ENABLED(CONFIG_USERSPACE)
&& (thread->base.user_options & K_USER)) {
Expand Down
1 change: 0 additions & 1 deletion include/zephyr/arch/riscv/exp.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ struct __esf {

ulong_t s0; /* callee-saved s0 */

ulong_t tp; /* thread pointer */
#ifdef CONFIG_USERSPACE
ulong_t sp; /* preserved (user or kernel) stack pointer */
#endif
Expand Down
1 change: 0 additions & 1 deletion include/zephyr/arch/riscv/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
struct _callee_saved {
ulong_t sp; /* Stack pointer, (x2 register) */
ulong_t ra; /* return address */
ulong_t tp; /* thread pointer */

ulong_t s0; /* saved register/frame pointer */
ulong_t s1; /* saved register */
Expand Down

0 comments on commit 3f8e326

Please sign in to comment.