diff options
author | Paul Mackerras <paulus@samba.org> | 2014-07-19 03:47:57 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-07-22 01:55:51 -0400 |
commit | e698b9667879b79e479cc985f9d74ecf126e343e (patch) | |
tree | 6072870769c85d687c774bd8c532ad9fb1a172f8 /arch/powerpc/lib | |
parent | bd6ba3518fcb2539d83163a3f486d09411bc535d (diff) |
powerpc: Fix bugs in emulate_step()
This fixes some bugs in emulate_step(). First, the setting of the carry
bit for the arithmetic right-shift instructions was not correct on 64-bit
machines because we were masking with a mask of type int rather than
unsigned long. Secondly, the sld (shift left doubleword) instruction was
using the wrong instruction field for the register containing the shift
count.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/lib')
-rw-r--r-- | arch/powerpc/lib/sstep.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index 412dd46dd0b7..5c09f365c842 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c | |||
@@ -1198,7 +1198,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | |||
1198 | sh = regs->gpr[rb] & 0x3f; | 1198 | sh = regs->gpr[rb] & 0x3f; |
1199 | ival = (signed int) regs->gpr[rd]; | 1199 | ival = (signed int) regs->gpr[rd]; |
1200 | regs->gpr[ra] = ival >> (sh < 32 ? sh : 31); | 1200 | regs->gpr[ra] = ival >> (sh < 32 ? sh : 31); |
1201 | if (ival < 0 && (sh >= 32 || (ival & ((1 << sh) - 1)) != 0)) | 1201 | if (ival < 0 && (sh >= 32 || (ival & ((1ul << sh) - 1)) != 0)) |
1202 | regs->xer |= XER_CA; | 1202 | regs->xer |= XER_CA; |
1203 | else | 1203 | else |
1204 | regs->xer &= ~XER_CA; | 1204 | regs->xer &= ~XER_CA; |
@@ -1208,7 +1208,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | |||
1208 | sh = rb; | 1208 | sh = rb; |
1209 | ival = (signed int) regs->gpr[rd]; | 1209 | ival = (signed int) regs->gpr[rd]; |
1210 | regs->gpr[ra] = ival >> sh; | 1210 | regs->gpr[ra] = ival >> sh; |
1211 | if (ival < 0 && (ival & ((1 << sh) - 1)) != 0) | 1211 | if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0) |
1212 | regs->xer |= XER_CA; | 1212 | regs->xer |= XER_CA; |
1213 | else | 1213 | else |
1214 | regs->xer &= ~XER_CA; | 1214 | regs->xer &= ~XER_CA; |
@@ -1216,7 +1216,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | |||
1216 | 1216 | ||
1217 | #ifdef __powerpc64__ | 1217 | #ifdef __powerpc64__ |
1218 | case 27: /* sld */ | 1218 | case 27: /* sld */ |
1219 | sh = regs->gpr[rd] & 0x7f; | 1219 | sh = regs->gpr[rb] & 0x7f; |
1220 | if (sh < 64) | 1220 | if (sh < 64) |
1221 | regs->gpr[ra] = regs->gpr[rd] << sh; | 1221 | regs->gpr[ra] = regs->gpr[rd] << sh; |
1222 | else | 1222 | else |
@@ -1235,7 +1235,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | |||
1235 | sh = regs->gpr[rb] & 0x7f; | 1235 | sh = regs->gpr[rb] & 0x7f; |
1236 | ival = (signed long int) regs->gpr[rd]; | 1236 | ival = (signed long int) regs->gpr[rd]; |
1237 | regs->gpr[ra] = ival >> (sh < 64 ? sh : 63); | 1237 | regs->gpr[ra] = ival >> (sh < 64 ? sh : 63); |
1238 | if (ival < 0 && (sh >= 64 || (ival & ((1 << sh) - 1)) != 0)) | 1238 | if (ival < 0 && (sh >= 64 || (ival & ((1ul << sh) - 1)) != 0)) |
1239 | regs->xer |= XER_CA; | 1239 | regs->xer |= XER_CA; |
1240 | else | 1240 | else |
1241 | regs->xer &= ~XER_CA; | 1241 | regs->xer &= ~XER_CA; |
@@ -1246,7 +1246,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | |||
1246 | sh = rb | ((instr & 2) << 4); | 1246 | sh = rb | ((instr & 2) << 4); |
1247 | ival = (signed long int) regs->gpr[rd]; | 1247 | ival = (signed long int) regs->gpr[rd]; |
1248 | regs->gpr[ra] = ival >> sh; | 1248 | regs->gpr[ra] = ival >> sh; |
1249 | if (ival < 0 && (ival & ((1 << sh) - 1)) != 0) | 1249 | if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0) |
1250 | regs->xer |= XER_CA; | 1250 | regs->xer |= XER_CA; |
1251 | else | 1251 | else |
1252 | regs->xer &= ~XER_CA; | 1252 | regs->xer &= ~XER_CA; |