diff options
author | Nickhu <nickhu@andestech.com> | 2018-05-03 10:15:56 +0800 |
---|---|---|
committer | Greentime Hu <greentime@andestech.com> | 2018-05-23 13:26:22 +0800 |
commit | 1613de8a785d21b3aac73d2a2e640b66d514393b (patch) | |
tree | 0fcdfcff3e72c84871b202c5ef4a132a5ae5cbe7 /arch | |
parent | b3a75846a5cfbea137e2810b2bf9407141e70feb (diff) | |
download | linux-1613de8a785d21b3aac73d2a2e640b66d514393b.tar.gz linux-1613de8a785d21b3aac73d2a2e640b66d514393b.tar.bz2 linux-1613de8a785d21b3aac73d2a2e640b66d514393b.zip |
nds32: Fix the unaligned access handler
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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/nds32/mm/alignment.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/arch/nds32/mm/alignment.c b/arch/nds32/mm/alignment.c index e515f6f3d247..e1aed9dc692d 100644 --- a/arch/nds32/mm/alignment.c +++ b/arch/nds32/mm/alignment.c @@ -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); |