aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2014-04-17 04:17:54 -0400
committerIngo Molnar <mingo@kernel.org>2014-04-24 04:03:01 -0400
commit55479f64756fc508182a05e35e52f01395a50d4d (patch)
tree7b54c148e68e74f38108edde74a2408c1d04fe2c /kernel
parent7ec8a97a990da8e3ba87175a757731e17f74072e (diff)
kprobes: Allow probe on some kprobe functions
There is no need to prohibit probing on the functions used for preparation, registeration, optimization, controll etc. Those are safely probed because those are not invoked from breakpoint/fault/debug handlers, there is no chance to cause recursive exceptions. Following functions are now removed from the kprobes blacklist: add_new_kprobe aggr_kprobe_disabled alloc_aggr_kprobe alloc_aggr_kprobe arm_all_kprobes __arm_kprobe arm_kprobe arm_kprobe_ftrace check_kprobe_address_safe collect_garbage_slots collect_garbage_slots collect_one_slot debugfs_kprobe_init __disable_kprobe disable_kprobe disarm_all_kprobes __disarm_kprobe disarm_kprobe disarm_kprobe_ftrace do_free_cleaned_kprobes do_optimize_kprobes do_unoptimize_kprobes enable_kprobe force_unoptimize_kprobe free_aggr_kprobe free_aggr_kprobe __free_insn_slot __get_insn_slot get_optimized_kprobe __get_valid_kprobe init_aggr_kprobe init_aggr_kprobe in_nokprobe_functions kick_kprobe_optimizer kill_kprobe kill_optimized_kprobe kprobe_addr kprobe_optimizer kprobe_queued kprobe_seq_next kprobe_seq_start kprobe_seq_stop kprobes_module_callback kprobes_open optimize_all_kprobes optimize_kprobe prepare_kprobe prepare_optimized_kprobe register_aggr_kprobe register_jprobe register_jprobes register_kprobe register_kprobes register_kretprobe register_kretprobe register_kretprobes register_kretprobes report_probe show_kprobe_addr try_to_optimize_kprobe unoptimize_all_kprobes unoptimize_kprobe unregister_jprobe unregister_jprobes unregister_kprobe __unregister_kprobe_bottom unregister_kprobes __unregister_kprobe_top unregister_kretprobe unregister_kretprobe unregister_kretprobes unregister_kretprobes wait_for_kprobe_optimizer I tested those functions by putting kprobes on all instructions in the functions with the bash script I sent to LKML. See: https://lkml.org/lkml/2014/3/27/33 Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Link: http://lkml.kernel.org/r/20140417081753.26341.57889.stgit@ltc230.yrl.intra.hitachi.co.jp Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> Cc: David S. Miller <davem@davemloft.net> Cc: fche@redhat.com Cc: systemtap@sourceware.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/kprobes.c153
1 files changed, 76 insertions, 77 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 5ffc6875d2a7..4db2cc616f50 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -138,13 +138,13 @@ struct kprobe_insn_cache kprobe_insn_slots = {
138 .insn_size = MAX_INSN_SIZE, 138 .insn_size = MAX_INSN_SIZE,
139 .nr_garbage = 0, 139 .nr_garbage = 0,
140}; 140};
141static int __kprobes collect_garbage_slots(struct kprobe_insn_cache *c); 141static int collect_garbage_slots(struct kprobe_insn_cache *c);
142 142
143/** 143/**
144 * __get_insn_slot() - Find a slot on an executable page for an instruction. 144 * __get_insn_slot() - Find a slot on an executable page for an instruction.
145 * We allocate an executable page if there's no room on existing ones. 145 * We allocate an executable page if there's no room on existing ones.
146 */ 146 */
147kprobe_opcode_t __kprobes *__get_insn_slot(struct kprobe_insn_cache *c) 147kprobe_opcode_t *__get_insn_slot(struct kprobe_insn_cache *c)
148{ 148{
149 struct kprobe_insn_page *kip; 149 struct kprobe_insn_page *kip;
150 kprobe_opcode_t *slot = NULL; 150 kprobe_opcode_t *slot = NULL;
@@ -201,7 +201,7 @@ out:
201} 201}
202 202
203/* Return 1 if all garbages are collected, otherwise 0. */ 203/* Return 1 if all garbages are collected, otherwise 0. */
204static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx) 204static int collect_one_slot(struct kprobe_insn_page *kip, int idx)
205{ 205{
206 kip->slot_used[idx] = SLOT_CLEAN; 206 kip->slot_used[idx] = SLOT_CLEAN;
207 kip->nused--; 207 kip->nused--;
@@ -222,7 +222,7 @@ static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx)
222 return 0; 222 return 0;
223} 223}
224 224
225static int __kprobes collect_garbage_slots(struct kprobe_insn_cache *c) 225static int collect_garbage_slots(struct kprobe_insn_cache *c)
226{ 226{
227 struct kprobe_insn_page *kip, *next; 227 struct kprobe_insn_page *kip, *next;
228 228
@@ -244,8 +244,8 @@ static int __kprobes collect_garbage_slots(struct kprobe_insn_cache *c)
244 return 0; 244 return 0;
245} 245}
246 246
247void __kprobes __free_insn_slot(struct kprobe_insn_cache *c, 247void __free_insn_slot(struct kprobe_insn_cache *c,
248 kprobe_opcode_t *slot, int dirty) 248 kprobe_opcode_t *slot, int dirty)
249{ 249{
250 struct kprobe_insn_page *kip; 250 struct kprobe_insn_page *kip;
251 251
@@ -361,7 +361,7 @@ void __kprobes opt_pre_handler(struct kprobe *p, struct pt_regs *regs)
361} 361}
362 362
363/* Free optimized instructions and optimized_kprobe */ 363/* Free optimized instructions and optimized_kprobe */
364static __kprobes void free_aggr_kprobe(struct kprobe *p) 364static void free_aggr_kprobe(struct kprobe *p)
365{ 365{
366 struct optimized_kprobe *op; 366 struct optimized_kprobe *op;
367 367
@@ -399,7 +399,7 @@ static inline int kprobe_disarmed(struct kprobe *p)
399} 399}
400 400
401/* Return true(!0) if the probe is queued on (un)optimizing lists */ 401/* Return true(!0) if the probe is queued on (un)optimizing lists */
402static int __kprobes kprobe_queued(struct kprobe *p) 402static int kprobe_queued(struct kprobe *p)
403{ 403{
404 struct optimized_kprobe *op; 404 struct optimized_kprobe *op;
405 405
@@ -415,7 +415,7 @@ static int __kprobes kprobe_queued(struct kprobe *p)
415 * Return an optimized kprobe whose optimizing code replaces 415 * Return an optimized kprobe whose optimizing code replaces
416 * instructions including addr (exclude breakpoint). 416 * instructions including addr (exclude breakpoint).
417 */ 417 */
418static struct kprobe *__kprobes get_optimized_kprobe(unsigned long addr) 418static struct kprobe *get_optimized_kprobe(unsigned long addr)
419{ 419{
420 int i; 420 int i;
421 struct kprobe *p = NULL; 421 struct kprobe *p = NULL;
@@ -447,7 +447,7 @@ static DECLARE_DELAYED_WORK(optimizing_work, kprobe_optimizer);
447 * Optimize (replace a breakpoint with a jump) kprobes listed on 447 * Optimize (replace a breakpoint with a jump) kprobes listed on
448 * optimizing_list. 448 * optimizing_list.
449 */ 449 */
450static __kprobes void do_optimize_kprobes(void) 450static void do_optimize_kprobes(void)
451{ 451{
452 /* Optimization never be done when disarmed */ 452 /* Optimization never be done when disarmed */
453 if (kprobes_all_disarmed || !kprobes_allow_optimization || 453 if (kprobes_all_disarmed || !kprobes_allow_optimization ||
@@ -475,7 +475,7 @@ static __kprobes void do_optimize_kprobes(void)
475 * Unoptimize (replace a jump with a breakpoint and remove the breakpoint 475 * Unoptimize (replace a jump with a breakpoint and remove the breakpoint
476 * if need) kprobes listed on unoptimizing_list. 476 * if need) kprobes listed on unoptimizing_list.
477 */ 477 */
478static __kprobes void do_unoptimize_kprobes(void) 478static void do_unoptimize_kprobes(void)
479{ 479{
480 struct optimized_kprobe *op, *tmp; 480 struct optimized_kprobe *op, *tmp;
481 481
@@ -507,7 +507,7 @@ static __kprobes void do_unoptimize_kprobes(void)
507} 507}
508 508
509/* Reclaim all kprobes on the free_list */ 509/* Reclaim all kprobes on the free_list */
510static __kprobes void do_free_cleaned_kprobes(void) 510static void do_free_cleaned_kprobes(void)
511{ 511{
512 struct optimized_kprobe *op, *tmp; 512 struct optimized_kprobe *op, *tmp;
513 513
@@ -519,13 +519,13 @@ static __kprobes void do_free_cleaned_kprobes(void)
519} 519}
520 520
521/* Start optimizer after OPTIMIZE_DELAY passed */ 521/* Start optimizer after OPTIMIZE_DELAY passed */
522static __kprobes void kick_kprobe_optimizer(void) 522static void kick_kprobe_optimizer(void)
523{ 523{
524 schedule_delayed_work(&optimizing_work, OPTIMIZE_DELAY); 524 schedule_delayed_work(&optimizing_work, OPTIMIZE_DELAY);
525} 525}
526 526
527/* Kprobe jump optimizer */ 527/* Kprobe jump optimizer */
528static __kprobes void kprobe_optimizer(struct work_struct *work) 528static void kprobe_optimizer(struct work_struct *work)
529{ 529{
530 mutex_lock(&kprobe_mutex); 530 mutex_lock(&kprobe_mutex);
531 /* Lock modules while optimizing kprobes */ 531 /* Lock modules while optimizing kprobes */
@@ -561,7 +561,7 @@ static __kprobes void kprobe_optimizer(struct work_struct *work)
561} 561}
562 562
563/* Wait for completing optimization and unoptimization */ 563/* Wait for completing optimization and unoptimization */
564static __kprobes void wait_for_kprobe_optimizer(void) 564static void wait_for_kprobe_optimizer(void)
565{ 565{
566 mutex_lock(&kprobe_mutex); 566 mutex_lock(&kprobe_mutex);
567 567
@@ -580,7 +580,7 @@ static __kprobes void wait_for_kprobe_optimizer(void)
580} 580}
581 581
582/* Optimize kprobe if p is ready to be optimized */ 582/* Optimize kprobe if p is ready to be optimized */
583static __kprobes void optimize_kprobe(struct kprobe *p) 583static void optimize_kprobe(struct kprobe *p)
584{ 584{
585 struct optimized_kprobe *op; 585 struct optimized_kprobe *op;
586 586
@@ -614,7 +614,7 @@ static __kprobes void optimize_kprobe(struct kprobe *p)
614} 614}
615 615
616/* Short cut to direct unoptimizing */ 616/* Short cut to direct unoptimizing */
617static __kprobes void force_unoptimize_kprobe(struct optimized_kprobe *op) 617static void force_unoptimize_kprobe(struct optimized_kprobe *op)
618{ 618{
619 get_online_cpus(); 619 get_online_cpus();
620 arch_unoptimize_kprobe(op); 620 arch_unoptimize_kprobe(op);
@@ -624,7 +624,7 @@ static __kprobes void force_unoptimize_kprobe(struct optimized_kprobe *op)
624} 624}
625 625
626/* Unoptimize a kprobe if p is optimized */ 626/* Unoptimize a kprobe if p is optimized */
627static __kprobes void unoptimize_kprobe(struct kprobe *p, bool force) 627static void unoptimize_kprobe(struct kprobe *p, bool force)
628{ 628{
629 struct optimized_kprobe *op; 629 struct optimized_kprobe *op;
630 630
@@ -684,7 +684,7 @@ static void reuse_unused_kprobe(struct kprobe *ap)
684} 684}
685 685
686/* Remove optimized instructions */ 686/* Remove optimized instructions */
687static void __kprobes kill_optimized_kprobe(struct kprobe *p) 687static void kill_optimized_kprobe(struct kprobe *p)
688{ 688{
689 s