[PATCH v2 2/6] riscv: insn: Set sstatus.MXR when reading userspace instruction
"Yicong Yang" <[email protected]> Tue, 28 Jul 2026 17:46:23 +0800
| Newsgroups | org.infradead.lists.linux-riscv |
|---|---|
| Message-ID | <[email protected]> |
The __read_insn() uses get_user() to read userspace instructions. Bo Gan noticed that get_user() is insufficient in this case since it's possible for the instruction segment mapped as execute-only and get_user() doesn't have permissions to load it. The architecture provides sstatus.MXR for handling this so set MXR when reading userspace instruction. Cc: Bo Gan <[email protected]> Signed-off-by: Yicong Yang <[email protected]> --- arch/riscv/include/asm/csr.h | 1 + arch/riscv/include/asm/insn.h | 2 ++ arch/riscv/include/asm/processor.h | 2 +- arch/riscv/kernel/asm-offsets.c | 6 +++--- arch/riscv/kernel/entry.S | 14 +++++++------- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index d5d309b3b570..7bfbda958f0f 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -17,6 +17,7 @@ #define SR_SPP _AC(0x00000100, UL) /* Previously Supervisor */ #define SR_MPP _AC(0x00001800, UL) /* Previously Machine */ #define SR_SUM _AC(0x00040000, UL) /* Supervisor User Memory Access */ +#define SR_MXR _AC(0x00080000, UL) /* Make eXecutable Readable */ /* zicfilp landing pad status bit */ #define SR_SPELP _AC(0x00800000, UL) diff --git a/arch/riscv/include/asm/insn.h b/arch/riscv/include/asm/insn.h index 5f60367c2abc..c36d1dfa16c6 100644 --- a/arch/riscv/include/asm/insn.h +++ b/arch/riscv/include/asm/insn.h @@ -606,7 +606,9 @@ static inline void riscv_insn_insert_utype_itype_imm(u32 *utype_insn, u32 *itype int __ret; \ \ if (user_mode(regs)) { \ + csr_set(CSR_STATUS, SR_MXR); \ __ret = get_user(insn, (type __user *) insn_addr); \ + csr_clear(CSR_STATUS, SR_MXR); \ } else { \ insn = *(type *)insn_addr; \ __ret = 0; \ diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h index 812517b2cec1..1e1523952b45 100644 --- a/arch/riscv/include/asm/processor.h +++ b/arch/riscv/include/asm/processor.h @@ -111,7 +111,7 @@ struct thread_struct { struct __riscv_d_ext_state fstate; unsigned long bad_cause; unsigned long envcfg; - unsigned long sum; + unsigned long sum_mxr; u32 riscv_v_flags; u32 vstate_ctrl; struct __riscv_v_ext_state vstate; diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c index a75f0cfea1e9..b6de2179570b 100644 --- a/arch/riscv/kernel/asm-offsets.c +++ b/arch/riscv/kernel/asm-offsets.c @@ -35,7 +35,7 @@ void asm_offsets(void) OFFSET(TASK_THREAD_S9, task_struct, thread.s[9]); OFFSET(TASK_THREAD_S10, task_struct, thread.s[10]); OFFSET(TASK_THREAD_S11, task_struct, thread.s[11]); - OFFSET(TASK_THREAD_SUM, task_struct, thread.sum); + OFFSET(TASK_THREAD_SUM_MXR, task_struct, thread.sum_mxr); OFFSET(TASK_TI_CPU, task_struct, thread_info.cpu); OFFSET(TASK_TI_PREEMPT_COUNT, task_struct, thread_info.preempt_count); @@ -352,8 +352,8 @@ void asm_offsets(void) offsetof(struct task_struct, thread.s[11]) - offsetof(struct task_struct, thread.ra) ); - DEFINE(TASK_THREAD_SUM_RA, - offsetof(struct task_struct, thread.sum) + DEFINE(TASK_THREAD_SUM_MXR_RA, + offsetof(struct task_struct, thread.sum_mxr) - offsetof(struct task_struct, thread.ra) ); diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S index d799c4e56f80..9ccc74aafece 100644 --- a/arch/riscv/kernel/entry.S +++ b/arch/riscv/kernel/entry.S @@ -172,13 +172,13 @@ SYM_CODE_START(handle_exception) save_from_x6_to_x31 /* - * Disable user-mode memory access as it should only be set in the - * actual user copy routines. + * Disable user-mode memory access and MXR as it should only be set in + * the actual user copy routines. * * Disable the FPU/Vector to detect illegal usage of floating point * or vector in kernel space. */ - li t0, SR_SUM | SR_FS_VS + li t0, SR_SUM | SR_MXR | SR_FS_VS #ifdef CONFIG_64BIT li t1, SR_ELP or t0, t0, t1 @@ -443,15 +443,15 @@ SYM_FUNC_START(__switch_to) REG_S s10, TASK_THREAD_S10_RA(a3) REG_S s11, TASK_THREAD_S11_RA(a3) - /* save the user space access flag */ + /* save the user space access and MXR flag */ csrr s0, CSR_STATUS - REG_S s0, TASK_THREAD_SUM_RA(a3) + REG_S s0, TASK_THREAD_SUM_MXR_RA(a3) /* Save the kernel shadow call stack pointer */ scs_save_current /* Restore context from next->thread */ - REG_L s0, TASK_THREAD_SUM_RA(a4) - li s1, SR_SUM + REG_L s0, TASK_THREAD_SUM_MXR_RA(a4) + li s1, SR_SUM | SR_MXR and s0, s0, s1 csrs CSR_STATUS, s0 REG_L ra, TASK_THREAD_RA_RA(a4) -- 2.50.1 (Apple Git-155) _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv