Blame view

kernel/kprobes.c 56.2 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>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
  #include <linux/module.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

d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
52
  #include <asm-generic/sections.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53
54
  #include <asm/cacheflush.h>
  #include <asm/errno.h>
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
55
  #include <asm/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
60
61
62
63
64
65
66
67
  
  /*
   * Some oddball architectures like 64bit powerpc have function descriptors
   * so this must be overridable.
   */
  #ifndef kprobe_lookup_name
  #define kprobe_lookup_name(name, addr) \
  	addr = ((kprobe_opcode_t *)(kallsyms_lookup_name(name)))
  #endif
ef53d9c5e   Srinivasa D S   kprobes: improve ...
68
  static int kprobes_initialized;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
  static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
70
  static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71

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

43948f502   Masami Hiramatsu   kprobes: Remove r...
75
76
  /* This protects kprobe_table and optimizing_list */
  static DEFINE_MUTEX(kprobe_mutex);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
77
  static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
78
  static struct {
7e036d040   Andrew Morton   kernel/kprobes.c:...
79
  	spinlock_t lock ____cacheline_aligned_in_smp;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
80
81
82
83
84
85
  } kretprobe_table_locks[KPROBE_TABLE_SIZE];
  
  static spinlock_t *kretprobe_table_lock_ptr(unsigned long hash)
  {
  	return &(kretprobe_table_locks[hash].lock);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86

3d8d996e0   Srinivasa Ds   kprobes: prevent ...
87
88
89
90
91
92
93
  /*
   * Normally, functions that we'd want to prohibit kprobes in, are marked
   * __kprobes. But, there are cases where such functions already belong to
   * a different section (__sched for preempt_schedule)
   *
   * For such cases, we now have a blacklist
   */
544304b20   Daniel Guilak   kernel/kprobes.c:...
94
  static struct kprobe_blackpoint kprobe_blacklist[] = {
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
95
  	{"preempt_schedule",},
65e234ec2   Masami Hiramatsu   kprobes: Prohibit...
96
  	{"native_get_debugreg",},
a00e817f4   Masami Hiramatsu   kprobes/x86-32: M...
97
98
  	{"irq_entries_start",},
  	{"common_interrupt",},
5ecaafdbf   Masami Hiramatsu   kprobes: Add mcou...
99
  	{"mcount",},	/* mcount can be called from everywhere */
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
100
101
  	{NULL}    /* Terminator */
  };
2d14e39da   Anil S Keshavamurthy   [PATCH] kprobes: ...
102
  #ifdef __ARCH_WANT_KPROBES_INSN_SLOT
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
103
104
105
106
107
108
  /*
   * 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: ...
109
  struct kprobe_insn_page {
c5cb5a2d8   Masami Hiramatsu   kprobes: Clean up...
110
  	struct list_head list;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
111
  	kprobe_opcode_t *insns;		/* Page of instruction slots */
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
112
  	int nused;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
113
  	int ngarbage;
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
114
  	char slot_used[];
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
115
  };
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
116
117
118
119
120
121
122
123
124
125
126
127
128
129
  #define KPROBE_INSN_PAGE_SIZE(slots)			\
  	(offsetof(struct kprobe_insn_page, slot_used) +	\
  	 (sizeof(char) * (slots)))
  
  struct kprobe_insn_cache {
  	struct list_head pages;	/* list of kprobe_insn_page */
  	size_t insn_size;	/* size of instruction slot */
  	int nr_garbage;
  };
  
  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: ...
130
131
132
133
134
  enum kprobe_slot_state {
  	SLOT_CLEAN = 0,
  	SLOT_DIRTY = 1,
  	SLOT_USED = 2,
  };
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
135
136
137
138
139
140
141
  static DEFINE_MUTEX(kprobe_insn_mutex);	/* Protects kprobe_insn_slots */
  static struct kprobe_insn_cache kprobe_insn_slots = {
  	.pages = LIST_HEAD_INIT(kprobe_insn_slots.pages),
  	.insn_size = MAX_INSN_SIZE,
  	.nr_garbage = 0,
  };
  static int __kprobes collect_garbage_slots(struct kprobe_insn_cache *c);
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
142

9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
143
  /**
129415607   Masami Hiramatsu   kprobes: add kpro...
144
   * __get_insn_slot() - Find a slot on an executable page for an instruction.
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
145
146
   * We allocate an executable page if there's no room on existing ones.
   */
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
147
  static kprobe_opcode_t __kprobes *__get_insn_slot(struct kprobe_insn_cache *c)
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
148
149
  {
  	struct kprobe_insn_page *kip;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
150

6f716acd5   Christoph Hellwig   kprobes: codingst...
151
   retry:
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
152
153
  	list_for_each_entry(kip, &c->pages, list) {
  		if (kip->nused < slots_per_page(c)) {
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
154
  			int i;
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
155
  			for (i = 0; i < slots_per_page(c); i++) {
ab40c5c6b   Masami Hiramatsu   [PATCH] kprobes: ...
156
157
  				if (kip->slot_used[i] == SLOT_CLEAN) {
  					kip->slot_used[i] = SLOT_USED;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
158
  					kip->nused++;
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
159
  					return kip->insns + (i * c->insn_size);
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
160
161
  				}
  			}
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
162
163
164
  			/* kip->nused is broken. Fix it. */
  			kip->nused = slots_per_page(c);
  			WARN_ON(1);
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
165
166
  		}
  	}
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
167
  	/* If there are any garbage slots, collect it and try again. */
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
168
  	if (c->nr_garbage && collect_garbage_slots(c) == 0)
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
169
  		goto retry;
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
170
171
172
  
  	/* 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...
173
  	if (!kip)
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
174
  		return NULL;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
175
176
177
178
179
180
181
182
183
184
185
  
  	/*
  	 * 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.
  	 */
  	kip->insns = module_alloc(PAGE_SIZE);
  	if (!kip->insns) {
  		kfree(kip);
  		return NULL;
  	}
c5cb5a2d8   Masami Hiramatsu   kprobes: Clean up...
186
  	INIT_LIST_HEAD(&kip->list);
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
187
  	memset(kip->slot_used, SLOT_CLEAN, slots_per_page(c));
ab40c5c6b   Masami Hiramatsu   [PATCH] kprobes: ...
188
  	kip->slot_used[0] = SLOT_USED;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
189
  	kip->nused = 1;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
190
  	kip->ngarbage = 0;
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
191
  	list_add(&kip->list, &c->pages);
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
192
193
  	return kip->insns;
  }
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
194

129415607   Masami Hiramatsu   kprobes: add kpro...
195
196
  kprobe_opcode_t __kprobes *get_insn_slot(void)
  {
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
197
  	kprobe_opcode_t *ret = NULL;
129415607   Masami Hiramatsu   kprobes: add kpro...
198
  	mutex_lock(&kprobe_insn_mutex);
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
199
  	ret = __get_insn_slot(&kprobe_insn_slots);
129415607   Masami Hiramatsu   kprobes: add kpro...
200
  	mutex_unlock(&kprobe_insn_mutex);
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
201

129415607   Masami Hiramatsu   kprobes: add kpro...
202
203
  	return ret;
  }
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
204
205
206
  /* Return 1 if all garbages are collected, otherwise 0. */
  static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx)
  {
ab40c5c6b   Masami Hiramatsu   [PATCH] kprobes: ...
207
  	kip->slot_used[idx] = SLOT_CLEAN;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
208
209
210
211
212
213
214
215
  	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...
216
  		if (!list_is_singular(&kip->list)) {
c5cb5a2d8   Masami Hiramatsu   kprobes: Clean up...
217
  			list_del(&kip->list);
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
218
219
220
221
222
223
224
  			module_free(NULL, kip->insns);
  			kfree(kip);
  		}
  		return 1;
  	}
  	return 0;
  }
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
225
  static int __kprobes collect_garbage_slots(struct kprobe_insn_cache *c)
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
226
  {
c5cb5a2d8   Masami Hiramatsu   kprobes: Clean up...
227
  	struct kprobe_insn_page *kip, *next;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
228

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

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

4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
251
  	list_for_each_entry(kip, &c->pages, list) {
83ff56f46   Masami Hiramatsu   kprobes: Calculat...
252
253
  		long idx = ((long)slot - (long)kip->insns) /
  				(c->insn_size * sizeof(kprobe_opcode_t));
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
254
255
  		if (idx >= 0 && idx < slots_per_page(c)) {
  			WARN_ON(kip->slot_used[idx] != SLOT_USED);
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
256
  			if (dirty) {
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
257
  				kip->slot_used[idx] = SLOT_DIRTY;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
258
  				kip->ngarbage++;
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
259
260
  				if (++c->nr_garbage > slots_per_page(c))
  					collect_garbage_slots(c);
c5cb5a2d8   Masami Hiramatsu   kprobes: Clean up...
261
  			} else
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
262
263
  				collect_one_slot(kip, idx);
  			return;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
264
265
  		}
  	}
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
266
267
268
  	/* Could not free this slot. */
  	WARN_ON(1);
  }
6f716acd5   Christoph Hellwig   kprobes: codingst...
269

