Skip to content

Commit 85f79de

Browse files
Merge patch series "riscv: misaligned: Add ZCB handling and fix sleeping function"
Nylon Chen <[email protected]> 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 <[email protected]> Signed-off-by: Nylon Chen [email protected] 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/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
2 parents bafa451 + 7b30b1b commit 85f79de

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

arch/riscv/kernel/traps_misaligned.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,13 @@
8888
#define INSN_MATCH_C_FSWSP 0xe002
8989
#define INSN_MASK_C_FSWSP 0xe003
9090

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

93100
#if defined(CONFIG_64BIT)
@@ -431,6 +438,13 @@ static int handle_scalar_misaligned_load(struct pt_regs *regs)
431438
fp = 1;
432439
len = 4;
433440
#endif
441+
} else if ((insn & INSN_MASK_C_LHU) == INSN_MATCH_C_LHU) {
442+
len = 2;
443+
insn = RVC_RS2S(insn) << SH_RD;
444+
} else if ((insn & INSN_MASK_C_LH) == INSN_MATCH_C_LH) {
445+
len = 2;
446+
shift = 8 * (sizeof(ulong) - len);
447+
insn = RVC_RS2S(insn) << SH_RD;
434448
} else {
435449
regs->epc = epc;
436450
return -1;
@@ -441,7 +455,7 @@ static int handle_scalar_misaligned_load(struct pt_regs *regs)
441455

442456
val.data_u64 = 0;
443457
if (user_mode(regs)) {
444-
if (copy_from_user(&val, (u8 __user *)addr, len))
458+
if (copy_from_user_nofault(&val, (u8 __user *)addr, len))
445459
return -1;
446460
} else {
447461
memcpy(&val, (u8 *)addr, len);
@@ -530,6 +544,9 @@ static int handle_scalar_misaligned_store(struct pt_regs *regs)
530544
len = 4;
531545
val.data_ulong = GET_F32_RS2C(insn, regs);
532546
#endif
547+
} else if ((insn & INSN_MASK_C_SH) == INSN_MATCH_C_SH) {
548+
len = 2;
549+
val.data_ulong = GET_RS2S(insn, regs);
533550
} else {
534551
regs->epc = epc;
535552
return -1;
@@ -539,7 +556,7 @@ static int handle_scalar_misaligned_store(struct pt_regs *regs)
539556
return -EOPNOTSUPP;
540557

541558
if (user_mode(regs)) {
542-
if (copy_to_user((u8 __user *)addr, &val, len))
559+
if (copy_to_user_nofault((u8 __user *)addr, &val, len))
543560
return -1;
544561
} else {
545562
memcpy((u8 *)addr, &val, len);

0 commit comments

Comments
 (0)