Blame view

kernel/kprobes.c 63 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  /*
   *  Kernel Probes (KProbes)
   *  kernel/kprobes.c
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   *
   * 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: ...
30
31
32
   * 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
33
34
   */
  #include <linux/kprobes.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
36
  #include <linux/hash.h>
  #include <linux/init.h>
4e57b6817   Tim Schmielau   [PATCH] fix missi...
37
  #include <linux/slab.h>
e38697929   Randy Dunlap   kprobes: fix spar...
38
  #include <linux/stddef.h>
9984de1a5   Paul Gortmaker   kernel: Map most ...
39
  #include <linux/export.h>
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
40
  #include <linux/moduleloader.h>
3a872d89b   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
41
  #include <linux/kallsyms.h>
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
42
  #include <linux/freezer.h>
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
43
44
  #include <linux/seq_file.h>
  #include <linux/debugfs.h>
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
45
  #include <linux/sysctl.h>
1eeb66a1b   Christoph Hellwig   move die notifier...
46
  #include <linux/kdebug.h>
4460fdad8   Mathieu Desnoyers   tracing, Text Edi...
47
  #include <linux/memory.h>
4554dbcb8   Masami Hiramatsu   kprobes: Check pr...
48
  #include <linux/ftrace.h>
afd66255b   Masami Hiramatsu   kprobes: Introduc...
49
  #include <linux/cpu.h>
bf5438fca   Jason Baron   jump label: Base ...
50
  #include <linux/jump_label.h>
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
51

bfd45be0b   Christoph Hellwig   kprobes: include ...
52
  #include <asm/sections.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53
54
  #include <asm/cacheflush.h>
  #include <asm/errno.h>
7c0f6ba68   Linus Torvalds   Replace <asm/uacc...
55
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
57
58
  
  #define KPROBE_HASH_BITS 6
  #define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS)
3a872d89b   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
59

ef53d9c5e   Srinivasa D S   kprobes: improve ...
60
  static int kprobes_initialized;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
  static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
62
  static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63

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

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

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

2d14e39da   Anil S Keshavamurthy   [PATCH] kprobes: ...
86
  #ifdef __ARCH_WANT_KPROBES_INSN_SLOT
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
87
88
89
90
91
92
  /*
   * 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: ...
93
  struct kprobe_insn_page {
c5cb5a2d8   Masami Hiramatsu   kprobes: Clean up...
94
  	struct list_head list;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
95
  	kprobe_opcode_t *insns;		/* Page of instruction slots */
af96397de   Heiko Carstens   kprobes: allow to...
96
  	struct kprobe_insn_cache *cache;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
97
  	int nused;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
98
  	int ngarbage;
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
99
  	char slot_used[];
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
100
  };
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
101
102
103
  #define KPROBE_INSN_PAGE_SIZE(slots)			\
  	(offsetof(struct kprobe_insn_page, slot_used) +	\
  	 (sizeof(char) * (slots)))
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
104
105
106
107
  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: ...
108
109
110
111
112
  enum kprobe_slot_state {
  	SLOT_CLEAN = 0,
  	SLOT_DIRTY = 1,
  	SLOT_USED = 2,
  };
af96397de   Heiko Carstens   kprobes: allow to...
113
114
115
116
  static void *alloc_insn_page(void)
  {
  	return module_alloc(PAGE_SIZE);
  }
c93f5cf57   Masami Hiramatsu   kprobes/x86: Fix ...
117
  void __weak free_insn_page(void *page)
af96397de   Heiko Carstens   kprobes: allow to...
118
  {
be1f221c0   Rusty Russell   module: remove mo...
119
  	module_memfree(page);
af96397de   Heiko Carstens   kprobes: allow to...
120
  }
c802d64a3   Heiko Carstens   kprobes: unify in...
121
122
  struct kprobe_insn_cache kprobe_insn_slots = {
  	.mutex = __MUTEX_INITIALIZER(kprobe_insn_slots.mutex),
af96397de   Heiko Carstens   kprobes: allow to...
123
124
  	.alloc = alloc_insn_page,
  	.free = free_insn_page,
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
125
126
127
128
  	.pages = LIST_HEAD_INIT(kprobe_insn_slots.pages),
  	.insn_size = MAX_INSN_SIZE,
  	.nr_garbage = 0,
  };
55479f647   Masami Hiramatsu   kprobes: Allow pr...
129
  static int collect_garbage_slots(struct kprobe_insn_cache *c);
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
130

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

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

b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
163
  	/* If there are any garbage slots, collect it and try again. */
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
164
  	if (c->nr_garbage && collect_garbage_slots(c) == 0)
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
165
  		goto retry;
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
166
167
168
  
  	/* 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...
169
  	if (!kip)
c802d64a3   Heiko Carstens   kprobes: unify in...
170
  		goto out;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
171
172
173
174
175
176
  
  	/*
  	 * 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...
177
  	kip->insns = c->alloc();
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
178
179
  	if (!kip->insns) {
  		kfree(kip);
c802d64a3   Heiko Carstens   kprobes: unify in...
180
  		goto out;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
181
  	}
c5cb5a2d8   Masami Hiramatsu   kprobes: Clean up...
182
  	INIT_LIST_HEAD(&kip->list);
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
183
  	memset(kip->slot_used, SLOT_CLEAN, slots_per_page(c));
ab40c5c6b   Masami Hiramatsu   [PATCH] kprobes: ...
184
  	kip->slot_used[0] = SLOT_USED;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
185
  	kip->nused = 1;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
186
  	kip->ngarbage = 0;
af96397de   Heiko Carstens   kprobes: allow to...
187
  	kip->cache = c;
5b485629b   Masami Hiramatsu   kprobes, extable:...
188
  	list_add_rcu(&kip->list, &c->pages);
c802d64a3   Heiko Carstens   kprobes: unify in...
189
190
191
192
  	slot = kip->insns;
  out:
  	mutex_unlock(&c->mutex);
  	return slot;
129415607   Masami Hiramatsu   kprobes: add kpro...
193
  }
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
194
  /* Return 1 if all garbages are collected, otherwise 0. */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
195
  static int collect_one_slot(struct kprobe_insn_page *kip, int idx)
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
196
  {
ab40c5c6b   Masami Hiramatsu   [PATCH] kprobes: ...
197
  	kip->slot_used[idx] = SLOT_CLEAN;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
198
199
200
201
202
203
204
205
  	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...
206
  		if (!list_is_singular(&kip->list)) {
5b485629b   Masami Hiramatsu   kprobes, extable:...
207
208
  			list_del_rcu(&kip->list);
  			synchronize_rcu();
af96397de   Heiko Carstens   kprobes: allow to...
209
  			kip->cache->free(kip->insns);
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
210
211
212
213
214
215
  			kfree(kip);
  		}
  		return 1;
  	}
  	return 0;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
216
  static int collect_garbage_slots(struct kprobe_insn_cache *c)
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
217
  {
c5cb5a2d8   Masami Hiramatsu   kprobes: Clean up...
218
  	struct kprobe_insn_page *kip, *next;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
219

615d0ebbc   Masami Hiramatsu   kprobes: Disable ...
220
221
  	/* Ensure no-one is interrupted on the garbages */
  	synchronize_sched();
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
222

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

c802d64a3   Heiko Carstens   kprobes: unify in...
242
  	mutex_lock(&c->mutex);
5b485629b   Masami Hiramatsu   kprobes, extable:...
243
244
245
246
247
  	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...
248
  			goto out;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
249
  	}
5b485629b   Masami Hiramatsu   kprobes, extable:...
250
  	/* Could not find this slot. */
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
251
  	WARN_ON(1);
5b485629b   Masami Hiramatsu   kprobes, extable:...
252
  	kip = NULL;
c802d64a3   Heiko Carstens   kprobes: unify in...
253
  out:
5b485629b   Masami Hiramatsu   kprobes, extable:...
254
255
256
257
258
259
260
261
262
263
264
265
266
267
  	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...
268
  	mutex_unlock(&c->mutex);
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
269
  }
6f716acd5   Christoph Hellwig   kprobes: codingst...
270

5b485629b   Masami Hiramatsu   kprobes, extable:...
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
  /*
   * 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;
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
293
294
  #ifdef CONFIG_OPTPROBES
  /* For optimized_kprobe buffer */
c802d64a3   Heiko Carstens   kprobes: unify in...
295
296
  struct kprobe_insn_cache kprobe_optinsn_slots = {
  	.mutex = __MUTEX_INITIALIZER(kprobe_optinsn_slots.mutex),
af96397de   Heiko Carstens   kprobes: allow to...
297
298
  	.alloc = alloc_insn_page,
  	.free = free_insn_page,
afd66255b   Masami Hiramatsu   kprobes: Introduc...
299
300
301
302
  	.pages = LIST_HEAD_INIT(kprobe_optinsn_slots.pages),
  	/* .insn_size is initialized later */
  	.nr_garbage = 0,
  };
afd66255b   Masami Hiramatsu   kprobes: Introduc...
303
  #endif
2d14e39da   Anil S Keshavamurthy   [PATCH] kprobes: ...
304
  #endif
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
305

