Blame view

kernel/kprobes.c 58.8 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 */
af96397de   Heiko Carstens   kprobes: allow to...
111
  	struct kprobe_insn_cache *cache;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
112
  	int nused;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
113
  	int ngarbage;
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
114
  	char slot_used[];
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
115
  };
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
116
117
118
  #define KPROBE_INSN_PAGE_SIZE(slots)			\
  	(offsetof(struct kprobe_insn_page, slot_used) +	\
  	 (sizeof(char) * (slots)))
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
119
120
121
122
  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: ...
123
124
125
126
127
  enum kprobe_slot_state {
  	SLOT_CLEAN = 0,
  	SLOT_DIRTY = 1,
  	SLOT_USED = 2,
  };
af96397de   Heiko Carstens   kprobes: allow to...
128
129
130
131
132
133
134
135
136
  static void *alloc_insn_page(void)
  {
  	return module_alloc(PAGE_SIZE);
  }
  
  static void free_insn_page(void *page)
  {
  	module_free(NULL, page);
  }
c802d64a3   Heiko Carstens   kprobes: unify in...
137
138
  struct kprobe_insn_cache kprobe_insn_slots = {
  	.mutex = __MUTEX_INITIALIZER(kprobe_insn_slots.mutex),
af96397de   Heiko Carstens   kprobes: allow to...
139
140
  	.alloc = alloc_insn_page,
  	.free = free_insn_page,
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
141
142
143
144
145
  	.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: ...
146

9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
147
  /**
129415607   Masami Hiramatsu   kprobes: add kpro...
148
   * __get_insn_slot() - Find a slot on an executable page for an instruction.
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
149
150
   * We allocate an executable page if there's no room on existing ones.
   */
c802d64a3   Heiko Carstens   kprobes: unify in...
151
  kprobe_opcode_t __kprobes *__get_insn_slot(struct kprobe_insn_cache *c)
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
152
153
  {
  	struct kprobe_insn_page *kip;
c802d64a3   Heiko Carstens   kprobes: unify in...
154
  	kprobe_opcode_t *slot = NULL;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
155

c802d64a3   Heiko Carstens   kprobes: unify in...
156
  	mutex_lock(&c->mutex);
6f716acd5   Christoph Hellwig   kprobes: codingst...
157
   retry:
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
158
159
  	list_for_each_entry(kip, &c->pages, list) {
  		if (kip->nused < slots_per_page(c)) {
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
160
  			int i;
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
161
  			for (i = 0; i < slots_per_page(c); i++) {
ab40c5c6b   Masami Hiramatsu   [PATCH] kprobes: ...
162
163
  				if (kip->slot_used[i] == SLOT_CLEAN) {
  					kip->slot_used[i] = SLOT_USED;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
164
  					kip->nused++;
c802d64a3   Heiko Carstens   kprobes: unify in...
165
166
  					slot = kip->insns + (i * c->insn_size);
  					goto out;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
167
168
  				}
  			}
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
169
170
171
  			/* kip->nused is broken. Fix it. */
  			kip->nused = slots_per_page(c);
  			WARN_ON(1);
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
172
173
  		}
  	}
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
174
  	/* If there are any garbage slots, collect it and try again. */
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
175
  	if (c->nr_garbage && collect_garbage_slots(c) == 0)
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
176
  		goto retry;
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
177
178
179
  
  	/* 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...
180
  	if (!kip)
c802d64a3   Heiko Carstens   kprobes: unify in...
181
  		goto out;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
182
183
184
185
186
187
  
  	/*
  	 * Use module_alloc so this page is within +/- 2GB of where the
  	 * kernel image and loaded module images reside. This is required
  	 * so x86_64 can correctly handle the %rip-relative fixups.
  	 */
af96397de   Heiko Carstens   kprobes: allow to...
188
  	kip->insns = c->alloc();
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
189
190
  	if (!kip->insns) {
  		kfree(kip);
c802d64a3   Heiko Carstens   kprobes: unify in...
191
  		goto out;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
192
  	}
c5cb5a2d8   Masami Hiramatsu   kprobes: Clean up...
193
  	INIT_LIST_HEAD(&kip->list);
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
194
  	memset(kip->slot_used, SLOT_CLEAN, slots_per_page(c));
ab40c5c6b   Masami Hiramatsu   [PATCH] kprobes: ...
195
  	kip->slot_used[0] = SLOT_USED;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
196
  	kip->nused = 1;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
197
  	kip->ngarbage = 0;
af96397de   Heiko Carstens   kprobes: allow to...
198
  	kip->cache = c;
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
199
  	list_add(&kip->list, &c->pages);
c802d64a3   Heiko Carstens   kprobes: unify in...
200
201
202
203
  	slot = kip->insns;
  out:
  	mutex_unlock(&c->mutex);
  	return slot;
129415607   Masami Hiramatsu   kprobes: add kpro...
204
  }
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
205
206
207
  /* 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: ...
208
  	kip->slot_used[idx] = SLOT_CLEAN;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
209
210
211
212
213
214
215
216
  	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...
217
  		if (!list_is_singular(&kip->list)) {
c5cb5a2d8   Masami Hiramatsu   kprobes: Clean up...
218
  			list_del(&kip->list);
af96397de   Heiko Carstens   kprobes: allow to...
219
  			kip->cache->free(kip->insns);
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
220
221
222
223
224
225
  			kfree(kip);
  		}
  		return 1;
  	}
  	return 0;
  }
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
226
  static int __kprobes collect_garbage_slots(struct kprobe_insn_cache *c)
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
227
  {
c5cb5a2d8   Masami Hiramatsu   kprobes: Clean up...
228
  	struct kprobe_insn_page *kip, *next;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
229

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

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

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

afd66255b   Masami Hiramatsu   kprobes: Introduc...
274
275
  #ifdef CONFIG_OPTPROBES
  /* For optimized_kprobe buffer */
c802d64a3   Heiko Carstens   kprobes: unify in...
276
277
  struct kprobe_insn_cache kprobe_optinsn_slots = {
  	.mutex = __MUTEX_INITIALIZER(kprobe_optinsn_slots.mutex),
af96397de   Heiko Carstens   kprobes: allow to...
278
279
  	.alloc = alloc_insn_page,
  	.free = free_insn_page,
afd66255b   Masami Hiramatsu   kprobes: Introduc...
280
281
282
283
  	.pages = LIST_HEAD_INIT(kprobe_optinsn_slots.pages),
  	/* .insn_size is initialized later */
  	.nr_garbage = 0,
  };
afd66255b   Masami Hiramatsu   kprobes: Introduc...
284
  #endif
2d14e39da   Anil S Keshavamurthy   [PATCH] kprobes: ...
285
  #endif
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
286

e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
287
288
289
  /* 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...
290
  	__this_cpu_write(kprobe_instance, kp);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
291
292
293
294
  }
  
  static inline void reset_kprobe_instance(void)
  {
b76834bc1   Christoph Lameter   kprobes: Use this...
295
  	__this_cpu_write(kprobe_instance, NULL);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
296
  }
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
297
298
  /*
   * This routine is called either:
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
299
   * 	- under the kprobe_mutex - during kprobe_[un]register()
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
300
   * 				OR
d217d5450   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
301
   * 	- with preemption disabled - from arch/xxx/kernel/kprobes.c
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
302
   */
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
303
  struct kprobe __kprobes *get_kprobe(void *addr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
305
  {
  	struct hlist_head *head;
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
306
  	struct kprobe *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
308
  
  	head = &kprobe_table[hash_ptr(addr, KPROBE_HASH_BITS)];
b67bfe0d4   Sasha Levin   hlist: drop the n...
309
  	hlist_for_each_entry_rcu(p, head, hlist) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
311
312
  		if (p->addr == addr)
  			return p;
  	}
afd66255b   Masami Hiramatsu   kprobes: Introduc...
313

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
314
315
  	return NULL;
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
316
317
318
319
320
321
322
  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 ...
323
324
325
326
327
328
  /* 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...
329
330
331
  /*
   * Keep all fields in the kprobe consistent
   */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
332
  static inline void copy_kprobe(struct kprobe *ap, struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
333
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
334
335
  	memcpy(&p->opcode, &ap->opcode, sizeof(kprobe_opcode_t));
  	memcpy(&p->ainsn, &ap->ainsn, sizeof(struct arch_specific_insn));
afd66255b   Masami Hiramatsu   kprobes: Introduc...
336
337
338
  }
  
  #ifdef CONFIG_OPTPROBES
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
339
340
  /* NOTE: change this value only with kprobe_mutex held */
  static bool kprobes_allow_optimization;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
  /*
   * 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 ...
357
358
359
360
361
362
363
364
365
366
  /* 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...
367
368
369
370
371
372
373
374
375
376
377
378
  /* 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 ...
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
  /* 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...
405
406
407
408
  /*
   * Return an optimized kprobe whose optimizing code replaces
   * instructions including addr (exclude breakpoint).
   */
6376b2297   Namhyung Kim   kprobes: Make fun...
409
  static struct kprobe *__kprobes get_optimized_kprobe(unsigned long addr)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
  {
  	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 ...
430
  static LIST_HEAD(unoptimizing_list);
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
431
  static LIST_HEAD(freeing_list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
432
433
434
435
  
  static void kprobe_optimizer(struct work_struct *work);
  static DECLARE_DELAYED_WORK(optimizing_work, kprobe_optimizer);
  #define OPTIMIZE_DELAY 5
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
436
437
438
439
440
  /*
   * Optimize (replace a breakpoint with a jump) kprobes listed on
   * optimizing_list.
   */
  static __kprobes void do_optimize_kprobes(void)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
441
  {
6274de498   Masami Hiramatsu   kprobes: Support ...
442
443
444
445
  	/* Optimization never be done when disarmed */
  	if (kprobes_all_disarmed || !kprobes_allow_optimization ||
  	    list_empty(&optimizing_list))
  		return;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
446
447
448
449
450
451
452
453
454
455
456
457
  	/*
  	 * 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...
458
  	arch_optimize_kprobes(&optimizing_list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
459
460
  	mutex_unlock(&text_mutex);
  	put_online_cpus();
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
461
  }
6274de498   Masami Hiramatsu   kprobes: Support ...
462
463
464
465
  /*
   * Unoptimize (replace a jump with a breakpoint and remove the breakpoint
   * if need) kprobes listed on unoptimizing_list.
   */
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
466
  static __kprobes void do_unoptimize_kprobes(void)
6274de498   Masami Hiramatsu   kprobes: Support ...
467
468
469
470
471
472
473
474
475
476
  {
  	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);
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
477
  	arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list);
f984ba4eb   Masami Hiramatsu   kprobes: Use text...
478
  	/* Loop free_list for disarming */
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
479
  	list_for_each_entry_safe(op, tmp, &freeing_list, list) {
6274de498   Masami Hiramatsu   kprobes: Support ...
480
481
482
483
484
485
486
487
488
489
  		/* 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 ...
490
491
492
493
494
495
496
497
  		} else
  			list_del_init(&op->list);
  	}
  	mutex_unlock(&text_mutex);
  	put_online_cpus();
  }
  
  /* Reclaim all kprobes on the free_list */
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
498
  static __kprobes void do_free_cleaned_kprobes(void)
6274de498   Masami Hiramatsu   kprobes: Support ...
499
500
  {
  	struct optimized_kprobe *op, *tmp;
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
501
  	list_for_each_entry_safe(op, tmp, &freeing_list, list) {
6274de498   Masami Hiramatsu   kprobes: Support ...
502
503
504
505
506
507
508
509
510
  		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)
  {
ad72b3bea   Tejun Heo   kprobes: fix wait...
511
  	schedule_delayed_work(&optimizing_work, OPTIMIZE_DELAY);
6274de498   Masami Hiramatsu   kprobes: Support ...
512
  }
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
513
514
515
  /* Kprobe jump optimizer */
  static __kprobes void kprobe_optimizer(struct work_struct *work)
  {
72ef3794c   Steven Rostedt   kprobes: Inverse ...
516
  	mutex_lock(&kprobe_mutex);
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
517
518
  	/* Lock modules while optimizing kprobes */
  	mutex_lock(&module_mutex);
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
519
520
  
  	/*
6274de498   Masami Hiramatsu   kprobes: Support ...
521
522
523
  	 * Step 1: Unoptimize kprobes and collect cleaned (unused and disarmed)
  	 * kprobes before waiting for quiesence period.
  	 */
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
524
  	do_unoptimize_kprobes();
6274de498   Masami Hiramatsu   kprobes: Support ...
525
526
527
  
  	/*
  	 * Step 2: Wait for quiesence period to ensure all running interrupts
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
528
529
530
531
532
533
  	 * 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 ...
534
  	/* Step 3: Optimize kprobes after quiesence period */
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
535
  	do_optimize_kprobes();
6274de498   Masami Hiramatsu   kprobes: Support ...
536
537
  
  	/* Step 4: Free cleaned kprobes after quiesence period */
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
538
  	do_free_cleaned_kprobes();
6274de498   Masami Hiramatsu   kprobes: Support ...
539

afd66255b   Masami Hiramatsu   kprobes: Introduc...
540
  	mutex_unlock(&module_mutex);
72ef3794c   Steven Rostedt   kprobes: Inverse ...
541
  	mutex_unlock(&kprobe_mutex);
6274de498   Masami Hiramatsu   kprobes: Support ...
542

cd7ebe229   Masami Hiramatsu   kprobes: Use text...
543
  	/* Step 5: Kick optimizer again if needed */
f984ba4eb   Masami Hiramatsu   kprobes: Use text...
544
  	if (!list_empty(&optimizing_list) || !list_empty(&unoptimizing_list))
cd7ebe229   Masami Hiramatsu   kprobes: Use text...
545
  		kick_kprobe_optimizer();
6274de498   Masami Hiramatsu   kprobes: Support ...
546
547
548
549
550
  }
  
  /* Wait for completing optimization and unoptimization */
  static __kprobes void wait_for_kprobe_optimizer(void)
  {
ad72b3bea   Tejun Heo   kprobes: fix wait...
551
552
553
554
555
556
557
558
559
560
561
562
563
564
  	mutex_lock(&kprobe_mutex);
  
  	while (!list_empty(&optimizing_list) || !list_empty(&unoptimizing_list)) {
  		mutex_unlock(&kprobe_mutex);
  
  		/* this will also make optimizing_work execute immmediately */
  		flush_delayed_work(&optimizing_work);
  		/* @optimizing_work might not have been queued yet, relax */
  		cpu_relax();
  
  		mutex_lock(&kprobe_mutex);
  	}
  
  	mutex_unlock(&kprobe_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
565
566
567
568
569
570
571
572
  }
  
  /* 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...
573
  	if (!kprobe_optready(p) || !kprobes_allow_optimization ||
afd66255b   Masami Hiramatsu   kprobes: Introduc...
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
  	    (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...
590
  	op->kp.flags |= KPROBE_FLAG_OPTIMIZED;
6274de498   Masami Hiramatsu   kprobes: Support ...
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
  
  	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...
609
610
611
  }
  
  /* Unoptimize a kprobe if p is optimized */
6274de498   Masami Hiramatsu   kprobes: Support ...
612
  static __kprobes void unoptimize_kprobe(struct kprobe *p, bool force)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
613
614
  {
  	struct optimized_kprobe *op;
6274de498   Masami Hiramatsu   kprobes: Support ...
615
616
617
618
619
620
621
622
623
624
625
626
  	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...
627
  			list_del_init(&op->list);
6274de498   Masami Hiramatsu   kprobes: Support ...
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
  			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...
646
647
  	}
  }
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
  /* 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...
669
670
671
672
673
674
  /* 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 ...
675
676
  	if (!list_empty(&op->list))
  		/* Dequeue from the (un)optimization queue */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
677
  		list_del_init(&op->list);
6274de498   Masami Hiramatsu   kprobes: Support ...
678
  	op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
679
680
681
682
683
684
685
686
687
688
689
  
  	if (kprobe_unused(p)) {
  		/* Enqueue if it is unused */
  		list_add(&op->list, &freeing_list);
  		/*
  		 * Remove unused probes from the hash list. After waiting
  		 * for synchronization, this probe is reclaimed.
  		 * (reclaiming is done by do_free_cleaned_kprobes().)
  		 */
  		hlist_del_rcu(&op->kp.hlist);
  	}
6274de498   Masami Hiramatsu   kprobes: Support ...
690
  	/* Don't touch the code, because it is already freed. */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
691
692
693
694
695
696
697
698
699
700
701
  	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...
702
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
  /* 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;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
728
729
730
  	/* Impossible to optimize ftrace-based kprobe */
  	if (kprobe_ftrace(p))
  		return;
25764288d   Masami Hiramatsu   kprobes: Move loc...
731
732
733
  	/* For preparing optimization, jump_label_text_reserved() is called */
  	jump_label_lock();
  	mutex_lock(&text_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
734
735
  	ap = alloc_aggr_kprobe(p);
  	if (!ap)
25764288d   Masami Hiramatsu   kprobes: Move loc...
736
  		goto out;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
737
738
739
740
  
  	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 ...
741
742
  		arch_remove_optimized_kprobe(op);
  		kfree(op);
25764288d   Masami Hiramatsu   kprobes: Move loc...
743
  		goto out;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
744
745
746
  	}
  
  	init_aggr_kprobe(ap, p);
25764288d   Masami Hiramatsu   kprobes: Move loc...
747
748
749
750
751
  	optimize_kprobe(ap);	/* This just kicks optimizer thread */
  
  out:
  	mutex_unlock(&text_mutex);
  	jump_label_unlock();
afd66255b   Masami Hiramatsu   kprobes: Introduc...
752
  }
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
753
754
755
756
  #ifdef CONFIG_SYSCTL
  static void __kprobes optimize_all_kprobes(void)
  {
  	struct hlist_head *head;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
757
758
  	struct kprobe *p;
  	unsigned int i;
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
759
  	mutex_lock(&kprobe_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
760
761
  	/* If optimization is already allowed, just return */
  	if (kprobes_allow_optimization)
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
762
  		goto out;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
763
764
  
  	kprobes_allow_optimization = true;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
765
766
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
b67bfe0d4   Sasha Levin   hlist: drop the n...
767
  		hlist_for_each_entry_rcu(p, head, hlist)
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
768
769
770
  			if (!kprobe_disabled(p))
  				optimize_kprobe(p);
  	}
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
771
772
  	printk(KERN_INFO "Kprobes globally optimized
  ");
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
773
774
  out:
  	mutex_unlock(&kprobe_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
775
776
777
778
779
  }
  
  static void __kprobes unoptimize_all_kprobes(void)
  {
  	struct hlist_head *head;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
780
781
  	struct kprobe *p;
  	unsigned int i;
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
782
  	mutex_lock(&kprobe_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
783
  	/* If optimization is already prohibited, just return */
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
784
785
  	if (!kprobes_allow_optimization) {
  		mutex_unlock(&kprobe_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
786
  		return;
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
787
  	}
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
788
789
  
  	kprobes_allow_optimization = false;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
790
791
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
b67bfe0d4   Sasha Levin   hlist: drop the n...
792
  		hlist_for_each_entry_rcu(p, head, hlist) {
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
793
  			if (!kprobe_disabled(p))
6274de498   Masami Hiramatsu   kprobes: Support ...
794
  				unoptimize_kprobe(p, false);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
795
796
  		}
  	}
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
797
  	mutex_unlock(&kprobe_mutex);
6274de498   Masami Hiramatsu   kprobes: Support ...
798
799
800
801
  	/* Wait for unoptimizing completion */
  	wait_for_kprobe_optimizer();
  	printk(KERN_INFO "Kprobes globally unoptimized
  ");
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
802
  }
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
803
  static DEFINE_MUTEX(kprobe_sysctl_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
804
805
806
807
808
809
  int sysctl_kprobes_optimization;
  int proc_kprobes_optimization_handler(struct ctl_table *table, int write,
  				      void __user *buffer, size_t *length,
  				      loff_t *ppos)
  {
  	int ret;
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
810
  	mutex_lock(&kprobe_sysctl_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
811
812
813
814
815
816
817
  	sysctl_kprobes_optimization = kprobes_allow_optimization ? 1 : 0;
  	ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
  
  	if (sysctl_kprobes_optimization)
  		optimize_all_kprobes();
  	else
  		unoptimize_all_kprobes();
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
818
  	mutex_unlock(&kprobe_sysctl_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
819
820
821
822
  
  	return ret;
  }
  #endif /* CONFIG_SYSCTL */
6274de498   Masami Hiramatsu   kprobes: Support ...
823
  /* Put a breakpoint for a probe. Must be called with text_mutex locked */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
824
825
  static void __kprobes __arm_kprobe(struct kprobe *p)
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
826
  	struct kprobe *_p;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
827
828
  
  	/* Check collision with other optimized kprobes */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
829
830
  	_p = get_optimized_kprobe((unsigned long)p->addr);
  	if (unlikely(_p))
6274de498   Masami Hiramatsu   kprobes: Support ...
831
832
  		/* Fallback to unoptimized kprobe */
  		unoptimize_kprobe(_p, true);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
833
834
835
836
  
  	arch_arm_kprobe(p);
  	optimize_kprobe(p);	/* Try to optimize (add kprobe to a list) */
  }
6274de498   Masami Hiramatsu   kprobes: Support ...
837
838
  /* 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...
839
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
840
  	struct kprobe *_p;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
841

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

6274de498   Masami Hiramatsu   kprobes: Support ...
844
845
846
847
848
849
850
851
  	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...
852
853
854
855
856
  }
  
  #else /* !CONFIG_OPTPROBES */
  
  #define optimize_kprobe(p)			do {} while (0)
6274de498   Masami Hiramatsu   kprobes: Support ...
857
  #define unoptimize_kprobe(p, f)			do {} while (0)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
858
859
860
861
  #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 ...
862
863
864
  #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...
865

0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
866
867
868
869
870
871
872
  /* 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...
873
874
  static __kprobes void free_aggr_kprobe(struct kprobe *p)
  {
6274de498   Masami Hiramatsu   kprobes: Support ...
875
  	arch_remove_kprobe(p);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
876
877
878
879
880
881
882
883
  	kfree(p);
  }
  
  static __kprobes struct kprobe *alloc_aggr_kprobe(struct kprobe *p)
  {
  	return kzalloc(sizeof(struct kprobe), GFP_KERNEL);
  }
  #endif /* CONFIG_OPTPROBES */
e7dbfe349   Masami Hiramatsu   kprobes/x86: Move...
884
  #ifdef CONFIG_KPROBES_ON_FTRACE
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
885
  static struct ftrace_ops kprobe_ftrace_ops __read_mostly = {
e52538965   Masami Hiramatsu   kprobes/x86: ftra...
886
  	.func = kprobe_ftrace_handler,
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
  	.flags = FTRACE_OPS_FL_SAVE_REGS,
  };
  static int kprobe_ftrace_enabled;
  
  /* Must ensure p->addr is really on ftrace */
  static int __kprobes prepare_kprobe(struct kprobe *p)
  {
  	if (!kprobe_ftrace(p))
  		return arch_prepare_kprobe(p);
  
  	return arch_prepare_kprobe_ftrace(p);
  }
  
  /* Caller must lock kprobe_mutex */
  static void __kprobes arm_kprobe_ftrace(struct kprobe *p)
  {
  	int ret;
  
  	ret = ftrace_set_filter_ip(&kprobe_ftrace_ops,
  				   (unsigned long)p->addr, 0, 0);
  	WARN(ret < 0, "Failed to arm kprobe-ftrace at %p (%d)
  ", p->addr, ret);
  	kprobe_ftrace_enabled++;
  	if (kprobe_ftrace_enabled == 1) {
  		ret = register_ftrace_function(&kprobe_ftrace_ops);
  		WARN(ret < 0, "Failed to init kprobe-ftrace (%d)
  ", ret);
  	}
  }
  
  /* Caller must lock kprobe_mutex */
  static void __kprobes disarm_kprobe_ftrace(struct kprobe *p)
  {
  	int ret;
  
  	kprobe_ftrace_enabled--;
  	if (kprobe_ftrace_enabled == 0) {
  		ret = unregister_ftrace_function(&kprobe_ftrace_ops);
  		WARN(ret < 0, "Failed to init kprobe-ftrace (%d)
  ", ret);
  	}
  	ret = ftrace_set_filter_ip(&kprobe_ftrace_ops,
  			   (unsigned long)p->addr, 1, 0);
  	WARN(ret < 0, "Failed to disarm kprobe-ftrace at %p (%d)
  ", p->addr, ret);
  }
e7dbfe349   Masami Hiramatsu   kprobes/x86: Move...
933
  #else	/* !CONFIG_KPROBES_ON_FTRACE */
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
934
935
936
937
  #define prepare_kprobe(p)	arch_prepare_kprobe(p)
  #define arm_kprobe_ftrace(p)	do {} while (0)
  #define disarm_kprobe_ftrace(p)	do {} while (0)
  #endif
201517a7f   Masami Hiramatsu   kprobes: fix to u...
938
939
940
  /* Arm a kprobe with text_mutex */
  static void __kprobes arm_kprobe(struct kprobe *kp)
  {
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
941
942
943
944
  	if (unlikely(kprobe_ftrace(kp))) {
  		arm_kprobe_ftrace(kp);
  		return;
  	}
afd66255b   Masami Hiramatsu   kprobes: Introduc...
945
946
947
948
949
  	/*
  	 * 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...
950
  	mutex_lock(&text_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
951
  	__arm_kprobe(kp);
201517a7f   Masami Hiramatsu   kprobes: fix to u...
952
953
954
955
  	mutex_unlock(&text_mutex);
  }
  
  /* Disarm a kprobe with text_mutex */
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
956
  static void __kprobes disarm_kprobe(struct kprobe *kp, bool reopt)
201517a7f   Masami Hiramatsu   kprobes: fix to u...
957
  {
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
958
959
960
961
  	if (unlikely(kprobe_ftrace(kp))) {
  		disarm_kprobe_ftrace(kp);
  		return;
  	}
6274de498   Masami Hiramatsu   kprobes: Support ...
962
  	/* Ditto */
201517a7f   Masami Hiramatsu   kprobes: fix to u...
963
  	mutex_lock(&text_mutex);
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
964
  	__disarm_kprobe(kp, reopt);
201517a7f   Masami Hiramatsu   kprobes: fix to u...
965
966
  	mutex_unlock(&text_mutex);
  }
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
967
968
969
970
  /*
   * 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: ...
971
  static int __kprobes aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
972
973
  {
  	struct kprobe *kp;
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
974
  	list_for_each_entry_rcu(kp, &p->list, list) {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
975
  		if (kp->pre_handler && likely(!kprobe_disabled(kp))) {
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
976
  			set_kprobe_instance(kp);
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
977
978
  			if (kp->pre_handler(kp, regs))
  				return 1;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
979
  		}
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
980
  		reset_kprobe_instance();
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
981
982
983
  	}
  	return 0;
  }
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
984
985
  static void __kprobes aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
  					unsigned long flags)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
986
987
  {
  	struct kprobe *kp;
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
988
  	list_for_each_entry_rcu(kp, &p->list, list) {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
989
  		if (kp->post_handler && likely(!kprobe_disabled(kp))) {
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
990
  			set_kprobe_instance(kp);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
991
  			kp->post_handler(kp, regs, flags);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
992
  			reset_kprobe_instance();
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
993
994
  		}
  	}
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
995
  }
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
996
997
  static int __kprobes aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
  					int trapnr)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
998
  {
b76834bc1   Christoph Lameter   kprobes: Use this...
999
  	struct kprobe *cur = __this_cpu_read(kprobe_instance);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1000

64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1001
1002
1003
1004
  	/*
  	 * 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: ...
1005
1006
  	if (cur && cur->fault_handler) {
  		if (cur->fault_handler(cur, regs, trapnr))
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1007
1008
1009
1010
  			return 1;
  	}
  	return 0;
  }
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1011
  static int __kprobes aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1012
  {
b76834bc1   Christoph Lameter   kprobes: Use this...
1013
  	struct kprobe *cur = __this_cpu_read(kprobe_instance);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1014
1015
1016
1017
1018
  	int ret = 0;
  
  	if (cur && cur->break_handler) {
  		if (cur->break_handler(cur, regs))
  			ret = 1;
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1019
  	}
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1020
1021
  	reset_kprobe_instance();
  	return ret;
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1022
  }
bf8d5c52c   Keshavamurthy Anil S   [PATCH] kprobes: ...
1023
1024
1025
1026
  /* 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...
1027
  	if (!kprobe_aggrprobe(p)) {
bf8d5c52c   Keshavamurthy Anil S   [PATCH] kprobes: ...
1028
1029
1030
1031
1032
1033
1034
  		p->nmissed++;
  	} else {
  		list_for_each_entry_rcu(kp, &p->list, list)
  			kp->nmissed++;
  	}
  	return;
  }
99219a3fb   bibo,mao   [PATCH] kretprobe...
1035
1036
  void __kprobes recycle_rp_inst(struct kretprobe_instance *ri,
  				struct hlist_head *head)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1037
  {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1038
  	struct kretprobe *rp = ri->rp;
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1039
1040
  	/* remove rp inst off the rprobe_inst_table */
  	hlist_del(&ri->hlist);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1041
1042
  	INIT_HLIST_NODE(&ri->hlist);
  	if (likely(rp)) {
ec484608c   Thomas Gleixner   locking, kprobes:...
1043
  		raw_spin_lock(&rp->lock);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1044
  		hlist_add_head(&ri->hlist, &rp->free_instances);
ec484608c   Thomas Gleixner   locking, kprobes:...
1045
  		raw_spin_unlock(&rp->lock);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1046
1047
  	} else
  		/* Unregistering */
99219a3fb   bibo,mao   [PATCH] kretprobe...
1048
  		hlist_add_head(&ri->hlist, head);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1049
  }
017c39bdb   Masami Hiramatsu   kprobes: add __kp...
1050
  void __kprobes kretprobe_hash_lock(struct task_struct *tsk,
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1051
  			 struct hlist_head **head, unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1052
  __acquires(hlist_lock)
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1053
1054
  {
  	unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS);
ec484608c   Thomas Gleixner   locking, kprobes:...
1055
  	raw_spinlock_t *hlist_lock;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1056
1057
1058
  
  	*head = &kretprobe_inst_table[hash];
  	hlist_lock = kretprobe_table_lock_ptr(hash);
ec484608c   Thomas Gleixner   locking, kprobes:...
1059
  	raw_spin_lock_irqsave(hlist_lock, *flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1060
  }
017c39bdb   Masami Hiramatsu   kprobes: add __kp...
1061
1062
  static void __kprobes kretprobe_table_lock(unsigned long hash,
  	unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1063
  __acquires(hlist_lock)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1064
  {
ec484608c   Thomas Gleixner   locking, kprobes:...
1065
1066
  	raw_spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash);
  	raw_spin_lock_irqsave(hlist_lock, *flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1067
  }
017c39bdb   Masami Hiramatsu   kprobes: add __kp...
1068
1069
  void __kprobes kretprobe_hash_unlock(struct task_struct *tsk,
  	unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1070
  __releases(hlist_lock)
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1071
1072
  {
  	unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS);
ec484608c   Thomas Gleixner   locking, kprobes:...
1073
  	raw_spinlock_t *hlist_lock;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1074
1075
  
  	hlist_lock = kretprobe_table_lock_ptr(hash);
ec484608c   Thomas Gleixner   locking, kprobes:...
1076
  	raw_spin_unlock_irqrestore(hlist_lock, *flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1077
  }
6376b2297   Namhyung Kim   kprobes: Make fun...
1078
1079
  static void __kprobes kretprobe_table_unlock(unsigned long hash,
         unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1080
  __releases(hlist_lock)
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1081
  {
ec484608c   Thomas Gleixner   locking, kprobes:...
1082
1083
  	raw_spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash);
  	raw_spin_unlock_irqrestore(hlist_lock, *flags);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1084
  }
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1085
  /*
c6fd91f0b   bibo mao   [PATCH] kretprobe...
1086
1087
1088
1089
   * 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: ...
1090
   */
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1091
  void __kprobes kprobe_flush_task(struct task_struct *tk)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1092
  {
62c27be0d   bibo,mao   [PATCH] kprobe wh...
1093
  	struct kretprobe_instance *ri;
99219a3fb   bibo,mao   [PATCH] kretprobe...
1094
  	struct hlist_head *head, empty_rp;
b67bfe0d4   Sasha Levin   hlist: drop the n...
1095
  	struct hlist_node *tmp;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1096
  	unsigned long hash, flags = 0;
802eae7c8   Rusty Lynch   [PATCH] Return pr...
1097

ef53d9c5e   Srinivasa D S   kprobes: improve ...
1098
1099
1100
  	if (unlikely(!kprobes_initialized))
  		/* Early boot.  kretprobe_table_locks not yet initialized. */
  		return;
d496aab56   Ananth N Mavinakayanahalli   kprobes: initiali...
1101
  	INIT_HLIST_HEAD(&empty_rp);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1102
1103
1104
  	hash = hash_ptr(tk, KPROBE_HASH_BITS);
  	head = &kretprobe_inst_table[hash];
  	kretprobe_table_lock(hash, &flags);
b67bfe0d4   Sasha Levin   hlist: drop the n...
1105
  	hlist_for_each_entry_safe(ri, tmp, head, hlist) {
62c27be0d   bibo,mao   [PATCH] kprobe wh...
1106
  		if (ri->task == tk)
99219a3fb   bibo,mao   [PATCH] kretprobe...
1107
  			recycle_rp_inst(ri, &empty_rp);
62c27be0d   bibo,mao   [PATCH] kprobe wh...
1108
  	}
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1109
  	kretprobe_table_unlock(hash, &flags);
b67bfe0d4   Sasha Levin   hlist: drop the n...
1110
  	hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
99219a3fb   bibo,mao   [PATCH] kretprobe...
1111
1112
1113
  		hlist_del(&ri->hlist);
  		kfree(ri);
  	}
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1114
  }
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1115
1116
1117
  static inline void free_rp_inst(struct kretprobe *rp)
  {
  	struct kretprobe_instance *ri;
b67bfe0d4   Sasha Levin   hlist: drop the n...
1118
  	struct hlist_node *next;
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1119

b67bfe0d4   Sasha Levin   hlist: drop the n...
1120
  	hlist_for_each_entry_safe(ri, next, &rp->free_instances, hlist) {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1121
  		hlist_del(&ri->hlist);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1122
1123
1124
  		kfree(ri);
  	}
  }
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1125
1126
  static void __kprobes cleanup_rp_inst(struct kretprobe *rp)
  {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1127
  	unsigned long flags, hash;
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1128
  	struct kretprobe_instance *ri;
b67bfe0d4   Sasha Levin   hlist: drop the n...
1129
  	struct hlist_node *next;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1130
  	struct hlist_head *head;
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1131
  	/* No race here */
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1132
1133
1134
  	for (hash = 0; hash < KPROBE_TABLE_SIZE; hash++) {
  		kretprobe_table_lock(hash, &flags);
  		head = &kretprobe_inst_table[hash];
b67bfe0d4   Sasha Levin   hlist: drop the n...
1135
  		hlist_for_each_entry_safe(ri, next, head, hlist) {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1136
1137
1138
1139
  			if (ri->rp == rp)
  				ri->rp = NULL;
  		}
  		kretprobe_table_unlock(hash, &flags);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1140
  	}
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1141
1142
  	free_rp_inst(rp);
  }
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1143
  /*
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1144
  * Add the new probe to ap->list. Fail if this is the
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1145
1146
  * second jprobe at the address - two jprobes can't coexist
  */
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1147
  static int __kprobes add_new_kprobe(struct kprobe *ap, struct kprobe *p)
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1148
  {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1149
  	BUG_ON(kprobe_gone(ap) || kprobe_gone(p));
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1150
1151
  
  	if (p->break_handler || p->post_handler)
6274de498   Masami Hiramatsu   kprobes: Support ...
1152
  		unoptimize_kprobe(ap, true);	/* Fall back to normal kprobe */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1153

8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1154
  	if (p->break_handler) {
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1155
  		if (ap->break_handler)
367216567   mao, bibo   [PATCH] Kprobe: m...
1156
  			return -EEXIST;
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1157
1158
  		list_add_tail_rcu(&p->list, &ap->list);
  		ap->break_handler = aggr_break_handler;
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1159
  	} else
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1160
1161
1162
  		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 ...
1163

8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1164
1165
1166
1167
  	return 0;
  }
  
  /*
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1168
1169
1170
   * 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...
1171
  static void __kprobes init_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1172
  {
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1173
  	/* Copy p's insn slot to ap */
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1174
  	copy_kprobe(p, ap);
a9ad965ea   bibo, mao   [PATCH] IA64: kpr...
1175
  	flush_insn_slot(ap);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1176
  	ap->addr = p->addr;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1177
  	ap->flags = p->flags & ~KPROBE_FLAG_OPTIMIZED;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1178
  	ap->pre_handler = aggr_pre_handler;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1179
  	ap->fault_handler = aggr_fault_handler;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1180
1181
  	/* We don't care the kprobe which has gone. */
  	if (p->post_handler && !kprobe_gone(p))
367216567   mao, bibo   [PATCH] Kprobe: m...
1182
  		ap->post_handler = aggr_post_handler;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1183
  	if (p->break_handler && !kprobe_gone(p))
367216567   mao, bibo   [PATCH] Kprobe: m...
1184
  		ap->break_handler = aggr_break_handler;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1185
1186
  
  	INIT_LIST_HEAD(&ap->list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1187
  	INIT_HLIST_NODE(&ap->hlist);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1188

afd66255b   Masami Hiramatsu   kprobes: Introduc...
1189
  	list_add_rcu(&p->list, &ap->list);
adad0f331   Keshavamurthy Anil S   [PATCH] kprobes: ...
1190
  	hlist_replace_rcu(&p->hlist, &ap->hlist);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1191
1192
1193
1194
1195
  }
  
  /*
   * This is the second or subsequent kprobe at the address - handle
   * the intricacies
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1196
   */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1197
  static int __kprobes register_aggr_kprobe(struct kprobe *orig_p,
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1198
  					  struct kprobe *p)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1199
1200
  {
  	int ret = 0;
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1201
  	struct kprobe *ap = orig_p;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1202

25764288d   Masami Hiramatsu   kprobes: Move loc...
1203
1204
1205
1206
1207
1208
1209
1210
  	/* For preparing optimization, jump_label_text_reserved() is called */
  	jump_label_lock();
  	/*
  	 * Get online CPUs to avoid text_mutex deadlock.with stop machine,
  	 * which is invoked by unoptimize_kprobe() in add_new_kprobe()
  	 */
  	get_online_cpus();
  	mutex_lock(&text_mutex);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1211
1212
1213
  	if (!kprobe_aggrprobe(orig_p)) {
  		/* If orig_p is not an aggr_kprobe, create new aggr_kprobe. */
  		ap = alloc_aggr_kprobe(orig_p);
25764288d   Masami Hiramatsu   kprobes: Move loc...
1214
1215
1216
1217
  		if (!ap) {
  			ret = -ENOMEM;
  			goto out;
  		}
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1218
  		init_aggr_kprobe(ap, orig_p);
6274de498   Masami Hiramatsu   kprobes: Support ...
1219
  	} else if (kprobe_unused(ap))
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
1220
1221
  		/* This probe is going to die. Rescue it */
  		reuse_unused_kprobe(ap);
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1222
1223
  
  	if (kprobe_gone(ap)) {
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1224
1225
1226
1227
1228
1229
  		/*
  		 * 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 ...
1230
  		ret = arch_prepare_kprobe(ap);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1231
  		if (ret)
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1232
1233
1234
1235
1236
  			/*
  			 * Even if fail to allocate new slot, don't need to
  			 * free aggr_probe. It will be used next time, or
  			 * freed by unregister_kprobe.
  			 */
25764288d   Masami Hiramatsu   kprobes: Move loc...
1237
  			goto out;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1238

afd66255b   Masami Hiramatsu   kprobes: Introduc...
1239
1240
  		/* Prepare optimized instructions if possible. */
  		prepare_optimized_kprobe(ap);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1241
  		/*
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1242
1243
  		 * Clear gone flag to prevent allocating new slot again, and
  		 * set disabled flag because it is not armed yet.
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1244
  		 */
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1245
1246
  		ap->flags = (ap->flags & ~KPROBE_FLAG_GONE)
  			    | KPROBE_FLAG_DISABLED;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1247
  	}
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1248

afd66255b   Masami Hiramatsu   kprobes: Introduc...
1249
  	/* Copy ap's insn slot to p */
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1250
  	copy_kprobe(ap, p);
25764288d   Masami Hiramatsu   kprobes: Move loc...
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
  	ret = add_new_kprobe(ap, p);
  
  out:
  	mutex_unlock(&text_mutex);
  	put_online_cpus();
  	jump_label_unlock();
  
  	if (ret == 0 && kprobe_disabled(ap) && !kprobe_disabled(p)) {
  		ap->flags &= ~KPROBE_FLAG_DISABLED;
  		if (!kprobes_all_disarmed)
  			/* Arm the breakpoint again. */
  			arm_kprobe(ap);
  	}
  	return ret;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1265
  }
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1266
1267
  static int __kprobes in_kprobes_functions(unsigned long addr)
  {
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
1268
  	struct kprobe_blackpoint *kb;
6f716acd5   Christoph Hellwig   kprobes: codingst...
1269
1270
  	if (addr >= (unsigned long)__kprobes_text_start &&
  	    addr < (unsigned long)__kprobes_text_end)
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1271
  		return -EINVAL;
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
  	/*
  	 * 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: ...
1283
1284
  	return 0;
  }
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1285
1286
1287
  /*
   * 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 -...
1288
1289
   * This returns encoded errors if it fails to look up symbol or invalid
   * combination of parameters.
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1290
1291
1292
1293
   */
  static kprobe_opcode_t __kprobes *kprobe_addr(struct kprobe *p)
  {
  	kprobe_opcode_t *addr = p->addr;
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1294
1295
1296
1297
  
  	if ((p->symbol_name && p->addr) ||
  	    (!p->symbol_name && !p->addr))
  		goto invalid;
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1298
  	if (p->symbol_name) {
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1299
  		kprobe_lookup_name(p->symbol_name, addr);
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1300
1301
  		if (!addr)
  			return ERR_PTR(-ENOENT);
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1302
  	}
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1303
1304
1305
1306
1307
1308
  	addr = (kprobe_opcode_t *)(((char *)addr) + p->offset);
  	if (addr)
  		return addr;
  
  invalid:
  	return ERR_PTR(-EINVAL);
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1309
  }
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1310
1311
1312
  /* 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...
1313
  	struct kprobe *ap, *list_p;
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1314

6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1315
1316
  	ap = get_kprobe(p->addr);
  	if (unlikely(!ap))
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1317
  		return NULL;
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1318
1319
  	if (p != ap) {
  		list_for_each_entry_rcu(list_p, &ap->list, list)
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1320
1321
1322
1323
1324
1325
  			if (list_p == p)
  			/* kprobe p is a valid probe */
  				goto valid;
  		return NULL;
  	}
  valid:
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1326
  	return ap;
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1327
1328
1329
1330
1331
1332
  }
  
  /* 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 ...
1333
1334
  
  	mutex_lock(&kprobe_mutex);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1335
  	if (__get_valid_kprobe(p))
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1336
1337
  		ret = -EINVAL;
  	mutex_unlock(&kprobe_mutex);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1338

1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1339
1340
  	return ret;
  }
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1341
1342
  static __kprobes int check_kprobe_address_safe(struct kprobe *p,
  					       struct module **probed_mod)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1343
1344
  {
  	int ret = 0;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1345
1346
1347
1348
1349
1350
1351
1352
  	unsigned long ftrace_addr;
  
  	/*
  	 * If the address is located on a ftrace nop, set the
  	 * breakpoint to the following instruction.
  	 */
  	ftrace_addr = ftrace_location((unsigned long)p->addr);
  	if (ftrace_addr) {
e7dbfe349   Masami Hiramatsu   kprobes/x86: Move...
1353
  #ifdef CONFIG_KPROBES_ON_FTRACE
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1354
1355
1356
  		/* Given address is not on the instruction boundary */
  		if ((unsigned long)p->addr != ftrace_addr)
  			return -EILSEQ;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1357
  		p->flags |= KPROBE_FLAG_FTRACE;
e7dbfe349   Masami Hiramatsu   kprobes/x86: Move...
1358
  #else	/* !CONFIG_KPROBES_ON_FTRACE */
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1359
1360
1361
  		return -EINVAL;
  #endif
  	}
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1362

91bad2f8d   Jason Baron   jump label: Fix d...
1363
  	jump_label_lock();
de31c3ca8   Steven Rostedt   jump label: Fix e...
1364
  	preempt_disable();
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1365
1366
  
  	/* Ensure it is not in reserved area nor out of text */
ec30c5f3a   Masami Hiramatsu   kprobes: Use kern...
1367
  	if (!kernel_text_address((unsigned long) p->addr) ||
4554dbcb8   Masami Hiramatsu   kprobes: Check pr...
1368
  	    in_kprobes_functions((unsigned long) p->addr) ||
f986a499e   Prashanth Nageshappa   kprobes: return p...
1369
1370
  	    jump_label_text_reserved(p->addr, p->addr)) {
  		ret = -EINVAL;
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1371
  		goto out;
f986a499e   Prashanth Nageshappa   kprobes: return p...
1372
  	}
b3e55c727   Mao, Bibo   [PATCH] Kprobes: ...
1373

f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1374
1375
1376
  	/* Check if are we probing a module */
  	*probed_mod = __module_text_address((unsigned long) p->addr);
  	if (*probed_mod) {
6f716acd5   Christoph Hellwig   kprobes: codingst...
1377
  		/*
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1378
1379
  		 * We must hold a refcount of the probed module while updating
  		 * its code to prohibit unexpected unloading.
df019b1d8   Keshavamurthy Anil S   [PATCH] kprobes: ...
1380
  		 */
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1381
1382
1383
1384
  		if (unlikely(!try_module_get(*probed_mod))) {
  			ret = -ENOENT;
  			goto out;
  		}
de31c3ca8   Steven Rostedt   jump label: Fix e...
1385

f24659d96   Masami Hiramatsu   kprobes: support ...
1386
1387
1388
1389
  		/*
  		 * If the module freed .init.text, we couldn't insert
  		 * kprobes in there.
  		 */
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1390
1391
1392
1393
1394
  		if (within_module_init((unsigned long)p->addr, *probed_mod) &&
  		    (*probed_mod)->state != MODULE_STATE_COMING) {
  			module_put(*probed_mod);
  			*probed_mod = NULL;
  			ret = -ENOENT;
f24659d96   Masami Hiramatsu   kprobes: support ...
1395
  		}
df019b1d8   Keshavamurthy Anil S   [PATCH] kprobes: ...
1396
  	}
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1397
  out:
a189d0350   Masami Hiramatsu   kprobes: disable ...
1398
  	preempt_enable();
de31c3ca8   Steven Rostedt   jump label: Fix e...
1399
  	jump_label_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1400

f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
  	return ret;
  }
  
  int __kprobes register_kprobe(struct kprobe *p)
  {
  	int ret;
  	struct kprobe *old_p;
  	struct module *probed_mod;
  	kprobe_opcode_t *addr;
  
  	/* Adjust probe address from symbol */
  	addr = kprobe_addr(p);
  	if (IS_ERR(addr))
  		return PTR_ERR(addr);
  	p->addr = addr;
  
  	ret = check_kprobe_rereg(p);
  	if (ret)
  		return ret;
  
  	/* User can pass only KPROBE_FLAG_DISABLED to register_kprobe */
  	p->flags &= KPROBE_FLAG_DISABLED;
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1423
  	p->nmissed = 0;
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1424
  	INIT_LIST_HEAD(&p->list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1425

f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1426
1427
1428
1429
1430
  	ret = check_kprobe_address_safe(p, &probed_mod);
  	if (ret)
  		return ret;
  
  	mutex_lock(&kprobe_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1431

64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1432
1433
  	old_p = get_kprobe(p->addr);
  	if (old_p) {
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1434
  		/* Since this may unoptimize old_p, locking text_mutex. */
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1435
  		ret = register_aggr_kprobe(old_p, p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1436
1437
  		goto out;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1438

25764288d   Masami Hiramatsu   kprobes: Move loc...
1439
  	mutex_lock(&text_mutex);	/* Avoiding text modification */
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1440
  	ret = prepare_kprobe(p);
25764288d   Masami Hiramatsu   kprobes: Move loc...
1441
  	mutex_unlock(&text_mutex);
6f716acd5   Christoph Hellwig   kprobes: codingst...
1442
  	if (ret)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1443
  		goto out;
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1444

64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1445
  	INIT_HLIST_NODE(&p->hlist);
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1446
  	hlist_add_head_rcu(&p->hlist,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1447
  		       &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1448
  	if (!kprobes_all_disarmed && !kprobe_disabled(p))
25764288d   Masami Hiramatsu   kprobes: Move loc...
1449
  		arm_kprobe(p);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1450
1451
1452
  
  	/* Try to optimize kprobe */
  	try_to_optimize_kprobe(p);
74a0b5762   Christoph Hellwig   x86: optimize pag...
1453

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1454
  out:
7a7d1cf95   Ingo Molnar   [PATCH] sem2mutex...
1455
  	mutex_unlock(&kprobe_mutex);
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1456

e8386a0cb   Masami Hiramatsu   kprobes: support ...
1457
  	if (probed_mod)
df019b1d8   Keshavamurthy Anil S   [PATCH] kprobes: ...
1458
  		module_put(probed_mod);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1459

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1460
1461
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1462
  EXPORT_SYMBOL_GPL(register_kprobe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1463

6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
  /* 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)) {
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1497
  			disarm_kprobe(orig_p, true);
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1498
1499
1500
1501
1502
1503
  			orig_p->flags |= KPROBE_FLAG_DISABLED;
  		}
  	}
  
  	return orig_p;
  }
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1504
1505
1506
1507
1508
  /*
   * Unregister a kprobe without a scheduler synchronization.
   */
  static int __kprobes __unregister_kprobe_top(struct kprobe *p)
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1509
  	struct kprobe *ap, *list_p;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1510

6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1511
1512
  	/* Disable kprobe. This will disarm it if needed. */
  	ap = __disable_kprobe(p);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1513
  	if (ap == NULL)
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1514
  		return -EINVAL;
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1515
  	if (ap == p)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
1516
  		/*
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1517
1518
  		 * 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...
1519
  		 */
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1520
1521
1522
1523
  		goto disarmed;
  
  	/* Following process expects this probe is an aggrprobe */
  	WARN_ON(!kprobe_aggrprobe(ap));
6274de498   Masami Hiramatsu   kprobes: Support ...
1524
1525
1526
1527
1528
  	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 ...
1529
1530
1531
  		goto disarmed;
  	else {
  		/* If disabling probe has special handlers, update aggrprobe */
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1532
  		if (p->break_handler && !kprobe_gone(p))
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1533
  			ap->break_handler = NULL;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1534
  		if (p->post_handler && !kprobe_gone(p)) {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1535
  			list_for_each_entry_rcu(list_p, &ap->list, list) {
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1536
1537
1538
  				if ((list_p != p) && (list_p->post_handler))
  					goto noclean;
  			}
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1539
  			ap->post_handler = NULL;
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1540
1541
  		}
  noclean:
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1542
1543
1544
1545
  		/*
  		 * Remove from the aggrprobe: this path will do nothing in
  		 * __unregister_kprobe_bottom().
  		 */
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1546
  		list_del_rcu(&p->list);
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1547
1548
1549
1550
1551
1552
  		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: ...
1553
  	}
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1554
  	return 0;
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1555
1556
  
  disarmed:
6274de498   Masami Hiramatsu   kprobes: Support ...
1557
  	BUG_ON(!kprobe_disarmed(ap));
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1558
1559
  	hlist_del_rcu(&ap->hlist);
  	return 0;
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1560
  }
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1561

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

e8386a0cb   Masami Hiramatsu   kprobes: support ...
1566
  	if (list_empty(&p->list))
6274de498   Masami Hiramatsu   kprobes: Support ...
1567
  		/* This is an independent kprobe */
0498b6350   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1568
  		arch_remove_kprobe(p);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1569
  	else if (list_is_singular(&p->list)) {
6274de498   Masami Hiramatsu   kprobes: Support ...
1570
  		/* This is the last child of an aggrprobe */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1571
  		ap = list_entry(p->list.next, struct kprobe, list);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1572
  		list_del(&p->list);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1573
  		free_aggr_kprobe(ap);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1574
  	}
6274de498   Masami Hiramatsu   kprobes: Support ...
1575
  	/* Otherwise, do nothing. */
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1576
  }
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1577
  int __kprobes register_kprobes(struct kprobe **kps, int num)
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1578
1579
1580
1581
1582
1583
  {
  	int i, ret = 0;
  
  	if (num <= 0)
  		return -EINVAL;
  	for (i = 0; i < num; i++) {
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1584
  		ret = register_kprobe(kps[i]);
67dddaad5   Masami Hiramatsu   kprobes: fix erro...
1585
1586
1587
  		if (ret < 0) {
  			if (i > 0)
  				unregister_kprobes(kps, i);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1588
  			break;
367216567   mao, bibo   [PATCH] Kprobe: m...
1589
  		}
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1590
  	}
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1591
1592
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1593
  EXPORT_SYMBOL_GPL(register_kprobes);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1594

9861668f7   Masami Hiramatsu   kprobes: add (un)...
1595
1596
1597
1598
  void __kprobes unregister_kprobe(struct kprobe *p)
  {
  	unregister_kprobes(&p, 1);
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1599
  EXPORT_SYMBOL_GPL(unregister_kprobe);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1600

9861668f7   Masami Hiramatsu   kprobes: add (un)...
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
  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
1617
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1618
  EXPORT_SYMBOL_GPL(unregister_kprobes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1619
1620
1621
  
  static struct notifier_block kprobe_exceptions_nb = {
  	.notifier_call = kprobe_exceptions_notify,
3d5631e06   Anil S Keshavamurthy   [PATCH] Kprobes r...
1622
1623
  	.priority = 0x7fffffff /* we need to be notified first */
  };
3d7e33825   Michael Ellerman   jprobes: make jpr...
1624
1625
1626
1627
  unsigned long __weak arch_deref_entry_point(void *entry)
  {
  	return (unsigned long)entry;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1628

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

26b31c190   Masami Hiramatsu   kprobes: add (un)...
1634
  	if (num <= 0)
3d7e33825   Michael Ellerman   jprobes: make jpr...
1635
  		return -EINVAL;
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1636
  	for (i = 0; i < num; i++) {
05662bdb6   Namhyung Kim   kprobes: Verify j...
1637
  		unsigned long addr, offset;
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1638
1639
  		jp = jps[i];
  		addr = arch_deref_entry_point(jp->entry);
05662bdb6   Namhyung Kim   kprobes: Verify j...
1640
1641
1642
1643
1644
1645
1646
1647
  		/* 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...
1648

67dddaad5   Masami Hiramatsu   kprobes: fix erro...
1649
1650
1651
  		if (ret < 0) {
  			if (i > 0)
  				unregister_jprobes(jps, i);
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1652
1653
1654
1655
1656
  			break;
  		}
  	}
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1657
  EXPORT_SYMBOL_GPL(register_jprobes);
3d7e33825   Michael Ellerman   jprobes: make jpr...
1658

26b31c190   Masami Hiramatsu   kprobes: add (un)...
1659
1660
  int __kprobes register_jprobe(struct jprobe *jp)
  {
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1661
  	return register_jprobes(&jp, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1662
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1663
  EXPORT_SYMBOL_GPL(register_jprobe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1664

d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1665
  void __kprobes unregister_jprobe(struct jprobe *jp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1666
  {
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1667
1668
  	unregister_jprobes(&jp, 1);
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1669
  EXPORT_SYMBOL_GPL(unregister_jprobe);
26b31c190   Masami Hiramatsu   kprobes: add (un)...
1670

26b31c190   Masami Hiramatsu   kprobes: add (un)...
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
  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
1688
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1689
  EXPORT_SYMBOL_GPL(unregister_jprobes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1690

9edddaa20   Ananth N Mavinakayanahalli   Kprobes: indicate...
1691
  #ifdef CONFIG_KRETPROBES
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1692
1693
1694
1695
1696
1697
1698
1699
  /*
   * 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 ...
1700
1701
  	unsigned long hash, flags = 0;
  	struct kretprobe_instance *ri;
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1702
1703
  
  	/*TODO: consider to only swap the RA after the last pre_handler fired */
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1704
  	hash = hash_ptr(current, KPROBE_HASH_BITS);
ec484608c   Thomas Gleixner   locking, kprobes:...
1705
  	raw_spin_lock_irqsave(&rp->lock, flags);
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1706
  	if (!hlist_empty(&rp->free_instances)) {
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1707
  		ri = hlist_entry(rp->free_instances.first,
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1708
1709
  				struct kretprobe_instance, hlist);
  		hlist_del(&ri->hlist);
ec484608c   Thomas Gleixner   locking, kprobes:...
1710
  		raw_spin_unlock_irqrestore(&rp->lock, flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1711

4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1712
1713
  		ri->rp = rp;
  		ri->task = current;
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1714

55ca6140e   Jiang Liu   kprobes: fix a me...
1715
1716
1717
1718
  		if (rp->entry_handler && rp->entry_handler(ri, regs)) {
  			raw_spin_lock_irqsave(&rp->lock, flags);
  			hlist_add_head(&ri->hlist, &rp->free_instances);
  			raw_spin_unlock_irqrestore(&rp->lock, flags);
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1719
  			return 0;
55ca6140e   Jiang Liu   kprobes: fix a me...
1720
  		}
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1721

4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1722
1723
1724
  		arch_prepare_kretprobe(ri, regs);
  
  		/* XXX(hch): why is there no hlist_move_head? */
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1725
1726
1727
1728
1729
  		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...
1730
  		rp->nmissed++;
ec484608c   Thomas Gleixner   locking, kprobes:...
1731
  		raw_spin_unlock_irqrestore(&rp->lock, flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1732
  	}
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1733
1734
  	return 0;
  }
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1735
  int __kprobes register_kretprobe(struct kretprobe *rp)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1736
1737
1738
1739
  {
  	int ret = 0;
  	struct kretprobe_instance *inst;
  	int i;
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1740
  	void *addr;
f438d914b   Masami Hiramatsu   kprobes: support ...
1741
1742
  
  	if (kretprobe_blacklist_size) {
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1743
  		addr = kprobe_addr(&rp->kp);
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1744
1745
  		if (IS_ERR(addr))
  			return PTR_ERR(addr);
f438d914b   Masami Hiramatsu   kprobes: support ...
1746
1747
1748
1749
1750
1751
  
  		for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
  			if (kretprobe_blacklist[i].addr == addr)
  				return -EINVAL;
  		}
  	}
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1752
1753
  
  	rp->kp.pre_handler = pre_handler_kretprobe;
7522a8423   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1754
1755
1756
  	rp->kp.post_handler = NULL;
  	rp->kp.fault_handler = NULL;
  	rp->kp.break_handler = NULL;
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1757
1758
1759
1760
  
  	/* Pre-allocate memory for max kretprobe instances */
  	if (rp->maxactive <= 0) {
  #ifdef CONFIG_PREEMPT
c2ef6661c   Heiko Carstens   kprobes: Fix dist...
1761
  		rp->maxactive = max_t(unsigned int, 10, 2*num_possible_cpus());
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1762
  #else
4dae560f9   Ananth N Mavinakayanahalli   kprobes: Sanitize...
1763
  		rp->maxactive = num_possible_cpus();
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1764
1765
  #endif
  	}
ec484608c   Thomas Gleixner   locking, kprobes:...
1766
  	raw_spin_lock_init(&rp->lock);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1767
1768
  	INIT_HLIST_HEAD(&rp->free_instances);
  	for (i = 0; i < rp->maxactive; i++) {
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1769
1770
  		inst = kmalloc(sizeof(struct kretprobe_instance) +
  			       rp->data_size, GFP_KERNEL);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1771
1772
1773
1774
  		if (inst == NULL) {
  			free_rp_inst(rp);
  			return -ENOMEM;
  		}
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1775
1776
  		INIT_HLIST_NODE(&inst->hlist);
  		hlist_add_head(&inst->hlist, &rp->free_instances);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1777
1778
1779
1780
  	}
  
  	rp->nmissed = 0;
  	/* Establish function entry probe point */
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1781
  	ret = register_kprobe(&rp->kp);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1782
  	if (ret != 0)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1783
1784
1785
  		free_rp_inst(rp);
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1786
  EXPORT_SYMBOL_GPL(register_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1787

49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1788
  int __kprobes register_kretprobes(struct kretprobe **rps, int num)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1789
1790
1791
1792
1793
1794
  {
  	int ret = 0, i;
  
  	if (num <= 0)
  		return -EINVAL;
  	for (i = 0; i < num; i++) {
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1795
  		ret = register_kretprobe(rps[i]);
67dddaad5   Masami Hiramatsu   kprobes: fix erro...
1796
1797
1798
  		if (ret < 0) {
  			if (i > 0)
  				unregister_kretprobes(rps, i);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1799
1800
1801
1802
1803
  			break;
  		}
  	}
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1804
  EXPORT_SYMBOL_GPL(register_kretprobes);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1805

4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1806
1807
1808
1809
  void __kprobes unregister_kretprobe(struct kretprobe *rp)
  {
  	unregister_kretprobes(&rp, 1);
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1810
  EXPORT_SYMBOL_GPL(unregister_kretprobe);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1811

4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
  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...
1832
  EXPORT_SYMBOL_GPL(unregister_kretprobes);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1833

9edddaa20   Ananth N Mavinakayanahalli   Kprobes: indicate...
1834
  #else /* CONFIG_KRETPROBES */
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1835
  int __kprobes register_kretprobe(struct kretprobe *rp)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1836
1837
1838
  {
  	return -ENOSYS;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1839
  EXPORT_SYMBOL_GPL(register_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1840

4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1841
  int __kprobes register_kretprobes(struct kretprobe **rps, int num)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
1842
  {
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1843
  	return -ENOSYS;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
1844
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1845
  EXPORT_SYMBOL_GPL(register_kretprobes);
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1846
  void __kprobes unregister_kretprobe(struct kretprobe *rp)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1847
  {
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1848
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1849
  EXPORT_SYMBOL_GPL(unregister_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1850

4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1851
1852
1853
  void __kprobes unregister_kretprobes(struct kretprobe **rps, int num)
  {
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1854
  EXPORT_SYMBOL_GPL(unregister_kretprobes);
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1855

4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1856
1857
1858
1859
  static int __kprobes pre_handler_kretprobe(struct kprobe *p,
  					   struct pt_regs *regs)
  {
  	return 0;
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1860
  }
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1861
  #endif /* CONFIG_KRETPROBES */
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1862
1863
1864
1865
  /* 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 ...
1866

e8386a0cb   Masami Hiramatsu   kprobes: support ...
1867
  	p->flags |= KPROBE_FLAG_GONE;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1868
  	if (kprobe_aggrprobe(p)) {
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1869
1870
1871
1872
1873
1874
1875
1876
  		/*
  		 * 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...
1877
  		kill_optimized_kprobe(p);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1878
1879
1880
1881
1882
1883
1884
  	}
  	/*
  	 * 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...
1885
1886
1887
1888
  /* Disable one kprobe */
  int __kprobes disable_kprobe(struct kprobe *kp)
  {
  	int ret = 0;
c0614829c   Masami Hiramatsu   kprobes: Move ena...
1889
1890
  
  	mutex_lock(&kprobe_mutex);
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1891
1892
  	/* Disable this kprobe */
  	if (__disable_kprobe(kp) == NULL)
c0614829c   Masami Hiramatsu   kprobes: Move ena...
1893
  		ret = -EINVAL;
c0614829c   Masami Hiramatsu   kprobes: Move ena...
1894

c0614829c   Masami Hiramatsu   kprobes: Move ena...
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
  	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: ...
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
  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 ...
1943
1944
1945
1946
1947
1948
  /* 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;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1949
1950
  	struct kprobe *p;
  	unsigned int i;
f24659d96   Masami Hiramatsu   kprobes: support ...
1951
  	int checkcore = (val == MODULE_STATE_GOING);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1952

f24659d96   Masami Hiramatsu   kprobes: support ...
1953
  	if (val != MODULE_STATE_GOING && val != MODULE_STATE_LIVE)
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1954
1955
1956
  		return NOTIFY_DONE;
  
  	/*
f24659d96   Masami Hiramatsu   kprobes: support ...
1957
1958
1959
1960
  	 * 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 ...
1961
1962
1963
1964
  	 */
  	mutex_lock(&kprobe_mutex);
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
b67bfe0d4   Sasha Levin   hlist: drop the n...
1965
  		hlist_for_each_entry_rcu(p, head, hlist)
f24659d96   Masami Hiramatsu   kprobes: support ...
1966
1967
1968
  			if (within_module_init((unsigned long)p->addr, mod) ||
  			    (checkcore &&
  			     within_module_core((unsigned long)p->addr, mod))) {
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
  				/*
  				 * 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
1985
1986
1987
  static int __init init_kprobes(void)
  {
  	int i, err = 0;
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
1988
  	unsigned long offset = 0, size = 0;
ab7678656   Joe Mario   kprobes: use KSYM...
1989
  	char *modname, namebuf[KSYM_NAME_LEN];
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
1990
1991
1992
  	const char *symbol_name;
  	void *addr;
  	struct kprobe_blackpoint *kb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1993
1994
1995
  
  	/* FIXME allocate the probe table, currently defined statically */
  	/* initialize all list heads */
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1996
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1997
  		INIT_HLIST_HEAD(&kprobe_table[i]);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1998
  		INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
ec484608c   Thomas Gleixner   locking, kprobes:...
1999
  		raw_spin_lock_init(&(kretprobe_table_locks[i].lock));
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2000
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2001

3d8d996e0   Srinivasa Ds   kprobes: prevent ...
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
  	/*
  	 * 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 ...
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
  	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...
2034
2035
  #if defined(CONFIG_OPTPROBES)
  #if defined(__ARCH_WANT_KPROBES_INSN_SLOT)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2036
2037
2038
  	/* Init kprobe_optinsn_slots */
  	kprobe_optinsn_slots.insn_size = MAX_OPTINSN_SIZE;
  #endif
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
2039
2040
2041
  	/* By default, kprobes can be optimized */
  	kprobes_allow_optimization = true;
  #endif
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2042

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

6772926be   Rusty Lynch   [PATCH] kprobes: ...
2046
  	err = arch_init_kprobes();
802eae7c8   Rusty Lynch   [PATCH] Return pr...
2047
2048
  	if (!err)
  		err = register_die_notifier(&kprobe_exceptions_nb);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2049
2050
  	if (!err)
  		err = register_module_notifier(&kprobe_module_nb);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
2051
  	kprobes_initialized = (err == 0);
802eae7c8   Rusty Lynch   [PATCH] Return pr...
2052

8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
2053
2054
  	if (!err)
  		init_test_probes();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2055
2056
  	return err;
  }
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2057
2058
  #ifdef CONFIG_DEBUG_FS
  static void __kprobes report_probe(struct seq_file *pi, struct kprobe *p,
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2059
  		const char *sym, int offset, char *modname, struct kprobe *pp)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2060
2061
2062
2063
2064
2065
2066
2067
2068
  {
  	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...
2069

346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2070
  	if (sym)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2071
  		seq_printf(pi, "%p  %s  %s+0x%x  %s ",
de5bd88d5   Masami Hiramatsu   kprobes: support ...
2072
  			p->addr, kprobe_type, sym, offset,
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2073
  			(modname ? modname : " "));
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2074
  	else
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2075
2076
2077
2078
2079
  		seq_printf(pi, "%p  %s  %p ",
  			p->addr, kprobe_type, p->addr);
  
  	if (!pp)
  		pp = p;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
2080
2081
  	seq_printf(pi, "%s%s%s%s
  ",
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2082
2083
  		(kprobe_gone(p) ? "[GONE]" : ""),
  		((kprobe_disabled(p) && !kprobe_gone(p)) ?  "[DISABLED]" : ""),
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
2084
2085
  		(kprobe_optimized(pp) ? "[OPTIMIZED]" : ""),
  		(kprobe_ftrace(pp) ? "[FTRACE]" : ""));
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
  }
  
  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;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2109
2110
2111
  	struct kprobe *p, *kp;
  	const char *sym = NULL;
  	unsigned int i = *(loff_t *) v;
ffb451227   Alexey Dobriyan   Simplify kallsyms...
2112
  	unsigned long offset = 0;
ab7678656   Joe Mario   kprobes: use KSYM...
2113
  	char *modname, namebuf[KSYM_NAME_LEN];
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2114
2115
2116
  
  	head = &kprobe_table[i];
  	preempt_disable();
b67bfe0d4   Sasha Levin   hlist: drop the n...
2117
  	hlist_for_each_entry_rcu(p, head, hlist) {
ffb451227   Alexey Dobriyan   Simplify kallsyms...
2118
  		sym = kallsyms_lookup((unsigned long)p->addr, NULL,
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2119
  					&offset, &modname, namebuf);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2120
  		if (kprobe_aggrprobe(p)) {
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2121
  			list_for_each_entry_rcu(kp, &p->list, list)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2122
  				report_probe(pi, kp, sym, offset, modname, p);
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2123
  		} else
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2124
  			report_probe(pi, p, sym, offset, modname, NULL);
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2125
2126
2127
2128
  	}
  	preempt_enable();
  	return 0;
  }
88e9d34c7   James Morris   seq_file: constif...
2129
  static const struct seq_operations kprobes_seq_ops = {
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
  	.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...
2140
  static const struct file_operations debugfs_kprobes_operations = {
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2141
2142
2143
2144
2145
  	.open           = kprobes_open,
  	.read           = seq_read,
  	.llseek         = seq_lseek,
  	.release        = seq_release,
  };
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2146
  static void __kprobes arm_all_kprobes(void)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2147
2148
  {
  	struct hlist_head *head;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2149
2150
2151
2152
  	struct kprobe *p;
  	unsigned int i;
  
  	mutex_lock(&kprobe_mutex);
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2153
2154
  	/* If kprobes are armed, just return */
  	if (!kprobes_all_disarmed)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2155
  		goto already_enabled;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2156
  	/* Arming kprobes doesn't optimize kprobe itself */
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2157
2158
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
b67bfe0d4   Sasha Levin   hlist: drop the n...
2159
  		hlist_for_each_entry_rcu(p, head, hlist)
de5bd88d5   Masami Hiramatsu   kprobes: support ...
2160
  			if (!kprobe_disabled(p))
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
2161
  				arm_kprobe(p);
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2162
  	}
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2163
  	kprobes_all_disarmed = false;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2164
2165
2166
2167
2168
2169
2170
  	printk(KERN_INFO "Kprobes globally enabled
  ");
  
  already_enabled:
  	mutex_unlock(&kprobe_mutex);
  	return;
  }
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2171
  static void __kprobes disarm_all_kprobes(void)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2172
2173
  {
  	struct hlist_head *head;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2174
2175
2176
2177
  	struct kprobe *p;
  	unsigned int i;
  
  	mutex_lock(&kprobe_mutex);
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2178
  	/* If kprobes are already disarmed, just return */
6274de498   Masami Hiramatsu   kprobes: Support ...
2179
2180
2181
2182
  	if (kprobes_all_disarmed) {
  		mutex_unlock(&kprobe_mutex);
  		return;
  	}
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2183

e579abeb5   Masami Hiramatsu   kprobes: rename k...
2184
  	kprobes_all_disarmed = true;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2185
2186
  	printk(KERN_INFO "Kprobes globally disabled
  ");
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2187

bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2188
2189
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
b67bfe0d4   Sasha Levin   hlist: drop the n...
2190
  		hlist_for_each_entry_rcu(p, head, hlist) {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
2191
  			if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p))
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
2192
  				disarm_kprobe(p, false);
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2193
2194
  		}
  	}
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2195
  	mutex_unlock(&kprobe_mutex);
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2196

6274de498   Masami Hiramatsu   kprobes: Support ...
2197
2198
  	/* Wait for disarming all kprobes by optimizer */
  	wait_for_kprobe_optimizer();
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
  }
  
  /*
   * 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...
2210
  	if (!kprobes_all_disarmed)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
  		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 ...
2224
  	size_t buf_size;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2225
2226
2227
2228
  
  	buf_size = min(count, (sizeof(buf)-1));
  	if (copy_from_user(buf, user_buf, buf_size))
  		return -EFAULT;
10fb46d5f   Mathias Krause   kprobes: handle e...
2229
  	buf[buf_size] = '\0';
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2230
2231
2232
2233
  	switch (buf[0]) {
  	case 'y':
  	case 'Y':
  	case '1':
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2234
  		arm_all_kprobes();
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2235
2236
2237
2238
  		break;
  	case 'n':
  	case 'N':
  	case '0':
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2239
  		disarm_all_kprobes();
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2240
  		break;
10fb46d5f   Mathias Krause   kprobes: handle e...
2241
2242
  	default:
  		return -EINVAL;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2243
2244
2245
2246
  	}
  
  	return count;
  }
828c09509   Alexey Dobriyan   const: constify r...
2247
  static const struct file_operations fops_kp = {
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2248
2249
  	.read =         read_enabled_file_bool,
  	.write =        write_enabled_file_bool,
6038f373a   Arnd Bergmann   llseek: automatic...
2250
  	.llseek =	default_llseek,
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2251
  };
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2252
2253
2254
  static int __kprobes debugfs_kprobe_init(void)
  {
  	struct dentry *dir, *file;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2255
  	unsigned int value = 1;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2256
2257
2258
2259
  
  	dir = debugfs_create_dir("kprobes", NULL);
  	if (!dir)
  		return -ENOMEM;
e38697929   Randy Dunlap   kprobes: fix spar...
2260
  	file = debugfs_create_file("list", 0444, dir, NULL,
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2261
2262
2263
2264
2265
  				&debugfs_kprobes_operations);
  	if (!file) {
  		debugfs_remove(dir);
  		return -ENOMEM;
  	}
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2266
2267
2268
2269
2270
2271
  	file = debugfs_create_file("enabled", 0600, dir,
  					&value, &fops_kp);
  	if (!file) {
  		debugfs_remove(dir);
  		return -ENOMEM;
  	}
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2272
2273
2274
2275
2276
2277
2278
  	return 0;
  }
  
  late_initcall(debugfs_kprobe_init);
  #endif /* CONFIG_DEBUG_FS */
  
  module_init(init_kprobes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2279

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