Blame view

kernel/kprobes.c 71.2 KB
1a59d1b8e   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
  /*
   *  Kernel Probes (KProbes)
   *  kernel/kprobes.c
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
7
8
9
10
11
12
13
14
15
16
   * Copyright (C) IBM Corporation, 2002, 2004
   *
   * 2002-Oct	Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel
   *		Probes initial implementation (includes suggestions from
   *		Rusty Russell).
   * 2004-Aug	Updated by Prasanna S Panchamukhi <prasanna@in.ibm.com> with
   *		hlists and exceptions notifier as suggested by Andi Kleen.
   * 2004-July	Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
   *		interface to access function arguments.
   * 2004-Sep	Prasanna S Panchamukhi <prasanna@in.ibm.com> Changed Kprobes
   *		exceptions notifier to be first on the priority list.
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
17
18
19
   * 2005-May	Hien Nguyen <hien@us.ibm.com>, Jim Keniston
   *		<jkenisto@us.ibm.com> and Prasanna S Panchamukhi
   *		<prasanna@in.ibm.com> added function-return probes.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
21
   */
  #include <linux/kprobes.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
23
  #include <linux/hash.h>
  #include <linux/init.h>
4e57b6817   Tim Schmielau   [PATCH] fix missi...
24
  #include <linux/slab.h>
e38697929   Randy Dunlap   kprobes: fix spar...
25
  #include <linux/stddef.h>
9984de1a5   Paul Gortmaker   kernel: Map most ...
26
  #include <linux/export.h>
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
27
  #include <linux/moduleloader.h>
3a872d89b   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
28
  #include <linux/kallsyms.h>
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
29
  #include <linux/freezer.h>
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
30
31
  #include <linux/seq_file.h>
  #include <linux/debugfs.h>
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
32
  #include <linux/sysctl.h>
1eeb66a1b   Christoph Hellwig   move die notifier...
33
  #include <linux/kdebug.h>
4460fdad8   Mathieu Desnoyers   tracing, Text Edi...
34
  #include <linux/memory.h>
4554dbcb8   Masami Hiramatsu   kprobes: Check pr...
35
  #include <linux/ftrace.h>
afd66255b   Masami Hiramatsu   kprobes: Introduc...
36
  #include <linux/cpu.h>
bf5438fca   Jason Baron   jump label: Base ...
37
  #include <linux/jump_label.h>
69e490886   Adrian Hunter   kprobes: Add perf...
38
  #include <linux/perf_event.h>
6333e8f73   Peter Zijlstra   static_call: Avoi...
39
  #include <linux/static_call.h>
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
40

bfd45be0b   Christoph Hellwig   kprobes: include ...
41
  #include <asm/sections.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
42
43
  #include <asm/cacheflush.h>
  #include <asm/errno.h>
7c0f6ba68   Linus Torvalds   Replace <asm/uacc...
44
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
46
47
  
  #define KPROBE_HASH_BITS 6
  #define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS)
3a872d89b   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
48

ef53d9c5e   Srinivasa D S   kprobes: improve ...
49
  static int kprobes_initialized;
7e6a71d8e   Masami Hiramatsu   kprobes: Use non ...
50
51
52
53
54
  /* kprobe_table can be accessed by
   * - Normal hlist traversal and RCU add/del under kprobe_mutex is held.
   * Or
   * - RCU hlist traversal under disabling preempt (breakpoint handlers)
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
  static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
56
  static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57

bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
58
  /* NOTE: change this value only with kprobe_mutex held */
e579abeb5   Masami Hiramatsu   kprobes: rename k...
59
  static bool kprobes_all_disarmed;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
60

43948f502   Masami Hiramatsu   kprobes: Remove r...
61
62
  /* This protects kprobe_table and optimizing_list */
  static DEFINE_MUTEX(kprobe_mutex);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
63
  static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
64
  static struct {
ec484608c   Thomas Gleixner   locking, kprobes:...
65
  	raw_spinlock_t lock ____cacheline_aligned_in_smp;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
66
  } kretprobe_table_locks[KPROBE_TABLE_SIZE];
290e30707   Naveen N. Rao   powerpc/kprobes: ...
67
68
  kprobe_opcode_t * __weak kprobe_lookup_name(const char *name,
  					unsigned int __unused)
49e0b4658   Naveen N. Rao   kprobes: Convert ...
69
70
71
  {
  	return ((kprobe_opcode_t *)(kallsyms_lookup_name(name)));
  }
ec484608c   Thomas Gleixner   locking, kprobes:...
72
  static raw_spinlock_t *kretprobe_table_lock_ptr(unsigned long hash)
ef53d9c5e   Srinivasa D S   kprobes: improve ...
73
74
75
  {
  	return &(kretprobe_table_locks[hash].lock);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76

376e24242   Masami Hiramatsu   kprobes: Introduc...
77
78
  /* Blacklist -- list of struct kprobe_blacklist_entry */
  static LIST_HEAD(kprobe_blacklist);
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
79

2d14e39da   Anil S Keshavamurthy   [PATCH] kprobes: ...
80
  #ifdef __ARCH_WANT_KPROBES_INSN_SLOT
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
81
82
83
84
85
86
  /*
   * kprobe->ainsn.insn points to the copy of the instruction to be
   * single-stepped. x86_64, POWER4 and above have no-exec support and
   * stepping on the instruction on a vmalloced/kmalloced/data page
   * is a recipe for disaster
   */
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
87
  struct kprobe_insn_page {
c5cb5a2d8   Masami Hiramatsu   kprobes: Clean up...
88
  	struct list_head list;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
89
  	kprobe_opcode_t *insns;		/* Page of instruction slots */
af96397de   Heiko Carstens   kprobes: allow to...
90
  	struct kprobe_insn_cache *cache;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
91
  	int nused;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
92
  	int ngarbage;
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
93
  	char slot_used[];
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
94
  };
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
95
96
97
  #define KPROBE_INSN_PAGE_SIZE(slots)			\
  	(offsetof(struct kprobe_insn_page, slot_used) +	\
  	 (sizeof(char) * (slots)))
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
98
99
100
101
  static int slots_per_page(struct kprobe_insn_cache *c)
  {
  	return PAGE_SIZE/(c->insn_size * sizeof(kprobe_opcode_t));
  }
ab40c5c6b   Masami Hiramatsu   [PATCH] kprobes: ...
102
103
104
105
106
  enum kprobe_slot_state {
  	SLOT_CLEAN = 0,
  	SLOT_DIRTY = 1,
  	SLOT_USED = 2,
  };
63fef14fc   Masami Hiramatsu   kprobes/x86: Make...
107
  void __weak *alloc_insn_page(void)
af96397de   Heiko Carstens   kprobes: allow to...
108
109
110
  {
  	return module_alloc(PAGE_SIZE);
  }
c93f5cf57   Masami Hiramatsu   kprobes/x86: Fix ...
111
  void __weak free_insn_page(void *page)
af96397de   Heiko Carstens   kprobes: allow to...
112
  {
be1f221c0   Rusty Russell   module: remove mo...
113
  	module_memfree(page);
af96397de   Heiko Carstens   kprobes: allow to...
114
  }
c802d64a3   Heiko Carstens   kprobes: unify in...
115
116
  struct kprobe_insn_cache kprobe_insn_slots = {
  	.mutex = __MUTEX_INITIALIZER(kprobe_insn_slots.mutex),
af96397de   Heiko Carstens   kprobes: allow to...
117
118
  	.alloc = alloc_insn_page,
  	.free = free_insn_page,
d002b8bc6   Adrian Hunter   kprobes: Add symb...
119
  	.sym = KPROBE_INSN_PAGE_SYM,
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
120
121
122
123
  	.pages = LIST_HEAD_INIT(kprobe_insn_slots.pages),
  	.insn_size = MAX_INSN_SIZE,
  	.nr_garbage = 0,
  };
55479f647   Masami Hiramatsu   kprobes: Allow pr...
124
  static int collect_garbage_slots(struct kprobe_insn_cache *c);
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
125

9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
126
  /**
129415607   Masami Hiramatsu   kprobes: add kpro...
127
   * __get_insn_slot() - Find a slot on an executable page for an instruction.
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
128
129
   * We allocate an executable page if there's no room on existing ones.
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
130
  kprobe_opcode_t *__get_insn_slot(struct kprobe_insn_cache *c)
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
131
132
  {
  	struct kprobe_insn_page *kip;
c802d64a3   Heiko Carstens   kprobes: unify in...
133
  	kprobe_opcode_t *slot = NULL;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
134

5b485629b   Masami Hiramatsu   kprobes, extable:...
135
  	/* Since the slot array is not protected by rcu, we need a mutex */
c802d64a3   Heiko Carstens   kprobes: unify in...
136
  	mutex_lock(&c->mutex);
6f716acd5   Christoph Hellwig   kprobes: codingst...
137
   retry:
5b485629b   Masami Hiramatsu   kprobes, extable:...
138
139
  	rcu_read_lock();
  	list_for_each_entry_rcu(kip, &c->pages, list) {
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
140
  		if (kip->nused < slots_per_page(c)) {
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
141
  			int i;
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
142
  			for (i = 0; i < slots_per_page(c); i++) {
ab40c5c6b   Masami Hiramatsu   [PATCH] kprobes: ...
143
144
  				if (kip->slot_used[i] == SLOT_CLEAN) {
  					kip->slot_used[i] = SLOT_USED;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
145
  					kip->nused++;
c802d64a3   Heiko Carstens   kprobes: unify in...
146
  					slot = kip->insns + (i * c->insn_size);
5b485629b   Masami Hiramatsu   kprobes, extable:...
147
  					rcu_read_unlock();
c802d64a3   Heiko Carstens   kprobes: unify in...
148
  					goto out;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
149
150
  				}
  			}
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
151
152
153
  			/* kip->nused is broken. Fix it. */
  			kip->nused = slots_per_page(c);
  			WARN_ON(1);
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
154
155
  		}
  	}
5b485629b   Masami Hiramatsu   kprobes, extable:...
156
  	rcu_read_unlock();
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
157

b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
158
  	/* If there are any garbage slots, collect it and try again. */
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
159
  	if (c->nr_garbage && collect_garbage_slots(c) == 0)
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
160
  		goto retry;
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
161
162
163
  
  	/* All out of space.  Need to allocate a new page. */
  	kip = kmalloc(KPROBE_INSN_PAGE_SIZE(slots_per_page(c)), GFP_KERNEL);
6f716acd5   Christoph Hellwig   kprobes: codingst...
164
  	if (!kip)
c802d64a3   Heiko Carstens   kprobes: unify in...
165
  		goto out;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
166
167
168
169
170
171
  
  	/*
  	 * Use module_alloc so this page is within +/- 2GB of where the
  	 * kernel image and loaded module images reside. This is required
  	 * so x86_64 can correctly handle the %rip-relative fixups.
  	 */
af96397de   Heiko Carstens   kprobes: allow to...
172
  	kip->insns = c->alloc();
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
173
174
  	if (!kip->insns) {
  		kfree(kip);
c802d64a3   Heiko Carstens   kprobes: unify in...
175
  		goto out;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
176
  	}
c5cb5a2d8   Masami Hiramatsu   kprobes: Clean up...
177
  	INIT_LIST_HEAD(&kip->list);
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
178
  	memset(kip->slot_used, SLOT_CLEAN, slots_per_page(c));
ab40c5c6b   Masami Hiramatsu   [PATCH] kprobes: ...
179
  	kip->slot_used[0] = SLOT_USED;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
180
  	kip->nused = 1;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
181
  	kip->ngarbage = 0;
af96397de   Heiko Carstens   kprobes: allow to...
182
  	kip->cache = c;
5b485629b   Masami Hiramatsu   kprobes, extable:...
183
  	list_add_rcu(&kip->list, &c->pages);
c802d64a3   Heiko Carstens   kprobes: unify in...
184
  	slot = kip->insns;
69e490886   Adrian Hunter   kprobes: Add perf...
185
186
187
188
  
  	/* Record the perf ksymbol register event after adding the page */
  	perf_event_ksymbol(PERF_RECORD_KSYMBOL_TYPE_OOL, (unsigned long)kip->insns,
  			   PAGE_SIZE, false, c->sym);
c802d64a3   Heiko Carstens   kprobes: unify in...
189
190
191
  out:
  	mutex_unlock(&c->mutex);
  	return slot;
129415607   Masami Hiramatsu   kprobes: add kpro...
192
  }
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
193
  /* Return 1 if all garbages are collected, otherwise 0. */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
