Merge patch series "riscv: misaligned: Add ZCB handling and fix sleeping function"

Nylon Chen <nylon.chen@sifive.com> says:

1. Adds support for ZCB compressed instructions (C.LHU, C.LH, C.SH).

2. Fixes a bug where copy_from/to_user() calls in non-sleepable contexts
triggered attempts to sleep.

Signed-off-by: Zong Li <zong.li@sifive.com>
Signed-off-by: Nylon Chen nylon.chen@sifive.com

Nylon Chen (2):
  riscv: misaligned: Add handling for ZCB instructions
  riscv: misaligned: fix sleeping function called during misaligned
    access handling

* b4-shazam-merge:
  riscv: misaligned: fix sleeping function called during misaligned access handling
  riscv: misaligned: Add handling for ZCB instructions

Link: https://lore.kernel.org/r/20250411073850.3699180-1-nylon.chen@sifive.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
Palmer Dabbelt 2025-04-18 10:51:58 -07:00
commit 85f79dece5
No known key found for this signature in database
GPG Key ID: EF4CA1502CCBAB41

View File

@ -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;
@ -441,7 +455,7 @@ static int handle_scalar_misaligned_load(struct pt_regs *regs)
val.data_u64 = 0;
if (user_mode(regs)) {
if (copy_from_user(&val, (u8 __user *)addr, len))
if (copy_from_user_nofault(&val, (u8 __user *)addr, len))
return -1;
} else {
memcpy(&val, (u8 *)addr, len);
@ -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;
@ -539,7 +556,7 @@ static int handle_scalar_misaligned_store(struct pt_regs *regs)
return -EOPNOTSUPP;
if (user_mode(regs)) {
if (copy_to_user((u8 __user *)addr, &val, len))
if (copy_to_user_nofault((u8 __user *)addr, &val, len))
return -1;
} else {
memcpy((u8 *)addr, &val, len);