4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
270
271
272
273
  void __kprobes free_insn_slot(kprobe_opcode_t * slot, int dirty)
  {
  	mutex_lock(&kprobe_insn_mutex);
  	__free_insn_slot(&kprobe_insn_slots, slot, dirty);
129415607   Masami Hiramatsu   kprobes: add kpro...
274
  	mutex_unlock(&kprobe_insn_mutex);
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
275
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
  #ifdef CONFIG_OPTPROBES
  /* For optimized_kprobe buffer */
  static DEFINE_MUTEX(kprobe_optinsn_mutex); /* Protects kprobe_optinsn_slots */
  static struct kprobe_insn_cache kprobe_optinsn_slots = {
  	.pages = LIST_HEAD_INIT(kprobe_optinsn_slots.pages),
  	/* .insn_size is initialized later */
  	.nr_garbage = 0,
  };
  /* Get a slot for optimized_kprobe buffer */
  kprobe_opcode_t __kprobes *get_optinsn_slot(void)
  {
  	kprobe_opcode_t *ret = NULL;
  
  	mutex_lock(&kprobe_optinsn_mutex);
  	ret = __get_insn_slot(&kprobe_optinsn_slots);
  	mutex_unlock(&kprobe_optinsn_mutex);
  
  	return ret;
  }
  
  void __kprobes free_optinsn_slot(kprobe_opcode_t * slot, int dirty)
  {
  	mutex_lock(&kprobe_optinsn_mutex);
  	__free_insn_slot(&kprobe_optinsn_slots, slot, dirty);
  	mutex_unlock(&kprobe_optinsn_mutex);
  }
  #endif
2d14e39da   Anil S Keshavamurthy   [PATCH] kprobes: ...
303
  #endif
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
304

e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
305
306
307
  /* 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...
308
  	__this_cpu_write(kprobe_instance, kp);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
309
310
311
312
  }
  
  static inline void reset_kprobe_instance(void)
  {
b76834bc1   Christoph Lameter   kprobes: Use this...
313
  	__this_cpu_write(kprobe_instance, NULL);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
314
  }
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
315
316
  /*
   * This routine is called either:
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
317
   * 	- under the kprobe_mutex - during kprobe_[un]register()
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
318
   * 				OR
d217d5450   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
319
   * 	- with preemption disabled - from arch/xxx/kernel/kprobes.c
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
320
   */
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
321
  struct kprobe __kprobes *get_kprobe(void *addr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
323
324
  {
  	struct hlist_head *head;
  	struct hlist_node *node;
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)];
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
328
  	hlist_for_each_entry_rcu(p, node, 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;
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
335
336
337
338
339
340
341
  static int __kprobes aggr_pre_handler(struct kprobe *p, struct pt_regs *regs);
  
  /* 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 ...
342
343
344
345
346
347
  /* 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...
348
349
350
  /*
   * Keep all fields in the kprobe consistent
   */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
351
  static inline void copy_kprobe(struct kprobe *ap, struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
352
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
353
354
  	memcpy(&p->opcode, &ap->opcode, sizeof(kprobe_opcode_t));
  	memcpy(&p->ainsn, &ap->ainsn, sizeof(struct arch_specific_insn));
afd66255b   Masami Hiramatsu   kprobes: Introduc...
355
356
357
  }
  
  #ifdef CONFIG_OPTPROBES
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
358
359
  /* NOTE: change this value only with kprobe_mutex held */
  static bool kprobes_allow_optimization;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
  /*
   * Call all pre_handler on the list, but ignores its return value.
   * This must be called from arch-dep optimized caller.
   */
  void __kprobes opt_pre_handler(struct kprobe *p, struct pt_regs *regs)
  {
  	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();
  	}
  }
6274de498   Masami Hiramatsu   kprobes: Support ...
376
377
378
379
380
381
382
383
384
385
  /* Free optimized instructions and optimized_kprobe */
  static __kprobes void free_aggr_kprobe(struct kprobe *p)
  {
  	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...
386
387
388
389
390
391
392
393
394
395
396
397
  /* 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 ...
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
  /* 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 */
  static int __kprobes kprobe_queued(struct kprobe *p)
  {
  	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...
424
425
426
427
  /*
   * Return an optimized kprobe whose optimizing code replaces
   * instructions including addr (exclude breakpoint).
   */
6376b2297   Namhyung Kim   kprobes: Make fun...
428
  static struct kprobe *__kprobes get_optimized_kprobe(unsigned long addr)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
  {
  	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 ...
449
  static LIST_HEAD(unoptimizing_list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
450
451
452
  
  static void kprobe_optimizer(struct work_struct *work);
  static DECLARE_DELAYED_WORK(optimizing_work, kprobe_optimizer);
6274de498   Masami Hiramatsu   kprobes: Support ...
453
  static DECLARE_COMPLETION(optimizer_comp);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
454
  #define OPTIMIZE_DELAY 5
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
455
456
457
458
459
  /*
   * Optimize (replace a breakpoint with a jump) kprobes listed on
   * optimizing_list.
   */
  static __kprobes void do_optimize_kprobes(void)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
460
  {
6274de498   Masami Hiramatsu   kprobes: Support ...
461
462
463
464
  	/* Optimization never be done when disarmed */
  	if (kprobes_all_disarmed || !kprobes_allow_optimization ||
  	    list_empty(&optimizing_list))
  		return;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
465
466
467
468
469
470
471
472
473
474
475
476
  	/*
  	 * 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)
  	 * To avoid this deadlock, we need to call get_online_cpus()
  	 * for preventing cpu-hotplug outside of text_mutex locking.
  	 */
  	get_online_cpus();
  	mutex_lock(&text_mutex);
cd7ebe229   Masami Hiramatsu   kprobes: Use text...
477
  	arch_optimize_kprobes(&optimizing_list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
478
479
  	mutex_unlock(&text_mutex);
  	put_online_cpus();
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
480
  }
6274de498   Masami Hiramatsu   kprobes: Support ...
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
  /*
   * Unoptimize (replace a jump with a breakpoint and remove the breakpoint
   * if need) kprobes listed on unoptimizing_list.
   */
  static __kprobes void do_unoptimize_kprobes(struct list_head *free_list)
  {
  	struct optimized_kprobe *op, *tmp;
  
  	/* Unoptimization must be done anytime */
  	if (list_empty(&unoptimizing_list))
  		return;
  
  	/* Ditto to do_optimize_kprobes */
  	get_online_cpus();
  	mutex_lock(&text_mutex);
f984ba4eb   Masami Hiramatsu   kprobes: Use text...
496
497
498
  	arch_unoptimize_kprobes(&unoptimizing_list, free_list);
  	/* Loop free_list for disarming */
  	list_for_each_entry_safe(op, tmp, free_list, list) {
6274de498   Masami Hiramatsu   kprobes: Support ...
499
500
501
502
503
504
505
506
507
508
  		/* 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 ...
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
  		} else
  			list_del_init(&op->list);
  	}
  	mutex_unlock(&text_mutex);
  	put_online_cpus();
  }
  
  /* Reclaim all kprobes on the free_list */
  static __kprobes void do_free_cleaned_kprobes(struct list_head *free_list)
  {
  	struct optimized_kprobe *op, *tmp;
  
  	list_for_each_entry_safe(op, tmp, free_list, list) {
  		BUG_ON(!kprobe_unused(&op->kp));
  		list_del_init(&op->list);
  		free_aggr_kprobe(&op->kp);
  	}
  }
  
  /* Start optimizer after OPTIMIZE_DELAY passed */
  static __kprobes void kick_kprobe_optimizer(void)
  {
  	if (!delayed_work_pending(&optimizing_work))
  		schedule_delayed_work(&optimizing_work, OPTIMIZE_DELAY);
  }
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
534
535
536
  /* Kprobe jump optimizer */
  static __kprobes void kprobe_optimizer(struct work_struct *work)
  {
6274de498   Masami Hiramatsu   kprobes: Support ...
537
  	LIST_HEAD(free_list);
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
538
539
540
  	/* Lock modules while optimizing kprobes */
  	mutex_lock(&module_mutex);
  	mutex_lock(&kprobe_mutex);
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
541
542
  
  	/*
6274de498   Masami Hiramatsu   kprobes: Support ...
543
544
545
546
547
548
549
  	 * Step 1: Unoptimize kprobes and collect cleaned (unused and disarmed)
  	 * kprobes before waiting for quiesence period.
  	 */
  	do_unoptimize_kprobes(&free_list);
  
  	/*
  	 * Step 2: Wait for quiesence period to ensure all running interrupts
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
550
551
552
553
554
555
  	 * are done. Because optprobe may modify multiple instructions
  	 * there is a chance that Nth instruction is interrupted. In that
  	 * case, running interrupt can return to 2nd-Nth byte of jump
  	 * instruction. This wait is for avoiding it.
  	 */
  	synchronize_sched();
6274de498   Masami Hiramatsu   kprobes: Support ...
556
  	/* Step 3: Optimize kprobes after quiesence period */
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
557
  	do_optimize_kprobes();
6274de498   Masami Hiramatsu   kprobes: Support ...
558
559
560
  
  	/* Step 4: Free cleaned kprobes after quiesence period */
  	do_free_cleaned_kprobes(&free_list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
561
562
  	mutex_unlock(&kprobe_mutex);
  	mutex_unlock(&module_mutex);
6274de498   Masami Hiramatsu   kprobes: Support ...
563

cd7ebe229   Masami Hiramatsu   kprobes: Use text...
564
  	/* Step 5: Kick optimizer again if needed */
f984ba4eb   Masami Hiramatsu   kprobes: Use text...
565
  	if (!list_empty(&optimizing_list) || !list_empty(&unoptimizing_list))
cd7ebe229   Masami Hiramatsu   kprobes: Use text...
566
567
568
569
  		kick_kprobe_optimizer();
  	else
  		/* Wake up all waiters */
  		complete_all(&optimizer_comp);
6274de498   Masami Hiramatsu   kprobes: Support ...
570
571
572
573
574
575
576
  }
  
  /* Wait for completing optimization and unoptimization */
  static __kprobes void wait_for_kprobe_optimizer(void)
  {
  	if (delayed_work_pending(&optimizing_work))
  		wait_for_completion(&optimizer_comp);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
577
578
579
580
581
582
583
584
  }
  
  /* Optimize kprobe if p is ready to be optimized */
  static __kprobes void optimize_kprobe(struct kprobe *p)
  {
  	struct optimized_kprobe *op;
  
  	/* Check if the kprobe is disabled or not ready for optimization. */
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
585
  	if (!kprobe_optready(p) || !kprobes_allow_optimization ||
afd66255b   Masami Hiramatsu   kprobes: Introduc...
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
  	    (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...
602
  	op->kp.flags |= KPROBE_FLAG_OPTIMIZED;
6274de498   Masami Hiramatsu   kprobes: Support ...
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
  
  	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 */
  static __kprobes void force_unoptimize_kprobe(struct optimized_kprobe *op)
  {
  	get_online_cpus();
  	arch_unoptimize_kprobe(op);
  	put_online_cpus();
  	if (kprobe_disabled(&op->kp))
  		arch_disarm_kprobe(&op->kp);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
621
622
623
  }
  
  /* Unoptimize a kprobe if p is optimized */
6274de498   Masami Hiramatsu   kprobes: Support ...
624
  static __kprobes void unoptimize_kprobe(struct kprobe *p, bool force)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
625
626
  {
  	struct optimized_kprobe *op;
6274de498   Masami Hiramatsu   kprobes: Support ...
627
628
629
630
631
632
633
634
635
636
637
638
  	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...
639
  			list_del_init(&op->list);
6274de498   Masami Hiramatsu   kprobes: Support ...
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
  			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...
658
659
  	}
  }
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
  /* Cancel unoptimizing for reusing */
  static void reuse_unused_kprobe(struct kprobe *ap)
  {
  	struct optimized_kprobe *op;
  
  	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) */
  	BUG_ON(!kprobe_optready(ap));
  	optimize_kprobe(ap);
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
681
682
683
684
685
686
  /* Remove optimized instructions */
  static void __kprobes kill_optimized_kprobe(struct kprobe *p)
  {
  	struct optimized_kprobe *op;
  
  	op = container_of(p, struct optimized_kprobe, kp);
6274de498   Masami Hiramatsu   kprobes: Support ...
687
688
  	if (!list_empty(&op->list))
  		/* Dequeue from the (un)optimization queue */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
689
  		list_del_init(&op->list);
6274de498   Masami Hiramatsu   kprobes: Support ...
690
691
692
  
  	op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
  	/* Don't touch the code, because it is already freed. */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
693
694
695
696
697
698
699
700
701
702
703
  	arch_remove_optimized_kprobe(op);
  }
  
  /* Try to prepare optimized instructions */
  static __kprobes void prepare_optimized_kprobe(struct kprobe *p)
  {
  	struct optimized_kprobe *op;
  
  	op = container_of(p, struct optimized_kprobe, kp);
  	arch_prepare_optimized_kprobe(op);
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
  /* Allocate new optimized_kprobe and try to prepare optimized instructions */
  static __kprobes struct kprobe *alloc_aggr_kprobe(struct kprobe *p)
  {
  	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;
  	arch_prepare_optimized_kprobe(op);
  
  	return &op->kp;
  }
  
  static void __kprobes init_aggr_kprobe(struct kprobe *ap, struct kprobe *p);
  
  /*
   * Prepare an optimized_kprobe and optimize it
   * NOTE: p must be a normal registered kprobe
   */
  static __kprobes void try_to_optimize_kprobe(struct kprobe *p)
  {
  	struct kprobe *ap;
  	struct optimized_kprobe *op;
  
  	ap = alloc_aggr_kprobe(p);
  	if (!ap)
  		return;
  
  	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 ...
738
739
  		arch_remove_optimized_kprobe(op);
  		kfree(op);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
740
741
742
743
744
745
  		return;
  	}
  
  	init_aggr_kprobe(ap, p);
  	optimize_kprobe(ap);
  }
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
746
  #ifdef CONFIG_SYSCTL
43948f502   Masami Hiramatsu   kprobes: Remove r...
747
  /* This should be called with kprobe_mutex locked */
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
748
749
750
751
752
753
754
755
756
757
758
759
  static void __kprobes optimize_all_kprobes(void)
  {
  	struct hlist_head *head;
  	struct hlist_node *node;
  	struct kprobe *p;
  	unsigned int i;
  
  	/* If optimization is already allowed, just return */
  	if (kprobes_allow_optimization)
  		return;
  
  	kprobes_allow_optimization = true;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
760
761
762
763
764
765
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
  		hlist_for_each_entry_rcu(p, node, head, hlist)
  			if (!kprobe_disabled(p))
  				optimize_kprobe(p);
  	}
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
766
767
768
  	printk(KERN_INFO "Kprobes globally optimized
  ");
  }
43948f502   Masami Hiramatsu   kprobes: Remove r...
769
  /* This should be called with kprobe_mutex locked */
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
770
771
772
773
774
775
776
777
778
779
780
781
  static void __kprobes unoptimize_all_kprobes(void)
  {
  	struct hlist_head *head;
  	struct hlist_node *node;
  	struct kprobe *p;
  	unsigned int i;
  
  	/* If optimization is already prohibited, just return */
  	if (!kprobes_allow_optimization)
  		return;
  
  	kprobes_allow_optimization = false;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
782
783
784
785
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
  		hlist_for_each_entry_rcu(p, node, head, hlist) {
  			if (!kprobe_disabled(p))
6274de498   Masami Hiramatsu   kprobes: Support ...
786
  				unoptimize_kprobe(p, false);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
787
788
  		}
  	}
6274de498   Masami Hiramatsu   kprobes: Support ...
789
790
791
792
  	/* Wait for unoptimizing completion */
  	wait_for_kprobe_optimizer();
  	printk(KERN_INFO "Kprobes globally unoptimized
  ");
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
  }
  
  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;
  
  	mutex_lock(&kprobe_mutex);
  	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();
  	mutex_unlock(&kprobe_mutex);
  
  	return ret;
  }
  #endif /* CONFIG_SYSCTL */
6274de498   Masami Hiramatsu   kprobes: Support ...
815
  /* Put a breakpoint for a probe. Must be called with text_mutex locked */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
816
817
  static void __kprobes __arm_kprobe(struct kprobe *p)
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
818
  	struct kprobe *_p;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
819
820
  
  	/* Check collision with other optimized kprobes */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
821
822
  	_p = get_optimized_kprobe((unsigned long)p->addr);
  	if (unlikely(_p))
6274de498   Masami Hiramatsu   kprobes: Support ...
823
824
  		/* Fallback to unoptimized kprobe */
  		unoptimize_kprobe(_p, true);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
825
826
827
828
  
  	arch_arm_kprobe(p);
  	optimize_kprobe(p);	/* Try to optimize (add kprobe to a list) */
  }
6274de498   Masami Hiramatsu   kprobes: Support ...
829
830
  /* Remove the breakpoint of a probe. Must be called with text_mutex locked */
  static void __kprobes __disarm_kprobe(struct kprobe *p, bool reopt)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
831
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
832
  	struct kprobe *_p;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
833

6274de498   Masami Hiramatsu   kprobes: Support ...
834
  	unoptimize_kprobe(p, false);	/* Try to unoptimize */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
835

6274de498   Masami Hiramatsu   kprobes: Support ...
836
837
838
839
840
841
842
843
  	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...
844
845
846
847
848
  }
  
  #else /* !CONFIG_OPTPROBES */
  
  #define optimize_kprobe(p)			do {} while (0)
6274de498   Masami Hiramatsu   kprobes: Support ...
849
  #define unoptimize_kprobe(p, f)			do {} while (0)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
850
851
852
853
  #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 ...
854
855
856
  #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...
857

0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
858
859
860
861
862
863
864
  /* There should be no unused kprobes can be reused without optimization */
  static void reuse_unused_kprobe(struct kprobe *ap)
  {
  	printk(KERN_ERR "Error: There should be no unused kprobe here.
  ");
  	BUG_ON(kprobe_unused(ap));
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
865
866
  static __kprobes void free_aggr_kprobe(struct kprobe *p)
  {
6274de498   Masami Hiramatsu   kprobes: Support ...
867
  	arch_remove_kprobe(p);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
868
869
870
871
872
873
874
875
  	kfree(p);
  }
  
  static __kprobes struct kprobe *alloc_aggr_kprobe(struct kprobe *p)
  {
  	return kzalloc(sizeof(struct kprobe), GFP_KERNEL);
  }
  #endif /* CONFIG_OPTPROBES */
201517a7f   Masami Hiramatsu   kprobes: fix to u...
876
877
878
  /* Arm a kprobe with text_mutex */
  static void __kprobes arm_kprobe(struct kprobe *kp)
  {
afd66255b   Masami Hiramatsu   kprobes: Introduc...
879
880
881
882
883
  	/*
  	 * Here, since __arm_kprobe() doesn't use stop_machine(),
  	 * this doesn't cause deadlock on text_mutex. So, we don't
  	 * need get_online_cpus().
  	 */
201517a7f   Masami Hiramatsu   kprobes: fix to u...
884
  	mutex_lock(&text_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
885
  	__arm_kprobe(kp);
201517a7f   Masami Hiramatsu   kprobes: fix to u...
886
887
888
889
890
891
  	mutex_unlock(&text_mutex);
  }
  
  /* Disarm a kprobe with text_mutex */
  static void __kprobes disarm_kprobe(struct kprobe *kp)
  {
6274de498   Masami Hiramatsu   kprobes: Support ...
892
  	/* Ditto */
201517a7f   Masami Hiramatsu   kprobes: fix to u...
893
  	mutex_lock(&text_mutex);
6274de498   Masami Hiramatsu   kprobes: Support ...
894
  	__disarm_kprobe(kp, true);
201517a7f   Masami Hiramatsu   kprobes: fix to u...
895
896
  	mutex_unlock(&text_mutex);
  }
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
897
898
899
900
  /*
   * Aggregate handlers for multiple kprobes support - these handlers
   * take care of invoking the individual kprobe handlers on p->list
   */
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
901
  static int __kprobes aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
902
903
  {
  	struct kprobe *kp;
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
904
  	list_for_each_entry_rcu(kp, &p->list, list) {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
905
  		if (kp->pre_handler && likely(!kprobe_disabled(kp))) {
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
906
  			set_kprobe_instance(kp);
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
907
908
  			if (kp->pre_handler(kp, regs))
  				return 1;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
909
  		}
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
910
  		reset_kprobe_instance();
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
911
912
913
  	}
  	return 0;
  }
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
914
915
  static void __kprobes aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
  					unsigned long flags)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
916
917
  {
  	struct kprobe *kp;
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
918
  	list_for_each_entry_rcu(kp, &p->list, list) {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
919
  		if (kp->post_handler && likely(!kprobe_disabled(kp))) {
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
920
  			set_kprobe_instance(kp);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
921
  			kp->post_handler(kp, regs, flags);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
922
  			reset_kprobe_instance();
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
923
924
  		}
  	}
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
925
  }
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
926
927
  static int __kprobes aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
  					int trapnr)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
928
  {
b76834bc1   Christoph Lameter   kprobes: Use this...
929
  	struct kprobe *cur = __this_cpu_read(kprobe_instance);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
930

64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
931
932
933
934
  	/*
  	 * 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: ...
935
936
  	if (cur && cur->fault_handler) {
  		if (cur->fault_handler(cur, regs, trapnr))
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
937
938
939
940
  			return 1;
  	}
  	return 0;
  }
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
941
  static int __kprobes aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
942
  {
b76834bc1   Christoph Lameter   kprobes: Use this...
943
  	struct kprobe *cur = __this_cpu_read(kprobe_instance);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
944
945
946
947
948
  	int ret = 0;
  
  	if (cur && cur->break_handler) {
  		if (cur->break_handler(cur, regs))
  			ret = 1;
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
949
  	}
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
950
951
  	reset_kprobe_instance();
  	return ret;
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
952
  }
bf8d5c52c   Keshavamurthy Anil S   [PATCH] kprobes: ...
953
954
955
956
  /* Walks the list and increments nmissed count for multiprobe case */
  void __kprobes kprobes_inc_nmissed_count(struct kprobe *p)
  {
  	struct kprobe *kp;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
957
  	if (!kprobe_aggrprobe(p)) {
bf8d5c52c   Keshavamurthy Anil S   [PATCH] kprobes: ...
958
959
960
961
962
963
964
  		p->nmissed++;
  	} else {
  		list_for_each_entry_rcu(kp, &p->list, list)
  			kp->nmissed++;
  	}
  	return;
  }
99219a3fb   bibo,mao   [PATCH] kretprobe...
965
966
  void __kprobes recycle_rp_inst(struct kretprobe_instance *ri,
  				struct hlist_head *head)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
967
  {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
968
  	struct kretprobe *rp = ri->rp;
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
969
970
  	/* remove rp inst off the rprobe_inst_table */
  	hlist_del(&ri->hlist);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
971
972
973
974
975
  	INIT_HLIST_NODE(&ri->hlist);
  	if (likely(rp)) {
  		spin_lock(&rp->lock);
  		hlist_add_head(&ri->hlist, &rp->free_instances);
  		spin_unlock(&rp->lock);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
976
977
  	} else
  		/* Unregistering */
99219a3fb   bibo,mao   [PATCH] kretprobe...
978
  		hlist_add_head(&ri->hlist, head);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
979
  }
017c39bdb   Masami Hiramatsu   kprobes: add __kp...
980
  void __kprobes kretprobe_hash_lock(struct task_struct *tsk,
ef53d9c5e   Srinivasa D S   kprobes: improve ...
981
  			 struct hlist_head **head, unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
982
  __acquires(hlist_lock)
ef53d9c5e   Srinivasa D S   kprobes: improve ...
983
984
985
986
987
988
989
990
  {
  	unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS);
  	spinlock_t *hlist_lock;
  
  	*head = &kretprobe_inst_table[hash];
  	hlist_lock = kretprobe_table_lock_ptr(hash);
  	spin_lock_irqsave(hlist_lock, *flags);
  }
017c39bdb   Masami Hiramatsu   kprobes: add __kp...
991
992
  static void __kprobes kretprobe_table_lock(unsigned long hash,
  	unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
993
  __acquires(hlist_lock)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
994
  {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
995
996
997
  	spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash);
  	spin_lock_irqsave(hlist_lock, *flags);
  }
017c39bdb   Masami Hiramatsu   kprobes: add __kp...
998
999
  void __kprobes kretprobe_hash_unlock(struct task_struct *tsk,
  	unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1000
  __releases(hlist_lock)
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1001
1002
1003
1004
1005
1006
1007
  {
  	unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS);
  	spinlock_t *hlist_lock;
  
  	hlist_lock = kretprobe_table_lock_ptr(hash);
  	spin_unlock_irqrestore(hlist_lock, *flags);
  }
6376b2297   Namhyung Kim   kprobes: Make fun...
1008
1009
  static void __kprobes kretprobe_table_unlock(unsigned long hash,
         unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1010
  __releases(hlist_lock)
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1011
1012
1013
  {
  	spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash);
  	spin_unlock_irqrestore(hlist_lock, *flags);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1014
  }
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1015
  /*
c6fd91f0b   bibo mao   [PATCH] kretprobe...
1016
1017
1018
1019
   * 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: ...
1020
   */
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1021
  void __kprobes kprobe_flush_task(struct task_struct *tk)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1022
  {
62c27be0d   bibo,mao   [PATCH] kprobe wh...
1023
  	struct kretprobe_instance *ri;
99219a3fb   bibo,mao   [PATCH] kretprobe...
1024
  	struct hlist_head *head, empty_rp;
802eae7c8   Rusty Lynch   [PATCH] Return pr...
1025
  	struct hlist_node *node, *tmp;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1026
  	unsigned long hash, flags = 0;
802eae7c8   Rusty Lynch   [PATCH] Return pr...
1027

ef53d9c5e   Srinivasa D S   kprobes: improve ...
1028
1029
1030
1031
1032
1033
1034
  	if (unlikely(!kprobes_initialized))
  		/* Early boot.  kretprobe_table_locks not yet initialized. */
  		return;
  
  	hash = hash_ptr(tk, KPROBE_HASH_BITS);
  	head = &kretprobe_inst_table[hash];
  	kretprobe_table_lock(hash, &flags);
62c27be0d   bibo,mao   [PATCH] kprobe wh...
1035
1036
  	hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
  		if (ri->task == tk)
99219a3fb   bibo,mao   [PATCH] kretprobe...
1037
  			recycle_rp_inst(ri, &empty_rp);
62c27be0d   bibo,mao   [PATCH] kprobe wh...
1038
  	}
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1039
1040
  	kretprobe_table_unlock(hash, &flags);
  	INIT_HLIST_HEAD(&empty_rp);
99219a3fb   bibo,mao   [PATCH] kretprobe...
1041
1042
1043
1044
  	hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
  		hlist_del(&ri->hlist);
  		kfree(ri);
  	}
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1045
  }
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1046
1047
1048
  static inline void free_rp_inst(struct kretprobe *rp)
  {
  	struct kretprobe_instance *ri;
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1049
  	struct hlist_node *pos, *next;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1050
1051
  	hlist_for_each_entry_safe(ri, pos, next, &rp->free_instances, hlist) {
  		hlist_del(&ri->hlist);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1052
1053
1054
  		kfree(ri);
  	}
  }
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1055
1056
  static void __kprobes cleanup_rp_inst(struct kretprobe *rp)
  {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1057
  	unsigned long flags, hash;
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1058
1059
  	struct kretprobe_instance *ri;
  	struct hlist_node *pos, *next;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1060
  	struct hlist_head *head;
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1061
  	/* No race here */
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1062
1063
1064
1065
1066
1067
1068
1069
  	for (hash = 0; hash < KPROBE_TABLE_SIZE; hash++) {
  		kretprobe_table_lock(hash, &flags);
  		head = &kretprobe_inst_table[hash];
  		hlist_for_each_entry_safe(ri, pos, next, head, hlist) {
  			if (ri->rp == rp)
  				ri->rp = NULL;
  		}
  		kretprobe_table_unlock(hash, &flags);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1070
  	}
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1071
1072
  	free_rp_inst(rp);
  }
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1073
  /*
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1074
  * Add the new probe to ap->list. Fail if this is the
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1075
1076
  * second jprobe at the address - two jprobes can't coexist
  */
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1077
  static int __kprobes add_new_kprobe(struct kprobe *ap, struct kprobe *p)
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1078
  {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1079
  	BUG_ON(kprobe_gone(ap) || kprobe_gone(p));
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1080
1081
  
  	if (p->break_handler || p->post_handler)
6274de498   Masami Hiramatsu   kprobes: Support ...
1082
  		unoptimize_kprobe(ap, true);	/* Fall back to normal kprobe */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1083

8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1084
  	if (p->break_handler) {
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1085
  		if (ap->break_handler)
367216567   mao, bibo   [PATCH] Kprobe: m...
1086
  			return -EEXIST;
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1087
1088
  		list_add_tail_rcu(&p->list, &ap->list);
  		ap->break_handler = aggr_break_handler;
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1089
  	} else
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1090
1091
1092
  		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 ...
1093
1094
1095
1096
1097
  
  	if (kprobe_disabled(ap) && !kprobe_disabled(p)) {
  		ap->flags &= ~KPROBE_FLAG_DISABLED;
  		if (!kprobes_all_disarmed)
  			/* Arm the breakpoint again. */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1098
  			__arm_kprobe(ap);
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1099
  	}
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1100
1101
1102
1103
  	return 0;
  }
  
  /*
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1104
1105
1106
   * Fill in the required fields of the "manager kprobe". Replace the
   * earlier kprobe in the hlist with the manager kprobe
   */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1107
  static void __kprobes init_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1108
  {
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1109
  	/* Copy p's insn slot to ap */
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1110
  	copy_kprobe(p, ap);
a9ad965ea   bibo, mao   [PATCH] IA64: kpr...
1111
  	flush_insn_slot(ap);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1112
  	ap->addr = p->addr;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1113
  	ap->flags = p->flags & ~KPROBE_FLAG_OPTIMIZED;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1114
  	ap->pre_handler = aggr_pre_handler;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1115
  	ap->fault_handler = aggr_fault_handler;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1116
1117
  	/* We don't care the kprobe which has gone. */
  	if (p->post_handler && !kprobe_gone(p))
367216567   mao, bibo   [PATCH] Kprobe: m...
1118
  		ap->post_handler = aggr_post_handler;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1119
  	if (p->break_handler && !kprobe_gone(p))
367216567   mao, bibo   [PATCH] Kprobe: m...
1120
  		ap->break_handler = aggr_break_handler;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1121
1122
  
  	INIT_LIST_HEAD(&ap->list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1123
  	INIT_HLIST_NODE(&ap->hlist);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1124

afd66255b   Masami Hiramatsu   kprobes: Introduc...
1125
  	list_add_rcu(&p->list, &ap->list);
adad0f331   Keshavamurthy Anil S   [PATCH] kprobes: ...
1126
  	hlist_replace_rcu(&p->hlist, &ap->hlist);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1127
1128
1129
1130
1131
  }
  
  /*
   * This is the second or subsequent kprobe at the address - handle
   * the intricacies
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1132
   */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1133
  static int __kprobes register_aggr_kprobe(struct kprobe *orig_p,
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1134
  					  struct kprobe *p)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1135
1136
  {
  	int ret = 0;
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1137
  	struct kprobe *ap = orig_p;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1138

6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1139
1140
1141
  	if (!kprobe_aggrprobe(orig_p)) {
  		/* If orig_p is not an aggr_kprobe, create new aggr_kprobe. */
  		ap = alloc_aggr_kprobe(orig_p);
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1142
1143
  		if (!ap)
  			return -ENOMEM;
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1144
  		init_aggr_kprobe(ap, orig_p);
6274de498   Masami Hiramatsu   kprobes: Support ...
1145
  	} else if (kprobe_unused(ap))
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
1146
1147
  		/* This probe is going to die. Rescue it */
  		reuse_unused_kprobe(ap);
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1148
1149
  
  	if (kprobe_gone(ap)) {
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1150
1151
1152
1153
1154
1155
  		/*
  		 * 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 ...
1156
  		ret = arch_prepare_kprobe(ap);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1157
  		if (ret)
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1158
1159
1160
1161
1162
  			/*
  			 * 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.
  			 */
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1163
  			return ret;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1164

afd66255b   Masami Hiramatsu   kprobes: Introduc...
1165
1166
  		/* Prepare optimized instructions if possible. */
  		prepare_optimized_kprobe(ap);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1167
  		/*
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1168
1169
  		 * Clear gone flag to prevent allocating new slot again, and
  		 * set disabled flag because it is not armed yet.
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1170
  		 */
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1171
1172
  		ap->flags = (ap->flags & ~KPROBE_FLAG_GONE)
  			    | KPROBE_FLAG_DISABLED;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1173
  	}
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1174

afd66255b   Masami Hiramatsu   kprobes: Introduc...
1175
  	/* Copy ap's insn slot to p */
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1176
1177
  	copy_kprobe(ap, p);
  	return add_new_kprobe(ap, p);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1178
  }
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1179
1180
  static int __kprobes in_kprobes_functions(unsigned long addr)
  {
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
1181
  	struct kprobe_blackpoint *kb;
6f716acd5   Christoph Hellwig   kprobes: codingst...
1182
1183
  	if (addr >= (unsigned long)__kprobes_text_start &&
  	    addr < (unsigned long)__kprobes_text_end)
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1184
  		return -EINVAL;
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
  	/*
  	 * If there exists a kprobe_blacklist, verify and
  	 * fail any probe registration in the prohibited area
  	 */
  	for (kb = kprobe_blacklist; kb->name != NULL; kb++) {
  		if (kb->start_addr) {
  			if (addr >= kb->start_addr &&
  			    addr < (kb->start_addr + kb->range))
  				return -EINVAL;
  		}
  	}
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1196
1197
  	return 0;
  }
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1198
1199
1200
  /*
   * 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 -...
1201
1202
   * This returns encoded errors if it fails to look up symbol or invalid
   * combination of parameters.
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1203
1204
1205
1206
   */
  static kprobe_opcode_t __kprobes *kprobe_addr(struct kprobe *p)
  {
  	kprobe_opcode_t *addr = p->addr;
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1207
1208
1209
1210
  
  	if ((p->symbol_name && p->addr) ||
  	    (!p->symbol_name && !p->addr))
  		goto invalid;
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1211
  	if (p->symbol_name) {
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1212
  		kprobe_lookup_name(p->symbol_name, addr);
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1213
1214
  		if (!addr)
  			return ERR_PTR(-ENOENT);
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1215
  	}
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1216
1217
1218
1219
1220
1221
  	addr = (kprobe_opcode_t *)(((char *)addr) + p->offset);
  	if (addr)
  		return addr;
  
  invalid:
  	return ERR_PTR(-EINVAL);
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1222
  }
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1223
1224
1225
  /* Check passed kprobe is valid and return kprobe in kprobe_table. */
  static struct kprobe * __kprobes __get_valid_kprobe(struct kprobe *p)
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1226
  	struct kprobe *ap, *list_p;
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1227

6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1228
1229
  	ap = get_kprobe(p->addr);
  	if (unlikely(!ap))
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1230
  		return NULL;
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1231
1232
  	if (p != ap) {
  		list_for_each_entry_rcu(list_p, &ap->list, list)
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1233
1234
1235
1236
1237
1238
  			if (list_p == p)
  			/* kprobe p is a valid probe */
  				goto valid;
  		return NULL;
  	}
  valid:
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1239
  	return ap;
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1240
1241
1242
1243
1244
1245
  }
  
  /* 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 ...
1246
1247
  
  	mutex_lock(&kprobe_mutex);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1248
  	if (__get_valid_kprobe(p))
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1249
1250
  		ret = -EINVAL;
  	mutex_unlock(&kprobe_mutex);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1251

1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1252
1253
  	return ret;
  }
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1254
  int __kprobes register_kprobe(struct kprobe *p)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1255
1256
  {
  	int ret = 0;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1257
  	struct kprobe *old_p;
df019b1d8   Keshavamurthy Anil S   [PATCH] kprobes: ...
1258
  	struct module *probed_mod;
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1259
  	kprobe_opcode_t *addr;
b3e55c727   Mao, Bibo   [PATCH] Kprobes: ...
1260

b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1261
  	addr = kprobe_addr(p);
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1262
1263
  	if (IS_ERR(addr))
  		return PTR_ERR(addr);
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1264
  	p->addr = addr;
3a872d89b   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1265

1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1266
1267
1268
  	ret = check_kprobe_rereg(p);
  	if (ret)
  		return ret;
91bad2f8d   Jason Baron   jump label: Fix d...
1269
  	jump_label_lock();
de31c3ca8   Steven Rostedt   jump label: Fix e...
1270
  	preempt_disable();
ec30c5f3a   Masami Hiramatsu   kprobes: Use kern...
1271
  	if (!kernel_text_address((unsigned long) p->addr) ||
4554dbcb8   Masami Hiramatsu   kprobes: Check pr...
1272
  	    in_kprobes_functions((unsigned long) p->addr) ||
4c3ef6d79   Jason Baron   jump label: Add j...
1273
  	    ftrace_text_reserved(p->addr, p->addr) ||
de31c3ca8   Steven Rostedt   jump label: Fix e...
1274
1275
  	    jump_label_text_reserved(p->addr, p->addr))
  		goto fail_with_jump_label;
b3e55c727   Mao, Bibo   [PATCH] Kprobes: ...
1276

de5bd88d5   Masami Hiramatsu   kprobes: support ...
1277
1278
  	/* User can pass only KPROBE_FLAG_DISABLED to register_kprobe */
  	p->flags &= KPROBE_FLAG_DISABLED;
6f716acd5   Christoph Hellwig   kprobes: codingst...
1279
1280
1281
  	/*
  	 * Check if are we probing a module.
  	 */
a189d0350   Masami Hiramatsu   kprobes: disable ...
1282
  	probed_mod = __module_text_address((unsigned long) p->addr);
6f716acd5   Christoph Hellwig   kprobes: codingst...
1283
  	if (probed_mod) {
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1284
1285
  		/* Return -ENOENT if fail. */
  		ret = -ENOENT;
6f716acd5   Christoph Hellwig   kprobes: codingst...
1286
  		/*
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1287
1288
  		 * We must hold a refcount of the probed module while updating
  		 * its code to prohibit unexpected unloading.
df019b1d8   Keshavamurthy Anil S   [PATCH] kprobes: ...
1289
  		 */
de31c3ca8   Steven Rostedt   jump label: Fix e...
1290
1291
  		if (unlikely(!try_module_get(probed_mod)))
  			goto fail_with_jump_label;
f24659d96   Masami Hiramatsu   kprobes: support ...
1292
1293
1294
1295
1296
1297
1298
  		/*
  		 * If the module freed .init.text, we couldn't insert
  		 * kprobes in there.
  		 */
  		if (within_module_init((unsigned long)p->addr, probed_mod) &&
  		    probed_mod->state != MODULE_STATE_COMING) {
  			module_put(probed_mod);
de31c3ca8   Steven Rostedt   jump label: Fix e...
1299
  			goto fail_with_jump_label;
f24659d96   Masami Hiramatsu   kprobes: support ...
1300
  		}
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1301
  		/* ret will be updated by following code */
df019b1d8   Keshavamurthy Anil S   [PATCH] kprobes: ...
1302
  	}
a189d0350   Masami Hiramatsu   kprobes: disable ...
1303
  	preempt_enable();
de31c3ca8   Steven Rostedt   jump label: Fix e...
1304
  	jump_label_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1305

3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1306
  	p->nmissed = 0;
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1307
  	INIT_LIST_HEAD(&p->list);
7a7d1cf95   Ingo Molnar   [PATCH] sem2mutex...
1308
  	mutex_lock(&kprobe_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1309

91bad2f8d   Jason Baron   jump label: Fix d...
1310
  	jump_label_lock(); /* needed to call jump_label_text_reserved() */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1311
1312
  	get_online_cpus();	/* For avoiding text_mutex deadlock. */
  	mutex_lock(&text_mutex);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1313
1314
  	old_p = get_kprobe(p->addr);
  	if (old_p) {
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1315
  		/* Since this may unoptimize old_p, locking text_mutex. */
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1316
  		ret = register_aggr_kprobe(old_p, p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1317
1318
  		goto out;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1319

6f716acd5   Christoph Hellwig   kprobes: codingst...
1320
1321
  	ret = arch_prepare_kprobe(p);
  	if (ret)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1322
  		goto out;
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1323

64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1324
  	INIT_HLIST_NODE(&p->hlist);
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1325
  	hlist_add_head_rcu(&p->hlist,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1326
  		       &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1327
  	if (!kprobes_all_disarmed && !kprobe_disabled(p))
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1328
1329
1330
1331
  		__arm_kprobe(p);
  
  	/* Try to optimize kprobe */
  	try_to_optimize_kprobe(p);
74a0b5762   Christoph Hellwig   x86: optimize pag...
1332

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1333
  out:
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1334
1335
  	mutex_unlock(&text_mutex);
  	put_online_cpus();
91bad2f8d   Jason Baron   jump label: Fix d...
1336
  	jump_label_unlock();
7a7d1cf95   Ingo Molnar   [PATCH] sem2mutex...
1337
  	mutex_unlock(&kprobe_mutex);
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1338

e8386a0cb   Masami Hiramatsu   kprobes: support ...
1339
  	if (probed_mod)
df019b1d8   Keshavamurthy Anil S   [PATCH] kprobes: ...
1340
  		module_put(probed_mod);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1341

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1342
  	return ret;
de31c3ca8   Steven Rostedt   jump label: Fix e...
1343
1344
1345
1346
  
  fail_with_jump_label:
  	preempt_enable();
  	jump_label_unlock();
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1347
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1348
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1349
  EXPORT_SYMBOL_GPL(register_kprobe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1350

6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
  /* Check if all probes on the aggrprobe are disabled */
  static int __kprobes aggr_kprobe_disabled(struct kprobe *ap)
  {
  	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 */
  static struct kprobe *__kprobes __disable_kprobe(struct kprobe *p)
  {
  	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)) {
  			disarm_kprobe(orig_p);
  			orig_p->flags |= KPROBE_FLAG_DISABLED;
  		}
  	}
  
  	return orig_p;
  }
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1391
1392
1393
1394
1395
  /*
   * Unregister a kprobe without a scheduler synchronization.
   */
  static int __kprobes __unregister_kprobe_top(struct kprobe *p)
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1396
  	struct kprobe *ap, *list_p;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1397

6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1398
1399
  	/* Disable kprobe. This will disarm it if needed. */
  	ap = __disable_kprobe(p);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1400
  	if (ap == NULL)
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1401
  		return -EINVAL;
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1402
  	if (ap == p)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
1403
  		/*
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1404
1405
  		 * 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...
1406
  		 */
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1407
1408
1409
1410
  		goto disarmed;
  
  	/* Following process expects this probe is an aggrprobe */
  	WARN_ON(!kprobe_aggrprobe(ap));
6274de498   Masami Hiramatsu   kprobes: Support ...
1411
1412
1413
1414
1415
  	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 ...
1416
1417
1418
  		goto disarmed;
  	else {
  		/* If disabling probe has special handlers, update aggrprobe */
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1419
  		if (p->break_handler && !kprobe_gone(p))
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1420
  			ap->break_handler = NULL;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1421
  		if (p->post_handler && !kprobe_gone(p)) {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1422
  			list_for_each_entry_rcu(list_p, &ap->list, list) {
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1423
1424
1425
  				if ((list_p != p) && (list_p->post_handler))
  					goto noclean;
  			}
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1426
  			ap->post_handler = NULL;
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1427
1428
  		}
  noclean:
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1429
1430
1431
1432
  		/*
  		 * Remove from the aggrprobe: this path will do nothing in
  		 * __unregister_kprobe_bottom().
  		 */
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1433
  		list_del_rcu(&p->list);
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1434
1435
1436
1437
1438
1439
  		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: ...
1440
  	}
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1441
  	return 0;
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1442
1443
  
  disarmed:
6274de498   Masami Hiramatsu   kprobes: Support ...
1444
  	BUG_ON(!kprobe_disarmed(ap));
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1445
1446
  	hlist_del_rcu(&ap->hlist);
  	return 0;
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1447
  }
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1448

9861668f7   Masami Hiramatsu   kprobes: add (un)...
1449
1450
  static void __kprobes __unregister_kprobe_bottom(struct kprobe *p)
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1451
  	struct kprobe *ap;
b3e55c727   Mao, Bibo   [PATCH] Kprobes: ...
1452

e8386a0cb   Masami Hiramatsu   kprobes: support ...
1453
  	if (list_empty(&p->list))
6274de498   Masami Hiramatsu   kprobes: Support ...
1454
  		/* This is an independent kprobe */
0498b6350   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1455
  		arch_remove_kprobe(p);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1456
  	else if (list_is_singular(&p->list)) {
6274de498   Masami Hiramatsu   kprobes: Support ...
1457
  		/* This is the last child of an aggrprobe */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1458
  		ap = list_entry(p->list.next, struct kprobe, list);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1459
  		list_del(&p->list);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1460
  		free_aggr_kprobe(ap);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1461
  	}
6274de498   Masami Hiramatsu   kprobes: Support ...
1462
  	/* Otherwise, do nothing. */
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1463
  }
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1464
  int __kprobes register_kprobes(struct kprobe **kps, int num)
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1465
1466
1467
1468
1469
1470
  {
  	int i, ret = 0;
  
  	if (num <= 0)
  		return -EINVAL;
  	for (i = 0; i < num; i++) {
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1471
  		ret = register_kprobe(kps[i]);
67dddaad5   Masami Hiramatsu   kprobes: fix erro...
1472
1473
1474
  		if (ret < 0) {
  			if (i > 0)
  				unregister_kprobes(kps, i);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1475
  			break;
367216567   mao, bibo   [PATCH] Kprobe: m...
1476
  		}
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1477
  	}
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1478
1479
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1480
  EXPORT_SYMBOL_GPL(register_kprobes);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1481

9861668f7   Masami Hiramatsu   kprobes: add (un)...
1482
1483
1484
1485
  void __kprobes unregister_kprobe(struct kprobe *p)
  {
  	unregister_kprobes(&p, 1);
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1486
  EXPORT_SYMBOL_GPL(unregister_kprobe);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1487

9861668f7   Masami Hiramatsu   kprobes: add (un)...
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
  void __kprobes unregister_kprobes(struct kprobe **kps, int num)
  {
  	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
1504
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1505
  EXPORT_SYMBOL_GPL(unregister_kprobes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1506
1507
1508
  
  static struct notifier_block kprobe_exceptions_nb = {
  	.notifier_call = kprobe_exceptions_notify,
3d5631e06   Anil S Keshavamurthy   [PATCH] Kprobes r...
1509
1510
  	.priority = 0x7fffffff /* we need to be notified first */
  };
3d7e33825   Michael Ellerman   jprobes: make jpr...
1511
1512
1513
1514
  unsigned long __weak arch_deref_entry_point(void *entry)
  {
  	return (unsigned long)entry;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1515

49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1516
  int __kprobes register_jprobes(struct jprobe **jps, int num)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1517
  {
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1518
1519
  	struct jprobe *jp;
  	int ret = 0, i;
3d7e33825   Michael Ellerman   jprobes: make jpr...
1520

26b31c190   Masami Hiramatsu   kprobes: add (un)...
1521
  	if (num <= 0)
3d7e33825   Michael Ellerman   jprobes: make jpr...
1522
  		return -EINVAL;
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1523
  	for (i = 0; i < num; i++) {
05662bdb6   Namhyung Kim   kprobes: Verify j...
1524
  		unsigned long addr, offset;
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1525
1526
  		jp = jps[i];
  		addr = arch_deref_entry_point(jp->entry);
05662bdb6   Namhyung Kim   kprobes: Verify j...
1527
1528
1529
1530
1531
1532
1533
1534
  		/* Verify probepoint is a function entry point */
  		if (kallsyms_lookup_size_offset(addr, NULL, &offset) &&
  		    offset == 0) {
  			jp->kp.pre_handler = setjmp_pre_handler;
  			jp->kp.break_handler = longjmp_break_handler;
  			ret = register_kprobe(&jp->kp);
  		} else
  			ret = -EINVAL;
edbaadbe4   Namhyung Kim   kprobes: Remove r...
1535

67dddaad5   Masami Hiramatsu   kprobes: fix erro...
1536
1537
1538
  		if (ret < 0) {
  			if (i > 0)
  				unregister_jprobes(jps, i);
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1539
1540
1541
1542
1543
  			break;
  		}
  	}
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1544
  EXPORT_SYMBOL_GPL(register_jprobes);
3d7e33825   Michael Ellerman   jprobes: make jpr...
1545

26b31c190   Masami Hiramatsu   kprobes: add (un)...
1546
1547
  int __kprobes register_jprobe(struct jprobe *jp)
  {
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1548
  	return register_jprobes(&jp, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1549
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1550
  EXPORT_SYMBOL_GPL(register_jprobe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1551

d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1552
  void __kprobes unregister_jprobe(struct jprobe *jp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1553
  {
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1554
1555
  	unregister_jprobes(&jp, 1);
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1556
  EXPORT_SYMBOL_GPL(unregister_jprobe);
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1557

26b31c190   Masami Hiramatsu   kprobes: add (un)...
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
  void __kprobes unregister_jprobes(struct jprobe **jps, int num)
  {
  	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
1575
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1576
  EXPORT_SYMBOL_GPL(unregister_jprobes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1577

9edddaa20   Ananth N Mavinakayanahalli   Kprobes: indicate...
1578
  #ifdef CONFIG_KRETPROBES
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1579
1580
1581
1582
1583
1584
1585
1586
  /*
   * This kprobe pre_handler is registered with every kretprobe. When probe
   * hits it will set up the return probe.
   */
  static int __kprobes pre_handler_kretprobe(struct kprobe *p,
  					   struct pt_regs *regs)
  {
  	struct kretprobe *rp = container_of(p, struct kretprobe, kp);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1587
1588
  	unsigned long hash, flags = 0;
  	struct kretprobe_instance *ri;
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1589
1590
  
  	/*TODO: consider to only swap the RA after the last pre_handler fired */
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1591
1592
  	hash = hash_ptr(current, KPROBE_HASH_BITS);
  	spin_lock_irqsave(&rp->lock, flags);
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1593
  	if (!hlist_empty(&rp->free_instances)) {
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1594
  		ri = hlist_entry(rp->free_instances.first,
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1595
1596
1597
  				struct kretprobe_instance, hlist);
  		hlist_del(&ri->hlist);
  		spin_unlock_irqrestore(&rp->lock, flags);
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1598
1599
  		ri->rp = rp;
  		ri->task = current;
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1600

f02b8624f   Ananth N Mavinakayanahalli   kprobes: Fix lock...
1601
  		if (rp->entry_handler && rp->entry_handler(ri, regs))
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1602
  			return 0;
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1603

4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1604
1605
1606
  		arch_prepare_kretprobe(ri, regs);
  
  		/* XXX(hch): why is there no hlist_move_head? */
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1607
1608
1609
1610
1611
  		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...
1612
  		rp->nmissed++;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1613
1614
  		spin_unlock_irqrestore(&rp->lock, flags);
  	}
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1615
1616
  	return 0;
  }
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1617
  int __kprobes register_kretprobe(struct kretprobe *rp)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1618
1619
1620
1621
  {
  	int ret = 0;
  	struct kretprobe_instance *inst;
  	int i;
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1622
  	void *addr;
f438d914b   Masami Hiramatsu   kprobes: support ...
1623
1624
  
  	if (kretprobe_blacklist_size) {
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1625
  		addr = kprobe_addr(&rp->kp);
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1626
1627
  		if (IS_ERR(addr))
  			return PTR_ERR(addr);
f438d914b   Masami Hiramatsu   kprobes: support ...
1628
1629
1630
1631
1632
1633
  
  		for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
  			if (kretprobe_blacklist[i].addr == addr)
  				return -EINVAL;
  		}
  	}
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1634
1635
  
  	rp->kp.pre_handler = pre_handler_kretprobe;
7522a8423   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1636
1637
1638
  	rp->kp.post_handler = NULL;
  	rp->kp.fault_handler = NULL;
  	rp->kp.break_handler = NULL;
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1639
1640
1641
1642
  
  	/* Pre-allocate memory for max kretprobe instances */
  	if (rp->maxactive <= 0) {
  #ifdef CONFIG_PREEMPT
c2ef6661c   Heiko Carstens   kprobes: Fix dist...
1643
  		rp->maxactive = max_t(unsigned int, 10, 2*num_possible_cpus());
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1644
  #else
4dae560f9   Ananth N Mavinakayanahalli   kprobes: Sanitize...
1645
  		rp->maxactive = num_possible_cpus();
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1646
1647
  #endif
  	}
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1648
  	spin_lock_init(&rp->lock);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1649
1650
  	INIT_HLIST_HEAD(&rp->free_instances);
  	for (i = 0; i < rp->maxactive; i++) {
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1651
1652
  		inst = kmalloc(sizeof(struct kretprobe_instance) +
  			       rp->data_size, GFP_KERNEL);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1653
1654
1655
1656
  		if (inst == NULL) {
  			free_rp_inst(rp);
  			return -ENOMEM;
  		}
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1657
1658
  		INIT_HLIST_NODE(&inst->hlist);
  		hlist_add_head(&inst->hlist, &rp->free_instances);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1659
1660
1661
1662
  	}
  
  	rp->nmissed = 0;
  	/* Establish function entry probe point */
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1663
  	ret = register_kprobe(&rp->kp);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1664
  	if (ret != 0)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1665
1666
1667
  		free_rp_inst(rp);
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1668
  EXPORT_SYMBOL_GPL(register_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1669

49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1670
  int __kprobes register_kretprobes(struct kretprobe **rps, int num)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1671
1672
1673
1674
1675
1676
  {
  	int ret = 0, i;
  
  	if (num <= 0)
  		return -EINVAL;
  	for (i = 0; i < num; i++) {
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1677
  		ret = register_kretprobe(rps[i]);
67dddaad5   Masami Hiramatsu   kprobes: fix erro...
1678
1679
1680
  		if (ret < 0) {
  			if (i > 0)
  				unregister_kretprobes(rps, i);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1681
1682
1683
1684
1685
  			break;
  		}
  	}
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1686
  EXPORT_SYMBOL_GPL(register_kretprobes);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1687

4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1688
1689
1690
1691
  void __kprobes unregister_kretprobe(struct kretprobe *rp)
  {
  	unregister_kretprobes(&rp, 1);
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1692
  EXPORT_SYMBOL_GPL(unregister_kretprobe);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1693

4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
  void __kprobes unregister_kretprobes(struct kretprobe **rps, int num)
  {
  	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...
1714
  EXPORT_SYMBOL_GPL(unregister_kretprobes);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1715

9edddaa20   Ananth N Mavinakayanahalli   Kprobes: indicate...
1716
  #else /* CONFIG_KRETPROBES */
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1717
  int __kprobes register_kretprobe(struct kretprobe *rp)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1718
1719
1720
  {
  	return -ENOSYS;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1721
  EXPORT_SYMBOL_GPL(register_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1722

4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1723
  int __kprobes register_kretprobes(struct kretprobe **rps, int num)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
1724
  {
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1725
  	return -ENOSYS;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
1726
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1727
  EXPORT_SYMBOL_GPL(register_kretprobes);
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1728
  void __kprobes unregister_kretprobe(struct kretprobe *rp)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1729
  {
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1730
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1731
  EXPORT_SYMBOL_GPL(unregister_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1732

4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1733
1734
1735
  void __kprobes unregister_kretprobes(struct kretprobe **rps, int num)
  {
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1736
  EXPORT_SYMBOL_GPL(unregister_kretprobes);
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1737

4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1738
1739
1740
1741
  static int __kprobes pre_handler_kretprobe(struct kprobe *p,
  					   struct pt_regs *regs)
  {
  	return 0;
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1742
  }
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1743
  #endif /* CONFIG_KRETPROBES */
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1744
1745
1746
1747
  /* Set the kprobe gone and remove its instruction buffer. */
  static void __kprobes kill_kprobe(struct kprobe *p)
  {
  	struct kprobe *kp;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1748

e8386a0cb   Masami Hiramatsu   kprobes: support ...
1749
  	p->flags |= KPROBE_FLAG_GONE;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1750
  	if (kprobe_aggrprobe(p)) {
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1751
1752
1753
1754
1755
1756
1757
1758
  		/*
  		 * 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...
1759
  		kill_optimized_kprobe(p);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1760
1761
1762
1763
1764
1765
1766
  	}
  	/*
  	 * 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...
1767
1768
1769
1770
  /* Disable one kprobe */
  int __kprobes disable_kprobe(struct kprobe *kp)
  {
  	int ret = 0;
c0614829c   Masami Hiramatsu   kprobes: Move ena...
1771
1772
  
  	mutex_lock(&kprobe_mutex);
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1773
1774
  	/* Disable this kprobe */
  	if (__disable_kprobe(kp) == NULL)
c0614829c   Masami Hiramatsu   kprobes: Move ena...
1775
  		ret = -EINVAL;
c0614829c   Masami Hiramatsu   kprobes: Move ena...
1776

c0614829c   Masami Hiramatsu   kprobes: Move ena...
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
  	mutex_unlock(&kprobe_mutex);
  	return ret;
  }
  EXPORT_SYMBOL_GPL(disable_kprobe);
  
  /* Enable one kprobe */
  int __kprobes enable_kprobe(struct kprobe *kp)
  {
  	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);
24851d244   Frederic Weisbecker   tracing/kprobes: ...
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
  void __kprobes dump_kprobe(struct kprobe *kp)
  {
  	printk(KERN_WARNING "Dumping kprobe:
  ");
  	printk(KERN_WARNING "Name: %s
  Address: %p
  Offset: %x
  ",
  	       kp->symbol_name, kp->addr, kp->offset);
  }
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1825
1826
1827
1828
1829
1830
1831
1832
1833
  /* Module notifier call back, checking kprobes on the module */
  static int __kprobes kprobes_module_callback(struct notifier_block *nb,
  					     unsigned long val, void *data)
  {
  	struct module *mod = data;
  	struct hlist_head *head;
  	struct hlist_node *node;
  	struct kprobe *p;
  	unsigned int i;
f24659d96   Masami Hiramatsu   kprobes: support ...
1834
  	int checkcore = (val == MODULE_STATE_GOING);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1835

f24659d96   Masami Hiramatsu   kprobes: support ...
1836
  	if (val != MODULE_STATE_GOING && val != MODULE_STATE_LIVE)
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1837
1838
1839
  		return NOTIFY_DONE;
  
  	/*
f24659d96   Masami Hiramatsu   kprobes: support ...
1840
1841
1842
1843
  	 * 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 ...
1844
1845
1846
1847
1848
  	 */
  	mutex_lock(&kprobe_mutex);
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
  		hlist_for_each_entry_rcu(p, node, head, hlist)
f24659d96   Masami Hiramatsu   kprobes: support ...
1849
1850
1851
  			if (within_module_init((unsigned long)p->addr, mod) ||
  			    (checkcore &&
  			     within_module_core((unsigned long)p->addr, mod))) {
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
  				/*
  				 * The vaddr this probe is installed will soon
  				 * be vfreed buy not synced to disk. Hence,
  				 * disarming the breakpoint isn't needed.
  				 */
  				kill_kprobe(p);
  			}
  	}
  	mutex_unlock(&kprobe_mutex);
  	return NOTIFY_DONE;
  }
  
  static struct notifier_block kprobe_module_nb = {
  	.notifier_call = kprobes_module_callback,
  	.priority = 0
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1868
1869
1870
  static int __init init_kprobes(void)
  {
  	int i, err = 0;
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
1871
1872
1873
1874
1875
  	unsigned long offset = 0, size = 0;
  	char *modname, namebuf[128];
  	const char *symbol_name;
  	void *addr;
  	struct kprobe_blackpoint *kb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1876
1877
1878
  
  	/* FIXME allocate the probe table, currently defined statically */
  	/* initialize all list heads */
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1879
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1880
  		INIT_HLIST_HEAD(&kprobe_table[i]);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1881
  		INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1882
  		spin_lock_init(&(kretprobe_table_locks[i].lock));
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1883
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1884

3d8d996e0   Srinivasa Ds   kprobes: prevent ...
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
  	/*
  	 * 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.
  	 */
  	for (kb = kprobe_blacklist; kb->name != NULL; kb++) {
  		kprobe_lookup_name(kb->name, addr);
  		if (!addr)
  			continue;
  
  		kb->start_addr = (unsigned long)addr;
  		symbol_name = kallsyms_lookup(kb->start_addr,
  				&size, &offset, &modname, namebuf);
  		if (!symbol_name)
  			kb->range = 0;
  		else
  			kb->range = size;
  	}
f438d914b   Masami Hiramatsu   kprobes: support ...
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
  	if (kretprobe_blacklist_size) {
  		/* lookup the function address from its name */
  		for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
  			kprobe_lookup_name(kretprobe_blacklist[i].name,
  					   kretprobe_blacklist[i].addr);
  			if (!kretprobe_blacklist[i].addr)
  				printk("kretprobe: lookup failed: %s
  ",
  				       kretprobe_blacklist[i].name);
  		}
  	}
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
1917
1918
  #if defined(CONFIG_OPTPROBES)
  #if defined(__ARCH_WANT_KPROBES_INSN_SLOT)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1919
1920
1921
  	/* Init kprobe_optinsn_slots */
  	kprobe_optinsn_slots.insn_size = MAX_OPTINSN_SIZE;
  #endif
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
1922
1923
1924
  	/* By default, kprobes can be optimized */
  	kprobes_allow_optimization = true;
  #endif
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1925

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

6772926be   Rusty Lynch   [PATCH] kprobes: ...
1929
  	err = arch_init_kprobes();
802eae7c8   Rusty Lynch   [PATCH] Return pr...
1930
1931
  	if (!err)
  		err = register_die_notifier(&kprobe_exceptions_nb);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1932
1933
  	if (!err)
  		err = register_module_notifier(&kprobe_module_nb);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1934
  	kprobes_initialized = (err == 0);
802eae7c8   Rusty Lynch   [PATCH] Return pr...
1935

8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
1936
1937
  	if (!err)
  		init_test_probes();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1938
1939
  	return err;
  }
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
1940
1941
  #ifdef CONFIG_DEBUG_FS
  static void __kprobes report_probe(struct seq_file *pi, struct kprobe *p,
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1942
  		const char *sym, int offset, char *modname, struct kprobe *pp)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
1943
1944
1945
1946
1947
1948
1949
1950
1951
  {
  	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...
1952

346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
1953
  	if (sym)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1954
  		seq_printf(pi, "%p  %s  %s+0x%x  %s ",
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1955
  			p->addr, kprobe_type, sym, offset,
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1956
  			(modname ? modname : " "));
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
1957
  	else
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
  		seq_printf(pi, "%p  %s  %p ",
  			p->addr, kprobe_type, p->addr);
  
  	if (!pp)
  		pp = p;
  	seq_printf(pi, "%s%s%s
  ",
  		(kprobe_gone(p) ? "[GONE]" : ""),
  		((kprobe_disabled(p) && !kprobe_gone(p)) ?  "[DISABLED]" : ""),
  		(kprobe_optimized(pp) ? "[OPTIMIZED]" : ""));
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
  }
  
  static void __kprobes *kprobe_seq_start(struct seq_file *f, loff_t *pos)
  {
  	return (*pos < KPROBE_TABLE_SIZE) ? pos : NULL;
  }
  
  static void __kprobes *kprobe_seq_next(struct seq_file *f, void *v, loff_t *pos)
  {
  	(*pos)++;
  	if (*pos >= KPROBE_TABLE_SIZE)
  		return NULL;
  	return pos;
  }
  
  static void __kprobes kprobe_seq_stop(struct seq_file *f, void *v)
  {
  	/* Nothing to do */
  }
  
  static int __kprobes show_kprobe_addr(struct seq_file *pi, void *v)
  {
  	struct hlist_head *head;
  	struct hlist_node *node;
  	struct kprobe *p, *kp;
  	const char *sym = NULL;
  	unsigned int i = *(loff_t *) v;
ffb451227   Alexey Dobriyan   Simplify kallsyms...
1995
  	unsigned long offset = 0;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
1996
1997
1998
1999
2000
  	char *modname, namebuf[128];
  
  	head = &kprobe_table[i];
  	preempt_disable();
  	hlist_for_each_entry_rcu(p, node, head, hlist) {
ffb451227   Alexey Dobriyan   Simplify kallsyms...
2001
  		sym = kallsyms_lookup((unsigned long)p->addr, NULL,
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2002
  					&offset, &modname, namebuf);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2003
  		if (kprobe_aggrprobe(p)) {
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2004
  			list_for_each_entry_rcu(kp, &p->list, list)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2005
  				report_probe(pi, kp, sym, offset, modname, p);
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2006
  		} else
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2007
  			report_probe(pi, p, sym, offset, modname, NULL);
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2008
2009
2010
2011
  	}
  	preempt_enable();
  	return 0;
  }
88e9d34c7   James Morris   seq_file: constif...
2012
  static const struct seq_operations kprobes_seq_ops = {
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
  	.start = kprobe_seq_start,
  	.next  = kprobe_seq_next,
  	.stop  = kprobe_seq_stop,
  	.show  = show_kprobe_addr
  };
  
  static int __kprobes kprobes_open(struct inode *inode, struct file *filp)
  {
  	return seq_open(filp, &kprobes_seq_ops);
  }
828c09509   Alexey Dobriyan   const: constify r...
2023
  static const struct file_operations debugfs_kprobes_operations = {
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2024
2025
2026
2027
2028
  	.open           = kprobes_open,
  	.read           = seq_read,
  	.llseek         = seq_lseek,
  	.release        = seq_release,
  };
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2029
  static void __kprobes arm_all_kprobes(void)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2030
2031
2032
2033
2034
2035
2036
  {
  	struct hlist_head *head;
  	struct hlist_node *node;
  	struct kprobe *p;
  	unsigned int i;
  
  	mutex_lock(&kprobe_mutex);
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2037
2038
  	/* If kprobes are armed, just return */
  	if (!kprobes_all_disarmed)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2039
  		goto already_enabled;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2040
  	/* Arming kprobes doesn't optimize kprobe itself */
4460fdad8   Mathieu Desnoyers   tracing, Text Edi...
2041
  	mutex_lock(&text_mutex);
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2042
2043
2044
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
  		hlist_for_each_entry_rcu(p, node, head, hlist)
de5bd88d5   Masami Hiramatsu   kprobes: support ...
2045
  			if (!kprobe_disabled(p))
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2046
  				__arm_kprobe(p);
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2047
  	}
4460fdad8   Mathieu Desnoyers   tracing, Text Edi...
2048
  	mutex_unlock(&text_mutex);
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2049

e579abeb5   Masami Hiramatsu   kprobes: rename k...
2050
  	kprobes_all_disarmed = false;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2051
2052
2053
2054
2055
2056
2057
  	printk(KERN_INFO "Kprobes globally enabled
  ");
  
  already_enabled:
  	mutex_unlock(&kprobe_mutex);
  	return;
  }
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2058
  static void __kprobes disarm_all_kprobes(void)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2059
2060
2061
2062
2063
2064
2065
  {
  	struct hlist_head *head;
  	struct hlist_node *node;
  	struct kprobe *p;
  	unsigned int i;
  
  	mutex_lock(&kprobe_mutex);
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2066
  	/* If kprobes are already disarmed, just return */
6274de498   Masami Hiramatsu   kprobes: Support ...
2067
2068
2069
2070
  	if (kprobes_all_disarmed) {
  		mutex_unlock(&kprobe_mutex);
  		return;
  	}
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2071

e579abeb5   Masami Hiramatsu   kprobes: rename k...
2072
  	kprobes_all_disarmed = true;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2073
2074
  	printk(KERN_INFO "Kprobes globally disabled
  ");
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2075

4460fdad8   Mathieu Desnoyers   tracing, Text Edi...
2076
  	mutex_lock(&text_mutex);
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2077
2078
2079
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
  		hlist_for_each_entry_rcu(p, node, head, hlist) {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
2080
  			if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p))
6274de498   Masami Hiramatsu   kprobes: Support ...
2081
  				__disarm_kprobe(p, false);
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2082
2083
  		}
  	}
4460fdad8   Mathieu Desnoyers   tracing, Text Edi...
2084
  	mutex_unlock(&text_mutex);
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2085
  	mutex_unlock(&kprobe_mutex);
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2086

6274de498   Masami Hiramatsu   kprobes: Support ...
2087
2088
  	/* Wait for disarming all kprobes by optimizer */
  	wait_for_kprobe_optimizer();
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
  }
  
  /*
   * 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...
2100
  	if (!kprobes_all_disarmed)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
  		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];
  	int buf_size;
  
  	buf_size = min(count, (sizeof(buf)-1));
  	if (copy_from_user(buf, user_buf, buf_size))
  		return -EFAULT;
  
  	switch (buf[0]) {
  	case 'y':
  	case 'Y':
  	case '1':
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2124
  		arm_all_kprobes();
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2125
2126
2127
2128
  		break;
  	case 'n':
  	case 'N':
  	case '0':
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2129
  		disarm_all_kprobes();
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2130
2131
2132
2133
2134
  		break;
  	}
  
  	return count;
  }
828c09509   Alexey Dobriyan   const: constify r...
2135
  static const struct file_operations fops_kp = {
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2136
2137
  	.read =         read_enabled_file_bool,
  	.write =        write_enabled_file_bool,
6038f373a   Arnd Bergmann   llseek: automatic...
2138
  	.llseek =	default_llseek,
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2139
  };
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2140
2141
2142
  static int __kprobes debugfs_kprobe_init(void)
  {
  	struct dentry *dir, *file;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2143
  	unsigned int value = 1;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2144
2145
2146
2147
  
  	dir = debugfs_create_dir("kprobes", NULL);
  	if (!dir)
  		return -ENOMEM;
e38697929   Randy Dunlap   kprobes: fix spar...
2148
  	file = debugfs_create_file("list", 0444, dir, NULL,
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2149
2150
2151
2152
2153
  				&debugfs_kprobes_operations);
  	if (!file) {
  		debugfs_remove(dir);
  		return -ENOMEM;
  	}
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2154
2155
2156
2157
2158
2159
  	file = debugfs_create_file("enabled", 0600, dir,
  					&value, &fops_kp);
  	if (!file) {
  		debugfs_remove(dir);
  		return -ENOMEM;
  	}
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2160
2161
2162
2163
2164
2165
2166
  	return 0;
  }
  
  late_initcall(debugfs_kprobe_init);
  #endif /* CONFIG_DEBUG_FS */
  
  module_init(init_kprobes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2167

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