194
  static int collect_one_slot(struct kprobe_insn_page *kip, int idx)
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
195
  {
ab40c5c6b   Masami Hiramatsu   [PATCH] kprobes: ...
196
  	kip->slot_used[idx] = SLOT_CLEAN;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
197
198
199
200
201
202
203
204
  	kip->nused--;
  	if (kip->nused == 0) {
  		/*
  		 * Page is no longer in use.  Free it unless
  		 * it's the last one.  We keep the last one
  		 * so as not to have to set it up again the
  		 * next time somebody inserts a probe.
  		 */
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
205
  		if (!list_is_singular(&kip->list)) {
69e490886   Adrian Hunter   kprobes: Add perf...
206
207
208
209
210
211
212
  			/*
  			 * Record perf ksymbol unregister event before removing
  			 * the page.
  			 */
  			perf_event_ksymbol(PERF_RECORD_KSYMBOL_TYPE_OOL,
  					   (unsigned long)kip->insns, PAGE_SIZE, true,
  					   kip->cache->sym);
5b485629b   Masami Hiramatsu   kprobes, extable:...
213
214
  			list_del_rcu(&kip->list);
  			synchronize_rcu();
af96397de   Heiko Carstens   kprobes: allow to...
215
  			kip->cache->free(kip->insns);
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
216
217
218
219
220
221
  			kfree(kip);
  		}
  		return 1;
  	}
  	return 0;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
222
  static int collect_garbage_slots(struct kprobe_insn_cache *c)
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
223
  {
c5cb5a2d8   Masami Hiramatsu   kprobes: Clean up...
224
  	struct kprobe_insn_page *kip, *next;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
225

615d0ebbc   Masami Hiramatsu   kprobes: Disable ...
226
  	/* Ensure no-one is interrupted on the garbages */
ae8b7ce76   Paul E. McKenney   kprobes: Replace ...
227
  	synchronize_rcu();
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
228

4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
229
  	list_for_each_entry_safe(kip, next, &c->pages, list) {
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
230
  		int i;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
231
232
233
  		if (kip->ngarbage == 0)
  			continue;
  		kip->ngarbage = 0;	/* we will collect all garbages */
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
234
  		for (i = 0; i < slots_per_page(c); i++) {
5b485629b   Masami Hiramatsu   kprobes, extable:...
235
  			if (kip->slot_used[i] == SLOT_DIRTY && collect_one_slot(kip, i))
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
236
237
238
  				break;
  		}
  	}
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
239
  	c->nr_garbage = 0;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
240
241
  	return 0;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
242
243
  void __free_insn_slot(struct kprobe_insn_cache *c,
  		      kprobe_opcode_t *slot, int dirty)
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
244
245
  {
  	struct kprobe_insn_page *kip;
5b485629b   Masami Hiramatsu   kprobes, extable:...
246
  	long idx;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
247

c802d64a3   Heiko Carstens   kprobes: unify in...
248
  	mutex_lock(&c->mutex);
5b485629b   Masami Hiramatsu   kprobes, extable:...
249
250
251
252
253
  	rcu_read_lock();
  	list_for_each_entry_rcu(kip, &c->pages, list) {
  		idx = ((long)slot - (long)kip->insns) /
  			(c->insn_size * sizeof(kprobe_opcode_t));
  		if (idx >= 0 && idx < slots_per_page(c))
c802d64a3   Heiko Carstens   kprobes: unify in...
254
  			goto out;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
255
  	}
5b485629b   Masami Hiramatsu   kprobes, extable:...
256
  	/* Could not find this slot. */
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
257
  	WARN_ON(1);
5b485629b   Masami Hiramatsu   kprobes, extable:...
258
  	kip = NULL;
c802d64a3   Heiko Carstens   kprobes: unify in...
259
  out:
5b485629b   Masami Hiramatsu   kprobes, extable:...
260
261
262
263
264
265
266
267
268
269
270
271
272
273
  	rcu_read_unlock();
  	/* Mark and sweep: this may sleep */
  	if (kip) {
  		/* Check double free */
  		WARN_ON(kip->slot_used[idx] != SLOT_USED);
  		if (dirty) {
  			kip->slot_used[idx] = SLOT_DIRTY;
  			kip->ngarbage++;
  			if (++c->nr_garbage > slots_per_page(c))
  				collect_garbage_slots(c);
  		} else {
  			collect_one_slot(kip, idx);
  		}
  	}
c802d64a3   Heiko Carstens   kprobes: unify in...
274
  	mutex_unlock(&c->mutex);
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
275
  }
6f716acd5   Christoph Hellwig   kprobes: codingst...
276

5b485629b   Masami Hiramatsu   kprobes, extable:...
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
  /*
   * Check given address is on the page of kprobe instruction slots.
   * This will be used for checking whether the address on a stack
   * is on a text area or not.
   */
  bool __is_insn_slot_addr(struct kprobe_insn_cache *c, unsigned long addr)
  {
  	struct kprobe_insn_page *kip;
  	bool ret = false;
  
  	rcu_read_lock();
  	list_for_each_entry_rcu(kip, &c->pages, list) {
  		if (addr >= (unsigned long)kip->insns &&
  		    addr < (unsigned long)kip->insns + PAGE_SIZE) {
  			ret = true;
  			break;
  		}
  	}
  	rcu_read_unlock();
  
  	return ret;
  }
d002b8bc6   Adrian Hunter   kprobes: Add symb...
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
  int kprobe_cache_get_kallsym(struct kprobe_insn_cache *c, unsigned int *symnum,
  			     unsigned long *value, char *type, char *sym)
  {
  	struct kprobe_insn_page *kip;
  	int ret = -ERANGE;
  
  	rcu_read_lock();
  	list_for_each_entry_rcu(kip, &c->pages, list) {
  		if ((*symnum)--)
  			continue;
  		strlcpy(sym, c->sym, KSYM_NAME_LEN);
  		*type = 't';
  		*value = (unsigned long)kip->insns;
  		ret = 0;
  		break;
  	}
  	rcu_read_unlock();
  
  	return ret;
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
319
320
  #ifdef CONFIG_OPTPROBES
  /* For optimized_kprobe buffer */
c802d64a3   Heiko Carstens   kprobes: unify in...
321
322
  struct kprobe_insn_cache kprobe_optinsn_slots = {
  	.mutex = __MUTEX_INITIALIZER(kprobe_optinsn_slots.mutex),
af96397de   Heiko Carstens   kprobes: allow to...
323
324
  	.alloc = alloc_insn_page,
  	.free = free_insn_page,
d002b8bc6   Adrian Hunter   kprobes: Add symb...
325
  	.sym = KPROBE_OPTINSN_PAGE_SYM,
afd66255b   Masami Hiramatsu   kprobes: Introduc...
326
327
328
329
  	.pages = LIST_HEAD_INIT(kprobe_optinsn_slots.pages),
  	/* .insn_size is initialized later */
  	.nr_garbage = 0,
  };
afd66255b   Masami Hiramatsu   kprobes: Introduc...
330
  #endif
2d14e39da   Anil S Keshavamurthy   [PATCH] kprobes: ...
331
  #endif
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
332

e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
333
334
335
  /* We have preemption disabled.. so it is safe to use __ versions */
  static inline void set_kprobe_instance(struct kprobe *kp)
  {
b76834bc1   Christoph Lameter   kprobes: Use this...
336
  	__this_cpu_write(kprobe_instance, kp);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
337
338
339
340
  }
  
  static inline void reset_kprobe_instance(void)
  {
b76834bc1   Christoph Lameter   kprobes: Use this...
341
  	__this_cpu_write(kprobe_instance, NULL);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
342
  }
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
343
344
  /*
   * This routine is called either:
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
345
   * 	- under the kprobe_mutex - during kprobe_[un]register()
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
346
   * 				OR
d217d5450   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
347
   * 	- with preemption disabled - from arch/xxx/kernel/kprobes.c
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
348
   */
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
349
  struct kprobe *get_kprobe(void *addr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350
351
  {
  	struct hlist_head *head;
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
352
  	struct kprobe *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
353
354
  
  	head = &kprobe_table[hash_ptr(addr, KPROBE_HASH_BITS)];
6743ad432   Masami Hiramatsu   kprobes: Suppress...
355
356
  	hlist_for_each_entry_rcu(p, head, hlist,
  				 lockdep_is_held(&kprobe_mutex)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
357
358
359
  		if (p->addr == addr)
  			return p;
  	}
afd66255b   Masami Hiramatsu   kprobes: Introduc...
360

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
361
362
  	return NULL;
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
363
  NOKPROBE_SYMBOL(get_kprobe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
365
  static int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
366
367
368
369
370
371
  
  /* Return true if the kprobe is an aggregator */
  static inline int kprobe_aggrprobe(struct kprobe *p)
  {
  	return p->pre_handler == aggr_pre_handler;
  }
6274de498   Masami Hiramatsu   kprobes: Support ...
372
373
374
375
376
377
  /* Return true(!0) if the kprobe is unused */
  static inline int kprobe_unused(struct kprobe *p)
  {
  	return kprobe_aggrprobe(p) && kprobe_disabled(p) &&
  	       list_empty(&p->list);
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
378
379
380
  /*
   * Keep all fields in the kprobe consistent
   */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
381
  static inline void copy_kprobe(struct kprobe *ap, struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
382
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
383
384
  	memcpy(&p->opcode, &ap->opcode, sizeof(kprobe_opcode_t));
  	memcpy(&p->ainsn, &ap->ainsn, sizeof(struct arch_specific_insn));
afd66255b   Masami Hiramatsu   kprobes: Introduc...
385
386
387
  }
  
  #ifdef CONFIG_OPTPROBES
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
388
389
  /* NOTE: change this value only with kprobe_mutex held */
  static bool kprobes_allow_optimization;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
390
391
392
393
  /*
   * Call all pre_handler on the list, but ignores its return value.
   * This must be called from arch-dep optimized caller.
   */
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
394
  void opt_pre_handler(struct kprobe *p, struct pt_regs *regs)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
395
396
397
398
399
400
  {
  	struct kprobe *kp;
  
  	list_for_each_entry_rcu(kp, &p->list, list) {
  		if (kp->pre_handler && likely(!kprobe_disabled(kp))) {
  			set_kprobe_instance(kp);
4f3a87144   Naveen N. Rao   Revert "kprobes: ...
401
  			kp->pre_handler(kp, regs);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
402
403
404
405
  		}
  		reset_kprobe_instance();
  	}
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
406
  NOKPROBE_SYMBOL(opt_pre_handler);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
407

6274de498   Masami Hiramatsu   kprobes: Support ...
408
  /* Free optimized instructions and optimized_kprobe */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
409
  static void free_aggr_kprobe(struct kprobe *p)
6274de498   Masami Hiramatsu   kprobes: Support ...
410
411
412
413
414
415
416
417
  {
  	struct optimized_kprobe *op;
  
  	op = container_of(p, struct optimized_kprobe, kp);
  	arch_remove_optimized_kprobe(op);
  	arch_remove_kprobe(p);
  	kfree(op);
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
418
419
420
421
422
423
424
425
426
427
428
429
  /* Return true(!0) if the kprobe is ready for optimization. */
  static inline int kprobe_optready(struct kprobe *p)
  {
  	struct optimized_kprobe *op;
  
  	if (kprobe_aggrprobe(p)) {
  		op = container_of(p, struct optimized_kprobe, kp);
  		return arch_prepared_optinsn(&op->optinsn);
  	}
  
  	return 0;
  }
6274de498   Masami Hiramatsu   kprobes: Support ...
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
  /* Return true(!0) if the kprobe is disarmed. Note: p must be on hash list */
  static inline int kprobe_disarmed(struct kprobe *p)
  {
  	struct optimized_kprobe *op;
  
  	/* If kprobe is not aggr/opt probe, just return kprobe is disabled */
  	if (!kprobe_aggrprobe(p))
  		return kprobe_disabled(p);
  
  	op = container_of(p, struct optimized_kprobe, kp);
  
  	return kprobe_disabled(p) && list_empty(&op->list);
  }
  
  /* Return true(!0) if the probe is queued on (un)optimizing lists */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
445
  static int kprobe_queued(struct kprobe *p)
6274de498   Masami Hiramatsu   kprobes: Support ...
446
447
448
449
450
451
452
453
454
455
  {
  	struct optimized_kprobe *op;
  
  	if (kprobe_aggrprobe(p)) {
  		op = container_of(p, struct optimized_kprobe, kp);
  		if (!list_empty(&op->list))
  			return 1;
  	}
  	return 0;
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
456
457
458
459
  /*
   * Return an optimized kprobe whose optimizing code replaces
   * instructions including addr (exclude breakpoint).
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
460
  static struct kprobe *get_optimized_kprobe(unsigned long addr)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
  {
  	int i;
  	struct kprobe *p = NULL;
  	struct optimized_kprobe *op;
  
  	/* Don't check i == 0, since that is a breakpoint case. */
  	for (i = 1; !p && i < MAX_OPTIMIZED_LENGTH; i++)
  		p = get_kprobe((void *)(addr - i));
  
  	if (p && kprobe_optready(p)) {
  		op = container_of(p, struct optimized_kprobe, kp);
  		if (arch_within_optimized_kprobe(op, addr))
  			return p;
  	}
  
  	return NULL;
  }
  
  /* Optimization staging list, protected by kprobe_mutex */
  static LIST_HEAD(optimizing_list);
6274de498   Masami Hiramatsu   kprobes: Support ...
481
  static LIST_HEAD(unoptimizing_list);
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
482
  static LIST_HEAD(freeing_list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
483
484
485
486
  
  static void kprobe_optimizer(struct work_struct *work);
  static DECLARE_DELAYED_WORK(optimizing_work, kprobe_optimizer);
  #define OPTIMIZE_DELAY 5
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
487
488
489
490
  /*
   * Optimize (replace a breakpoint with a jump) kprobes listed on
   * optimizing_list.
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
491
  static void do_optimize_kprobes(void)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
492
  {
f1c6ece23   Andrea Righi   kprobes: Fix pote...
493
  	lockdep_assert_held(&text_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
494
495
496
497
498
499
500
  	/*
  	 * The optimization/unoptimization refers online_cpus via
  	 * stop_machine() and cpu-hotplug modifies online_cpus.
  	 * And same time, text_mutex will be held in cpu-hotplug and here.
  	 * This combination can cause a deadlock (cpu-hotplug try to lock
  	 * text_mutex but stop_machine can not be done because online_cpus
  	 * has been changed)
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
501
  	 * To avoid this deadlock, caller must have locked cpu hotplug
afd66255b   Masami Hiramatsu   kprobes: Introduc...
502
503
  	 * for preventing cpu-hotplug outside of text_mutex locking.
  	 */
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
504
505
506
507
508
509
  	lockdep_assert_cpus_held();
  
  	/* Optimization never be done when disarmed */
  	if (kprobes_all_disarmed || !kprobes_allow_optimization ||
  	    list_empty(&optimizing_list))
  		return;
cd7ebe229   Masami Hiramatsu   kprobes: Use text...
510
  	arch_optimize_kprobes(&optimizing_list);
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
511
  }
6274de498   Masami Hiramatsu   kprobes: Support ...
512
513
514
515
  /*
   * Unoptimize (replace a jump with a breakpoint and remove the breakpoint
   * if need) kprobes listed on unoptimizing_list.
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
516
  static void do_unoptimize_kprobes(void)
6274de498   Masami Hiramatsu   kprobes: Support ...
517
518
  {
  	struct optimized_kprobe *op, *tmp;
f1c6ece23   Andrea Righi   kprobes: Fix pote...
519
  	lockdep_assert_held(&text_mutex);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
520
521
  	/* See comment in do_optimize_kprobes() */
  	lockdep_assert_cpus_held();
6274de498   Masami Hiramatsu   kprobes: Support ...
522
523
524
  	/* Unoptimization must be done anytime */
  	if (list_empty(&unoptimizing_list))
  		return;
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
525
  	arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list);
f984ba4eb   Masami Hiramatsu   kprobes: Use text...
526
  	/* Loop free_list for disarming */
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
527
  	list_for_each_entry_safe(op, tmp, &freeing_list, list) {
f66c0447c   Masami Hiramatsu   kprobes: Set unop...
528
529
  		/* Switching from detour code to origin */
  		op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
6274de498   Masami Hiramatsu   kprobes: Support ...
530
531
532
533
534
535
536
537
538
539
  		/* Disarm probes if marked disabled */
  		if (kprobe_disabled(&op->kp))
  			arch_disarm_kprobe(&op->kp);
  		if (kprobe_unused(&op->kp)) {
  			/*
  			 * Remove unused probes from hash list. After waiting
  			 * for synchronization, these probes are reclaimed.
  			 * (reclaiming is done by do_free_cleaned_kprobes.)
  			 */
  			hlist_del_rcu(&op->kp.hlist);
6274de498   Masami Hiramatsu   kprobes: Support ...
540
541
542
  		} else
  			list_del_init(&op->list);
  	}
6274de498   Masami Hiramatsu   kprobes: Support ...
543
544
545
  }
  
  /* Reclaim all kprobes on the free_list */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
546
  static void do_free_cleaned_kprobes(void)
6274de498   Masami Hiramatsu   kprobes: Support ...
547
548
  {
  	struct optimized_kprobe *op, *tmp;
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
549
  	list_for_each_entry_safe(op, tmp, &freeing_list, list) {
6274de498   Masami Hiramatsu   kprobes: Support ...
550
  		list_del_init(&op->list);
cbdd96f55   Masami Hiramatsu   kprobes: Don't ca...
551
552
553
554
555
556
557
  		if (WARN_ON_ONCE(!kprobe_unused(&op->kp))) {
  			/*
  			 * This must not happen, but if there is a kprobe
  			 * still in use, keep it on kprobes hash list.
  			 */
  			continue;
  		}
6274de498   Masami Hiramatsu   kprobes: Support ...
558
559
560
561
562
  		free_aggr_kprobe(&op->kp);
  	}
  }
  
  /* Start optimizer after OPTIMIZE_DELAY passed */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
563
  static void kick_kprobe_optimizer(void)
6274de498   Masami Hiramatsu   kprobes: Support ...
564
  {
ad72b3bea   Tejun Heo   kprobes: fix wait...
565
  	schedule_delayed_work(&optimizing_work, OPTIMIZE_DELAY);
6274de498   Masami Hiramatsu   kprobes: Support ...
566
  }
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
567
  /* Kprobe jump optimizer */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
568
  static void kprobe_optimizer(struct work_struct *work)
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
569
  {
72ef3794c   Steven Rostedt   kprobes: Inverse ...
570
  	mutex_lock(&kprobe_mutex);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
571
  	cpus_read_lock();
f1c6ece23   Andrea Righi   kprobes: Fix pote...
572
  	mutex_lock(&text_mutex);
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
573
574
  
  	/*
6274de498   Masami Hiramatsu   kprobes: Support ...
575
576
577
  	 * Step 1: Unoptimize kprobes and collect cleaned (unused and disarmed)
  	 * kprobes before waiting for quiesence period.
  	 */
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
578
  	do_unoptimize_kprobes();
6274de498   Masami Hiramatsu   kprobes: Support ...
579
580
  
  	/*
a30b85df7   Masami Hiramatsu   kprobes: Use sync...
581
582
583
584
585
586
587
  	 * Step 2: Wait for quiesence period to ensure all potentially
  	 * preempted tasks to have normally scheduled. Because optprobe
  	 * may modify multiple instructions, there is a chance that Nth
  	 * instruction is preempted. In that case, such tasks can return
  	 * to 2nd-Nth byte of jump instruction. This wait is for avoiding it.
  	 * Note that on non-preemptive kernel, this is transparently converted
  	 * to synchronoze_sched() to wait for all interrupts to have completed.
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
588
  	 */
a30b85df7   Masami Hiramatsu   kprobes: Use sync...
589
  	synchronize_rcu_tasks();
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
590

6274de498   Masami Hiramatsu   kprobes: Support ...
591
  	/* Step 3: Optimize kprobes after quiesence period */
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
592
  	do_optimize_kprobes();
6274de498   Masami Hiramatsu   kprobes: Support ...
593
594
  
  	/* Step 4: Free cleaned kprobes after quiesence period */
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
595
  	do_free_cleaned_kprobes();
6274de498   Masami Hiramatsu   kprobes: Support ...
596

f1c6ece23   Andrea Righi   kprobes: Fix pote...
597
  	mutex_unlock(&text_mutex);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
598
  	cpus_read_unlock();
6274de498   Masami Hiramatsu   kprobes: Support ...
599

cd7ebe229   Masami Hiramatsu   kprobes: Use text...
600
  	/* Step 5: Kick optimizer again if needed */
f984ba4eb   Masami Hiramatsu   kprobes: Use text...
601
  	if (!list_empty(&optimizing_list) || !list_empty(&unoptimizing_list))
cd7ebe229   Masami Hiramatsu   kprobes: Use text...
602
  		kick_kprobe_optimizer();
1a0aa991a   Masami Hiramatsu   kprobes: Fix to p...
603
604
  
  	mutex_unlock(&kprobe_mutex);
6274de498   Masami Hiramatsu   kprobes: Support ...
605
606
607
  }
  
  /* Wait for completing optimization and unoptimization */
30e7d894c   Thomas Gleixner   tracing/kprobes: ...
608
  void wait_for_kprobe_optimizer(void)
6274de498   Masami Hiramatsu   kprobes: Support ...
609
  {
ad72b3bea   Tejun Heo   kprobes: fix wait...
610
611
612
613
614
615
616
617
618
619
620
621
622
623
  	mutex_lock(&kprobe_mutex);
  
  	while (!list_empty(&optimizing_list) || !list_empty(&unoptimizing_list)) {
  		mutex_unlock(&kprobe_mutex);
  
  		/* this will also make optimizing_work execute immmediately */
  		flush_delayed_work(&optimizing_work);
  		/* @optimizing_work might not have been queued yet, relax */
  		cpu_relax();
  
  		mutex_lock(&kprobe_mutex);
  	}
  
  	mutex_unlock(&kprobe_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
624
  }
e4add2477   Masami Hiramatsu   kprobes: Fix opti...
625
626
627
628
629
630
631
632
633
634
635
  static bool optprobe_queued_unopt(struct optimized_kprobe *op)
  {
  	struct optimized_kprobe *_op;
  
  	list_for_each_entry(_op, &unoptimizing_list, list) {
  		if (op == _op)
  			return true;
  	}
  
  	return false;
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
636
  /* Optimize kprobe if p is ready to be optimized */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
637
  static void optimize_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
638
639
640
641
  {
  	struct optimized_kprobe *op;
  
  	/* Check if the kprobe is disabled or not ready for optimization. */
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
642
  	if (!kprobe_optready(p) || !kprobes_allow_optimization ||
afd66255b   Masami Hiramatsu   kprobes: Introduc...
643
644
  	    (kprobe_disabled(p) || kprobes_all_disarmed))
  		return;
059053a27   Masami Hiramatsu   kprobes: Don't ch...
645
646
  	/* kprobes with post_handler can not be optimized */
  	if (p->post_handler)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
647
648
649
650
651
652
653
654
655
  		return;
  
  	op = container_of(p, struct optimized_kprobe, kp);
  
  	/* Check there is no other kprobes at the optimized instructions */
  	if (arch_check_optimized_kprobe(op) < 0)
  		return;
  
  	/* Check if it is already optimized. */
e4add2477   Masami Hiramatsu   kprobes: Fix opti...
656
657
658
659
660
  	if (op->kp.flags & KPROBE_FLAG_OPTIMIZED) {
  		if (optprobe_queued_unopt(op)) {
  			/* This is under unoptimizing. Just dequeue the probe */
  			list_del_init(&op->list);
  		}
afd66255b   Masami Hiramatsu   kprobes: Introduc...
661
  		return;
e4add2477   Masami Hiramatsu   kprobes: Fix opti...
662
  	}
afd66255b   Masami Hiramatsu   kprobes: Introduc...
663
  	op->kp.flags |= KPROBE_FLAG_OPTIMIZED;
6274de498   Masami Hiramatsu   kprobes: Support ...
664

e4add2477   Masami Hiramatsu   kprobes: Fix opti...
665
666
667
668
669
670
  	/* On unoptimizing/optimizing_list, op must have OPTIMIZED flag */
  	if (WARN_ON_ONCE(!list_empty(&op->list)))
  		return;
  
  	list_add(&op->list, &optimizing_list);
  	kick_kprobe_optimizer();
6274de498   Masami Hiramatsu   kprobes: Support ...
671
672
673
  }
  
  /* Short cut to direct unoptimizing */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
674
  static void force_unoptimize_kprobe(struct optimized_kprobe *op)
6274de498   Masami Hiramatsu   kprobes: Support ...
675
  {
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
676
  	lockdep_assert_cpus_held();
6274de498   Masami Hiramatsu   kprobes: Support ...
677
  	arch_unoptimize_kprobe(op);
f66c0447c   Masami Hiramatsu   kprobes: Set unop...
678
  	op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
679
680
681
  }
  
  /* Unoptimize a kprobe if p is optimized */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
682
  static void unoptimize_kprobe(struct kprobe *p, bool force)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
683
684
  {
  	struct optimized_kprobe *op;
6274de498   Masami Hiramatsu   kprobes: Support ...
685
686
687
688
  	if (!kprobe_aggrprobe(p) || kprobe_disarmed(p))
  		return; /* This is not an optprobe nor optimized */
  
  	op = container_of(p, struct optimized_kprobe, kp);
e4add2477   Masami Hiramatsu   kprobes: Fix opti...
689
  	if (!kprobe_optimized(p))
6274de498   Masami Hiramatsu   kprobes: Support ...
690
  		return;
6274de498   Masami Hiramatsu   kprobes: Support ...
691

6274de498   Masami Hiramatsu   kprobes: Support ...
692
  	if (!list_empty(&op->list)) {
e4add2477   Masami Hiramatsu   kprobes: Fix opti...
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
  		if (optprobe_queued_unopt(op)) {
  			/* Queued in unoptimizing queue */
  			if (force) {
  				/*
  				 * Forcibly unoptimize the kprobe here, and queue it
  				 * in the freeing list for release afterwards.
  				 */
  				force_unoptimize_kprobe(op);
  				list_move(&op->list, &freeing_list);
  			}
  		} else {
  			/* Dequeue from the optimizing queue */
  			list_del_init(&op->list);
  			op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
  		}
6274de498   Masami Hiramatsu   kprobes: Support ...
708
709
  		return;
  	}
e4add2477   Masami Hiramatsu   kprobes: Fix opti...
710

6274de498   Masami Hiramatsu   kprobes: Support ...
711
  	/* Optimized kprobe case */
e4add2477   Masami Hiramatsu   kprobes: Fix opti...
712
  	if (force) {
6274de498   Masami Hiramatsu   kprobes: Support ...
713
714
  		/* Forcibly update the code: this is a special case */
  		force_unoptimize_kprobe(op);
e4add2477   Masami Hiramatsu   kprobes: Fix opti...
715
  	} else {
6274de498   Masami Hiramatsu   kprobes: Support ...
716
717
  		list_add(&op->list, &unoptimizing_list);
  		kick_kprobe_optimizer();
afd66255b   Masami Hiramatsu   kprobes: Introduc...
718
719
  	}
  }
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
720
  /* Cancel unoptimizing for reusing */
819319fc9   Masami Hiramatsu   kprobes: Return e...
721
  static int reuse_unused_kprobe(struct kprobe *ap)
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
722
723
  {
  	struct optimized_kprobe *op;
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
724
725
726
727
728
  	/*
  	 * Unused kprobe MUST be on the way of delayed unoptimizing (means
  	 * there is still a relative jump) and disabled.
  	 */
  	op = container_of(ap, struct optimized_kprobe, kp);
4458515b2   Masami Hiramatsu   kprobes: Replace ...
729
  	WARN_ON_ONCE(list_empty(&op->list));
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
730
731
732
  	/* Enable the probe again */
  	ap->flags &= ~KPROBE_FLAG_DISABLED;
  	/* Optimize it again (remove from op->list) */
5f843ed41   Masami Hiramatsu   kprobes: Fix erro...
733
734
  	if (!kprobe_optready(ap))
  		return -EINVAL;
819319fc9   Masami Hiramatsu   kprobes: Return e...
735

0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
736
  	optimize_kprobe(ap);
819319fc9   Masami Hiramatsu   kprobes: Return e...
737
  	return 0;
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
738
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
739
  /* Remove optimized instructions */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
740
  static void kill_optimized_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
741
742
743
744
  {
  	struct optimized_kprobe *op;
  
  	op = container_of(p, struct optimized_kprobe, kp);
6274de498   Masami Hiramatsu   kprobes: Support ...
745
746
  	if (!list_empty(&op->list))
  		/* Dequeue from the (un)optimization queue */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
747
  		list_del_init(&op->list);
6274de498   Masami Hiramatsu   kprobes: Support ...
748
  	op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
749
750
751
752
753
754
755
756
757
758
759
  
  	if (kprobe_unused(p)) {
  		/* Enqueue if it is unused */
  		list_add(&op->list, &freeing_list);
  		/*
  		 * Remove unused probes from the hash list. After waiting
  		 * for synchronization, this probe is reclaimed.
  		 * (reclaiming is done by do_free_cleaned_kprobes().)
  		 */
  		hlist_del_rcu(&op->kp.hlist);
  	}
6274de498   Masami Hiramatsu   kprobes: Support ...
760
  	/* Don't touch the code, because it is already freed. */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
761
762
  	arch_remove_optimized_kprobe(op);
  }
a460246c7   Masami Hiramatsu   kprobes: Skip pre...
763
764
765
766
767
768
  static inline
  void __prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
  {
  	if (!kprobe_ftrace(p))
  		arch_prepare_optimized_kprobe(op, p);
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
769
  /* Try to prepare optimized instructions */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
770
  static void prepare_optimized_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
771
772
773
774
  {
  	struct optimized_kprobe *op;
  
  	op = container_of(p, struct optimized_kprobe, kp);
a460246c7   Masami Hiramatsu   kprobes: Skip pre...
775
  	__prepare_optimized_kprobe(op, p);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
776
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
777
  /* Allocate new optimized_kprobe and try to prepare optimized instructions */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
778
  static struct kprobe *alloc_aggr_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
779
780
781
782
783
784
785
786
787
  {
  	struct optimized_kprobe *op;
  
  	op = kzalloc(sizeof(struct optimized_kprobe), GFP_KERNEL);
  	if (!op)
  		return NULL;
  
  	INIT_LIST_HEAD(&op->list);
  	op->kp.addr = p->addr;
a460246c7   Masami Hiramatsu   kprobes: Skip pre...
788
  	__prepare_optimized_kprobe(op, p);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
789
790
791
  
  	return &op->kp;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
792
  static void init_aggr_kprobe(struct kprobe *ap, struct kprobe *p);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
793
794
795
796
797
  
  /*
   * Prepare an optimized_kprobe and optimize it
   * NOTE: p must be a normal registered kprobe
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
798
  static void try_to_optimize_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
799
800
801
  {
  	struct kprobe *ap;
  	struct optimized_kprobe *op;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
802
803
804
  	/* Impossible to optimize ftrace-based kprobe */
  	if (kprobe_ftrace(p))
  		return;
25764288d   Masami Hiramatsu   kprobes: Move loc...
805
  	/* For preparing optimization, jump_label_text_reserved() is called */
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
806
  	cpus_read_lock();
25764288d   Masami Hiramatsu   kprobes: Move loc...
807
808
  	jump_label_lock();
  	mutex_lock(&text_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
809
810
  	ap = alloc_aggr_kprobe(p);
  	if (!ap)
25764288d   Masami Hiramatsu   kprobes: Move loc...
811
  		goto out;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
812
813
814
815
  
  	op = container_of(ap, struct optimized_kprobe, kp);
  	if (!arch_prepared_optinsn(&op->optinsn)) {
  		/* If failed to setup optimizing, fallback to kprobe */
6274de498   Masami Hiramatsu   kprobes: Support ...
816
817
  		arch_remove_optimized_kprobe(op);
  		kfree(op);
25764288d   Masami Hiramatsu   kprobes: Move loc...
818
  		goto out;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
819
820
821
  	}
  
  	init_aggr_kprobe(ap, p);
25764288d   Masami Hiramatsu   kprobes: Move loc...
822
823
824
825
826
  	optimize_kprobe(ap);	/* This just kicks optimizer thread */
  
  out:
  	mutex_unlock(&text_mutex);
  	jump_label_unlock();
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
827
  	cpus_read_unlock();
afd66255b   Masami Hiramatsu   kprobes: Introduc...
828
  }
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
829
  #ifdef CONFIG_SYSCTL
55479f647   Masami Hiramatsu   kprobes: Allow pr...
830
  static void optimize_all_kprobes(void)
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
831
832
  {
  	struct hlist_head *head;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
833
834
  	struct kprobe *p;
  	unsigned int i;
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
835
  	mutex_lock(&kprobe_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
836
837
  	/* If optimization is already allowed, just return */
  	if (kprobes_allow_optimization)
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
838
  		goto out;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
839

2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
840
  	cpus_read_lock();
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
841
  	kprobes_allow_optimization = true;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
842
843
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
7e6a71d8e   Masami Hiramatsu   kprobes: Use non ...
844
  		hlist_for_each_entry(p, head, hlist)
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
845
846
847
  			if (!kprobe_disabled(p))
  				optimize_kprobe(p);
  	}
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
848
  	cpus_read_unlock();
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
849
850
  	printk(KERN_INFO "Kprobes globally optimized
  ");
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
851
852
  out:
  	mutex_unlock(&kprobe_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
853
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
854
  static void unoptimize_all_kprobes(void)
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
855
856
  {
  	struct hlist_head *head;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
857
858
  	struct kprobe *p;
  	unsigned int i;
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
859
  	mutex_lock(&kprobe_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
860
  	/* If optimization is already prohibited, just return */
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
861
862
  	if (!kprobes_allow_optimization) {
  		mutex_unlock(&kprobe_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
863
  		return;
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
864
  	}
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
865

2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
866
  	cpus_read_lock();
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
867
  	kprobes_allow_optimization = false;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
868
869
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
7e6a71d8e   Masami Hiramatsu   kprobes: Use non ...
870
  		hlist_for_each_entry(p, head, hlist) {
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
871
  			if (!kprobe_disabled(p))
6274de498   Masami Hiramatsu   kprobes: Support ...
872
  				unoptimize_kprobe(p, false);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
873
874
  		}
  	}
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
875
  	cpus_read_unlock();
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
876
  	mutex_unlock(&kprobe_mutex);
6274de498   Masami Hiramatsu   kprobes: Support ...
877
878
879
880
  	/* Wait for unoptimizing completion */
  	wait_for_kprobe_optimizer();
  	printk(KERN_INFO "Kprobes globally unoptimized
  ");
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
881
  }
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
882
  static DEFINE_MUTEX(kprobe_sysctl_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
883
884
  int sysctl_kprobes_optimization;
  int proc_kprobes_optimization_handler(struct ctl_table *table, int write,
32927393d   Christoph Hellwig   sysctl: pass kern...
885
  				      void *buffer, size_t *length,
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
886
887
888
  				      loff_t *ppos)
  {
  	int ret;
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
889
  	mutex_lock(&kprobe_sysctl_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
890
891
892
893
894
895
896
  	sysctl_kprobes_optimization = kprobes_allow_optimization ? 1 : 0;
  	ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
  
  	if (sysctl_kprobes_optimization)
  		optimize_all_kprobes();
  	else
  		unoptimize_all_kprobes();
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
897
  	mutex_unlock(&kprobe_sysctl_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
898
899
900
901
  
  	return ret;
  }
  #endif /* CONFIG_SYSCTL */
6274de498   Masami Hiramatsu   kprobes: Support ...
902
  /* Put a breakpoint for a probe. Must be called with text_mutex locked */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
903
  static void __arm_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
904
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
905
  	struct kprobe *_p;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
906
907
  
  	/* Check collision with other optimized kprobes */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
908
909
  	_p = get_optimized_kprobe((unsigned long)p->addr);
  	if (unlikely(_p))
6274de498   Masami Hiramatsu   kprobes: Support ...
910
911
  		/* Fallback to unoptimized kprobe */
  		unoptimize_kprobe(_p, true);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
912
913
914
915
  
  	arch_arm_kprobe(p);
  	optimize_kprobe(p);	/* Try to optimize (add kprobe to a list) */
  }
6274de498   Masami Hiramatsu   kprobes: Support ...
916
  /* Remove the breakpoint of a probe. Must be called with text_mutex locked */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
917
  static void __disarm_kprobe(struct kprobe *p, bool reopt)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
918
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
919
  	struct kprobe *_p;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
920

69d54b916   Wang Nan   kprobes: makes kp...
921
922
  	/* Try to unoptimize */
  	unoptimize_kprobe(p, kprobes_all_disarmed);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
923

6274de498   Masami Hiramatsu   kprobes: Support ...
924
925
926
927
928
929
930
931
  	if (!kprobe_queued(p)) {
  		arch_disarm_kprobe(p);
  		/* If another kprobe was blocked, optimize it. */
  		_p = get_optimized_kprobe((unsigned long)p->addr);
  		if (unlikely(_p) && reopt)
  			optimize_kprobe(_p);
  	}
  	/* TODO: reoptimize others after unoptimized this probe */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
932
933
934
935
936
  }
  
  #else /* !CONFIG_OPTPROBES */
  
  #define optimize_kprobe(p)			do {} while (0)
6274de498   Masami Hiramatsu   kprobes: Support ...
937
  #define unoptimize_kprobe(p, f)			do {} while (0)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
938
939
940
941
  #define kill_optimized_kprobe(p)		do {} while (0)
  #define prepare_optimized_kprobe(p)		do {} while (0)
  #define try_to_optimize_kprobe(p)		do {} while (0)
  #define __arm_kprobe(p)				arch_arm_kprobe(p)
6274de498   Masami Hiramatsu   kprobes: Support ...
942
943
944
  #define __disarm_kprobe(p, o)			arch_disarm_kprobe(p)
  #define kprobe_disarmed(p)			kprobe_disabled(p)
  #define wait_for_kprobe_optimizer()		do {} while (0)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
945

819319fc9   Masami Hiramatsu   kprobes: Return e...
946
  static int reuse_unused_kprobe(struct kprobe *ap)
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
947
  {
819319fc9   Masami Hiramatsu   kprobes: Return e...
948
949
950
951
952
953
  	/*
  	 * If the optimized kprobe is NOT supported, the aggr kprobe is
  	 * released at the same time that the last aggregated kprobe is
  	 * unregistered.
  	 * Thus there should be no chance to reuse unused kprobe.
  	 */
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
954
955
  	printk(KERN_ERR "Error: There should be no unused kprobe here.
  ");
819319fc9   Masami Hiramatsu   kprobes: Return e...
956
  	return -EINVAL;
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
957
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
958
  static void free_aggr_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
959
  {
6274de498   Masami Hiramatsu   kprobes: Support ...
960
  	arch_remove_kprobe(p);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
961
962
  	kfree(p);
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
963
  static struct kprobe *alloc_aggr_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
964
965
966
967
  {
  	return kzalloc(sizeof(struct kprobe), GFP_KERNEL);
  }
  #endif /* CONFIG_OPTPROBES */
e7dbfe349   Masami Hiramatsu   kprobes/x86: Move...
968
  #ifdef CONFIG_KPROBES_ON_FTRACE
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
969
  static struct ftrace_ops kprobe_ftrace_ops __read_mostly = {
e52538965   Masami Hiramatsu   kprobes/x86: ftra...
970
  	.func = kprobe_ftrace_handler,
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
971
972
973
974
975
  	.flags = FTRACE_OPS_FL_SAVE_REGS,
  };
  
  static struct ftrace_ops kprobe_ipmodify_ops __read_mostly = {
  	.func = kprobe_ftrace_handler,
1d70be34d   Masami Hiramatsu   kprobes: Add IPMO...
976
  	.flags = FTRACE_OPS_FL_SAVE_REGS | FTRACE_OPS_FL_IPMODIFY,
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
977
  };
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
978
979
  
  static int kprobe_ipmodify_enabled;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
980
981
982
  static int kprobe_ftrace_enabled;
  
  /* Must ensure p->addr is really on ftrace */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
983
  static int prepare_kprobe(struct kprobe *p)
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
984
985
986
987
988
989
990
991
  {
  	if (!kprobe_ftrace(p))
  		return arch_prepare_kprobe(p);
  
  	return arch_prepare_kprobe_ftrace(p);
  }
  
  /* Caller must lock kprobe_mutex */
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
992
993
  static int __arm_kprobe_ftrace(struct kprobe *p, struct ftrace_ops *ops,
  			       int *cnt)
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
994
  {
12310e343   Jessica Yu   kprobes: Propagat...
995
  	int ret = 0;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
996

0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
997
  	ret = ftrace_set_filter_ip(ops, (unsigned long)p->addr, 0, 0);
12310e343   Jessica Yu   kprobes: Propagat...
998
  	if (ret) {
4458515b2   Masami Hiramatsu   kprobes: Replace ...
999
1000
1001
  		pr_debug("Failed to arm kprobe-ftrace at %pS (%d)
  ",
  			 p->addr, ret);
12310e343   Jessica Yu   kprobes: Propagat...
1002
1003
  		return ret;
  	}
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
1004
1005
  	if (*cnt == 0) {
  		ret = register_ftrace_function(ops);
12310e343   Jessica Yu   kprobes: Propagat...
1006
1007
1008
1009
1010
  		if (ret) {
  			pr_debug("Failed to init kprobe-ftrace (%d)
  ", ret);
  			goto err_ftrace;
  		}
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1011
  	}
12310e343   Jessica Yu   kprobes: Propagat...
1012

0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
1013
  	(*cnt)++;
12310e343   Jessica Yu   kprobes: Propagat...
1014
1015
1016
1017
  	return ret;
  
  err_ftrace:
  	/*
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
1018
1019
  	 * At this point, sinec ops is not registered, we should be sefe from
  	 * registering empty filter.
12310e343   Jessica Yu   kprobes: Propagat...
1020
  	 */
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
1021
  	ftrace_set_filter_ip(ops, (unsigned long)p->addr, 1, 0);
12310e343   Jessica Yu   kprobes: Propagat...
1022
  	return ret;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1023
  }
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
1024
1025
1026
1027
1028
1029
1030
1031
  static int arm_kprobe_ftrace(struct kprobe *p)
  {
  	bool ipmodify = (p->post_handler != NULL);
  
  	return __arm_kprobe_ftrace(p,
  		ipmodify ? &kprobe_ipmodify_ops : &kprobe_ftrace_ops,
  		ipmodify ? &kprobe_ipmodify_enabled : &kprobe_ftrace_enabled);
  }
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1032
  /* Caller must lock kprobe_mutex */
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
1033
1034
  static int __disarm_kprobe_ftrace(struct kprobe *p, struct ftrace_ops *ops,
  				  int *cnt)
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1035
  {
297f9233b   Jessica Yu   kprobes: Propagat...
1036
  	int ret = 0;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1037

0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
1038
1039
  	if (*cnt == 1) {
  		ret = unregister_ftrace_function(ops);
297f9233b   Jessica Yu   kprobes: Propagat...
1040
1041
1042
  		if (WARN(ret < 0, "Failed to unregister kprobe-ftrace (%d)
  ", ret))
  			return ret;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1043
  	}
297f9233b   Jessica Yu   kprobes: Propagat...
1044

0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
1045
  	(*cnt)--;
297f9233b   Jessica Yu   kprobes: Propagat...
1046

0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
1047
  	ret = ftrace_set_filter_ip(ops, (unsigned long)p->addr, 1, 0);
4458515b2   Masami Hiramatsu   kprobes: Replace ...
1048
1049
1050
  	WARN_ONCE(ret < 0, "Failed to disarm kprobe-ftrace at %pS (%d)
  ",
  		  p->addr, ret);
297f9233b   Jessica Yu   kprobes: Propagat...
1051
  	return ret;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1052
  }
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
1053
1054
1055
1056
1057
1058
1059
1060
1061
  
  static int disarm_kprobe_ftrace(struct kprobe *p)
  {
  	bool ipmodify = (p->post_handler != NULL);
  
  	return __disarm_kprobe_ftrace(p,
  		ipmodify ? &kprobe_ipmodify_ops : &kprobe_ftrace_ops,
  		ipmodify ? &kprobe_ipmodify_enabled : &kprobe_ftrace_enabled);
  }
e7dbfe349   Masami Hiramatsu   kprobes/x86: Move...
1062
  #else	/* !CONFIG_KPROBES_ON_FTRACE */
10de795a5   Muchun Song   kprobes: Fix comp...
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
  static inline int prepare_kprobe(struct kprobe *p)
  {
  	return arch_prepare_kprobe(p);
  }
  
  static inline int arm_kprobe_ftrace(struct kprobe *p)
  {
  	return -ENODEV;
  }
  
  static inline int disarm_kprobe_ftrace(struct kprobe *p)
  {
  	return -ENODEV;
  }
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1077
  #endif
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1078
  /* Arm a kprobe with text_mutex */
12310e343   Jessica Yu   kprobes: Propagat...
1079
  static int arm_kprobe(struct kprobe *kp)
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1080
  {
12310e343   Jessica Yu   kprobes: Propagat...
1081
1082
  	if (unlikely(kprobe_ftrace(kp)))
  		return arm_kprobe_ftrace(kp);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1083
  	cpus_read_lock();
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1084
  	mutex_lock(&text_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1085
  	__arm_kprobe(kp);
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1086
  	mutex_unlock(&text_mutex);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1087
  	cpus_read_unlock();
12310e343   Jessica Yu   kprobes: Propagat...
1088
1089
  
  	return 0;
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1090
1091
1092
  }
  
  /* Disarm a kprobe with text_mutex */
297f9233b   Jessica Yu   kprobes: Propagat...
1093
  static int disarm_kprobe(struct kprobe *kp, bool reopt)
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1094
  {
297f9233b   Jessica Yu   kprobes: Propagat...
1095
1096
  	if (unlikely(kprobe_ftrace(kp)))
  		return disarm_kprobe_ftrace(kp);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1097
1098
  
  	cpus_read_lock();
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1099
  	mutex_lock(&text_mutex);
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1100
  	__disarm_kprobe(kp, reopt);
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1101
  	mutex_unlock(&text_mutex);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1102
  	cpus_read_unlock();
297f9233b   Jessica Yu   kprobes: Propagat...
1103
1104
  
  	return 0;
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1105
  }
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1106
1107
1108
1109
  /*
   * Aggregate handlers for multiple kprobes support - these handlers
   * take care of invoking the individual kprobe handlers on p->list
   */
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1110
  static int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1111
1112
  {
  	struct kprobe *kp;
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1113
  	list_for_each_entry_rcu(kp, &p->list, list) {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1114
  		if (kp->pre_handler && likely(!kprobe_disabled(kp))) {
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1115
  			set_kprobe_instance(kp);
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1116
1117
  			if (kp->pre_handler(kp, regs))
  				return 1;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1118
  		}
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1119
  		reset_kprobe_instance();
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1120
1121
1122
  	}
  	return 0;
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1123
  NOKPROBE_SYMBOL(aggr_pre_handler);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1124

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1125
1126
  static void aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
  			      unsigned long flags)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1127
1128
  {
  	struct kprobe *kp;
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1129
  	list_for_each_entry_rcu(kp, &p->list, list) {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1130
  		if (kp->post_handler && likely(!kprobe_disabled(kp))) {
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1131
  			set_kprobe_instance(kp);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1132
  			kp->post_handler(kp, regs, flags);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1133
  			reset_kprobe_instance();
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1134
1135
  		}
  	}
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1136
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1137
  NOKPROBE_SYMBOL(aggr_post_handler);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1138

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1139
1140
  static int aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
  			      int trapnr)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1141
  {
b76834bc1   Christoph Lameter   kprobes: Use this...
1142
  	struct kprobe *cur = __this_cpu_read(kprobe_instance);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1143

64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1144
1145
1146
1147
  	/*
  	 * if we faulted "during" the execution of a user specified
  	 * probe handler, invoke just that probe's fault handler
  	 */
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1148
1149
  	if (cur && cur->fault_handler) {
  		if (cur->fault_handler(cur, regs, trapnr))
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1150
1151
1152
1153
  			return 1;
  	}
  	return 0;
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1154
  NOKPROBE_SYMBOL(aggr_fault_handler);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1155

bf8d5c52c   Keshavamurthy Anil S   [PATCH] kprobes: ...
1156
  /* Walks the list and increments nmissed count for multiprobe case */
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1157
  void kprobes_inc_nmissed_count(struct kprobe *p)
bf8d5c52c   Keshavamurthy Anil S   [PATCH] kprobes: ...
1158
1159
  {
  	struct kprobe *kp;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1160
  	if (!kprobe_aggrprobe(p)) {
bf8d5c52c   Keshavamurthy Anil S   [PATCH] kprobes: ...
1161
1162
1163
1164
1165
1166
1167
  		p->nmissed++;
  	} else {
  		list_for_each_entry_rcu(kp, &p->list, list)
  			kp->nmissed++;
  	}
  	return;
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1168
  NOKPROBE_SYMBOL(kprobes_inc_nmissed_count);
bf8d5c52c   Keshavamurthy Anil S   [PATCH] kprobes: ...
1169

b33881780   Masami Hiramatsu   kprobes: Free kre...
1170
  static void recycle_rp_inst(struct kretprobe_instance *ri)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1171
  {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1172
  	struct kretprobe *rp = ri->rp;
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1173
1174
  	/* remove rp inst off the rprobe_inst_table */
  	hlist_del(&ri->hlist);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1175
1176
  	INIT_HLIST_NODE(&ri->hlist);
  	if (likely(rp)) {
ec484608c   Thomas Gleixner   locking, kprobes:...
1177
  		raw_spin_lock(&rp->lock);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1178
  		hlist_add_head(&ri->hlist, &rp->free_instances);
ec484608c   Thomas Gleixner   locking, kprobes:...
1179
  		raw_spin_unlock(&rp->lock);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1180
  	} else
b33881780   Masami Hiramatsu   kprobes: Free kre...
1181
  		kfree_rcu(ri, rcu);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1182
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1183
  NOKPROBE_SYMBOL(recycle_rp_inst);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1184

319f0ce28   Masami Hiramatsu   kprobes: Make loc...
1185
  static void kretprobe_hash_lock(struct task_struct *tsk,
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1186
  			 struct hlist_head **head, unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1187
  __acquires(hlist_lock)
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1188
1189
  {
  	unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS);
ec484608c   Thomas Gleixner   locking, kprobes:...
1190
  	raw_spinlock_t *hlist_lock;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1191
1192
1193
  
  	*head = &kretprobe_inst_table[hash];
  	hlist_lock = kretprobe_table_lock_ptr(hash);
645f224e7   Steven Rostedt (VMware)   kprobes: Tell loc...
1194
1195
1196
1197
1198
1199
1200
  	/*
  	 * Nested is a workaround that will soon not be needed.
  	 * There's other protections that make sure the same lock
  	 * is not taken on the same CPU that lockdep is unaware of.
  	 * Differentiate when it is taken in NMI context.
  	 */
  	raw_spin_lock_irqsave_nested(hlist_lock, *flags, !!in_nmi());
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1201
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1202
  NOKPROBE_SYMBOL(kretprobe_hash_lock);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1203

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1204
1205
  static void kretprobe_table_lock(unsigned long hash,
  				 unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1206
  __acquires(hlist_lock)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1207
  {
ec484608c   Thomas Gleixner   locking, kprobes:...
1208
  	raw_spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash);
645f224e7   Steven Rostedt (VMware)   kprobes: Tell loc...
1209
1210
1211
1212
1213
1214
1215
  	/*
  	 * Nested is a workaround that will soon not be needed.
  	 * There's other protections that make sure the same lock
  	 * is not taken on the same CPU that lockdep is unaware of.
  	 * Differentiate when it is taken in NMI context.
  	 */
  	raw_spin_lock_irqsave_nested(hlist_lock, *flags, !!in_nmi());
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1216
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1217
  NOKPROBE_SYMBOL(kretprobe_table_lock);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1218

319f0ce28   Masami Hiramatsu   kprobes: Make loc...
1219
  static void kretprobe_hash_unlock(struct task_struct *tsk,
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1220
  			   unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1221
  __releases(hlist_lock)
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1222
1223
  {
  	unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS);
ec484608c   Thomas Gleixner   locking, kprobes:...
1224
  	raw_spinlock_t *hlist_lock;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1225
1226
  
  	hlist_lock = kretprobe_table_lock_ptr(hash);
ec484608c   Thomas Gleixner   locking, kprobes:...
1227
  	raw_spin_unlock_irqrestore(hlist_lock, *flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1228
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1229
  NOKPROBE_SYMBOL(kretprobe_hash_unlock);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1230

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1231
1232
  static void kretprobe_table_unlock(unsigned long hash,
  				   unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1233
  __releases(hlist_lock)
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1234
  {
ec484608c   Thomas Gleixner   locking, kprobes:...
1235
1236
  	raw_spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash);
  	raw_spin_unlock_irqrestore(hlist_lock, *flags);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1237
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1238
  NOKPROBE_SYMBOL(kretprobe_table_unlock);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1239

319f0ce28   Masami Hiramatsu   kprobes: Make loc...
1240
  static struct kprobe kprobe_busy = {
9b38cc704   Jiri Olsa   kretprobe: Preven...
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
  	.addr = (void *) get_kprobe,
  };
  
  void kprobe_busy_begin(void)
  {
  	struct kprobe_ctlblk *kcb;
  
  	preempt_disable();
  	__this_cpu_write(current_kprobe, &kprobe_busy);
  	kcb = get_kprobe_ctlblk();
  	kcb->kprobe_status = KPROBE_HIT_ACTIVE;
  }
  
  void kprobe_busy_end(void)
  {
  	__this_cpu_write(current_kprobe, NULL);
  	preempt_enable();
  }
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1259
  /*
c6fd91f0b   bibo mao   [PATCH] kretprobe...
1260
1261
1262
1263
   * This function is called from finish_task_switch when task tk becomes dead,
   * so that we can recycle any function-return probe instances associated
   * with this task. These left over instances represent probed functions
   * that have been called but will never return.
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1264
   */
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1265
  void kprobe_flush_task(struct task_struct *tk)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1266
  {
62c27be0d   bibo,mao   [PATCH] kprobe wh...
1267
  	struct kretprobe_instance *ri;
b33881780   Masami Hiramatsu   kprobes: Free kre...
1268
  	struct hlist_head *head;
b67bfe0d4   Sasha Levin   hlist: drop the n...
1269
  	struct hlist_node *tmp;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1270
  	unsigned long hash, flags = 0;
802eae7c8   Rusty Lynch   [PATCH] Return pr...
1271

ef53d9c5e   Srinivasa D S   kprobes: improve ...
1272
1273
1274
  	if (unlikely(!kprobes_initialized))
  		/* Early boot.  kretprobe_table_locks not yet initialized. */
  		return;
9b38cc704   Jiri Olsa   kretprobe: Preven...
1275
  	kprobe_busy_begin();
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1276
1277
1278
  	hash = hash_ptr(tk, KPROBE_HASH_BITS);
  	head = &kretprobe_inst_table[hash];
  	kretprobe_table_lock(hash, &flags);
b67bfe0d4   Sasha Levin   hlist: drop the n...
1279
  	hlist_for_each_entry_safe(ri, tmp, head, hlist) {
62c27be0d   bibo,mao   [PATCH] kprobe wh...
1280
  		if (ri->task == tk)
b33881780   Masami Hiramatsu   kprobes: Free kre...
1281
  			recycle_rp_inst(ri);
62c27be0d   bibo,mao   [PATCH] kprobe wh...
1282
  	}
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1283
  	kretprobe_table_unlock(hash, &flags);
9b38cc704   Jiri Olsa   kretprobe: Preven...
1284
1285
  
  	kprobe_busy_end();
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1286
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1287
  NOKPROBE_SYMBOL(kprobe_flush_task);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1288

b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1289
1290
1291
  static inline void free_rp_inst(struct kretprobe *rp)
  {
  	struct kretprobe_instance *ri;
b67bfe0d4   Sasha Levin   hlist: drop the n...
1292
  	struct hlist_node *next;
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1293

b67bfe0d4   Sasha Levin   hlist: drop the n...
1294
  	hlist_for_each_entry_safe(ri, next, &rp->free_instances, hlist) {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1295
  		hlist_del(&ri->hlist);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1296
1297
1298
  		kfree(ri);
  	}
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1299
  static void cleanup_rp_inst(struct kretprobe *rp)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1300
  {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1301
  	unsigned long flags, hash;
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1302
  	struct kretprobe_instance *ri;
b67bfe0d4   Sasha Levin   hlist: drop the n...
1303
  	struct hlist_node *next;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1304
  	struct hlist_head *head;
e03b4a084   Masami Hiramatsu   kprobes: Remove N...
1305
1306
  	/* To avoid recursive kretprobe by NMI, set kprobe busy here */
  	kprobe_busy_begin();
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1307
1308
1309
  	for (hash = 0; hash < KPROBE_TABLE_SIZE; hash++) {
  		kretprobe_table_lock(hash, &flags);
  		head = &kretprobe_inst_table[hash];
b67bfe0d4   Sasha Levin   hlist: drop the n...
1310
  		hlist_for_each_entry_safe(ri, next, head, hlist) {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1311
1312
1313
1314
  			if (ri->rp == rp)
  				ri->rp = NULL;
  		}
  		kretprobe_table_unlock(hash, &flags);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1315
  	}
e03b4a084   Masami Hiramatsu   kprobes: Remove N...
1316
  	kprobe_busy_end();
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1317
1318
  	free_rp_inst(rp);
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1319
  NOKPROBE_SYMBOL(cleanup_rp_inst);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1320

059053a27   Masami Hiramatsu   kprobes: Don't ch...
1321
  /* Add the new probe to ap->list */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1322
  static int add_new_kprobe(struct kprobe *ap, struct kprobe *p)
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1323
  {
059053a27   Masami Hiramatsu   kprobes: Don't ch...
1324
  	if (p->post_handler)
6274de498   Masami Hiramatsu   kprobes: Support ...
1325
  		unoptimize_kprobe(ap, true);	/* Fall back to normal kprobe */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1326

059053a27   Masami Hiramatsu   kprobes: Don't ch...
1327
  	list_add_rcu(&p->list, &ap->list);
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1328
1329
  	if (p->post_handler && !ap->post_handler)
  		ap->post_handler = aggr_post_handler;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1330

8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1331
1332
1333
1334
  	return 0;
  }
  
  /*
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1335
1336
1337
   * Fill in the required fields of the "manager kprobe". Replace the
   * earlier kprobe in the hlist with the manager kprobe
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1338
  static void init_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1339
  {
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1340
  	/* Copy p's insn slot to ap */
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1341
  	copy_kprobe(p, ap);
a9ad965ea   bibo, mao   [PATCH] IA64: kpr...
1342
  	flush_insn_slot(ap);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1343
  	ap->addr = p->addr;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1344
  	ap->flags = p->flags & ~KPROBE_FLAG_OPTIMIZED;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1345
  	ap->pre_handler = aggr_pre_handler;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1346
  	ap->fault_handler = aggr_fault_handler;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1347
1348
  	/* We don't care the kprobe which has gone. */
  	if (p->post_handler && !kprobe_gone(p))
367216567   mao, bibo   [PATCH] Kprobe: m...
1349
  		ap->post_handler = aggr_post_handler;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1350
1351
  
  	INIT_LIST_HEAD(&ap->list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1352
  	INIT_HLIST_NODE(&ap->hlist);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1353

afd66255b   Masami Hiramatsu   kprobes: Introduc...
1354
  	list_add_rcu(&p->list, &ap->list);
adad0f331   Keshavamurthy Anil S   [PATCH] kprobes: ...
1355
  	hlist_replace_rcu(&p->hlist, &ap->hlist);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1356
1357
1358
1359
1360
  }
  
  /*
   * This is the second or subsequent kprobe at the address - handle
   * the intricacies
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1361
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1362
  static int register_aggr_kprobe(struct kprobe *orig_p, struct kprobe *p)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1363
1364
  {
  	int ret = 0;
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1365
  	struct kprobe *ap = orig_p;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1366

2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1367
  	cpus_read_lock();
25764288d   Masami Hiramatsu   kprobes: Move loc...
1368
1369
  	/* For preparing optimization, jump_label_text_reserved() is called */
  	jump_label_lock();
25764288d   Masami Hiramatsu   kprobes: Move loc...
1370
  	mutex_lock(&text_mutex);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1371
1372
1373
  	if (!kprobe_aggrprobe(orig_p)) {
  		/* If orig_p is not an aggr_kprobe, create new aggr_kprobe. */
  		ap = alloc_aggr_kprobe(orig_p);
25764288d   Masami Hiramatsu   kprobes: Move loc...
1374
1375
1376
1377
  		if (!ap) {
  			ret = -ENOMEM;
  			goto out;
  		}
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1378
  		init_aggr_kprobe(ap, orig_p);
819319fc9   Masami Hiramatsu   kprobes: Return e...
1379
  	} else if (kprobe_unused(ap)) {
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
1380
  		/* This probe is going to die. Rescue it */
819319fc9   Masami Hiramatsu   kprobes: Return e...
1381
1382
1383
1384
  		ret = reuse_unused_kprobe(ap);
  		if (ret)
  			goto out;
  	}
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1385
1386
  
  	if (kprobe_gone(ap)) {
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1387
1388
1389
1390
1391
1392
  		/*
  		 * Attempting to insert new probe at the same location that
  		 * had a probe in the module vaddr area which already
  		 * freed. So, the instruction slot has already been
  		 * released. We need a new slot for the new probe.
  		 */
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1393
  		ret = arch_prepare_kprobe(ap);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1394
  		if (ret)
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1395
1396
1397
1398
1399
  			/*
  			 * Even if fail to allocate new slot, don't need to
  			 * free aggr_probe. It will be used next time, or
  			 * freed by unregister_kprobe.
  			 */
25764288d   Masami Hiramatsu   kprobes: Move loc...
1400
  			goto out;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1401

afd66255b   Masami Hiramatsu   kprobes: Introduc...
1402
1403
  		/* Prepare optimized instructions if possible. */
  		prepare_optimized_kprobe(ap);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1404
  		/*
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1405
1406
  		 * Clear gone flag to prevent allocating new slot again, and
  		 * set disabled flag because it is not armed yet.
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1407
  		 */
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1408
1409
  		ap->flags = (ap->flags & ~KPROBE_FLAG_GONE)
  			    | KPROBE_FLAG_DISABLED;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1410
  	}
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1411

afd66255b   Masami Hiramatsu   kprobes: Introduc...
1412
  	/* Copy ap's insn slot to p */
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1413
  	copy_kprobe(ap, p);
25764288d   Masami Hiramatsu   kprobes: Move loc...
1414
1415
1416
1417
  	ret = add_new_kprobe(ap, p);
  
  out:
  	mutex_unlock(&text_mutex);
25764288d   Masami Hiramatsu   kprobes: Move loc...
1418
  	jump_label_unlock();
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1419
  	cpus_read_unlock();
25764288d   Masami Hiramatsu   kprobes: Move loc...
1420
1421
1422
  
  	if (ret == 0 && kprobe_disabled(ap) && !kprobe_disabled(p)) {
  		ap->flags &= ~KPROBE_FLAG_DISABLED;
12310e343   Jessica Yu   kprobes: Propagat...
1423
  		if (!kprobes_all_disarmed) {
25764288d   Masami Hiramatsu   kprobes: Move loc...
1424
  			/* Arm the breakpoint again. */
12310e343   Jessica Yu   kprobes: Propagat...
1425
1426
1427
1428
  			ret = arm_kprobe(ap);
  			if (ret) {
  				ap->flags |= KPROBE_FLAG_DISABLED;
  				list_del_rcu(&p->list);
ae8b7ce76   Paul E. McKenney   kprobes: Replace ...
1429
  				synchronize_rcu();
12310e343   Jessica Yu   kprobes: Propagat...
1430
1431
  			}
  		}
25764288d   Masami Hiramatsu   kprobes: Move loc...
1432
1433
  	}
  	return ret;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1434
  }
be8f27432   Masami Hiramatsu   kprobes: Prohibit...
1435
1436
1437
1438
1439
1440
  bool __weak arch_within_kprobe_blacklist(unsigned long addr)
  {
  	/* The __kprobes marked functions and entry code must not be probed */
  	return addr >= (unsigned long)__kprobes_text_start &&
  	       addr < (unsigned long)__kprobes_text_end;
  }
6143c6fb1   Masami Hiramatsu   kprobes: Search n...
1441
  static bool __within_kprobe_blacklist(unsigned long addr)
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1442
  {
376e24242   Masami Hiramatsu   kprobes: Introduc...
1443
  	struct kprobe_blacklist_entry *ent;
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
1444

be8f27432   Masami Hiramatsu   kprobes: Prohibit...
1445
  	if (arch_within_kprobe_blacklist(addr))
376e24242   Masami Hiramatsu   kprobes: Introduc...
1446
  		return true;
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
1447
1448
1449
1450
  	/*
  	 * If there exists a kprobe_blacklist, verify and
  	 * fail any probe registration in the prohibited area
  	 */
376e24242   Masami Hiramatsu   kprobes: Introduc...
1451
1452
1453
  	list_for_each_entry(ent, &kprobe_blacklist, list) {
  		if (addr >= ent->start_addr && addr < ent->end_addr)
  			return true;
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
1454
  	}
6143c6fb1   Masami Hiramatsu   kprobes: Search n...
1455
1456
  	return false;
  }
376e24242   Masami Hiramatsu   kprobes: Introduc...
1457

6143c6fb1   Masami Hiramatsu   kprobes: Search n...
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
  bool within_kprobe_blacklist(unsigned long addr)
  {
  	char symname[KSYM_NAME_LEN], *p;
  
  	if (__within_kprobe_blacklist(addr))
  		return true;
  
  	/* Check if the address is on a suffixed-symbol */
  	if (!lookup_symbol_name(addr, symname)) {
  		p = strchr(symname, '.');
  		if (!p)
  			return false;
  		*p = '\0';
  		addr = (unsigned long)kprobe_lookup_name(symname, 0);
  		if (addr)
  			return __within_kprobe_blacklist(addr);
  	}
376e24242   Masami Hiramatsu   kprobes: Introduc...
1475
  	return false;
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1476
  }
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1477
1478
1479
  /*
   * If we have a symbol_name argument, look it up and add the offset field
   * to it. This way, we can specify a relative address to a symbol.
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1480
1481
   * This returns encoded errors if it fails to look up symbol or invalid
   * combination of parameters.
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1482
   */
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1483
1484
  static kprobe_opcode_t *_kprobe_addr(kprobe_opcode_t *addr,
  			const char *symbol_name, unsigned int offset)
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1485
  {
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1486
  	if ((symbol_name && addr) || (!symbol_name && !addr))
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1487
  		goto invalid;
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1488
  	if (symbol_name) {
7246f6006   Linus Torvalds   Merge tag 'powerp...
1489
  		addr = kprobe_lookup_name(symbol_name, offset);
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1490
1491
  		if (!addr)
  			return ERR_PTR(-ENOENT);
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1492
  	}
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1493
  	addr = (kprobe_opcode_t *)(((char *)addr) + offset);
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1494
1495
1496
1497
1498
  	if (addr)
  		return addr;
  
  invalid:
  	return ERR_PTR(-EINVAL);
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1499
  }
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1500
1501
1502
1503
  static kprobe_opcode_t *kprobe_addr(struct kprobe *p)
  {
  	return _kprobe_addr(p->addr, p->symbol_name, p->offset);
  }
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1504
  /* Check passed kprobe is valid and return kprobe in kprobe_table. */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1505
  static struct kprobe *__get_valid_kprobe(struct kprobe *p)
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1506
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1507
  	struct kprobe *ap, *list_p;
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1508

7e6a71d8e   Masami Hiramatsu   kprobes: Use non ...
1509
  	lockdep_assert_held(&kprobe_mutex);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1510
1511
  	ap = get_kprobe(p->addr);
  	if (unlikely(!ap))
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1512
  		return NULL;
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1513
  	if (p != ap) {
7e6a71d8e   Masami Hiramatsu   kprobes: Use non ...
1514
  		list_for_each_entry(list_p, &ap->list, list)
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1515
1516
1517
1518
1519
1520
  			if (list_p == p)
  			/* kprobe p is a valid probe */
  				goto valid;
  		return NULL;
  	}
  valid:
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1521
  	return ap;
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1522
1523
1524
1525
1526
1527
  }
  
  /* Return error if the kprobe is being re-registered */
  static inline int check_kprobe_rereg(struct kprobe *p)
  {
  	int ret = 0;
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1528
1529
  
  	mutex_lock(&kprobe_mutex);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1530
  	if (__get_valid_kprobe(p))
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1531
1532
  		ret = -EINVAL;
  	mutex_unlock(&kprobe_mutex);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1533

1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1534
1535
  	return ret;
  }
f7f242ff0   Heiko Carstens   kprobes: introduc...
1536
  int __weak arch_check_ftrace_location(struct kprobe *p)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1537
  {
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1538
  	unsigned long ftrace_addr;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1539
1540
  	ftrace_addr = ftrace_location((unsigned long)p->addr);
  	if (ftrace_addr) {
e7dbfe349   Masami Hiramatsu   kprobes/x86: Move...
1541
  #ifdef CONFIG_KPROBES_ON_FTRACE
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1542
1543
1544
  		/* Given address is not on the instruction boundary */
  		if ((unsigned long)p->addr != ftrace_addr)
  			return -EILSEQ;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1545
  		p->flags |= KPROBE_FLAG_FTRACE;
e7dbfe349   Masami Hiramatsu   kprobes/x86: Move...
1546
  #else	/* !CONFIG_KPROBES_ON_FTRACE */
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1547
1548
1549
  		return -EINVAL;
  #endif
  	}
f7f242ff0   Heiko Carstens   kprobes: introduc...
1550
1551
1552
1553
1554
1555
1556
  	return 0;
  }
  
  static int check_kprobe_address_safe(struct kprobe *p,
  				     struct module **probed_mod)
  {
  	int ret;
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1557

f7f242ff0   Heiko Carstens   kprobes: introduc...
1558
1559
1560
  	ret = arch_check_ftrace_location(p);
  	if (ret)
  		return ret;
91bad2f8d   Jason Baron   jump label: Fix d...
1561
  	jump_label_lock();
de31c3ca8   Steven Rostedt   jump label: Fix e...
1562
  	preempt_disable();
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1563
1564
  
  	/* Ensure it is not in reserved area nor out of text */
ec30c5f3a   Masami Hiramatsu   kprobes: Use kern...
1565
  	if (!kernel_text_address((unsigned long) p->addr) ||
376e24242   Masami Hiramatsu   kprobes: Introduc...
1566
  	    within_kprobe_blacklist((unsigned long) p->addr) ||
e336b4027   Masami Hiramatsu   kprobes: Prohibit...
1567
  	    jump_label_text_reserved(p->addr, p->addr) ||
6333e8f73   Peter Zijlstra   static_call: Avoi...
1568
  	    static_call_text_reserved(p->addr, p->addr) ||
e336b4027   Masami Hiramatsu   kprobes: Prohibit...
1569
  	    find_bug((unsigned long)p->addr)) {
f986a499e   Prashanth Nageshappa   kprobes: return p...
1570
  		ret = -EINVAL;
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1571
  		goto out;
f986a499e   Prashanth Nageshappa   kprobes: return p...
1572
  	}
b3e55c727   Mao, Bibo   [PATCH] Kprobes: ...
1573

f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1574
1575
1576
  	/* Check if are we probing a module */
  	*probed_mod = __module_text_address((unsigned long) p->addr);
  	if (*probed_mod) {
6f716acd5   Christoph Hellwig   kprobes: codingst...
1577
  		/*
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1578
1579
  		 * We must hold a refcount of the probed module while updating
  		 * its code to prohibit unexpected unloading.
df019b1d8   Keshavamurthy Anil S   [PATCH] kprobes: ...
1580
  		 */
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1581
1582
1583
1584
  		if (unlikely(!try_module_get(*probed_mod))) {
  			ret = -ENOENT;
  			goto out;
  		}
de31c3ca8   Steven Rostedt   jump label: Fix e...
1585

f24659d96   Masami Hiramatsu   kprobes: support ...
1586
1587
1588
1589
  		/*
  		 * If the module freed .init.text, we couldn't insert
  		 * kprobes in there.
  		 */
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1590
1591
1592
1593
1594
  		if (within_module_init((unsigned long)p->addr, *probed_mod) &&
  		    (*probed_mod)->state != MODULE_STATE_COMING) {
  			module_put(*probed_mod);
  			*probed_mod = NULL;
  			ret = -ENOENT;
f24659d96   Masami Hiramatsu   kprobes: support ...
1595
  		}
df019b1d8   Keshavamurthy Anil S   [PATCH] kprobes: ...
1596
  	}
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1597
  out:
a189d0350   Masami Hiramatsu   kprobes: disable ...
1598
  	preempt_enable();
de31c3ca8   Steven Rostedt   jump label: Fix e...
1599
  	jump_label_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1600

f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1601
1602
  	return ret;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1603
  int register_kprobe(struct kprobe *p)
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
  {
  	int ret;
  	struct kprobe *old_p;
  	struct module *probed_mod;
  	kprobe_opcode_t *addr;
  
  	/* Adjust probe address from symbol */
  	addr = kprobe_addr(p);
  	if (IS_ERR(addr))
  		return PTR_ERR(addr);
  	p->addr = addr;
  
  	ret = check_kprobe_rereg(p);
  	if (ret)
  		return ret;
  
  	/* User can pass only KPROBE_FLAG_DISABLED to register_kprobe */
  	p->flags &= KPROBE_FLAG_DISABLED;
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1622
  	p->nmissed = 0;
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1623
  	INIT_LIST_HEAD(&p->list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1624

f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1625
1626
1627
1628
1629
  	ret = check_kprobe_address_safe(p, &probed_mod);
  	if (ret)
  		return ret;
  
  	mutex_lock(&kprobe_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1630

64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1631
1632
  	old_p = get_kprobe(p->addr);
  	if (old_p) {
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1633
  		/* Since this may unoptimize old_p, locking text_mutex. */
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1634
  		ret = register_aggr_kprobe(old_p, p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1635
1636
  		goto out;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1637

2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1638
1639
1640
  	cpus_read_lock();
  	/* Prevent text modification */
  	mutex_lock(&text_mutex);
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1641
  	ret = prepare_kprobe(p);
25764288d   Masami Hiramatsu   kprobes: Move loc...
1642
  	mutex_unlock(&text_mutex);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1643
  	cpus_read_unlock();
6f716acd5   Christoph Hellwig   kprobes: codingst...
1644
  	if (ret)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1645
  		goto out;
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1646

64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1647
  	INIT_HLIST_NODE(&p->hlist);
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1648
  	hlist_add_head_rcu(&p->hlist,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1649
  		       &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
12310e343   Jessica Yu   kprobes: Propagat...
1650
1651
1652
1653
  	if (!kprobes_all_disarmed && !kprobe_disabled(p)) {
  		ret = arm_kprobe(p);
  		if (ret) {
  			hlist_del_rcu(&p->hlist);
ae8b7ce76   Paul E. McKenney   kprobes: Replace ...
1654
  			synchronize_rcu();
12310e343   Jessica Yu   kprobes: Propagat...
1655
1656
1657
  			goto out;
  		}
  	}
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1658
1659
1660
  
  	/* Try to optimize kprobe */
  	try_to_optimize_kprobe(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1661
  out:
7a7d1cf95   Ingo Molnar   [PATCH] sem2mutex...
1662
  	mutex_unlock(&kprobe_mutex);
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1663

e8386a0cb   Masami Hiramatsu   kprobes: support ...
1664
  	if (probed_mod)
df019b1d8   Keshavamurthy Anil S   [PATCH] kprobes: ...
1665
  		module_put(probed_mod);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1666

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1667
1668
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1669
  EXPORT_SYMBOL_GPL(register_kprobe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1670

6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1671
  /* Check if all probes on the aggrprobe are disabled */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1672
  static int aggr_kprobe_disabled(struct kprobe *ap)
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1673
1674
  {
  	struct kprobe *kp;
7e6a71d8e   Masami Hiramatsu   kprobes: Use non ...
1675
1676
1677
  	lockdep_assert_held(&kprobe_mutex);
  
  	list_for_each_entry(kp, &ap->list, list)
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
  		if (!kprobe_disabled(kp))
  			/*
  			 * There is an active probe on the list.
  			 * We can't disable this ap.
  			 */
  			return 0;
  
  	return 1;
  }
  
  /* Disable one kprobe: Make sure called under kprobe_mutex is locked */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1689
  static struct kprobe *__disable_kprobe(struct kprobe *p)
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1690
1691
  {
  	struct kprobe *orig_p;
297f9233b   Jessica Yu   kprobes: Propagat...
1692
  	int ret;
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1693
1694
1695
1696
  
  	/* Get an original kprobe for return */
  	orig_p = __get_valid_kprobe(p);
  	if (unlikely(orig_p == NULL))
297f9233b   Jessica Yu   kprobes: Propagat...
1697
  		return ERR_PTR(-EINVAL);
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1698
1699
1700
1701
1702
1703
1704
1705
  
  	if (!kprobe_disabled(p)) {
  		/* Disable probe if it is a child probe */
  		if (p != orig_p)
  			p->flags |= KPROBE_FLAG_DISABLED;
  
  		/* Try to disarm and disable this/parent probe */
  		if (p == orig_p || aggr_kprobe_disabled(orig_p)) {
69d54b916   Wang Nan   kprobes: makes kp...
1706
1707
1708
1709
1710
  			/*
  			 * If kprobes_all_disarmed is set, orig_p
  			 * should have already been disarmed, so
  			 * skip unneed disarming process.
  			 */
297f9233b   Jessica Yu   kprobes: Propagat...
1711
1712
1713
1714
1715
1716
1717
  			if (!kprobes_all_disarmed) {
  				ret = disarm_kprobe(orig_p, true);
  				if (ret) {
  					p->flags &= ~KPROBE_FLAG_DISABLED;
  					return ERR_PTR(ret);
  				}
  			}
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1718
1719
1720
1721
1722
1723
  			orig_p->flags |= KPROBE_FLAG_DISABLED;
  		}
  	}
  
  	return orig_p;
  }
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1724
1725
1726
  /*
   * Unregister a kprobe without a scheduler synchronization.
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1727
  static int __unregister_kprobe_top(struct kprobe *p)
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1728
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1729
  	struct kprobe *ap, *list_p;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1730

6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1731
1732
  	/* Disable kprobe. This will disarm it if needed. */
  	ap = __disable_kprobe(p);
297f9233b   Jessica Yu   kprobes: Propagat...
1733
1734
  	if (IS_ERR(ap))
  		return PTR_ERR(ap);
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1735

6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1736
  	if (ap == p)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
1737
  		/*
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1738
1739
  		 * This probe is an independent(and non-optimized) kprobe
  		 * (not an aggrprobe). Remove from the hash list.
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
1740
  		 */
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1741
1742
1743
1744
  		goto disarmed;
  
  	/* Following process expects this probe is an aggrprobe */
  	WARN_ON(!kprobe_aggrprobe(ap));
6274de498   Masami Hiramatsu   kprobes: Support ...
1745
1746
1747
1748
1749
  	if (list_is_singular(&ap->list) && kprobe_disarmed(ap))
  		/*
  		 * !disarmed could be happen if the probe is under delayed
  		 * unoptimizing.
  		 */
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1750
1751
1752
  		goto disarmed;
  	else {
  		/* If disabling probe has special handlers, update aggrprobe */
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1753
  		if (p->post_handler && !kprobe_gone(p)) {
7e6a71d8e   Masami Hiramatsu   kprobes: Use non ...
1754
  			list_for_each_entry(list_p, &ap->list, list) {
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1755
1756
1757
  				if ((list_p != p) && (list_p->post_handler))
  					goto noclean;
  			}
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1758
  			ap->post_handler = NULL;
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1759
1760
  		}
  noclean:
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1761
1762
1763
1764
  		/*
  		 * Remove from the aggrprobe: this path will do nothing in
  		 * __unregister_kprobe_bottom().
  		 */
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1765
  		list_del_rcu(&p->list);
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1766
1767
1768
1769
1770
1771
  		if (!kprobe_disabled(ap) && !kprobes_all_disarmed)
  			/*
  			 * Try to optimize this probe again, because post
  			 * handler may have been changed.
  			 */
  			optimize_kprobe(ap);
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1772
  	}
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1773
  	return 0;
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1774
1775
1776
1777
  
  disarmed:
  	hlist_del_rcu(&ap->hlist);
  	return 0;
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1778
  }
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1779

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1780
  static void __unregister_kprobe_bottom(struct kprobe *p)
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1781
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1782
  	struct kprobe *ap;
b3e55c727   Mao, Bibo   [PATCH] Kprobes: ...
1783

e8386a0cb   Masami Hiramatsu   kprobes: support ...
1784
  	if (list_empty(&p->list))
6274de498   Masami Hiramatsu   kprobes: Support ...
1785
  		/* This is an independent kprobe */
0498b6350   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1786
  		arch_remove_kprobe(p);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1787
  	else if (list_is_singular(&p->list)) {
6274de498   Masami Hiramatsu   kprobes: Support ...
1788
  		/* This is the last child of an aggrprobe */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1789
  		ap = list_entry(p->list.next, struct kprobe, list);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1790
  		list_del(&p->list);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1791
  		free_aggr_kprobe(ap);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1792
  	}
6274de498   Masami Hiramatsu   kprobes: Support ...
1793
  	/* Otherwise, do nothing. */
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1794
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1795
  int register_kprobes(struct kprobe **kps, int num)
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1796
1797
1798
1799
1800
1801
  {
  	int i, ret = 0;
  
  	if (num <= 0)
  		return -EINVAL;
  	for (i = 0; i < num; i++) {
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1802
  		ret = register_kprobe(kps[i]);
67dddaad5   Masami Hiramatsu   kprobes: fix erro...
1803
1804
1805
  		if (ret < 0) {
  			if (i > 0)
  				unregister_kprobes(kps, i);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1806
  			break;
367216567   mao, bibo   [PATCH] Kprobe: m...
1807
  		}
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1808
  	}
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1809
1810
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1811
  EXPORT_SYMBOL_GPL(register_kprobes);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1812

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1813
  void unregister_kprobe(struct kprobe *p)
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1814
1815
1816
  {
  	unregister_kprobes(&p, 1);
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1817
  EXPORT_SYMBOL_GPL(unregister_kprobe);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1818

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1819
  void unregister_kprobes(struct kprobe **kps, int num)
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
  {
  	int i;
  
  	if (num <= 0)
  		return;
  	mutex_lock(&kprobe_mutex);
  	for (i = 0; i < num; i++)
  		if (__unregister_kprobe_top(kps[i]) < 0)
  			kps[i]->addr = NULL;
  	mutex_unlock(&kprobe_mutex);
ae8b7ce76   Paul E. McKenney   kprobes: Replace ...
1830
  	synchronize_rcu();
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1831
1832
1833
  	for (i = 0; i < num; i++)
  		if (kps[i]->addr)
  			__unregister_kprobe_bottom(kps[i]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1834
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1835
  EXPORT_SYMBOL_GPL(unregister_kprobes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1836

5f6bee347   Naveen N. Rao   kprobes: Convert ...
1837
1838
  int __weak kprobe_exceptions_notify(struct notifier_block *self,
  					unsigned long val, void *data)
fc62d0207   Naveen N. Rao   kprobes: Introduc...
1839
1840
1841
  {
  	return NOTIFY_DONE;
  }
5f6bee347   Naveen N. Rao   kprobes: Convert ...
1842
  NOKPROBE_SYMBOL(kprobe_exceptions_notify);
fc62d0207   Naveen N. Rao   kprobes: Introduc...
1843

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1844
1845
  static struct notifier_block kprobe_exceptions_nb = {
  	.notifier_call = kprobe_exceptions_notify,
3d5631e06   Anil S Keshavamurthy   [PATCH] Kprobes r...
1846
1847
  	.priority = 0x7fffffff /* we need to be notified first */
  };
3d7e33825   Michael Ellerman   jprobes: make jpr...
1848
1849
1850
1851
  unsigned long __weak arch_deref_entry_point(void *entry)
  {
  	return (unsigned long)entry;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1852

9edddaa20   Ananth N Mavinakayanahalli   Kprobes: indicate...
1853
  #ifdef CONFIG_KRETPROBES
66ada2cca   Masami Hiramatsu   kprobes: Add gene...
1854
1855
1856
1857
1858
1859
  
  unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs,
  					     void *trampoline_address,
  					     void *frame_pointer)
  {
  	struct kretprobe_instance *ri = NULL, *last = NULL;
b33881780   Masami Hiramatsu   kprobes: Free kre...
1860
  	struct hlist_head *head;
66ada2cca   Masami Hiramatsu   kprobes: Add gene...
1861
1862
1863
1864
  	struct hlist_node *tmp;
  	unsigned long flags;
  	kprobe_opcode_t *correct_ret_addr = NULL;
  	bool skipped = false;
66ada2cca   Masami Hiramatsu   kprobes: Add gene...
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
  	kretprobe_hash_lock(current, &head, &flags);
  
  	/*
  	 * It is possible to have multiple instances associated with a given
  	 * task either because multiple functions in the call path have
  	 * return probes installed on them, and/or more than one
  	 * return probe was registered for a target function.
  	 *
  	 * We can handle this because:
  	 *     - instances are always pushed into the head of the list
  	 *     - when multiple return probes are registered for the same
  	 *	 function, the (chronologically) first instance's ret_addr
  	 *	 will be the real return address, and all the rest will
  	 *	 point to kretprobe_trampoline.
  	 */
  	hlist_for_each_entry(ri, head, hlist) {
  		if (ri->task != current)
  			/* another task is sharing our hash bucket */
  			continue;
  		/*
  		 * Return probes must be pushed on this hash list correct
  		 * order (same as return order) so that it can be popped
  		 * correctly. However, if we find it is pushed it incorrect
  		 * order, this means we find a function which should not be
  		 * probed, because the wrong order entry is pushed on the
  		 * path of processing other kretprobe itself.
  		 */
  		if (ri->fp != frame_pointer) {
  			if (!skipped)
  				pr_warn("kretprobe is stacked incorrectly. Trying to fixup.
  ");
  			skipped = true;
  			continue;
  		}
  
  		correct_ret_addr = ri->ret_addr;
  		if (skipped)
  			pr_warn("%ps must be blacklisted because of incorrect kretprobe order
  ",
  				ri->rp->kp.addr);
  
  		if (correct_ret_addr != trampoline_address)
  			/*
  			 * This is the real return address. Any other
  			 * instances associated with this task are for
  			 * other calls deeper on the call stack
  			 */
  			break;
  	}
319f0ce28   Masami Hiramatsu   kprobes: Make loc...
1914
  	BUG_ON(!correct_ret_addr || (correct_ret_addr == trampoline_address));
66ada2cca   Masami Hiramatsu   kprobes: Add gene...
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
  	last = ri;
  
  	hlist_for_each_entry_safe(ri, tmp, head, hlist) {
  		if (ri->task != current)
  			/* another task is sharing our hash bucket */
  			continue;
  		if (ri->fp != frame_pointer)
  			continue;
  
  		if (ri->rp && ri->rp->handler) {
  			struct kprobe *prev = kprobe_running();
  
  			__this_cpu_write(current_kprobe, &ri->rp->kp);
  			ri->ret_addr = correct_ret_addr;
  			ri->rp->handler(ri, regs);
  			__this_cpu_write(current_kprobe, prev);
  		}
b33881780   Masami Hiramatsu   kprobes: Free kre...
1932
  		recycle_rp_inst(ri);
66ada2cca   Masami Hiramatsu   kprobes: Add gene...
1933
1934
1935
1936
1937
1938
  
  		if (ri == last)
  			break;
  	}
  
  	kretprobe_hash_unlock(current, &flags);
66ada2cca   Masami Hiramatsu   kprobes: Add gene...
1939
1940
1941
  	return (unsigned long)correct_ret_addr;
  }
  NOKPROBE_SYMBOL(__kretprobe_trampoline_handler)
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1942
1943
1944
1945
  /*
   * This kprobe pre_handler is registered with every kretprobe. When probe
   * hits it will set up the return probe.
   */
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1946
  static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1947
1948
  {
  	struct kretprobe *rp = container_of(p, struct kretprobe, kp);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1949
1950
  	unsigned long hash, flags = 0;
  	struct kretprobe_instance *ri;
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1951

f96f56780   Masami Hiramatsu   kprobes: Skip kre...
1952
  	/* TODO: consider to only swap the RA after the last pre_handler fired */
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1953
  	hash = hash_ptr(current, KPROBE_HASH_BITS);
645f224e7   Steven Rostedt (VMware)   kprobes: Tell loc...
1954
1955
1956
1957
1958
1959
  	/*
  	 * Nested is a workaround that will soon not be needed.
  	 * There's other protections that make sure the same lock
  	 * is not taken on the same CPU that lockdep is unaware of.
  	 */
  	raw_spin_lock_irqsave_nested(&rp->lock, flags, 1);
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1960
  	if (!hlist_empty(&rp->free_instances)) {
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1961
  		ri = hlist_entry(rp->free_instances.first,
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1962
1963
  				struct kretprobe_instance, hlist);
  		hlist_del(&ri->hlist);
ec484608c   Thomas Gleixner   locking, kprobes:...
1964
  		raw_spin_unlock_irqrestore(&rp->lock, flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1965

4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1966
1967
  		ri->rp = rp;
  		ri->task = current;
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1968

55ca6140e   Jiang Liu   kprobes: fix a me...
1969
  		if (rp->entry_handler && rp->entry_handler(ri, regs)) {
645f224e7   Steven Rostedt (VMware)   kprobes: Tell loc...
1970
  			raw_spin_lock_irqsave_nested(&rp->lock, flags, 1);
55ca6140e   Jiang Liu   kprobes: fix a me...
1971
1972
  			hlist_add_head(&ri->hlist, &rp->free_instances);
  			raw_spin_unlock_irqrestore(&rp->lock, flags);
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1973
  			return 0;
55ca6140e   Jiang Liu   kprobes: fix a me...
1974
  		}
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1975

4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1976
1977
1978
  		arch_prepare_kretprobe(ri, regs);
  
  		/* XXX(hch): why is there no hlist_move_head? */
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1979
1980
1981
1982
1983
  		INIT_HLIST_NODE(&ri->hlist);
  		kretprobe_table_lock(hash, &flags);
  		hlist_add_head(&ri->hlist, &kretprobe_inst_table[hash]);
  		kretprobe_table_unlock(hash, &flags);
  	} else {
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1984
  		rp->nmissed++;
ec484608c   Thomas Gleixner   locking, kprobes:...
1985
  		raw_spin_unlock_irqrestore(&rp->lock, flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1986
  	}
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1987
1988
  	return 0;
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1989
  NOKPROBE_SYMBOL(pre_handler_kretprobe);
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1990

659b957f2   Naveen N. Rao   kprobes: Rename [...
1991
  bool __weak arch_kprobe_on_func_entry(unsigned long offset)
90ec5e89e   Naveen N. Rao   kretprobes: Ensur...
1992
1993
1994
  {
  	return !offset;
  }
659b957f2   Naveen N. Rao   kprobes: Rename [...
1995
  bool kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset)
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1996
1997
1998
1999
2000
2001
2002
  {
  	kprobe_opcode_t *kp_addr = _kprobe_addr(addr, sym, offset);
  
  	if (IS_ERR(kp_addr))
  		return false;
  
  	if (!kallsyms_lookup_size_offset((unsigned long)kp_addr, NULL, &offset) ||
659b957f2   Naveen N. Rao   kprobes: Rename [...
2003
  						!arch_kprobe_on_func_entry(offset))
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
2004
2005
2006
2007
  		return false;
  
  	return true;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2008
  int register_kretprobe(struct kretprobe *rp)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2009
2010
2011
2012
  {
  	int ret = 0;
  	struct kretprobe_instance *inst;
  	int i;
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
2013
  	void *addr;
90ec5e89e   Naveen N. Rao   kretprobes: Ensur...
2014

659b957f2   Naveen N. Rao   kprobes: Rename [...
2015
  	if (!kprobe_on_func_entry(rp->kp.addr, rp->kp.symbol_name, rp->kp.offset))
90ec5e89e   Naveen N. Rao   kretprobes: Ensur...
2016
  		return -EINVAL;
f438d914b   Masami Hiramatsu   kprobes: support ...
2017
2018
  
  	if (kretprobe_blacklist_size) {
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
2019
  		addr = kprobe_addr(&rp->kp);
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
2020
2021
  		if (IS_ERR(addr))
  			return PTR_ERR(addr);
f438d914b   Masami Hiramatsu   kprobes: support ...
2022
2023
2024
2025
2026
2027
  
  		for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
  			if (kretprobe_blacklist[i].addr == addr)
  				return -EINVAL;
  		}
  	}
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2028
2029
  
  	rp->kp.pre_handler = pre_handler_kretprobe;
7522a8423   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
2030
2031
  	rp->kp.post_handler = NULL;
  	rp->kp.fault_handler = NULL;
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2032
2033
2034
  
  	/* Pre-allocate memory for max kretprobe instances */
  	if (rp->maxactive <= 0) {
926166063   Thomas Gleixner   kprobes: Use CONF...
2035
  #ifdef CONFIG_PREEMPTION
c2ef6661c   Heiko Carstens   kprobes: Fix dist...
2036
  		rp->maxactive = max_t(unsigned int, 10, 2*num_possible_cpus());
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2037
  #else
4dae560f9   Ananth N Mavinakayanahalli   kprobes: Sanitize...
2038
  		rp->maxactive = num_possible_cpus();
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2039
2040
  #endif
  	}
ec484608c   Thomas Gleixner   locking, kprobes:...
2041
  	raw_spin_lock_init(&rp->lock);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2042
2043
  	INIT_HLIST_HEAD(&rp->free_instances);
  	for (i = 0; i < rp->maxactive; i++) {
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
2044
2045
  		inst = kmalloc(sizeof(struct kretprobe_instance) +
  			       rp->data_size, GFP_KERNEL);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2046
2047
2048
2049
  		if (inst == NULL) {
  			free_rp_inst(rp);
  			return -ENOMEM;
  		}
ef53d9c5e   Srinivasa D S   kprobes: improve ...
2050
2051
  		INIT_HLIST_NODE(&inst->hlist);
  		hlist_add_head(&inst->hlist, &rp->free_instances);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2052
2053
2054
2055
  	}
  
  	rp->nmissed = 0;
  	/* Establish function entry probe point */
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
2056
  	ret = register_kprobe(&rp->kp);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
2057
  	if (ret != 0)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2058
2059
2060
  		free_rp_inst(rp);
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
2061
  EXPORT_SYMBOL_GPL(register_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2062

55479f647   Masami Hiramatsu   kprobes: Allow pr...
2063
  int register_kretprobes(struct kretprobe **rps, int num)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
2064
2065
2066
2067
2068
2069
  {
  	int ret = 0, i;
  
  	if (num <= 0)
  		return -EINVAL;
  	for (i = 0; i < num; i++) {
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
2070
  		ret = register_kretprobe(rps[i]);
67dddaad5   Masami Hiramatsu   kprobes: fix erro...
2071
2072
2073
  		if (ret < 0) {
  			if (i > 0)
  				unregister_kretprobes(rps, i);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
2074
2075
2076
2077
2078
  			break;
  		}
  	}
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
2079
  EXPORT_SYMBOL_GPL(register_kretprobes);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
2080

55479f647   Masami Hiramatsu   kprobes: Allow pr...
2081
  void unregister_kretprobe(struct kretprobe *rp)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
2082
2083
2084
  {
  	unregister_kretprobes(&rp, 1);
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
2085
  EXPORT_SYMBOL_GPL(unregister_kretprobe);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
2086

55479f647   Masami Hiramatsu   kprobes: Allow pr...
2087
  void unregister_kretprobes(struct kretprobe **rps, int num)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
  {
  	int i;
  
  	if (num <= 0)
  		return;
  	mutex_lock(&kprobe_mutex);
  	for (i = 0; i < num; i++)
  		if (__unregister_kprobe_top(&rps[i]->kp) < 0)
  			rps[i]->kp.addr = NULL;
  	mutex_unlock(&kprobe_mutex);
ae8b7ce76   Paul E. McKenney   kprobes: Replace ...
2098
  	synchronize_rcu();
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
2099
2100
2101
2102
2103
2104
2105
  	for (i = 0; i < num; i++) {
  		if (rps[i]->kp.addr) {
  			__unregister_kprobe_bottom(&rps[i]->kp);
  			cleanup_rp_inst(rps[i]);
  		}
  	}
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
2106
  EXPORT_SYMBOL_GPL(unregister_kretprobes);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
2107

9edddaa20   Ananth N Mavinakayanahalli   Kprobes: indicate...
2108
  #else /* CONFIG_KRETPROBES */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2109
  int register_kretprobe(struct kretprobe *rp)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2110
2111
2112
  {
  	return -ENOSYS;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
2113
  EXPORT_SYMBOL_GPL(register_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2114

55479f647   Masami Hiramatsu   kprobes: Allow pr...
2115
  int register_kretprobes(struct kretprobe **rps, int num)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2116
  {
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
2117
  	return -ENOSYS;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2118
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
2119
  EXPORT_SYMBOL_GPL(register_kretprobes);
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2120
  void unregister_kretprobe(struct kretprobe *rp)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2121
  {
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
2122
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
2123
  EXPORT_SYMBOL_GPL(unregister_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2124

55479f647   Masami Hiramatsu   kprobes: Allow pr...
2125
  void unregister_kretprobes(struct kretprobe **rps, int num)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
2126
2127
  {
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
2128
  EXPORT_SYMBOL_GPL(unregister_kretprobes);
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
2129

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
2130
  static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
2131
2132
  {
  	return 0;
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2133
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
2134
  NOKPROBE_SYMBOL(pre_handler_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2135

4a296e07c   Masami Hiramatsu   kprobes: add (un)...
2136
  #endif /* CONFIG_KRETPROBES */
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2137
  /* Set the kprobe gone and remove its instruction buffer. */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2138
  static void kill_kprobe(struct kprobe *p)
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2139
2140
  {
  	struct kprobe *kp;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
2141

7e6a71d8e   Masami Hiramatsu   kprobes: Use non ...
2142
  	lockdep_assert_held(&kprobe_mutex);
b0399092c   Muchun Song   kprobes: fix kill...
2143
2144
  	if (WARN_ON_ONCE(kprobe_gone(p)))
  		return;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2145
  	p->flags |= KPROBE_FLAG_GONE;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2146
  	if (kprobe_aggrprobe(p)) {
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2147
2148
2149
2150
  		/*
  		 * If this is an aggr_kprobe, we have to list all the
  		 * chained probes and mark them GONE.
  		 */
7e6a71d8e   Masami Hiramatsu   kprobes: Use non ...
2151
  		list_for_each_entry(kp, &p->list, list)
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2152
2153
  			kp->flags |= KPROBE_FLAG_GONE;
  		p->post_handler = NULL;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2154
  		kill_optimized_kprobe(p);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2155
2156
2157
2158
2159
2160
  	}
  	/*
  	 * Here, we can remove insn_slot safely, because no thread calls
  	 * the original probed function (which will be freed soon) any more.
  	 */
  	arch_remove_kprobe(p);
0cb2f1372   Muchun Song   kprobes: Fix NULL...
2161
2162
2163
  
  	/*
  	 * The module is going away. We should disarm the kprobe which
3031313eb   Masami Hiramatsu   kprobes: Fix to c...
2164
2165
  	 * is using ftrace, because ftrace framework is still available at
  	 * MODULE_STATE_GOING notification.
0cb2f1372   Muchun Song   kprobes: Fix NULL...
2166
  	 */
3031313eb   Masami Hiramatsu   kprobes: Fix to c...
2167
  	if (kprobe_ftrace(p) && !kprobe_disabled(p) && !kprobes_all_disarmed)
0cb2f1372   Muchun Song   kprobes: Fix NULL...
2168
  		disarm_kprobe_ftrace(p);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2169
  }
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2170
  /* Disable one kprobe */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2171
  int disable_kprobe(struct kprobe *kp)
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2172
2173
  {
  	int ret = 0;
297f9233b   Jessica Yu   kprobes: Propagat...
2174
  	struct kprobe *p;
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2175
2176
  
  	mutex_lock(&kprobe_mutex);
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
2177
  	/* Disable this kprobe */
297f9233b   Jessica Yu   kprobes: Propagat...
2178
2179
2180
  	p = __disable_kprobe(kp);
  	if (IS_ERR(p))
  		ret = PTR_ERR(p);
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2181

c0614829c   Masami Hiramatsu   kprobes: Move ena...
2182
2183
2184
2185
2186
2187
  	mutex_unlock(&kprobe_mutex);
  	return ret;
  }
  EXPORT_SYMBOL_GPL(disable_kprobe);
  
  /* Enable one kprobe */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2188
  int enable_kprobe(struct kprobe *kp)
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
  {
  	int ret = 0;
  	struct kprobe *p;
  
  	mutex_lock(&kprobe_mutex);
  
  	/* Check whether specified probe is valid. */
  	p = __get_valid_kprobe(kp);
  	if (unlikely(p == NULL)) {
  		ret = -EINVAL;
  		goto out;
  	}
  
  	if (kprobe_gone(kp)) {
  		/* This kprobe has gone, we couldn't enable it. */
  		ret = -EINVAL;
  		goto out;
  	}
  
  	if (p != kp)
  		kp->flags &= ~KPROBE_FLAG_DISABLED;
  
  	if (!kprobes_all_disarmed && kprobe_disabled(p)) {
  		p->flags &= ~KPROBE_FLAG_DISABLED;
12310e343   Jessica Yu   kprobes: Propagat...
2213
2214
2215
  		ret = arm_kprobe(p);
  		if (ret)
  			p->flags |= KPROBE_FLAG_DISABLED;
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2216
2217
2218
2219
2220
2221
  	}
  out:
  	mutex_unlock(&kprobe_mutex);
  	return ret;
  }
  EXPORT_SYMBOL_GPL(enable_kprobe);
4458515b2   Masami Hiramatsu   kprobes: Replace ...
2222
  /* Caller must NOT call this in usual path. This is only for critical case */
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
2223
  void dump_kprobe(struct kprobe *kp)
24851d244   Frederic Weisbecker   tracing/kprobes: ...
2224
  {
4458515b2   Masami Hiramatsu   kprobes: Replace ...
2225
2226
2227
2228
2229
2230
2231
  	pr_err("Dumping kprobe:
  ");
  	pr_err("Name: %s
  Offset: %x
  Address: %pS
  ",
  	       kp->symbol_name, kp->offset, kp->addr);
24851d244   Frederic Weisbecker   tracing/kprobes: ...
2232
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
2233
  NOKPROBE_SYMBOL(dump_kprobe);
24851d244   Frederic Weisbecker   tracing/kprobes: ...
2234

fb1a59fae   Masami Hiramatsu   kprobes: Blacklis...
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
  int kprobe_add_ksym_blacklist(unsigned long entry)
  {
  	struct kprobe_blacklist_entry *ent;
  	unsigned long offset = 0, size = 0;
  
  	if (!kernel_text_address(entry) ||
  	    !kallsyms_lookup_size_offset(entry, &size, &offset))
  		return -EINVAL;
  
  	ent = kmalloc(sizeof(*ent), GFP_KERNEL);
  	if (!ent)
  		return -ENOMEM;
  	ent->start_addr = entry;
  	ent->end_addr = entry + size;
  	INIT_LIST_HEAD(&ent->list);
  	list_add_tail(&ent->list, &kprobe_blacklist);
  
  	return (int)size;
  }
  
  /* Add all symbols in given area into kprobe blacklist */
  int kprobe_add_area_blacklist(unsigned long start, unsigned long end)
  {
  	unsigned long entry;
  	int ret = 0;
  
  	for (entry = start; entry < end; entry += ret) {
  		ret = kprobe_add_ksym_blacklist(entry);
  		if (ret < 0)
  			return ret;
  		if (ret == 0)	/* In case of alias symbol */
  			ret = 1;
  	}
  	return 0;
  }
1e6769b0a   Masami Hiramatsu   kprobes: Support ...
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
  /* Remove all symbols in given area from kprobe blacklist */
  static void kprobe_remove_area_blacklist(unsigned long start, unsigned long end)
  {
  	struct kprobe_blacklist_entry *ent, *n;
  
  	list_for_each_entry_safe(ent, n, &kprobe_blacklist, list) {
  		if (ent->start_addr < start || ent->start_addr >= end)
  			continue;
  		list_del(&ent->list);
  		kfree(ent);
  	}
  }
16db6264c   Masami Hiramatsu   kprobes: Support ...
2282
2283
2284
2285
  static void kprobe_remove_ksym_blacklist(unsigned long entry)
  {
  	kprobe_remove_area_blacklist(entry, entry + 1);
  }
d002b8bc6   Adrian Hunter   kprobes: Add symb...
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
  int __weak arch_kprobe_get_kallsym(unsigned int *symnum, unsigned long *value,
  				   char *type, char *sym)
  {
  	return -ERANGE;
  }
  
  int kprobe_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
  		       char *sym)
  {
  #ifdef __ARCH_WANT_KPROBES_INSN_SLOT
  	if (!kprobe_cache_get_kallsym(&kprobe_insn_slots, &symnum, value, type, sym))
  		return 0;
  #ifdef CONFIG_OPTPROBES
  	if (!kprobe_cache_get_kallsym(&kprobe_optinsn_slots, &symnum, value, type, sym))
  		return 0;
  #endif
  #endif
  	if (!arch_kprobe_get_kallsym(&symnum, value, type, sym))
  		return 0;
  	return -ERANGE;
  }
fb1a59fae   Masami Hiramatsu   kprobes: Blacklis...
2307
2308
2309
2310
  int __init __weak arch_populate_kprobe_blacklist(void)
  {
  	return 0;
  }
376e24242   Masami Hiramatsu   kprobes: Introduc...
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
  /*
   * Lookup and populate the kprobe_blacklist.
   *
   * Unlike the kretprobe blacklist, we'll need to determine
   * the range of addresses that belong to the said functions,
   * since a kprobe need not necessarily be at the beginning
   * of a function.
   */
  static int __init populate_kprobe_blacklist(unsigned long *start,
  					     unsigned long *end)
  {
fb1a59fae   Masami Hiramatsu   kprobes: Blacklis...
2322
  	unsigned long entry;
376e24242   Masami Hiramatsu   kprobes: Introduc...
2323
  	unsigned long *iter;
fb1a59fae   Masami Hiramatsu   kprobes: Blacklis...
2324
  	int ret;
376e24242   Masami Hiramatsu   kprobes: Introduc...
2325
2326
  
  	for (iter = start; iter < end; iter++) {
d81b4253b   Masami Hiramatsu   kprobes: Fix "Fai...
2327
  		entry = arch_deref_entry_point((void *)*iter);
fb1a59fae   Masami Hiramatsu   kprobes: Blacklis...
2328
2329
  		ret = kprobe_add_ksym_blacklist(entry);
  		if (ret == -EINVAL)
376e24242   Masami Hiramatsu   kprobes: Introduc...
2330
  			continue;
fb1a59fae   Masami Hiramatsu   kprobes: Blacklis...
2331
2332
  		if (ret < 0)
  			return ret;
376e24242   Masami Hiramatsu   kprobes: Introduc...
2333
  	}
fb1a59fae   Masami Hiramatsu   kprobes: Blacklis...
2334
2335
2336
2337
  
  	/* Symbols in __kprobes_text are blacklisted */
  	ret = kprobe_add_area_blacklist((unsigned long)__kprobes_text_start,
  					(unsigned long)__kprobes_text_end);
66e9b0717   Thomas Gleixner   kprobes: Prevent ...
2338
2339
2340
2341
2342
2343
  	if (ret)
  		return ret;
  
  	/* Symbols in noinstr section are blacklisted */
  	ret = kprobe_add_area_blacklist((unsigned long)__noinstr_text_start,
  					(unsigned long)__noinstr_text_end);
fb1a59fae   Masami Hiramatsu   kprobes: Blacklis...
2344
2345
  
  	return ret ? : arch_populate_kprobe_blacklist();
376e24242   Masami Hiramatsu   kprobes: Introduc...
2346
  }
1e6769b0a   Masami Hiramatsu   kprobes: Support ...
2347
2348
2349
  static void add_module_kprobe_blacklist(struct module *mod)
  {
  	unsigned long start, end;
16db6264c   Masami Hiramatsu   kprobes: Support ...
2350
2351
2352
2353
2354
2355
  	int i;
  
  	if (mod->kprobe_blacklist) {
  		for (i = 0; i < mod->num_kprobe_blacklist; i++)
  			kprobe_add_ksym_blacklist(mod->kprobe_blacklist[i]);
  	}
1e6769b0a   Masami Hiramatsu   kprobes: Support ...
2356
2357
2358
2359
2360
2361
  
  	start = (unsigned long)mod->kprobes_text_start;
  	if (start) {
  		end = start + mod->kprobes_text_size;
  		kprobe_add_area_blacklist(start, end);
  	}
66e9b0717   Thomas Gleixner   kprobes: Prevent ...
2362
2363
2364
2365
2366
2367
  
  	start = (unsigned long)mod->noinstr_text_start;
  	if (start) {
  		end = start + mod->noinstr_text_size;
  		kprobe_add_area_blacklist(start, end);
  	}
1e6769b0a   Masami Hiramatsu   kprobes: Support ...
2368
2369
2370
2371
2372
  }
  
  static void remove_module_kprobe_blacklist(struct module *mod)
  {
  	unsigned long start, end;
16db6264c   Masami Hiramatsu   kprobes: Support ...
2373
2374
2375
2376
2377
2378
  	int i;
  
  	if (mod->kprobe_blacklist) {
  		for (i = 0; i < mod->num_kprobe_blacklist; i++)
  			kprobe_remove_ksym_blacklist(mod->kprobe_blacklist[i]);
  	}
1e6769b0a   Masami Hiramatsu   kprobes: Support ...
2379
2380
2381
2382
2383
2384
  
  	start = (unsigned long)mod->kprobes_text_start;
  	if (start) {
  		end = start + mod->kprobes_text_size;
  		kprobe_remove_area_blacklist(start, end);
  	}
66e9b0717   Thomas Gleixner   kprobes: Prevent ...
2385
2386
2387
2388
2389
2390
  
  	start = (unsigned long)mod->noinstr_text_start;
  	if (start) {
  		end = start + mod->noinstr_text_size;
  		kprobe_remove_area_blacklist(start, end);
  	}
1e6769b0a   Masami Hiramatsu   kprobes: Support ...
2391
  }
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2392
  /* Module notifier call back, checking kprobes on the module */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2393
2394
  static int kprobes_module_callback(struct notifier_block *nb,
  				   unsigned long val, void *data)
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2395
2396
2397
  {
  	struct module *mod = data;
  	struct hlist_head *head;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2398
2399
  	struct kprobe *p;
  	unsigned int i;
f24659d96   Masami Hiramatsu   kprobes: support ...
2400
  	int checkcore = (val == MODULE_STATE_GOING);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2401

1e6769b0a   Masami Hiramatsu   kprobes: Support ...
2402
2403
2404
2405
2406
  	if (val == MODULE_STATE_COMING) {
  		mutex_lock(&kprobe_mutex);
  		add_module_kprobe_blacklist(mod);
  		mutex_unlock(&kprobe_mutex);
  	}
f24659d96   Masami Hiramatsu   kprobes: support ...
2407
  	if (val != MODULE_STATE_GOING && val != MODULE_STATE_LIVE)
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2408
2409
2410
  		return NOTIFY_DONE;
  
  	/*
f24659d96   Masami Hiramatsu   kprobes: support ...
2411
2412
2413
2414
  	 * When MODULE_STATE_GOING was notified, both of module .text and
  	 * .init.text sections would be freed. When MODULE_STATE_LIVE was
  	 * notified, only .init.text section would be freed. We need to
  	 * disable kprobes which have been inserted in the sections.
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2415
2416
2417
2418
  	 */
  	mutex_lock(&kprobe_mutex);
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
b0399092c   Muchun Song   kprobes: fix kill...
2419
2420
2421
  		hlist_for_each_entry(p, head, hlist) {
  			if (kprobe_gone(p))
  				continue;
f24659d96   Masami Hiramatsu   kprobes: support ...
2422
2423
2424
  			if (within_module_init((unsigned long)p->addr, mod) ||
  			    (checkcore &&
  			     within_module_core((unsigned long)p->addr, mod))) {
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2425
2426
2427
2428
  				/*
  				 * The vaddr this probe is installed will soon
  				 * be vfreed buy not synced to disk. Hence,
  				 * disarming the breakpoint isn't needed.
545a02819   Steven Rostedt (VMware)   kprobes: Document...
2429
2430
2431
2432
2433
2434
  				 *
  				 * Note, this will also move any optimized probes
  				 * that are pending to be removed from their
  				 * corresponding lists to the freeing_list and
  				 * will not be touched by the delayed
  				 * kprobe_optimizer work handler.
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2435
2436
2437
  				 */
  				kill_kprobe(p);
  			}
b0399092c   Muchun Song   kprobes: fix kill...
2438
  		}
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2439
  	}
1e6769b0a   Masami Hiramatsu   kprobes: Support ...
2440
2441
  	if (val == MODULE_STATE_GOING)
  		remove_module_kprobe_blacklist(mod);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2442
2443
2444
2445
2446
2447
2448
2449
  	mutex_unlock(&kprobe_mutex);
  	return NOTIFY_DONE;
  }
  
  static struct notifier_block kprobe_module_nb = {
  	.notifier_call = kprobes_module_callback,
  	.priority = 0
  };
376e24242   Masami Hiramatsu   kprobes: Introduc...
2450
2451
2452
  /* Markers of _kprobe_blacklist section */
  extern unsigned long __start_kprobe_blacklist[];
  extern unsigned long __stop_kprobe_blacklist[];
82d083ab6   Masami Hiramatsu   kprobes: tracing/...
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
  void kprobe_free_init_mem(void)
  {
  	void *start = (void *)(&__init_begin);
  	void *end = (void *)(&__init_end);
  	struct hlist_head *head;
  	struct kprobe *p;
  	int i;
  
  	mutex_lock(&kprobe_mutex);
  
  	/* Kill all kprobes on initmem */
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
  		hlist_for_each_entry(p, head, hlist) {
  			if (start <= (void *)p->addr && (void *)p->addr < end)
  				kill_kprobe(p);
  		}
  	}
  
  	mutex_unlock(&kprobe_mutex);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2474
2475
2476
2477
2478
2479
  static int __init init_kprobes(void)
  {
  	int i, err = 0;
  
  	/* FIXME allocate the probe table, currently defined statically */
  	/* initialize all list heads */
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2480
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2481
  		INIT_HLIST_HEAD(&kprobe_table[i]);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2482
  		INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
ec484608c   Thomas Gleixner   locking, kprobes:...
2483
  		raw_spin_lock_init(&(kretprobe_table_locks[i].lock));
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2484
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2485

376e24242   Masami Hiramatsu   kprobes: Introduc...
2486
2487
2488
2489
2490
2491
2492
  	err = populate_kprobe_blacklist(__start_kprobe_blacklist,
  					__stop_kprobe_blacklist);
  	if (err) {
  		pr_err("kprobes: failed to populate blacklist: %d
  ", err);
  		pr_err("Please take care of using kprobes.
  ");
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
2493
  	}
f438d914b   Masami Hiramatsu   kprobes: support ...
2494
2495
2496
  	if (kretprobe_blacklist_size) {
  		/* lookup the function address from its name */
  		for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
49e0b4658   Naveen N. Rao   kprobes: Convert ...
2497
  			kretprobe_blacklist[i].addr =
290e30707   Naveen N. Rao   powerpc/kprobes: ...
2498
  				kprobe_lookup_name(kretprobe_blacklist[i].name, 0);
f438d914b   Masami Hiramatsu   kprobes: support ...
2499
2500
2501
2502
2503
2504
  			if (!kretprobe_blacklist[i].addr)
  				printk("kretprobe: lookup failed: %s
  ",
  				       kretprobe_blacklist[i].name);
  		}
  	}
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
2505
2506
  #if defined(CONFIG_OPTPROBES)
  #if defined(__ARCH_WANT_KPROBES_INSN_SLOT)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2507
2508
2509
  	/* Init kprobe_optinsn_slots */
  	kprobe_optinsn_slots.insn_size = MAX_OPTINSN_SIZE;
  #endif
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
2510
2511
2512
  	/* By default, kprobes can be optimized */
  	kprobes_allow_optimization = true;
  #endif
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2513

e579abeb5   Masami Hiramatsu   kprobes: rename k...
2514
2515
  	/* By default, kprobes are armed */
  	kprobes_all_disarmed = false;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2516

6772926be   Rusty Lynch   [PATCH] kprobes: ...
2517
  	err = arch_init_kprobes();
802eae7c8   Rusty Lynch   [PATCH] Return pr...
2518
2519
  	if (!err)
  		err = register_die_notifier(&kprobe_exceptions_nb);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2520
2521
  	if (!err)
  		err = register_module_notifier(&kprobe_module_nb);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
2522
  	kprobes_initialized = (err == 0);
802eae7c8   Rusty Lynch   [PATCH] Return pr...
2523

8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
2524
2525
  	if (!err)
  		init_test_probes();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2526
2527
  	return err;
  }
36dadef23   Masami Hiramatsu   kprobes: Init kpr...
2528
  early_initcall(init_kprobes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2529

346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2530
  #ifdef CONFIG_DEBUG_FS
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2531
  static void report_probe(struct seq_file *pi, struct kprobe *p,
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2532
  		const char *sym, int offset, char *modname, struct kprobe *pp)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2533
2534
  {
  	char *kprobe_type;
81365a947   Masami Hiramatsu   kprobes: Show add...
2535
  	void *addr = p->addr;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2536
2537
2538
  
  	if (p->pre_handler == pre_handler_kretprobe)
  		kprobe_type = "r";
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2539
2540
  	else
  		kprobe_type = "k";
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2541

60f7bb66b   Kees Cook   kprobes: Do not e...
2542
  	if (!kallsyms_show_value(pi->file->f_cred))
81365a947   Masami Hiramatsu   kprobes: Show add...
2543
  		addr = NULL;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2544
  	if (sym)
81365a947   Masami Hiramatsu   kprobes: Show add...
2545
2546
  		seq_printf(pi, "%px  %s  %s+0x%x  %s ",
  			addr, kprobe_type, sym, offset,
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2547
  			(modname ? modname : " "));
81365a947   Masami Hiramatsu   kprobes: Show add...
2548
2549
2550
  	else	/* try to use %pS */
  		seq_printf(pi, "%px  %s  %pS ",
  			addr, kprobe_type, p->addr);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2551
2552
2553
  
  	if (!pp)
  		pp = p;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
2554
2555
  	seq_printf(pi, "%s%s%s%s
  ",
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2556
2557
  		(kprobe_gone(p) ? "[GONE]" : ""),
  		((kprobe_disabled(p) && !kprobe_gone(p)) ?  "[DISABLED]" : ""),
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
2558
2559
  		(kprobe_optimized(pp) ? "[OPTIMIZED]" : ""),
  		(kprobe_ftrace(pp) ? "[FTRACE]" : ""));
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2560
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2561
  static void *kprobe_seq_start(struct seq_file *f, loff_t *pos)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2562
2563
2564
  {
  	return (*pos < KPROBE_TABLE_SIZE) ? pos : NULL;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2565
  static void *kprobe_seq_next(struct seq_file *f, void *v, loff_t *pos)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2566
2567
2568
2569
2570
2571
  {
  	(*pos)++;
  	if (*pos >= KPROBE_TABLE_SIZE)
  		return NULL;
  	return pos;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2572
  static void kprobe_seq_stop(struct seq_file *f, void *v)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2573
2574
2575
  {
  	/* Nothing to do */
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2576
  static int show_kprobe_addr(struct seq_file *pi, void *v)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2577
2578
  {
  	struct hlist_head *head;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2579
2580
2581
  	struct kprobe *p, *kp;
  	const char *sym = NULL;
  	unsigned int i = *(loff_t *) v;
ffb451227   Alexey Dobriyan   Simplify kallsyms...
2582
  	unsigned long offset = 0;
ab7678656   Joe Mario   kprobes: use KSYM...
2583
  	char *modname, namebuf[KSYM_NAME_LEN];
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2584
2585
2586
  
  	head = &kprobe_table[i];
  	preempt_disable();
b67bfe0d4   Sasha Levin   hlist: drop the n...
2587
  	hlist_for_each_entry_rcu(p, head, hlist) {
ffb451227   Alexey Dobriyan   Simplify kallsyms...
2588
  		sym = kallsyms_lookup((unsigned long)p->addr, NULL,
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2589
  					&offset, &modname, namebuf);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2590
  		if (kprobe_aggrprobe(p)) {
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2591
  			list_for_each_entry_rcu(kp, &p->list, list)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2592
  				report_probe(pi, kp, sym, offset, modname, p);
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2593
  		} else
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2594
  			report_probe(pi, p, sym, offset, modname, NULL);
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2595
2596
2597
2598
  	}
  	preempt_enable();
  	return 0;
  }
eac2cece4   Kefeng Wang   kernel/kprobes.c:...
2599
  static const struct seq_operations kprobes_sops = {
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2600
2601
2602
2603
2604
  	.start = kprobe_seq_start,
  	.next  = kprobe_seq_next,
  	.stop  = kprobe_seq_stop,
  	.show  = show_kprobe_addr
  };
eac2cece4   Kefeng Wang   kernel/kprobes.c:...
2605
  DEFINE_SEQ_ATTRIBUTE(kprobes);
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2606

637247403   Masami Hiramatsu   kprobes: Show bla...
2607
2608
2609
  /* kprobes/blacklist -- shows which functions can not be probed */
  static void *kprobe_blacklist_seq_start(struct seq_file *m, loff_t *pos)
  {
4fdd88877   Masami Hiramatsu   kprobes: Lock kpr...
2610
  	mutex_lock(&kprobe_mutex);
637247403   Masami Hiramatsu   kprobes: Show bla...
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
  	return seq_list_start(&kprobe_blacklist, *pos);
  }
  
  static void *kprobe_blacklist_seq_next(struct seq_file *m, void *v, loff_t *pos)
  {
  	return seq_list_next(v, &kprobe_blacklist, pos);
  }
  
  static int kprobe_blacklist_seq_show(struct seq_file *m, void *v)
  {
  	struct kprobe_blacklist_entry *ent =
  		list_entry(v, struct kprobe_blacklist_entry, list);
ffb9bd68e   Masami Hiramatsu   kprobes: Show bla...
2623
2624
2625
2626
  	/*
  	 * If /proc/kallsyms is not showing kernel address, we won't
  	 * show them here either.
  	 */
60f7bb66b   Kees Cook   kprobes: Do not e...
2627
  	if (!kallsyms_show_value(m->file->f_cred))
ffb9bd68e   Masami Hiramatsu   kprobes: Show bla...
2628
2629
2630
2631
2632
2633
2634
  		seq_printf(m, "0x%px-0x%px\t%ps
  ", NULL, NULL,
  			   (void *)ent->start_addr);
  	else
  		seq_printf(m, "0x%px-0x%px\t%ps
  ", (void *)ent->start_addr,
  			   (void *)ent->end_addr, (void *)ent->start_addr);
637247403   Masami Hiramatsu   kprobes: Show bla...
2635
2636
  	return 0;
  }
4fdd88877   Masami Hiramatsu   kprobes: Lock kpr...
2637
2638
2639
2640
  static void kprobe_blacklist_seq_stop(struct seq_file *f, void *v)
  {
  	mutex_unlock(&kprobe_mutex);
  }
eac2cece4   Kefeng Wang   kernel/kprobes.c:...
2641
  static const struct seq_operations kprobe_blacklist_sops = {
637247403   Masami Hiramatsu   kprobes: Show bla...
2642
2643
  	.start = kprobe_blacklist_seq_start,
  	.next  = kprobe_blacklist_seq_next,
4fdd88877   Masami Hiramatsu   kprobes: Lock kpr...
2644
  	.stop  = kprobe_blacklist_seq_stop,
637247403   Masami Hiramatsu   kprobes: Show bla...
2645
2646
  	.show  = kprobe_blacklist_seq_show,
  };
eac2cece4   Kefeng Wang   kernel/kprobes.c:...
2647
  DEFINE_SEQ_ATTRIBUTE(kprobe_blacklist);
637247403   Masami Hiramatsu   kprobes: Show bla...
2648

12310e343   Jessica Yu   kprobes: Propagat...
2649
  static int arm_all_kprobes(void)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2650
2651
  {
  	struct hlist_head *head;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2652
  	struct kprobe *p;
12310e343   Jessica Yu   kprobes: Propagat...
2653
2654
  	unsigned int i, total = 0, errors = 0;
  	int err, ret = 0;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2655
2656
  
  	mutex_lock(&kprobe_mutex);
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2657
2658
  	/* If kprobes are armed, just return */
  	if (!kprobes_all_disarmed)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2659
  		goto already_enabled;
977ad481b   Wang Nan   kprobes: set kpro...
2660
2661
2662
2663
2664
2665
  	/*
  	 * optimize_kprobe() called by arm_kprobe() checks
  	 * kprobes_all_disarmed, so set kprobes_all_disarmed before
  	 * arm_kprobe.
  	 */
  	kprobes_all_disarmed = false;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2666
  	/* Arming kprobes doesn't optimize kprobe itself */
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2667
2668
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
12310e343   Jessica Yu   kprobes: Propagat...
2669
  		/* Arm all kprobes on a best-effort basis */
7e6a71d8e   Masami Hiramatsu   kprobes: Use non ...
2670
  		hlist_for_each_entry(p, head, hlist) {
12310e343   Jessica Yu   kprobes: Propagat...
2671
2672
2673
2674
2675
2676
2677
2678
2679
  			if (!kprobe_disabled(p)) {
  				err = arm_kprobe(p);
  				if (err)  {
  					errors++;
  					ret = err;
  				}
  				total++;
  			}
  		}
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2680
  	}
12310e343   Jessica Yu   kprobes: Propagat...
2681
2682
2683
2684
2685
2686
2687
  	if (errors)
  		pr_warn("Kprobes globally enabled, but failed to arm %d out of %d probes
  ",
  			errors, total);
  	else
  		pr_info("Kprobes globally enabled
  ");
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2688
2689
2690
  
  already_enabled:
  	mutex_unlock(&kprobe_mutex);
12310e343   Jessica Yu   kprobes: Propagat...
2691
  	return ret;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2692
  }
297f9233b   Jessica Yu   kprobes: Propagat...
2693
  static int disarm_all_kprobes(void)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2694
2695
  {
  	struct hlist_head *head;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2696
  	struct kprobe *p;
297f9233b   Jessica Yu   kprobes: Propagat...
2697
2698
  	unsigned int i, total = 0, errors = 0;
  	int err, ret = 0;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2699
2700
  
  	mutex_lock(&kprobe_mutex);
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2701
  	/* If kprobes are already disarmed, just return */
6274de498   Masami Hiramatsu   kprobes: Support ...
2702
2703
  	if (kprobes_all_disarmed) {
  		mutex_unlock(&kprobe_mutex);
297f9233b   Jessica Yu   kprobes: Propagat...
2704
  		return 0;
6274de498   Masami Hiramatsu   kprobes: Support ...
2705
  	}
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2706

e579abeb5   Masami Hiramatsu   kprobes: rename k...
2707
  	kprobes_all_disarmed = true;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2708

bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2709
2710
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
297f9233b   Jessica Yu   kprobes: Propagat...
2711
  		/* Disarm all kprobes on a best-effort basis */
7e6a71d8e   Masami Hiramatsu   kprobes: Use non ...
2712
  		hlist_for_each_entry(p, head, hlist) {
297f9233b   Jessica Yu   kprobes: Propagat...
2713
2714
2715
2716
2717
2718
2719
2720
  			if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p)) {
  				err = disarm_kprobe(p, false);
  				if (err) {
  					errors++;
  					ret = err;
  				}
  				total++;
  			}
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2721
2722
  		}
  	}
297f9233b   Jessica Yu   kprobes: Propagat...
2723
2724
2725
2726
2727
2728
2729
2730
  
  	if (errors)
  		pr_warn("Kprobes globally disabled, but failed to disarm %d out of %d probes
  ",
  			errors, total);
  	else
  		pr_info("Kprobes globally disabled
  ");
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2731
  	mutex_unlock(&kprobe_mutex);
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2732

6274de498   Masami Hiramatsu   kprobes: Support ...
2733
2734
  	/* Wait for disarming all kprobes by optimizer */
  	wait_for_kprobe_optimizer();
297f9233b   Jessica Yu   kprobes: Propagat...
2735
2736
  
  	return ret;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
  }
  
  /*
   * XXX: The debugfs bool file interface doesn't allow for callbacks
   * when the bool state is switched. We can reuse that facility when
   * available
   */
  static ssize_t read_enabled_file_bool(struct file *file,
  	       char __user *user_buf, size_t count, loff_t *ppos)
  {
  	char buf[3];
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2748
  	if (!kprobes_all_disarmed)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
  		buf[0] = '1';
  	else
  		buf[0] = '0';
  	buf[1] = '
  ';
  	buf[2] = 0x00;
  	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
  }
  
  static ssize_t write_enabled_file_bool(struct file *file,
  	       const char __user *user_buf, size_t count, loff_t *ppos)
  {
  	char buf[32];
efeb156e7   Stephen Boyd   kprobes: silence ...
2762
  	size_t buf_size;
12310e343   Jessica Yu   kprobes: Propagat...
2763
  	int ret = 0;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2764
2765
2766
2767
  
  	buf_size = min(count, (sizeof(buf)-1));
  	if (copy_from_user(buf, user_buf, buf_size))
  		return -EFAULT;
10fb46d5f   Mathias Krause   kprobes: handle e...
2768
  	buf[buf_size] = '\0';
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2769
2770
2771
2772
  	switch (buf[0]) {
  	case 'y':
  	case 'Y':
  	case '1':
12310e343   Jessica Yu   kprobes: Propagat...
2773
  		ret = arm_all_kprobes();
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2774
2775
2776
2777
  		break;
  	case 'n':
  	case 'N':
  	case '0':
297f9233b   Jessica Yu   kprobes: Propagat...
2778
  		ret = disarm_all_kprobes();
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2779
  		break;
10fb46d5f   Mathias Krause   kprobes: handle e...
2780
2781
  	default:
  		return -EINVAL;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2782
  	}
12310e343   Jessica Yu   kprobes: Propagat...
2783
2784
  	if (ret)
  		return ret;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2785
2786
  	return count;
  }
828c09509   Alexey Dobriyan   const: constify r...
2787
  static const struct file_operations fops_kp = {
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2788
2789
  	.read =         read_enabled_file_bool,
  	.write =        write_enabled_file_bool,
6038f373a   Arnd Bergmann   llseek: automatic...
2790
  	.llseek =	default_llseek,
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2791
  };
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2792
  static int __init debugfs_kprobe_init(void)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2793
  {
8c0fd1fa6   Greg Kroah-Hartman   kprobes: no need ...
2794
  	struct dentry *dir;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2795
  	unsigned int value = 1;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2796
2797
  
  	dir = debugfs_create_dir("kprobes", NULL);
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2798

eac2cece4   Kefeng Wang   kernel/kprobes.c:...
2799
  	debugfs_create_file("list", 0400, dir, NULL, &kprobes_fops);
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2800

8c0fd1fa6   Greg Kroah-Hartman   kprobes: no need ...
2801
  	debugfs_create_file("enabled", 0600, dir, &value, &fops_kp);
637247403   Masami Hiramatsu   kprobes: Show bla...
2802

8c0fd1fa6   Greg Kroah-Hartman   kprobes: no need ...
2803
  	debugfs_create_file("blacklist", 0400, dir, NULL,
eac2cece4   Kefeng Wang   kernel/kprobes.c:...
2804
  			    &kprobe_blacklist_fops);
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2805

346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2806
2807
2808
2809
2810
  	return 0;
  }
  
  late_initcall(debugfs_kprobe_init);
  #endif /* CONFIG_DEBUG_FS */