diff options
author | Masami Hiramatsu <mhiramat@redhat.com> | 2008-01-30 07:31:21 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:31:21 -0500 |
commit | d6be29b871e285d33be0e3025929e2d6bcabb0c0 (patch) | |
tree | 5dbcd8ef953d19e3978062d337c76e4fa103150b | |
parent | 8533bbe9f87b01f49ff951f665ea1988252fa3c2 (diff) |
x86: kprobes code for x86 unification
This patch unifies kprobes code.
- Unify kprobes_*.h to kprobes.h
- Unify kprobes_*.c to kprobes.c
(Differences are separated by ifdefs)
- Most differences are related to REX prefix and rip relatives.
- Two inline assembly code are different.
- One difference in kprobe_handlre()
- One fixup exception code is different, but it will be unified
if mm/extable_*.c are unified.
- Merge history logs into arch/x86/kernel/kprobes.c.
Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Signed-off-by: Jim Keniston <jkenisto@us.ibm.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | arch/x86/kernel/Makefile_32 | 2 | ||||
-rw-r--r-- | arch/x86/kernel/Makefile_64 | 2 | ||||
-rw-r--r-- | arch/x86/kernel/kprobes.c (renamed from arch/x86/kernel/kprobes_64.c) | 164 | ||||
-rw-r--r-- | arch/x86/kernel/kprobes_32.c | 848 | ||||
-rw-r--r-- | include/asm-x86/kprobes.h | 103 | ||||
-rw-r--r-- | include/asm-x86/kprobes_32.h | 102 | ||||
-rw-r--r-- | include/asm-x86/kprobes_64.h | 102 |
7 files changed, 228 insertions, 1095 deletions
diff --git a/arch/x86/kernel/Makefile_32 b/arch/x86/kernel/Makefile_32 index a854e23eac0b..c7a959da363a 100644 --- a/arch/x86/kernel/Makefile_32 +++ b/arch/x86/kernel/Makefile_32 | |||
@@ -35,7 +35,7 @@ obj-$(CONFIG_KEXEC) += machine_kexec_32.o relocate_kernel_32.o crash.o | |||
35 | obj-$(CONFIG_CRASH_DUMP) += crash_dump_32.o | 35 | obj-$(CONFIG_CRASH_DUMP) += crash_dump_32.o |
36 | obj-$(CONFIG_X86_NUMAQ) += numaq_32.o | 36 | obj-$(CONFIG_X86_NUMAQ) += numaq_32.o |
37 | obj-$(CONFIG_X86_SUMMIT_NUMA) += summit_32.o | 37 | obj-$(CONFIG_X86_SUMMIT_NUMA) += summit_32.o |
38 | obj-$(CONFIG_KPROBES) += kprobes_32.o | 38 | obj-$(CONFIG_KPROBES) += kprobes.o |
39 | obj-$(CONFIG_MODULES) += module_32.o | 39 | obj-$(CONFIG_MODULES) += module_32.o |
40 | obj-$(CONFIG_ACPI_SRAT) += srat_32.o | 40 | obj-$(CONFIG_ACPI_SRAT) += srat_32.o |
41 | obj-$(CONFIG_EFI) += efi.o efi_32.o efi_stub_32.o | 41 | obj-$(CONFIG_EFI) += efi.o efi_32.o efi_stub_32.o |
diff --git a/arch/x86/kernel/Makefile_64 b/arch/x86/kernel/Makefile_64 index e5093dd8cf01..fbb370071239 100644 --- a/arch/x86/kernel/Makefile_64 +++ b/arch/x86/kernel/Makefile_64 | |||
@@ -34,7 +34,7 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | |||
34 | obj-$(CONFIG_GART_IOMMU) += pci-gart_64.o aperture_64.o | 34 | obj-$(CONFIG_GART_IOMMU) += pci-gart_64.o aperture_64.o |
35 | obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o | 35 | obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o |
36 | obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o | 36 | obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o |
37 | obj-$(CONFIG_KPROBES) += kprobes_64.o | 37 | obj-$(CONFIG_KPROBES) += kprobes.o |
38 | obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o | 38 | obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o |
39 | obj-$(CONFIG_X86_VSMP) += vsmp_64.o | 39 | obj-$(CONFIG_X86_VSMP) += vsmp_64.o |
40 | obj-$(CONFIG_K8_NB) += k8.o | 40 | obj-$(CONFIG_K8_NB) += k8.o |
diff --git a/arch/x86/kernel/kprobes_64.c b/arch/x86/kernel/kprobes.c index 2d7763749b1b..9aadd4d4a229 100644 --- a/arch/x86/kernel/kprobes_64.c +++ b/arch/x86/kernel/kprobes.c | |||
@@ -22,14 +22,22 @@ | |||
22 | * Rusty Russell). | 22 | * Rusty Russell). |
23 | * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes | 23 | * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes |
24 | * interface to access function arguments. | 24 | * interface to access function arguments. |
25 | * 2004-Oct Jim Keniston <kenistoj@us.ibm.com> and Prasanna S Panchamukhi | 25 | * 2004-Oct Jim Keniston <jkenisto@us.ibm.com> and Prasanna S Panchamukhi |
26 | * <prasanna@in.ibm.com> adapted for x86_64 | 26 | * <prasanna@in.ibm.com> adapted for x86_64 from i386. |
27 | * 2005-Mar Roland McGrath <roland@redhat.com> | 27 | * 2005-Mar Roland McGrath <roland@redhat.com> |
28 | * Fixed to handle %rip-relative addressing mode correctly. | 28 | * Fixed to handle %rip-relative addressing mode correctly. |
29 | * 2005-May Rusty Lynch <rusty.lynch@intel.com> | 29 | * 2005-May Hien Nguyen <hien@us.ibm.com>, Jim Keniston |
30 | * Added function return probes functionality | 30 | * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi |
31 | * <prasanna@in.ibm.com> added function-return probes. | ||
32 | * 2005-May Rusty Lynch <rusty.lynch@intel.com> | ||
33 | * Added function return probes functionality | ||
34 | * 2006-Feb Masami Hiramatsu <hiramatu@sdl.hitachi.co.jp> added | ||
35 | * kprobe-booster and kretprobe-booster for i386. | ||
31 | * 2007-Dec Masami Hiramatsu <mhiramat@redhat.com> added kprobe-booster | 36 | * 2007-Dec Masami Hiramatsu <mhiramat@redhat.com> added kprobe-booster |
32 | * and kretprobe-booster for x86-64 | 37 | * and kretprobe-booster for x86-64 |
38 | * 2007-Dec Masami Hiramatsu <mhiramat@redhat.com>, Arjan van de Ven | ||
39 | * <arjan@infradead.org> and Jim Keniston <jkenisto@us.ibm.com> | ||
40 | * unified x86 kprobes code. | ||
33 | */ | 41 | */ |
34 | 42 | ||
35 | #include <linux/kprobes.h> | 43 | #include <linux/kprobes.h> |
@@ -51,7 +59,19 @@ void jprobe_return_end(void); | |||
51 | DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; | 59 | DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; |
52 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); | 60 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); |
53 | 61 | ||
62 | #ifdef CONFIG_X86_64 | ||
54 | #define stack_addr(regs) ((unsigned long *)regs->sp) | 63 | #define stack_addr(regs) ((unsigned long *)regs->sp) |
64 | #else | ||
65 | /* | ||
66 | * "®s->sp" looks wrong, but it's correct for x86_32. x86_32 CPUs | ||
67 | * don't save the ss and esp registers if the CPU is already in kernel | ||
68 | * mode when it traps. So for kprobes, regs->sp and regs->ss are not | ||
69 | * the [nonexistent] saved stack pointer and ss register, but rather | ||
70 | * the top 8 bytes of the pre-int3 stack. So ®s->sp happens to | ||
71 | * point to the top of the pre-int3 stack. | ||
72 | */ | ||
73 | #define stack_addr(regs) ((unsigned long *)®s->sp) | ||
74 | #endif | ||
55 | 75 | ||
56 | #define W(row, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf)\ | 76 | #define W(row, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf)\ |
57 | (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \ | 77 | (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \ |
@@ -151,8 +171,8 @@ static __always_inline void set_jmp_op(void *from, void *to) | |||
151 | } | 171 | } |
152 | 172 | ||
153 | /* | 173 | /* |
154 | * returns non-zero if opcode is boostable. | 174 | * Returns non-zero if opcode is boostable. |
155 | * RIP relative instructions are adjusted at copying time | 175 | * RIP relative instructions are adjusted at copying time in 64 bits mode |
156 | */ | 176 | */ |
157 | static __always_inline int can_boost(kprobe_opcode_t *opcodes) | 177 | static __always_inline int can_boost(kprobe_opcode_t *opcodes) |
158 | { | 178 | { |
@@ -173,8 +193,10 @@ retry: | |||
173 | } | 193 | } |
174 | 194 | ||
175 | switch (opcode & 0xf0) { | 195 | switch (opcode & 0xf0) { |
196 | #ifdef CONFIG_X86_64 | ||
176 | case 0x40: | 197 | case 0x40: |
177 | goto retry; /* REX prefix is boostable */ | 198 | goto retry; /* REX prefix is boostable */ |
199 | #endif | ||
178 | case 0x60: | 200 | case 0x60: |
179 | if (0x63 < opcode && opcode < 0x67) | 201 | if (0x63 < opcode && opcode < 0x67) |
180 | goto retry; /* prefixes */ | 202 | goto retry; /* prefixes */ |
@@ -206,7 +228,7 @@ retry: | |||
206 | } | 228 | } |
207 | 229 | ||
208 | /* | 230 | /* |
209 | * returns non-zero if opcode modifies the interrupt flag. | 231 | * Returns non-zero if opcode modifies the interrupt flag. |
210 | */ | 232 | */ |
211 | static int __kprobes is_IF_modifier(kprobe_opcode_t *insn) | 233 | static int __kprobes is_IF_modifier(kprobe_opcode_t *insn) |
212 | { | 234 | { |
@@ -217,16 +239,18 @@ static int __kprobes is_IF_modifier(kprobe_opcode_t *insn) | |||
217 | case 0x9d: /* popf/popfd */ | 239 | case 0x9d: /* popf/popfd */ |
218 | return 1; | 240 | return 1; |
219 | } | 241 | } |
220 | 242 | #ifdef CONFIG_X86_64 | |
221 | /* | 243 | /* |
222 | * on 64 bit x86, 0x40-0x4f are prefixes so we need to look | 244 | * on 64 bit x86, 0x40-0x4f are prefixes so we need to look |
223 | * at the next byte instead.. but of course not recurse infinitely | 245 | * at the next byte instead.. but of course not recurse infinitely |
224 | */ | 246 | */ |
225 | if (*insn >= 0x40 && *insn <= 0x4f) | 247 | if (*insn >= 0x40 && *insn <= 0x4f) |
226 | return is_IF_modifier(++insn); | 248 | return is_IF_modifier(++insn); |
249 | #endif | ||
227 | return 0; | 250 | return 0; |
228 | } | 251 | } |
229 | 252 | ||
253 | #ifdef CONFIG_X86_64 | ||
230 | /* | 254 | /* |
231 | * Adjust the displacement if the instruction uses the %rip-relative | 255 | * Adjust the displacement if the instruction uses the %rip-relative |
232 | * addressing mode. | 256 | * addressing mode. |
@@ -263,17 +287,20 @@ static void __kprobes fix_riprel(struct kprobe *p) | |||
263 | if ((*insn & 0xf0) == 0x40) | 287 | if ((*insn & 0xf0) == 0x40) |
264 | ++insn; | 288 | ++insn; |
265 | 289 | ||
266 | if (*insn == 0x0f) { /* Two-byte opcode. */ | 290 | if (*insn == 0x0f) { |
291 | /* Two-byte opcode. */ | ||
267 | ++insn; | 292 | ++insn; |
268 | need_modrm = test_bit(*insn, | 293 | need_modrm = test_bit(*insn, |
269 | (unsigned long *)twobyte_has_modrm); | 294 | (unsigned long *)twobyte_has_modrm); |
270 | } else /* One-byte opcode. */ | 295 | } else |
296 | /* One-byte opcode. */ | ||
271 | need_modrm = test_bit(*insn, | 297 | need_modrm = test_bit(*insn, |
272 | (unsigned long *)onebyte_has_modrm); | 298 | (unsigned long *)onebyte_has_modrm); |
273 | 299 | ||
274 | if (need_modrm) { | 300 | if (need_modrm) { |
275 | u8 modrm = *++insn; | 301 | u8 modrm = *++insn; |
276 | if ((modrm & 0xc7) == 0x05) { /* %rip+disp32 addressing mode */ | 302 | if ((modrm & 0xc7) == 0x05) { |
303 | /* %rip+disp32 addressing mode */ | ||
277 | /* Displacement follows ModRM byte. */ | 304 | /* Displacement follows ModRM byte. */ |
278 | ++insn; | 305 | ++insn; |
279 | /* | 306 | /* |
@@ -296,11 +323,14 @@ static void __kprobes fix_riprel(struct kprobe *p) | |||
296 | } | 323 | } |
297 | } | 324 | } |
298 | } | 325 | } |
326 | #endif | ||
299 | 327 | ||
300 | static void __kprobes arch_copy_kprobe(struct kprobe *p) | 328 | static void __kprobes arch_copy_kprobe(struct kprobe *p) |
301 | { | 329 | { |
302 | memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); | 330 | memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); |
331 | #ifdef CONFIG_X86_64 | ||
303 | fix_riprel(p); | 332 | fix_riprel(p); |
333 | #endif | ||
304 | if (can_boost(p->addr)) | 334 | if (can_boost(p->addr)) |
305 | p->ainsn.boostable = 0; | 335 | p->ainsn.boostable = 0; |
306 | else | 336 | else |
@@ -365,13 +395,13 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, | |||
365 | static __always_inline void clear_btf(void) | 395 | static __always_inline void clear_btf(void) |
366 | { | 396 | { |
367 | if (test_thread_flag(TIF_DEBUGCTLMSR)) | 397 | if (test_thread_flag(TIF_DEBUGCTLMSR)) |
368 | wrmsrl(MSR_IA32_DEBUGCTLMSR, 0); | 398 | wrmsr(MSR_IA32_DEBUGCTLMSR, 0, 0); |
369 | } | 399 | } |
370 | 400 | ||
371 | static __always_inline void restore_btf(void) | 401 | static __always_inline void restore_btf(void) |
372 | { | 402 | { |
373 | if (test_thread_flag(TIF_DEBUGCTLMSR)) | 403 | if (test_thread_flag(TIF_DEBUGCTLMSR)) |
374 | wrmsrl(MSR_IA32_DEBUGCTLMSR, current->thread.debugctlmsr); | 404 | wrmsr(MSR_IA32_DEBUGCTLMSR, current->thread.debugctlmsr, 0); |
375 | } | 405 | } |
376 | 406 | ||
377 | static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | 407 | static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) |
@@ -427,6 +457,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
427 | regs->flags &= ~TF_MASK; | 457 | regs->flags &= ~TF_MASK; |
428 | regs->flags |= kcb->kprobe_saved_flags; | 458 | regs->flags |= kcb->kprobe_saved_flags; |
429 | goto no_kprobe; | 459 | goto no_kprobe; |
460 | #ifdef CONFIG_X86_64 | ||
430 | } else if (kcb->kprobe_status == KPROBE_HIT_SSDONE) { | 461 | } else if (kcb->kprobe_status == KPROBE_HIT_SSDONE) { |
431 | /* TODO: Provide re-entrancy from | 462 | /* TODO: Provide re-entrancy from |
432 | * post_kprobes_handler() and avoid exception | 463 | * post_kprobes_handler() and avoid exception |
@@ -437,6 +468,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
437 | regs->ip = (unsigned long)p->addr; | 468 | regs->ip = (unsigned long)p->addr; |
438 | reset_current_kprobe(); | 469 | reset_current_kprobe(); |
439 | return 1; | 470 | return 1; |
471 | #endif | ||
440 | } | 472 | } |
441 | /* We have reentered the kprobe_handler(), since | 473 | /* We have reentered the kprobe_handler(), since |
442 | * another probe was hit while within the handler. | 474 | * another probe was hit while within the handler. |
@@ -461,9 +493,8 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
461 | goto no_kprobe; | 493 | goto no_kprobe; |
462 | } | 494 | } |
463 | p = __get_cpu_var(current_kprobe); | 495 | p = __get_cpu_var(current_kprobe); |
464 | if (p->break_handler && p->break_handler(p, regs)) { | 496 | if (p->break_handler && p->break_handler(p, regs)) |
465 | goto ss_probe; | 497 | goto ss_probe; |
466 | } | ||
467 | } | 498 | } |
468 | goto no_kprobe; | 499 | goto no_kprobe; |
469 | } | 500 | } |
@@ -519,8 +550,10 @@ no_kprobe: | |||
519 | */ | 550 | */ |
520 | void __kprobes kretprobe_trampoline_holder(void) | 551 | void __kprobes kretprobe_trampoline_holder(void) |
521 | { | 552 | { |
522 | asm volatile ( ".global kretprobe_trampoline\n" | 553 | asm volatile ( |
554 | ".global kretprobe_trampoline\n" | ||
523 | "kretprobe_trampoline: \n" | 555 | "kretprobe_trampoline: \n" |
556 | #ifdef CONFIG_X86_64 | ||
524 | /* We don't bother saving the ss register */ | 557 | /* We don't bother saving the ss register */ |
525 | " pushq %rsp\n" | 558 | " pushq %rsp\n" |
526 | " pushfq\n" | 559 | " pushfq\n" |
@@ -566,25 +599,64 @@ no_kprobe: | |||
566 | /* Skip orig_ax, ip, cs */ | 599 | /* Skip orig_ax, ip, cs */ |
567 | " addq $24, %rsp\n" | 600 | " addq $24, %rsp\n" |
568 | " popfq\n" | 601 | " popfq\n" |
602 | #else | ||
603 | " pushf\n" | ||
604 | /* | ||
605 | * Skip cs, ip, orig_ax. | ||
606 | * trampoline_handler() will plug in these values | ||
607 | */ | ||
608 | " subl $12, %esp\n" | ||
609 | " pushl %fs\n" | ||
610 | " pushl %ds\n" | ||
611 | " pushl %es\n" | ||
612 | " pushl %eax\n" | ||
613 | " pushl %ebp\n" | ||
614 | " pushl %edi\n" | ||
615 | " pushl %esi\n" | ||
616 | " pushl %edx\n" | ||
617 | " pushl %ecx\n" | ||
618 | " pushl %ebx\n" | ||
619 | " movl %esp, %eax\n" | ||
620 | " call trampoline_handler\n" | ||
621 | /* Move flags to cs */ | ||
622 | " movl 52(%esp), %edx\n" | ||
623 | " movl %edx, 48(%esp)\n" | ||
624 | /* Replace saved flags with true return address. */ | ||
625 | " movl %eax, 52(%esp)\n" | ||
626 | " popl %ebx\n" | ||
627 | " popl %ecx\n" | ||
628 | " popl %edx\n" | ||
629 | " popl %esi\n" | ||
630 | " popl %edi\n" | ||
631 | " popl %ebp\n" | ||
632 | " popl %eax\n" | ||
633 | /* Skip ip, orig_ax, es, ds, fs */ | ||
634 | " addl $20, %esp\n" | ||
635 | " popf\n" | ||
636 | #endif | ||
569 | " ret\n"); | 637 | " ret\n"); |
570 | } | 638 | } |
571 | 639 | ||
572 | /* | 640 | /* |
573 | * Called from kretprobe_trampoline | 641 | * Called from kretprobe_trampoline |
574 | */ | 642 | */ |
575 | fastcall void * __kprobes trampoline_handler(struct pt_regs *regs) | 643 | void * __kprobes trampoline_handler(struct pt_regs *regs) |
576 | { | 644 | { |
577 | struct kretprobe_instance *ri = NULL; | 645 | struct kretprobe_instance *ri = NULL; |
578 | struct hlist_head *head, empty_rp; | 646 | struct hlist_head *head, empty_rp; |
579 | struct hlist_node *node, *tmp; | 647 | struct hlist_node *node, *tmp; |
580 | unsigned long flags, orig_ret_address = 0; | 648 | unsigned long flags, orig_ret_address = 0; |
581 | unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; | 649 | unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; |
582 | 650 | ||
583 | INIT_HLIST_HEAD(&empty_rp); | 651 | INIT_HLIST_HEAD(&empty_rp); |
584 | spin_lock_irqsave(&kretprobe_lock, flags); | 652 | spin_lock_irqsave(&kretprobe_lock, flags); |
585 | head = kretprobe_inst_table_head(current); | 653 | head = kretprobe_inst_table_head(current); |
586 | /* fixup registers */ | 654 | /* fixup registers */ |
655 | #ifdef CONFIG_X86_64 | ||
587 | regs->cs = __KERNEL_CS; | 656 | regs->cs = __KERNEL_CS; |
657 | #else | ||
658 | regs->cs = __KERNEL_CS | get_kernel_rpl(); | ||
659 | #endif | ||
588 | regs->ip = trampoline_address; | 660 | regs->ip = trampoline_address; |
589 | regs->orig_ax = ~0UL; | 661 | regs->orig_ax = ~0UL; |
590 | 662 | ||
@@ -671,9 +743,11 @@ static void __kprobes resume_execution(struct kprobe *p, | |||
671 | unsigned long orig_ip = (unsigned long)p->addr; | 743 | unsigned long orig_ip = (unsigned long)p->addr; |
672 | kprobe_opcode_t *insn = p->ainsn.insn; | 744 | kprobe_opcode_t *insn = p->ainsn.insn; |
673 | 745 | ||
746 | #ifdef CONFIG_X86_64 | ||
674 | /*skip the REX prefix*/ | 747 | /*skip the REX prefix*/ |
675 | if (*insn >= 0x40 && *insn <= 0x4f) | 748 | if (*insn >= 0x40 && *insn <= 0x4f) |
676 | insn++; | 749 | insn++; |
750 | #endif | ||
677 | 751 | ||
678 | regs->flags &= ~TF_MASK; | 752 | regs->flags &= ~TF_MASK; |
679 | switch (*insn) { | 753 | switch (*insn) { |
@@ -693,6 +767,11 @@ static void __kprobes resume_execution(struct kprobe *p, | |||
693 | case 0xe8: /* call relative - Fix return addr */ | 767 | case 0xe8: /* call relative - Fix return addr */ |
694 | *tos = orig_ip + (*tos - copy_ip); | 768 | *tos = orig_ip + (*tos - copy_ip); |
695 | break; | 769 | break; |
770 | #ifndef CONFIG_X86_64 | ||
771 | case 0x9a: /* call absolute -- same as call absolute, indirect */ | ||
772 | *tos = orig_ip + (*tos - copy_ip); | ||
773 | goto no_change; | ||
774 | #endif | ||
696 | case 0xff: | 775 | case 0xff: |
697 | if ((insn[1] & 0x30) == 0x10) { | 776 | if ((insn[1] & 0x30) == 0x10) { |
698 | /* | 777 | /* |
@@ -783,9 +862,8 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) | |||
783 | { | 862 | { |
784 | struct kprobe *cur = kprobe_running(); | 863 | struct kprobe *cur = kprobe_running(); |
785 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 864 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
786 | const struct exception_table_entry *fixup; | ||
787 | 865 | ||
788 | switch(kcb->kprobe_status) { | 866 | switch (kcb->kprobe_status) { |
789 | case KPROBE_HIT_SS: | 867 | case KPROBE_HIT_SS: |
790 | case KPROBE_REENTER: | 868 | case KPROBE_REENTER: |
791 | /* | 869 | /* |
@@ -826,12 +904,19 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) | |||
826 | * In case the user-specified fault handler returned | 904 | * In case the user-specified fault handler returned |
827 | * zero, try to fix up. | 905 | * zero, try to fix up. |
828 | */ | 906 | */ |
829 | fixup = search_exception_tables(regs->ip); | 907 | #ifdef CONFIG_X86_64 |
830 | if (fixup) { | 908 | { |
831 | regs->ip = fixup->fixup; | 909 | const struct exception_table_entry *fixup; |
832 | return 1; | 910 | fixup = search_exception_tables(regs->ip); |
911 | if (fixup) { | ||
912 | regs->ip = fixup->fixup; | ||
913 | return 1; | ||
914 | } | ||
833 | } | 915 | } |
834 | 916 | #else | |
917 | if (fixup_exception(regs)) | ||
918 | return 1; | ||
919 | #endif | ||
835 | /* | 920 | /* |
836 | * fixup routine could not handle it, | 921 | * fixup routine could not handle it, |
837 | * Let do_page_fault() fix it. | 922 | * Let do_page_fault() fix it. |
@@ -896,7 +981,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
896 | * the argument area. | 981 | * the argument area. |
897 | */ | 982 | */ |
898 | memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr, | 983 | memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr, |
899 | MIN_STACK_SIZE(addr)); | 984 | MIN_STACK_SIZE(addr)); |
900 | regs->flags &= ~IF_MASK; | 985 | regs->flags &= ~IF_MASK; |
901 | trace_hardirqs_off(); | 986 | trace_hardirqs_off(); |
902 | regs->ip = (unsigned long)(jp->entry); | 987 | regs->ip = (unsigned long)(jp->entry); |
@@ -907,12 +992,17 @@ void __kprobes jprobe_return(void) | |||
907 | { | 992 | { |
908 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 993 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
909 | 994 | ||
910 | asm volatile (" xchg %%rbx,%%rsp \n" | 995 | asm volatile ( |
911 | " int3 \n" | 996 | #ifdef CONFIG_X86_64 |
912 | " .globl jprobe_return_end \n" | 997 | " xchg %%rbx,%%rsp \n" |
913 | " jprobe_return_end: \n" | 998 | #else |
914 | " nop \n"::"b" | 999 | " xchgl %%ebx,%%esp \n" |
915 | (kcb->jprobe_saved_sp):"memory"); | 1000 | #endif |
1001 | " int3 \n" | ||
1002 | " .globl jprobe_return_end\n" | ||
1003 | " jprobe_return_end: \n" | ||
1004 | " nop \n"::"b" | ||
1005 | (kcb->jprobe_saved_sp):"memory"); | ||
916 | } | 1006 | } |
917 | 1007 | ||
918 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | 1008 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) |
@@ -921,14 +1011,16 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | |||
921 | u8 *addr = (u8 *) (regs->ip - 1); | 1011 | u8 *addr = (u8 *) (regs->ip - 1); |
922 | struct jprobe *jp = container_of(p, struct jprobe, kp); | 1012 | struct jprobe *jp = container_of(p, struct jprobe, kp); |
923 | 1013 | ||
924 | if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { | 1014 | if ((addr > (u8 *) jprobe_return) && |
1015 | (addr < (u8 *) jprobe_return_end)) { | ||
925 | if (stack_addr(regs) != kcb->jprobe_saved_sp) { | 1016 | if (stack_addr(regs) != kcb->jprobe_saved_sp) { |
926 | struct pt_regs *saved_regs = &kcb->jprobe_saved_regs; | 1017 | struct pt_regs *saved_regs = &kcb->jprobe_saved_regs; |
927 | printk("current sp %p does not match saved sp %p\n", | 1018 | printk(KERN_ERR |
1019 | "current sp %p does not match saved sp %p\n", | ||
928 | stack_addr(regs), kcb->jprobe_saved_sp); | 1020 | stack_addr(regs), kcb->jprobe_saved_sp); |
929 | printk("Saved registers for jprobe %p\n", jp); | 1021 | printk(KERN_ERR "Saved registers for jprobe %p\n", jp); |
930 | show_registers(saved_regs); | 1022 | show_registers(saved_regs); |
931 | printk("Current registers\n"); | 1023 | printk(KERN_ERR "Current registers\n"); |
932 | show_registers(regs); | 1024 | show_registers(regs); |
933 | BUG(); | 1025 | BUG(); |
934 | } | 1026 | } |
diff --git a/arch/x86/kernel/kprobes_32.c b/arch/x86/kernel/kprobes_32.c deleted file mode 100644 index 8e06431d8b03..000000000000 --- a/arch/x86/kernel/kprobes_32.c +++ /dev/null | |||
@@ -1,848 +0,0 @@ | |||
1 | /* | ||
2 | * Kernel Probes (KProbes) | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | * | ||
18 | * Copyright (C) IBM Corporation, 2002, 2004 | ||
19 | * | ||
20 | * 2002-Oct Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel | ||
21 | * Probes initial implementation ( includes contributions from | ||
22 | * Rusty Russell). | ||
23 | * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes | ||
24 | * interface to access function arguments. | ||
25 | * 2005-May Hien Nguyen <hien@us.ibm.com>, Jim Keniston | ||
26 | * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi | ||
27 | * <prasanna@in.ibm.com> added function-return probes. | ||
28 | */ | ||
29 | |||
30 | #include <linux/kprobes.h> | ||
31 | #include <linux/ptrace.h> | ||
32 | #include <linux/string.h> | ||
33 | #include <linux/slab.h> | ||
34 | #include <linux/preempt.h> | ||
35 | #include <linux/module.h> | ||
36 | #include <linux/kdebug.h> | ||
37 | |||
38 | #include <asm/cacheflush.h> | ||
39 | #include <asm/desc.h> | ||
40 | #include <asm/pgtable.h> | ||
41 | #include <asm/uaccess.h> | ||
42 | #include <asm/alternative.h> | ||
43 | |||
44 | void jprobe_return_end(void); | ||
45 | |||
46 | DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; | ||
47 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); | ||
48 | |||
49 | /* | ||
50 | * "®s->sp" looks wrong, but it's correct for x86_32. x86_32 CPUs | ||
51 | * don't save the ss and esp registers if the CPU is already in kernel | ||
52 | * mode when it traps. So for kprobes, regs->sp and regs->ss are not | ||
53 | * the [nonexistent] saved stack pointer and ss register, but rather | ||
54 | * the top 8 bytes of the pre-int3 stack. So ®s->sp happens to | ||
55 | * point to the top of the pre-int3 stack. | ||
56 | */ | ||
57 | #define stack_addr(regs) ((unsigned long *)®s->sp) | ||
58 | |||
59 | #define W(row, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf)\ | ||
60 | (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \ | ||
61 | (b4##UL << 0x4)|(b5##UL << 0x5)|(b6##UL << 0x6)|(b7##UL << 0x7) | \ | ||
62 | (b8##UL << 0x8)|(b9##UL << 0x9)|(ba##UL << 0xa)|(bb##UL << 0xb) | \ | ||
63 | (bc##UL << 0xc)|(bd##UL << 0xd)|(be##UL << 0xe)|(bf##UL << 0xf)) \ | ||
64 | << (row % 32)) | ||
65 | /* | ||
66 | * Undefined/reserved opcodes, conditional jump, Opcode Extension | ||
67 | * Groups, and some special opcodes can not boost. | ||
68 | */ | ||
69 | static const u32 twobyte_is_boostable[256 / 32] = { | ||
70 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | ||
71 | /* ---------------------------------------------- */ | ||
72 | W(0x00, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0) | /* 00 */ | ||
73 | W(0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 10 */ | ||
74 | W(0x20, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 20 */ | ||
75 | W(0x30, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 30 */ | ||
76 | W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 40 */ | ||
77 | W(0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 50 */ | ||
78 | W(0x60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1) | /* 60 */ | ||
79 | W(0x70, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1) , /* 70 */ | ||
80 | W(0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 80 */ | ||
81 | W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */ | ||
82 | W(0xa0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1) | /* a0 */ | ||
83 | W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1) , /* b0 */ | ||
84 | W(0xc0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1) | /* c0 */ | ||
85 | W(0xd0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1) , /* d0 */ | ||
86 | W(0xe0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1) | /* e0 */ | ||
87 | W(0xf0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0) /* f0 */ | ||
88 | /* ----------------------------------------------- */ | ||
89 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | ||
90 | }; | ||
91 | static const u32 onebyte_has_modrm[256 / 32] = { | ||
92 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | ||
93 | /* ----------------------------------------------- */ | ||
94 | W(0x00, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 00 */ | ||
95 | W(0x10, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) , /* 10 */ | ||
96 | W(0x20, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 20 */ | ||
97 | W(0x30, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) , /* 30 */ | ||
98 | W(0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 40 */ | ||
99 | W(0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 50 */ | ||
100 | W(0x60, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0) | /* 60 */ | ||
101 | W(0x70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 70 */ | ||
102 | W(0x80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */ | ||
103 | W(0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 90 */ | ||
104 | W(0xa0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* a0 */ | ||
105 | W(0xb0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* b0 */ | ||
106 | W(0xc0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0) | /* c0 */ | ||
107 | W(0xd0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */ | ||
108 | W(0xe0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* e0 */ | ||
109 | W(0xf0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1) /* f0 */ | ||
110 | /* ----------------------------------------------- */ | ||
111 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | ||
112 | }; | ||
113 | static const u32 twobyte_has_modrm[256 / 32] = { | ||
114 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | ||
115 | /* ----------------------------------------------- */ | ||
116 | W(0x00, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1) | /* 0f */ | ||
117 | W(0x10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0) , /* 1f */ | ||
118 | W(0x20, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1) | /* 2f */ | ||
119 | W(0x30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 3f */ | ||
120 | W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 4f */ | ||
121 | W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 5f */ | ||
122 | W(0x60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 6f */ | ||
123 | W(0x70, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1) , /* 7f */ | ||
124 | W(0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 8f */ | ||
125 | W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 9f */ | ||
126 | W(0xa0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1) | /* af */ | ||
127 | W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1) , /* bf */ | ||
128 | W(0xc0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0) | /* cf */ | ||
129 | W(0xd0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* df */ | ||
130 | W(0xe0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* ef */ | ||
131 | W(0xf0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0) /* ff */ | ||
132 | /* ----------------------------------------------- */ | ||
133 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | ||
134 | }; | ||
135 | #undef W | ||
136 | |||
137 | struct kretprobe_blackpoint kretprobe_blacklist[] = { | ||
138 | {"__switch_to", }, /* This function switches only current task, but | ||
139 | doesn't switch kernel stack.*/ | ||
140 | {NULL, NULL} /* Terminator */ | ||
141 | }; | ||
142 | const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist); | ||
143 | |||
144 | /* Insert a jump instruction at address 'from', which jumps to address 'to'.*/ | ||
145 | static __always_inline void set_jmp_op(void *from, void *to) | ||
146 | { | ||
147 | struct __arch_jmp_op { | ||
148 | char op; | ||
149 | s32 raddr; | ||
150 | } __attribute__((packed)) * jop; | ||
151 | jop = (struct __arch_jmp_op *)from; | ||
152 | jop->raddr = (s32)((long)(to) - ((long)(from) + 5)); | ||
153 | jop->op = RELATIVEJUMP_INSTRUCTION; | ||
154 | } | ||
155 | |||
156 | /* | ||
157 | * returns non-zero if opcode is boostable. | ||
158 | */ | ||
159 | static __always_inline int can_boost(kprobe_opcode_t *opcodes) | ||
160 | { | ||
161 | kprobe_opcode_t opcode; | ||
162 | kprobe_opcode_t *orig_opcodes = opcodes; | ||
163 | |||
164 | retry: | ||
165 | if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) | ||
166 | return 0; | ||
167 | opcode = *(opcodes++); | ||
168 | |||
169 | /* 2nd-byte opcode */ | ||
170 | if (opcode == 0x0f) { | ||
171 | if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) | ||
172 | return 0; | ||
173 | return test_bit(*opcodes, | ||
174 | (unsigned long *)twobyte_is_boostable); | ||
175 | } | ||
176 | |||
177 | switch (opcode & 0xf0) { | ||
178 | case 0x60: | ||
179 | if (0x63 < opcode && opcode < 0x67) | ||
180 | goto retry; /* prefixes */ | ||
181 | /* can't boost Address-size override and bound */ | ||
182 | return (opcode != 0x62 && opcode != 0x67); | ||
183 | case 0x70: | ||
184 | return 0; /* can't boost conditional jump */ | ||
185 | case 0xc0: | ||
186 | /* can't boost software-interruptions */ | ||
187 | return (0xc1 < opcode && opcode < 0xcc) || opcode == 0xcf; | ||
188 | case 0xd0: | ||
189 | /* can boost AA* and XLAT */ | ||
190 | return (opcode == 0xd4 || opcode == 0xd5 || opcode == 0xd7); | ||
191 | case 0xe0: | ||
192 | /* can boost in/out and absolute jmps */ | ||
193 | return ((opcode & 0x04) || opcode == 0xea); | ||
194 | case 0xf0: | ||
195 | if ((opcode & 0x0c) == 0 && opcode != 0xf1) | ||
196 | goto retry; /* lock/rep(ne) prefix */ | ||
197 | /* clear and set flags are boostable */ | ||
198 | return (opcode == 0xf5 || (0xf7 < opcode && opcode < 0xfe)); | ||
199 | default: | ||
200 | /* segment override prefixes are boostable */ | ||
201 | if (opcode == 0x26 || opcode == 0x36 || opcode == 0x3e) | ||
202 | goto retry; /* prefixes */ | ||
203 | /* CS override prefix and call are not boostable */ | ||
204 | return (opcode != 0x2e && opcode != 0x9a); | ||
205 | } | ||
206 | } | ||
207 | |||
208 | /* | ||
209 | * returns non-zero if opcode modifies the interrupt flag. | ||
210 | */ | ||
211 | static int __kprobes is_IF_modifier(kprobe_opcode_t *insn) | ||
212 | { | ||
213 | switch (*insn) { | ||
214 | case 0xfa: /* cli */ | ||
215 | case 0xfb: /* sti */ | ||
216 | case 0xcf: /* iret/iretd */ | ||
217 | case 0x9d: /* popf/popfd */ | ||
218 | return 1; | ||
219 | } | ||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static void __kprobes arch_copy_kprobe(struct kprobe *p) | ||
224 | { | ||
225 | memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); | ||
226 | if (can_boost(p->addr)) | ||
227 | p->ainsn.boostable = 0; | ||
228 | else | ||
229 | p->ainsn.boostable = -1; | ||
230 | |||
231 | p->opcode = *p->addr; | ||
232 | } | ||
233 | |||
234 | int __kprobes arch_prepare_kprobe(struct kprobe *p) | ||
235 | { | ||
236 | /* insn: must be on special executable page on x86. */ | ||
237 | p->ainsn.insn = get_insn_slot(); | ||
238 | if (!p->ainsn.insn) | ||
239 | return -ENOMEM; | ||
240 | arch_copy_kprobe(p); | ||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | void __kprobes arch_arm_kprobe(struct kprobe *p) | ||
245 | { | ||
246 | text_poke(p->addr, ((unsigned char []){BREAKPOINT_INSTRUCTION}), 1); | ||
247 | } | ||
248 | |||
249 | void __kprobes arch_disarm_kprobe(struct kprobe *p) | ||
250 | { | ||
251 | text_poke(p->addr, &p->opcode, 1); | ||
252 | } | ||
253 | |||
254 | void __kprobes arch_remove_kprobe(struct kprobe *p) | ||
255 | { | ||
256 | mutex_lock(&kprobe_mutex); | ||
257 | free_insn_slot(p->ainsn.insn, (p->ainsn.boostable == 1)); | ||
258 | mutex_unlock(&kprobe_mutex); | ||
259 | } | ||
260 | |||
261 | static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) | ||
262 | { | ||
263 | kcb->prev_kprobe.kp = kprobe_running(); | ||
264 | kcb->prev_kprobe.status = kcb->kprobe_status; | ||
265 | kcb->prev_kprobe.old_flags = kcb->kprobe_old_flags; | ||
266 | kcb->prev_kprobe.saved_flags = kcb->kprobe_saved_flags; | ||
267 | } | ||
268 | |||
269 | static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) | ||
270 | { | ||
271 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; | ||
272 | kcb->kprobe_status = kcb->prev_kprobe.status; | ||
273 | kcb->kprobe_old_flags = kcb->prev_kprobe.old_flags; | ||
274 | kcb->kprobe_saved_flags = kcb->prev_kprobe.saved_flags; | ||
275 | } | ||
276 | |||
277 | static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, | ||
278 | struct kprobe_ctlblk *kcb) | ||
279 | { | ||
280 | __get_cpu_var(current_kprobe) = p; | ||
281 | kcb->kprobe_saved_flags = kcb->kprobe_old_flags | ||
282 | = (regs->flags & (TF_MASK | IF_MASK)); | ||
283 | if (is_IF_modifier(p->ainsn.insn)) | ||
284 | kcb->kprobe_saved_flags &= ~IF_MASK; | ||
285 | } | ||
286 | |||
287 | static __always_inline void clear_btf(void) | ||
288 | { | ||
289 | if (test_thread_flag(TIF_DEBUGCTLMSR)) | ||
290 | wrmsr(MSR_IA32_DEBUGCTLMSR, 0, 0); | ||
291 | } | ||
292 | |||
293 | static __always_inline void restore_btf(void) | ||
294 | { | ||
295 | if (test_thread_flag(TIF_DEBUGCTLMSR)) | ||
296 | wrmsr(MSR_IA32_DEBUGCTLMSR, current->thread.debugctlmsr, 0); | ||
297 | } | ||
298 | |||
299 | static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | ||
300 | { | ||
301 | clear_btf(); | ||
302 | regs->flags |= TF_MASK; | ||
303 | regs->flags &= ~IF_MASK; | ||
304 | /*single step inline if the instruction is an int3*/ | ||
305 | if (p->opcode == BREAKPOINT_INSTRUCTION) | ||
306 | regs->ip = (unsigned long)p->addr; | ||
307 | else | ||
308 | regs->ip = (unsigned long)p->ainsn.insn; | ||
309 | } | ||
310 | |||
311 | /* Called with kretprobe_lock held */ | ||
312 | void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, | ||
313 | struct pt_regs *regs) | ||
314 | { | ||
315 | unsigned long *sara = stack_addr(regs); | ||
316 | |||
317 | ri->ret_addr = (kprobe_opcode_t *) *sara; | ||
318 | |||
319 | /* Replace the return addr with trampoline addr */ | ||
320 | *sara = (unsigned long) &kretprobe_trampoline; | ||
321 | } | ||
322 | |||
323 | /* | ||
324 | * Interrupts are disabled on entry as trap3 is an interrupt gate and they | ||
325 | * remain disabled thorough out this function. | ||
326 | */ | ||
327 | static int __kprobes kprobe_handler(struct pt_regs *regs) | ||
328 | { | ||
329 | struct kprobe *p; | ||
330 | int ret = 0; | ||
331 | kprobe_opcode_t *addr; | ||
332 | struct kprobe_ctlblk *kcb; | ||
333 | |||
334 | addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t)); | ||
335 | |||
336 | /* | ||
337 | * We don't want to be preempted for the entire | ||
338 | * duration of kprobe processing | ||
339 | */ | ||
340 | preempt_disable(); | ||
341 | kcb = get_kprobe_ctlblk(); | ||
342 | |||
343 | /* Check we're not actually recursing */ | ||
344 | if (kprobe_running()) { | ||
345 | p = get_kprobe(addr); | ||
346 | if (p) { | ||
347 | if (kcb->kprobe_status == KPROBE_HIT_SS && | ||
348 | *p->ainsn.insn == BREAKPOINT_INSTRUCTION) { | ||
349 | regs->flags &= ~TF_MASK; | ||
350 | regs->flags |= kcb->kprobe_saved_flags; | ||
351 | goto no_kprobe; | ||
352 | } | ||
353 | /* We have reentered the kprobe_handler(), since | ||
354 | * another probe was hit while within the handler. | ||
355 | * We here save the original kprobes variables and | ||
356 | * just single step on the instruction of the new probe | ||
357 | * without calling any user handlers. | ||
358 | */ | ||
359 | save_previous_kprobe(kcb); | ||
360 | set_current_kprobe(p, regs, kcb); | ||
361 | kprobes_inc_nmissed_count(p); | ||
362 | prepare_singlestep(p, regs); | ||
363 | kcb->kprobe_status = KPROBE_REENTER; | ||
364 | return 1; | ||
365 | } else { | ||
366 | if (*addr != BREAKPOINT_INSTRUCTION) { | ||
367 | /* The breakpoint instruction was removed by | ||
368 | * another cpu right after we hit, no further | ||
369 | * handling of this interrupt is appropriate | ||
370 | */ | ||
371 | regs->ip = (unsigned long)addr; | ||
372 | ret = 1; | ||
373 | goto no_kprobe; | ||
374 | } | ||
375 | p = __get_cpu_var(current_kprobe); | ||
376 | if (p->break_handler && p->break_handler(p, regs)) { | ||
377 | goto ss_probe; | ||
378 | } | ||
379 | } | ||
380 | goto no_kprobe; | ||
381 | } | ||
382 | |||
383 | p = get_kprobe(addr); | ||
384 | if (!p) { | ||
385 | if (*addr != BREAKPOINT_INSTRUCTION) { | ||
386 | /* | ||
387 | * The breakpoint instruction was removed right | ||
388 | * after we hit it. Another cpu has removed | ||
389 | * either a probepoint or a debugger breakpoint | ||
390 | * at this address. In either case, no further | ||
391 | * handling of this interrupt is appropriate. | ||
392 | * Back up over the (now missing) int3 and run | ||
393 | * the original instruction. | ||
394 | */ | ||
395 | regs->ip = (unsigned long)addr; | ||
396 | ret = 1; | ||
397 | } | ||
398 | /* Not one of ours: let kernel handle it */ | ||
399 | goto no_kprobe; | ||
400 | } | ||
401 | |||
402 | set_current_kprobe(p, regs, kcb); | ||
403 | kcb->kprobe_status = KPROBE_HIT_ACTIVE; | ||
404 | |||
405 | if (p->pre_handler && p->pre_handler(p, regs)) | ||
406 | /* handler has already set things up, so skip ss setup */ | ||
407 | return 1; | ||
408 | |||
409 | ss_probe: | ||
410 | #if !defined(CONFIG_PREEMPT) || defined(CONFIG_PM) | ||
411 | if (p->ainsn.boostable == 1 && !p->post_handler) { | ||
412 | /* Boost up -- we can execute copied instructions directly */ | ||
413 | reset_current_kprobe(); | ||
414 | regs->ip = (unsigned long)p->ainsn.insn; | ||
415 | preempt_enable_no_resched(); | ||
416 | return 1; | ||
417 | } | ||
418 | #endif | ||
419 | prepare_singlestep(p, regs); | ||
420 | kcb->kprobe_status = KPROBE_HIT_SS; | ||
421 | return 1; | ||
422 | |||
423 | no_kprobe: | ||
424 | preempt_enable_no_resched(); | ||
425 | return ret; | ||
426 | } | ||
427 | |||
428 | /* | ||
429 | * When a retprobed function returns, this code saves registers and | ||
430 | * calls trampoline_handler() runs, which calls the kretprobe's handler. | ||
431 | */ | ||
432 | void __kprobes kretprobe_trampoline_holder(void) | ||
433 | { | ||
434 | asm volatile ( ".global kretprobe_trampoline\n" | ||
435 | "kretprobe_trampoline: \n" | ||
436 | " pushf\n" | ||
437 | /* | ||
438 | * Skip cs, ip, orig_ax. | ||
439 | * trampoline_handler() will plug in these values | ||
440 | */ | ||
441 | " subl $12, %esp\n" | ||
442 | " pushl %fs\n" | ||
443 | " pushl %ds\n" | ||
444 | " pushl %es\n" | ||
445 | " pushl %eax\n" | ||
446 | " pushl %ebp\n" | ||
447 | " pushl %edi\n" | ||
448 | " pushl %esi\n" | ||
449 | " pushl %edx\n" | ||
450 | " pushl %ecx\n" | ||
451 | " pushl %ebx\n" | ||
452 | " movl %esp, %eax\n" | ||
453 | " call trampoline_handler\n" | ||
454 | /* Move flags to cs */ | ||
455 | " movl 52(%esp), %edx\n" | ||
456 | " movl %edx, 48(%esp)\n" | ||
457 | /* Replace saved flags with true return address. */ | ||
458 | " movl %eax, 52(%esp)\n" | ||
459 | " popl %ebx\n" | ||
460 | " popl %ecx\n" | ||
461 | " popl %edx\n" | ||
462 | " popl %esi\n" | ||
463 | " popl %edi\n" | ||
464 | " popl %ebp\n" | ||
465 | " popl %eax\n" | ||
466 | /* Skip ip, orig_ax, es, ds, fs */ | ||
467 | " addl $20, %esp\n" | ||
468 | " popf\n" | ||
469 | " ret\n"); | ||
470 | } | ||
471 | |||
472 | /* | ||
473 | * Called from kretprobe_trampoline | ||
474 | */ | ||
475 | void * __kprobes trampoline_handler(struct pt_regs *regs) | ||
476 | { | ||
477 | struct kretprobe_instance *ri = NULL; | ||
478 | struct hlist_head *head, empty_rp; | ||
479 | struct hlist_node *node, *tmp; | ||
480 | unsigned long flags, orig_ret_address = 0; | ||
481 | unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; | ||
482 | |||
483 | INIT_HLIST_HEAD(&empty_rp); | ||
484 | spin_lock_irqsave(&kretprobe_lock, flags); | ||
485 | head = kretprobe_inst_table_head(current); | ||
486 | /* fixup registers */ | ||
487 | regs->cs = __KERNEL_CS | get_kernel_rpl(); | ||
488 | regs->ip = trampoline_address; | ||
489 | regs->orig_ax = ~0UL; | ||
490 | |||
491 | /* | ||
492 | * It is possible to have multiple instances associated with a given | ||
493 | * task either because multiple functions in the call path have | ||
494 | * return probes installed on them, and/or more then one | ||
495 | * return probe was registered for a target function. | ||
496 | * | ||
497 | * We can handle this because: | ||
498 | * - instances are always pushed into the head of the list | ||
499 | * - when multiple return probes are registered for the same | ||
500 | * function, the (chronologically) first instance's ret_addr | ||
501 | * will be the real return address, and all the rest will | ||
502 | * point to kretprobe_trampoline. | ||
503 | */ | ||
504 | hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { | ||
505 | if (ri->task != current) | ||
506 | /* another task is sharing our hash bucket */ | ||
507 | continue; | ||
508 | |||
509 | if (ri->rp && ri->rp->handler) { | ||
510 | __get_cpu_var(current_kprobe) = &ri->rp->kp; | ||
511 | get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; | ||
512 | ri->rp->handler(ri, regs); | ||
513 | __get_cpu_var(current_kprobe) = NULL; | ||
514 | } | ||
515 | |||
516 | orig_ret_address = (unsigned long)ri->ret_addr; | ||
517 | recycle_rp_inst(ri, &empty_rp); | ||
518 | |||
519 | if (orig_ret_address != trampoline_address) | ||
520 | /* | ||
521 | * This is the real return address. Any other | ||
522 | * instances associated with this task are for | ||
523 | * other calls deeper on the call stack | ||
524 | */ | ||
525 | break; | ||
526 | } | ||
527 | |||
528 | kretprobe_assert(ri, orig_ret_address, trampoline_address); | ||
529 | |||
530 | spin_unlock_irqrestore(&kretprobe_lock, flags); | ||
531 | |||
532 | hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { | ||
533 | hlist_del(&ri->hlist); | ||
534 | kfree(ri); | ||
535 | } | ||
536 | return (void *)orig_ret_address; | ||
537 | } | ||
538 | |||
539 | /* | ||
540 | * Called after single-stepping. p->addr is the address of the | ||
541 | * instruction whose first byte has been replaced by the "int 3" | ||
542 | * instruction. To avoid the SMP problems that can occur when we | ||
543 | * temporarily put back the original opcode to single-step, we | ||
544 | * single-stepped a copy of the instruction. The address of this | ||
545 | * copy is p->ainsn.insn. | ||
546 | * | ||
547 | * This function prepares to return from the post-single-step | ||
548 | * interrupt. We have to fix up the stack as follows: | ||
549 | * | ||
550 | * 0) Except in the case of absolute or indirect jump or call instructions, | ||
551 | * the new ip is relative to the copied instruction. We need to make | ||
552 | * it relative to the original instruction. | ||
553 | * | ||
554 | * 1) If the single-stepped instruction was pushfl, then the TF and IF | ||
555 | * flags are set in the just-pushed flags, and may need to be cleared. | ||
556 | * | ||
557 | * 2) If the single-stepped instruction was a call, the return address | ||
558 | * that is atop the stack is the address following the copied instruction. | ||
559 | * We need to make it the address following the original instruction. | ||
560 | * | ||
561 | * If this is the first time we've single-stepped the instruction at | ||
562 | * this probepoint, and the instruction is boostable, boost it: add a | ||
563 | * jump instruction after the copied instruction, that jumps to the next | ||
564 | * instruction after the probepoint. | ||
565 | */ | ||
566 | static void __kprobes resume_execution(struct kprobe *p, | ||
567 | struct pt_regs *regs, struct kprobe_ctlblk *kcb) | ||
568 | { | ||
569 | unsigned long *tos = stack_addr(regs); | ||
570 | unsigned long copy_ip = (unsigned long)p->ainsn.insn; | ||
571 | unsigned long orig_ip = (unsigned long)p->addr; | ||
572 | kprobe_opcode_t *insn = p->ainsn.insn; | ||
573 | |||
574 | regs->flags &= ~TF_MASK; | ||
575 | switch (*insn) { | ||
576 | case 0x9c: /* pushfl */ | ||
577 | *tos &= ~(TF_MASK | IF_MASK); | ||
578 | *tos |= kcb->kprobe_old_flags; | ||
579 | break; | ||
580 | case 0xc2: /* iret/ret/lret */ | ||
581 | case 0xc3: | ||
582 | case 0xca: | ||
583 | case 0xcb: | ||
584 | case 0xcf: | ||
585 | case 0xea: /* jmp absolute -- ip is correct */ | ||
586 | /* ip is already adjusted, no more changes required */ | ||
587 | p->ainsn.boostable = 1; | ||
588 | goto no_change; | ||
589 | case 0xe8: /* call relative - Fix return addr */ | ||
590 | *tos = orig_ip + (*tos - copy_ip); | ||
591 | break; | ||
592 | case 0x9a: /* call absolute -- same as call absolute, indirect */ | ||
593 | *tos = orig_ip + (*tos - copy_ip); | ||
594 | goto no_change; | ||
595 | case 0xff: | ||
596 | if ((insn[1] & 0x30) == 0x10) { | ||
597 | /* | ||
598 | * call absolute, indirect | ||
599 | * Fix return addr; ip is correct. | ||
600 | * But this is not boostable | ||
601 | */ | ||
602 | *tos = orig_ip + (*tos - copy_ip); | ||
603 | goto no_change; | ||
604 | } else if (((insn[1] & 0x31) == 0x20) || | ||
605 | ((insn[1] & 0x31) == 0x21)) { | ||
606 | /* | ||
607 | * jmp near and far, absolute indirect | ||
608 | * ip is correct. And this is boostable | ||
609 | */ | ||
610 | p->ainsn.boostable = 1; | ||
611 | goto no_change; | ||
612 | } | ||
613 | default: | ||
614 | break; | ||
615 | } | ||
616 | |||
617 | if (p->ainsn.boostable == 0) { | ||
618 | if ((regs->ip > copy_ip) && | ||
619 | (regs->ip - copy_ip) + 5 < MAX_INSN_SIZE) { | ||
620 | /* | ||
621 | * These instructions can be executed directly if it | ||
622 | * jumps back to correct address. | ||
623 | */ | ||
624 | set_jmp_op((void *)regs->ip, | ||
625 | (void *)orig_ip + (regs->ip - copy_ip)); | ||
626 | p->ainsn.boostable = 1; | ||
627 | } else { | ||
628 | p->ainsn.boostable = -1; | ||
629 | } | ||
630 | } | ||
631 | |||
632 | regs->ip += orig_ip - copy_ip; | ||
633 | |||
634 | no_change: | ||
635 | restore_btf(); | ||
636 | |||
637 | return; | ||
638 | } | ||
639 | |||
640 | /* | ||
641 | * Interrupts are disabled on entry as trap1 is an interrupt gate and they | ||
642 | * remain disabled thoroughout this function. | ||
643 | */ | ||
644 | static int __kprobes post_kprobe_handler(struct pt_regs *regs) | ||
645 | { | ||
646 | struct kprobe *cur = kprobe_running(); | ||
647 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
648 | |||
649 | if (!cur) | ||
650 | return 0; | ||
651 | |||
652 | if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) { | ||
653 | kcb->kprobe_status = KPROBE_HIT_SSDONE; | ||
654 | cur->post_handler(cur, regs, 0); | ||
655 | } | ||
656 | |||
657 | resume_execution(cur, regs, kcb); | ||
658 | regs->flags |= kcb->kprobe_saved_flags; | ||
659 | trace_hardirqs_fixup_flags(regs->flags); | ||
660 | |||
661 | /* Restore back the original saved kprobes variables and continue. */ | ||
662 | if (kcb->kprobe_status == KPROBE_REENTER) { | ||
663 | restore_previous_kprobe(kcb); | ||
664 | goto out; | ||
665 | } | ||
666 | reset_current_kprobe(); | ||
667 | out: | ||
668 | preempt_enable_no_resched(); | ||
669 | |||
670 | /* | ||
671 | * if somebody else is singlestepping across a probe point, flags | ||
672 | * will have TF set, in which case, continue the remaining processing | ||
673 | * of do_debug, as if this is not a probe hit. | ||
674 | */ | ||
675 | if (regs->flags & TF_MASK) | ||
676 | return 0; | ||
677 | |||
678 | return 1; | ||
679 | } | ||
680 | |||
681 | int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) | ||
682 | { | ||
683 | struct kprobe *cur = kprobe_running(); | ||
684 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
685 | |||
686 | switch(kcb->kprobe_status) { | ||
687 | case KPROBE_HIT_SS: | ||
688 | case KPROBE_REENTER: | ||
689 | /* | ||
690 | * We are here because the instruction being single | ||
691 | * stepped caused a page fault. We reset the current | ||
692 | * kprobe and the ip points back to the probe address | ||
693 | * and allow the page fault handler to continue as a | ||
694 | * normal page fault. | ||
695 | */ | ||
696 | regs->ip = (unsigned long)cur->addr; | ||
697 | regs->flags |= kcb->kprobe_old_flags; | ||
698 | if (kcb->kprobe_status == KPROBE_REENTER) | ||
699 | restore_previous_kprobe(kcb); | ||
700 | else | ||
701 | reset_current_kprobe(); | ||
702 | preempt_enable_no_resched(); | ||
703 | break; | ||
704 | case KPROBE_HIT_ACTIVE: | ||
705 | case KPROBE_HIT_SSDONE: | ||
706 | /* | ||
707 | * We increment the nmissed count for accounting, | ||
708 | * we can also use npre/npostfault count for accounting | ||
709 | * these specific fault cases. | ||
710 | */ | ||
711 | kprobes_inc_nmissed_count(cur); | ||
712 | |||
713 | /* | ||
714 | * We come here because instructions in the pre/post | ||
715 | * handler caused the page_fault, this could happen | ||
716 | * if handler tries to access user space by | ||
717 | * copy_from_user(), get_user() etc. Let the | ||
718 | * user-specified handler try to fix it first. | ||
719 | */ | ||
720 | if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) | ||
721 | return 1; | ||
722 | |||
723 | /* | ||
724 | * In case the user-specified fault handler returned | ||
725 | * zero, try to fix up. | ||
726 | */ | ||
727 | if (fixup_exception(regs)) | ||
728 | return 1; | ||
729 | |||
730 | /* | ||
731 | * fixup routine could not handle it, | ||
732 | * Let do_page_fault() fix it. | ||
733 | */ | ||
734 | break; | ||
735 | default: | ||
736 | break; | ||
737 | } | ||
738 | return 0; | ||
739 | } | ||
740 | |||
741 | /* | ||
742 | * Wrapper routine for handling exceptions. | ||
743 | */ | ||
744 | int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | ||
745 | unsigned long val, void *data) | ||
746 | { | ||
747 | struct die_args *args = (struct die_args *)data; | ||
748 | int ret = NOTIFY_DONE; | ||
749 | |||
750 | if (args->regs && user_mode_vm(args->regs)) | ||
751 | return ret; | ||
752 | |||
753 | switch (val) { | ||
754 | case DIE_INT3: | ||
755 | if (kprobe_handler(args->regs)) | ||
756 | ret = NOTIFY_STOP; | ||
757 | break; | ||
758 | case DIE_DEBUG: | ||
759 | if (post_kprobe_handler(args->regs)) | ||
760 | ret = NOTIFY_STOP; | ||
761 | break; | ||
762 | case DIE_GPF: | ||
763 | /* kprobe_running() needs smp_processor_id() */ | ||
764 | preempt_disable(); | ||
765 | if (kprobe_running() && | ||
766 | kprobe_fault_handler(args->regs, args->trapnr)) | ||
767 | ret = NOTIFY_STOP; | ||
768 | preempt_enable(); | ||
769 | break; | ||
770 | default: | ||
771 | break; | ||
772 | } | ||
773 | return ret; | ||
774 | } | ||
775 | |||
776 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | ||
777 | { | ||
778 | struct jprobe *jp = container_of(p, struct jprobe, kp); | ||
779 | unsigned long addr; | ||
780 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
781 | |||
782 | kcb->jprobe_saved_regs = *regs; | ||
783 | kcb->jprobe_saved_sp = stack_addr(regs); | ||
784 | addr = (unsigned long)(kcb->jprobe_saved_sp); | ||
785 | |||
786 | /* | ||
787 | * As Linus pointed out, gcc assumes that the callee | ||
788 | * owns the argument space and could overwrite it, e.g. | ||
789 | * tailcall optimization. So, to be absolutely safe | ||
790 | * we also save and restore enough stack bytes to cover | ||
791 | * the argument area. | ||
792 | */ | ||
793 | memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr, | ||
794 | MIN_STACK_SIZE(addr)); | ||
795 | regs->flags &= ~IF_MASK; | ||
796 | trace_hardirqs_off(); | ||
797 | regs->ip = (unsigned long)(jp->entry); | ||
798 | return 1; | ||
799 | } | ||
800 | |||
801 | void __kprobes jprobe_return(void) | ||
802 | { | ||
803 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
804 | |||
805 | asm volatile (" xchgl %%ebx,%%esp \n" | ||
806 | " int3 \n" | ||
807 | " .globl jprobe_return_end \n" | ||
808 | " jprobe_return_end: \n" | ||
809 | " nop \n"::"b" | ||
810 | (kcb->jprobe_saved_sp):"memory"); | ||
811 | } | ||
812 | |||
813 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | ||
814 | { | ||
815 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
816 | u8 *addr = (u8 *) (regs->ip - 1); | ||
817 | struct jprobe *jp = container_of(p, struct jprobe, kp); | ||
818 | |||
819 | if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { | ||
820 | if (stack_addr(regs) != kcb->jprobe_saved_sp) { | ||
821 | struct pt_regs *saved_regs = &kcb->jprobe_saved_regs; | ||
822 | printk("current sp %p does not match saved sp %p\n", | ||
823 | stack_addr(regs), kcb->jprobe_saved_sp); | ||
824 | printk("Saved registers for jprobe %p\n", jp); | ||
825 | show_registers(saved_regs); | ||
826 | printk("Current registers\n"); | ||
827 | show_registers(regs); | ||
828 | BUG(); | ||
829 | } | ||
830 | *regs = kcb->jprobe_saved_regs; | ||
831 | memcpy((kprobe_opcode_t *)(kcb->jprobe_saved_sp), | ||
832 | kcb->jprobes_stack, | ||
833 | MIN_STACK_SIZE(kcb->jprobe_saved_sp)); | ||
834 | preempt_enable_no_resched(); | ||
835 | return 1; | ||
836 | } | ||
837 | return 0; | ||
838 | } | ||
839 | |||
840 | int __init arch_init_kprobes(void) | ||
841 | { | ||
842 | return 0; | ||
843 | } | ||
844 | |||
845 | int __kprobes arch_trampoline_kprobe(struct kprobe *p) | ||
846 | { | ||
847 | return 0; | ||
848 | } | ||
diff --git a/include/asm-x86/kprobes.h b/include/asm-x86/kprobes.h index b7bbd25ba2a6..6e6371a856e7 100644 --- a/include/asm-x86/kprobes.h +++ b/include/asm-x86/kprobes.h | |||
@@ -1,5 +1,98 @@ | |||
1 | #ifdef CONFIG_X86_32 | 1 | #ifndef _ASM_KPROBES_H |
2 | # include "kprobes_32.h" | 2 | #define _ASM_KPROBES_H |
3 | #else | 3 | /* |
4 | # include "kprobes_64.h" | 4 | * Kernel Probes (KProbes) |
5 | #endif | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | * | ||
20 | * Copyright (C) IBM Corporation, 2002, 2004 | ||
21 | * | ||
22 | * See arch/x86/kernel/kprobes.c for x86 kprobes history. | ||
23 | */ | ||
24 | #include <linux/types.h> | ||
25 | #include <linux/ptrace.h> | ||
26 | #include <linux/percpu.h> | ||
27 | |||
28 | #define __ARCH_WANT_KPROBES_INSN_SLOT | ||
29 | |||
30 | struct pt_regs; | ||
31 | struct kprobe; | ||
32 | |||
33 | typedef u8 kprobe_opcode_t; | ||
34 | #define BREAKPOINT_INSTRUCTION 0xcc | ||
35 | #define RELATIVEJUMP_INSTRUCTION 0xe9 | ||
36 | #define MAX_INSN_SIZE 16 | ||
37 | #define MAX_STACK_SIZE 64 | ||
38 | #define MIN_STACK_SIZE(ADDR) (((MAX_STACK_SIZE) < \ | ||
39 | (((unsigned long)current_thread_info()) + THREAD_SIZE \ | ||
40 | - (unsigned long)(ADDR))) \ | ||
41 | ? (MAX_STACK_SIZE) \ | ||
42 | : (((unsigned long)current_thread_info()) + THREAD_SIZE \ | ||
43 | - (unsigned long)(ADDR))) | ||
44 | |||
45 | #define ARCH_SUPPORTS_KRETPROBES | ||
46 | #define flush_insn_slot(p) do { } while (0) | ||
47 | |||
48 | extern const int kretprobe_blacklist_size; | ||
49 | |||
50 | void arch_remove_kprobe(struct kprobe *p); | ||
51 | void kretprobe_trampoline(void); | ||
52 | |||
53 | /* Architecture specific copy of original instruction*/ | ||
54 | struct arch_specific_insn { | ||
55 | /* copy of the original instruction */ | ||
56 | kprobe_opcode_t *insn; | ||
57 | /* | ||
58 | * boostable = -1: This instruction type is not boostable. | ||
59 | * boostable = 0: This instruction type is boostable. | ||
60 | * boostable = 1: This instruction has been boosted: we have | ||
61 | * added a relative jump after the instruction copy in insn, | ||
62 | * so no single-step and fixup are needed (unless there's | ||
63 | * a post_handler or break_handler). | ||
64 | */ | ||
65 | int boostable; | ||
66 | }; | ||
67 | |||
68 | struct prev_kprobe { | ||
69 | struct kprobe *kp; | ||
70 | unsigned long status; | ||
71 | unsigned long old_flags; | ||
72 | unsigned long saved_flags; | ||
73 | }; | ||
74 | |||
75 | /* per-cpu kprobe control block */ | ||
76 | struct kprobe_ctlblk { | ||
77 | unsigned long kprobe_status; | ||
78 | unsigned long kprobe_old_flags; | ||
79 | unsigned long kprobe_saved_flags; | ||
80 | unsigned long *jprobe_saved_sp; | ||
81 | struct pt_regs jprobe_saved_regs; | ||
82 | kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; | ||
83 | struct prev_kprobe prev_kprobe; | ||
84 | }; | ||
85 | |||
86 | /* trap3/1 are intr gates for kprobes. So, restore the status of IF, | ||
87 | * if necessary, before executing the original int3/1 (trap) handler. | ||
88 | */ | ||
89 | static inline void restore_interrupts(struct pt_regs *regs) | ||
90 | { | ||
91 | if (regs->flags & IF_MASK) | ||
92 | local_irq_enable(); | ||
93 | } | ||
94 | |||
95 | extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); | ||
96 | extern int kprobe_exceptions_notify(struct notifier_block *self, | ||
97 | unsigned long val, void *data); | ||
98 | #endif /* _ASM_KPROBES_H */ | ||
diff --git a/include/asm-x86/kprobes_32.h b/include/asm-x86/kprobes_32.h deleted file mode 100644 index 94dff09b2ebe..000000000000 --- a/include/asm-x86/kprobes_32.h +++ /dev/null | |||
@@ -1,102 +0,0 @@ | |||
1 | #ifndef _ASM_KPROBES_H | ||
2 | #define _ASM_KPROBES_H | ||
3 | /* | ||
4 | * Kernel Probes (KProbes) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | * | ||
20 | * Copyright (C) IBM Corporation, 2002, 2004 | ||
21 | * | ||
22 | * 2002-Oct Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel | ||
23 | * Probes initial implementation ( includes suggestions from | ||
24 | * Rusty Russell). | ||
25 | * 2004-Oct Prasanna S Panchamukhi <prasanna@in.ibm.com> and Jim Keniston | ||
26 | * kenistoj@us.ibm.com adopted from i386. | ||
27 | */ | ||
28 | #include <linux/types.h> | ||
29 | #include <linux/ptrace.h> | ||
30 | #include <linux/percpu.h> | ||
31 | |||
32 | #define __ARCH_WANT_KPROBES_INSN_SLOT | ||
33 | |||
34 | struct pt_regs; | ||
35 | struct kprobe; | ||
36 | |||
37 | typedef u8 kprobe_opcode_t; | ||
38 | #define BREAKPOINT_INSTRUCTION 0xcc | ||
39 | #define RELATIVEJUMP_INSTRUCTION 0xe9 | ||
40 | #define MAX_INSN_SIZE 16 | ||
41 | #define MAX_STACK_SIZE 64 | ||
42 | #define MIN_STACK_SIZE(ADDR) (((MAX_STACK_SIZE) < \ | ||
43 | (((unsigned long)current_thread_info()) + THREAD_SIZE \ | ||
44 | - (unsigned long)(ADDR))) \ | ||
45 | ? (MAX_STACK_SIZE) \ | ||
46 | : (((unsigned long)current_thread_info()) + THREAD_SIZE \ | ||
47 | - (unsigned long)(ADDR))) | ||
48 | |||
49 | #define ARCH_SUPPORTS_KRETPROBES | ||
50 | #define flush_insn_slot(p) do { } while (0) | ||
51 | |||
52 | extern const int kretprobe_blacklist_size; | ||
53 | |||
54 | void arch_remove_kprobe(struct kprobe *p); | ||
55 | void kretprobe_trampoline(void); | ||
56 | |||
57 | /* Architecture specific copy of original instruction*/ | ||
58 | struct arch_specific_insn { | ||
59 | /* copy of the original instruction */ | ||
60 | kprobe_opcode_t *insn; | ||
61 | /* | ||
62 | * boostable = -1: This instruction type is not boostable. | ||
63 | * boostable = 0: This instruction type is boostable. | ||
64 | * boostable = 1: This instruction has been boosted: we have | ||
65 | * added a relative jump after the instruction copy in insn, | ||
66 | * so no single-step and fixup are needed (unless there's | ||
67 | * a post_handler or break_handler). | ||
68 | */ | ||
69 | int boostable; | ||
70 | }; | ||
71 | |||
72 | struct prev_kprobe { | ||
73 | struct kprobe *kp; | ||
74 | unsigned long status; | ||
75 | unsigned long old_flags; | ||
76 | unsigned long saved_flags; | ||
77 | }; | ||
78 | |||
79 | /* per-cpu kprobe control block */ | ||
80 | struct kprobe_ctlblk { | ||
81 | unsigned long kprobe_status; | ||
82 | unsigned long kprobe_old_flags; | ||
83 | unsigned long kprobe_saved_flags; | ||
84 | unsigned long *jprobe_saved_sp; | ||
85 | struct pt_regs jprobe_saved_regs; | ||
86 | kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; | ||
87 | struct prev_kprobe prev_kprobe; | ||
88 | }; | ||
89 | |||
90 | /* trap3/1 are intr gates for kprobes. So, restore the status of IF, | ||
91 | * if necessary, before executing the original int3/1 (trap) handler. | ||
92 | */ | ||
93 | static inline void restore_interrupts(struct pt_regs *regs) | ||
94 | { | ||
95 | if (regs->flags & IF_MASK) | ||
96 | local_irq_enable(); | ||
97 | } | ||
98 | |||
99 | extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); | ||
100 | extern int kprobe_exceptions_notify(struct notifier_block *self, | ||
101 | unsigned long val, void *data); | ||
102 | #endif /* _ASM_KPROBES_H */ | ||
diff --git a/include/asm-x86/kprobes_64.h b/include/asm-x86/kprobes_64.h deleted file mode 100644 index 94dff09b2ebe..000000000000 --- a/include/asm-x86/kprobes_64.h +++ /dev/null | |||
@@ -1,102 +0,0 @@ | |||
1 | #ifndef _ASM_KPROBES_H | ||
2 | #define _ASM_KPROBES_H | ||
3 | /* | ||
4 | * Kernel Probes (KProbes) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | * | ||
20 | * Copyright (C) IBM Corporation, 2002, 2004 | ||
21 | * | ||
22 | * 2002-Oct Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel | ||
23 | * Probes initial implementation ( includes suggestions from | ||
24 | * Rusty Russell). | ||
25 | * 2004-Oct Prasanna S Panchamukhi <prasanna@in.ibm.com> and Jim Keniston | ||
26 | * kenistoj@us.ibm.com adopted from i386. | ||
27 | */ | ||
28 | #include <linux/types.h> | ||
29 | #include <linux/ptrace.h> | ||
30 | #include <linux/percpu.h> | ||
31 | |||
32 | #define __ARCH_WANT_KPROBES_INSN_SLOT | ||
33 | |||
34 | struct pt_regs; | ||
35 | struct kprobe; | ||
36 | |||
37 | typedef u8 kprobe_opcode_t; | ||
38 | #define BREAKPOINT_INSTRUCTION 0xcc | ||
39 | #define RELATIVEJUMP_INSTRUCTION 0xe9 | ||
40 | #define MAX_INSN_SIZE 16 | ||
41 | #define MAX_STACK_SIZE 64 | ||
42 | #define MIN_STACK_SIZE(ADDR) (((MAX_STACK_SIZE) < \ | ||
43 | (((unsigned long)current_thread_info()) + THREAD_SIZE \ | ||
44 | - (unsigned long)(ADDR))) \ | ||
45 | ? (MAX_STACK_SIZE) \ | ||
46 | : (((unsigned long)current_thread_info()) + THREAD_SIZE \ | ||
47 | - (unsigned long)(ADDR))) | ||
48 | |||
49 | #define ARCH_SUPPORTS_KRETPROBES | ||
50 | #define flush_insn_slot(p) do { } while (0) | ||
51 | |||
52 | extern const int kretprobe_blacklist_size; | ||
53 | |||
54 | void arch_remove_kprobe(struct kprobe *p); | ||
55 | void kretprobe_trampoline(void); | ||
56 | |||
57 | /* Architecture specific copy of original instruction*/ | ||
58 | struct arch_specific_insn { | ||
59 | /* copy of the original instruction */ | ||
60 | kprobe_opcode_t *insn; | ||
61 | /* | ||
62 | * boostable = -1: This instruction type is not boostable. | ||
63 | * boostable = 0: This instruction type is boostable. | ||
64 | * boostable = 1: This instruction has been boosted: we have | ||
65 | * added a relative jump after the instruction copy in insn, | ||
66 | * so no single-step and fixup are needed (unless there's | ||
67 | * a post_handler or break_handler). | ||
68 | */ | ||
69 | int boostable; | ||
70 | }; | ||
71 | |||
72 | struct prev_kprobe { | ||
73 | struct kprobe *kp; | ||
74 | unsigned long status; | ||
75 | unsigned long old_flags; | ||
76 | unsigned long saved_flags; | ||
77 | }; | ||
78 | |||
79 | /* per-cpu kprobe control block */ | ||
80 | struct kprobe_ctlblk { | ||
81 | unsigned long kprobe_status; | ||
82 | unsigned long kprobe_old_flags; | ||
83 | unsigned long kprobe_saved_flags; | ||
84 | unsigned long *jprobe_saved_sp; | ||
85 | struct pt_regs jprobe_saved_regs; | ||
86 | kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; | ||
87 | struct prev_kprobe prev_kprobe; | ||
88 | }; | ||
89 | |||
90 | /* trap3/1 are intr gates for kprobes. So, restore the status of IF, | ||
91 | * if necessary, before executing the original int3/1 (trap) handler. | ||
92 | */ | ||
93 | static inline void restore_interrupts(struct pt_regs *regs) | ||
94 | { | ||
95 | if (regs->flags & IF_MASK) | ||
96 | local_irq_enable(); | ||
97 | } | ||
98 | |||
99 | extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); | ||
100 | extern int kprobe_exceptions_notify(struct notifier_block *self, | ||
101 | unsigned long val, void *data); | ||
102 | #endif /* _ASM_KPROBES_H */ | ||