diff options
Diffstat (limited to 'arch/sh/kernel/kprobes.c')
-rw-r--r-- | arch/sh/kernel/kprobes.c | 100 |
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 @@ | |||
20 | DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; | 20 | DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; |
21 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); | 21 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); |
22 | 22 | ||
23 | static struct kprobe saved_current_opcode; | 23 | static DEFINE_PER_CPU(struct kprobe, saved_current_opcode); |
24 | static struct kprobe saved_next_opcode; | 24 | static DEFINE_PER_CPU(struct kprobe, saved_next_opcode); |
25 | static struct kprobe saved_next_opcode2; | 25 | static 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 | ||
103 | void __kprobes arch_remove_kprobe(struct kprobe *p) | 103 | void __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 | */ |
142 | static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | 147 | static 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 | ||
573 | int __init arch_init_kprobes(void) | 582 | int __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 | } |