[PATCH] riscv: misaligned: Restore epc in error path
Zishun Yi
vulab at iscas.ac.cn
Mon Mar 23 10:28:26 PDT 2026
In handle_scalar_misaligned_{store, load}, regs->epc is temporarily set
to 0. While it is properly restored in the instruction decoding error
path, it is not restored in the subsequent error paths. This causes the
epc to be corrupted.
Fix this by restoring regs->epc in the unsupported fp and
copy_{from,to}_user error paths.
Fixes: 7c586a555a48 ("riscv: add floating point insn support to misaligned access emulation")
Fixes: 441381506ba7 ("riscv: misaligned: remove CONFIG_RISCV_M_MODE specific code")
Signed-off-by: Zishun Yi <vulab at iscas.ac.cn>
---
To be honest, I am not entirely sure about the purpose of setting
regs->epc = 0 early in these functions. I suspect that simply removing
this line might be a better fix.
arch/riscv/kernel/traps_misaligned.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/arch/riscv/kernel/traps_misaligned.c b/arch/riscv/kernel/traps_misaligned.c
index 2a27d3ff4ac6..24f898853bba 100644
--- a/arch/riscv/kernel/traps_misaligned.c
+++ b/arch/riscv/kernel/traps_misaligned.c
@@ -307,13 +307,17 @@ static int handle_scalar_misaligned_load(struct pt_regs *regs)
return -1;
}
- if (!IS_ENABLED(CONFIG_FPU) && fp)
+ if (!IS_ENABLED(CONFIG_FPU) && fp) {
+ regs->epc = epc;
return -EOPNOTSUPP;
+ }
val.data_u64 = 0;
if (user_mode(regs)) {
- if (copy_from_user(&val, (u8 __user *)addr, len))
+ if (copy_from_user(&val, (u8 __user *)addr, len)) {
+ regs->epc = epc;
return -1;
+ }
} else {
memcpy(&val, (u8 *)addr, len);
}
@@ -409,12 +413,16 @@ static int handle_scalar_misaligned_store(struct pt_regs *regs)
return -1;
}
- if (!IS_ENABLED(CONFIG_FPU) && fp)
+ if (!IS_ENABLED(CONFIG_FPU) && fp) {
+ regs->epc = epc;
return -EOPNOTSUPP;
+ }
if (user_mode(regs)) {
- if (copy_to_user((u8 __user *)addr, &val, len))
+ if (copy_to_user((u8 __user *)addr, &val, len)) {
+ regs->epc = epc;
return -1;
+ }
} else {
memcpy((u8 *)addr, &val, len);
}
--
2.51.2
More information about the linux-riscv
mailing list