diff options
| author | Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> | 2014-04-17 04:18:14 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2014-04-24 04:26:38 -0400 |
| commit | 9326638cbee2d36b051ed2a69f3e4e107e5f86bd (patch) | |
| tree | 995433e24b135a2858765519aec8fe9e889afd68 | |
| parent | 9c54b6164eeb292a0eac86c6913bd8daaff35e62 (diff) | |
kprobes, x86: Use NOKPROBE_SYMBOL() instead of __kprobes annotation
Use NOKPROBE_SYMBOL macro for protecting functions
from kprobes instead of __kprobes annotation under
arch/x86.
This applies nokprobe_inline annotation for some cases,
because NOKPROBE_SYMBOL() will inhibit inlining by
referring the symbol address.
This just folds a bunch of previous NOKPROBE_SYMBOL()
cleanup patches for x86 to one patch.
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Link: http://lkml.kernel.org/r/20140417081814.26341.51656.stgit@ltc230.yrl.intra.hitachi.co.jp
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Borislav Petkov <bp@suse.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Fernando Luis Vázquez Cao <fernando_b1@lab.ntt.co.jp>
Cc: Gleb Natapov <gleb@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Jonathan Lebon <jlebon@redhat.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Matt Fleming <matt.fleming@intel.com>
Cc: Michel Lespinasse <walken@google.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Raghavendra K T <raghavendra.kt@linux.vnet.ibm.com>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Seiji Aguchi <seiji.aguchi@hds.com>
Cc: Srivatsa Vaddagiri <vatsa@linux.vnet.ibm.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Vineet Gupta <vgupta@synopsys.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
| -rw-r--r-- | arch/x86/include/asm/traps.h | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/hw_nmi.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_amd_ibs.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/dumpstack.c | 9 | ||||
| -rw-r--r-- | arch/x86/kernel/kprobes/core.c | 77 | ||||
| -rw-r--r-- | arch/x86/kernel/kprobes/ftrace.c | 15 | ||||
| -rw-r--r-- | arch/x86/kernel/kprobes/opt.c | 8 | ||||
| -rw-r--r-- | arch/x86/kernel/kvm.c | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/nmi.c | 18 | ||||
| -rw-r--r-- | arch/x86/kernel/traps.c | 20 | ||||
| -rw-r--r-- | arch/x86/mm/fault.c | 29 |
12 files changed, 122 insertions, 69 deletions
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h index 58d66fe06b61..ca32508c58c5 100644 --- a/arch/x86/include/asm/traps.h +++ b/arch/x86/include/asm/traps.h | |||
| @@ -68,7 +68,7 @@ dotraplinkage void do_segment_not_present(struct pt_regs *, long); | |||
| 68 | dotraplinkage void do_stack_segment(struct pt_regs *, long); | 68 | dotraplinkage void do_stack_segment(struct pt_regs *, long); |
| 69 | #ifdef CONFIG_X86_64 | 69 | #ifdef CONFIG_X86_64 |
| 70 | dotraplinkage void do_double_fault(struct pt_regs *, long); | 70 | dotraplinkage void do_double_fault(struct pt_regs *, long); |
| 71 | asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *); | 71 | asmlinkage struct pt_regs *sync_regs(struct pt_regs *); |
| 72 | #endif | 72 | #endif |
| 73 | dotraplinkage void do_general_protection(struct pt_regs *, long); | 73 | dotraplinkage void do_general_protection(struct pt_regs *, long); |
| 74 | dotraplinkage void do_page_fault(struct pt_regs *, unsigned long); | 74 | dotraplinkage void do_page_fault(struct pt_regs *, unsigned long); |
diff --git a/arch/x86/kernel/apic/hw_nmi.c b/arch/x86/kernel/apic/hw_nmi.c index a698d7165c96..73eb5b336f63 100644 --- a/arch/x86/kernel/apic/hw_nmi.c +++ b/arch/x86/kernel/apic/hw_nmi.c | |||
| @@ -60,7 +60,7 @@ void arch_trigger_all_cpu_backtrace(void) | |||
| 60 | smp_mb__after_clear_bit(); | 60 | smp_mb__after_clear_bit(); |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | static int __kprobes | 63 | static int |
| 64 | arch_trigger_all_cpu_backtrace_handler(unsigned int cmd, struct pt_regs *regs) | 64 | arch_trigger_all_cpu_backtrace_handler(unsigned int cmd, struct pt_regs *regs) |
| 65 | { | 65 | { |
| 66 | int cpu; | 66 | int cpu; |
| @@ -80,6 +80,7 @@ arch_trigger_all_cpu_backtrace_handler(unsigned int cmd, struct pt_regs *regs) | |||
| 80 | 80 | ||
| 81 | return NMI_DONE; | 81 | return NMI_DONE; |
| 82 | } | 82 | } |
| 83 | NOKPROBE_SYMBOL(arch_trigger_all_cpu_backtrace_handler); | ||
| 83 | 84 | ||
| 84 | static int __init register_trigger_all_cpu_backtrace(void) | 85 | static int __init register_trigger_all_cpu_backtrace(void) |
| 85 | { | 86 | { |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index ae407f7226c8..5fc8771979ba 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
| @@ -1292,7 +1292,7 @@ void perf_events_lapic_init(void) | |||
| 1292 | apic_write(APIC_LVTPC, APIC_DM_NMI); | 1292 | apic_write(APIC_LVTPC, APIC_DM_NMI); |
| 1293 | } | 1293 | } |
| 1294 | 1294 | ||
| 1295 | static int __kprobes | 1295 | static int |
| 1296 | perf_event_nmi_handler(unsigned int cmd, struct pt_regs *regs) | 1296 | perf_event_nmi_handler(unsigned int cmd, struct pt_regs *regs) |
| 1297 | { | 1297 | { |
| 1298 | u64 start_clock; | 1298 | u64 start_clock; |
| @@ -1310,6 +1310,7 @@ perf_event_nmi_handler(unsigned int cmd, struct pt_regs *regs) | |||
| 1310 | 1310 | ||
| 1311 | return ret; | 1311 | return ret; |
| 1312 | } | 1312 | } |
| 1313 | NOKPROBE_SYMBOL(perf_event_nmi_handler); | ||
| 1313 | 1314 | ||
| 1314 | struct event_constraint emptyconstraint; | 1315 | struct event_constraint emptyconstraint; |
| 1315 | struct event_constraint unconstrained; | 1316 | struct event_constraint unconstrained; |
diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c index 4c36bbe3173a..cbb1be3ed9e4 100644 --- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c +++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c | |||
| @@ -593,7 +593,7 @@ out: | |||
| 593 | return 1; | 593 | return 1; |
| 594 | } | 594 | } |
| 595 | 595 | ||
| 596 | static int __kprobes | 596 | static int |
| 597 | perf_ibs_nmi_handler(unsigned int cmd, struct pt_regs *regs) | 597 | perf_ibs_nmi_handler(unsigned int cmd, struct pt_regs *regs) |
| 598 | { | 598 | { |
| 599 | int handled = 0; | 599 | int handled = 0; |
| @@ -606,6 +606,7 @@ perf_ibs_nmi_handler(unsigned int cmd, struct pt_regs *regs) | |||
| 606 | 606 | ||
| 607 | return handled; | 607 | return handled; |
| 608 | } | 608 | } |
| 609 | NOKPROBE_SYMBOL(perf_ibs_nmi_handler); | ||
| 609 | 610 | ||
| 610 | static __init int perf_ibs_pmu_init(struct perf_ibs *perf_ibs, char *name) | 611 | static __init int perf_ibs_pmu_init(struct perf_ibs *perf_ibs, char *name) |
| 611 | { | 612 | { |
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index d9c12d3022a7..b74ebc7c4402 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c | |||
| @@ -200,7 +200,7 @@ static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED; | |||
| 200 | static int die_owner = -1; | 200 | static int die_owner = -1; |
| 201 | static unsigned int die_nest_count; | 201 | static unsigned int die_nest_count; |
| 202 | 202 | ||
| 203 | unsigned __kprobes long oops_begin(void) | 203 | unsigned long oops_begin(void) |
| 204 | { | 204 | { |
| 205 | int cpu; | 205 | int cpu; |
| 206 | unsigned long flags; | 206 | unsigned long flags; |
| @@ -223,8 +223,9 @@ unsigned __kprobes long oops_begin(void) | |||
| 223 | return flags; | 223 | return flags; |
| 224 | } | 224 | } |
| 225 | EXPORT_SYMBOL_GPL(oops_begin); | 225 | EXPORT_SYMBOL_GPL(oops_begin); |
| 226 | NOKPROBE_SYMBOL(oops_begin); | ||
| 226 | 227 | ||
| 227 | void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) | 228 | void oops_end(unsigned long flags, struct pt_regs *regs, int signr) |
| 228 | { | 229 | { |
| 229 | if (regs && kexec_should_crash(current)) | 230 | if (regs && kexec_should_crash(current)) |
| 230 | crash_kexec(regs); | 231 | crash_kexec(regs); |
| @@ -247,8 +248,9 @@ void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) | |||
| 247 | panic("Fatal exception"); | 248 | panic("Fatal exception"); |
| 248 | do_exit(signr); | 249 | do_exit(signr); |
| 249 | } | 250 | } |
| 251 | NOKPROBE_SYMBOL(oops_end); | ||
| 250 | 252 | ||
| 251 | int __kprobes __die(const char *str, struct pt_regs *regs, long err) | 253 | int __die(const char *str, struct pt_regs *regs, long err) |
| 252 | { | 254 | { |
| 253 | #ifdef CONFIG_X86_32 | 255 | #ifdef CONFIG_X86_32 |
| 254 | unsigned short ss; | 256 | unsigned short ss; |
| @@ -291,6 +293,7 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err) | |||
| 291 | #endif | 293 | #endif |
| 292 | return 0; | 294 | return 0; |
| 293 | } | 295 | } |
| 296 | NOKPROBE_SYMBOL(__die); | ||
| 294 | 297 | ||
| 295 | /* | 298 | /* |
| 296 | * This is gone through when something in the kernel has done something bad | 299 | * This is gone through when something in the kernel has done something bad |
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index bd717137ae77..7596df664901 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c | |||
| @@ -112,7 +112,8 @@ struct kretprobe_blackpoint kretprobe_blacklist[] = { | |||
| 112 | 112 | ||
| 113 | const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist); | 113 | const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist); |
| 114 | 114 | ||
| 115 | static void __kprobes __synthesize_relative_insn(void *from, void *to, u8 op) | 115 | static nokprobe_inline void |
| 116 | __synthesize_relative_insn(void *from, void *to, u8 op) | ||
| 116 | { | 117 | { |
| 117 | struct __arch_relative_insn { | 118 | struct __arch_relative_insn { |
| 118 | u8 op; | 119 | u8 op; |
| @@ -125,21 +126,23 @@ static void __kprobes __synthesize_relative_insn(void *from, void *to, u8 op) | |||
| 125 | } | 126 | } |
| 126 | 127 | ||
| 127 | /* Insert a jump instruction at address 'from', which jumps to address 'to'.*/ | 128 | /* Insert a jump instruction at address 'from', which jumps to address 'to'.*/ |
| 128 | void __kprobes synthesize_reljump(void *from, void *to) | 129 | void synthesize_reljump(void *from, void *to) |
| 129 | { | 130 | { |
| 130 | __synthesize_relative_insn(from, to, RELATIVEJUMP_OPCODE); | 131 | __synthesize_relative_insn(from, to, RELATIVEJUMP_OPCODE); |
| 131 | } | 132 | } |
| 133 | NOKPROBE_SYMBOL(synthesize_reljump); | ||
| 132 | 134 | ||
| 133 | /* Insert a call instruction at address 'from', which calls address 'to'.*/ | 135 | /* Insert a call instruction at address 'from', which calls address 'to'.*/ |
| 134 | void __kprobes synthesize_relcall(void *from, void *to) | 136 | void synthesize_relcall(void *from, void *to) |
| 135 | { | 137 | { |
| 136 | __synthesize_relative_insn(from, to, RELATIVECALL_OPCODE); | 138 | __synthesize_relative_insn(from, to, RELATIVECALL_OPCODE); |
| 137 | } | 139 | } |
| 140 | NOKPROBE_SYMBOL(synthesize_relcall); | ||
| 138 | 141 | ||
| 139 | /* | 142 | /* |
| 140 | * Skip the prefixes of the instruction. | 143 | * Skip the prefixes of the instruction. |
| 141 | */ | 144 | */ |
| 142 | static kprobe_opcode_t *__kprobes skip_prefixes(kprobe_opcode_t *insn) | 145 | static kprobe_opcode_t *skip_prefixes(kprobe_opcode_t *insn) |
| 143 | { | 146 | { |
| 144 | insn_attr_t attr; | 147 | insn_attr_t attr; |
| 145 | 148 | ||
| @@ -154,6 +157,7 @@ static kprobe_opcode_t *__kprobes skip_prefixes(kprobe_opcode_t *insn) | |||
| 154 | #endif | 157 | #endif |
| 155 | return insn; | 158 | return insn; |
| 156 | } | 159 | } |
| 160 | NOKPROBE_SYMBOL(skip_prefixes); | ||
| 157 | 161 | ||
| 158 | /* | 162 | /* |
| 159 | * Returns non-zero if opcode is boostable. | 163 | * Returns non-zero if opcode is boostable. |
| @@ -425,7 +429,8 @@ void arch_remove_kprobe(struct kprobe *p) | |||
| 425 | } | 429 | } |
| 426 | } | 430 | } |
| 427 | 431 | ||
| 428 | static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) | 432 | static nokprobe_inline void |
| 433 | save_previous_kprobe(struct kprobe_ctlblk *kcb) | ||
| 429 | { | 434 | { |
| 430 | kcb->prev_kprobe.kp = kprobe_running(); | 435 | kcb->prev_kprobe.kp = kprobe_running(); |
| 431 | kcb->prev_kprobe.status = kcb->kprobe_status; | 436 | kcb->prev_kprobe.status = kcb->kprobe_status; |
| @@ -433,7 +438,8 @@ static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) | |||
| 433 | kcb->prev_kprobe.saved_flags = kcb->kprobe_saved_flags; | 438 | kcb->prev_kprobe.saved_flags = kcb->kprobe_saved_flags; |
| 434 | } | 439 | } |
| 435 | 440 | ||
| 436 | static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) | 441 | static nokprobe_inline void |
| 442 | restore_previous_kprobe(struct kprobe_ctlblk *kcb) | ||
| 437 | { | 443 | { |
| 438 | __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp); | 444 | __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp); |
| 439 | kcb->kprobe_status = kcb->prev_kprobe.status; | 445 | kcb->kprobe_status = kcb->prev_kprobe.status; |
| @@ -441,8 +447,9 @@ static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) | |||
| 441 | kcb->kprobe_saved_flags = kcb->prev_kprobe.saved_flags; | 447 | kcb->kprobe_saved_flags = kcb->prev_kprobe.saved_flags; |
| 442 | } | 448 | } |
| 443 | 449 | ||
| 444 | static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, | 450 | static nokprobe_inline void |
| 445 | struct kprobe_ctlblk *kcb) | 451 | set_current_kprobe(struct kprobe *p, struct pt_regs *regs, |
| 452 | struct kprobe_ctlblk *kcb) | ||
| 446 | { | 453 | { |
| 447 | __this_cpu_write(current_kprobe, p); | 454 | __this_cpu_write(current_kprobe, p); |
| 448 | kcb->kprobe_saved_flags = kcb->kprobe_old_flags | 455 | kcb->kprobe_saved_flags = kcb->kprobe_old_flags |
| @@ -451,7 +458,7 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, | |||
| 451 | kcb->kprobe_saved_flags &= ~X86_EFLAGS_IF; | 458 | kcb->kprobe_saved_flags &= ~X86_EFLAGS_IF; |
| 452 | } | 459 | } |
| 453 | 460 | ||
| 454 | static void __kprobes clear_btf(void) | 461 | static nokprobe_inline void clear_btf(void) |
| 455 | { | 462 | { |
| 456 | if (test_thread_flag(TIF_BLOCKSTEP)) { | 463 | if (test_thread_flag(TIF_BLOCKSTEP)) { |
| 457 | unsigned long debugctl = get_debugctlmsr(); | 464 | unsigned long debugctl = get_debugctlmsr(); |
| @@ -461,7 +468,7 @@ static void __kprobes clear_btf(void) | |||
| 461 | } | 468 | } |
| 462 | } | 469 | } |
| 463 | 470 | ||
| 464 | static void __kprobes restore_btf(void) | 471 | static nokprobe_inline void restore_btf(void) |
| 465 | { | 472 | { |
| 466 | if (test_thread_flag(TIF_BLOCKSTEP)) { | 473 | if (test_thread_flag(TIF_BLOCKSTEP)) { |
| 467 | unsigned long debugctl = get_debugctlmsr(); | 474 | unsigned long debugctl = get_debugctlmsr(); |
| @@ -471,8 +478,7 @@ static void __kprobes restore_btf(void) | |||
| 471 | } | 478 | } |
| 472 | } | 479 | } |
| 473 | 480 | ||
| 474 | void __kprobes | 481 | void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) |
| 475 | arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) | ||
| 476 | { | 482 | { |
| 477 | unsigned long *sara = stack_addr(regs); | 483 | unsigned long *sara = stack_addr(regs); |
| 478 | 484 | ||
| @@ -481,9 +487,10 @@ arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) | |||
| 481 | /* Replace the return addr with trampoline addr */ | 487 | /* Replace the return addr with trampoline addr */ |
| 482 | *sara = (unsigned long) &kretprobe_trampoline; | 488 | *sara = (unsigned long) &kretprobe_trampoline; |
| 483 | } | 489 | } |
| 490 | NOKPROBE_SYMBOL(arch_prepare_kretprobe); | ||
| 484 | 491 | ||
| 485 | static void __kprobes | 492 | static void setup_singlestep(struct kprobe *p, struct pt_regs *regs, |
| 486 | setup_singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb, int reenter) | 493 | struct kprobe_ctlblk *kcb, int reenter) |
| 487 | { | 494 | { |
| 488 | if (setup_detour_execution(p, regs, reenter)) | 495 | if (setup_detour_execution(p, regs, reenter)) |
| 489 | return; | 496 | return; |
| @@ -519,14 +526,15 @@ setup_singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *k | |||
| 519 | else | 526 | else |
| 520 | regs->ip = (unsigned long)p->ainsn.insn; | 527 | regs->ip = (unsigned long)p->ainsn.insn; |
| 521 | } | 528 | } |
| 529 | NOKPROBE_SYMBOL(setup_singlestep); | ||
| 522 | 530 | ||
| 523 | /* | 531 | /* |
| 524 | * We have reentered the kprobe_handler(), since another probe was hit while | 532 | * We have reentered the kprobe_handler(), since another probe was hit while |
| 525 | * within the handler. We save the original kprobes variables and just single | 533 | * within the handler. We save the original kprobes variables and just single |
| 526 | * step on the instruction of the new probe without calling any user handlers. | 534 | * step on the instruction of the new probe without calling any user handlers. |
| 527 | */ | 535 | */ |
| 528 | static int __kprobes | 536 | static int reenter_kprobe(struct kprobe *p, struct pt_regs *regs, |
| 529 | reenter_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) | 537 | struct kprobe_ctlblk *kcb) |
| 530 | { | 538 | { |
| 531 | switch (kcb->kprobe_status) { | 539 | switch (kcb->kprobe_status) { |
| 532 | case KPROBE_HIT_SSDONE: | 540 | case KPROBE_HIT_SSDONE: |
| @@ -554,12 +562,13 @@ reenter_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb | |||
| 554 | 562 | ||
| 555 | return 1; | 563 | return 1; |
| 556 | } | 564 | } |
| 565 | NOKPROBE_SYMBOL(reenter_kprobe); | ||
| 557 | 566 | ||
| 558 | /* | 567 | /* |
| 559 | * Interrupts are disabled on entry as trap3 is an interrupt gate and they | 568 | * Interrupts are disabled on entry as trap3 is an interrupt gate and they |
| 560 | * remain disabled throughout this function. | 569 | * remain disabled throughout this function. |
| 561 | */ | 570 | */ |
| 562 | int __kprobes kprobe_int3_handler(struct pt_regs *regs) | 571 | int kprobe_int3_handler(struct pt_regs *regs) |
| 563 | { | 572 | { |
| 564 | kprobe_opcode_t *addr; | 573 | kprobe_opcode_t *addr; |
| 565 | struct kprobe *p; | 574 | struct kprobe *p; |
| @@ -622,12 +631,13 @@ int __kprobes kprobe_int3_handler(struct pt_regs *regs) | |||
| 622 | preempt_enable_no_resched(); | 631 | preempt_enable_no_resched(); |
| 623 | return 0; | 632 | return 0; |
| 624 | } | 633 | } |
| 634 | NOKPROBE_SYMBOL(kprobe_int3_handler); | ||
| 625 | 635 | ||
| 626 | /* | 636 | /* |
| 627 | * When a retprobed function returns, this code saves registers and | 637 | * When a retprobed function returns, this code saves registers and |
| 628 | * calls trampoline_handler() runs, which calls the kretprobe's handler. | 638 | * calls trampoline_handler() runs, which calls the kretprobe's handler. |
| 629 | */ | 639 | */ |
| 630 | static void __used __kprobes kretprobe_trampoline_holder(void) | 640 | static void __used kretprobe_trampoline_holder(void) |
| 631 | { | 641 | { |
| 632 | asm volatile ( | 642 | asm volatile ( |
| 633 | ".global kretprobe_trampoline\n" | 643 | ".global kretprobe_trampoline\n" |
| @@ -658,11 +668,13 @@ static void __used __kprobes kretprobe_trampoline_holder(void) | |||
| 658 | #endif | 668 | #endif |
| 659 | " ret\n"); | 669 | " ret\n"); |
| 660 | } | 670 | } |
| 671 | NOKPROBE_SYMBOL(kretprobe_trampoline_holder); | ||
| 672 | NOKPROBE_SYMBOL(kretprobe_trampoline); | ||
| 661 | 673 | ||
| 662 | /* | 674 | /* |
| 663 | * Called from kretprobe_trampoline | 675 | * Called from kretprobe_trampoline |
| 664 | */ | 676 | */ |
| 665 | __visible __used __kprobes void *trampoline_handler(struct pt_regs *regs) | 677 | __visible __used void *trampoline_handler(struct pt_regs *regs) |
| 666 | { | 678 | { |
| 667 | struct kretprobe_instance *ri = NULL; | 679 | struct kretprobe_instance *ri = NULL; |
| 668 | struct hlist_head *head, empty_rp; | 680 | struct hlist_head *head, empty_rp; |
| @@ -748,6 +760,7 @@ __visible __used __kprobes void *trampoline_handler(struct pt_regs *regs) | |||
| 748 | } | 760 | } |
| 749 | return (void *)orig_ret_address; | 761 | return (void *)orig_ret_address; |
| 750 | } | 762 | } |
| 763 | NOKPROBE_SYMBOL(trampoline_handler); | ||
| 751 | 764 | ||
| 752 | /* | 765 | /* |
| 753 | * Called after single-stepping. p->addr is the address of the | 766 | * Called after single-stepping. p->addr is the address of the |
| @@ -776,8 +789,8 @@ __visible __used __kprobes void *trampoline_handler(struct pt_regs *regs) | |||
| 776 | * jump instruction after the copied instruction, that jumps to the next | 789 | * jump instruction after the copied instruction, that jumps to the next |
| 777 | * instruction after the probepoint. | 790 | * instruction after the probepoint. |
| 778 | */ | 791 | */ |
| 779 | static void __kprobes | 792 | static void resume_execution(struct kprobe *p, struct pt_regs *regs, |
| 780 | resume_execution(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) | 793 | struct kprobe_ctlblk *kcb) |
| 781 | { | 794 | { |
| 782 | unsigned long *tos = stack_addr(regs); | 795 | unsigned long *tos = stack_addr(regs); |
| 783 | unsigned long copy_ip = (unsigned long)p->ainsn.insn; | 796 | unsigned long copy_ip = (unsigned long)p->ainsn.insn; |
| @@ -852,12 +865,13 @@ resume_execution(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *k | |||
| 852 | no_change: | 865 | no_change: |
| 853 | restore_btf(); | 866 | restore_btf(); |
| 854 | } | 867 | } |
| 868 | NOKPROBE_SYMBOL(resume_execution); | ||
| 855 | 869 | ||
| 856 | /* | 870 | /* |
| 857 | * Interrupts are disabled on entry as trap1 is an interrupt gate and they | 871 | * Interrupts are disabled on entry as trap1 is an interrupt gate and they |
| 858 | * remain disabled throughout this function. | 872 | * remain disabled throughout this function. |
| 859 | */ | 873 | */ |
| 860 | int __kprobes kprobe_debug_handler(struct pt_regs *regs) | 874 | int kprobe_debug_handler(struct pt_regs *regs) |
| 861 | { | 875 | { |
| 862 | struct kprobe *cur = kprobe_running(); | 876 | struct kprobe *cur = kprobe_running(); |
| 863 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 877 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
| @@ -892,8 +906,9 @@ out: | |||
| 892 | 906 | ||
| 893 | return 1; | 907 | return 1; |
| 894 | } | 908 | } |
| 909 | NOKPROBE_SYMBOL(kprobe_debug_handler); | ||
| 895 | 910 | ||
| 896 | int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) | 911 | int kprobe_fault_handler(struct pt_regs *regs, int trapnr) |
| 897 | { | 912 | { |
| 898 | struct kprobe *cur = kprobe_running(); | 913 | struct kprobe *cur = kprobe_running(); |
| 899 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 914 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
| @@ -950,12 +965,13 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) | |||
| 950 | 965 | ||
| 951 | return 0; | 966 | return 0; |
| 952 | } | 967 | } |
| 968 | NOKPROBE_SYMBOL(kprobe_fault_handler); | ||
| 953 | 969 | ||
| 954 | /* | 970 | /* |
| 955 | * Wrapper routine for handling exceptions. | 971 | * Wrapper routine for handling exceptions. |
| 956 | */ | 972 | */ |
| 957 | int __kprobes | 973 | int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, |
| 958 | kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *data) | 974 | void *data) |
| 959 | { | 975 | { |
| 960 | struct die_args *args = data; | 976 | struct die_args *args = data; |
| 961 | int ret = NOTIFY_DONE; | 977 | int ret = NOTIFY_DONE; |
| @@ -975,8 +991,9 @@ kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *d | |||
| 975 | } | 991 | } |
| 976 | return ret; | 992 | return ret; |
| 977 | } | 993 | } |
| 994 | NOKPROBE_SYMBOL(kprobe_exceptions_notify); | ||
| 978 | 995 | ||
| 979 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | 996 | int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) |
| 980 | { | 997 | { |
| 981 | struct jprobe *jp = container_of(p, struct jprobe, kp); | 998 | struct jprobe *jp = container_of(p, struct jprobe, kp); |
| 982 | unsigned long addr; | 999 | unsigned long addr; |
| @@ -1000,8 +1017,9 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
| 1000 | regs->ip = (unsigned long)(jp->entry); | 1017 | regs->ip = (unsigned long)(jp->entry); |
| 1001 | return 1; | 1018 | return 1; |
| 1002 | } | 1019 | } |
| 1020 | NOKPROBE_SYMBOL(setjmp_pre_handler); | ||
| 1003 | 1021 | ||
| 1004 | void __kprobes jprobe_return(void) | 1022 | void jprobe_return(void) |
| 1005 | { | 1023 | { |
| 1006 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 1024 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
| 1007 | 1025 | ||
| @@ -1017,8 +1035,10 @@ void __kprobes jprobe_return(void) | |||
| 1017 | " nop \n"::"b" | 1035 | " nop \n"::"b" |
| 1018 | (kcb->jprobe_saved_sp):"memory"); | 1036 | (kcb->jprobe_saved_sp):"memory"); |
| 1019 | } | 1037 | } |
| 1038 | NOKPROBE_SYMBOL(jprobe_return); | ||
| 1039 | NOKPROBE_SYMBOL(jprobe_return_end); | ||
| 1020 | 1040 | ||
| 1021 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | 1041 | int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) |
| 1022 | { | 1042 | { |
| 1023 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 1043 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
| 1024 | u8 *addr = (u8 *) (regs->ip - 1); | 1044 | u8 *addr = (u8 *) (regs->ip - 1); |
| @@ -1046,6 +1066,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | |||
| 1046 | } | 1066 | } |
| 1047 | return 0; | 1067 | return 0; |
| 1048 | } | 1068 | } |
| 1069 | NOKPROBE_SYMBOL(longjmp_break_handler); | ||
| 1049 | 1070 | ||
| 1050 | bool arch_within_kprobe_blacklist(unsigned long addr) | 1071 | bool arch_within_kprobe_blacklist(unsigned long addr) |
| 1051 | { | 1072 | { |
diff --git a/arch/x86/kernel/kprobes/ftrace.c b/arch/x86/kernel/kprobes/ftrace.c index dcaa1310ccfd..717b02a22e67 100644 --- a/arch/x86/kernel/kprobes/ftrace.c +++ b/arch/x86/kernel/kprobes/ftrace.c | |||
| @@ -25,8 +25,9 @@ | |||
| 25 | 25 | ||
| 26 | #include "common.h" | 26 | #include "common.h" |
| 27 | 27 | ||
| 28 | static int __skip_singlestep(struct kprobe *p, struct pt_regs *regs, | 28 | static nokprobe_inline |
| 29 | struct kprobe_ctlblk *kcb) | 29 | int __skip_singlestep(struct kprobe *p, struct pt_regs *regs, |
| 30 | struct kprobe_ctlblk *kcb) | ||
| 30 | { | 31 | { |
| 31 | /* | 32 | /* |
| 32 | * Emulate singlestep (and also recover regs->ip) | 33 | * Emulate singlestep (and also recover regs->ip) |
| @@ -41,18 +42,19 @@ static int __skip_singlestep(struct kprobe *p, struct pt_regs *regs, | |||
| 41 | return 1; | 42 | return 1; |
| 42 | } | 43 | } |
| 43 | 44 | ||
| 44 | int __kprobes skip_singlestep(struct kprobe *p, struct pt_regs *regs, | 45 | int skip_singlestep(struct kprobe *p, struct pt_regs *regs, |
| 45 | struct kprobe_ctlblk *kcb) | 46 | struct kprobe_ctlblk *kcb) |
| 46 | { | 47 | { |
| 47 | if (kprobe_ftrace(p)) | 48 | if (kprobe_ftrace(p)) |
| 48 | return __skip_singlestep(p, regs, kcb); | 49 | return __skip_singlestep(p, regs, kcb); |
| 49 | else | 50 | else |
| 50 | return 0; | 51 | return 0; |
| 51 | } | 52 | } |
| 53 | NOKPROBE_SYMBOL(skip_singlestep); | ||
| 52 | 54 | ||
| 53 | /* Ftrace callback handler for kprobes */ | 55 | /* Ftrace callback handler for kprobes */ |
| 54 | void __kprobes kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, | 56 | void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, |
| 55 | struct ftrace_ops *ops, struct pt_regs *regs) | 57 | struct ftrace_ops *ops, struct pt_regs *regs) |
| 56 | { | 58 | { |
| 57 | struct kprobe *p; | 59 | struct kprobe *p; |
| 58 | struct kprobe_ctlblk *kcb; | 60 | struct kprobe_ctlblk *kcb; |
| @@ -84,6 +86,7 @@ void __kprobes kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, | |||
| 84 | end: | 86 | end: |
| 85 | local_irq_restore(flags); | 87 | local_irq_restore(flags); |
| 86 | } | 88 | } |
| 89 | NOKPROBE_SYMBOL(kprobe_ftrace_handler); | ||
| 87 | 90 | ||
| 88 | int arch_prepare_kprobe_ftrace(struct kprobe *p) | 91 | int arch_prepare_kprobe_ftrace(struct kprobe *p) |
| 89 | { | 92 | { |
diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c index fba7fb075e8a..f304773285ae 100644 --- a/arch/x86/kernel/kprobes/opt.c +++ b/arch/x86/kernel/kprobes/opt.c | |||
| @@ -138,7 +138,8 @@ asm ( | |||
| 138 | #define INT3_SIZE sizeof(kprobe_opcode_t) | 138 | #define INT3_SIZE sizeof(kprobe_opcode_t) |
| 139 | 139 | ||
| 140 | /* Optimized kprobe call back function: called from optinsn */ | 140 | /* Optimized kprobe call back function: called from optinsn */ |
| 141 | static void __kprobes optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs) | 141 | static void |
| 142 | optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs) | ||
| 142 | { | 143 | { |
| 143 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 144 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
| 144 | unsigned long flags; | 145 | unsigned long flags; |
| @@ -168,6 +169,7 @@ static void __kprobes optimized_callback(struct optimized_kprobe *op, struct pt_ | |||
| 168 | } | 169 | } |
| 169 | local_irq_restore(flags); | 170 | local_irq_restore(flags); |
| 170 | } | 171 | } |
| 172 | NOKPROBE_SYMBOL(optimized_callback); | ||
| 171 | 173 | ||
| 172 | static int copy_optimized_instructions(u8 *dest, u8 *src) | 174 | static int copy_optimized_instructions(u8 *dest, u8 *src) |
| 173 | { | 175 | { |
| @@ -424,8 +426,7 @@ extern void arch_unoptimize_kprobes(struct list_head *oplist, | |||
| 424 | } | 426 | } |
| 425 | } | 427 | } |
| 426 | 428 | ||
| 427 | int __kprobes | 429 | int setup_detour_execution(struct kprobe *p, struct pt_regs *regs, int reenter) |
| 428 | setup_detour_execution(struct kprobe *p, struct pt_regs *regs, int reenter) | ||
| 429 | { | 430 | { |
| 430 | struct optimized_kprobe *op; | 431 | struct optimized_kprobe *op; |
| 431 | 432 | ||
| @@ -441,3 +442,4 @@ setup_detour_execution(struct kprobe *p, struct pt_regs *regs, int reenter) | |||
| 441 | } | 442 | } |
| 442 | return 0; | 443 | return 0; |
| 443 | } | 444 | } |
| 445 | NOKPROBE_SYMBOL(setup_detour_execution); | ||
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 0331cb389d68..d81abcbfe501 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c | |||
| @@ -251,8 +251,9 @@ u32 kvm_read_and_reset_pf_reason(void) | |||
| 251 | return reason; | 251 | return reason; |
| 252 | } | 252 | } |
| 253 | EXPORT_SYMBOL_GPL(kvm_read_and_reset_pf_reason); | 253 | EXPORT_SYMBOL_GPL(kvm_read_and_reset_pf_reason); |
| 254 | NOKPROBE_SYMBOL(kvm_read_and_reset_pf_reason); | ||
| 254 | 255 | ||
| 255 | dotraplinkage void __kprobes | 256 | dotraplinkage void |
| 256 | do_async_page_fault(struct pt_regs *regs, unsigned long error_code) | 257 | do_async_page_fault(struct pt_regs *regs, unsigned long error_code) |
| 257 | { | 258 | { |
| 258 | enum ctx_state prev_state; | 259 | enum ctx_state prev_state; |
| @@ -276,6 +277,7 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
| 276 | break; | 277 | break; |
| 277 | } | 278 | } |
| 278 | } | 279 | } |
| 280 | NOKPROBE_SYMBOL(do_async_page_fault); | ||
| 279 | 281 | ||
| 280 | static void __init paravirt_ops_setup(void) | 282 | static void __init paravirt_ops_setup(void) |
| 281 | { | 283 | { |
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index b4872b999a71..c3e985d1751c 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c | |||
| @@ -110,7 +110,7 @@ static void nmi_max_handler(struct irq_work *w) | |||
| 110 | a->handler, whole_msecs, decimal_msecs); | 110 | a->handler, whole_msecs, decimal_msecs); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | static int __kprobes nmi_handle(unsigned int type, struct pt_regs *regs, bool b2b) | 113 | static int nmi_handle(unsigned int type, struct pt_regs *regs, bool b2b) |
| 114 | { | 114 | { |
| 115 | struct nmi_desc *desc = nmi_to_desc(type); | 115 | struct nmi_desc *desc = nmi_to_desc(type); |
| 116 | struct nmiaction *a; | 116 | struct nmiaction *a; |
| @@ -146,6 +146,7 @@ static int __kprobes nmi_handle(unsigned int type, struct pt_regs *regs, bool b2 | |||
| 146 | /* return total number of NMI events handled */ | 146 | /* return total number of NMI events handled */ |
| 147 | return handled; | 147 | return handled; |
| 148 | } | 148 | } |
| 149 | NOKPROBE_SYMBOL(nmi_handle); | ||
| 149 | 150 | ||
| 150 | int __register_nmi_handler(unsigned int type, struct nmiaction *action) | 151 | int __register_nmi_handler(unsigned int type, struct nmiaction *action) |
| 151 | { | 152 | { |
| @@ -208,7 +209,7 @@ void unregister_nmi_handler(unsigned int type, const char *name) | |||
| 208 | } | 209 | } |
| 209 | EXPORT_SYMBOL_GPL(unregister_nmi_handler); | 210 | EXPORT_SYMBOL_GPL(unregister_nmi_handler); |
| 210 | 211 | ||
| 211 | static __kprobes void | 212 | static void |
| 212 | pci_serr_error(unsigned char reason, struct pt_regs *regs) | 213 | pci_serr_error(unsigned char reason, struct pt_regs *regs) |
| 213 | { | 214 | { |
| 214 | /* check to see if anyone registered against these types of errors */ | 215 | /* check to see if anyone registered against these types of errors */ |
| @@ -238,8 +239,9 @@ pci_serr_error(unsigned char reason, struct pt_regs *regs) | |||
| 238 | reason = (reason & NMI_REASON_CLEAR_MASK) | NMI_REASON_CLEAR_SERR; | 239 | reason = (reason & NMI_REASON_CLEAR_MASK) | NMI_REASON_CLEAR_SERR; |
| 239 | outb(reason, NMI_REASON_PORT); | 240 | outb(reason, NMI_REASON_PORT); |
| 240 | } | 241 | } |
| 242 | NOKPROBE_SYMBOL(pci_serr_error); | ||
| 241 | 243 | ||
| 242 | static __kprobes void | 244 | static void |
| 243 | io_check_error(unsigned char reason, struct pt_regs *regs) | 245 | io_check_error(unsigned char reason, struct pt_regs *regs) |
| 244 | { | 246 | { |
| 245 | unsigned long i; | 247 | unsigned long i; |
| @@ -269,8 +271,9 @@ io_check_error(unsigned char reason, struct pt_regs *regs) | |||
| 269 | reason &= ~NMI_REASON_CLEAR_IOCHK; | 271 | reason &= ~NMI_REASON_CLEAR_IOCHK; |
| 270 | outb(reason, NMI_REASON_PORT); | 272 | outb(reason, NMI_REASON_PORT); |
| 271 | } | 273 | } |
| 274 | NOKPROBE_SYMBOL(io_check_error); | ||
| 272 | 275 | ||
| 273 | static __kprobes void | 276 | static void |
| 274 | unknown_nmi_error(unsigned char reason, struct pt_regs *regs) | 277 | unknown_nmi_error(unsigned char reason, struct pt_regs *regs) |
| 275 | { | 278 | { |
| 276 | int handled; | 279 | int handled; |
| @@ -298,11 +301,12 @@ unknown_nmi_error(unsigned char reason, struct pt_regs *regs) | |||
| 298 | 301 | ||
| 299 | pr_emerg("Dazed and confused, but trying to continue\n"); | 302 | pr_emerg("Dazed and confused, but trying to continue\n"); |
| 300 | } | 303 | } |
| 304 | NOKPROBE_SYMBOL(unknown_nmi_error); | ||
| 301 | 305 | ||
| 302 | static DEFINE_PER_CPU(bool, swallow_nmi); | 306 | static DEFINE_PER_CPU(bool, swallow_nmi); |
| 303 | static DEFINE_PER_CPU(unsigned long, last_nmi_rip); | 307 | static DEFINE_PER_CPU(unsigned long, last_nmi_rip); |
| 304 | 308 | ||
| 305 | static __kprobes void default_do_nmi(struct pt_regs *regs) | 309 | static void default_do_nmi(struct pt_regs *regs) |
| 306 | { | 310 | { |
| 307 | unsigned char reason = 0; | 311 | unsigned char reason = 0; |
| 308 | int handled; | 312 | int handled; |
| @@ -401,6 +405,7 @@ static __kprobes void default_do_nmi(struct pt_regs *regs) | |||
| 401 | else | 405 | else |
| 402 | unknown_nmi_error(reason, regs); | 406 | unknown_nmi_error(reason, regs); |
| 403 | } | 407 | } |
| 408 | NOKPROBE_SYMBOL(default_do_nmi); | ||
| 404 | 409 | ||
| 405 | /* | 410 | /* |
| 406 | * NMIs can hit breakpoints which will cause it to lose its | 411 | * NMIs can hit breakpoints which will cause it to lose its |
| @@ -520,7 +525,7 @@ static inline void nmi_nesting_postprocess(void) | |||
| 520 | } | 525 | } |
| 521 | #endif | 526 | #endif |
| 522 | 527 | ||
| 523 | dotraplinkage notrace __kprobes void | 528 | dotraplinkage notrace void |
| 524 | do_nmi(struct pt_regs *regs, long error_code) | 529 | do_nmi(struct pt_regs *regs, long error_code) |
| 525 | { | 530 | { |
| 526 | nmi_nesting_preprocess(regs); | 531 | nmi_nesting_preprocess(regs); |
| @@ -537,6 +542,7 @@ do_nmi(struct pt_regs *regs, long error_code) | |||
| 537 | /* On i386, may loop back to preprocess */ | 542 | /* On i386, may loop back to preprocess */ |
| 538 | nmi_nesting_postprocess(); | 543 | nmi_nesting_postprocess(); |
| 539 | } | 544 | } |
| 545 | NOKPROBE_SYMBOL(do_nmi); | ||
| 540 | 546 | ||
| 541 | void stop_nmi(void) | 547 | void stop_nmi(void) |
| 542 | { | 548 | { |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index ba9abe9cbce3..3c8ae7d83820 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
| @@ -106,7 +106,7 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) | |||
| 106 | preempt_count_dec(); | 106 | preempt_count_dec(); |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | static int __kprobes | 109 | static nokprobe_inline int |
| 110 | do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str, | 110 | do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str, |
| 111 | struct pt_regs *regs, long error_code) | 111 | struct pt_regs *regs, long error_code) |
| 112 | { | 112 | { |
| @@ -136,7 +136,7 @@ do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str, | |||
| 136 | return -1; | 136 | return -1; |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | static void __kprobes | 139 | static void |
| 140 | do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, | 140 | do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, |
| 141 | long error_code, siginfo_t *info) | 141 | long error_code, siginfo_t *info) |
| 142 | { | 142 | { |
| @@ -173,6 +173,7 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, | |||
| 173 | else | 173 | else |
| 174 | force_sig(signr, tsk); | 174 | force_sig(signr, tsk); |
| 175 | } | 175 | } |
| 176 | NOKPROBE_SYMBOL(do_trap); | ||
| 176 | 177 | ||
| 177 | #define DO_ERROR(trapnr, signr, str, name) \ | 178 | #define DO_ERROR(trapnr, signr, str, name) \ |
| 178 | dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ | 179 | dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ |
| @@ -263,7 +264,7 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) | |||
| 263 | } | 264 | } |
| 264 | #endif | 265 | #endif |
| 265 | 266 | ||
| 266 | dotraplinkage void __kprobes | 267 | dotraplinkage void |
| 267 | do_general_protection(struct pt_regs *regs, long error_code) | 268 | do_general_protection(struct pt_regs *regs, long error_code) |
| 268 | { | 269 | { |
| 269 | struct task_struct *tsk; | 270 | struct task_struct *tsk; |
| @@ -309,9 +310,10 @@ do_general_protection(struct pt_regs *regs, long error_code) | |||
| 309 | exit: | 310 | exit: |
| 310 | exception_exit(prev_state); | 311 | exception_exit(prev_state); |
| 311 | } | 312 | } |
| 313 | NOKPROBE_SYMBOL(do_general_protection); | ||
| 312 | 314 | ||
| 313 | /* May run on IST stack. */ | 315 | /* May run on IST stack. */ |
| 314 | dotraplinkage void __kprobes notrace do_int3(struct pt_regs *regs, long error_code) | 316 | dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code) |
| 315 | { | 317 | { |
| 316 | enum ctx_state prev_state; | 318 | enum ctx_state prev_state; |
| 317 | 319 | ||
| @@ -355,6 +357,7 @@ dotraplinkage void __kprobes notrace do_int3(struct pt_regs *regs, long error_co | |||
| 355 | exit: | 357 | exit: |
| 356 | exception_exit(prev_state); | 358 | exception_exit(prev_state); |
| 357 | } | 359 | } |
| 360 | NOKPROBE_SYMBOL(do_int3); | ||
| 358 | 361 | ||
| 359 | #ifdef CONFIG_X86_64 | 362 | #ifdef CONFIG_X86_64 |
| 360 | /* | 363 | /* |
| @@ -362,7 +365,7 @@ exit: | |||
| 362 | * for scheduling or signal handling. The actual stack switch is done in | 365 | * for scheduling or signal handling. The actual stack switch is done in |
| 363 | * entry.S | 366 | * entry.S |
| 364 | */ | 367 | */ |
| 365 | asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) | 368 | asmlinkage struct pt_regs *sync_regs(struct pt_regs *eregs) |
| 366 | { | 369 | { |
| 367 | struct pt_regs *regs = eregs; | 370 | struct pt_regs *regs = eregs; |
| 368 | /* Did already sync */ | 371 | /* Did already sync */ |
| @@ -381,6 +384,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) | |||
| 381 | *regs = *eregs; | 384 | *regs = *eregs; |
| 382 | return regs; | 385 | return regs; |
| 383 | } | 386 | } |
| 387 | NOKPROBE_SYMBOL(sync_regs); | ||
| 384 | #endif | 388 | #endif |
| 385 | 389 | ||
| 386 | /* | 390 | /* |
| @@ -407,7 +411,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) | |||
| 407 | * | 411 | * |
| 408 | * May run on IST stack. | 412 | * May run on IST stack. |
| 409 | */ | 413 | */ |
| 410 | dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) | 414 | dotraplinkage void do_debug(struct pt_regs *regs, long error_code) |
| 411 | { | 415 | { |
| 412 | struct task_struct *tsk = current; | 416 | struct task_struct *tsk = current; |
| 413 | enum ctx_state prev_state; | 417 | enum ctx_state prev_state; |
| @@ -491,6 +495,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) | |||
| 491 | exit: | 495 | exit: |
| 492 | exception_exit(prev_state); | 496 | exception_exit(prev_state); |
| 493 | } | 497 | } |
| 498 | NOKPROBE_SYMBOL(do_debug); | ||
| 494 | 499 | ||
| 495 | /* | 500 | /* |
| 496 | * Note that we play around with the 'TS' bit in an attempt to get | 501 | * Note that we play around with the 'TS' bit in an attempt to get |
| @@ -662,7 +667,7 @@ void math_state_restore(void) | |||
| 662 | } | 667 | } |
| 663 | EXPORT_SYMBOL_GPL(math_state_restore); | 668 | EXPORT_SYMBOL_GPL(math_state_restore); |
| 664 | 669 | ||
| 665 | dotraplinkage void __kprobes | 670 | dotraplinkage void |
| 666 | do_device_not_available(struct pt_regs *regs, long error_code) | 671 | do_device_not_available(struct pt_regs *regs, long error_code) |
| 667 | { | 672 | { |
| 668 | enum ctx_state prev_state; | 673 | enum ctx_state prev_state; |
| @@ -688,6 +693,7 @@ do_device_not_available(struct pt_regs *regs, long error_code) | |||
| 688 | #endif | 693 | #endif |
| 689 | exception_exit(prev_state); | 694 | exception_exit(prev_state); |
| 690 | } | 695 | } |
| 696 | NOKPROBE_SYMBOL(do_device_not_available); | ||
| 691 | 697 | ||
| 692 | #ifdef CONFIG_X86_32 | 698 | #ifdef CONFIG_X86_32 |
| 693 | dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) | 699 | dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) |
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 8e5722992677..f83bd0de5eef 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | #include <linux/kdebug.h> /* oops_begin/end, ... */ | 8 | #include <linux/kdebug.h> /* oops_begin/end, ... */ |
| 9 | #include <linux/module.h> /* search_exception_table */ | 9 | #include <linux/module.h> /* search_exception_table */ |
| 10 | #include <linux/bootmem.h> /* max_low_pfn */ | 10 | #include <linux/bootmem.h> /* max_low_pfn */ |
| 11 | #include <linux/kprobes.h> /* __kprobes, ... */ | 11 | #include <linux/kprobes.h> /* NOKPROBE_SYMBOL, ... */ |
| 12 | #include <linux/mmiotrace.h> /* kmmio_handler, ... */ | 12 | #include <linux/mmiotrace.h> /* kmmio_handler, ... */ |
| 13 | #include <linux/perf_event.h> /* perf_sw_event */ | 13 | #include <linux/perf_event.h> /* perf_sw_event */ |
| 14 | #include <linux/hugetlb.h> /* hstate_index_to_shift */ | 14 | #include <linux/hugetlb.h> /* hstate_index_to_shift */ |
| @@ -45,7 +45,7 @@ enum x86_pf_error_code { | |||
| 45 | * Returns 0 if mmiotrace is disabled, or if the fault is not | 45 | * Returns 0 if mmiotrace is disabled, or if the fault is not |
| 46 | * handled by mmiotrace: | 46 | * handled by mmiotrace: |
| 47 | */ | 47 | */ |
| 48 | static inline int __kprobes | 48 | static nokprobe_inline int |
| 49 | kmmio_fault(struct pt_regs *regs, unsigned long addr) | 49 | kmmio_fault(struct pt_regs *regs, unsigned long addr) |
| 50 | { | 50 | { |
| 51 | if (unlikely(is_kmmio_active())) | 51 | if (unlikely(is_kmmio_active())) |
| @@ -54,7 +54,7 @@ kmmio_fault(struct pt_regs *regs, unsigned long addr) | |||
| 54 | return 0; | 54 | return 0; |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | static inline int __kprobes kprobes_fault(struct pt_regs *regs) | 57 | static nokprobe_inline int kprobes_fault(struct pt_regs *regs) |
| 58 | { | 58 | { |
| 59 | int ret = 0; | 59 | int ret = 0; |
| 60 | 60 | ||
| @@ -261,7 +261,7 @@ void vmalloc_sync_all(void) | |||
| 261 | * | 261 | * |
| 262 | * Handle a fault on the vmalloc or module mapping area | 262 | * Handle a fault on the vmalloc or module mapping area |
| 263 | */ | 263 | */ |
| 264 | static noinline __kprobes int vmalloc_fault(unsigned long address) | 264 | static noinline int vmalloc_fault(unsigned long address) |
| 265 | { | 265 | { |
| 266 | unsigned long pgd_paddr; | 266 | unsigned long pgd_paddr; |
| 267 | pmd_t *pmd_k; | 267 | pmd_t *pmd_k; |
| @@ -291,6 +291,7 @@ static noinline __kprobes int vmalloc_fault(unsigned long address) | |||
| 291 | 291 | ||
| 292 | return 0; | 292 | return 0; |
| 293 | } | 293 | } |
| 294 | NOKPROBE_SYMBOL(vmalloc_fault); | ||
| 294 | 295 | ||
| 295 | /* | 296 | /* |
| 296 | * Did it hit the DOS screen memory VA from vm86 mode? | 297 | * Did it hit the DOS screen memory VA from vm86 mode? |
| @@ -358,7 +359,7 @@ void vmalloc_sync_all(void) | |||
| 358 | * | 359 | * |
| 359 | * This assumes no large pages in there. | 360 | * This assumes no large pages in there. |
| 360 | */ | 361 | */ |
| 361 | static noinline __kprobes int vmalloc_fault(unsigned long address) | 362 | static noinline int vmalloc_fault(unsigned long address) |
| 362 | { | 363 | { |
| 363 | pgd_t *pgd, *pgd_ref; | 364 | pgd_t *pgd, *pgd_ref; |
| 364 | pud_t *pud, *pud_ref; | 365 | pud_t *pud, *pud_ref; |
| @@ -425,6 +426,7 @@ static noinline __kprobes int vmalloc_fault(unsigned long address) | |||
| 425 | 426 | ||
| 426 | return 0; | 427 | return 0; |
| 427 | } | 428 | } |
| 429 | NOKPROBE_SYMBOL(vmalloc_fault); | ||
| 428 | 430 | ||
| 429 | #ifdef CONFIG_CPU_SUP_AMD | 431 | #ifdef CONFIG_CPU_SUP_AMD |
| 430 | static const char errata93_warning[] = | 432 | static const char errata93_warning[] = |
| @@ -927,7 +929,7 @@ static int spurious_fault_check(unsigned long error_code, pte_t *pte) | |||
| 927 | * There are no security implications to leaving a stale TLB when | 929 | * There are no security implications to leaving a stale TLB when |
| 928 | * increasing the permissions on a page. | 930 | * increasing the permissions on a page. |
| 929 | */ | 931 | */ |
| 930 | static noinline __kprobes int | 932 | static noinline int |
| 931 | spurious_fault(unsigned long error_code, unsigned long address) | 933 | spurious_fault(unsigned long error_code, unsigned long address) |
| 932 | { | 934 | { |
| 933 | pgd_t *pgd; | 935 | pgd_t *pgd; |
| @@ -975,6 +977,7 @@ spurious_fault(unsigned long error_code, unsigned long address) | |||
| 975 | 977 | ||
| 976 | return ret; | 978 | return ret; |
| 977 | } | 979 | } |
| 980 | NOKPROBE_SYMBOL(spurious_fault); | ||
| 978 | 981 | ||
| 979 | int show_unhandled_signals = 1; | 982 | int show_unhandled_signals = 1; |
| 980 | 983 | ||
| @@ -1030,7 +1033,7 @@ static inline bool smap_violation(int error_code, struct pt_regs *regs) | |||
| 1030 | * {,trace_}do_page_fault() have notrace on. Having this an actual function | 1033 | * {,trace_}do_page_fault() have notrace on. Having this an actual function |
| 1031 | * guarantees there's a function trace entry. | 1034 | * guarantees there's a function trace entry. |
| 1032 | */ | 1035 | */ |
| 1033 | static void __kprobes noinline | 1036 | static noinline void |
| 1034 | __do_page_fault(struct pt_regs *regs, unsigned long error_code, | 1037 | __do_page_fault(struct pt_regs *regs, unsigned long error_code, |
| 1035 | unsigned long address) | 1038 | unsigned long address) |
| 1036 | { | 1039 | { |
| @@ -1253,8 +1256,9 @@ good_area: | |||
| 1253 | 1256 | ||
| 1254 | up_read(&mm->mmap_sem); | 1257 | up_read(&mm->mmap_sem); |
| 1255 | } | 1258 | } |
| 1259 | NOKPROBE_SYMBOL(__do_page_fault); | ||
| 1256 | 1260 | ||
| 1257 | dotraplinkage void __kprobes notrace | 1261 | dotraplinkage void notrace |
| 1258 | do_page_fault(struct pt_regs *regs, unsigned long error_code) | 1262 | do_page_fault(struct pt_regs *regs, unsigned long error_code) |
| 1259 | { | 1263 | { |
| 1260 | unsigned long address = read_cr2(); /* Get the faulting address */ | 1264 | unsigned long address = read_cr2(); /* Get the faulting address */ |
| @@ -1272,10 +1276,12 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
| 1272 | __do_page_fault(regs, error_code, address); | 1276 | __do_page_fault(regs, error_code, address); |
| 1273 | exception_exit(prev_state); | 1277 | exception_exit(prev_state); |
| 1274 | } | 1278 | } |
| 1279 | NOKPROBE_SYMBOL(do_page_fault); | ||
| 1275 | 1280 | ||
| 1276 | #ifdef CONFIG_TRACING | 1281 | #ifdef CONFIG_TRACING |
| 1277 | static void trace_page_fault_entries(unsigned long address, struct pt_regs *regs, | 1282 | static nokprobe_inline void |
| 1278 | unsigned long error_code) | 1283 | trace_page_fault_entries(unsigned long address, struct pt_regs *regs, |
| 1284 | unsigned long error_code) | ||
| 1279 | { | 1285 | { |
| 1280 | if (user_mode(regs)) | 1286 | if (user_mode(regs)) |
| 1281 | trace_page_fault_user(address, regs, error_code); | 1287 | trace_page_fault_user(address, regs, error_code); |
| @@ -1283,7 +1289,7 @@ static void trace_page_fault_entries(unsigned long address, struct pt_regs *regs | |||
| 1283 | trace_page_fault_kernel(address, regs, error_code); | 1289 | trace_page_fault_kernel(address, regs, error_code); |
| 1284 | } | 1290 | } |
| 1285 | 1291 | ||
| 1286 | dotraplinkage void __kprobes notrace | 1292 | dotraplinkage void notrace |
| 1287 | trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) | 1293 | trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) |
| 1288 | { | 1294 | { |
| 1289 | /* | 1295 | /* |
| @@ -1300,4 +1306,5 @@ trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
| 1300 | __do_page_fault(regs, error_code, address); | 1306 | __do_page_fault(regs, error_code, address); |
| 1301 | exception_exit(prev_state); | 1307 | exception_exit(prev_state); |
| 1302 | } | 1308 | } |
| 1309 | NOKPROBE_SYMBOL(trace_do_page_fault); | ||
| 1303 | #endif /* CONFIG_TRACING */ | 1310 | #endif /* CONFIG_TRACING */ |
