Blame view

kernel/kprobes.c 56.3 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  /*
   *  Kernel Probes (KProbes)
   *  kernel/kprobes.c
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   *
   * Copyright (C) IBM Corporation, 2002, 2004
   *
   * 2002-Oct	Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel
   *		Probes initial implementation (includes suggestions from
   *		Rusty Russell).
   * 2004-Aug	Updated by Prasanna S Panchamukhi <prasanna@in.ibm.com> with
   *		hlists and exceptions notifier as suggested by Andi Kleen.
   * 2004-July	Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
   *		interface to access function arguments.
   * 2004-Sep	Prasanna S Panchamukhi <prasanna@in.ibm.com> Changed Kprobes
   *		exceptions notifier to be first on the priority list.
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
30
31
32
   * 2005-May	Hien Nguyen <hien@us.ibm.com>, Jim Keniston
   *		<jkenisto@us.ibm.com> and Prasanna S Panchamukhi
   *		<prasanna@in.ibm.com> added function-return probes.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
34
   */
  #include <linux/kprobes.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
36
  #include <linux/hash.h>
  #include <linux/init.h>
4e57b6817   Tim Schmielau   [PATCH] fix missi...
37
  #include <linux/slab.h>
e38697929   Randy Dunlap   kprobes: fix spar...
38
  #include <linux/stddef.h>
9984de1a5   Paul Gortmaker   kernel: Map most ...
39
  #include <linux/export.h>
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
40
  #include <linux/moduleloader.h>
3a872d89b   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
41
  #include <linux/kallsyms.h>
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
42
  #include <linux/freezer.h>
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
43
44
  #include <linux/seq_file.h>
  #include <linux/debugfs.h>
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
45
  #include <linux/sysctl.h>
1eeb66a1b   Christoph Hellwig   move die notifier...
46
  #include <linux/kdebug.h>
4460fdad8   Mathieu Desnoyers   tracing, Text Edi...
47
  #include <linux/memory.h>
4554dbcb8   Masami Hiramatsu   kprobes: Check pr...
48
  #include <linux/ftrace.h>
afd66255b   Masami Hiramatsu   kprobes: Introduc...
49
  #include <linux/cpu.h>
bf5438fca   Jason Baron   jump label: Base ...
50
  #include <linux/jump_label.h>
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
51

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 {
ec484608c   Thomas Gleixner   locking, kprobes:...
79
  	raw_spinlock_t lock ____cacheline_aligned_in_smp;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
80
  } kretprobe_table_locks[KPROBE_TABLE_SIZE];
ec484608c   Thomas Gleixner   locking, kprobes:...
81
  static raw_spinlock_t *kretprobe_table_lock_ptr(unsigned long hash)
ef53d9c5e   Srinivasa D S   kprobes: improve ...
82
83
84
  {
  	return &(kretprobe_table_locks[hash].lock);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85

3d8d996e0   Srinivasa Ds   kprobes: prevent ...
86
87
88
89
90
91
92
  /*
   * 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:...
93
  static struct kprobe_blackpoint kprobe_blacklist[] = {
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
94
  	{"preempt_schedule",},
65e234ec2   Masami Hiramatsu   kprobes: Prohibit...
95
  	{"native_get_debugreg",},
a00e817f4   Masami Hiramatsu   kprobes/x86-32: M...
96
97
  	{"irq_entries_start",},
  	{"common_interrupt",},
5ecaafdbf   Masami Hiramatsu   kprobes: Add mcou...
98
  	{"mcount",},	/* mcount can be called from everywhere */
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
99
100
  	{NULL}    /* Terminator */
  };
2d14e39da   Anil S Keshavamurthy   [PATCH] kprobes: ...
101
  #ifdef __ARCH_WANT_KPROBES_INSN_SLOT
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
102
103
104
105
106
107
  /*
   * 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: ...
108
  struct kprobe_insn_page {
c5cb5a2d8   Masami Hiramatsu   kprobes: Clean up...
109
  	struct list_head list;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
110
  	kprobe_opcode_t *insns;		/* Page of instruction slots */
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
111
  	int nused;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
112
  	int ngarbage;
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
113
  	char slot_used[];
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
114
  };
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
115
116
117
118
119
120
121
122
123
124
125
126
127
128
  #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: ...
129
130
131
132
133
  enum kprobe_slot_state {
  	SLOT_CLEAN = 0,
  	SLOT_DIRTY = 1,
  	SLOT_USED = 2,
  };
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
134
135
136
137
138
139
140
  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: ...
141

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

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

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

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

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

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

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

4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
269
270
271
272
  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...
