riscv: stop preserving the tp register needlessly

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 <npitre@baylibre.com>
This commit is contained in:
Nicolas Pitre 2022-06-07 08:04:55 -04:00 committed by Anas Nashif
commit 3f8e326d1a
7 changed files with 11 additions and 17 deletions

View file

@ -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);

View file

@ -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
@ -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

View file

@ -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)
@ -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

View file

@ -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) );\
@ -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.

View file

@ -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),
@ -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)) {

View file

@ -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

View file

@ -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 */