* [PATCH v2 0/6] Add workarounds for Picoheart erratas
@ 2026-07-28 9:46 Yicong Yang
2026-07-28 9:46 ` [PATCH v2 1/6] riscv: Make get_insn public for instruction fault handling Yicong Yang
` (5 more replies)
0 siblings, 6 replies; 9+ messages in thread
From: Yicong Yang @ 2026-07-28 9:46 UTC (permalink / raw)
To: pjw, palmer, aou, linux-riscv
Cc: wangruikang, ganboing, geshijian, niehaitao, cuiyunhui,
yang.yicong
This series add basic errata framework for Picoheart SoCs for handling
upcoming Picoheart erratas. And add workarounds for the first two
erratas on our hardware. Also do some fixups and refactor in support
of the erratas.
Change since v1:
- factor out a common get_insn for reading userspace instructions
- fix the issue from reading instructions of a exec-only mapping
- cleanups and code style refinements per comments
Link: https://lore.kernel.org/linux-riscv/20260715084724.26578-1-yang.yicong@picoheart.com/
Yicong Yang (6):
riscv: Make get_insn public for instruction fault handling
riscv: insn: Set sstatus.MXR when reading userspace instruction
riscv: insn: Support decoding of CBO instructions
riscv: errata: Add init framework for picoheart errata
riscv: errata: picoheart: Add workaround for cbo.clean errata
riscv: errata: picoheart: Add workaround for AMOCASQ errata
arch/riscv/Kconfig.errata | 34 +++
arch/riscv/errata/Makefile | 1 +
arch/riscv/errata/picoheart/Makefile | 5 +
arch/riscv/errata/picoheart/errata.c | 238 +++++++++++++++++++
arch/riscv/include/asm/alternative.h | 3 +
arch/riscv/include/asm/cmpxchg.h | 2 +-
arch/riscv/include/asm/cpufeature.h | 8 +
arch/riscv/include/asm/csr.h | 1 +
arch/riscv/include/asm/errata_list.h | 25 +-
arch/riscv/include/asm/errata_list_vendors.h | 4 +
arch/riscv/include/asm/insn.h | 63 ++++-
arch/riscv/include/asm/processor.h | 2 +-
arch/riscv/include/asm/vendorid_list.h | 1 +
arch/riscv/kernel/alternative.c | 5 +
arch/riscv/kernel/asm-offsets.c | 6 +-
arch/riscv/kernel/cpufeature.c | 16 +-
arch/riscv/kernel/entry.S | 14 +-
arch/riscv/kernel/traps.c | 4 +
arch/riscv/kernel/traps_misaligned.c | 52 ----
arch/riscv/kernel/vector.c | 6 +-
20 files changed, 419 insertions(+), 71 deletions(-)
create mode 100644 arch/riscv/errata/picoheart/Makefile
create mode 100644 arch/riscv/errata/picoheart/errata.c
--
2.50.1 (Apple Git-155)
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 1/6] riscv: Make get_insn public for instruction fault handling
2026-07-28 9:46 [PATCH v2 0/6] Add workarounds for Picoheart erratas Yicong Yang
@ 2026-07-28 9:46 ` Yicong Yang
2026-07-28 9:46 ` [PATCH v2 2/6] riscv: insn: Set sstatus.MXR when reading userspace instruction Yicong Yang
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Yicong Yang @ 2026-07-28 9:46 UTC (permalink / raw)
To: pjw, palmer, aou, linux-riscv
Cc: wangruikang, ganboing, geshijian, niehaitao, cuiyunhui,
yang.yicong
Currently two places (vector and misaligned load/store) need
to get fault instructions for handling and they implement the
function separately. This is a common function so make
get_insn() public in asm/insn.h for doing this job to make it
less fragile and improve the maintainability.
Signed-off-by: Yicong Yang <yang.yicong@picoheart.com>
---
arch/riscv/include/asm/insn.h | 53 ++++++++++++++++++++++++++++
arch/riscv/kernel/traps_misaligned.c | 52 ---------------------------
arch/riscv/kernel/vector.c | 6 ++--
3 files changed, 56 insertions(+), 55 deletions(-)
diff --git a/arch/riscv/include/asm/insn.h b/arch/riscv/include/asm/insn.h
index c3005573e8c9..5f60367c2abc 100644
--- a/arch/riscv/include/asm/insn.h
+++ b/arch/riscv/include/asm/insn.h
@@ -600,4 +600,57 @@ static inline void riscv_insn_insert_utype_itype_imm(u32 *utype_insn, u32 *itype
*utype_insn |= (imm & RV_U_IMM_31_12_MASK) + ((imm & BIT(11)) << 1);
*itype_insn |= ((imm & RV_I_IMM_11_0_MASK) << RV_I_IMM_11_0_OPOFF);
}
+
+#define __read_insn(regs, insn, insn_addr, type) \
+({ \
+ int __ret; \
+ \
+ if (user_mode(regs)) { \
+ __ret = get_user(insn, (type __user *) insn_addr); \
+ } else { \
+ insn = *(type *)insn_addr; \
+ __ret = 0; \
+ } \
+ \
+ __ret; \
+})
+
+static inline int get_insn(struct pt_regs *regs, ulong epc, ulong *r_insn)
+{
+ ulong insn = 0;
+
+ if (epc & 0x2) {
+ ulong tmp = 0;
+
+ if (__read_insn(regs, insn, epc, u16))
+ return -EFAULT;
+ /* __get_user() uses regular "lw" which sign extend the loaded
+ * value make sure to clear higher order bits in case we "or" it
+ * below with the upper 16 bits half.
+ */
+ insn &= GENMASK(15, 0);
+ if ((insn & __INSN_LENGTH_MASK) != __INSN_LENGTH_32) {
+ *r_insn = insn;
+ return 0;
+ }
+ epc += sizeof(u16);
+ if (__read_insn(regs, tmp, epc, u16))
+ return -EFAULT;
+ *r_insn = (tmp << 16) | insn;
+
+ return 0;
+ } else {
+ if (__read_insn(regs, insn, epc, u32))
+ return -EFAULT;
+ if ((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) {
+ *r_insn = insn;
+ return 0;
+ }
+ insn &= GENMASK(15, 0);
+ *r_insn = insn;
+
+ return 0;
+ }
+}
+
#endif /* _ASM_RISCV_INSN_H */
diff --git a/arch/riscv/kernel/traps_misaligned.c b/arch/riscv/kernel/traps_misaligned.c
index 6e8ae6c66322..f10f14001480 100644
--- a/arch/riscv/kernel/traps_misaligned.c
+++ b/arch/riscv/kernel/traps_misaligned.c
@@ -129,58 +129,6 @@ static unsigned long get_f32_rs(unsigned long insn, u8 fp_reg_offset,
#define GET_F32_RS2C(insn, regs) (get_f32_rs(insn, 2, regs))
#define GET_F32_RS2S(insn, regs) (get_f32_rs(RVC_RS2S(insn), 0, regs))
-#define __read_insn(regs, insn, insn_addr, type) \
-({ \
- int __ret; \
- \
- if (user_mode(regs)) { \
- __ret = get_user(insn, (type __user *) insn_addr); \
- } else { \
- insn = *(type *)insn_addr; \
- __ret = 0; \
- } \
- \
- __ret; \
-})
-
-static inline int get_insn(struct pt_regs *regs, ulong epc, ulong *r_insn)
-{
- ulong insn = 0;
-
- if (epc & 0x2) {
- ulong tmp = 0;
-
- if (__read_insn(regs, insn, epc, u16))
- return -EFAULT;
- /* __get_user() uses regular "lw" which sign extend the loaded
- * value make sure to clear higher order bits in case we "or" it
- * below with the upper 16 bits half.
- */
- insn &= GENMASK(15, 0);
- if ((insn & __INSN_LENGTH_MASK) != __INSN_LENGTH_32) {
- *r_insn = insn;
- return 0;
- }
- epc += sizeof(u16);
- if (__read_insn(regs, tmp, epc, u16))
- return -EFAULT;
- *r_insn = (tmp << 16) | insn;
-
- return 0;
- } else {
- if (__read_insn(regs, insn, epc, u32))
- return -EFAULT;
- if ((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) {
- *r_insn = insn;
- return 0;
- }
- insn &= GENMASK(15, 0);
- *r_insn = insn;
-
- return 0;
- }
-}
-
union reg_data {
u8 data_bytes[8];
ulong data_ulong;
diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c
index b112166d51e9..1e37810035a9 100644
--- a/arch/riscv/kernel/vector.c
+++ b/arch/riscv/kernel/vector.c
@@ -184,8 +184,8 @@ EXPORT_SYMBOL_GPL(riscv_v_vstate_ctrl_user_allowed);
bool riscv_v_first_use_handler(struct pt_regs *regs)
{
- u32 __user *epc = (u32 __user *)regs->epc;
- u32 insn = (u32)regs->badaddr;
+ unsigned long epc = regs->epc;
+ unsigned long insn = regs->badaddr;
if (!(has_vector() || has_xtheadvector()))
return false;
@@ -200,7 +200,7 @@ bool riscv_v_first_use_handler(struct pt_regs *regs)
/* Get the instruction */
if (!insn) {
- if (__get_user(insn, epc))
+ if (get_insn(regs, epc, &insn))
return false;
}
--
2.50.1 (Apple Git-155)
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 2/6] riscv: insn: Set sstatus.MXR when reading userspace instruction
2026-07-28 9:46 [PATCH v2 0/6] Add workarounds for Picoheart erratas Yicong Yang
2026-07-28 9:46 ` [PATCH v2 1/6] riscv: Make get_insn public for instruction fault handling Yicong Yang
@ 2026-07-28 9:46 ` Yicong Yang
2026-08-25 0:06 ` Paul Walmsley
2026-07-28 9:46 ` [PATCH v2 3/6] riscv: insn: Support decoding of CBO instructions Yicong Yang
` (3 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: Yicong Yang @ 2026-07-28 9:46 UTC (permalink / raw)
To: pjw, palmer, aou, linux-riscv
Cc: wangruikang, ganboing, geshijian, niehaitao, cuiyunhui,
yang.yicong
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 <ganboing@gmail.com>
Signed-off-by: Yicong Yang <yang.yicong@picoheart.com>
---
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
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 3/6] riscv: insn: Support decoding of CBO instructions
2026-07-28 9:46 [PATCH v2 0/6] Add workarounds for Picoheart erratas Yicong Yang
2026-07-28 9:46 ` [PATCH v2 1/6] riscv: Make get_insn public for instruction fault handling Yicong Yang
2026-07-28 9:46 ` [PATCH v2 2/6] riscv: insn: Set sstatus.MXR when reading userspace instruction Yicong Yang
@ 2026-07-28 9:46 ` Yicong Yang
2026-07-28 9:46 ` [PATCH v2 4/6] riscv: errata: Add init framework for picoheart errata Yicong Yang
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Yicong Yang @ 2026-07-28 9:46 UTC (permalink / raw)
To: pjw, palmer, aou, linux-riscv
Cc: wangruikang, ganboing, geshijian, niehaitao, cuiyunhui,
yang.yicong
Add definitions for decoding CBO instructions. Rename
RVG_OPCODE_FENCE to RVG_OPCODE_MISC_MEM as spec defines
it as MISC-MEM and it's also used by CBO instructions.
Signed-off-by: Yicong Yang <yang.yicong@picoheart.com>
---
arch/riscv/include/asm/insn.h | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/include/asm/insn.h b/arch/riscv/include/asm/insn.h
index c36d1dfa16c6..f6b32d8d558d 100644
--- a/arch/riscv/include/asm/insn.h
+++ b/arch/riscv/include/asm/insn.h
@@ -12,6 +12,7 @@
#define RV_INSN_FUNCT3_OPOFF 12
#define RV_INSN_OPCODE_MASK GENMASK(6, 0)
#define RV_INSN_OPCODE_OPOFF 0
+#define RV_INSN_FUNCT12_MASK GENMASK(31, 20)
#define RV_INSN_FUNCT12_OPOFF 20
#define RV_ENCODE_FUNCT3(f_) (RVG_FUNCT3_##f_ << RV_INSN_FUNCT3_OPOFF)
@@ -135,7 +136,7 @@
#define RVC_C2_RS1_MASK GENMASK(4, 0)
/* parts of opcode for RVG*/
-#define RVG_OPCODE_FENCE 0x0f
+#define RVG_OPCODE_MISC_MEM 0x0f
#define RVG_OPCODE_AUIPC 0x17
#define RVG_OPCODE_BRANCH 0x63
#define RVG_OPCODE_JALR 0x67
@@ -171,6 +172,7 @@
#define RVG_FUNCT3_JALR 0x0
#define RVG_FUNCT3_BEQ 0x0
#define RVG_FUNCT3_BNE 0x1
+#define RVG_FUNCT3_CBO 0x2
#define RVG_FUNCT3_BLT 0x4
#define RVG_FUNCT3_BGE 0x5
#define RVG_FUNCT3_BLTU 0x6
@@ -186,12 +188,14 @@
#define RVC_FUNCT4_C_EBREAK 0x9
#define RVG_FUNCT12_EBREAK 0x1
+#define RVG_FUNCT12_CBO_CLEAN 0x1
+#define RVG_FUNCT12_CBO_FLUSH 0x2
#define RVG_FUNCT12_SRET 0x102
#define RVG_MATCH_AUIPC (RVG_OPCODE_AUIPC)
#define RVG_MATCH_JALR (RV_ENCODE_FUNCT3(JALR) | RVG_OPCODE_JALR)
#define RVG_MATCH_JAL (RVG_OPCODE_JAL)
-#define RVG_MATCH_FENCE (RVG_OPCODE_FENCE)
+#define RVG_MATCH_FENCE (RVG_OPCODE_MISC_MEM)
#define RVG_MATCH_BEQ (RV_ENCODE_FUNCT3(BEQ) | RVG_OPCODE_BRANCH)
#define RVG_MATCH_BNE (RV_ENCODE_FUNCT3(BNE) | RVG_OPCODE_BRANCH)
#define RVG_MATCH_BLT (RV_ENCODE_FUNCT3(BLT) | RVG_OPCODE_BRANCH)
--
2.50.1 (Apple Git-155)
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 4/6] riscv: errata: Add init framework for picoheart errata
2026-07-28 9:46 [PATCH v2 0/6] Add workarounds for Picoheart erratas Yicong Yang
` (2 preceding siblings ...)
2026-07-28 9:46 ` [PATCH v2 3/6] riscv: insn: Support decoding of CBO instructions Yicong Yang
@ 2026-07-28 9:46 ` Yicong Yang
2026-07-28 9:46 ` [PATCH v2 5/6] riscv: errata: picoheart: Add workaround for cbo.clean errata Yicong Yang
2026-07-28 9:46 ` [PATCH v2 6/6] riscv: errata: picoheart: Add workaround for AMOCASQ errata Yicong Yang
5 siblings, 0 replies; 9+ messages in thread
From: Yicong Yang @ 2026-07-28 9:46 UTC (permalink / raw)
To: pjw, palmer, aou, linux-riscv
Cc: wangruikang, ganboing, geshijian, niehaitao, cuiyunhui,
yang.yicong
Add init framework for handling upcoming picoheart erratas.
Signed-off-by: Yicong Yang <yang.yicong@picoheart.com>
---
arch/riscv/Kconfig.errata | 10 ++++
arch/riscv/errata/Makefile | 1 +
arch/riscv/errata/picoheart/Makefile | 5 ++
arch/riscv/errata/picoheart/errata.c | 57 ++++++++++++++++++++
arch/riscv/include/asm/alternative.h | 3 ++
arch/riscv/include/asm/errata_list_vendors.h | 4 ++
arch/riscv/include/asm/vendorid_list.h | 1 +
arch/riscv/kernel/alternative.c | 5 ++
8 files changed, 86 insertions(+)
create mode 100644 arch/riscv/errata/picoheart/Makefile
create mode 100644 arch/riscv/errata/picoheart/errata.c
diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
index 3c945d086c7d..374d7fcf7936 100644
--- a/arch/riscv/Kconfig.errata
+++ b/arch/riscv/Kconfig.errata
@@ -154,4 +154,14 @@ config ERRATA_THEAD_GHOSTWRITE
If you don't know what to do here, say "Y".
+config ERRATA_PICOHEART
+ bool "Picoheart errata"
+ depends on RISCV_ALTERNATIVE
+ help
+ All Picoheart errata Kconfig depend on this Kconfig. Disabling
+ this Kconfig will disable all Picoheart errata. Please say "Y"
+ here if your platform uses Picoheart CPU cores.
+
+ Otherwise, please say "N" here to avoid unnecessary overhead.
+
endmenu # "CPU errata selection"
diff --git a/arch/riscv/errata/Makefile b/arch/riscv/errata/Makefile
index 02a7a3335b1d..a36c5ce1ce7b 100644
--- a/arch/riscv/errata/Makefile
+++ b/arch/riscv/errata/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_ERRATA_ANDES) += andes/
obj-$(CONFIG_ERRATA_MIPS) += mips/
obj-$(CONFIG_ERRATA_SIFIVE) += sifive/
obj-$(CONFIG_ERRATA_THEAD) += thead/
+obj-$(CONFIG_ERRATA_PICOHEART) += picoheart/
diff --git a/arch/riscv/errata/picoheart/Makefile b/arch/riscv/errata/picoheart/Makefile
new file mode 100644
index 000000000000..6278c389b801
--- /dev/null
+++ b/arch/riscv/errata/picoheart/Makefile
@@ -0,0 +1,5 @@
+ifdef CONFIG_RISCV_ALTERNATIVE_EARLY
+CFLAGS_errata.o := -mcmodel=medany
+endif
+
+obj-y += errata.o
diff --git a/arch/riscv/errata/picoheart/errata.c b/arch/riscv/errata/picoheart/errata.c
new file mode 100644
index 000000000000..53b690878f78
--- /dev/null
+++ b/arch/riscv/errata/picoheart/errata.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2026 Picoheart (SG) Pte. Ltd.
+ *
+ * Author: Yicong Yang <yang.yicong@picoheart.com>
+ */
+
+#include <linux/cacheflush.h>
+#include <linux/cleanup.h>
+#include <linux/kernel.h>
+#include <linux/memory.h>
+#include <linux/string.h>
+#include <asm/alternative.h>
+#include <asm/errata_list.h>
+#include <asm/text-patching.h>
+#include <asm/vendor_extensions.h>
+#include <asm/vendorid_list.h>
+
+static u32 picoheart_errata_probe(unsigned int stage, unsigned long archid,
+ unsigned long impid)
+{
+ return 0;
+}
+
+void picoheart_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
+ unsigned long archid, unsigned long impid,
+ unsigned int stage)
+{
+ u32 cpu_req_errata = picoheart_errata_probe(stage, archid, impid);
+ struct alt_entry *alt;
+ void *oldptr, *altptr;
+ u32 tmp;
+
+ BUILD_BUG_ON(ERRATA_PICOHEART_NUMBER >= RISCV_VENDOR_EXT_ALTERNATIVES_BASE);
+
+ for (alt = begin; alt < end; alt++) {
+ if (alt->vendor_id != PICOHEART_VENDOR_ID ||
+ alt->patch_id >= ERRATA_PICOHEART_NUMBER)
+ continue;
+
+ tmp = (1U << alt->patch_id);
+ if (cpu_req_errata & tmp) {
+ oldptr = ALT_OLD_PTR(alt);
+ altptr = ALT_ALT_PTR(alt);
+
+ if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) {
+ memcpy(oldptr, altptr, alt->alt_len);
+ } else {
+ guard(mutex)(&text_mutex);
+ patch_text_nosync(oldptr, altptr, alt->alt_len);
+ }
+ }
+ }
+
+ if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
+ local_flush_icache_all();
+}
diff --git a/arch/riscv/include/asm/alternative.h b/arch/riscv/include/asm/alternative.h
index 8407d1d535b8..57298f21bb70 100644
--- a/arch/riscv/include/asm/alternative.h
+++ b/arch/riscv/include/asm/alternative.h
@@ -57,6 +57,9 @@ void sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
void thead_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
unsigned long archid, unsigned long impid,
unsigned int stage);
+void picoheart_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
+ unsigned long archid, unsigned long impid,
+ unsigned int stage);
void riscv_cpufeature_patch_func(struct alt_entry *begin, struct alt_entry *end,
unsigned int stage);
diff --git a/arch/riscv/include/asm/errata_list_vendors.h b/arch/riscv/include/asm/errata_list_vendors.h
index ec7eba373437..958e4f4624f7 100644
--- a/arch/riscv/include/asm/errata_list_vendors.h
+++ b/arch/riscv/include/asm/errata_list_vendors.h
@@ -26,4 +26,8 @@
#define ERRATA_MIPS_NUMBER 1
#endif
+#ifdef CONFIG_ERRATA_PICOHEART
+#define ERRATA_PICOHEART_NUMBER 0
+#endif
+
#endif /* ASM_ERRATA_LIST_VENDORS_H */
diff --git a/arch/riscv/include/asm/vendorid_list.h b/arch/riscv/include/asm/vendorid_list.h
index beaf9236dba7..dba770b8503c 100644
--- a/arch/riscv/include/asm/vendorid_list.h
+++ b/arch/riscv/include/asm/vendorid_list.h
@@ -10,6 +10,7 @@
#define MIPS_VENDOR_ID 0x127
#define SIFIVE_VENDOR_ID 0x489
#define THEAD_VENDOR_ID 0x5b7
+#define PICOHEART_VENDOR_ID 0x77d
#define QEMU_VIRT_VENDOR_ID 0x000
#define QEMU_VIRT_IMPL_ID 0x000
diff --git a/arch/riscv/kernel/alternative.c b/arch/riscv/kernel/alternative.c
index 104dc0862c5c..88639918ee7d 100644
--- a/arch/riscv/kernel/alternative.c
+++ b/arch/riscv/kernel/alternative.c
@@ -61,6 +61,11 @@ static void riscv_fill_cpu_mfr_info(struct cpu_manufacturer_info_t *cpu_mfr_info
case THEAD_VENDOR_ID:
cpu_mfr_info->patch_func = thead_errata_patch_func;
break;
+#endif
+#ifdef CONFIG_ERRATA_PICOHEART
+ case PICOHEART_VENDOR_ID:
+ cpu_mfr_info->patch_func = picoheart_errata_patch_func;
+ break;
#endif
default:
cpu_mfr_info->patch_func = NULL;
--
2.50.1 (Apple Git-155)
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 5/6] riscv: errata: picoheart: Add workaround for cbo.clean errata
2026-07-28 9:46 [PATCH v2 0/6] Add workarounds for Picoheart erratas Yicong Yang
` (3 preceding siblings ...)
2026-07-28 9:46 ` [PATCH v2 4/6] riscv: errata: Add init framework for picoheart errata Yicong Yang
@ 2026-07-28 9:46 ` Yicong Yang
2026-07-28 9:46 ` [PATCH v2 6/6] riscv: errata: picoheart: Add workaround for AMOCASQ errata Yicong Yang
5 siblings, 0 replies; 9+ messages in thread
From: Yicong Yang @ 2026-07-28 9:46 UTC (permalink / raw)
To: pjw, palmer, aou, linux-riscv
Cc: wangruikang, ganboing, geshijian, niehaitao, cuiyunhui,
yang.yicong
cbo.clean may fail to write back the cacheline in a few very corner
cases on the affected Picoheart SoCs. Since cbo.flush is not affected,
the problem could be solved by promoting cbo.clean to cbo.flush to
keep the data coherent. So Implement and register Picoheart specific
riscv_nonstd_cache_ops for all the kernel space cache maintenance
operations. Implement riscv_nonstd_cache_ops->wback with cbo.clean
while other callbacks with corresponding CBO operations.
This could solve the issue in the kernel space. For userspace, clear
the xenvcfg.CBCFE to trap the cbo.{clean, flush} and emulate
the cbo.clean with cbo.flush in the kernel space to avoid the issue.
Signed-off-by: Yicong Yang <yang.yicong@picoheart.com>
---
arch/riscv/Kconfig.errata | 12 ++
arch/riscv/errata/picoheart/errata.c | 159 +++++++++++++++++++++++++++
arch/riscv/include/asm/errata_list.h | 25 ++++-
arch/riscv/kernel/cpufeature.c | 3 +
arch/riscv/kernel/traps.c | 4 +
5 files changed, 202 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
index 374d7fcf7936..8ce5c0314321 100644
--- a/arch/riscv/Kconfig.errata
+++ b/arch/riscv/Kconfig.errata
@@ -164,4 +164,16 @@ config ERRATA_PICOHEART
Otherwise, please say "N" here to avoid unnecessary overhead.
+config ERRATA_PICOHEART_CBO_CLEAN
+ bool "Apply Picoheart cbo.clean errata"
+ depends on ERRATA_PICOHEART
+ select RISCV_NONSTANDARD_CACHE_OPS
+ default y
+ help
+ This will apply the cbo.clean errata workaround on the affected
+ Picoheart SoCs where cbo.clean instructions may fail to write back
+ the cacheline in few corner cases.
+
+ If you don't know what to do here, say "Y".
+
endmenu # "CPU errata selection"
diff --git a/arch/riscv/errata/picoheart/errata.c b/arch/riscv/errata/picoheart/errata.c
index 53b690878f78..21480d19c084 100644
--- a/arch/riscv/errata/picoheart/errata.c
+++ b/arch/riscv/errata/picoheart/errata.c
@@ -5,20 +5,179 @@
* Author: Yicong Yang <yang.yicong@picoheart.com>
*/
+#include <linux/align.h>
#include <linux/cacheflush.h>
#include <linux/cleanup.h>
+#include <linux/jump_label.h>
#include <linux/kernel.h>
#include <linux/memory.h>
+#include <linux/mm_types.h>
+#include <linux/mmap_lock.h>
+#include <linux/signal.h>
#include <linux/string.h>
+#include <asm/asm-extable.h>
#include <asm/alternative.h>
+#include <asm/cpufeature.h>
+#include <asm/dma-noncoherent.h>
#include <asm/errata_list.h>
+#include <asm/insn.h>
+#include <asm/insn-def.h>
#include <asm/text-patching.h>
+#include <asm/uaccess.h>
#include <asm/vendor_extensions.h>
#include <asm/vendorid_list.h>
+#ifdef CONFIG_ERRATA_PICOHEART_CBO_CLEAN
+
+static bool insn_is_cbo_clean_flush(u32 insn_buf)
+{
+ u32 rd, opcode, funct3, funct12;
+
+ /* CBO instructions don't have compressed variants */
+ if (GET_INSN_LENGTH(insn_buf) != 4)
+ return false;
+
+ rd = RV_EXTRACT_RD_REG(insn_buf);
+ opcode = insn_buf & __INSN_OPCODE_MASK;
+ funct3 = insn_buf & RV_INSN_FUNCT3_MASK;
+ funct12 = insn_buf & RV_INSN_FUNCT12_MASK;
+
+ if (rd != 0 || opcode != RVG_OPCODE_MISC_MEM ||
+ funct3 != RV_ENCODE_FUNCT3(CBO) ||
+ (funct12 != RV_ENCODE_FUNCT12(CBO_CLEAN) &&
+ funct12 != RV_ENCODE_FUNCT12(CBO_FLUSH)))
+ return false;
+
+ return true;
+}
+
+static int cbo_clean_fault_sicode(unsigned long addr)
+{
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+
+ guard(mmap_read_lock)(mm);
+ vma = vma_lookup(mm, addr);
+ if (!vma)
+ return SEGV_MAPERR;
+
+ return SEGV_ACCERR;
+}
+
+bool riscv_picoheart_illegal_insn_handler(struct pt_regs *regs)
+{
+ unsigned long insn = regs->badaddr;
+ unsigned long epc = regs->epc;
+ void __user *line_addr;
+ int ret = 0;
+ u64 addr;
+ u32 rs1;
+
+ if (!insn) {
+ if (get_insn(regs, epc, &insn))
+ return false;
+ }
+
+ if (!insn_is_cbo_clean_flush(insn))
+ return false;
+
+ rs1 = RV_EXTRACT_RS1_REG(insn);
+ addr = rs1 ? ((unsigned long *)regs)[rs1] : 0;
+ line_addr = (void __user *)ALIGN_DOWN(addr, riscv_cbom_block_size);
+
+ /*
+ * Check if the target address is within the valid userspace
+ * address range. Otherwise update the bad_cause to match the
+ * store page fault. See the comment below.
+ */
+ if (!access_ok(line_addr, riscv_cbom_block_size)) {
+ current->thread.bad_cause = EXC_STORE_PAGE_FAULT;
+ goto err_map;
+ }
+
+ __enable_user_access();
+ asm volatile("\n"
+ "1: \n"
+ CBO_FLUSH(%[addr])
+ "2: \n"
+ _ASM_EXTABLE_UACCESS_ERR(1b, 2b, %[err])
+ : [err] "+r" (ret)
+ : [addr] "r" (untagged_addr(addr))
+ : "memory");
+ __disable_user_access();
+
+ if (ret)
+ goto err_map;
+
+ regs->epc += GET_INSN_LENGTH(insn);
+ return true;
+
+err_map:
+ /*
+ * We'll reach here if the target address is invalid.
+ * cbo.{flush ,clean} on invalid address will cause
+ * store page fault, update the cause and badaddr.
+ */
+ regs->badaddr = addr;
+ regs->cause = current->thread.bad_cause;
+
+ /*
+ * In emulation of the cbo.clean, a SIGSEGV rather than
+ * a SIGILL should be issued if the target address is
+ * invalid. Use do_trap() to handle the signal delivery
+ * and related stuffs to make it analogous to the page
+ * fault.
+ */
+ do_trap(regs, SIGSEGV, cbo_clean_fault_sicode(untagged_addr(addr)),
+ untagged_addr(addr));
+
+ return true;
+}
+
+#endif /* CONFIG_ERRATA_PICOHEART_CBO_CLEAN */
+
+static void picoheart_errata_cache_wback(phys_addr_t paddr, size_t size)
+{
+ void *vaddr = phys_to_virt(paddr);
+
+ ALT_CMO_OP(FLUSH, vaddr, size, riscv_cbom_block_size);
+}
+
+/*
+ * The errata only affects the cbo.clean (wback) so use standard operations
+ * for other semantic.
+ */
+struct riscv_nonstd_cache_ops picoheart_errata_cmo_ops = {
+ .wback = &picoheart_errata_cache_wback,
+};
+
+DEFINE_STATIC_KEY_FALSE(has_picoheart_cbo_clean_errata);
+
+static void picoheart_errata_probe_cbo_clean(unsigned int stage,
+ unsigned long archid,
+ unsigned long impid)
+{
+ if (!IS_ENABLED(CONFIG_ERRATA_PICOHEART_CBO_CLEAN))
+ return;
+
+ if (stage != RISCV_ALTERNATIVES_BOOT)
+ return;
+
+ if (!riscv_isa_extension_available(NULL, ZICBOM))
+ return;
+
+ if (archid != 0x804a555049544552 || impid != 0x100)
+ return;
+
+ riscv_noncoherent_supported();
+ riscv_noncoherent_register_cache_ops(&picoheart_errata_cmo_ops);
+ static_branch_enable(&has_picoheart_cbo_clean_errata);
+}
+
static u32 picoheart_errata_probe(unsigned int stage, unsigned long archid,
unsigned long impid)
{
+ picoheart_errata_probe_cbo_clean(stage, archid, impid);
return 0;
}
diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
index 6694b5ccdcf8..7e31acae4e0a 100644
--- a/arch/riscv/include/asm/errata_list.h
+++ b/arch/riscv/include/asm/errata_list.h
@@ -117,6 +117,29 @@ asm volatile(ALTERNATIVE( \
#define THEAD_C9XX_RV_IRQ_PMU 17
#define THEAD_C9XX_CSR_SCOUNTEROF 0x5c5
-#endif /* __ASSEMBLER__ */
+#ifdef CONFIG_ERRATA_PICOHEART_CBO_CLEAN
+
+#include <linux/jump_label.h>
+
+DECLARE_STATIC_KEY_FALSE(has_picoheart_cbo_clean_errata);
+
+static inline bool riscv_has_picoheart_zicbom_errata(void)
+{
+ return static_branch_unlikely(&has_picoheart_cbo_clean_errata);
+}
+
+bool riscv_picoheart_illegal_insn_handler(struct pt_regs *regs);
+
+#else /* !CONFIG_ERRATA_PICOHEART_CBO_CLEAN */
+
+static inline bool riscv_has_picoheart_zicbom_errata(void) { return false; }
+static inline bool riscv_picoheart_illegal_insn_handler(struct pt_regs *regs)
+{
+ return false;
+}
+
+#endif /* CONFIG_ERRATA_PICOHEART_CBO_CLEAN */
+
+#endif /* __ASSEMBLY__ */
#endif
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 1fe647e03515..160809d7268d 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -1208,6 +1208,9 @@ void __init riscv_user_isa_enable(void)
if (!riscv_has_extension_unlikely(RISCV_ISA_EXT_ZICBOP) &&
any_cpu_has_zicbop)
pr_warn("Zicbop disabled as it is unavailable on some harts\n");
+
+ if (riscv_has_picoheart_zicbom_errata())
+ current->thread.envcfg &= ~ENVCFG_CBCFE;
}
#ifdef CONFIG_RISCV_ALTERNATIVE
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 8c62c771a656..8d0f8d3446b6 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -177,6 +177,10 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re
local_irq_enable();
handled = riscv_v_first_use_handler(regs);
+
+ if (!handled && riscv_has_picoheart_zicbom_errata())
+ handled = riscv_picoheart_illegal_insn_handler(regs);
+
if (!handled)
do_trap_error(regs, SIGILL, ILL_ILLOPC, regs->epc,
"Oops - illegal instruction");
--
2.50.1 (Apple Git-155)
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 6/6] riscv: errata: picoheart: Add workaround for AMOCASQ errata
2026-07-28 9:46 [PATCH v2 0/6] Add workarounds for Picoheart erratas Yicong Yang
` (4 preceding siblings ...)
2026-07-28 9:46 ` [PATCH v2 5/6] riscv: errata: picoheart: Add workaround for cbo.clean errata Yicong Yang
@ 2026-07-28 9:46 ` Yicong Yang
5 siblings, 0 replies; 9+ messages in thread
From: Yicong Yang @ 2026-07-28 9:46 UTC (permalink / raw)
To: pjw, palmer, aou, linux-riscv
Cc: wangruikang, ganboing, geshijian, niehaitao, cuiyunhui,
yang.yicong
Some Picoheart CPUs implement Zacas extension but lack support
for AMOCASQ PMA attribute. Thus makes the CASQ instruction de
facto unavailable. Since currently no ways to retrieve the PMA
information and the riscv kernel will declare cmpxchg128 support
if platform declare support of Zacas, the use of cmpxchg128 will
lead to PMA violation and crash the kernel. Add the errata
workaround to disable the use of cmpxchg128 on the affected CPUs.
Signed-off-by: Yicong Yang <yang.yicong@picoheart.com>
---
arch/riscv/Kconfig.errata | 12 ++++++++++++
arch/riscv/errata/picoheart/errata.c | 22 ++++++++++++++++++++++
arch/riscv/include/asm/cmpxchg.h | 2 +-
arch/riscv/include/asm/cpufeature.h | 8 ++++++++
arch/riscv/kernel/cpufeature.c | 13 ++++++++++++-
5 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
index 8ce5c0314321..16e37391d596 100644
--- a/arch/riscv/Kconfig.errata
+++ b/arch/riscv/Kconfig.errata
@@ -176,4 +176,16 @@ config ERRATA_PICOHEART_CBO_CLEAN
If you don't know what to do here, say "Y".
+config ERRATA_PICOHEART_AMOCASQ
+ bool "Apply Picoheart AMOCASQ errata"
+ depends on ERRATA_PICOHEART && RISCV_ISA_ZACAS
+ default y
+ help
+ Some Picoheart CPUs implement the Zacas extension but lack support
+ for AMOCASQ PMA attribute. Thus makes the CASQ instruction de facto
+ unavailable. Enable this errata workaround to disable the use of
+ CASQ in the kernel (cmpxchg128).
+
+ If you don't know what to do here, say "Y".
+
endmenu # "CPU errata selection"
diff --git a/arch/riscv/errata/picoheart/errata.c b/arch/riscv/errata/picoheart/errata.c
index 21480d19c084..0fb4cb41ab03 100644
--- a/arch/riscv/errata/picoheart/errata.c
+++ b/arch/riscv/errata/picoheart/errata.c
@@ -174,10 +174,32 @@ static void picoheart_errata_probe_cbo_clean(unsigned int stage,
static_branch_enable(&has_picoheart_cbo_clean_errata);
}
+static void picoheart_errata_probe_amocasq(unsigned int stage,
+ unsigned long archid,
+ unsigned long impid)
+{
+ if (!IS_ENABLED(CONFIG_ERRATA_PICOHEART_AMOCASQ))
+ return;
+
+ if (stage != RISCV_ALTERNATIVES_BOOT)
+ return;
+
+ if (!IS_ENABLED(CONFIG_RISCV_ISA_ZACAS) ||
+ !riscv_isa_extension_available(NULL, ZACAS))
+ return;
+
+ if (archid != 0x804a555049544552 || impid != 0x100)
+ return;
+
+ static_branch_disable(&cpus_support_cmpxchg128);
+}
+
static u32 picoheart_errata_probe(unsigned int stage, unsigned long archid,
unsigned long impid)
{
picoheart_errata_probe_cbo_clean(stage, archid, impid);
+ picoheart_errata_probe_amocasq(stage, archid, impid);
+
return 0;
}
diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index 8712cf9c69dc..5d51948116e6 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -320,7 +320,7 @@
#if defined(CONFIG_64BIT) && defined(CONFIG_RISCV_ISA_ZACAS) && defined(CONFIG_TOOLCHAIN_HAS_ZACAS)
-#define system_has_cmpxchg128() riscv_has_extension_unlikely(RISCV_ISA_EXT_ZACAS)
+#define system_has_cmpxchg128 system_has_cmpxchg128
union __u128_halves {
u128 full;
diff --git a/arch/riscv/include/asm/cpufeature.h b/arch/riscv/include/asm/cpufeature.h
index 739fcc84bf7b..f9d95cbf5abd 100644
--- a/arch/riscv/include/asm/cpufeature.h
+++ b/arch/riscv/include/asm/cpufeature.h
@@ -164,4 +164,12 @@ static inline bool cpu_supports_indirect_br_lp_instr(void)
riscv_has_extension_unlikely(RISCV_ISA_EXT_ZICFILP));
}
+DECLARE_STATIC_KEY_FALSE(cpus_support_cmpxchg128);
+
+static inline bool system_has_cmpxchg128(void)
+{
+ return riscv_has_extension_unlikely(RISCV_ISA_EXT_ZACAS) &&
+ static_branch_likely(&cpus_support_cmpxchg128);
+}
+
#endif
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 160809d7268d..45b00100d476 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -46,6 +46,9 @@ struct riscv_isainfo hart_isa[NR_CPUS];
u32 thead_vlenb_of;
+/* All the CPUs supports cmpxchg128 (CASQ*). */
+DEFINE_STATIC_KEY_FALSE(cpus_support_cmpxchg128);
+
/**
* riscv_isa_extension_base() - Get base extension word
*
@@ -317,6 +320,14 @@ static int riscv_cfiss_validate(const struct riscv_isa_ext_data *data,
return 0;
}
+static int riscv_ext_zacas_validate(const struct riscv_isa_ext_data *data,
+ const unsigned long *isa_bitmap)
+{
+ static_branch_enable(&cpus_support_cmpxchg128);
+
+ return 0;
+}
+
static const unsigned int riscv_a_exts[] = {
RISCV_ISA_EXT_ZAAMO,
RISCV_ISA_EXT_ZALRSC,
@@ -538,7 +549,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
__RISCV_ISA_EXT_DATA(zimop, RISCV_ISA_EXT_ZIMOP),
__RISCV_ISA_EXT_DATA(zaamo, RISCV_ISA_EXT_ZAAMO),
__RISCV_ISA_EXT_DATA(zabha, RISCV_ISA_EXT_ZABHA),
- __RISCV_ISA_EXT_DATA(zacas, RISCV_ISA_EXT_ZACAS),
+ __RISCV_ISA_EXT_DATA_VALIDATE(zacas, RISCV_ISA_EXT_ZACAS, riscv_ext_zacas_validate),
__RISCV_ISA_EXT_DATA(zalasr, RISCV_ISA_EXT_ZALASR),
__RISCV_ISA_EXT_DATA(zalrsc, RISCV_ISA_EXT_ZALRSC),
__RISCV_ISA_EXT_DATA(zawrs, RISCV_ISA_EXT_ZAWRS),
--
2.50.1 (Apple Git-155)
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/6] riscv: insn: Set sstatus.MXR when reading userspace instruction
2026-07-28 9:46 ` [PATCH v2 2/6] riscv: insn: Set sstatus.MXR when reading userspace instruction Yicong Yang
@ 2026-08-25 0:06 ` Paul Walmsley
2026-08-25 7:39 ` Yicong Yang
0 siblings, 1 reply; 9+ messages in thread
From: Paul Walmsley @ 2026-08-25 0:06 UTC (permalink / raw)
To: Yicong Yang
Cc: pjw, palmer, aou, linux-riscv, wangruikang, ganboing, geshijian,
niehaitao, cuiyunhui
Hi,
On Tue, 28 Jul 2026, Yicong Yang wrote:
> 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.
If this patch fixes a bug with the preceding patch, it would
better just to roll the fix into the original patch.
- Paul
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/6] riscv: insn: Set sstatus.MXR when reading userspace instruction
2026-08-25 0:06 ` Paul Walmsley
@ 2026-08-25 7:39 ` Yicong Yang
0 siblings, 0 replies; 9+ messages in thread
From: Yicong Yang @ 2026-08-25 7:39 UTC (permalink / raw)
To: Paul Walmsley
Cc: yang.yicong, palmer, aou, linux-riscv, wangruikang, ganboing,
geshijian, niehaitao, cuiyunhui
On 8/25/26 8:06 AM, Paul Walmsley wrote:
> Hi,
>
> On Tue, 28 Jul 2026, Yicong Yang wrote:
>
>> 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.
>
> If this patch fixes a bug with the preceding patch, it would
> better just to roll the fix into the original patch.
sure, will squash into previous one.
I used to split the refactor (preceding) and fix (current)
to separate patches for better review.
thanks.
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-08-25 7:39 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-28 9:46 [PATCH v2 0/6] Add workarounds for Picoheart erratas Yicong Yang
2026-07-28 9:46 ` [PATCH v2 1/6] riscv: Make get_insn public for instruction fault handling Yicong Yang
2026-07-28 9:46 ` [PATCH v2 2/6] riscv: insn: Set sstatus.MXR when reading userspace instruction Yicong Yang
2026-08-25 0:06 ` Paul Walmsley
2026-08-25 7:39 ` Yicong Yang
2026-07-28 9:46 ` [PATCH v2 3/6] riscv: insn: Support decoding of CBO instructions Yicong Yang
2026-07-28 9:46 ` [PATCH v2 4/6] riscv: errata: Add init framework for picoheart errata Yicong Yang
2026-07-28 9:46 ` [PATCH v2 5/6] riscv: errata: picoheart: Add workaround for cbo.clean errata Yicong Yang
2026-07-28 9:46 ` [PATCH v2 6/6] riscv: errata: picoheart: Add workaround for AMOCASQ errata Yicong Yang
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.