Skip to content

Commit 1c49463

Browse files
nylon7jfvogel
authored andcommitted
riscv: misaligned: Add handling for ZCB instructions
[ Upstream commit eb16b37 ] 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: 956d705 ("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> (cherry picked from commit 126be03494f2f9d3352910885e28a0f89f2aa576) Signed-off-by: Jack Vogel <jack.vogel@oracle.com>
1 parent ee9cf8f commit 1c49463

File tree

1 file changed

+17
-0
lines changed

1 file changed

+17
-0
lines changed

arch/riscv/kernel/traps_misaligned.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@
8787
#define INSN_MATCH_C_FSWSP 0xe002
8888
#define INSN_MASK_C_FSWSP 0xe003
8989

90+
#define INSN_MATCH_C_LHU 0x8400
91+
#define INSN_MASK_C_LHU 0xfc43
92+
#define INSN_MATCH_C_LH 0x8440
93+
#define INSN_MASK_C_LH 0xfc43
94+
#define INSN_MATCH_C_SH 0x8c00
95+
#define INSN_MASK_C_SH 0xfc43
96+
9097
#define INSN_LEN(insn) ((((insn) & 0x3) < 0x3) ? 2 : 4)
9198

9299
#if defined(CONFIG_64BIT)
@@ -405,6 +412,13 @@ int handle_misaligned_load(struct pt_regs *regs)
405412
fp = 1;
406413
len = 4;
407414
#endif
415+
} else if ((insn & INSN_MASK_C_LHU) == INSN_MATCH_C_LHU) {
416+
len = 2;
417+
insn = RVC_RS2S(insn) << SH_RD;
418+
} else if ((insn & INSN_MASK_C_LH) == INSN_MATCH_C_LH) {
419+
len = 2;
420+
shift = 8 * (sizeof(ulong) - len);
421+
insn = RVC_RS2S(insn) << SH_RD;
408422
} else {
409423
regs->epc = epc;
410424
return -1;
@@ -504,6 +518,9 @@ int handle_misaligned_store(struct pt_regs *regs)
504518
len = 4;
505519
val.data_ulong = GET_F32_RS2C(insn, regs);
506520
#endif
521+
} else if ((insn & INSN_MASK_C_SH) == INSN_MATCH_C_SH) {
522+
len = 2;
523+
val.data_ulong = GET_RS2S(insn, regs);
507524
} else {
508525
regs->epc = epc;
509526
return -1;

0 commit comments

Comments
 (0)