aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/kprobes.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/kprobes.c')
-rw-r--r--arch/sh/kernel/kprobes.c100
1 files changed, 50 insertions, 50 deletions
diff --git a/arch/sh/kernel/kprobes.c b/arch/sh/kernel/kprobes.c
index 4049d99f76e..1208b09e95c 100644
--- a/arch/sh/kernel/kprobes.c
+++ b/arch/sh/kernel/kprobes.c
@@ -20,9 +20,9 @@
20DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 20DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
21DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 21DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
22 22
23static struct kprobe saved_current_opcode; 23static DEFINE_PER_CPU(struct kprobe, saved_current_opcode);
24static struct kprobe saved_next_opcode; 24static DEFINE_PER_CPU(struct kprobe, saved_next_opcode);
25static struct kprobe saved_next_opcode2; 25static DEFINE_PER_CPU(struct kprobe, saved_next_opcode2);
26 26
27#define OPCODE_JMP(x) (((x) & 0xF0FF) == 0x402b) 27#define OPCODE_JMP(x) (((x) & 0xF0FF) == 0x402b)
28#define OPCODE_JSR(x) (((x) & 0xF0FF) == 0x400b) 28#define OPCODE_JSR(x) (((x) & 0xF0FF) == 0x400b)
@@ -102,16 +102,21 @@ int __kprobes kprobe_handle_illslot(unsigned long pc)
102 102
103void __kprobes arch_remove_kprobe(struct kprobe *p) 103void __kprobes arch_remove_kprobe(struct kprobe *p)
104{ 104{
105 if (saved_next_opcode.addr != 0x0) { 105 struct kprobe *saved = &__get_cpu_var(saved_next_opcode);
106
107 if (saved->addr) {
106 arch_disarm_kprobe(p); 108 arch_disarm_kprobe(p);
107 arch_disarm_kprobe(&saved_next_opcode); 109 arch_disarm_kprobe(saved);
108 saved_next_opcode.addr = 0x0; 110
109 saved_next_opcode.opcode = 0x0; 111 saved->addr = NULL;
110 112 saved->opcode = 0;
111 if (saved_next_opcode2.addr != 0x0) { 113
112 arch_disarm_kprobe(&saved_next_opcode2); 114 saved = &__get_cpu_var(saved_next_opcode2);
113 saved_next_opcode2.addr = 0x0; 115 if (saved->addr) {
114 saved_next_opcode2.opcode = 0x0; 116 arch_disarm_kprobe(saved);
117
118 saved->addr = NULL;
119 saved->opcode = 0;
115 } 120 }
116 } 121 }
117} 122}
@@ -141,57 +146,59 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
141 */ 146 */
142static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) 147static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
143{ 148{
144 kprobe_opcode_t *addr = NULL; 149 __get_cpu_var(saved_current_opcode).addr = (kprobe_opcode_t *)regs->pc;
145 saved_current_opcode.addr = (kprobe_opcode_t *) (regs->pc);
146 addr = saved_current_opcode.addr;
147 150
148 if (p != NULL) { 151 if (p != NULL) {
152 struct kprobe *op1, *op2;
153
149 arch_disarm_kprobe(p); 154 arch_disarm_kprobe(p);
150 155
156 op1 = &__get_cpu_var(saved_next_opcode);
157 op2 = &__get_cpu_var(saved_next_opcode2);
158
151 if (OPCODE_JSR(p->opcode) || OPCODE_JMP(p->opcode)) { 159 if (OPCODE_JSR(p->opcode) || OPCODE_JMP(p->opcode)) {
152 unsigned int reg_nr = ((p->opcode >> 8) & 0x000F); 160 unsigned int reg_nr = ((p->opcode >> 8) & 0x000F);
153 saved_next_opcode.addr = 161 op1->addr = (kprobe_opcode_t *) regs->regs[reg_nr];
154 (kprobe_opcode_t *) regs->regs[reg_nr];
155 } else if (OPCODE_BRA(p->opcode) || OPCODE_BSR(p->opcode)) { 162 } else if (OPCODE_BRA(p->opcode) || OPCODE_BSR(p->opcode)) {
156 unsigned long disp = (p->opcode & 0x0FFF); 163 unsigned long disp = (p->opcode & 0x0FFF);
157 saved_next_opcode.addr = 164 op1->addr =
158 (kprobe_opcode_t *) (regs->pc + 4 + disp * 2); 165 (kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
159 166
160 } else if (OPCODE_BRAF(p->opcode) || OPCODE_BSRF(p->opcode)) { 167 } else if (OPCODE_BRAF(p->opcode) || OPCODE_BSRF(p->opcode)) {
161 unsigned int reg_nr = ((p->opcode >> 8) & 0x000F); 168 unsigned int reg_nr = ((p->opcode >> 8) & 0x000F);
162 saved_next_opcode.addr = 169 op1->addr =
163 (kprobe_opcode_t *) (regs->pc + 4 + 170 (kprobe_opcode_t *) (regs->pc + 4 +
164 regs->regs[reg_nr]); 171 regs->regs[reg_nr]);
165 172
166 } else if (OPCODE_RTS(p->opcode)) { 173 } else if (OPCODE_RTS(p->opcode)) {
167 saved_next_opcode.addr = (kprobe_opcode_t *) regs->pr; 174 op1->addr = (kprobe_opcode_t *) regs->pr;
168 175
169 } else if (OPCODE_BF(p->opcode) || OPCODE_BT(p->opcode)) { 176 } else if (OPCODE_BF(p->opcode) || OPCODE_BT(p->opcode)) {
170 unsigned long disp = (p->opcode & 0x00FF); 177 unsigned long disp = (p->opcode & 0x00FF);
171 /* case 1 */ 178 /* case 1 */
172 saved_next_opcode.addr = p->addr + 1; 179 op1->addr = p->addr + 1;
173 /* case 2 */ 180 /* case 2 */
174 saved_next_opcode2.addr = 181 op2->addr =
175 (kprobe_opcode_t *) (regs->pc + 4 + disp * 2); 182 (kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
176 saved_next_opcode2.opcode = *(saved_next_opcode2.addr); 183 op2->opcode = *(op2->addr);
177 arch_arm_kprobe(&saved_next_opcode2); 184 arch_arm_kprobe(op2);
178 185
179 } else if (OPCODE_BF_S(p->opcode) || OPCODE_BT_S(p->opcode)) { 186 } else if (OPCODE_BF_S(p->opcode) || OPCODE_BT_S(p->opcode)) {
180 unsigned long disp = (p->opcode & 0x00FF); 187 unsigned long disp = (p->opcode & 0x00FF);
181 /* case 1 */ 188 /* case 1 */
182 saved_next_opcode.addr = p->addr + 2; 189 op1->addr = p->addr + 2;
183 /* case 2 */ 190 /* case 2 */
184 saved_next_opcode2.addr = 191 op2->addr =
185 (kprobe_opcode_t *) (regs->pc + 4 + disp * 2); 192 (kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
186 saved_next_opcode2.opcode = *(saved_next_opcode2.addr); 193 op2->opcode = *(op2->addr);
187 arch_arm_kprobe(&saved_next_opcode2); 194 arch_arm_kprobe(op2);
188 195
189 } else { 196 } else {
190 saved_next_opcode.addr = p->addr + 1; 197 op1->addr = p->addr + 1;
191 } 198 }
192 199
193 saved_next_opcode.opcode = *(saved_next_opcode.addr); 200 op1->opcode = *(op1->addr);
194 arch_arm_kprobe(&saved_next_opcode); 201 arch_arm_kprobe(op1);
195 } 202 }
196} 203}
197 204
@@ -376,21 +383,23 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
376 cur->post_handler(cur, regs, 0); 383 cur->post_handler(cur, regs, 0);
377 } 384 }
378 385
379 if (saved_next_opcode.addr != 0x0) { 386 p = &__get_cpu_var(saved_next_opcode);
380 arch_disarm_kprobe(&saved_next_opcode); 387 if (p->addr) {
381 saved_next_opcode.addr = 0x0; 388 arch_disarm_kprobe(p);
382 saved_next_opcode.opcode = 0x0; 389 p->addr = NULL;
390 p->opcode = 0;
383 391
384 addr = saved_current_opcode.addr; 392 addr = __get_cpu_var(saved_current_opcode).addr;
385 saved_current_opcode.addr = 0x0; 393 __get_cpu_var(saved_current_opcode).addr = NULL;
386 394
387 p = get_kprobe(addr); 395 p = get_kprobe(addr);
388 arch_arm_kprobe(p); 396 arch_arm_kprobe(p);
389 397
390 if (saved_next_opcode2.addr != 0x0) { 398 p = &__get_cpu_var(saved_next_opcode2);
391 arch_disarm_kprobe(&saved_next_opcode2); 399 if (p->addr) {
392 saved_next_opcode2.addr = 0x0; 400 arch_disarm_kprobe(p);
393 saved_next_opcode2.opcode = 0x0; 401 p->addr = NULL;
402 p->opcode = 0;
394 } 403 }
395 } 404 }
396 405
@@ -572,14 +581,5 @@ static struct kprobe trampoline_p = {
572 581
573int __init arch_init_kprobes(void) 582int __init arch_init_kprobes(void)
574{ 583{
575 saved_next_opcode.addr = 0x0;
576 saved_next_opcode.opcode = 0x0;
577
578 saved_current_opcode.addr = 0x0;
579 saved_current_opcode.opcode = 0x0;
580
581 saved_next_opcode2.addr = 0x0;
582 saved_next_opcode2.opcode = 0x0;
583
584 return register_kprobe(&trampoline_p); 584 return register_kprobe(&trampoline_p);
585} 585}