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 /arch/x86 | |
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>
Diffstat (limited to 'arch/x86')
-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 */ |