Unverified Commit 85f79dec authored by Palmer Dabbelt's avatar Palmer Dabbelt
Browse files

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: default avatarZong Li <zong.li@sifive.com>
Signed-off-by: default avatarNylon 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: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parents bafa451a 7b30b1b0
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -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);