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