nds32: Fix the unaligned access handler
authorNickhu <nickhu@andestech.com>
Thu, 3 May 2018 02:15:56 +0000 (10:15 +0800)
committerGreentime Hu <greentime@andestech.com>
Wed, 23 May 2018 05:26:22 +0000 (13:26 +0800)
If the kernel config 'CONFIG_ALIGNMENT_TRAP' and the file
'/proc/sys/nds32/unaligned_access/enable' are set, the kernel
unaligned access handler does not handle correctly when the
value of immediate field is negative. This commit fixes the
unaligned access handler in kernel.

Signed-off-by: Nickhu <nickhu@andestech.com>
Reviewed-by: Greentime Hu <greentime@andestech.com>
Signed-off-by: Greentime Hu <greentime@andestech.com>
arch/nds32/mm/alignment.c

index e515f6f3d24736d7cf562d6d3a3ea39c1c45cdb9..e1aed9dc692dd3bac752720a82880de865e7cb2d 100644 (file)
@@ -19,7 +19,7 @@
 #define RA(inst)       (((inst) >> 15) & 0x1FUL)
 #define RB(inst)       (((inst) >> 10) & 0x1FUL)
 #define SV(inst)       (((inst) >> 8) & 0x3UL)
-#define IMM(inst)      (((inst) >> 0) & 0x3FFFUL)
+#define IMM(inst)      (((inst) >> 0) & 0x7FFFUL)
 
 #define RA3(inst)      (((inst) >> 3) & 0x7UL)
 #define RT3(inst)      (((inst) >> 6) & 0x7UL)
@@ -28,6 +28,9 @@
 #define RA5(inst)      (((inst) >> 0) & 0x1FUL)
 #define RT4(inst)      (((inst) >> 5) & 0xFUL)
 
+#define GET_IMMSVAL(imm_value) \
+       (((imm_value >> 14) & 0x1) ? (imm_value - 0x8000) : imm_value)
+
 #define __get8_data(val,addr,err)      \
        __asm__(                                        \
        "1:     lbi.bi  %1, [%2], #1\n"                 \
@@ -467,7 +470,7 @@ static inline int do_32(unsigned long inst, struct pt_regs *regs)
        }
 
        if (imm)
-               shift = IMM(inst) * len;
+               shift = GET_IMMSVAL(IMM(inst)) * len;
        else
                shift = *idx_to_addr(regs, RB(inst)) << SV(inst);