273
  	mutex_unlock(&kprobe_insn_mutex);
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
274
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
275
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
  #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: ...
302
  #endif
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
303

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
332
333
  	return NULL;
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
334
335
336
337
338
339
340
  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 ...
341
342
343
344
345
346
  /* 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...
347
348
349
  /*
   * Keep all fields in the kprobe consistent
   */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
350
  static inline void copy_kprobe(struct kprobe *ap, struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
351
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
352
353
  	memcpy(&p->opcode, &ap->opcode, sizeof(kprobe_opcode_t));
  	memcpy(&p->ainsn, &ap->ainsn, sizeof(struct arch_specific_insn));
afd66255b   Masami Hiramatsu   kprobes: Introduc...
354
355
356
  }
  
  #ifdef CONFIG_OPTPROBES
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
357
358
  /* NOTE: change this value only with kprobe_mutex held */
  static bool kprobes_allow_optimization;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
  /*
   * 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 ...
375
376
377
378
379
380
381
382
383
384
  /* 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...
385
386
387
388
389
390
391
392
393
394
395
396
  /* 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 ...
397
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
  /* 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...
423
424
425
426
  /*
   * Return an optimized kprobe whose optimizing code replaces
   * instructions including addr (exclude breakpoint).
   */
6376b2297   Namhyung Kim   kprobes: Make fun...
427
  static struct kprobe *__kprobes get_optimized_kprobe(unsigned long addr)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
  {
  	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 ...
448
  static LIST_HEAD(unoptimizing_list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
449
450
451
  
  static void kprobe_optimizer(struct work_struct *work);
  static DECLARE_DELAYED_WORK(optimizing_work, kprobe_optimizer);
6274de498   Masami Hiramatsu   kprobes: Support ...
452
  static DECLARE_COMPLETION(optimizer_comp);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
453
  #define OPTIMIZE_DELAY 5
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
454
455
456
457
458
  /*
   * Optimize (replace a breakpoint with a jump) kprobes listed on
   * optimizing_list.
   */
  static __kprobes void do_optimize_kprobes(void)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
459
  {
6274de498   Masami Hiramatsu   kprobes: Support ...
460
461
462
463
  	/* Optimization never be done when disarmed */
  	if (kprobes_all_disarmed || !kprobes_allow_optimization ||
  	    list_empty(&optimizing_list))
  		return;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
464
465
466
467
468
469
470
471
472
473
474
475
  	/*
  	 * 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...
476
  	arch_optimize_kprobes(&optimizing_list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
477
478
  	mutex_unlock(&text_mutex);
  	put_online_cpus();
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
479
  }
6274de498   Masami Hiramatsu   kprobes: Support ...
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
  /*
   * 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...
495
496
497
  	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 ...
498
499
500
501
502
503
504
505
506
507
  		/* 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 ...
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
  		} 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...
533
534
535
  /* Kprobe jump optimizer */
  static __kprobes void kprobe_optimizer(struct work_struct *work)
  {
6274de498   Masami Hiramatsu   kprobes: Support ...
536
  	LIST_HEAD(free_list);
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
537
538
539
  	/* Lock modules while optimizing kprobes */
  	mutex_lock(&module_mutex);
  	mutex_lock(&kprobe_mutex);
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
540
541
  
  	/*
6274de498   Masami Hiramatsu   kprobes: Support ...
542
543
544
545
546
547
548
  	 * 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...
549
550
551
552
553
554
  	 * 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 ...
555
  	/* Step 3: Optimize kprobes after quiesence period */
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
556
  	do_optimize_kprobes();
6274de498   Masami Hiramatsu   kprobes: Support ...
557
558
559
  
  	/* Step 4: Free cleaned kprobes after quiesence period */
  	do_free_cleaned_kprobes(&free_list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
560
561
  	mutex_unlock(&kprobe_mutex);
  	mutex_unlock(&module_mutex);
6274de498   Masami Hiramatsu   kprobes: Support ...
562

cd7ebe229   Masami Hiramatsu   kprobes: Use text...
563
  	/* Step 5: Kick optimizer again if needed */
f984ba4eb   Masami Hiramatsu   kprobes: Use text...
564
  	if (!list_empty(&optimizing_list) || !list_empty(&unoptimizing_list))
cd7ebe229   Masami Hiramatsu   kprobes: Use text...
565
566
567
568
  		kick_kprobe_optimizer();
  	else
  		/* Wake up all waiters */
  		complete_all(&optimizer_comp);
6274de498   Masami Hiramatsu   kprobes: Support ...
569
570
571
572
573
574
575
  }
  
  /* 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...
576
577
578
579
580
581
582
583
  }
  
  /* 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...
584
  	if (!kprobe_optready(p) || !kprobes_allow_optimization ||
afd66255b   Masami Hiramatsu   kprobes: Introduc...
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
  	    (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...
601
  	op->kp.flags |= KPROBE_FLAG_OPTIMIZED;
6274de498   Masami Hiramatsu   kprobes: Support ...
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
  
  	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...
620
621
622
  }
  
  /* Unoptimize a kprobe if p is optimized */
6274de498   Masami Hiramatsu   kprobes: Support ...
623
  static __kprobes void unoptimize_kprobe(struct kprobe *p, bool force)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
624
625
  {
  	struct optimized_kprobe *op;
6274de498   Masami Hiramatsu   kprobes: Support ...
626
627
628
629
630
631
632
633
634
635
636
637
  	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...
638
  			list_del_init(&op->list);
6274de498   Masami Hiramatsu   kprobes: Support ...
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
  			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...
657
658
  	}
  }
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
  /* 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...
680
681
682
683
684
685
  /* 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 ...
686
687
  	if (!list_empty(&op->list))
  		/* Dequeue from the (un)optimization queue */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
688
  		list_del_init(&op->list);
6274de498   Masami Hiramatsu   kprobes: Support ...
689
690
691
  
  	op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
  	/* Don't touch the code, because it is already freed. */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
692
693
694
695
696
697
698
699
700
701
702
  	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...
703
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
  /* 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 ...
737
738
  		arch_remove_optimized_kprobe(op);
  		kfree(op);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
739
740
741
742
743
744
  		return;
  	}
  
  	init_aggr_kprobe(ap, p);
  	optimize_kprobe(ap);
  }
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
745
  #ifdef CONFIG_SYSCTL
43948f502   Masami Hiramatsu   kprobes: Remove r...
746
  /* This should be called with kprobe_mutex locked */
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
747
748
749
750
751
752
753
754
755
756
757
758
  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...
759
760
761
762
763
764
  	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...
765
766
767
  	printk(KERN_INFO "Kprobes globally optimized
  ");
  }
43948f502   Masami Hiramatsu   kprobes: Remove r...
768
  /* This should be called with kprobe_mutex locked */
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
769
770
771
772
773
774
775
776
777
778
779
780
  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...
781
782
783
784
  	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 ...
785
  				unoptimize_kprobe(p, false);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
786
787
  		}
  	}
6274de498   Masami Hiramatsu   kprobes: Support ...
788
789
790
791
  	/* Wait for unoptimizing completion */
  	wait_for_kprobe_optimizer();
  	printk(KERN_INFO "Kprobes globally unoptimized
  ");
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
  }
  
  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 ...
814
  /* Put a breakpoint for a probe. Must be called with text_mutex locked */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
815
816
  static void __kprobes __arm_kprobe(struct kprobe *p)
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
817
  	struct kprobe *_p;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
818
819
  
  	/* Check collision with other optimized kprobes */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
820
821
  	_p = get_optimized_kprobe((unsigned long)p->addr);
  	if (unlikely(_p))
6274de498   Masami Hiramatsu   kprobes: Support ...
822
823
  		/* Fallback to unoptimized kprobe */
  		unoptimize_kprobe(_p, true);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
824
825
826
827
  
  	arch_arm_kprobe(p);
  	optimize_kprobe(p);	/* Try to optimize (add kprobe to a list) */
  }