e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
306
307
308
  /* 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...
309
  	__this_cpu_write(kprobe_instance, kp);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
310
311
312
313
  }
  
  static inline void reset_kprobe_instance(void)
  {
b76834bc1   Christoph Lameter   kprobes: Use this...
314
  	__this_cpu_write(kprobe_instance, NULL);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
315
  }
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
316
317
  /*
   * This routine is called either:
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
318
   * 	- under the kprobe_mutex - during kprobe_[un]register()
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
319
   * 				OR
d217d5450   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
320
   * 	- with preemption disabled - from arch/xxx/kernel/kprobes.c
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
321
   */
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
322
  struct kprobe *get_kprobe(void *addr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
323
324
  {
  	struct hlist_head *head;
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
325
  	struct kprobe *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326
327
  
  	head = &kprobe_table[hash_ptr(addr, KPROBE_HASH_BITS)];
b67bfe0d4   Sasha Levin   hlist: drop the n...
328
  	hlist_for_each_entry_rcu(p, head, hlist) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
329
330
331
  		if (p->addr == addr)
  			return p;
  	}
afd66255b   Masami Hiramatsu   kprobes: Introduc...
332

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
333
334
  	return NULL;
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
335
  NOKPROBE_SYMBOL(get_kprobe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
337
  static int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
338
339
340
341
342
343
  
  /* 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 ...
344
345
346
347
348
349
  /* 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...
350
351
352
  /*
   * Keep all fields in the kprobe consistent
   */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
353
  static inline void copy_kprobe(struct kprobe *ap, struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
354
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
355
356
  	memcpy(&p->opcode, &ap->opcode, sizeof(kprobe_opcode_t));
  	memcpy(&p->ainsn, &ap->ainsn, sizeof(struct arch_specific_insn));
afd66255b   Masami Hiramatsu   kprobes: Introduc...
357
358
359
  }
  
  #ifdef CONFIG_OPTPROBES
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
360
361
  /* NOTE: change this value only with kprobe_mutex held */
  static bool kprobes_allow_optimization;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
362
363
364
365
  /*
   * 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...
366
  void opt_pre_handler(struct kprobe *p, struct pt_regs *regs)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
367
368
369
370
371
372
373
374
375
376
377
  {
  	struct kprobe *kp;
  
  	list_for_each_entry_rcu(kp, &p->list, list) {
  		if (kp->pre_handler && likely(!kprobe_disabled(kp))) {
  			set_kprobe_instance(kp);
  			kp->pre_handler(kp, regs);
  		}
  		reset_kprobe_instance();
  	}
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
378
  NOKPROBE_SYMBOL(opt_pre_handler);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
379

6274de498   Masami Hiramatsu   kprobes: Support ...
380
  /* Free optimized instructions and optimized_kprobe */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
381
  static void free_aggr_kprobe(struct kprobe *p)
6274de498   Masami Hiramatsu   kprobes: Support ...
382
383
384
385
386
387
388
389
  {
  	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...
390
391
392
393
394
395
396
397
398
399
400
401
  /* 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 ...
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
  /* 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...
417
  static int kprobe_queued(struct kprobe *p)
6274de498   Masami Hiramatsu   kprobes: Support ...
418
419
420
421
422
423
424
425
426
427
  {
  	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...
428
429
430
431
  /*
   * Return an optimized kprobe whose optimizing code replaces
   * instructions including addr (exclude breakpoint).
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
432
  static struct kprobe *get_optimized_kprobe(unsigned long addr)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
  {
  	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 ...
453
  static LIST_HEAD(unoptimizing_list);
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
454
  static LIST_HEAD(freeing_list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
455
456
457
458
  
  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...
459
460
461
462
  /*
   * Optimize (replace a breakpoint with a jump) kprobes listed on
   * optimizing_list.
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
463
  static void do_optimize_kprobes(void)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
464
  {
afd66255b   Masami Hiramatsu   kprobes: Introduc...
465
466
467
468
469
470
471
  	/*
  	 * 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...
472
  	 * To avoid this deadlock, caller must have locked cpu hotplug
afd66255b   Masami Hiramatsu   kprobes: Introduc...
473
474
  	 * for preventing cpu-hotplug outside of text_mutex locking.
  	 */
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
475
476
477
478
479
480
  	lockdep_assert_cpus_held();
  
  	/* Optimization never be done when disarmed */
  	if (kprobes_all_disarmed || !kprobes_allow_optimization ||
  	    list_empty(&optimizing_list))
  		return;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
481
  	mutex_lock(&text_mutex);
cd7ebe229   Masami Hiramatsu   kprobes: Use text...
482
  	arch_optimize_kprobes(&optimizing_list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
483
  	mutex_unlock(&text_mutex);
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
484
  }
6274de498   Masami Hiramatsu   kprobes: Support ...
485
486
487
488
  /*
   * Unoptimize (replace a jump with a breakpoint and remove the breakpoint
   * if need) kprobes listed on unoptimizing_list.
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
489
  static void do_unoptimize_kprobes(void)
6274de498   Masami Hiramatsu   kprobes: Support ...
490
491
  {
  	struct optimized_kprobe *op, *tmp;
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
492
493
  	/* See comment in do_optimize_kprobes() */
  	lockdep_assert_cpus_held();
6274de498   Masami Hiramatsu   kprobes: Support ...
494
495
496
  	/* Unoptimization must be done anytime */
  	if (list_empty(&unoptimizing_list))
  		return;
6274de498   Masami Hiramatsu   kprobes: Support ...
497
  	mutex_lock(&text_mutex);
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
498
  	arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list);
f984ba4eb   Masami Hiramatsu   kprobes: Use text...
499
  	/* Loop free_list for disarming */
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
500
  	list_for_each_entry_safe(op, tmp, &freeing_list, list) {
6274de498   Masami Hiramatsu   kprobes: Support ...
501
502
503
504
505
506
507
508
509
510
  		/* 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 ...
511
512
513
514
  		} else
  			list_del_init(&op->list);
  	}
  	mutex_unlock(&text_mutex);
6274de498   Masami Hiramatsu   kprobes: Support ...
515
516
517
  }
  
  /* Reclaim all kprobes on the free_list */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
518
  static void do_free_cleaned_kprobes(void)
6274de498   Masami Hiramatsu   kprobes: Support ...
519
520
  {
  	struct optimized_kprobe *op, *tmp;
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
521
  	list_for_each_entry_safe(op, tmp, &freeing_list, list) {
6274de498   Masami Hiramatsu   kprobes: Support ...
522
523
524
525
526
527
528
  		BUG_ON(!kprobe_unused(&op->kp));
  		list_del_init(&op->list);
  		free_aggr_kprobe(&op->kp);
  	}
  }
  
  /* Start optimizer after OPTIMIZE_DELAY passed */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
529
  static void kick_kprobe_optimizer(void)
6274de498   Masami Hiramatsu   kprobes: Support ...
530
  {
ad72b3bea   Tejun Heo   kprobes: fix wait...
531
  	schedule_delayed_work(&optimizing_work, OPTIMIZE_DELAY);
6274de498   Masami Hiramatsu   kprobes: Support ...
532
  }
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
533
  /* Kprobe jump optimizer */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
534
  static void kprobe_optimizer(struct work_struct *work)
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
535
  {
72ef3794c   Steven Rostedt   kprobes: Inverse ...
536
  	mutex_lock(&kprobe_mutex);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
537
  	cpus_read_lock();
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
538
539
  	/* Lock modules while optimizing kprobes */
  	mutex_lock(&module_mutex);
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
540
541
  
  	/*
6274de498   Masami Hiramatsu   kprobes: Support ...
542
543
544
  	 * Step 1: Unoptimize kprobes and collect cleaned (unused and disarmed)
  	 * kprobes before waiting for quiesence period.
  	 */
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
545
  	do_unoptimize_kprobes();
6274de498   Masami Hiramatsu   kprobes: Support ...
546
547
  
  	/*
5715de464   Masami Hiramatsu   kprobes: Use sync...
548
549
550
551
552
553
554
  	 * 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...
555
  	 */
5715de464   Masami Hiramatsu   kprobes: Use sync...
556
  	synchronize_rcu_tasks();
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
557

6274de498   Masami Hiramatsu   kprobes: Support ...
558
  	/* Step 3: Optimize kprobes after quiesence period */
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
559
  	do_optimize_kprobes();
6274de498   Masami Hiramatsu   kprobes: Support ...
560
561
  
  	/* Step 4: Free cleaned kprobes after quiesence period */
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
562
  	do_free_cleaned_kprobes();
6274de498   Masami Hiramatsu   kprobes: Support ...
563

afd66255b   Masami Hiramatsu   kprobes: Introduc...
564
  	mutex_unlock(&module_mutex);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
565
  	cpus_read_unlock();
72ef3794c   Steven Rostedt   kprobes: Inverse ...
566
  	mutex_unlock(&kprobe_mutex);
6274de498   Masami Hiramatsu   kprobes: Support ...
567

cd7ebe229   Masami Hiramatsu   kprobes: Use text...
568
  	/* Step 5: Kick optimizer again if needed */
f984ba4eb   Masami Hiramatsu   kprobes: Use text...
569
  	if (!list_empty(&optimizing_list) || !list_empty(&unoptimizing_list))
cd7ebe229   Masami Hiramatsu   kprobes: Use text...
570
  		kick_kprobe_optimizer();
6274de498   Masami Hiramatsu   kprobes: Support ...
571
572
573
  }
  
  /* Wait for completing optimization and unoptimization */
30e7d894c   Thomas Gleixner   tracing/kprobes: ...
574
  void wait_for_kprobe_optimizer(void)
6274de498   Masami Hiramatsu   kprobes: Support ...
575
  {
ad72b3bea   Tejun Heo   kprobes: fix wait...
576
577
578
579
580
581
582
583
584
585
586
587
588
589
  	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...
590
591
592
  }
  
  /* Optimize kprobe if p is ready to be optimized */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
593
  static void optimize_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
594
595
596
597
  {
  	struct optimized_kprobe *op;
  
  	/* Check if the kprobe is disabled or not ready for optimization. */
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
598
  	if (!kprobe_optready(p) || !kprobes_allow_optimization ||
afd66255b   Masami Hiramatsu   kprobes: Introduc...
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
  	    (kprobe_disabled(p) || kprobes_all_disarmed))
  		return;
  
  	/* Both of break_handler and post_handler are not supported. */
  	if (p->break_handler || p->post_handler)
  		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. */
  	if (op->kp.flags & KPROBE_FLAG_OPTIMIZED)
  		return;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
615
  	op->kp.flags |= KPROBE_FLAG_OPTIMIZED;
6274de498   Masami Hiramatsu   kprobes: Support ...
616
617
618
619
620
621
622
623
624
625
626
  
  	if (!list_empty(&op->list))
  		/* This is under unoptimizing. Just dequeue the probe */
  		list_del_init(&op->list);
  	else {
  		list_add(&op->list, &optimizing_list);
  		kick_kprobe_optimizer();
  	}
  }
  
  /* Short cut to direct unoptimizing */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
627
  static void force_unoptimize_kprobe(struct optimized_kprobe *op)
6274de498   Masami Hiramatsu   kprobes: Support ...
628
  {
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
629
  	lockdep_assert_cpus_held();
6274de498   Masami Hiramatsu   kprobes: Support ...
630
  	arch_unoptimize_kprobe(op);
6274de498   Masami Hiramatsu   kprobes: Support ...
631
632
  	if (kprobe_disabled(&op->kp))
  		arch_disarm_kprobe(&op->kp);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
633
634
635
  }
  
  /* Unoptimize a kprobe if p is optimized */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
636
  static void unoptimize_kprobe(struct kprobe *p, bool force)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
637
638
  {
  	struct optimized_kprobe *op;
6274de498   Masami Hiramatsu   kprobes: Support ...
639
640
641
642
643
644
645
646
647
648
649
650
  	if (!kprobe_aggrprobe(p) || kprobe_disarmed(p))
  		return; /* This is not an optprobe nor optimized */
  
  	op = container_of(p, struct optimized_kprobe, kp);
  	if (!kprobe_optimized(p)) {
  		/* Unoptimized or unoptimizing case */
  		if (force && !list_empty(&op->list)) {
  			/*
  			 * Only if this is unoptimizing kprobe and forced,
  			 * forcibly unoptimize it. (No need to unoptimize
  			 * unoptimized kprobe again :)
  			 */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
651
  			list_del_init(&op->list);
6274de498   Masami Hiramatsu   kprobes: Support ...
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
  			force_unoptimize_kprobe(op);
  		}
  		return;
  	}
  
  	op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
  	if (!list_empty(&op->list)) {
  		/* Dequeue from the optimization queue */
  		list_del_init(&op->list);
  		return;
  	}
  	/* Optimized kprobe case */
  	if (force)
  		/* Forcibly update the code: this is a special case */
  		force_unoptimize_kprobe(op);
  	else {
  		list_add(&op->list, &unoptimizing_list);
  		kick_kprobe_optimizer();
afd66255b   Masami Hiramatsu   kprobes: Introduc...
670
671
  	}
  }
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
672
  /* Cancel unoptimizing for reusing */
0e0b860ff   Masami Hiramatsu   kprobes: Return e...
673
  static int reuse_unused_kprobe(struct kprobe *ap)
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
674
675
  {
  	struct optimized_kprobe *op;
0e0b860ff   Masami Hiramatsu   kprobes: Return e...
676
  	int ret;
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
677
678
679
680
681
682
683
684
685
686
687
688
689
690
  
  	BUG_ON(!kprobe_unused(ap));
  	/*
  	 * 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);
  	if (unlikely(list_empty(&op->list)))
  		printk(KERN_WARNING "Warning: found a stray unused "
  			"aggrprobe@%p
  ", ap->addr);
  	/* Enable the probe again */
  	ap->flags &= ~KPROBE_FLAG_DISABLED;
  	/* Optimize it again (remove from op->list) */
0e0b860ff   Masami Hiramatsu   kprobes: Return e...
691
692
693
  	ret = kprobe_optready(ap);
  	if (ret)
  		return ret;
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
694
  	optimize_kprobe(ap);
0e0b860ff   Masami Hiramatsu   kprobes: Return e...
695
  	return 0;
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
696
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
697
  /* Remove optimized instructions */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
698
  static void kill_optimized_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
699
700
701
702
  {
  	struct optimized_kprobe *op;
  
  	op = container_of(p, struct optimized_kprobe, kp);
6274de498   Masami Hiramatsu   kprobes: Support ...
703
704
  	if (!list_empty(&op->list))
  		/* Dequeue from the (un)optimization queue */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
705
  		list_del_init(&op->list);
6274de498   Masami Hiramatsu   kprobes: Support ...
706
  	op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
707
708
709
710
711
712
713
714
715
716
717
  
  	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 ...
718
  	/* Don't touch the code, because it is already freed. */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
719
720
  	arch_remove_optimized_kprobe(op);
  }
a460246c7   Masami Hiramatsu   kprobes: Skip pre...
721
722
723
724
725
726
  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...
727
  /* Try to prepare optimized instructions */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
728
  static void prepare_optimized_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
729
730
731
732
  {
  	struct optimized_kprobe *op;
  
  	op = container_of(p, struct optimized_kprobe, kp);
a460246c7   Masami Hiramatsu   kprobes: Skip pre...
733
  	__prepare_optimized_kprobe(op, p);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
734
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
735
  /* Allocate new optimized_kprobe and try to prepare optimized instructions */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
736
  static struct kprobe *alloc_aggr_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
737
738
739
740
741
742
743
744
745
  {
  	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...
746
  	__prepare_optimized_kprobe(op, p);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
747
748
749
  
  	return &op->kp;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
750
  static void init_aggr_kprobe(struct kprobe *ap, struct kprobe *p);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
751
752
753
754
755
  
  /*
   * Prepare an optimized_kprobe and optimize it
   * NOTE: p must be a normal registered kprobe
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
756
  static void try_to_optimize_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
757
758
759
  {
  	struct kprobe *ap;
  	struct optimized_kprobe *op;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
760
761
762
  	/* Impossible to optimize ftrace-based kprobe */
  	if (kprobe_ftrace(p))
  		return;
25764288d   Masami Hiramatsu   kprobes: Move loc...
763
  	/* For preparing optimization, jump_label_text_reserved() is called */
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
764
  	cpus_read_lock();
25764288d   Masami Hiramatsu   kprobes: Move loc...
765
766
  	jump_label_lock();
  	mutex_lock(&text_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
767
768
  	ap = alloc_aggr_kprobe(p);
  	if (!ap)
25764288d   Masami Hiramatsu   kprobes: Move loc...
769
  		goto out;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
770
771
772
773
  
  	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 ...
774
775
  		arch_remove_optimized_kprobe(op);
  		kfree(op);
25764288d   Masami Hiramatsu   kprobes: Move loc...
776
  		goto out;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
777
778
779
  	}
  
  	init_aggr_kprobe(ap, p);
25764288d   Masami Hiramatsu   kprobes: Move loc...
780
781
782
783
784
  	optimize_kprobe(ap);	/* This just kicks optimizer thread */
  
  out:
  	mutex_unlock(&text_mutex);
  	jump_label_unlock();
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
785
  	cpus_read_unlock();
afd66255b   Masami Hiramatsu   kprobes: Introduc...
786
  }
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
787
  #ifdef CONFIG_SYSCTL
55479f647   Masami Hiramatsu   kprobes: Allow pr...
788
  static void optimize_all_kprobes(void)
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
789
790
  {
  	struct hlist_head *head;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
791
792
  	struct kprobe *p;
  	unsigned int i;
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
793
  	mutex_lock(&kprobe_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
794
795
  	/* If optimization is already allowed, just return */
  	if (kprobes_allow_optimization)
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
796
  		goto out;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
797

2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
798
  	cpus_read_lock();
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
799
  	kprobes_allow_optimization = true;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
800
801
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
b67bfe0d4   Sasha Levin   hlist: drop the n...
802
  		hlist_for_each_entry_rcu(p, head, hlist)
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
803
804
805
  			if (!kprobe_disabled(p))
  				optimize_kprobe(p);
  	}
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
806
  	cpus_read_unlock();
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
807
808
  	printk(KERN_INFO "Kprobes globally optimized
  ");
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
809
810
  out:
  	mutex_unlock(&kprobe_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
811
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
812
  static void unoptimize_all_kprobes(void)
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
813
814
  {
  	struct hlist_head *head;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
815
816
  	struct kprobe *p;
  	unsigned int i;
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
817
  	mutex_lock(&kprobe_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
818
  	/* If optimization is already prohibited, just return */
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
819
820
  	if (!kprobes_allow_optimization) {
  		mutex_unlock(&kprobe_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
821
  		return;
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
822
  	}
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
823

2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
824
  	cpus_read_lock();
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
825
  	kprobes_allow_optimization = false;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
826
827
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
b67bfe0d4   Sasha Levin   hlist: drop the n...
828
  		hlist_for_each_entry_rcu(p, head, hlist) {
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
829
  			if (!kprobe_disabled(p))
6274de498   Masami Hiramatsu   kprobes: Support ...
830
  				unoptimize_kprobe(p, false);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
831
832
  		}
  	}
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
833
  	cpus_read_unlock();
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
834
  	mutex_unlock(&kprobe_mutex);
6274de498   Masami Hiramatsu   kprobes: Support ...
835
836
837
838
  	/* Wait for unoptimizing completion */
  	wait_for_kprobe_optimizer();
  	printk(KERN_INFO "Kprobes globally unoptimized
  ");
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
839
  }
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
840
  static DEFINE_MUTEX(kprobe_sysctl_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
841
842
843
844
845
846
  int sysctl_kprobes_optimization;
  int proc_kprobes_optimization_handler(struct ctl_table *table, int write,
  				      void __user *buffer, size_t *length,
  				      loff_t *ppos)
  {
  	int ret;
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
847
  	mutex_lock(&kprobe_sysctl_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
848
849
850
851
852
853
854
  	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...
855
  	mutex_unlock(&kprobe_sysctl_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
856
857
858
859
  
  	return ret;
  }
  #endif /* CONFIG_SYSCTL */
6274de498   Masami Hiramatsu   kprobes: Support ...
860
  /* Put a breakpoint for a probe. Must be called with text_mutex locked */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
861
  static void __arm_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
862
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
863
  	struct kprobe *_p;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
864
865
  
  	/* Check collision with other optimized kprobes */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
866
867
  	_p = get_optimized_kprobe((unsigned long)p->addr);
  	if (unlikely(_p))
6274de498   Masami Hiramatsu   kprobes: Support ...
868
869
  		/* Fallback to unoptimized kprobe */
  		unoptimize_kprobe(_p, true);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
870
871
872
873
  
  	arch_arm_kprobe(p);
  	optimize_kprobe(p);	/* Try to optimize (add kprobe to a list) */
  }
6274de498   Masami Hiramatsu   kprobes: Support ...
874
  /* Remove the breakpoint of a probe. Must be called with text_mutex locked */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
875
  static void __disarm_kprobe(struct kprobe *p, bool reopt)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
876
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
877
  	struct kprobe *_p;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
878

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

6274de498   Masami Hiramatsu   kprobes: Support ...
882
883
884
885
886
887
888
889
  	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...
890
891
892
893
894
  }
  
  #else /* !CONFIG_OPTPROBES */
  
  #define optimize_kprobe(p)			do {} while (0)
6274de498   Masami Hiramatsu   kprobes: Support ...
895
  #define unoptimize_kprobe(p, f)			do {} while (0)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
896
897
898
899
  #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 ...
900
901
902
  #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...
903

0e0b860ff   Masami Hiramatsu   kprobes: Return e...
904
  static int reuse_unused_kprobe(struct kprobe *ap)
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
905
  {
0e0b860ff   Masami Hiramatsu   kprobes: Return e...
906
907
908
909
910
911
  	/*
  	 * 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...
912
913
  	printk(KERN_ERR "Error: There should be no unused kprobe here.
  ");
0e0b860ff   Masami Hiramatsu   kprobes: Return e...
914
  	return -EINVAL;
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
915
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
916
  static void free_aggr_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
917
  {
6274de498   Masami Hiramatsu   kprobes: Support ...
918
  	arch_remove_kprobe(p);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
919
920
  	kfree(p);
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
921
  static struct kprobe *alloc_aggr_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
922
923
924
925
  {
  	return kzalloc(sizeof(struct kprobe), GFP_KERNEL);
  }
  #endif /* CONFIG_OPTPROBES */
e7dbfe349   Masami Hiramatsu   kprobes/x86: Move...
926
  #ifdef CONFIG_KPROBES_ON_FTRACE
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
927
  static struct ftrace_ops kprobe_ftrace_ops __read_mostly = {
e52538965   Masami Hiramatsu   kprobes/x86: ftra...
928
  	.func = kprobe_ftrace_handler,
1d70be34d   Masami Hiramatsu   kprobes: Add IPMO...
929
  	.flags = FTRACE_OPS_FL_SAVE_REGS | FTRACE_OPS_FL_IPMODIFY,
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
930
931
932
933
  };
  static int kprobe_ftrace_enabled;
  
  /* Must ensure p->addr is really on ftrace */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
934
  static int prepare_kprobe(struct kprobe *p)
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
935
936
937
938
939
940
941
942
  {
  	if (!kprobe_ftrace(p))
  		return arch_prepare_kprobe(p);
  
  	return arch_prepare_kprobe_ftrace(p);
  }
  
  /* Caller must lock kprobe_mutex */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
943
  static void arm_kprobe_ftrace(struct kprobe *p)
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
  {
  	int ret;
  
  	ret = ftrace_set_filter_ip(&kprobe_ftrace_ops,
  				   (unsigned long)p->addr, 0, 0);
  	WARN(ret < 0, "Failed to arm kprobe-ftrace at %p (%d)
  ", p->addr, ret);
  	kprobe_ftrace_enabled++;
  	if (kprobe_ftrace_enabled == 1) {
  		ret = register_ftrace_function(&kprobe_ftrace_ops);
  		WARN(ret < 0, "Failed to init kprobe-ftrace (%d)
  ", ret);
  	}
  }
  
  /* Caller must lock kprobe_mutex */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
960
  static void disarm_kprobe_ftrace(struct kprobe *p)
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
961
962
963
964
965
966
967
968
969
970
971
972
973
974
  {
  	int ret;
  
  	kprobe_ftrace_enabled--;
  	if (kprobe_ftrace_enabled == 0) {
  		ret = unregister_ftrace_function(&kprobe_ftrace_ops);
  		WARN(ret < 0, "Failed to init kprobe-ftrace (%d)
  ", ret);
  	}
  	ret = ftrace_set_filter_ip(&kprobe_ftrace_ops,
  			   (unsigned long)p->addr, 1, 0);
  	WARN(ret < 0, "Failed to disarm kprobe-ftrace at %p (%d)
  ", p->addr, ret);
  }
e7dbfe349   Masami Hiramatsu   kprobes/x86: Move...
975
  #else	/* !CONFIG_KPROBES_ON_FTRACE */
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
976
977
978
979
  #define prepare_kprobe(p)	arch_prepare_kprobe(p)
  #define arm_kprobe_ftrace(p)	do {} while (0)
  #define disarm_kprobe_ftrace(p)	do {} while (0)
  #endif
201517a7f   Masami Hiramatsu   kprobes: fix to u...
980
  /* Arm a kprobe with text_mutex */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
981
  static void arm_kprobe(struct kprobe *kp)
201517a7f   Masami Hiramatsu   kprobes: fix to u...
982
  {
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
983
984
985
986
  	if (unlikely(kprobe_ftrace(kp))) {
  		arm_kprobe_ftrace(kp);
  		return;
  	}
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
987
  	cpus_read_lock();
201517a7f   Masami Hiramatsu   kprobes: fix to u...
988
  	mutex_lock(&text_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
989
  	__arm_kprobe(kp);
201517a7f   Masami Hiramatsu   kprobes: fix to u...
990
  	mutex_unlock(&text_mutex);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
991
  	cpus_read_unlock();
201517a7f   Masami Hiramatsu   kprobes: fix to u...
992
993
994
  }
  
  /* Disarm a kprobe with text_mutex */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
995
  static void disarm_kprobe(struct kprobe *kp, bool reopt)
201517a7f   Masami Hiramatsu   kprobes: fix to u...
996
  {
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
997
998
999
1000
  	if (unlikely(kprobe_ftrace(kp))) {
  		disarm_kprobe_ftrace(kp);
  		return;
  	}
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1001
1002
  
  	cpus_read_lock();
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1003
  	mutex_lock(&text_mutex);
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1004
  	__disarm_kprobe(kp, reopt);
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1005
  	mutex_unlock(&text_mutex);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1006
  	cpus_read_unlock();
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1007
  }
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1008
1009
1010
1011
  /*
   * 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...
1012
  static int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1013
1014
  {
  	struct kprobe *kp;
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1015
  	list_for_each_entry_rcu(kp, &p->list, list) {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1016
  		if (kp->pre_handler && likely(!kprobe_disabled(kp))) {
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1017
  			set_kprobe_instance(kp);
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1018
1019
  			if (kp->pre_handler(kp, regs))
  				return 1;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1020
  		}
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1021
  		reset_kprobe_instance();
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1022
1023
1024
  	}
  	return 0;
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1025
  NOKPROBE_SYMBOL(aggr_pre_handler);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1026

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1027
1028
  static void aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
  			      unsigned long flags)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1029
1030
  {
  	struct kprobe *kp;
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1031
  	list_for_each_entry_rcu(kp, &p->list, list) {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1032
  		if (kp->post_handler && likely(!kprobe_disabled(kp))) {
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1033
  			set_kprobe_instance(kp);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1034
  			kp->post_handler(kp, regs, flags);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1035
  			reset_kprobe_instance();
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1036
1037
  		}
  	}
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1038
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1039
  NOKPROBE_SYMBOL(aggr_post_handler);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1040

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

64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1046
1047
1048
1049
  	/*
  	 * 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: ...
1050
1051
  	if (cur && cur->fault_handler) {
  		if (cur->fault_handler(cur, regs, trapnr))
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1052
1053
1054
1055
  			return 1;
  	}
  	return 0;
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1056
  NOKPROBE_SYMBOL(aggr_fault_handler);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1057

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1058
  static int aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1059
  {
b76834bc1   Christoph Lameter   kprobes: Use this...
1060
  	struct kprobe *cur = __this_cpu_read(kprobe_instance);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1061
1062
1063
1064
1065
  	int ret = 0;
  
  	if (cur && cur->break_handler) {
  		if (cur->break_handler(cur, regs))
  			ret = 1;
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1066
  	}
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1067
1068
  	reset_kprobe_instance();
  	return ret;
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1069
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1070
  NOKPROBE_SYMBOL(aggr_break_handler);
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1071

bf8d5c52c   Keshavamurthy Anil S   [PATCH] kprobes: ...
1072
  /* Walks the list and increments nmissed count for multiprobe case */
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1073
  void kprobes_inc_nmissed_count(struct kprobe *p)
bf8d5c52c   Keshavamurthy Anil S   [PATCH] kprobes: ...
1074
1075
  {
  	struct kprobe *kp;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1076
  	if (!kprobe_aggrprobe(p)) {
bf8d5c52c   Keshavamurthy Anil S   [PATCH] kprobes: ...
1077
1078
1079
1080
1081
1082
1083
  		p->nmissed++;
  	} else {
  		list_for_each_entry_rcu(kp, &p->list, list)
  			kp->nmissed++;
  	}
  	return;
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1084
  NOKPROBE_SYMBOL(kprobes_inc_nmissed_count);
bf8d5c52c   Keshavamurthy Anil S   [PATCH] kprobes: ...
1085

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1086
1087
  void recycle_rp_inst(struct kretprobe_instance *ri,
  		     struct hlist_head *head)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1088
  {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1089
  	struct kretprobe *rp = ri->rp;
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1090
1091
  	/* remove rp inst off the rprobe_inst_table */
  	hlist_del(&ri->hlist);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1092
1093
  	INIT_HLIST_NODE(&ri->hlist);
  	if (likely(rp)) {
ec484608c   Thomas Gleixner   locking, kprobes:...
1094
  		raw_spin_lock(&rp->lock);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1095
  		hlist_add_head(&ri->hlist, &rp->free_instances);
ec484608c   Thomas Gleixner   locking, kprobes:...
1096
  		raw_spin_unlock(&rp->lock);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1097
1098
  	} else
  		/* Unregistering */
99219a3fb   bibo,mao   [PATCH] kretprobe...
1099
  		hlist_add_head(&ri->hlist, head);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1100
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1101
  NOKPROBE_SYMBOL(recycle_rp_inst);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1102

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1103
  void kretprobe_hash_lock(struct task_struct *tsk,
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1104
  			 struct hlist_head **head, unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1105
  __acquires(hlist_lock)
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1106
1107
  {
  	unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS);
ec484608c   Thomas Gleixner   locking, kprobes:...
1108
  	raw_spinlock_t *hlist_lock;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1109
1110
1111
  
  	*head = &kretprobe_inst_table[hash];
  	hlist_lock = kretprobe_table_lock_ptr(hash);
ec484608c   Thomas Gleixner   locking, kprobes:...
1112
  	raw_spin_lock_irqsave(hlist_lock, *flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1113
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1114
  NOKPROBE_SYMBOL(kretprobe_hash_lock);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1115

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1116
1117
  static void kretprobe_table_lock(unsigned long hash,
  				 unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1118
  __acquires(hlist_lock)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1119
  {
ec484608c   Thomas Gleixner   locking, kprobes:...
1120
1121
  	raw_spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash);
  	raw_spin_lock_irqsave(hlist_lock, *flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1122
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1123
  NOKPROBE_SYMBOL(kretprobe_table_lock);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1124

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1125
1126
  void kretprobe_hash_unlock(struct task_struct *tsk,
  			   unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1127
  __releases(hlist_lock)
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1128
1129
  {
  	unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS);
ec484608c   Thomas Gleixner   locking, kprobes:...
1130
  	raw_spinlock_t *hlist_lock;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1131
1132
  
  	hlist_lock = kretprobe_table_lock_ptr(hash);
ec484608c   Thomas Gleixner   locking, kprobes:...
1133
  	raw_spin_unlock_irqrestore(hlist_lock, *flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1134
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1135
  NOKPROBE_SYMBOL(kretprobe_hash_unlock);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1136

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1137
1138
  static void kretprobe_table_unlock(unsigned long hash,
  				   unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1139
  __releases(hlist_lock)
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1140
  {
ec484608c   Thomas Gleixner   locking, kprobes:...
1141
1142
  	raw_spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash);
  	raw_spin_unlock_irqrestore(hlist_lock, *flags);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1143
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1144
  NOKPROBE_SYMBOL(kretprobe_table_unlock);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1145

b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1146
  /*
c6fd91f0b   bibo mao   [PATCH] kretprobe...
1147
1148
1149
1150
   * 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: ...
1151
   */
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1152
  void kprobe_flush_task(struct task_struct *tk)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1153
  {
62c27be0d   bibo,mao   [PATCH] kprobe wh...
1154
  	struct kretprobe_instance *ri;
99219a3fb   bibo,mao   [PATCH] kretprobe...
1155
  	struct hlist_head *head, empty_rp;
b67bfe0d4   Sasha Levin   hlist: drop the n...
1156
  	struct hlist_node *tmp;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1157
  	unsigned long hash, flags = 0;
802eae7c8   Rusty Lynch   [PATCH] Return pr...
1158

ef53d9c5e   Srinivasa D S   kprobes: improve ...
1159
1160
1161
  	if (unlikely(!kprobes_initialized))
  		/* Early boot.  kretprobe_table_locks not yet initialized. */
  		return;
d496aab56   Ananth N Mavinakayanahalli   kprobes: initiali...
1162
  	INIT_HLIST_HEAD(&empty_rp);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1163
1164
1165
  	hash = hash_ptr(tk, KPROBE_HASH_BITS);
  	head = &kretprobe_inst_table[hash];
  	kretprobe_table_lock(hash, &flags);
b67bfe0d4   Sasha Levin   hlist: drop the n...
1166
  	hlist_for_each_entry_safe(ri, tmp, head, hlist) {
62c27be0d   bibo,mao   [PATCH] kprobe wh...
1167
  		if (ri->task == tk)
99219a3fb   bibo,mao   [PATCH] kretprobe...
1168
  			recycle_rp_inst(ri, &empty_rp);
62c27be0d   bibo,mao   [PATCH] kprobe wh...
1169
  	}
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1170
  	kretprobe_table_unlock(hash, &flags);
b67bfe0d4   Sasha Levin   hlist: drop the n...
1171
  	hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
99219a3fb   bibo,mao   [PATCH] kretprobe...
1172
1173
1174
  		hlist_del(&ri->hlist);
  		kfree(ri);
  	}
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1175
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1176
  NOKPROBE_SYMBOL(kprobe_flush_task);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1177

b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1178
1179
1180
  static inline void free_rp_inst(struct kretprobe *rp)
  {
  	struct kretprobe_instance *ri;
b67bfe0d4   Sasha Levin   hlist: drop the n...
1181
  	struct hlist_node *next;
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1182

b67bfe0d4   Sasha Levin   hlist: drop the n...
1183
  	hlist_for_each_entry_safe(ri, next, &rp->free_instances, hlist) {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1184
  		hlist_del(&ri->hlist);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1185
1186
1187
  		kfree(ri);
  	}
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1188
  static void cleanup_rp_inst(struct kretprobe *rp)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1189
  {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1190
  	unsigned long flags, hash;
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1191
  	struct kretprobe_instance *ri;
b67bfe0d4   Sasha Levin   hlist: drop the n...
1192
  	struct hlist_node *next;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1193
  	struct hlist_head *head;
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1194
  	/* No race here */
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1195
1196
1197
  	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...
1198
  		hlist_for_each_entry_safe(ri, next, head, hlist) {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1199
1200
1201
1202
  			if (ri->rp == rp)
  				ri->rp = NULL;
  		}
  		kretprobe_table_unlock(hash, &flags);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1203
  	}
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1204
1205
  	free_rp_inst(rp);
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1206
  NOKPROBE_SYMBOL(cleanup_rp_inst);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1207

64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1208
  /*
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1209
  * Add the new probe to ap->list. Fail if this is the
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1210
1211
  * second jprobe at the address - two jprobes can't coexist
  */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1212
  static int add_new_kprobe(struct kprobe *ap, struct kprobe *p)
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1213
  {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1214
  	BUG_ON(kprobe_gone(ap) || kprobe_gone(p));
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1215
1216
  
  	if (p->break_handler || p->post_handler)
6274de498   Masami Hiramatsu   kprobes: Support ...
1217
  		unoptimize_kprobe(ap, true);	/* Fall back to normal kprobe */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1218

8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1219
  	if (p->break_handler) {
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1220
  		if (ap->break_handler)
367216567   mao, bibo   [PATCH] Kprobe: m...
1221
  			return -EEXIST;
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1222
1223
  		list_add_tail_rcu(&p->list, &ap->list);
  		ap->break_handler = aggr_break_handler;
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1224
  	} else
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1225
1226
1227
  		list_add_rcu(&p->list, &ap->list);
  	if (p->post_handler && !ap->post_handler)
  		ap->post_handler = aggr_post_handler;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1228

8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1229
1230
1231
1232
  	return 0;
  }
  
  /*
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1233
1234
1235
   * 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...
1236
  static void init_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1237
  {
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1238
  	/* Copy p's insn slot to ap */
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1239
  	copy_kprobe(p, ap);
a9ad965ea   bibo, mao   [PATCH] IA64: kpr...
1240
  	flush_insn_slot(ap);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1241
  	ap->addr = p->addr;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1242
  	ap->flags = p->flags & ~KPROBE_FLAG_OPTIMIZED;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1243
  	ap->pre_handler = aggr_pre_handler;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1244
  	ap->fault_handler = aggr_fault_handler;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1245
1246
  	/* We don't care the kprobe which has gone. */
  	if (p->post_handler && !kprobe_gone(p))
367216567   mao, bibo   [PATCH] Kprobe: m...
1247
  		ap->post_handler = aggr_post_handler;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1248
  	if (p->break_handler && !kprobe_gone(p))
367216567   mao, bibo   [PATCH] Kprobe: m...
1249
  		ap->break_handler = aggr_break_handler;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1250
1251
  
  	INIT_LIST_HEAD(&ap->list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1252
  	INIT_HLIST_NODE(&ap->hlist);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1253

afd66255b   Masami Hiramatsu   kprobes: Introduc...
1254
  	list_add_rcu(&p->list, &ap->list);
adad0f331   Keshavamurthy Anil S   [PATCH] kprobes: ...
1255
  	hlist_replace_rcu(&p->hlist, &ap->hlist);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1256
1257
1258
1259
1260
  }
  
  /*
   * This is the second or subsequent kprobe at the address - handle
   * the intricacies
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1261
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1262
  static int register_aggr_kprobe(struct kprobe *orig_p, struct kprobe *p)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1263
1264
  {
  	int ret = 0;
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1265
  	struct kprobe *ap = orig_p;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1266

2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1267
  	cpus_read_lock();
25764288d   Masami Hiramatsu   kprobes: Move loc...
1268
1269
  	/* For preparing optimization, jump_label_text_reserved() is called */
  	jump_label_lock();
25764288d   Masami Hiramatsu   kprobes: Move loc...
1270
  	mutex_lock(&text_mutex);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1271
1272
1273
  	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...
1274
1275
1276
1277
  		if (!ap) {
  			ret = -ENOMEM;
  			goto out;
  		}
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1278
  		init_aggr_kprobe(ap, orig_p);
0e0b860ff   Masami Hiramatsu   kprobes: Return e...
1279
  	} else if (kprobe_unused(ap)) {
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
1280
  		/* This probe is going to die. Rescue it */
0e0b860ff   Masami Hiramatsu   kprobes: Return e...
1281
1282
1283
1284
  		ret = reuse_unused_kprobe(ap);
  		if (ret)
  			goto out;
  	}
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1285
1286
  
  	if (kprobe_gone(ap)) {
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1287
1288
1289
1290
1291
1292
  		/*
  		 * 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 ...
1293
  		ret = arch_prepare_kprobe(ap);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1294
  		if (ret)
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1295
1296
1297
1298
1299
  			/*
  			 * 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...
1300
  			goto out;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1301

afd66255b   Masami Hiramatsu   kprobes: Introduc...
1302
1303
  		/* Prepare optimized instructions if possible. */
  		prepare_optimized_kprobe(ap);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1304
  		/*
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1305
1306
  		 * Clear gone flag to prevent allocating new slot again, and
  		 * set disabled flag because it is not armed yet.
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1307
  		 */
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1308
1309
  		ap->flags = (ap->flags & ~KPROBE_FLAG_GONE)
  			    | KPROBE_FLAG_DISABLED;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1310
  	}
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1311

afd66255b   Masami Hiramatsu   kprobes: Introduc...
1312
  	/* Copy ap's insn slot to p */
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1313
  	copy_kprobe(ap, p);
25764288d   Masami Hiramatsu   kprobes: Move loc...
1314
1315
1316
1317
  	ret = add_new_kprobe(ap, p);
  
  out:
  	mutex_unlock(&text_mutex);
25764288d   Masami Hiramatsu   kprobes: Move loc...
1318
  	jump_label_unlock();
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1319
  	cpus_read_unlock();
25764288d   Masami Hiramatsu   kprobes: Move loc...
1320
1321
1322
1323
1324
1325
1326
1327
  
  	if (ret == 0 && kprobe_disabled(ap) && !kprobe_disabled(p)) {
  		ap->flags &= ~KPROBE_FLAG_DISABLED;
  		if (!kprobes_all_disarmed)
  			/* Arm the breakpoint again. */
  			arm_kprobe(ap);
  	}
  	return ret;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1328
  }
be8f27432   Masami Hiramatsu   kprobes: Prohibit...
1329
1330
1331
1332
1333
1334
  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;
  }
e5779e8e1   Andy Lutomirski   perf/x86/hw_break...
1335
  bool within_kprobe_blacklist(unsigned long addr)
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1336
  {
376e24242   Masami Hiramatsu   kprobes: Introduc...
1337
  	struct kprobe_blacklist_entry *ent;
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
1338

be8f27432   Masami Hiramatsu   kprobes: Prohibit...
1339
  	if (arch_within_kprobe_blacklist(addr))
376e24242   Masami Hiramatsu   kprobes: Introduc...
1340
  		return true;
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
1341
1342
1343
1344
  	/*
  	 * If there exists a kprobe_blacklist, verify and
  	 * fail any probe registration in the prohibited area
  	 */
376e24242   Masami Hiramatsu   kprobes: Introduc...
1345
1346
1347
  	list_for_each_entry(ent, &kprobe_blacklist, list) {
  		if (addr >= ent->start_addr && addr < ent->end_addr)
  			return true;
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
1348
  	}
376e24242   Masami Hiramatsu   kprobes: Introduc...
1349
1350
  
  	return false;
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1351
  }
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1352
1353
1354
  /*
   * 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 -...
1355
1356
   * This returns encoded errors if it fails to look up symbol or invalid
   * combination of parameters.
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1357
   */
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1358
1359
  static kprobe_opcode_t *_kprobe_addr(kprobe_opcode_t *addr,
  			const char *symbol_name, unsigned int offset)
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1360
  {
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1361
  	if ((symbol_name && addr) || (!symbol_name && !addr))
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1362
  		goto invalid;
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1363
  	if (symbol_name) {
7246f6006   Linus Torvalds   Merge tag 'powerp...
1364
  		addr = kprobe_lookup_name(symbol_name, offset);
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1365
1366
  		if (!addr)
  			return ERR_PTR(-ENOENT);
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1367
  	}
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1368
  	addr = (kprobe_opcode_t *)(((char *)addr) + offset);
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1369
1370
1371
1372
1373
  	if (addr)
  		return addr;
  
  invalid:
  	return ERR_PTR(-EINVAL);
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1374
  }
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1375
1376
1377
1378
  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 ...
1379
  /* Check passed kprobe is valid and return kprobe in kprobe_table. */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1380
  static struct kprobe *__get_valid_kprobe(struct kprobe *p)
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1381
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1382
  	struct kprobe *ap, *list_p;
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1383

6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1384
1385
  	ap = get_kprobe(p->addr);
  	if (unlikely(!ap))
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1386
  		return NULL;
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1387
1388
  	if (p != ap) {
  		list_for_each_entry_rcu(list_p, &ap->list, list)
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1389
1390
1391
1392
1393
1394
  			if (list_p == p)
  			/* kprobe p is a valid probe */
  				goto valid;
  		return NULL;
  	}
  valid:
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1395
  	return ap;
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1396
1397
1398
1399
1400
1401
  }
  
  /* 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 ...
1402
1403
  
  	mutex_lock(&kprobe_mutex);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1404
  	if (__get_valid_kprobe(p))
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1405
1406
  		ret = -EINVAL;
  	mutex_unlock(&kprobe_mutex);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1407

1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1408
1409
  	return ret;
  }
f7f242ff0   Heiko Carstens   kprobes: introduc...
1410
  int __weak arch_check_ftrace_location(struct kprobe *p)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1411
  {
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1412
  	unsigned long ftrace_addr;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1413
1414
  	ftrace_addr = ftrace_location((unsigned long)p->addr);
  	if (ftrace_addr) {
e7dbfe349   Masami Hiramatsu   kprobes/x86: Move...
1415
  #ifdef CONFIG_KPROBES_ON_FTRACE
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1416
1417
1418
  		/* Given address is not on the instruction boundary */
  		if ((unsigned long)p->addr != ftrace_addr)
  			return -EILSEQ;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1419
  		p->flags |= KPROBE_FLAG_FTRACE;
e7dbfe349   Masami Hiramatsu   kprobes/x86: Move...
1420
  #else	/* !CONFIG_KPROBES_ON_FTRACE */
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1421
1422
1423
  		return -EINVAL;
  #endif
  	}
f7f242ff0   Heiko Carstens   kprobes: introduc...
1424
1425
1426
1427
1428
1429
1430
  	return 0;
  }
  
  static int check_kprobe_address_safe(struct kprobe *p,
  				     struct module **probed_mod)
  {
  	int ret;
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1431

f7f242ff0   Heiko Carstens   kprobes: introduc...
1432
1433
1434
  	ret = arch_check_ftrace_location(p);
  	if (ret)
  		return ret;
91bad2f8d   Jason Baron   jump label: Fix d...
1435
  	jump_label_lock();
de31c3ca8   Steven Rostedt   jump label: Fix e...
1436
  	preempt_disable();
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1437
1438
  
  	/* Ensure it is not in reserved area nor out of text */
ec30c5f3a   Masami Hiramatsu   kprobes: Use kern...
1439
  	if (!kernel_text_address((unsigned long) p->addr) ||
376e24242   Masami Hiramatsu   kprobes: Introduc...
1440
  	    within_kprobe_blacklist((unsigned long) p->addr) ||
f986a499e   Prashanth Nageshappa   kprobes: return p...
1441
1442
  	    jump_label_text_reserved(p->addr, p->addr)) {
  		ret = -EINVAL;
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1443
  		goto out;
f986a499e   Prashanth Nageshappa   kprobes: return p...
1444
  	}
b3e55c727   Mao, Bibo   [PATCH] Kprobes: ...
1445

f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1446
1447
1448
  	/* Check if are we probing a module */
  	*probed_mod = __module_text_address((unsigned long) p->addr);
  	if (*probed_mod) {
6f716acd5   Christoph Hellwig   kprobes: codingst...
1449
  		/*
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1450
1451
  		 * We must hold a refcount of the probed module while updating
  		 * its code to prohibit unexpected unloading.
df019b1d8   Keshavamurthy Anil S   [PATCH] kprobes: ...
1452
  		 */
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1453
1454
1455
1456
  		if (unlikely(!try_module_get(*probed_mod))) {
  			ret = -ENOENT;
  			goto out;
  		}
de31c3ca8   Steven Rostedt   jump label: Fix e...
1457

f24659d96   Masami Hiramatsu   kprobes: support ...
1458
1459
1460
1461
  		/*
  		 * If the module freed .init.text, we couldn't insert
  		 * kprobes in there.
  		 */
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1462
1463
1464
1465
1466
  		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 ...
1467
  		}
df019b1d8   Keshavamurthy Anil S   [PATCH] kprobes: ...
1468
  	}
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1469
  out:
a189d0350   Masami Hiramatsu   kprobes: disable ...
1470
  	preempt_enable();
de31c3ca8   Steven Rostedt   jump label: Fix e...
1471
  	jump_label_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1472

f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1473
1474
  	return ret;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1475
  int register_kprobe(struct kprobe *p)
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
  {
  	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: ...
1494
  	p->nmissed = 0;
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1495
  	INIT_LIST_HEAD(&p->list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1496

f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1497
1498
1499
1500
1501
  	ret = check_kprobe_address_safe(p, &probed_mod);
  	if (ret)
  		return ret;
  
  	mutex_lock(&kprobe_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1502

64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1503
1504
  	old_p = get_kprobe(p->addr);
  	if (old_p) {
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1505
  		/* Since this may unoptimize old_p, locking text_mutex. */
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1506
  		ret = register_aggr_kprobe(old_p, p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1507
1508
  		goto out;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1509

2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1510
1511
1512
  	cpus_read_lock();
  	/* Prevent text modification */
  	mutex_lock(&text_mutex);
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1513
  	ret = prepare_kprobe(p);
25764288d   Masami Hiramatsu   kprobes: Move loc...
1514
  	mutex_unlock(&text_mutex);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1515
  	cpus_read_unlock();
6f716acd5   Christoph Hellwig   kprobes: codingst...
1516
  	if (ret)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1517
  		goto out;
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1518

64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1519
  	INIT_HLIST_NODE(&p->hlist);
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1520
  	hlist_add_head_rcu(&p->hlist,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1521
  		       &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1522
  	if (!kprobes_all_disarmed && !kprobe_disabled(p))
25764288d   Masami Hiramatsu   kprobes: Move loc...
1523
  		arm_kprobe(p);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1524
1525
1526
  
  	/* Try to optimize kprobe */
  	try_to_optimize_kprobe(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1527
  out:
7a7d1cf95   Ingo Molnar   [PATCH] sem2mutex...
1528
  	mutex_unlock(&kprobe_mutex);
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1529

e8386a0cb   Masami Hiramatsu   kprobes: support ...
1530
  	if (probed_mod)
df019b1d8   Keshavamurthy Anil S   [PATCH] kprobes: ...
1531
  		module_put(probed_mod);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1532

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1533
1534
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1535
  EXPORT_SYMBOL_GPL(register_kprobe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1536

6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1537
  /* Check if all probes on the aggrprobe are disabled */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1538
  static int aggr_kprobe_disabled(struct kprobe *ap)
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
  {
  	struct kprobe *kp;
  
  	list_for_each_entry_rcu(kp, &ap->list, list)
  		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...
1554
  static struct kprobe *__disable_kprobe(struct kprobe *p)
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
  {
  	struct kprobe *orig_p;
  
  	/* Get an original kprobe for return */
  	orig_p = __get_valid_kprobe(p);
  	if (unlikely(orig_p == NULL))
  		return NULL;
  
  	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...
1570
1571
1572
1573
1574
1575
1576
  			/*
  			 * If kprobes_all_disarmed is set, orig_p
  			 * should have already been disarmed, so
  			 * skip unneed disarming process.
  			 */
  			if (!kprobes_all_disarmed)
  				disarm_kprobe(orig_p, true);
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1577
1578
1579
1580
1581
1582
  			orig_p->flags |= KPROBE_FLAG_DISABLED;
  		}
  	}
  
  	return orig_p;
  }
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1583
1584
1585
  /*
   * Unregister a kprobe without a scheduler synchronization.
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1586
  static int __unregister_kprobe_top(struct kprobe *p)
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1587
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1588
  	struct kprobe *ap, *list_p;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1589

6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1590
1591
  	/* Disable kprobe. This will disarm it if needed. */
  	ap = __disable_kprobe(p);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1592
  	if (ap == NULL)
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1593
  		return -EINVAL;
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1594
  	if (ap == p)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
1595
  		/*
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1596
1597
  		 * 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...
1598
  		 */
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1599
1600
1601
1602
  		goto disarmed;
  
  	/* Following process expects this probe is an aggrprobe */
  	WARN_ON(!kprobe_aggrprobe(ap));
6274de498   Masami Hiramatsu   kprobes: Support ...
1603
1604
1605
1606
1607
  	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 ...
1608
1609
1610
  		goto disarmed;
  	else {
  		/* If disabling probe has special handlers, update aggrprobe */
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1611
  		if (p->break_handler && !kprobe_gone(p))
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1612
  			ap->break_handler = NULL;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1613
  		if (p->post_handler && !kprobe_gone(p)) {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1614
  			list_for_each_entry_rcu(list_p, &ap->list, list) {
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1615
1616
1617
  				if ((list_p != p) && (list_p->post_handler))
  					goto noclean;
  			}
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1618
  			ap->post_handler = NULL;
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1619
1620
  		}
  noclean:
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1621
1622
1623
1624
  		/*
  		 * Remove from the aggrprobe: this path will do nothing in
  		 * __unregister_kprobe_bottom().
  		 */
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1625
  		list_del_rcu(&p->list);
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1626
1627
1628
1629
1630
1631
  		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: ...
1632
  	}
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1633
  	return 0;
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1634
1635
  
  disarmed:
6274de498   Masami Hiramatsu   kprobes: Support ...
1636
  	BUG_ON(!kprobe_disarmed(ap));
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1637
1638
  	hlist_del_rcu(&ap->hlist);
  	return 0;
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1639
  }
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1640

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

e8386a0cb   Masami Hiramatsu   kprobes: support ...
1645
  	if (list_empty(&p->list))
6274de498   Masami Hiramatsu   kprobes: Support ...
1646
  		/* This is an independent kprobe */
0498b6350   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1647
  		arch_remove_kprobe(p);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1648
  	else if (list_is_singular(&p->list)) {
6274de498   Masami Hiramatsu   kprobes: Support ...
1649
  		/* This is the last child of an aggrprobe */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1650
  		ap = list_entry(p->list.next, struct kprobe, list);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1651
  		list_del(&p->list);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1652
  		free_aggr_kprobe(ap);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1653
  	}
6274de498   Masami Hiramatsu   kprobes: Support ...
1654
  	/* Otherwise, do nothing. */
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1655
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1656
  int register_kprobes(struct kprobe **kps, int num)
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1657
1658
1659
1660
1661
1662
  {
  	int i, ret = 0;
  
  	if (num <= 0)
  		return -EINVAL;
  	for (i = 0; i < num; i++) {
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1663
  		ret = register_kprobe(kps[i]);
67dddaad5   Masami Hiramatsu   kprobes: fix erro...
1664
1665
1666
  		if (ret < 0) {
  			if (i > 0)
  				unregister_kprobes(kps, i);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1667
  			break;
367216567   mao, bibo   [PATCH] Kprobe: m...
1668
  		}
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1669
  	}
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1670
1671
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1672
  EXPORT_SYMBOL_GPL(register_kprobes);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1673

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1674
  void unregister_kprobe(struct kprobe *p)
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1675
1676
1677
  {
  	unregister_kprobes(&p, 1);
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1678
  EXPORT_SYMBOL_GPL(unregister_kprobe);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1679

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1680
  void unregister_kprobes(struct kprobe **kps, int num)
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
  {
  	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);
  
  	synchronize_sched();
  	for (i = 0; i < num; i++)
  		if (kps[i]->addr)
  			__unregister_kprobe_bottom(kps[i]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1696
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1697
  EXPORT_SYMBOL_GPL(unregister_kprobes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1698

5f6bee347   Naveen N. Rao   kprobes: Convert ...
1699
1700
  int __weak kprobe_exceptions_notify(struct notifier_block *self,
  					unsigned long val, void *data)
fc62d0207   Naveen N. Rao   kprobes: Introduc...
1701
1702
1703
  {
  	return NOTIFY_DONE;
  }
5f6bee347   Naveen N. Rao   kprobes: Convert ...
1704
  NOKPROBE_SYMBOL(kprobe_exceptions_notify);
fc62d0207   Naveen N. Rao   kprobes: Introduc...
1705

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1706
1707
  static struct notifier_block kprobe_exceptions_nb = {
  	.notifier_call = kprobe_exceptions_notify,
3d5631e06   Anil S Keshavamurthy   [PATCH] Kprobes r...
1708
1709
  	.priority = 0x7fffffff /* we need to be notified first */
  };
3d7e33825   Michael Ellerman   jprobes: make jpr...
1710
1711
1712
1713
  unsigned long __weak arch_deref_entry_point(void *entry)
  {
  	return (unsigned long)entry;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1714

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1715
  int register_jprobes(struct jprobe **jps, int num)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1716
  {
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1717
  	int ret = 0, i;
3d7e33825   Michael Ellerman   jprobes: make jpr...
1718

26b31c190   Masami Hiramatsu   kprobes: add (un)...
1719
  	if (num <= 0)
3d7e33825   Michael Ellerman   jprobes: make jpr...
1720
  		return -EINVAL;
0f73ff80b   Naveen N. Rao   kprobes: Simplify...
1721

26b31c190   Masami Hiramatsu   kprobes: add (un)...
1722
  	for (i = 0; i < num; i++) {
0f73ff80b   Naveen N. Rao   kprobes: Simplify...
1723
  		ret = register_jprobe(jps[i]);
edbaadbe4   Namhyung Kim   kprobes: Remove r...
1724

67dddaad5   Masami Hiramatsu   kprobes: fix erro...
1725
1726
1727
  		if (ret < 0) {
  			if (i > 0)
  				unregister_jprobes(jps, i);
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1728
1729
1730
  			break;
  		}
  	}
0f73ff80b   Naveen N. Rao   kprobes: Simplify...
1731

26b31c190   Masami Hiramatsu   kprobes: add (un)...
1732
1733
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1734
  EXPORT_SYMBOL_GPL(register_jprobes);
3d7e33825   Michael Ellerman   jprobes: make jpr...
1735

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1736
  int register_jprobe(struct jprobe *jp)
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1737
  {
0f73ff80b   Naveen N. Rao   kprobes: Simplify...
1738
1739
  	unsigned long addr, offset;
  	struct kprobe *kp = &jp->kp;
dbf580623   Naveen N. Rao   kprobes: Ensure t...
1740
1741
1742
1743
  	/*
  	 * Verify probepoint as well as the jprobe handler are
  	 * valid function entry points.
  	 */
0f73ff80b   Naveen N. Rao   kprobes: Simplify...
1744
  	addr = arch_deref_entry_point(jp->entry);
dbf580623   Naveen N. Rao   kprobes: Ensure t...
1745
1746
  	if (kallsyms_lookup_size_offset(addr, NULL, &offset) && offset == 0 &&
  	    kprobe_on_func_entry(kp->addr, kp->symbol_name, kp->offset)) {
0f73ff80b   Naveen N. Rao   kprobes: Simplify...
1747
1748
1749
1750
1751
1752
  		kp->pre_handler = setjmp_pre_handler;
  		kp->break_handler = longjmp_break_handler;
  		return register_kprobe(kp);
  	}
  
  	return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1753
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1754
  EXPORT_SYMBOL_GPL(register_jprobe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1755

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1756
  void unregister_jprobe(struct jprobe *jp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1757
  {
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1758
1759
  	unregister_jprobes(&jp, 1);
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1760
  EXPORT_SYMBOL_GPL(unregister_jprobe);
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1761

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1762
  void unregister_jprobes(struct jprobe **jps, int num)
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
  {
  	int i;
  
  	if (num <= 0)
  		return;
  	mutex_lock(&kprobe_mutex);
  	for (i = 0; i < num; i++)
  		if (__unregister_kprobe_top(&jps[i]->kp) < 0)
  			jps[i]->kp.addr = NULL;
  	mutex_unlock(&kprobe_mutex);
  
  	synchronize_sched();
  	for (i = 0; i < num; i++) {
  		if (jps[i]->kp.addr)
  			__unregister_kprobe_bottom(&jps[i]->kp);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1779
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1780
  EXPORT_SYMBOL_GPL(unregister_jprobes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1781

9edddaa20   Ananth N Mavinakayanahalli   Kprobes: indicate...
1782
  #ifdef CONFIG_KRETPROBES
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1783
1784
1785
1786
  /*
   * 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...
1787
  static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1788
1789
  {
  	struct kretprobe *rp = container_of(p, struct kretprobe, kp);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1790
1791
  	unsigned long hash, flags = 0;
  	struct kretprobe_instance *ri;
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1792

f96f56780   Masami Hiramatsu   kprobes: Skip kre...
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
  	/*
  	 * To avoid deadlocks, prohibit return probing in NMI contexts,
  	 * just skip the probe and increase the (inexact) 'nmissed'
  	 * statistical counter, so that the user is informed that
  	 * something happened:
  	 */
  	if (unlikely(in_nmi())) {
  		rp->nmissed++;
  		return 0;
  	}
  
  	/* TODO: consider to only swap the RA after the last pre_handler fired */
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1805
  	hash = hash_ptr(current, KPROBE_HASH_BITS);
ec484608c   Thomas Gleixner   locking, kprobes:...
1806
  	raw_spin_lock_irqsave(&rp->lock, flags);
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1807
  	if (!hlist_empty(&rp->free_instances)) {
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1808
  		ri = hlist_entry(rp->free_instances.first,
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1809
1810
  				struct kretprobe_instance, hlist);
  		hlist_del(&ri->hlist);
ec484608c   Thomas Gleixner   locking, kprobes:...
1811
  		raw_spin_unlock_irqrestore(&rp->lock, flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1812

4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1813
1814
  		ri->rp = rp;
  		ri->task = current;
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1815

55ca6140e   Jiang Liu   kprobes: fix a me...
1816
1817
1818
1819
  		if (rp->entry_handler && rp->entry_handler(ri, regs)) {
  			raw_spin_lock_irqsave(&rp->lock, flags);
  			hlist_add_head(&ri->hlist, &rp->free_instances);
  			raw_spin_unlock_irqrestore(&rp->lock, flags);
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1820
  			return 0;
55ca6140e   Jiang Liu   kprobes: fix a me...
1821
  		}
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1822

4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1823
1824
1825
  		arch_prepare_kretprobe(ri, regs);
  
  		/* XXX(hch): why is there no hlist_move_head? */
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1826
1827
1828
1829
1830
  		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...
1831
  		rp->nmissed++;
ec484608c   Thomas Gleixner   locking, kprobes:...
1832
  		raw_spin_unlock_irqrestore(&rp->lock, flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1833
  	}
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1834
1835
  	return 0;
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1836
  NOKPROBE_SYMBOL(pre_handler_kretprobe);
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1837

659b957f2   Naveen N. Rao   kprobes: Rename [...
1838
  bool __weak arch_kprobe_on_func_entry(unsigned long offset)
90ec5e89e   Naveen N. Rao   kretprobes: Ensur...
1839
1840
1841
  {
  	return !offset;
  }
659b957f2   Naveen N. Rao   kprobes: Rename [...
1842
  bool kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset)
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1843
1844
1845
1846
1847
1848
1849
  {
  	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 [...
1850
  						!arch_kprobe_on_func_entry(offset))
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1851
1852
1853
1854
  		return false;
  
  	return true;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1855
  int register_kretprobe(struct kretprobe *rp)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1856
1857
1858
1859
  {
  	int ret = 0;
  	struct kretprobe_instance *inst;
  	int i;
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1860
  	void *addr;
90ec5e89e   Naveen N. Rao   kretprobes: Ensur...
1861

659b957f2   Naveen N. Rao   kprobes: Rename [...
1862
  	if (!kprobe_on_func_entry(rp->kp.addr, rp->kp.symbol_name, rp->kp.offset))
90ec5e89e   Naveen N. Rao   kretprobes: Ensur...
1863
  		return -EINVAL;
f438d914b   Masami Hiramatsu   kprobes: support ...
1864
1865
  
  	if (kretprobe_blacklist_size) {
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1866
  		addr = kprobe_addr(&rp->kp);
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1867
1868
  		if (IS_ERR(addr))
  			return PTR_ERR(addr);
f438d914b   Masami Hiramatsu   kprobes: support ...
1869
1870
1871
1872
1873
1874
  
  		for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
  			if (kretprobe_blacklist[i].addr == addr)
  				return -EINVAL;
  		}
  	}
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1875
1876
  
  	rp->kp.pre_handler = pre_handler_kretprobe;
7522a8423   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1877
1878
1879
  	rp->kp.post_handler = NULL;
  	rp->kp.fault_handler = NULL;
  	rp->kp.break_handler = NULL;
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1880
1881
1882
1883
  
  	/* Pre-allocate memory for max kretprobe instances */
  	if (rp->maxactive <= 0) {
  #ifdef CONFIG_PREEMPT
c2ef6661c   Heiko Carstens   kprobes: Fix dist...
1884
  		rp->maxactive = max_t(unsigned int, 10, 2*num_possible_cpus());
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1885
  #else
4dae560f9   Ananth N Mavinakayanahalli   kprobes: Sanitize...
1886
  		rp->maxactive = num_possible_cpus();
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1887
1888
  #endif
  	}
ec484608c   Thomas Gleixner   locking, kprobes:...
1889
  	raw_spin_lock_init(&rp->lock);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1890
1891
  	INIT_HLIST_HEAD(&rp->free_instances);
  	for (i = 0; i < rp->maxactive; i++) {
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1892
1893
  		inst = kmalloc(sizeof(struct kretprobe_instance) +
  			       rp->data_size, GFP_KERNEL);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1894
1895
1896
1897
  		if (inst == NULL) {
  			free_rp_inst(rp);
  			return -ENOMEM;
  		}
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1898
1899
  		INIT_HLIST_NODE(&inst->hlist);
  		hlist_add_head(&inst->hlist, &rp->free_instances);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1900
1901
1902
1903
  	}
  
  	rp->nmissed = 0;
  	/* Establish function entry probe point */
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1904
  	ret = register_kprobe(&rp->kp);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1905
  	if (ret != 0)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1906
1907
1908
  		free_rp_inst(rp);
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1909
  EXPORT_SYMBOL_GPL(register_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1910

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1911
  int register_kretprobes(struct kretprobe **rps, int num)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1912
1913
1914
1915
1916
1917
  {
  	int ret = 0, i;
  
  	if (num <= 0)
  		return -EINVAL;
  	for (i = 0; i < num; i++) {
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1918
  		ret = register_kretprobe(rps[i]);
67dddaad5   Masami Hiramatsu   kprobes: fix erro...
1919
1920
1921
  		if (ret < 0) {
  			if (i > 0)
  				unregister_kretprobes(rps, i);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1922
1923
1924
1925
1926
  			break;
  		}
  	}
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1927
  EXPORT_SYMBOL_GPL(register_kretprobes);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1928

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1929
  void unregister_kretprobe(struct kretprobe *rp)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1930
1931
1932
  {
  	unregister_kretprobes(&rp, 1);
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1933
  EXPORT_SYMBOL_GPL(unregister_kretprobe);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1934

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1935
  void unregister_kretprobes(struct kretprobe **rps, int num)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
  {
  	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);
  
  	synchronize_sched();
  	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...
1955
  EXPORT_SYMBOL_GPL(unregister_kretprobes);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1956

9edddaa20   Ananth N Mavinakayanahalli   Kprobes: indicate...
1957
  #else /* CONFIG_KRETPROBES */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1958
  int register_kretprobe(struct kretprobe *rp)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1959
1960
1961
  {
  	return -ENOSYS;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1962
  EXPORT_SYMBOL_GPL(register_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1963

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1964
  int register_kretprobes(struct kretprobe **rps, int num)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
1965
  {
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1966
  	return -ENOSYS;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
1967
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1968
  EXPORT_SYMBOL_GPL(register_kretprobes);
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1969
  void unregister_kretprobe(struct kretprobe *rp)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1970
  {
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1971
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1972
  EXPORT_SYMBOL_GPL(unregister_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1973

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1974
  void unregister_kretprobes(struct kretprobe **rps, int num)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1975
1976
  {
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1977
  EXPORT_SYMBOL_GPL(unregister_kretprobes);
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1978

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1979
  static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1980
1981
  {
  	return 0;
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1982
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1983
  NOKPROBE_SYMBOL(pre_handler_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1984

4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1985
  #endif /* CONFIG_KRETPROBES */
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1986
  /* Set the kprobe gone and remove its instruction buffer. */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1987
  static void kill_kprobe(struct kprobe *p)
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1988
1989
  {
  	struct kprobe *kp;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1990

e8386a0cb   Masami Hiramatsu   kprobes: support ...
1991
  	p->flags |= KPROBE_FLAG_GONE;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1992
  	if (kprobe_aggrprobe(p)) {
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1993
1994
1995
1996
1997
1998
1999
2000
  		/*
  		 * If this is an aggr_kprobe, we have to list all the
  		 * chained probes and mark them GONE.
  		 */
  		list_for_each_entry_rcu(kp, &p->list, list)
  			kp->flags |= KPROBE_FLAG_GONE;
  		p->post_handler = NULL;
  		p->break_handler = NULL;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2001
  		kill_optimized_kprobe(p);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2002
2003
2004
2005
2006
2007
2008
  	}
  	/*
  	 * 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);
  }
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2009
  /* Disable one kprobe */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2010
  int disable_kprobe(struct kprobe *kp)
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2011
2012
  {
  	int ret = 0;
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2013
2014
  
  	mutex_lock(&kprobe_mutex);
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
2015
2016
  	/* Disable this kprobe */
  	if (__disable_kprobe(kp) == NULL)
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2017
  		ret = -EINVAL;
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2018

c0614829c   Masami Hiramatsu   kprobes: Move ena...
2019
2020
2021
2022
2023
2024
  	mutex_unlock(&kprobe_mutex);
  	return ret;
  }
  EXPORT_SYMBOL_GPL(disable_kprobe);
  
  /* Enable one kprobe */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2025
  int enable_kprobe(struct kprobe *kp)
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
  {
  	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;
  		arm_kprobe(p);
  	}
  out:
  	mutex_unlock(&kprobe_mutex);
  	return ret;
  }
  EXPORT_SYMBOL_GPL(enable_kprobe);
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
2057
  void dump_kprobe(struct kprobe *kp)
24851d244   Frederic Weisbecker   tracing/kprobes: ...
2058
2059
2060
2061
2062
2063
2064
2065
2066
  {
  	printk(KERN_WARNING "Dumping kprobe:
  ");
  	printk(KERN_WARNING "Name: %s
  Address: %p
  Offset: %x
  ",
  	       kp->symbol_name, kp->addr, kp->offset);
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
2067
  NOKPROBE_SYMBOL(dump_kprobe);
24851d244   Frederic Weisbecker   tracing/kprobes: ...
2068

376e24242   Masami Hiramatsu   kprobes: Introduc...
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
  /*
   * 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)
  {
  	unsigned long *iter;
  	struct kprobe_blacklist_entry *ent;
d81b4253b   Masami Hiramatsu   kprobes: Fix "Fai...
2082
  	unsigned long entry, offset = 0, size = 0;
376e24242   Masami Hiramatsu   kprobes: Introduc...
2083
2084
  
  	for (iter = start; iter < end; iter++) {
d81b4253b   Masami Hiramatsu   kprobes: Fix "Fai...
2085
2086
2087
2088
2089
2090
2091
  		entry = arch_deref_entry_point((void *)*iter);
  
  		if (!kernel_text_address(entry) ||
  		    !kallsyms_lookup_size_offset(entry, &size, &offset)) {
  			pr_err("Failed to find blacklist at %p
  ",
  				(void *)entry);
376e24242   Masami Hiramatsu   kprobes: Introduc...
2092
2093
2094
2095
2096
2097
  			continue;
  		}
  
  		ent = kmalloc(sizeof(*ent), GFP_KERNEL);
  		if (!ent)
  			return -ENOMEM;
d81b4253b   Masami Hiramatsu   kprobes: Fix "Fai...
2098
2099
  		ent->start_addr = entry;
  		ent->end_addr = entry + size;
376e24242   Masami Hiramatsu   kprobes: Introduc...
2100
2101
2102
2103
2104
  		INIT_LIST_HEAD(&ent->list);
  		list_add_tail(&ent->list, &kprobe_blacklist);
  	}
  	return 0;
  }
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2105
  /* Module notifier call back, checking kprobes on the module */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2106
2107
  static int kprobes_module_callback(struct notifier_block *nb,
  				   unsigned long val, void *data)
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2108
2109
2110
  {
  	struct module *mod = data;
  	struct hlist_head *head;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2111
2112
  	struct kprobe *p;
  	unsigned int i;
f24659d96   Masami Hiramatsu   kprobes: support ...
2113
  	int checkcore = (val == MODULE_STATE_GOING);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2114

f24659d96   Masami Hiramatsu   kprobes: support ...
2115
  	if (val != MODULE_STATE_GOING && val != MODULE_STATE_LIVE)
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2116
2117
2118
  		return NOTIFY_DONE;
  
  	/*
f24659d96   Masami Hiramatsu   kprobes: support ...
2119
2120
2121
2122
  	 * 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 ...
2123
2124
2125
2126
  	 */
  	mutex_lock(&kprobe_mutex);
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
b67bfe0d4   Sasha Levin   hlist: drop the n...
2127
  		hlist_for_each_entry_rcu(p, head, hlist)
f24659d96   Masami Hiramatsu   kprobes: support ...
2128
2129
2130
  			if (within_module_init((unsigned long)p->addr, mod) ||
  			    (checkcore &&
  			     within_module_core((unsigned long)p->addr, mod))) {
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2131
2132
2133
2134
  				/*
  				 * 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...
2135
2136
2137
2138
2139
2140
  				 *
  				 * 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 ...
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
  				 */
  				kill_kprobe(p);
  			}
  	}
  	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...
2153
2154
2155
  /* Markers of _kprobe_blacklist section */
  extern unsigned long __start_kprobe_blacklist[];
  extern unsigned long __stop_kprobe_blacklist[];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2156
2157
2158
2159
2160
2161
  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: ...
2162
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2163
  		INIT_HLIST_HEAD(&kprobe_table[i]);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2164
  		INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
ec484608c   Thomas Gleixner   locking, kprobes:...
2165
  		raw_spin_lock_init(&(kretprobe_table_locks[i].lock));
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2166
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2167

376e24242   Masami Hiramatsu   kprobes: Introduc...
2168
2169
2170
2171
2172
2173
2174
  	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 ...
2175
  	}
f438d914b   Masami Hiramatsu   kprobes: support ...
2176
2177
2178
  	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 ...
2179
  			kretprobe_blacklist[i].addr =
290e30707   Naveen N. Rao   powerpc/kprobes: ...
2180
  				kprobe_lookup_name(kretprobe_blacklist[i].name, 0);
f438d914b   Masami Hiramatsu   kprobes: support ...
2181
2182
2183
2184
2185
2186
  			if (!kretprobe_blacklist[i].addr)
  				printk("kretprobe: lookup failed: %s
  ",
  				       kretprobe_blacklist[i].name);
  		}
  	}
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
2187
2188
  #if defined(CONFIG_OPTPROBES)
  #if defined(__ARCH_WANT_KPROBES_INSN_SLOT)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2189
2190
2191
  	/* Init kprobe_optinsn_slots */
  	kprobe_optinsn_slots.insn_size = MAX_OPTINSN_SIZE;
  #endif
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
2192
2193
2194
  	/* By default, kprobes can be optimized */
  	kprobes_allow_optimization = true;
  #endif
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2195

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

6772926be   Rusty Lynch   [PATCH] kprobes: ...
2199
  	err = arch_init_kprobes();
802eae7c8   Rusty Lynch   [PATCH] Return pr...
2200
2201
  	if (!err)
  		err = register_die_notifier(&kprobe_exceptions_nb);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2202
2203
  	if (!err)
  		err = register_module_notifier(&kprobe_module_nb);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
2204
  	kprobes_initialized = (err == 0);
802eae7c8   Rusty Lynch   [PATCH] Return pr...
2205

8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
2206
2207
  	if (!err)
  		init_test_probes();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2208
2209
  	return err;
  }
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2210
  #ifdef CONFIG_DEBUG_FS
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2211
  static void report_probe(struct seq_file *pi, struct kprobe *p,
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2212
  		const char *sym, int offset, char *modname, struct kprobe *pp)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2213
2214
2215
2216
2217
2218
2219
2220
2221
  {
  	char *kprobe_type;
  
  	if (p->pre_handler == pre_handler_kretprobe)
  		kprobe_type = "r";
  	else if (p->pre_handler == setjmp_pre_handler)
  		kprobe_type = "j";
  	else
  		kprobe_type = "k";
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2222

346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2223
  	if (sym)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2224
  		seq_printf(pi, "%p  %s  %s+0x%x  %s ",
de5bd88d5   Masami Hiramatsu   kprobes: support ...
2225
  			p->addr, kprobe_type, sym, offset,
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2226
  			(modname ? modname : " "));
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2227
  	else
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2228
2229
2230
2231
2232
  		seq_printf(pi, "%p  %s  %p ",
  			p->addr, kprobe_type, p->addr);
  
  	if (!pp)
  		pp = p;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
2233
2234
  	seq_printf(pi, "%s%s%s%s
  ",
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2235
2236
  		(kprobe_gone(p) ? "[GONE]" : ""),
  		((kprobe_disabled(p) && !kprobe_gone(p)) ?  "[DISABLED]" : ""),
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
2237
2238
  		(kprobe_optimized(pp) ? "[OPTIMIZED]" : ""),
  		(kprobe_ftrace(pp) ? "[FTRACE]" : ""));
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2239
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2240
  static void *kprobe_seq_start(struct seq_file *f, loff_t *pos)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2241
2242
2243
  {
  	return (*pos < KPROBE_TABLE_SIZE) ? pos : NULL;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2244
  static void *kprobe_seq_next(struct seq_file *f, void *v, loff_t *pos)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2245
2246
2247
2248
2249
2250
  {
  	(*pos)++;
  	if (*pos >= KPROBE_TABLE_SIZE)
  		return NULL;
  	return pos;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2251
  static void kprobe_seq_stop(struct seq_file *f, void *v)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2252
2253
2254
  {
  	/* Nothing to do */
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2255
  static int show_kprobe_addr(struct seq_file *pi, void *v)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2256
2257
  {
  	struct hlist_head *head;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2258
2259
2260
  	struct kprobe *p, *kp;
  	const char *sym = NULL;
  	unsigned int i = *(loff_t *) v;
ffb451227   Alexey Dobriyan   Simplify kallsyms...
2261
  	unsigned long offset = 0;
ab7678656   Joe Mario   kprobes: use KSYM...
2262
  	char *modname, namebuf[KSYM_NAME_LEN];
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2263
2264
2265
  
  	head = &kprobe_table[i];
  	preempt_disable();
b67bfe0d4   Sasha Levin   hlist: drop the n...
2266
  	hlist_for_each_entry_rcu(p, head, hlist) {
ffb451227   Alexey Dobriyan   Simplify kallsyms...
2267
  		sym = kallsyms_lookup((unsigned long)p->addr, NULL,
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2268
  					&offset, &modname, namebuf);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2269
  		if (kprobe_aggrprobe(p)) {
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2270
  			list_for_each_entry_rcu(kp, &p->list, list)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2271
  				report_probe(pi, kp, sym, offset, modname, p);
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2272
  		} else
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2273
  			report_probe(pi, p, sym, offset, modname, NULL);
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2274
2275
2276
2277
  	}
  	preempt_enable();
  	return 0;
  }
88e9d34c7   James Morris   seq_file: constif...
2278
  static const struct seq_operations kprobes_seq_ops = {
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2279
2280
2281
2282
2283
  	.start = kprobe_seq_start,
  	.next  = kprobe_seq_next,
  	.stop  = kprobe_seq_stop,
  	.show  = show_kprobe_addr
  };
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2284
  static int kprobes_open(struct inode *inode, struct file *filp)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2285
2286
2287
  {
  	return seq_open(filp, &kprobes_seq_ops);
  }
828c09509   Alexey Dobriyan   const: constify r...
2288
  static const struct file_operations debugfs_kprobes_operations = {
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2289
2290
2291
2292
2293
  	.open           = kprobes_open,
  	.read           = seq_read,
  	.llseek         = seq_lseek,
  	.release        = seq_release,
  };
637247403   Masami Hiramatsu   kprobes: Show bla...
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
  /* kprobes/blacklist -- shows which functions can not be probed */
  static void *kprobe_blacklist_seq_start(struct seq_file *m, loff_t *pos)
  {
  	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);
  
  	seq_printf(m, "0x%p-0x%p\t%ps
  ", (void *)ent->start_addr,
  		   (void *)ent->end_addr, (void *)ent->start_addr);
  	return 0;
  }
  
  static const struct seq_operations kprobe_blacklist_seq_ops = {
  	.start = kprobe_blacklist_seq_start,
  	.next  = kprobe_blacklist_seq_next,
  	.stop  = kprobe_seq_stop,	/* Reuse void function */
  	.show  = kprobe_blacklist_seq_show,
  };
  
  static int kprobe_blacklist_open(struct inode *inode, struct file *filp)
  {
  	return seq_open(filp, &kprobe_blacklist_seq_ops);
  }
  
  static const struct file_operations debugfs_kprobe_blacklist_ops = {
  	.open           = kprobe_blacklist_open,
  	.read           = seq_read,
  	.llseek         = seq_lseek,
  	.release        = seq_release,
  };
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2334
  static void arm_all_kprobes(void)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2335
2336
  {
  	struct hlist_head *head;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2337
2338
2339
2340
  	struct kprobe *p;
  	unsigned int i;
  
  	mutex_lock(&kprobe_mutex);
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2341
2342
  	/* If kprobes are armed, just return */
  	if (!kprobes_all_disarmed)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2343
  		goto already_enabled;
977ad481b   Wang Nan   kprobes: set kpro...
2344
2345
2346
2347
2348
2349
  	/*
  	 * 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...
2350
  	/* Arming kprobes doesn't optimize kprobe itself */
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2351
2352
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
b67bfe0d4   Sasha Levin   hlist: drop the n...
2353
  		hlist_for_each_entry_rcu(p, head, hlist)
de5bd88d5   Masami Hiramatsu   kprobes: support ...
2354
  			if (!kprobe_disabled(p))
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
2355
  				arm_kprobe(p);
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2356
  	}
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2357
2358
2359
2360
2361
2362
2363
  	printk(KERN_INFO "Kprobes globally enabled
  ");
  
  already_enabled:
  	mutex_unlock(&kprobe_mutex);
  	return;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2364
  static void disarm_all_kprobes(void)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2365
2366
  {
  	struct hlist_head *head;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2367
2368
2369
2370
  	struct kprobe *p;
  	unsigned int i;
  
  	mutex_lock(&kprobe_mutex);
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2371
  	/* If kprobes are already disarmed, just return */
6274de498   Masami Hiramatsu   kprobes: Support ...
2372
2373
2374
2375
  	if (kprobes_all_disarmed) {
  		mutex_unlock(&kprobe_mutex);
  		return;
  	}
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2376

e579abeb5   Masami Hiramatsu   kprobes: rename k...
2377
  	kprobes_all_disarmed = true;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2378
2379
  	printk(KERN_INFO "Kprobes globally disabled
  ");
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2380

bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2381
2382
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
b67bfe0d4   Sasha Levin   hlist: drop the n...
2383
  		hlist_for_each_entry_rcu(p, head, hlist) {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
2384
  			if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p))
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
2385
  				disarm_kprobe(p, false);
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2386
2387
  		}
  	}
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2388
  	mutex_unlock(&kprobe_mutex);
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2389

6274de498   Masami Hiramatsu   kprobes: Support ...
2390
2391
  	/* Wait for disarming all kprobes by optimizer */
  	wait_for_kprobe_optimizer();
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
  }
  
  /*
   * 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...
2403
  	if (!kprobes_all_disarmed)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
  		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 ...
2417
  	size_t buf_size;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2418
2419
2420
2421
  
  	buf_size = min(count, (sizeof(buf)-1));
  	if (copy_from_user(buf, user_buf, buf_size))
  		return -EFAULT;
10fb46d5f   Mathias Krause   kprobes: handle e...
2422
  	buf[buf_size] = '\0';
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2423
2424
2425
2426
  	switch (buf[0]) {
  	case 'y':
  	case 'Y':
  	case '1':
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2427
  		arm_all_kprobes();
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2428
2429
2430
2431
  		break;
  	case 'n':
  	case 'N':
  	case '0':
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2432
  		disarm_all_kprobes();
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2433
  		break;
10fb46d5f   Mathias Krause   kprobes: handle e...
2434
2435
  	default:
  		return -EINVAL;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2436
2437
2438
2439
  	}
  
  	return count;
  }
828c09509   Alexey Dobriyan   const: constify r...
2440
  static const struct file_operations fops_kp = {
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2441
2442
  	.read =         read_enabled_file_bool,
  	.write =        write_enabled_file_bool,
6038f373a   Arnd Bergmann   llseek: automatic...
2443
  	.llseek =	default_llseek,
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2444
  };
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2445
  static int __init debugfs_kprobe_init(void)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2446
2447
  {
  	struct dentry *dir, *file;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2448
  	unsigned int value = 1;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2449
2450
2451
2452
  
  	dir = debugfs_create_dir("kprobes", NULL);
  	if (!dir)
  		return -ENOMEM;
4bdf9c175   Masami Hiramatsu   kprobes: Make lis...
2453
  	file = debugfs_create_file("list", 0400, dir, NULL,
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2454
  				&debugfs_kprobes_operations);
637247403   Masami Hiramatsu   kprobes: Show bla...
2455
2456
  	if (!file)
  		goto error;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2457

bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2458
2459
  	file = debugfs_create_file("enabled", 0600, dir,
  					&value, &fops_kp);
637247403   Masami Hiramatsu   kprobes: Show bla...
2460
2461
  	if (!file)
  		goto error;
4bdf9c175   Masami Hiramatsu   kprobes: Make lis...
2462
  	file = debugfs_create_file("blacklist", 0400, dir, NULL,
637247403   Masami Hiramatsu   kprobes: Show bla...
2463
2464
2465
  				&debugfs_kprobe_blacklist_ops);
  	if (!file)
  		goto error;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2466

346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2467
  	return 0;
637247403   Masami Hiramatsu   kprobes: Show bla...
2468
2469
2470
2471
  
  error:
  	debugfs_remove(dir);
  	return -ENOMEM;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2472
2473
2474
2475
2476
2477
  }
  
  late_initcall(debugfs_kprobe_init);
  #endif /* CONFIG_DEBUG_FS */
  
  module_init(init_kprobes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2478

99081ab55   Masami Hiramatsu   kprobes: move EXP...
2479
  /* defined in arch/.../kernel/kprobes.c */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2480
  EXPORT_SYMBOL_GPL(jprobe_return);