aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/kprobes.c
diff options
context:
space:
mode:
authorPrasanna S Panchamukhi <prasanna@in.ibm.com>2005-09-06 18:19:30 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-07 19:58:00 -0400
commit1f7ad57b75ab0fba27455c7344a6ab7aa6bd90c5 (patch)
treee0dd1b5a23c0e7088fe6bab276118accf4dc14c1 /arch/ia64/kernel/kprobes.c
parentbb144a85c70a65730424ad1a9dc50fef66e5cafe (diff)
[PATCH] Kprobes: prevent possible race conditions ia64 changes
This patch contains the ia64 architecture specific changes to prevent the possible race conditions. Signed-off-by: Prasanna S Panchamukhi <prasanna@in.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ia64/kernel/kprobes.c')
-rw-r--r--arch/ia64/kernel/kprobes.c57
1 files changed, 33 insertions, 24 deletions
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 884f5cd27d8a..82a41ac29386 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -87,8 +87,10 @@ static enum instruction_type bundle_encoding[32][3] = {
87 * is IP relative instruction and update the kprobe 87 * is IP relative instruction and update the kprobe
88 * inst flag accordingly 88 * inst flag accordingly
89 */ 89 */
90static void update_kprobe_inst_flag(uint template, uint slot, uint major_opcode, 90static void __kprobes update_kprobe_inst_flag(uint template, uint slot,
91 unsigned long kprobe_inst, struct kprobe *p) 91 uint major_opcode,
92 unsigned long kprobe_inst,
93 struct kprobe *p)
92{ 94{
93 p->ainsn.inst_flag = 0; 95 p->ainsn.inst_flag = 0;
94 p->ainsn.target_br_reg = 0; 96 p->ainsn.target_br_reg = 0;
@@ -126,8 +128,10 @@ static void update_kprobe_inst_flag(uint template, uint slot, uint major_opcode
126 * Returns 0 if supported 128 * Returns 0 if supported
127 * Returns -EINVAL if unsupported 129 * Returns -EINVAL if unsupported
128 */ 130 */
129static int unsupported_inst(uint template, uint slot, uint major_opcode, 131static int __kprobes unsupported_inst(uint template, uint slot,
130 unsigned long kprobe_inst, struct kprobe *p) 132 uint major_opcode,
133 unsigned long kprobe_inst,
134 struct kprobe *p)
131{ 135{
132 unsigned long addr = (unsigned long)p->addr; 136 unsigned long addr = (unsigned long)p->addr;
133 137
@@ -168,8 +172,9 @@ static int unsupported_inst(uint template, uint slot, uint major_opcode,
168 * on which we are inserting kprobe is cmp instruction 172 * on which we are inserting kprobe is cmp instruction
169 * with ctype as unc. 173 * with ctype as unc.
170 */ 174 */
171static uint is_cmp_ctype_unc_inst(uint template, uint slot, uint major_opcode, 175static uint __kprobes is_cmp_ctype_unc_inst(uint template, uint slot,
172unsigned long kprobe_inst) 176 uint major_opcode,
177 unsigned long kprobe_inst)
173{ 178{
174 cmp_inst_t cmp_inst; 179 cmp_inst_t cmp_inst;
175 uint ctype_unc = 0; 180 uint ctype_unc = 0;
@@ -201,8 +206,10 @@ out:
201 * In this function we override the bundle with 206 * In this function we override the bundle with
202 * the break instruction at the given slot. 207 * the break instruction at the given slot.
203 */ 208 */
204static void prepare_break_inst(uint template, uint slot, uint major_opcode, 209static void __kprobes prepare_break_inst(uint template, uint slot,
205 unsigned long kprobe_inst, struct kprobe *p) 210 uint major_opcode,
211 unsigned long kprobe_inst,
212 struct kprobe *p)
206{ 213{
207 unsigned long break_inst = BREAK_INST; 214 unsigned long break_inst = BREAK_INST;
208 bundle_t *bundle = &p->ainsn.insn.bundle; 215 bundle_t *bundle = &p->ainsn.insn.bundle;
@@ -271,7 +278,8 @@ static inline int in_ivt_functions(unsigned long addr)
271 && addr < (unsigned long)__end_ivt_text); 278 && addr < (unsigned long)__end_ivt_text);
272} 279}
273 280
274static int valid_kprobe_addr(int template, int slot, unsigned long addr) 281static int __kprobes valid_kprobe_addr(int template, int slot,
282 unsigned long addr)
275{ 283{
276 if ((slot > 2) || ((bundle_encoding[template][1] == L) && slot > 1)) { 284 if ((slot > 2) || ((bundle_encoding[template][1] == L) && slot > 1)) {
277 printk(KERN_WARNING "Attempting to insert unaligned kprobe " 285 printk(KERN_WARNING "Attempting to insert unaligned kprobe "
@@ -323,7 +331,7 @@ static void kretprobe_trampoline(void)
323 * - cleanup by marking the instance as unused 331 * - cleanup by marking the instance as unused
324 * - long jump back to the original return address 332 * - long jump back to the original return address
325 */ 333 */
326int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) 334int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
327{ 335{
328 struct kretprobe_instance *ri = NULL; 336 struct kretprobe_instance *ri = NULL;
329 struct hlist_head *head; 337 struct hlist_head *head;
@@ -381,7 +389,8 @@ int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
381 return 1; 389 return 1;
382} 390}
383 391
384void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) 392void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
393 struct pt_regs *regs)
385{ 394{
386 struct kretprobe_instance *ri; 395 struct kretprobe_instance *ri;
387 396
@@ -399,7 +408,7 @@ void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
399 } 408 }
400} 409}
401 410
402int arch_prepare_kprobe(struct kprobe *p) 411int __kprobes arch_prepare_kprobe(struct kprobe *p)
403{ 412{
404 unsigned long addr = (unsigned long) p->addr; 413 unsigned long addr = (unsigned long) p->addr;
405 unsigned long *kprobe_addr = (unsigned long *)(addr & ~0xFULL); 414 unsigned long *kprobe_addr = (unsigned long *)(addr & ~0xFULL);
@@ -430,7 +439,7 @@ int arch_prepare_kprobe(struct kprobe *p)
430 return 0; 439 return 0;
431} 440}
432 441
433void arch_arm_kprobe(struct kprobe *p) 442void __kprobes arch_arm_kprobe(struct kprobe *p)
434{ 443{
435 unsigned long addr = (unsigned long)p->addr; 444 unsigned long addr = (unsigned long)p->addr;
436 unsigned long arm_addr = addr & ~0xFULL; 445 unsigned long arm_addr = addr & ~0xFULL;
@@ -439,7 +448,7 @@ void arch_arm_kprobe(struct kprobe *p)
439 flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t)); 448 flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
440} 449}
441 450
442void arch_disarm_kprobe(struct kprobe *p) 451void __kprobes arch_disarm_kprobe(struct kprobe *p)
443{ 452{
444 unsigned long addr = (unsigned long)p->addr; 453 unsigned long addr = (unsigned long)p->addr;
445 unsigned long arm_addr = addr & ~0xFULL; 454 unsigned long arm_addr = addr & ~0xFULL;
@@ -449,7 +458,7 @@ void arch_disarm_kprobe(struct kprobe *p)
449 flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t)); 458 flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
450} 459}
451 460
452void arch_remove_kprobe(struct kprobe *p) 461void __kprobes arch_remove_kprobe(struct kprobe *p)
453{ 462{
454} 463}
455 464
@@ -461,7 +470,7 @@ void arch_remove_kprobe(struct kprobe *p)
461 * to original stack address, handle the case where we need to fixup the 470 * to original stack address, handle the case where we need to fixup the
462 * relative IP address and/or fixup branch register. 471 * relative IP address and/or fixup branch register.
463 */ 472 */
464static void resume_execution(struct kprobe *p, struct pt_regs *regs) 473static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
465{ 474{
466 unsigned long bundle_addr = ((unsigned long) (&p->opcode.bundle)) & ~0xFULL; 475 unsigned long bundle_addr = ((unsigned long) (&p->opcode.bundle)) & ~0xFULL;
467 unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL; 476 unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL;
@@ -528,7 +537,7 @@ turn_ss_off:
528 ia64_psr(regs)->ss = 0; 537 ia64_psr(regs)->ss = 0;
529} 538}
530 539
531static void prepare_ss(struct kprobe *p, struct pt_regs *regs) 540static void __kprobes prepare_ss(struct kprobe *p, struct pt_regs *regs)
532{ 541{
533 unsigned long bundle_addr = (unsigned long) &p->opcode.bundle; 542 unsigned long bundle_addr = (unsigned long) &p->opcode.bundle;
534 unsigned long slot = (unsigned long)p->addr & 0xf; 543 unsigned long slot = (unsigned long)p->addr & 0xf;
@@ -545,7 +554,7 @@ static void prepare_ss(struct kprobe *p, struct pt_regs *regs)
545 ia64_psr(regs)->ss = 1; 554 ia64_psr(regs)->ss = 1;
546} 555}
547 556
548static int pre_kprobes_handler(struct die_args *args) 557static int __kprobes pre_kprobes_handler(struct die_args *args)
549{ 558{
550 struct kprobe *p; 559 struct kprobe *p;
551 int ret = 0; 560 int ret = 0;
@@ -616,7 +625,7 @@ no_kprobe:
616 return ret; 625 return ret;
617} 626}
618 627
619static int post_kprobes_handler(struct pt_regs *regs) 628static int __kprobes post_kprobes_handler(struct pt_regs *regs)
620{ 629{
621 if (!kprobe_running()) 630 if (!kprobe_running())
622 return 0; 631 return 0;
@@ -641,7 +650,7 @@ out:
641 return 1; 650 return 1;
642} 651}
643 652
644static int kprobes_fault_handler(struct pt_regs *regs, int trapnr) 653static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr)
645{ 654{
646 if (!kprobe_running()) 655 if (!kprobe_running())
647 return 0; 656 return 0;
@@ -659,8 +668,8 @@ static int kprobes_fault_handler(struct pt_regs *regs, int trapnr)
659 return 0; 668 return 0;
660} 669}
661 670
662int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, 671int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
663 void *data) 672 unsigned long val, void *data)
664{ 673{
665 struct die_args *args = (struct die_args *)data; 674 struct die_args *args = (struct die_args *)data;
666 switch(val) { 675 switch(val) {
@@ -681,7 +690,7 @@ int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
681 return NOTIFY_DONE; 690 return NOTIFY_DONE;
682} 691}
683 692
684int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) 693int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
685{ 694{
686 struct jprobe *jp = container_of(p, struct jprobe, kp); 695 struct jprobe *jp = container_of(p, struct jprobe, kp);
687 unsigned long addr = ((struct fnptr *)(jp->entry))->ip; 696 unsigned long addr = ((struct fnptr *)(jp->entry))->ip;
@@ -703,7 +712,7 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
703 return 1; 712 return 1;
704} 713}
705 714
706int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) 715int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
707{ 716{
708 *regs = jprobe_saved_regs; 717 *regs = jprobe_saved_regs;
709 return 1; 718 return 1;