diff options
Diffstat (limited to 'arch/powerpc/lib/sstep.c')
| -rw-r--r-- | arch/powerpc/lib/sstep.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index 7e8ded051b5b..4aae0c387645 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c | |||
| @@ -54,7 +54,7 @@ static int __kprobes branch_taken(unsigned int instr, struct pt_regs *regs) | |||
| 54 | */ | 54 | */ |
| 55 | int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | 55 | int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) |
| 56 | { | 56 | { |
| 57 | unsigned int opcode, rd; | 57 | unsigned int opcode, rs, rb, rd, spr; |
| 58 | unsigned long int imm; | 58 | unsigned long int imm; |
| 59 | 59 | ||
| 60 | opcode = instr >> 26; | 60 | opcode = instr >> 26; |
| @@ -152,6 +152,49 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | |||
| 152 | regs->nip &= 0xffffffffUL; | 152 | regs->nip &= 0xffffffffUL; |
| 153 | return 1; | 153 | return 1; |
| 154 | #endif | 154 | #endif |
| 155 | case 0x26: /* mfcr */ | ||
| 156 | regs->gpr[rd] = regs->ccr; | ||
| 157 | regs->gpr[rd] &= 0xffffffffUL; | ||
| 158 | goto mtspr_out; | ||
| 159 | case 0x2a6: /* mfspr */ | ||
| 160 | spr = (instr >> 11) & 0x3ff; | ||
| 161 | switch (spr) { | ||
| 162 | case 0x20: /* mfxer */ | ||
| 163 | regs->gpr[rd] = regs->xer; | ||
| 164 | regs->gpr[rd] &= 0xffffffffUL; | ||
| 165 | goto mtspr_out; | ||
| 166 | case 0x100: /* mflr */ | ||
| 167 | regs->gpr[rd] = regs->link; | ||
| 168 | goto mtspr_out; | ||
| 169 | case 0x120: /* mfctr */ | ||
| 170 | regs->gpr[rd] = regs->ctr; | ||
| 171 | goto mtspr_out; | ||
| 172 | } | ||
| 173 | break; | ||
| 174 | case 0x378: /* orx */ | ||
| 175 | rs = (instr >> 21) & 0x1f; | ||
| 176 | rb = (instr >> 11) & 0x1f; | ||
| 177 | if (rs == rb) { /* mr */ | ||
| 178 | rd = (instr >> 16) & 0x1f; | ||
| 179 | regs->gpr[rd] = regs->gpr[rs]; | ||
| 180 | goto mtspr_out; | ||
| 181 | } | ||
| 182 | break; | ||
| 183 | case 0x3a6: /* mtspr */ | ||
| 184 | spr = (instr >> 11) & 0x3ff; | ||
| 185 | switch (spr) { | ||
| 186 | case 0x20: /* mtxer */ | ||
| 187 | regs->xer = (regs->gpr[rd] & 0xffffffffUL); | ||
| 188 | goto mtspr_out; | ||
| 189 | case 0x100: /* mtlr */ | ||
| 190 | regs->link = regs->gpr[rd]; | ||
| 191 | goto mtspr_out; | ||
| 192 | case 0x120: /* mtctr */ | ||
| 193 | regs->ctr = regs->gpr[rd]; | ||
| 194 | mtspr_out: | ||
| 195 | regs->nip += 4; | ||
| 196 | return 1; | ||
| 197 | } | ||
| 155 | } | 198 | } |
| 156 | } | 199 | } |
| 157 | return 0; | 200 | return 0; |
