1 /* 2 * Single-step support. 3 * 4 * Copyright (C) 2004 Paul Mackerras <paulus@au.ibm.com>, IBM 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 #include <linux/kernel.h> 12 #include <linux/kprobes.h> 13 #include <linux/ptrace.h> 14 #include <asm/sstep.h> 15 #include <asm/processor.h> 16 17 extern char system_call_common[]; 18 19 #ifdef CONFIG_PPC64 20 /* Bits in SRR1 that are copied from MSR */ 21 #define MSR_MASK 0xffffffff87c0ffffUL 22 #else 23 #define MSR_MASK 0x87c0ffff 24 #endif 25 26 /* 27 * Determine whether a conditional branch instruction would branch. 28 */ 29 static int __kprobes branch_taken(unsigned int instr, struct pt_regs *regs) 30 { 31 unsigned int bo = (instr >> 21) & 0x1f; 32 unsigned int bi; 33 34 if ((bo & 4) == 0) { 35 /* decrement counter */ 36 --regs->ctr; 37 if (((bo >> 1) & 1) ^ (regs->ctr == 0)) 38 return 0; 39 } 40 if ((bo & 0x10) == 0) { 41 /* check bit from CR */ 42 bi = (instr >> 16) & 0x1f; 43 if (((regs->ccr >> (31 - bi)) & 1) != ((bo >> 3) & 1)) 44 return 0; 45 } 46 return 1; 47 } 48 49 /* 50 * Emulate instructions that cause a transfer of control. 51 * Returns 1 if the step was emulated, 0 if not, 52 * or -1 if the instruction is one that should not be stepped, 53 * such as an rfid, or a mtmsrd that would clear MSR_RI. 54 */ 55 int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) 56 { 57 unsigned int opcode, rs, rb, rd, spr; 58 unsigned long int imm; 59 60 opcode = instr >> 26; 61 switch (opcode) { 62 case 16: /* bc */ 63 imm = (signed short)(instr & 0xfffc); 64 if ((instr & 2) == 0) 65 imm += regs->nip; 66 regs->nip += 4; 67 if ((regs->msr & MSR_SF) == 0) 68 regs->nip &= 0xffffffffUL; 69 if (instr & 1) 70 regs->link = regs->nip; 71 if (branch_taken(instr, regs)) 72 regs->nip = imm; 73 return 1; 74 #ifdef CONFIG_PPC64 75 case 17: /* sc */ 76 /* 77 * N.B. this uses knowledge about how the syscall 78 * entry code works. If that is changed, this will 79 * need to be changed also. 80 */ 81 regs->gpr[9] = regs->gpr[13]; 82 regs->gpr[11] = regs->nip + 4; 83 regs->gpr[12] = regs->msr & MSR_MASK; 84 regs->gpr[13] = (unsigned long) get_paca(); 85 regs->nip = (unsigned long) &system_call_common; 86 regs->msr = MSR_KERNEL; 87 return 1; 88 #endif 89 case 18: /* b */ 90 imm = instr & 0x03fffffc; 91 if (imm & 0x02000000) 92 imm -= 0x04000000; 93 if ((instr & 2) == 0) 94 imm += regs->nip; 95 if (instr & 1) { 96 regs->link = regs->nip + 4; 97 if ((regs->msr & MSR_SF) == 0) 98 regs->link &= 0xffffffffUL; 99 } 100 if ((regs->msr & MSR_SF) == 0) 101 imm &= 0xffffffffUL; 102 regs->nip = imm; 103 return 1; 104 case 19: 105 switch (instr & 0x7fe) { 106 case 0x20: /* bclr */ 107 case 0x420: /* bcctr */ 108 imm = (instr & 0x400)? regs->ctr: regs->link; 109 regs->nip += 4; 110 if ((regs->msr & MSR_SF) == 0) { 111 regs->nip &= 0xffffffffUL; 112 imm &= 0xffffffffUL; 113 } 114 if (instr & 1) 115 regs->link = regs->nip; 116 if (branch_taken(instr, regs)) 117 regs->nip = imm; 118 return 1; 119 case 0x24: /* rfid, scary */ 120 return -1; 121 } 122 case 31: 123 rd = (instr >> 21) & 0x1f; 124 switch (instr & 0x7fe) { 125 case 0xa6: /* mfmsr */ 126 regs->gpr[rd] = regs->msr & MSR_MASK; 127 regs->nip += 4; 128 if ((regs->msr & MSR_SF) == 0) 129 regs->nip &= 0xffffffffUL; 130 return 1; 131 case 0x124: /* mtmsr */ 132 imm = regs->gpr[rd]; 133 if ((imm & MSR_RI) == 0) 134 /* can't step mtmsr that would clear MSR_RI */ 135 return -1; 136 regs->msr = imm; 137 regs->nip += 4; 138 return 1; 139 #ifdef CONFIG_PPC64 140 case 0x164: /* mtmsrd */ 141 /* only MSR_EE and MSR_RI get changed if bit 15 set */ 142 /* mtmsrd doesn't change MSR_HV and MSR_ME */ 143 imm = (instr & 0x10000)? 0x8002: 0xefffffffffffefffUL; 144 imm = (regs->msr & MSR_MASK & ~imm) 145 | (regs->gpr[rd] & imm); 146 if ((imm & MSR_RI) == 0) 147 /* can't step mtmsrd that would clear MSR_RI */ 148 return -1; 149 regs->msr = imm; 150 regs->nip += 4; 151 if ((imm & MSR_SF) == 0) 152 regs->nip &= 0xffffffffUL; 153 return 1; 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 } 198 } 199 } 200 return 0; 201 } 202