| From fef354f790cae05caa33c95ca3fe926fdd65f9f6 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 11 Apr 2025 15:38:49 +0800 |
| Subject: riscv: misaligned: Add handling for ZCB instructions |
| |
| From: Nylon Chen <nylon.chen@sifive.com> |
| |
| [ Upstream commit eb16b3727c05ed36420c90eca1e8f0e279514c1c ] |
| |
| Add support for the Zcb extension's compressed half-word instructions |
| (C.LHU, C.LH, and C.SH) in the RISC-V misaligned access trap handler. |
| |
| Signed-off-by: Zong Li <zong.li@sifive.com> |
| Signed-off-by: Nylon Chen <nylon.chen@sifive.com> |
| Fixes: 956d705dd279 ("riscv: Unaligned load/store handling for M_MODE") |
| Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com> |
| Link: https://lore.kernel.org/r/20250411073850.3699180-2-nylon.chen@sifive.com |
| Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| arch/riscv/kernel/traps_misaligned.c | 17 +++++++++++++++++ |
| 1 file changed, 17 insertions(+) |
| |
| diff --git a/arch/riscv/kernel/traps_misaligned.c b/arch/riscv/kernel/traps_misaligned.c |
| index 4354c87c0376f..dde5d11dc1b50 100644 |
| --- a/arch/riscv/kernel/traps_misaligned.c |
| +++ b/arch/riscv/kernel/traps_misaligned.c |
| @@ -88,6 +88,13 @@ |
| #define INSN_MATCH_C_FSWSP 0xe002 |
| #define INSN_MASK_C_FSWSP 0xe003 |
| |
| +#define INSN_MATCH_C_LHU 0x8400 |
| +#define INSN_MASK_C_LHU 0xfc43 |
| +#define INSN_MATCH_C_LH 0x8440 |
| +#define INSN_MASK_C_LH 0xfc43 |
| +#define INSN_MATCH_C_SH 0x8c00 |
| +#define INSN_MASK_C_SH 0xfc43 |
| + |
| #define INSN_LEN(insn) ((((insn) & 0x3) < 0x3) ? 2 : 4) |
| |
| #if defined(CONFIG_64BIT) |
| @@ -431,6 +438,13 @@ static int handle_scalar_misaligned_load(struct pt_regs *regs) |
| fp = 1; |
| len = 4; |
| #endif |
| + } else if ((insn & INSN_MASK_C_LHU) == INSN_MATCH_C_LHU) { |
| + len = 2; |
| + insn = RVC_RS2S(insn) << SH_RD; |
| + } else if ((insn & INSN_MASK_C_LH) == INSN_MATCH_C_LH) { |
| + len = 2; |
| + shift = 8 * (sizeof(ulong) - len); |
| + insn = RVC_RS2S(insn) << SH_RD; |
| } else { |
| regs->epc = epc; |
| return -1; |
| @@ -530,6 +544,9 @@ static int handle_scalar_misaligned_store(struct pt_regs *regs) |
| len = 4; |
| val.data_ulong = GET_F32_RS2C(insn, regs); |
| #endif |
| + } else if ((insn & INSN_MASK_C_SH) == INSN_MATCH_C_SH) { |
| + len = 2; |
| + val.data_ulong = GET_RS2S(insn, regs); |
| } else { |
| regs->epc = epc; |
| return -1; |
| -- |
| 2.39.5 |
| |