forked from Minki/linux
powerpc/sstep: Fix issues with set_cr0()
set_cr0() broke when we changed analyse_instr() to not modify the
register state. Instead of looking at regs->gpr[x] which has not
been updated yet, we need to look at op->val.
Fixes: 3cdfcbfd32
("powerpc: Change analyse_instr so it doesn't modify *regs")
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
c1fa0768a8
commit
ad47ff3e33
@ -944,9 +944,9 @@ NOKPROBE_SYMBOL(emulate_dcbz);
|
|||||||
: "r" (addr), "i" (-EFAULT), "0" (err))
|
: "r" (addr), "i" (-EFAULT), "0" (err))
|
||||||
|
|
||||||
static nokprobe_inline void set_cr0(const struct pt_regs *regs,
|
static nokprobe_inline void set_cr0(const struct pt_regs *regs,
|
||||||
struct instruction_op *op, int rd)
|
struct instruction_op *op)
|
||||||
{
|
{
|
||||||
long val = regs->gpr[rd];
|
long val = op->val;
|
||||||
|
|
||||||
op->type |= SETCC;
|
op->type |= SETCC;
|
||||||
op->ccval = (regs->ccr & 0x0fffffff) | ((regs->xer >> 3) & 0x10000000);
|
op->ccval = (regs->ccr & 0x0fffffff) | ((regs->xer >> 3) & 0x10000000);
|
||||||
@ -1326,7 +1326,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
|
|||||||
case 13: /* addic. */
|
case 13: /* addic. */
|
||||||
imm = (short) instr;
|
imm = (short) instr;
|
||||||
add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0);
|
add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0);
|
||||||
set_cr0(regs, op, rd);
|
set_cr0(regs, op);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case 14: /* addi */
|
case 14: /* addi */
|
||||||
@ -1397,13 +1397,13 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
|
|||||||
|
|
||||||
case 28: /* andi. */
|
case 28: /* andi. */
|
||||||
op->val = regs->gpr[rd] & (unsigned short) instr;
|
op->val = regs->gpr[rd] & (unsigned short) instr;
|
||||||
set_cr0(regs, op, ra);
|
set_cr0(regs, op);
|
||||||
goto logical_done_nocc;
|
goto logical_done_nocc;
|
||||||
|
|
||||||
case 29: /* andis. */
|
case 29: /* andis. */
|
||||||
imm = (unsigned short) instr;
|
imm = (unsigned short) instr;
|
||||||
op->val = regs->gpr[rd] & (imm << 16);
|
op->val = regs->gpr[rd] & (imm << 16);
|
||||||
set_cr0(regs, op, ra);
|
set_cr0(regs, op);
|
||||||
goto logical_done_nocc;
|
goto logical_done_nocc;
|
||||||
|
|
||||||
#ifdef __powerpc64__
|
#ifdef __powerpc64__
|
||||||
@ -2526,7 +2526,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
|
|||||||
|
|
||||||
logical_done:
|
logical_done:
|
||||||
if (instr & 1)
|
if (instr & 1)
|
||||||
set_cr0(regs, op, ra);
|
set_cr0(regs, op);
|
||||||
logical_done_nocc:
|
logical_done_nocc:
|
||||||
op->reg = ra;
|
op->reg = ra;
|
||||||
op->type |= SETREG;
|
op->type |= SETREG;
|
||||||
@ -2534,7 +2534,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
|
|||||||
|
|
||||||
arith_done:
|
arith_done:
|
||||||
if (instr & 1)
|
if (instr & 1)
|
||||||
set_cr0(regs, op, rd);
|
set_cr0(regs, op);
|
||||||
compute_done:
|
compute_done:
|
||||||
op->reg = rd;
|
op->reg = rd;
|
||||||
op->type |= SETREG;
|
op->type |= SETREG;
|
||||||
|
Loading…
Reference in New Issue
Block a user