diff options
Diffstat (limited to 'arch/x86/kernel/kprobes.c')
-rw-r--r-- | arch/x86/kernel/kprobes.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index e948b28a5a9a..7b5169d2b000 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c | |||
@@ -193,6 +193,9 @@ static int __kprobes can_boost(kprobe_opcode_t *opcodes) | |||
193 | kprobe_opcode_t opcode; | 193 | kprobe_opcode_t opcode; |
194 | kprobe_opcode_t *orig_opcodes = opcodes; | 194 | kprobe_opcode_t *orig_opcodes = opcodes; |
195 | 195 | ||
196 | if (search_exception_tables((unsigned long)opcodes)) | ||
197 | return 0; /* Page fault may occur on this address. */ | ||
198 | |||
196 | retry: | 199 | retry: |
197 | if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) | 200 | if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) |
198 | return 0; | 201 | return 0; |
@@ -635,13 +638,13 @@ static void __used __kprobes kretprobe_trampoline_holder(void) | |||
635 | #else | 638 | #else |
636 | " pushf\n" | 639 | " pushf\n" |
637 | /* | 640 | /* |
638 | * Skip cs, ip, orig_ax. | 641 | * Skip cs, ip, orig_ax and gs. |
639 | * trampoline_handler() will plug in these values | 642 | * trampoline_handler() will plug in these values |
640 | */ | 643 | */ |
641 | " subl $12, %esp\n" | 644 | " subl $16, %esp\n" |
642 | " pushl %fs\n" | 645 | " pushl %fs\n" |
643 | " pushl %ds\n" | ||
644 | " pushl %es\n" | 646 | " pushl %es\n" |
647 | " pushl %ds\n" | ||
645 | " pushl %eax\n" | 648 | " pushl %eax\n" |
646 | " pushl %ebp\n" | 649 | " pushl %ebp\n" |
647 | " pushl %edi\n" | 650 | " pushl %edi\n" |
@@ -652,10 +655,10 @@ static void __used __kprobes kretprobe_trampoline_holder(void) | |||
652 | " movl %esp, %eax\n" | 655 | " movl %esp, %eax\n" |
653 | " call trampoline_handler\n" | 656 | " call trampoline_handler\n" |
654 | /* Move flags to cs */ | 657 | /* Move flags to cs */ |
655 | " movl 52(%esp), %edx\n" | 658 | " movl 56(%esp), %edx\n" |
656 | " movl %edx, 48(%esp)\n" | 659 | " movl %edx, 52(%esp)\n" |
657 | /* Replace saved flags with true return address. */ | 660 | /* Replace saved flags with true return address. */ |
658 | " movl %eax, 52(%esp)\n" | 661 | " movl %eax, 56(%esp)\n" |
659 | " popl %ebx\n" | 662 | " popl %ebx\n" |
660 | " popl %ecx\n" | 663 | " popl %ecx\n" |
661 | " popl %edx\n" | 664 | " popl %edx\n" |
@@ -663,8 +666,8 @@ static void __used __kprobes kretprobe_trampoline_holder(void) | |||
663 | " popl %edi\n" | 666 | " popl %edi\n" |
664 | " popl %ebp\n" | 667 | " popl %ebp\n" |
665 | " popl %eax\n" | 668 | " popl %eax\n" |
666 | /* Skip ip, orig_ax, es, ds, fs */ | 669 | /* Skip ds, es, fs, gs, orig_ax and ip */ |
667 | " addl $20, %esp\n" | 670 | " addl $24, %esp\n" |
668 | " popf\n" | 671 | " popf\n" |
669 | #endif | 672 | #endif |
670 | " ret\n"); | 673 | " ret\n"); |
@@ -688,6 +691,7 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs) | |||
688 | regs->cs = __KERNEL_CS; | 691 | regs->cs = __KERNEL_CS; |
689 | #else | 692 | #else |
690 | regs->cs = __KERNEL_CS | get_kernel_rpl(); | 693 | regs->cs = __KERNEL_CS | get_kernel_rpl(); |
694 | regs->gs = 0; | ||
691 | #endif | 695 | #endif |
692 | regs->ip = trampoline_address; | 696 | regs->ip = trampoline_address; |
693 | regs->orig_ax = ~0UL; | 697 | regs->orig_ax = ~0UL; |