6274de498   Masami Hiramatsu   kprobes: Support ...
828
829
  /* 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...
830
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
831
  	struct kprobe *_p;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
832

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

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

0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
857
858
859
860
861
862
863
  /* 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...
864
865
  static __kprobes void free_aggr_kprobe(struct kprobe *p)
  {
6274de498   Masami Hiramatsu   kprobes: Support ...
866
  	arch_remove_kprobe(p);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
867
868
869
870
871
872
873
874
  	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...
875
876
877
  /* Arm a kprobe with text_mutex */
  static void __kprobes arm_kprobe(struct kprobe *kp)
  {
afd66255b   Masami Hiramatsu   kprobes: Introduc...
878
879
880
881
882
  	/*
  	 * 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...
883
  	mutex_lock(&text_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
884
  	__arm_kprobe(kp);
201517a7f   Masami Hiramatsu   kprobes: fix to u...
885
886
887
888
889
890
  	mutex_unlock(&text_mutex);
  }
  
  /* Disarm a kprobe with text_mutex */
  static void __kprobes disarm_kprobe(struct kprobe *kp)
  {
6274de498   Masami Hiramatsu   kprobes: Support ...
891
  	/* Ditto */
201517a7f   Masami Hiramatsu   kprobes: fix to u...
892
  	mutex_lock(&text_mutex);
6274de498   Masami Hiramatsu   kprobes: Support ...
893
  	__disarm_kprobe(kp, true);
201517a7f   Masami Hiramatsu   kprobes: fix to u...
894
895
  	mutex_unlock(&text_mutex);
  }
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
896
897
898
899
  /*
   * 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: ...
900
  static int __kprobes aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
901
902
  {
  	struct kprobe *kp;
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
903
  	list_for_each_entry_rcu(kp, &p->list, list) {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
904
  		if (kp->pre_handler && likely(!kprobe_disabled(kp))) {
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
905
  			set_kprobe_instance(kp);
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
906
907
  			if (kp->pre_handler(kp, regs))
  				return 1;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
908
  		}
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
909
  		reset_kprobe_instance();
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
910
911
912
  	}
  	return 0;
  }
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
913
914
  static void __kprobes aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
  					unsigned long flags)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
915
916
  {
  	struct kprobe *kp;
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
917
  	list_for_each_entry_rcu(kp, &p->list, list) {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
918
  		if (kp->post_handler && likely(!kprobe_disabled(kp))) {
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
919
  			set_kprobe_instance(kp);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
920
  			kp->post_handler(kp, regs, flags);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
921
  			reset_kprobe_instance();
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
922
923
  		}
  	}
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
924
  }
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
925
926
  static int __kprobes aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
  					int trapnr)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
927
  {
b76834bc1   Christoph Lameter   kprobes: Use this...
928
  	struct kprobe *cur = __this_cpu_read(kprobe_instance);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
929

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1350
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
  /* 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 ...
1390
1391
1392
1393
1394
  /*
   * Unregister a kprobe without a scheduler synchronization.
   */
  static int __kprobes __unregister_kprobe_top(struct kprobe *p)
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1395
  	struct kprobe *ap, *list_p;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1396

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

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

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

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

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

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

26b31c190   Masami Hiramatsu   kprobes: add (un)...
1520
  	if (num <= 0)
3d7e33825   Michael Ellerman   jprobes: make jpr...
1521
  		return -EINVAL;
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1522
  	for (i = 0; i < num; i++) {
05662bdb6   Namhyung Kim   kprobes: Verify j...
1523
  		unsigned long addr, offset;
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1524
1525
  		jp = jps[i];
  		addr = arch_deref_entry_point(jp->entry);
05662bdb6   Namhyung Kim   kprobes: Verify j...
1526
1527
1528
1529
1530
1531
1532
1533
  		/* 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...
1534

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

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

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

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

9edddaa20   Ananth N Mavinakayanahalli   Kprobes: indicate...
1577
  #ifdef CONFIG_KRETPROBES
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1578
1579
1580
1581
1582
1583
1584
1585
  /*
   * 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 ...
1586
1587
  	unsigned long hash, flags = 0;
  	struct kretprobe_instance *ri;
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1588
1589
  
  	/*TODO: consider to only swap the RA after the last pre_handler fired */
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1590
  	hash = hash_ptr(current, KPROBE_HASH_BITS);
ec484608c   Thomas Gleixner   locking, kprobes:...
1591
  	raw_spin_lock_irqsave(&rp->lock, flags);
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1592
  	if (!hlist_empty(&rp->free_instances)) {
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1593
  		ri = hlist_entry(rp->free_instances.first,
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1594
1595
  				struct kretprobe_instance, hlist);
  		hlist_del(&ri->hlist);
ec484608c   Thomas Gleixner   locking, kprobes:...
1596
  		raw_spin_unlock_irqrestore(&rp->lock, flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1597

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++;
ec484608c   Thomas Gleixner   locking, kprobes:...
1613
  		raw_spin_unlock_irqrestore(&rp->lock, flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1614
  	}
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
  	}
ec484608c   Thomas Gleixner   locking, kprobes:...
1648
  	raw_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]);
ec484608c   Thomas Gleixner   locking, kprobes:...
1882
  		raw_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
  		buf[0] = '1';
  	else
  		buf[0] = '0';
  	buf[1] = '
  ';
  	buf[2] = 0x00;
  	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
  }
  
  static ssize_t write_enabled_file_bool(struct file *file,
  	       const char __user *user_buf, size_t count, loff_t *ppos)
  {
  	char buf[32];
efeb156e7   Stephen Boyd   kprobes: silence ...
2114
  	size_t buf_size;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2115
2116
2117
2118
2119
2120
2121
2122
2123
  
  	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);