Blame view

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

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

ef53d9c5e   Srinivasa D S   kprobes: improve ...
47
  static int kprobes_initialized;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
  static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
49
  static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50

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

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

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

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

9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
118
  /**
129415607   Masami Hiramatsu   kprobes: add kpro...
119
   * __get_insn_slot() - Find a slot on an executable page for an instruction.
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
120
121
   * We allocate an executable page if there's no room on existing ones.
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
122
  kprobe_opcode_t *__get_insn_slot(struct kprobe_insn_cache *c)
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
123
124
  {
  	struct kprobe_insn_page *kip;
c802d64a3   Heiko Carstens   kprobes: unify in...
125
  	kprobe_opcode_t *slot = NULL;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
126

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

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

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

4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
210
  	list_for_each_entry_safe(kip, next, &c->pages, list) {
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
211
  		int i;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
212
213
214
  		if (kip->ngarbage == 0)
  			continue;
  		kip->ngarbage = 0;	/* we will collect all garbages */
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
215
  		for (i = 0; i < slots_per_page(c); i++) {
5b485629b   Masami Hiramatsu   kprobes, extable:...
216
  			if (kip->slot_used[i] == SLOT_DIRTY && collect_one_slot(kip, i))
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
217
218
219
  				break;
  		}
  	}
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
220
  	c->nr_garbage = 0;
b4c6c34a5   Masami Hiramatsu   [PATCH] kprobes: ...
221
222
  	return 0;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
223
224
  void __free_insn_slot(struct kprobe_insn_cache *c,
  		      kprobe_opcode_t *slot, int dirty)
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
225
226
  {
  	struct kprobe_insn_page *kip;
5b485629b   Masami Hiramatsu   kprobes, extable:...
227
  	long idx;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
228

c802d64a3   Heiko Carstens   kprobes: unify in...
229
  	mutex_lock(&c->mutex);
5b485629b   Masami Hiramatsu   kprobes, extable:...
230
231
232
233
234
  	rcu_read_lock();
  	list_for_each_entry_rcu(kip, &c->pages, list) {
  		idx = ((long)slot - (long)kip->insns) /
  			(c->insn_size * sizeof(kprobe_opcode_t));
  		if (idx >= 0 && idx < slots_per_page(c))
c802d64a3   Heiko Carstens   kprobes: unify in...
235
  			goto out;
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
236
  	}
5b485629b   Masami Hiramatsu   kprobes, extable:...
237
  	/* Could not find this slot. */
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
238
  	WARN_ON(1);
5b485629b   Masami Hiramatsu   kprobes, extable:...
239
  	kip = NULL;
c802d64a3   Heiko Carstens   kprobes: unify in...
240
  out:
5b485629b   Masami Hiramatsu   kprobes, extable:...
241
242
243
244
245
246
247
248
249
250
251
252
253
254
  	rcu_read_unlock();
  	/* Mark and sweep: this may sleep */
  	if (kip) {
  		/* Check double free */
  		WARN_ON(kip->slot_used[idx] != SLOT_USED);
  		if (dirty) {
  			kip->slot_used[idx] = SLOT_DIRTY;
  			kip->ngarbage++;
  			if (++c->nr_garbage > slots_per_page(c))
  				collect_garbage_slots(c);
  		} else {
  			collect_one_slot(kip, idx);
  		}
  	}
c802d64a3   Heiko Carstens   kprobes: unify in...
255
  	mutex_unlock(&c->mutex);
4610ee1d3   Masami Hiramatsu   kprobes: Introduc...
256
  }
6f716acd5   Christoph Hellwig   kprobes: codingst...
257

5b485629b   Masami Hiramatsu   kprobes, extable:...
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
  /*
   * Check given address is on the page of kprobe instruction slots.
   * This will be used for checking whether the address on a stack
   * is on a text area or not.
   */
  bool __is_insn_slot_addr(struct kprobe_insn_cache *c, unsigned long addr)
  {
  	struct kprobe_insn_page *kip;
  	bool ret = false;
  
  	rcu_read_lock();
  	list_for_each_entry_rcu(kip, &c->pages, list) {
  		if (addr >= (unsigned long)kip->insns &&
  		    addr < (unsigned long)kip->insns + PAGE_SIZE) {
  			ret = true;
  			break;
  		}
  	}
  	rcu_read_unlock();
  
  	return ret;
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
280
281
  #ifdef CONFIG_OPTPROBES
  /* For optimized_kprobe buffer */
c802d64a3   Heiko Carstens   kprobes: unify in...
282
283
  struct kprobe_insn_cache kprobe_optinsn_slots = {
  	.mutex = __MUTEX_INITIALIZER(kprobe_optinsn_slots.mutex),
af96397de   Heiko Carstens   kprobes: allow to...
284
285
  	.alloc = alloc_insn_page,
  	.free = free_insn_page,
afd66255b   Masami Hiramatsu   kprobes: Introduc...
286
287
288
289
  	.pages = LIST_HEAD_INIT(kprobe_optinsn_slots.pages),
  	/* .insn_size is initialized later */
  	.nr_garbage = 0,
  };
afd66255b   Masami Hiramatsu   kprobes: Introduc...
290
  #endif
2d14e39da   Anil S Keshavamurthy   [PATCH] kprobes: ...
291
  #endif
9ec4b1f35   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
292

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
321
322
  	return NULL;
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
323
  NOKPROBE_SYMBOL(get_kprobe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
324

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
325
  static int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
326
327
328
329
330
331
  
  /* 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 ...
332
333
334
335
336
337
  /* 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...
338
339
340
  /*
   * Keep all fields in the kprobe consistent
   */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
341
  static inline void copy_kprobe(struct kprobe *ap, struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
342
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
343
344
  	memcpy(&p->opcode, &ap->opcode, sizeof(kprobe_opcode_t));
  	memcpy(&p->ainsn, &ap->ainsn, sizeof(struct arch_specific_insn));
afd66255b   Masami Hiramatsu   kprobes: Introduc...
345
346
347
  }
  
  #ifdef CONFIG_OPTPROBES
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
348
349
  /* NOTE: change this value only with kprobe_mutex held */
  static bool kprobes_allow_optimization;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
350
351
352
353
  /*
   * Call all pre_handler on the list, but ignores its return value.
   * This must be called from arch-dep optimized caller.
   */
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
354
  void opt_pre_handler(struct kprobe *p, struct pt_regs *regs)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
355
356
357
358
359
360
  {
  	struct kprobe *kp;
  
  	list_for_each_entry_rcu(kp, &p->list, list) {
  		if (kp->pre_handler && likely(!kprobe_disabled(kp))) {
  			set_kprobe_instance(kp);
4f3a87144   Naveen N. Rao   Revert "kprobes: ...
361
  			kp->pre_handler(kp, regs);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
362
363
364
365
  		}
  		reset_kprobe_instance();
  	}
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
366
  NOKPROBE_SYMBOL(opt_pre_handler);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
367

6274de498   Masami Hiramatsu   kprobes: Support ...
368
  /* Free optimized instructions and optimized_kprobe */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
369
  static void free_aggr_kprobe(struct kprobe *p)
6274de498   Masami Hiramatsu   kprobes: Support ...
370
371
372
373
374
375
376
377
  {
  	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...
378
379
380
381
382
383
384
385
386
387
388
389
  /* 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 ...
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 */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
405
  static int kprobe_queued(struct kprobe *p)
6274de498   Masami Hiramatsu   kprobes: Support ...
406
407
408
409
410
411
412
413
414
415
  {
  	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...
416
417
418
419
  /*
   * Return an optimized kprobe whose optimizing code replaces
   * instructions including addr (exclude breakpoint).
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
420
  static struct kprobe *get_optimized_kprobe(unsigned long addr)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
  {
  	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 ...
441
  static LIST_HEAD(unoptimizing_list);
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
442
  static LIST_HEAD(freeing_list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
443
444
445
446
  
  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...
447
448
449
450
  /*
   * Optimize (replace a breakpoint with a jump) kprobes listed on
   * optimizing_list.
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
451
  static void do_optimize_kprobes(void)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
452
  {
f1c6ece23   Andrea Righi   kprobes: Fix pote...
453
  	lockdep_assert_held(&text_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
454
455
456
457
458
459
460
  	/*
  	 * The optimization/unoptimization refers online_cpus via
  	 * stop_machine() and cpu-hotplug modifies online_cpus.
  	 * And same time, text_mutex will be held in cpu-hotplug and here.
  	 * This combination can cause a deadlock (cpu-hotplug try to lock
  	 * text_mutex but stop_machine can not be done because online_cpus
  	 * has been changed)
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
461
  	 * To avoid this deadlock, caller must have locked cpu hotplug
afd66255b   Masami Hiramatsu   kprobes: Introduc...
462
463
  	 * for preventing cpu-hotplug outside of text_mutex locking.
  	 */
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
464
465
466
467
468
469
  	lockdep_assert_cpus_held();
  
  	/* Optimization never be done when disarmed */
  	if (kprobes_all_disarmed || !kprobes_allow_optimization ||
  	    list_empty(&optimizing_list))
  		return;
cd7ebe229   Masami Hiramatsu   kprobes: Use text...
470
  	arch_optimize_kprobes(&optimizing_list);
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
471
  }
6274de498   Masami Hiramatsu   kprobes: Support ...
472
473
474
475
  /*
   * Unoptimize (replace a jump with a breakpoint and remove the breakpoint
   * if need) kprobes listed on unoptimizing_list.
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
476
  static void do_unoptimize_kprobes(void)
6274de498   Masami Hiramatsu   kprobes: Support ...
477
478
  {
  	struct optimized_kprobe *op, *tmp;
f1c6ece23   Andrea Righi   kprobes: Fix pote...
479
  	lockdep_assert_held(&text_mutex);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
480
481
  	/* See comment in do_optimize_kprobes() */
  	lockdep_assert_cpus_held();
6274de498   Masami Hiramatsu   kprobes: Support ...
482
483
484
  	/* Unoptimization must be done anytime */
  	if (list_empty(&unoptimizing_list))
  		return;
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
485
  	arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list);
f984ba4eb   Masami Hiramatsu   kprobes: Use text...
486
  	/* Loop free_list for disarming */
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
487
  	list_for_each_entry_safe(op, tmp, &freeing_list, list) {
74c515e04   Masami Hiramatsu   kprobes: Set unop...
488
489
  		/* Switching from detour code to origin */
  		op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
6274de498   Masami Hiramatsu   kprobes: Support ...
490
491
492
493
494
495
496
497
498
499
  		/* 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 ...
500
501
502
  		} else
  			list_del_init(&op->list);
  	}
6274de498   Masami Hiramatsu   kprobes: Support ...
503
504
505
  }
  
  /* Reclaim all kprobes on the free_list */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
506
  static void do_free_cleaned_kprobes(void)
6274de498   Masami Hiramatsu   kprobes: Support ...
507
508
  {
  	struct optimized_kprobe *op, *tmp;
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
509
  	list_for_each_entry_safe(op, tmp, &freeing_list, list) {
6274de498   Masami Hiramatsu   kprobes: Support ...
510
  		list_del_init(&op->list);
cbdd96f55   Masami Hiramatsu   kprobes: Don't ca...
511
512
513
514
515
516
517
  		if (WARN_ON_ONCE(!kprobe_unused(&op->kp))) {
  			/*
  			 * This must not happen, but if there is a kprobe
  			 * still in use, keep it on kprobes hash list.
  			 */
  			continue;
  		}
6274de498   Masami Hiramatsu   kprobes: Support ...
518
519
520
521
522
  		free_aggr_kprobe(&op->kp);
  	}
  }
  
  /* Start optimizer after OPTIMIZE_DELAY passed */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
523
  static void kick_kprobe_optimizer(void)
6274de498   Masami Hiramatsu   kprobes: Support ...
524
  {
ad72b3bea   Tejun Heo   kprobes: fix wait...
525
  	schedule_delayed_work(&optimizing_work, OPTIMIZE_DELAY);
6274de498   Masami Hiramatsu   kprobes: Support ...
526
  }
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
527
  /* Kprobe jump optimizer */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
528
  static void kprobe_optimizer(struct work_struct *work)
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
529
  {
72ef3794c   Steven Rostedt   kprobes: Inverse ...
530
  	mutex_lock(&kprobe_mutex);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
531
  	cpus_read_lock();
f1c6ece23   Andrea Righi   kprobes: Fix pote...
532
  	mutex_lock(&text_mutex);
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
533
534
  	/* Lock modules while optimizing kprobes */
  	mutex_lock(&module_mutex);
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
535
536
  
  	/*
6274de498   Masami Hiramatsu   kprobes: Support ...
537
538
539
  	 * Step 1: Unoptimize kprobes and collect cleaned (unused and disarmed)
  	 * kprobes before waiting for quiesence period.
  	 */
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
540
  	do_unoptimize_kprobes();
6274de498   Masami Hiramatsu   kprobes: Support ...
541
542
  
  	/*
a30b85df7   Masami Hiramatsu   kprobes: Use sync...
543
544
545
546
547
548
549
  	 * Step 2: Wait for quiesence period to ensure all potentially
  	 * preempted tasks to have normally scheduled. Because optprobe
  	 * may modify multiple instructions, there is a chance that Nth
  	 * instruction is preempted. In that case, such tasks can return
  	 * to 2nd-Nth byte of jump instruction. This wait is for avoiding it.
  	 * Note that on non-preemptive kernel, this is transparently converted
  	 * to synchronoze_sched() to wait for all interrupts to have completed.
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
550
  	 */
a30b85df7   Masami Hiramatsu   kprobes: Use sync...
551
  	synchronize_rcu_tasks();
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
552

6274de498   Masami Hiramatsu   kprobes: Support ...
553
  	/* Step 3: Optimize kprobes after quiesence period */
61f4e13ff   Masami Hiramatsu   kprobes: Separate...
554
  	do_optimize_kprobes();
6274de498   Masami Hiramatsu   kprobes: Support ...
555
556
  
  	/* Step 4: Free cleaned kprobes after quiesence period */
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
557
  	do_free_cleaned_kprobes();
6274de498   Masami Hiramatsu   kprobes: Support ...
558

afd66255b   Masami Hiramatsu   kprobes: Introduc...
559
  	mutex_unlock(&module_mutex);
f1c6ece23   Andrea Righi   kprobes: Fix pote...
560
  	mutex_unlock(&text_mutex);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
561
  	cpus_read_unlock();
6274de498   Masami Hiramatsu   kprobes: Support ...
562

cd7ebe229   Masami Hiramatsu   kprobes: Use text...
563
  	/* Step 5: Kick optimizer again if needed */
f984ba4eb   Masami Hiramatsu   kprobes: Use text...
564
  	if (!list_empty(&optimizing_list) || !list_empty(&unoptimizing_list))
cd7ebe229   Masami Hiramatsu   kprobes: Use text...
565
  		kick_kprobe_optimizer();
c19f0c3c9   Masami Hiramatsu   kprobes: Fix to p...
566
567
  
  	mutex_unlock(&kprobe_mutex);
6274de498   Masami Hiramatsu   kprobes: Support ...
568
569
570
  }
  
  /* Wait for completing optimization and unoptimization */
30e7d894c   Thomas Gleixner   tracing/kprobes: ...
571
  void wait_for_kprobe_optimizer(void)
6274de498   Masami Hiramatsu   kprobes: Support ...
572
  {
ad72b3bea   Tejun Heo   kprobes: fix wait...
573
574
575
576
577
578
579
580
581
582
583
584
585
586
  	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...
587
  }
4771b3f60   Masami Hiramatsu   kprobes: Fix opti...
588
589
590
591
592
593
594
595
596
597
598
  static bool optprobe_queued_unopt(struct optimized_kprobe *op)
  {
  	struct optimized_kprobe *_op;
  
  	list_for_each_entry(_op, &unoptimizing_list, list) {
  		if (op == _op)
  			return true;
  	}
  
  	return false;
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
599
  /* Optimize kprobe if p is ready to be optimized */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
600
  static void optimize_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
601
602
603
604
  {
  	struct optimized_kprobe *op;
  
  	/* Check if the kprobe is disabled or not ready for optimization. */
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
605
  	if (!kprobe_optready(p) || !kprobes_allow_optimization ||
afd66255b   Masami Hiramatsu   kprobes: Introduc...
606
607
  	    (kprobe_disabled(p) || kprobes_all_disarmed))
  		return;
059053a27   Masami Hiramatsu   kprobes: Don't ch...
608
609
  	/* kprobes with post_handler can not be optimized */
  	if (p->post_handler)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
610
611
612
613
614
615
616
617
618
  		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. */
4771b3f60   Masami Hiramatsu   kprobes: Fix opti...
619
620
621
622
623
  	if (op->kp.flags & KPROBE_FLAG_OPTIMIZED) {
  		if (optprobe_queued_unopt(op)) {
  			/* This is under unoptimizing. Just dequeue the probe */
  			list_del_init(&op->list);
  		}
afd66255b   Masami Hiramatsu   kprobes: Introduc...
624
  		return;
4771b3f60   Masami Hiramatsu   kprobes: Fix opti...
625
  	}
afd66255b   Masami Hiramatsu   kprobes: Introduc...
626
  	op->kp.flags |= KPROBE_FLAG_OPTIMIZED;
6274de498   Masami Hiramatsu   kprobes: Support ...
627

4771b3f60   Masami Hiramatsu   kprobes: Fix opti...
628
629
630
631
632
633
  	/* On unoptimizing/optimizing_list, op must have OPTIMIZED flag */
  	if (WARN_ON_ONCE(!list_empty(&op->list)))
  		return;
  
  	list_add(&op->list, &optimizing_list);
  	kick_kprobe_optimizer();
6274de498   Masami Hiramatsu   kprobes: Support ...
634
635
636
  }
  
  /* Short cut to direct unoptimizing */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
637
  static void force_unoptimize_kprobe(struct optimized_kprobe *op)
6274de498   Masami Hiramatsu   kprobes: Support ...
638
  {
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
639
  	lockdep_assert_cpus_held();
6274de498   Masami Hiramatsu   kprobes: Support ...
640
  	arch_unoptimize_kprobe(op);
74c515e04   Masami Hiramatsu   kprobes: Set unop...
641
  	op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
6274de498   Masami Hiramatsu   kprobes: Support ...
642
643
  	if (kprobe_disabled(&op->kp))
  		arch_disarm_kprobe(&op->kp);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
644
645
646
  }
  
  /* Unoptimize a kprobe if p is optimized */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
647
  static void unoptimize_kprobe(struct kprobe *p, bool force)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
648
649
  {
  	struct optimized_kprobe *op;
6274de498   Masami Hiramatsu   kprobes: Support ...
650
651
652
653
  	if (!kprobe_aggrprobe(p) || kprobe_disarmed(p))
  		return; /* This is not an optprobe nor optimized */
  
  	op = container_of(p, struct optimized_kprobe, kp);
4771b3f60   Masami Hiramatsu   kprobes: Fix opti...
654
  	if (!kprobe_optimized(p))
6274de498   Masami Hiramatsu   kprobes: Support ...
655
  		return;
6274de498   Masami Hiramatsu   kprobes: Support ...
656

6274de498   Masami Hiramatsu   kprobes: Support ...
657
  	if (!list_empty(&op->list)) {
4771b3f60   Masami Hiramatsu   kprobes: Fix opti...
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
  		if (optprobe_queued_unopt(op)) {
  			/* Queued in unoptimizing queue */
  			if (force) {
  				/*
  				 * Forcibly unoptimize the kprobe here, and queue it
  				 * in the freeing list for release afterwards.
  				 */
  				force_unoptimize_kprobe(op);
  				list_move(&op->list, &freeing_list);
  			}
  		} else {
  			/* Dequeue from the optimizing queue */
  			list_del_init(&op->list);
  			op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
  		}
6274de498   Masami Hiramatsu   kprobes: Support ...
673
674
  		return;
  	}
4771b3f60   Masami Hiramatsu   kprobes: Fix opti...
675

6274de498   Masami Hiramatsu   kprobes: Support ...
676
  	/* Optimized kprobe case */
4771b3f60   Masami Hiramatsu   kprobes: Fix opti...
677
  	if (force) {
6274de498   Masami Hiramatsu   kprobes: Support ...
678
679
  		/* Forcibly update the code: this is a special case */
  		force_unoptimize_kprobe(op);
4771b3f60   Masami Hiramatsu   kprobes: Fix opti...
680
  	} else {
6274de498   Masami Hiramatsu   kprobes: Support ...
681
682
  		list_add(&op->list, &unoptimizing_list);
  		kick_kprobe_optimizer();
afd66255b   Masami Hiramatsu   kprobes: Introduc...
683
684
  	}
  }
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
685
  /* Cancel unoptimizing for reusing */
819319fc9   Masami Hiramatsu   kprobes: Return e...
686
  static int reuse_unused_kprobe(struct kprobe *ap)
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
687
688
  {
  	struct optimized_kprobe *op;
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
689
690
691
692
693
  	/*
  	 * Unused kprobe MUST be on the way of delayed unoptimizing (means
  	 * there is still a relative jump) and disabled.
  	 */
  	op = container_of(ap, struct optimized_kprobe, kp);
4458515b2   Masami Hiramatsu   kprobes: Replace ...
694
  	WARN_ON_ONCE(list_empty(&op->list));
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
695
696
697
  	/* Enable the probe again */
  	ap->flags &= ~KPROBE_FLAG_DISABLED;
  	/* Optimize it again (remove from op->list) */
5f843ed41   Masami Hiramatsu   kprobes: Fix erro...
698
699
  	if (!kprobe_optready(ap))
  		return -EINVAL;
819319fc9   Masami Hiramatsu   kprobes: Return e...
700

0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
701
  	optimize_kprobe(ap);
819319fc9   Masami Hiramatsu   kprobes: Return e...
702
  	return 0;
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
703
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
704
  /* Remove optimized instructions */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
705
  static void kill_optimized_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
706
707
708
709
  {
  	struct optimized_kprobe *op;
  
  	op = container_of(p, struct optimized_kprobe, kp);
6274de498   Masami Hiramatsu   kprobes: Support ...
710
711
  	if (!list_empty(&op->list))
  		/* Dequeue from the (un)optimization queue */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
712
  		list_del_init(&op->list);
6274de498   Masami Hiramatsu   kprobes: Support ...
713
  	op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
7b959fc58   Masami Hiramatsu   kprobes: Fix to f...
714
715
716
717
718
719
720
721
722
723
724
  
  	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 ...
725
  	/* Don't touch the code, because it is already freed. */
afd66255b   Masami Hiramatsu   kprobes: Introduc...
726
727
  	arch_remove_optimized_kprobe(op);
  }
a460246c7   Masami Hiramatsu   kprobes: Skip pre...
728
729
730
731
732
733
  static inline
  void __prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
  {
  	if (!kprobe_ftrace(p))
  		arch_prepare_optimized_kprobe(op, p);
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
734
  /* Try to prepare optimized instructions */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
735
  static void prepare_optimized_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
736
737
738
739
  {
  	struct optimized_kprobe *op;
  
  	op = container_of(p, struct optimized_kprobe, kp);
a460246c7   Masami Hiramatsu   kprobes: Skip pre...
740
  	__prepare_optimized_kprobe(op, p);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
741
  }
afd66255b   Masami Hiramatsu   kprobes: Introduc...
742
  /* Allocate new optimized_kprobe and try to prepare optimized instructions */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
743
  static struct kprobe *alloc_aggr_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
744
745
746
747
748
749
750
751
752
  {
  	struct optimized_kprobe *op;
  
  	op = kzalloc(sizeof(struct optimized_kprobe), GFP_KERNEL);
  	if (!op)
  		return NULL;
  
  	INIT_LIST_HEAD(&op->list);
  	op->kp.addr = p->addr;
a460246c7   Masami Hiramatsu   kprobes: Skip pre...
753
  	__prepare_optimized_kprobe(op, p);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
754
755
756
  
  	return &op->kp;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
757
  static void init_aggr_kprobe(struct kprobe *ap, struct kprobe *p);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
758
759
760
761
762
  
  /*
   * Prepare an optimized_kprobe and optimize it
   * NOTE: p must be a normal registered kprobe
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
763
  static void try_to_optimize_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
764
765
766
  {
  	struct kprobe *ap;
  	struct optimized_kprobe *op;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
767
768
769
  	/* Impossible to optimize ftrace-based kprobe */
  	if (kprobe_ftrace(p))
  		return;
25764288d   Masami Hiramatsu   kprobes: Move loc...
770
  	/* For preparing optimization, jump_label_text_reserved() is called */
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
771
  	cpus_read_lock();
25764288d   Masami Hiramatsu   kprobes: Move loc...
772
773
  	jump_label_lock();
  	mutex_lock(&text_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
774
775
  	ap = alloc_aggr_kprobe(p);
  	if (!ap)
25764288d   Masami Hiramatsu   kprobes: Move loc...
776
  		goto out;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
777
778
779
780
  
  	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 ...
781
782
  		arch_remove_optimized_kprobe(op);
  		kfree(op);
25764288d   Masami Hiramatsu   kprobes: Move loc...
783
  		goto out;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
784
785
786
  	}
  
  	init_aggr_kprobe(ap, p);
25764288d   Masami Hiramatsu   kprobes: Move loc...
787
788
789
790
791
  	optimize_kprobe(ap);	/* This just kicks optimizer thread */
  
  out:
  	mutex_unlock(&text_mutex);
  	jump_label_unlock();
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
792
  	cpus_read_unlock();
afd66255b   Masami Hiramatsu   kprobes: Introduc...
793
  }
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
794
  #ifdef CONFIG_SYSCTL
55479f647   Masami Hiramatsu   kprobes: Allow pr...
795
  static void optimize_all_kprobes(void)
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
796
797
  {
  	struct hlist_head *head;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
798
799
  	struct kprobe *p;
  	unsigned int i;
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
800
  	mutex_lock(&kprobe_mutex);
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
801
802
  	/* If optimization is already allowed, just return */
  	if (kprobes_allow_optimization)
5c51543b0   Masami Hiramatsu   kprobes: Fix a do...
803
  		goto out;
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
804

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

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

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

6274de498   Masami Hiramatsu   kprobes: Support ...
889
890
891
892
893
894
895
896
  	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...
897
898
899
900
901
  }
  
  #else /* !CONFIG_OPTPROBES */
  
  #define optimize_kprobe(p)			do {} while (0)
6274de498   Masami Hiramatsu   kprobes: Support ...
902
  #define unoptimize_kprobe(p, f)			do {} while (0)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
903
904
905
906
  #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 ...
907
908
909
  #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...
910

819319fc9   Masami Hiramatsu   kprobes: Return e...
911
  static int reuse_unused_kprobe(struct kprobe *ap)
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
912
  {
819319fc9   Masami Hiramatsu   kprobes: Return e...
913
914
915
916
917
918
  	/*
  	 * If the optimized kprobe is NOT supported, the aggr kprobe is
  	 * released at the same time that the last aggregated kprobe is
  	 * unregistered.
  	 * Thus there should be no chance to reuse unused kprobe.
  	 */
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
919
920
  	printk(KERN_ERR "Error: There should be no unused kprobe here.
  ");
819319fc9   Masami Hiramatsu   kprobes: Return e...
921
  	return -EINVAL;
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
922
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
923
  static void free_aggr_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
924
  {
6274de498   Masami Hiramatsu   kprobes: Support ...
925
  	arch_remove_kprobe(p);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
926
927
  	kfree(p);
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
928
  static struct kprobe *alloc_aggr_kprobe(struct kprobe *p)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
929
930
931
932
  {
  	return kzalloc(sizeof(struct kprobe), GFP_KERNEL);
  }
  #endif /* CONFIG_OPTPROBES */
e7dbfe349   Masami Hiramatsu   kprobes/x86: Move...
933
  #ifdef CONFIG_KPROBES_ON_FTRACE
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
934
  static struct ftrace_ops kprobe_ftrace_ops __read_mostly = {
e52538965   Masami Hiramatsu   kprobes/x86: ftra...
935
  	.func = kprobe_ftrace_handler,
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
936
937
938
939
940
  	.flags = FTRACE_OPS_FL_SAVE_REGS,
  };
  
  static struct ftrace_ops kprobe_ipmodify_ops __read_mostly = {
  	.func = kprobe_ftrace_handler,
1d70be34d   Masami Hiramatsu   kprobes: Add IPMO...
941
  	.flags = FTRACE_OPS_FL_SAVE_REGS | FTRACE_OPS_FL_IPMODIFY,
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
942
  };
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
943
944
  
  static int kprobe_ipmodify_enabled;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
945
946
947
  static int kprobe_ftrace_enabled;
  
  /* Must ensure p->addr is really on ftrace */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
948
  static int prepare_kprobe(struct kprobe *p)
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
949
950
951
952
953
954
955
956
  {
  	if (!kprobe_ftrace(p))
  		return arch_prepare_kprobe(p);
  
  	return arch_prepare_kprobe_ftrace(p);
  }
  
  /* Caller must lock kprobe_mutex */
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
957
958
  static int __arm_kprobe_ftrace(struct kprobe *p, struct ftrace_ops *ops,
  			       int *cnt)
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
959
  {
12310e343   Jessica Yu   kprobes: Propagat...
960
  	int ret = 0;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
961

0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
962
  	ret = ftrace_set_filter_ip(ops, (unsigned long)p->addr, 0, 0);
12310e343   Jessica Yu   kprobes: Propagat...
963
  	if (ret) {
4458515b2   Masami Hiramatsu   kprobes: Replace ...
964
965
966
  		pr_debug("Failed to arm kprobe-ftrace at %pS (%d)
  ",
  			 p->addr, ret);
12310e343   Jessica Yu   kprobes: Propagat...
967
968
  		return ret;
  	}
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
969
970
  	if (*cnt == 0) {
  		ret = register_ftrace_function(ops);
12310e343   Jessica Yu   kprobes: Propagat...
971
972
973
974
975
  		if (ret) {
  			pr_debug("Failed to init kprobe-ftrace (%d)
  ", ret);
  			goto err_ftrace;
  		}
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
976
  	}
12310e343   Jessica Yu   kprobes: Propagat...
977

0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
978
  	(*cnt)++;
12310e343   Jessica Yu   kprobes: Propagat...
979
980
981
982
  	return ret;
  
  err_ftrace:
  	/*
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
983
984
  	 * At this point, sinec ops is not registered, we should be sefe from
  	 * registering empty filter.
12310e343   Jessica Yu   kprobes: Propagat...
985
  	 */
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
986
  	ftrace_set_filter_ip(ops, (unsigned long)p->addr, 1, 0);
12310e343   Jessica Yu   kprobes: Propagat...
987
  	return ret;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
988
  }
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
989
990
991
992
993
994
995
996
  static int arm_kprobe_ftrace(struct kprobe *p)
  {
  	bool ipmodify = (p->post_handler != NULL);
  
  	return __arm_kprobe_ftrace(p,
  		ipmodify ? &kprobe_ipmodify_ops : &kprobe_ftrace_ops,
  		ipmodify ? &kprobe_ipmodify_enabled : &kprobe_ftrace_enabled);
  }
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
997
  /* Caller must lock kprobe_mutex */
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
998
999
  static int __disarm_kprobe_ftrace(struct kprobe *p, struct ftrace_ops *ops,
  				  int *cnt)
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1000
  {
297f9233b   Jessica Yu   kprobes: Propagat...
1001
  	int ret = 0;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1002

0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
1003
1004
  	if (*cnt == 1) {
  		ret = unregister_ftrace_function(ops);
297f9233b   Jessica Yu   kprobes: Propagat...
1005
1006
1007
  		if (WARN(ret < 0, "Failed to unregister kprobe-ftrace (%d)
  ", ret))
  			return ret;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1008
  	}
297f9233b   Jessica Yu   kprobes: Propagat...
1009

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

0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
1012
  	ret = ftrace_set_filter_ip(ops, (unsigned long)p->addr, 1, 0);
4458515b2   Masami Hiramatsu   kprobes: Replace ...
1013
1014
1015
  	WARN_ONCE(ret < 0, "Failed to disarm kprobe-ftrace at %pS (%d)
  ",
  		  p->addr, ret);
297f9233b   Jessica Yu   kprobes: Propagat...
1016
  	return ret;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1017
  }
0bc11ed5a   Masami Hiramatsu   kprobes: Allow kp...
1018
1019
1020
1021
1022
1023
1024
1025
1026
  
  static int disarm_kprobe_ftrace(struct kprobe *p)
  {
  	bool ipmodify = (p->post_handler != NULL);
  
  	return __disarm_kprobe_ftrace(p,
  		ipmodify ? &kprobe_ipmodify_ops : &kprobe_ftrace_ops,
  		ipmodify ? &kprobe_ipmodify_enabled : &kprobe_ftrace_enabled);
  }
e7dbfe349   Masami Hiramatsu   kprobes/x86: Move...
1027
  #else	/* !CONFIG_KPROBES_ON_FTRACE */
b4a9fdf06   Muchun Song   kprobes: Fix comp...
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
  static inline int prepare_kprobe(struct kprobe *p)
  {
  	return arch_prepare_kprobe(p);
  }
  
  static inline int arm_kprobe_ftrace(struct kprobe *p)
  {
  	return -ENODEV;
  }
  
  static inline int disarm_kprobe_ftrace(struct kprobe *p)
  {
  	return -ENODEV;
  }
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1042
  #endif
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1043
  /* Arm a kprobe with text_mutex */
12310e343   Jessica Yu   kprobes: Propagat...
1044
  static int arm_kprobe(struct kprobe *kp)
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1045
  {
12310e343   Jessica Yu   kprobes: Propagat...
1046
1047
  	if (unlikely(kprobe_ftrace(kp)))
  		return arm_kprobe_ftrace(kp);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1048
  	cpus_read_lock();
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1049
  	mutex_lock(&text_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1050
  	__arm_kprobe(kp);
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1051
  	mutex_unlock(&text_mutex);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1052
  	cpus_read_unlock();
12310e343   Jessica Yu   kprobes: Propagat...
1053
1054
  
  	return 0;
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1055
1056
1057
  }
  
  /* Disarm a kprobe with text_mutex */
297f9233b   Jessica Yu   kprobes: Propagat...
1058
  static int disarm_kprobe(struct kprobe *kp, bool reopt)
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1059
  {
297f9233b   Jessica Yu   kprobes: Propagat...
1060
1061
  	if (unlikely(kprobe_ftrace(kp)))
  		return disarm_kprobe_ftrace(kp);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1062
1063
  
  	cpus_read_lock();
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1064
  	mutex_lock(&text_mutex);
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1065
  	__disarm_kprobe(kp, reopt);
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1066
  	mutex_unlock(&text_mutex);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1067
  	cpus_read_unlock();
297f9233b   Jessica Yu   kprobes: Propagat...
1068
1069
  
  	return 0;
201517a7f   Masami Hiramatsu   kprobes: fix to u...
1070
  }
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1071
1072
1073
1074
  /*
   * Aggregate handlers for multiple kprobes support - these handlers
   * take care of invoking the individual kprobe handlers on p->list
   */
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1075
  static int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1076
1077
  {
  	struct kprobe *kp;
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1078
  	list_for_each_entry_rcu(kp, &p->list, list) {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1079
  		if (kp->pre_handler && likely(!kprobe_disabled(kp))) {
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1080
  			set_kprobe_instance(kp);
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1081
1082
  			if (kp->pre_handler(kp, regs))
  				return 1;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1083
  		}
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1084
  		reset_kprobe_instance();
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1085
1086
1087
  	}
  	return 0;
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1088
  NOKPROBE_SYMBOL(aggr_pre_handler);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1089

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1090
1091
  static void aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
  			      unsigned long flags)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1092
1093
  {
  	struct kprobe *kp;
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1094
  	list_for_each_entry_rcu(kp, &p->list, list) {
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1095
  		if (kp->post_handler && likely(!kprobe_disabled(kp))) {
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1096
  			set_kprobe_instance(kp);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1097
  			kp->post_handler(kp, regs, flags);
e65845235   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1098
  			reset_kprobe_instance();
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1099
1100
  		}
  	}
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1101
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1102
  NOKPROBE_SYMBOL(aggr_post_handler);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1103

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

64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1109
1110
1111
1112
  	/*
  	 * 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: ...
1113
1114
  	if (cur && cur->fault_handler) {
  		if (cur->fault_handler(cur, regs, trapnr))
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1115
1116
1117
1118
  			return 1;
  	}
  	return 0;
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1119
  NOKPROBE_SYMBOL(aggr_fault_handler);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1120

bf8d5c52c   Keshavamurthy Anil S   [PATCH] kprobes: ...
1121
  /* Walks the list and increments nmissed count for multiprobe case */
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1122
  void kprobes_inc_nmissed_count(struct kprobe *p)
bf8d5c52c   Keshavamurthy Anil S   [PATCH] kprobes: ...
1123
1124
  {
  	struct kprobe *kp;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1125
  	if (!kprobe_aggrprobe(p)) {
bf8d5c52c   Keshavamurthy Anil S   [PATCH] kprobes: ...
1126
1127
1128
1129
1130
1131
1132
  		p->nmissed++;
  	} else {
  		list_for_each_entry_rcu(kp, &p->list, list)
  			kp->nmissed++;
  	}
  	return;
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1133
  NOKPROBE_SYMBOL(kprobes_inc_nmissed_count);
bf8d5c52c   Keshavamurthy Anil S   [PATCH] kprobes: ...
1134

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1135
1136
  void recycle_rp_inst(struct kretprobe_instance *ri,
  		     struct hlist_head *head)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1137
  {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1138
  	struct kretprobe *rp = ri->rp;
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1139
1140
  	/* remove rp inst off the rprobe_inst_table */
  	hlist_del(&ri->hlist);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1141
1142
  	INIT_HLIST_NODE(&ri->hlist);
  	if (likely(rp)) {
ec484608c   Thomas Gleixner   locking, kprobes:...
1143
  		raw_spin_lock(&rp->lock);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1144
  		hlist_add_head(&ri->hlist, &rp->free_instances);
ec484608c   Thomas Gleixner   locking, kprobes:...
1145
  		raw_spin_unlock(&rp->lock);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1146
1147
  	} else
  		/* Unregistering */
99219a3fb   bibo,mao   [PATCH] kretprobe...
1148
  		hlist_add_head(&ri->hlist, head);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1149
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1150
  NOKPROBE_SYMBOL(recycle_rp_inst);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1151

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1152
  void kretprobe_hash_lock(struct task_struct *tsk,
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1153
  			 struct hlist_head **head, unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1154
  __acquires(hlist_lock)
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1155
1156
  {
  	unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS);
ec484608c   Thomas Gleixner   locking, kprobes:...
1157
  	raw_spinlock_t *hlist_lock;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1158
1159
1160
  
  	*head = &kretprobe_inst_table[hash];
  	hlist_lock = kretprobe_table_lock_ptr(hash);
ec484608c   Thomas Gleixner   locking, kprobes:...
1161
  	raw_spin_lock_irqsave(hlist_lock, *flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1162
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1163
  NOKPROBE_SYMBOL(kretprobe_hash_lock);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1164

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1165
1166
  static void kretprobe_table_lock(unsigned long hash,
  				 unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1167
  __acquires(hlist_lock)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1168
  {
ec484608c   Thomas Gleixner   locking, kprobes:...
1169
1170
  	raw_spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash);
  	raw_spin_lock_irqsave(hlist_lock, *flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1171
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1172
  NOKPROBE_SYMBOL(kretprobe_table_lock);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1173

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1174
1175
  void kretprobe_hash_unlock(struct task_struct *tsk,
  			   unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1176
  __releases(hlist_lock)
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1177
1178
  {
  	unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS);
ec484608c   Thomas Gleixner   locking, kprobes:...
1179
  	raw_spinlock_t *hlist_lock;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1180
1181
  
  	hlist_lock = kretprobe_table_lock_ptr(hash);
ec484608c   Thomas Gleixner   locking, kprobes:...
1182
  	raw_spin_unlock_irqrestore(hlist_lock, *flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1183
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1184
  NOKPROBE_SYMBOL(kretprobe_hash_unlock);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1185

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1186
1187
  static void kretprobe_table_unlock(unsigned long hash,
  				   unsigned long *flags)
635c17c2b   Namhyung Kim   kprobes: Add spar...
1188
  __releases(hlist_lock)
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1189
  {
ec484608c   Thomas Gleixner   locking, kprobes:...
1190
1191
  	raw_spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash);
  	raw_spin_unlock_irqrestore(hlist_lock, *flags);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1192
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1193
  NOKPROBE_SYMBOL(kretprobe_table_unlock);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1194

3d390370d   Jiri Olsa   kretprobe: Preven...
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
  struct kprobe kprobe_busy = {
  	.addr = (void *) get_kprobe,
  };
  
  void kprobe_busy_begin(void)
  {
  	struct kprobe_ctlblk *kcb;
  
  	preempt_disable();
  	__this_cpu_write(current_kprobe, &kprobe_busy);
  	kcb = get_kprobe_ctlblk();
  	kcb->kprobe_status = KPROBE_HIT_ACTIVE;
  }
  
  void kprobe_busy_end(void)
  {
  	__this_cpu_write(current_kprobe, NULL);
  	preempt_enable();
  }
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1214
  /*
c6fd91f0b   bibo mao   [PATCH] kretprobe...
1215
1216
1217
1218
   * 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: ...
1219
   */
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1220
  void kprobe_flush_task(struct task_struct *tk)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1221
  {
62c27be0d   bibo,mao   [PATCH] kprobe wh...
1222
  	struct kretprobe_instance *ri;
99219a3fb   bibo,mao   [PATCH] kretprobe...
1223
  	struct hlist_head *head, empty_rp;
b67bfe0d4   Sasha Levin   hlist: drop the n...
1224
  	struct hlist_node *tmp;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1225
  	unsigned long hash, flags = 0;
802eae7c8   Rusty Lynch   [PATCH] Return pr...
1226

ef53d9c5e   Srinivasa D S   kprobes: improve ...
1227
1228
1229
  	if (unlikely(!kprobes_initialized))
  		/* Early boot.  kretprobe_table_locks not yet initialized. */
  		return;
3d390370d   Jiri Olsa   kretprobe: Preven...
1230
  	kprobe_busy_begin();
d496aab56   Ananth N Mavinakayanahalli   kprobes: initiali...
1231
  	INIT_HLIST_HEAD(&empty_rp);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1232
1233
1234
  	hash = hash_ptr(tk, KPROBE_HASH_BITS);
  	head = &kretprobe_inst_table[hash];
  	kretprobe_table_lock(hash, &flags);
b67bfe0d4   Sasha Levin   hlist: drop the n...
1235
  	hlist_for_each_entry_safe(ri, tmp, head, hlist) {
62c27be0d   bibo,mao   [PATCH] kprobe wh...
1236
  		if (ri->task == tk)
99219a3fb   bibo,mao   [PATCH] kretprobe...
1237
  			recycle_rp_inst(ri, &empty_rp);
62c27be0d   bibo,mao   [PATCH] kprobe wh...
1238
  	}
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1239
  	kretprobe_table_unlock(hash, &flags);
b67bfe0d4   Sasha Levin   hlist: drop the n...
1240
  	hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
99219a3fb   bibo,mao   [PATCH] kretprobe...
1241
1242
1243
  		hlist_del(&ri->hlist);
  		kfree(ri);
  	}
3d390370d   Jiri Olsa   kretprobe: Preven...
1244
1245
  
  	kprobe_busy_end();
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1246
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1247
  NOKPROBE_SYMBOL(kprobe_flush_task);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1248

b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1249
1250
1251
  static inline void free_rp_inst(struct kretprobe *rp)
  {
  	struct kretprobe_instance *ri;
b67bfe0d4   Sasha Levin   hlist: drop the n...
1252
  	struct hlist_node *next;
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1253

b67bfe0d4   Sasha Levin   hlist: drop the n...
1254
  	hlist_for_each_entry_safe(ri, next, &rp->free_instances, hlist) {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1255
  		hlist_del(&ri->hlist);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1256
1257
1258
  		kfree(ri);
  	}
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1259
  static void cleanup_rp_inst(struct kretprobe *rp)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1260
  {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1261
  	unsigned long flags, hash;
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1262
  	struct kretprobe_instance *ri;
b67bfe0d4   Sasha Levin   hlist: drop the n...
1263
  	struct hlist_node *next;
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1264
  	struct hlist_head *head;
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1265
  	/* No race here */
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1266
1267
1268
  	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...
1269
  		hlist_for_each_entry_safe(ri, next, head, hlist) {
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1270
1271
1272
1273
  			if (ri->rp == rp)
  				ri->rp = NULL;
  		}
  		kretprobe_table_unlock(hash, &flags);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1274
  	}
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1275
1276
  	free_rp_inst(rp);
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1277
  NOKPROBE_SYMBOL(cleanup_rp_inst);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1278

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

059053a27   Masami Hiramatsu   kprobes: Don't ch...
1285
  	list_add_rcu(&p->list, &ap->list);
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1286
1287
  	if (p->post_handler && !ap->post_handler)
  		ap->post_handler = aggr_post_handler;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1288

8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1289
1290
1291
1292
  	return 0;
  }
  
  /*
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1293
1294
1295
   * Fill in the required fields of the "manager kprobe". Replace the
   * earlier kprobe in the hlist with the manager kprobe
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1296
  static void init_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1297
  {
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1298
  	/* Copy p's insn slot to ap */
8b0914ea7   Prasanna S Panchamukhi   [PATCH] jprobes: ...
1299
  	copy_kprobe(p, ap);
a9ad965ea   bibo, mao   [PATCH] IA64: kpr...
1300
  	flush_insn_slot(ap);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1301
  	ap->addr = p->addr;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1302
  	ap->flags = p->flags & ~KPROBE_FLAG_OPTIMIZED;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1303
  	ap->pre_handler = aggr_pre_handler;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1304
  	ap->fault_handler = aggr_fault_handler;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1305
1306
  	/* We don't care the kprobe which has gone. */
  	if (p->post_handler && !kprobe_gone(p))
367216567   mao, bibo   [PATCH] Kprobe: m...
1307
  		ap->post_handler = aggr_post_handler;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1308
1309
  
  	INIT_LIST_HEAD(&ap->list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1310
  	INIT_HLIST_NODE(&ap->hlist);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1311

afd66255b   Masami Hiramatsu   kprobes: Introduc...
1312
  	list_add_rcu(&p->list, &ap->list);
adad0f331   Keshavamurthy Anil S   [PATCH] kprobes: ...
1313
  	hlist_replace_rcu(&p->hlist, &ap->hlist);
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1314
1315
1316
1317
1318
  }
  
  /*
   * This is the second or subsequent kprobe at the address - handle
   * the intricacies
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1319
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1320
  static int register_aggr_kprobe(struct kprobe *orig_p, struct kprobe *p)
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1321
1322
  {
  	int ret = 0;
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1323
  	struct kprobe *ap = orig_p;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1324

2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1325
  	cpus_read_lock();
25764288d   Masami Hiramatsu   kprobes: Move loc...
1326
1327
  	/* For preparing optimization, jump_label_text_reserved() is called */
  	jump_label_lock();
25764288d   Masami Hiramatsu   kprobes: Move loc...
1328
  	mutex_lock(&text_mutex);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1329
1330
1331
  	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...
1332
1333
1334
1335
  		if (!ap) {
  			ret = -ENOMEM;
  			goto out;
  		}
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1336
  		init_aggr_kprobe(ap, orig_p);
819319fc9   Masami Hiramatsu   kprobes: Return e...
1337
  	} else if (kprobe_unused(ap)) {
0490cd1f9   Masami Hiramatsu   kprobes: Reuse un...
1338
  		/* This probe is going to die. Rescue it */
819319fc9   Masami Hiramatsu   kprobes: Return e...
1339
1340
1341
1342
  		ret = reuse_unused_kprobe(ap);
  		if (ret)
  			goto out;
  	}
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1343
1344
  
  	if (kprobe_gone(ap)) {
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1345
1346
1347
1348
1349
1350
  		/*
  		 * 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 ...
1351
  		ret = arch_prepare_kprobe(ap);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1352
  		if (ret)
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1353
1354
1355
1356
1357
  			/*
  			 * 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...
1358
  			goto out;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1359

afd66255b   Masami Hiramatsu   kprobes: Introduc...
1360
1361
  		/* Prepare optimized instructions if possible. */
  		prepare_optimized_kprobe(ap);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1362
  		/*
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1363
1364
  		 * Clear gone flag to prevent allocating new slot again, and
  		 * set disabled flag because it is not armed yet.
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1365
  		 */
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1366
1367
  		ap->flags = (ap->flags & ~KPROBE_FLAG_GONE)
  			    | KPROBE_FLAG_DISABLED;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1368
  	}
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1369

afd66255b   Masami Hiramatsu   kprobes: Introduc...
1370
  	/* Copy ap's insn slot to p */
b918e5e60   Masami Hiramatsu   kprobes: cleanup ...
1371
  	copy_kprobe(ap, p);
25764288d   Masami Hiramatsu   kprobes: Move loc...
1372
1373
1374
1375
  	ret = add_new_kprobe(ap, p);
  
  out:
  	mutex_unlock(&text_mutex);
25764288d   Masami Hiramatsu   kprobes: Move loc...
1376
  	jump_label_unlock();
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1377
  	cpus_read_unlock();
25764288d   Masami Hiramatsu   kprobes: Move loc...
1378
1379
1380
  
  	if (ret == 0 && kprobe_disabled(ap) && !kprobe_disabled(p)) {
  		ap->flags &= ~KPROBE_FLAG_DISABLED;
12310e343   Jessica Yu   kprobes: Propagat...
1381
  		if (!kprobes_all_disarmed) {
25764288d   Masami Hiramatsu   kprobes: Move loc...
1382
  			/* Arm the breakpoint again. */
12310e343   Jessica Yu   kprobes: Propagat...
1383
1384
1385
1386
  			ret = arm_kprobe(ap);
  			if (ret) {
  				ap->flags |= KPROBE_FLAG_DISABLED;
  				list_del_rcu(&p->list);
ae8b7ce76   Paul E. McKenney   kprobes: Replace ...
1387
  				synchronize_rcu();
12310e343   Jessica Yu   kprobes: Propagat...
1388
1389
  			}
  		}
25764288d   Masami Hiramatsu   kprobes: Move loc...
1390
1391
  	}
  	return ret;
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1392
  }
be8f27432   Masami Hiramatsu   kprobes: Prohibit...
1393
1394
1395
1396
1397
1398
  bool __weak arch_within_kprobe_blacklist(unsigned long addr)
  {
  	/* The __kprobes marked functions and entry code must not be probed */
  	return addr >= (unsigned long)__kprobes_text_start &&
  	       addr < (unsigned long)__kprobes_text_end;
  }
6143c6fb1   Masami Hiramatsu   kprobes: Search n...
1399
  static bool __within_kprobe_blacklist(unsigned long addr)
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1400
  {
376e24242   Masami Hiramatsu   kprobes: Introduc...
1401
  	struct kprobe_blacklist_entry *ent;
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
1402

be8f27432   Masami Hiramatsu   kprobes: Prohibit...
1403
  	if (arch_within_kprobe_blacklist(addr))
376e24242   Masami Hiramatsu   kprobes: Introduc...
1404
  		return true;
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
1405
1406
1407
1408
  	/*
  	 * If there exists a kprobe_blacklist, verify and
  	 * fail any probe registration in the prohibited area
  	 */
376e24242   Masami Hiramatsu   kprobes: Introduc...
1409
1410
1411
  	list_for_each_entry(ent, &kprobe_blacklist, list) {
  		if (addr >= ent->start_addr && addr < ent->end_addr)
  			return true;
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
1412
  	}
6143c6fb1   Masami Hiramatsu   kprobes: Search n...
1413
1414
  	return false;
  }
376e24242   Masami Hiramatsu   kprobes: Introduc...
1415

6143c6fb1   Masami Hiramatsu   kprobes: Search n...
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
  bool within_kprobe_blacklist(unsigned long addr)
  {
  	char symname[KSYM_NAME_LEN], *p;
  
  	if (__within_kprobe_blacklist(addr))
  		return true;
  
  	/* Check if the address is on a suffixed-symbol */
  	if (!lookup_symbol_name(addr, symname)) {
  		p = strchr(symname, '.');
  		if (!p)
  			return false;
  		*p = '\0';
  		addr = (unsigned long)kprobe_lookup_name(symname, 0);
  		if (addr)
  			return __within_kprobe_blacklist(addr);
  	}
376e24242   Masami Hiramatsu   kprobes: Introduc...
1433
  	return false;
d0aaff979   Prasanna S Panchamukhi   [PATCH] Kprobes: ...
1434
  }
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1435
1436
1437
  /*
   * 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 -...
1438
1439
   * This returns encoded errors if it fails to look up symbol or invalid
   * combination of parameters.
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1440
   */
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1441
1442
  static kprobe_opcode_t *_kprobe_addr(kprobe_opcode_t *addr,
  			const char *symbol_name, unsigned int offset)
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1443
  {
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1444
  	if ((symbol_name && addr) || (!symbol_name && !addr))
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1445
  		goto invalid;
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1446
  	if (symbol_name) {
7246f6006   Linus Torvalds   Merge tag 'powerp...
1447
  		addr = kprobe_lookup_name(symbol_name, offset);
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1448
1449
  		if (!addr)
  			return ERR_PTR(-ENOENT);
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1450
  	}
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1451
  	addr = (kprobe_opcode_t *)(((char *)addr) + offset);
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1452
1453
1454
1455
1456
  	if (addr)
  		return addr;
  
  invalid:
  	return ERR_PTR(-EINVAL);
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1457
  }
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1458
1459
1460
1461
  static kprobe_opcode_t *kprobe_addr(struct kprobe *p)
  {
  	return _kprobe_addr(p->addr, p->symbol_name, p->offset);
  }
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1462
  /* Check passed kprobe is valid and return kprobe in kprobe_table. */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1463
  static struct kprobe *__get_valid_kprobe(struct kprobe *p)
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1464
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1465
  	struct kprobe *ap, *list_p;
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1466

6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1467
1468
  	ap = get_kprobe(p->addr);
  	if (unlikely(!ap))
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1469
  		return NULL;
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1470
1471
  	if (p != ap) {
  		list_for_each_entry_rcu(list_p, &ap->list, list)
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1472
1473
1474
1475
1476
1477
  			if (list_p == p)
  			/* kprobe p is a valid probe */
  				goto valid;
  		return NULL;
  	}
  valid:
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1478
  	return ap;
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1479
1480
1481
1482
1483
1484
  }
  
  /* 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 ...
1485
1486
  
  	mutex_lock(&kprobe_mutex);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1487
  	if (__get_valid_kprobe(p))
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1488
1489
  		ret = -EINVAL;
  	mutex_unlock(&kprobe_mutex);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1490

1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1491
1492
  	return ret;
  }
f7f242ff0   Heiko Carstens   kprobes: introduc...
1493
  int __weak arch_check_ftrace_location(struct kprobe *p)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1494
  {
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1495
  	unsigned long ftrace_addr;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1496
1497
  	ftrace_addr = ftrace_location((unsigned long)p->addr);
  	if (ftrace_addr) {
e7dbfe349   Masami Hiramatsu   kprobes/x86: Move...
1498
  #ifdef CONFIG_KPROBES_ON_FTRACE
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1499
1500
1501
  		/* Given address is not on the instruction boundary */
  		if ((unsigned long)p->addr != ftrace_addr)
  			return -EILSEQ;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1502
  		p->flags |= KPROBE_FLAG_FTRACE;
e7dbfe349   Masami Hiramatsu   kprobes/x86: Move...
1503
  #else	/* !CONFIG_KPROBES_ON_FTRACE */
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1504
1505
1506
  		return -EINVAL;
  #endif
  	}
f7f242ff0   Heiko Carstens   kprobes: introduc...
1507
1508
1509
1510
1511
1512
1513
  	return 0;
  }
  
  static int check_kprobe_address_safe(struct kprobe *p,
  				     struct module **probed_mod)
  {
  	int ret;
1f0ab4097   Ananth N Mavinakayanahalli   kprobes: Prevent ...
1514

f7f242ff0   Heiko Carstens   kprobes: introduc...
1515
1516
1517
  	ret = arch_check_ftrace_location(p);
  	if (ret)
  		return ret;
91bad2f8d   Jason Baron   jump label: Fix d...
1518
  	jump_label_lock();
de31c3ca8   Steven Rostedt   jump label: Fix e...
1519
  	preempt_disable();
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1520
1521
  
  	/* Ensure it is not in reserved area nor out of text */
ec30c5f3a   Masami Hiramatsu   kprobes: Use kern...
1522
  	if (!kernel_text_address((unsigned long) p->addr) ||
376e24242   Masami Hiramatsu   kprobes: Introduc...
1523
  	    within_kprobe_blacklist((unsigned long) p->addr) ||
e336b4027   Masami Hiramatsu   kprobes: Prohibit...
1524
1525
  	    jump_label_text_reserved(p->addr, p->addr) ||
  	    find_bug((unsigned long)p->addr)) {
f986a499e   Prashanth Nageshappa   kprobes: return p...
1526
  		ret = -EINVAL;
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1527
  		goto out;
f986a499e   Prashanth Nageshappa   kprobes: return p...
1528
  	}
b3e55c727   Mao, Bibo   [PATCH] Kprobes: ...
1529

f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1530
1531
1532
  	/* Check if are we probing a module */
  	*probed_mod = __module_text_address((unsigned long) p->addr);
  	if (*probed_mod) {
6f716acd5   Christoph Hellwig   kprobes: codingst...
1533
  		/*
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1534
1535
  		 * We must hold a refcount of the probed module while updating
  		 * its code to prohibit unexpected unloading.
df019b1d8   Keshavamurthy Anil S   [PATCH] kprobes: ...
1536
  		 */
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1537
1538
1539
1540
  		if (unlikely(!try_module_get(*probed_mod))) {
  			ret = -ENOENT;
  			goto out;
  		}
de31c3ca8   Steven Rostedt   jump label: Fix e...
1541

f24659d96   Masami Hiramatsu   kprobes: support ...
1542
1543
1544
1545
  		/*
  		 * If the module freed .init.text, we couldn't insert
  		 * kprobes in there.
  		 */
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1546
1547
1548
1549
1550
  		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 ...
1551
  		}
df019b1d8   Keshavamurthy Anil S   [PATCH] kprobes: ...
1552
  	}
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1553
  out:
a189d0350   Masami Hiramatsu   kprobes: disable ...
1554
  	preempt_enable();
de31c3ca8   Steven Rostedt   jump label: Fix e...
1555
  	jump_label_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1556

f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1557
1558
  	return ret;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1559
  int register_kprobe(struct kprobe *p)
f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
  {
  	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: ...
1578
  	p->nmissed = 0;
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1579
  	INIT_LIST_HEAD(&p->list);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1580

f7fa6ef0d   Masami Hiramatsu   kprobes: cleanup ...
1581
1582
1583
1584
1585
  	ret = check_kprobe_address_safe(p, &probed_mod);
  	if (ret)
  		return ret;
  
  	mutex_lock(&kprobe_mutex);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1586

64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1587
1588
  	old_p = get_kprobe(p->addr);
  	if (old_p) {
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1589
  		/* Since this may unoptimize old_p, locking text_mutex. */
64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1590
  		ret = register_aggr_kprobe(old_p, p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1591
1592
  		goto out;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1593

2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1594
1595
1596
  	cpus_read_lock();
  	/* Prevent text modification */
  	mutex_lock(&text_mutex);
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
1597
  	ret = prepare_kprobe(p);
25764288d   Masami Hiramatsu   kprobes: Move loc...
1598
  	mutex_unlock(&text_mutex);
2d1e38f56   Thomas Gleixner   kprobes: Cure hot...
1599
  	cpus_read_unlock();
6f716acd5   Christoph Hellwig   kprobes: codingst...
1600
  	if (ret)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1601
  		goto out;
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1602

64f562c6d   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1603
  	INIT_HLIST_NODE(&p->hlist);
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1604
  	hlist_add_head_rcu(&p->hlist,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1605
  		       &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
12310e343   Jessica Yu   kprobes: Propagat...
1606
1607
1608
1609
  	if (!kprobes_all_disarmed && !kprobe_disabled(p)) {
  		ret = arm_kprobe(p);
  		if (ret) {
  			hlist_del_rcu(&p->hlist);
ae8b7ce76   Paul E. McKenney   kprobes: Replace ...
1610
  			synchronize_rcu();
12310e343   Jessica Yu   kprobes: Propagat...
1611
1612
1613
  			goto out;
  		}
  	}
afd66255b   Masami Hiramatsu   kprobes: Introduc...
1614
1615
1616
  
  	/* Try to optimize kprobe */
  	try_to_optimize_kprobe(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1617
  out:
7a7d1cf95   Ingo Molnar   [PATCH] sem2mutex...
1618
  	mutex_unlock(&kprobe_mutex);
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1619

e8386a0cb   Masami Hiramatsu   kprobes: support ...
1620
  	if (probed_mod)
df019b1d8   Keshavamurthy Anil S   [PATCH] kprobes: ...
1621
  		module_put(probed_mod);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1622

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1623
1624
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1625
  EXPORT_SYMBOL_GPL(register_kprobe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1626

6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1627
  /* Check if all probes on the aggrprobe are disabled */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1628
  static int aggr_kprobe_disabled(struct kprobe *ap)
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
  {
  	struct kprobe *kp;
  
  	list_for_each_entry_rcu(kp, &ap->list, list)
  		if (!kprobe_disabled(kp))
  			/*
  			 * There is an active probe on the list.
  			 * We can't disable this ap.
  			 */
  			return 0;
  
  	return 1;
  }
  
  /* Disable one kprobe: Make sure called under kprobe_mutex is locked */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1644
  static struct kprobe *__disable_kprobe(struct kprobe *p)
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1645
1646
  {
  	struct kprobe *orig_p;
297f9233b   Jessica Yu   kprobes: Propagat...
1647
  	int ret;
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1648
1649
1650
1651
  
  	/* Get an original kprobe for return */
  	orig_p = __get_valid_kprobe(p);
  	if (unlikely(orig_p == NULL))
297f9233b   Jessica Yu   kprobes: Propagat...
1652
  		return ERR_PTR(-EINVAL);
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1653
1654
1655
1656
1657
1658
1659
1660
  
  	if (!kprobe_disabled(p)) {
  		/* Disable probe if it is a child probe */
  		if (p != orig_p)
  			p->flags |= KPROBE_FLAG_DISABLED;
  
  		/* Try to disarm and disable this/parent probe */
  		if (p == orig_p || aggr_kprobe_disabled(orig_p)) {
69d54b916   Wang Nan   kprobes: makes kp...
1661
1662
1663
1664
1665
  			/*
  			 * If kprobes_all_disarmed is set, orig_p
  			 * should have already been disarmed, so
  			 * skip unneed disarming process.
  			 */
297f9233b   Jessica Yu   kprobes: Propagat...
1666
1667
1668
1669
1670
1671
1672
  			if (!kprobes_all_disarmed) {
  				ret = disarm_kprobe(orig_p, true);
  				if (ret) {
  					p->flags &= ~KPROBE_FLAG_DISABLED;
  					return ERR_PTR(ret);
  				}
  			}
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1673
1674
1675
1676
1677
1678
  			orig_p->flags |= KPROBE_FLAG_DISABLED;
  		}
  	}
  
  	return orig_p;
  }
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1679
1680
1681
  /*
   * Unregister a kprobe without a scheduler synchronization.
   */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1682
  static int __unregister_kprobe_top(struct kprobe *p)
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1683
  {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1684
  	struct kprobe *ap, *list_p;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1685

6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1686
1687
  	/* Disable kprobe. This will disarm it if needed. */
  	ap = __disable_kprobe(p);
297f9233b   Jessica Yu   kprobes: Propagat...
1688
1689
  	if (IS_ERR(ap))
  		return PTR_ERR(ap);
de5bd88d5   Masami Hiramatsu   kprobes: support ...
1690

6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1691
  	if (ap == p)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
1692
  		/*
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1693
1694
  		 * 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...
1695
  		 */
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1696
1697
1698
1699
  		goto disarmed;
  
  	/* Following process expects this probe is an aggrprobe */
  	WARN_ON(!kprobe_aggrprobe(ap));
6274de498   Masami Hiramatsu   kprobes: Support ...
1700
1701
1702
1703
1704
  	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 ...
1705
1706
1707
  		goto disarmed;
  	else {
  		/* If disabling probe has special handlers, update aggrprobe */
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1708
  		if (p->post_handler && !kprobe_gone(p)) {
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1709
  			list_for_each_entry_rcu(list_p, &ap->list, list) {
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1710
1711
1712
  				if ((list_p != p) && (list_p->post_handler))
  					goto noclean;
  			}
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1713
  			ap->post_handler = NULL;
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1714
1715
  		}
  noclean:
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1716
1717
1718
1719
  		/*
  		 * Remove from the aggrprobe: this path will do nothing in
  		 * __unregister_kprobe_bottom().
  		 */
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1720
  		list_del_rcu(&p->list);
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1721
1722
1723
1724
1725
1726
  		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: ...
1727
  	}
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1728
  	return 0;
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
1729
1730
1731
1732
  
  disarmed:
  	hlist_del_rcu(&ap->hlist);
  	return 0;
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1733
  }
3516a4604   Ananth N Mavinakayanahalli   [PATCH] Kprobes: ...
1734

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

e8386a0cb   Masami Hiramatsu   kprobes: support ...
1739
  	if (list_empty(&p->list))
6274de498   Masami Hiramatsu   kprobes: Support ...
1740
  		/* This is an independent kprobe */
0498b6350   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1741
  		arch_remove_kprobe(p);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1742
  	else if (list_is_singular(&p->list)) {
6274de498   Masami Hiramatsu   kprobes: Support ...
1743
  		/* This is the last child of an aggrprobe */
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1744
  		ap = list_entry(p->list.next, struct kprobe, list);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
1745
  		list_del(&p->list);
6d8e40a85   Masami Hiramatsu   kprobes: Rename o...
1746
  		free_aggr_kprobe(ap);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1747
  	}
6274de498   Masami Hiramatsu   kprobes: Support ...
1748
  	/* Otherwise, do nothing. */
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1749
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1750
  int register_kprobes(struct kprobe **kps, int num)
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1751
1752
1753
1754
1755
1756
  {
  	int i, ret = 0;
  
  	if (num <= 0)
  		return -EINVAL;
  	for (i = 0; i < num; i++) {
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1757
  		ret = register_kprobe(kps[i]);
67dddaad5   Masami Hiramatsu   kprobes: fix erro...
1758
1759
1760
  		if (ret < 0) {
  			if (i > 0)
  				unregister_kprobes(kps, i);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1761
  			break;
367216567   mao, bibo   [PATCH] Kprobe: m...
1762
  		}
49a2a1b83   Anil S Keshavamurthy   [PATCH] kprobes: ...
1763
  	}
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1764
1765
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1766
  EXPORT_SYMBOL_GPL(register_kprobes);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1767

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1768
  void unregister_kprobe(struct kprobe *p)
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1769
1770
1771
  {
  	unregister_kprobes(&p, 1);
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1772
  EXPORT_SYMBOL_GPL(unregister_kprobe);
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1773

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1774
  void unregister_kprobes(struct kprobe **kps, int num)
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
  {
  	int i;
  
  	if (num <= 0)
  		return;
  	mutex_lock(&kprobe_mutex);
  	for (i = 0; i < num; i++)
  		if (__unregister_kprobe_top(kps[i]) < 0)
  			kps[i]->addr = NULL;
  	mutex_unlock(&kprobe_mutex);
ae8b7ce76   Paul E. McKenney   kprobes: Replace ...
1785
  	synchronize_rcu();
9861668f7   Masami Hiramatsu   kprobes: add (un)...
1786
1787
1788
  	for (i = 0; i < num; i++)
  		if (kps[i]->addr)
  			__unregister_kprobe_bottom(kps[i]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1789
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1790
  EXPORT_SYMBOL_GPL(unregister_kprobes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1791

5f6bee347   Naveen N. Rao   kprobes: Convert ...
1792
1793
  int __weak kprobe_exceptions_notify(struct notifier_block *self,
  					unsigned long val, void *data)
fc62d0207   Naveen N. Rao   kprobes: Introduc...
1794
1795
1796
  {
  	return NOTIFY_DONE;
  }
5f6bee347   Naveen N. Rao   kprobes: Convert ...
1797
  NOKPROBE_SYMBOL(kprobe_exceptions_notify);
fc62d0207   Naveen N. Rao   kprobes: Introduc...
1798

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1799
1800
  static struct notifier_block kprobe_exceptions_nb = {
  	.notifier_call = kprobe_exceptions_notify,
3d5631e06   Anil S Keshavamurthy   [PATCH] Kprobes r...
1801
1802
  	.priority = 0x7fffffff /* we need to be notified first */
  };
3d7e33825   Michael Ellerman   jprobes: make jpr...
1803
1804
1805
1806
  unsigned long __weak arch_deref_entry_point(void *entry)
  {
  	return (unsigned long)entry;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1807

9edddaa20   Ananth N Mavinakayanahalli   Kprobes: indicate...
1808
  #ifdef CONFIG_KRETPROBES
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1809
1810
1811
1812
  /*
   * This kprobe pre_handler is registered with every kretprobe. When probe
   * hits it will set up the return probe.
   */
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1813
  static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1814
1815
  {
  	struct kretprobe *rp = container_of(p, struct kretprobe, kp);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1816
1817
  	unsigned long hash, flags = 0;
  	struct kretprobe_instance *ri;
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1818

f96f56780   Masami Hiramatsu   kprobes: Skip kre...
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
  	/*
  	 * To avoid deadlocks, prohibit return probing in NMI contexts,
  	 * just skip the probe and increase the (inexact) 'nmissed'
  	 * statistical counter, so that the user is informed that
  	 * something happened:
  	 */
  	if (unlikely(in_nmi())) {
  		rp->nmissed++;
  		return 0;
  	}
  
  	/* TODO: consider to only swap the RA after the last pre_handler fired */
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1831
  	hash = hash_ptr(current, KPROBE_HASH_BITS);
ec484608c   Thomas Gleixner   locking, kprobes:...
1832
  	raw_spin_lock_irqsave(&rp->lock, flags);
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1833
  	if (!hlist_empty(&rp->free_instances)) {
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1834
  		ri = hlist_entry(rp->free_instances.first,
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1835
1836
  				struct kretprobe_instance, hlist);
  		hlist_del(&ri->hlist);
ec484608c   Thomas Gleixner   locking, kprobes:...
1837
  		raw_spin_unlock_irqrestore(&rp->lock, flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1838

4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1839
1840
  		ri->rp = rp;
  		ri->task = current;
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1841

55ca6140e   Jiang Liu   kprobes: fix a me...
1842
1843
1844
1845
  		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...
1846
  			return 0;
55ca6140e   Jiang Liu   kprobes: fix a me...
1847
  		}
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1848

4c4308cb9   Christoph Hellwig   kprobes: kretprob...
1849
1850
1851
  		arch_prepare_kretprobe(ri, regs);
  
  		/* XXX(hch): why is there no hlist_move_head? */
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1852
1853
1854
1855
1856
  		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...
1857
  		rp->nmissed++;
ec484608c   Thomas Gleixner   locking, kprobes:...
1858
  		raw_spin_unlock_irqrestore(&rp->lock, flags);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1859
  	}
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1860
1861
  	return 0;
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
1862
  NOKPROBE_SYMBOL(pre_handler_kretprobe);
e65cefe87   Adrian Bunk   [PATCH] kernel/kp...
1863

659b957f2   Naveen N. Rao   kprobes: Rename [...
1864
  bool __weak arch_kprobe_on_func_entry(unsigned long offset)
90ec5e89e   Naveen N. Rao   kretprobes: Ensur...
1865
1866
1867
  {
  	return !offset;
  }
659b957f2   Naveen N. Rao   kprobes: Rename [...
1868
  bool kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset)
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1869
1870
1871
1872
1873
1874
1875
  {
  	kprobe_opcode_t *kp_addr = _kprobe_addr(addr, sym, offset);
  
  	if (IS_ERR(kp_addr))
  		return false;
  
  	if (!kallsyms_lookup_size_offset((unsigned long)kp_addr, NULL, &offset) ||
659b957f2   Naveen N. Rao   kprobes: Rename [...
1876
  						!arch_kprobe_on_func_entry(offset))
1d585e709   Naveen N. Rao   trace/kprobes: Fi...
1877
1878
1879
1880
  		return false;
  
  	return true;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1881
  int register_kretprobe(struct kretprobe *rp)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1882
1883
1884
1885
  {
  	int ret = 0;
  	struct kretprobe_instance *inst;
  	int i;
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1886
  	void *addr;
90ec5e89e   Naveen N. Rao   kretprobes: Ensur...
1887

659b957f2   Naveen N. Rao   kprobes: Rename [...
1888
  	if (!kprobe_on_func_entry(rp->kp.addr, rp->kp.symbol_name, rp->kp.offset))
90ec5e89e   Naveen N. Rao   kretprobes: Ensur...
1889
  		return -EINVAL;
f438d914b   Masami Hiramatsu   kprobes: support ...
1890
1891
  
  	if (kretprobe_blacklist_size) {
b2a5cd693   Masami Hiramatsu   kprobes: fix a nu...
1892
  		addr = kprobe_addr(&rp->kp);
bc81d48d1   Masami Hiramatsu   kprobes: Return -...
1893
1894
  		if (IS_ERR(addr))
  			return PTR_ERR(addr);
f438d914b   Masami Hiramatsu   kprobes: support ...
1895
1896
1897
1898
1899
1900
  
  		for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
  			if (kretprobe_blacklist[i].addr == addr)
  				return -EINVAL;
  		}
  	}
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1901
1902
  
  	rp->kp.pre_handler = pre_handler_kretprobe;
7522a8423   Ananth N Mavinakayanahalli   [PATCH] kprobes: ...
1903
1904
  	rp->kp.post_handler = NULL;
  	rp->kp.fault_handler = NULL;
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1905
1906
1907
  
  	/* Pre-allocate memory for max kretprobe instances */
  	if (rp->maxactive <= 0) {
926166063   Thomas Gleixner   kprobes: Use CONF...
1908
  #ifdef CONFIG_PREEMPTION
c2ef6661c   Heiko Carstens   kprobes: Fix dist...
1909
  		rp->maxactive = max_t(unsigned int, 10, 2*num_possible_cpus());
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1910
  #else
4dae560f9   Ananth N Mavinakayanahalli   kprobes: Sanitize...
1911
  		rp->maxactive = num_possible_cpus();
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1912
1913
  #endif
  	}
ec484608c   Thomas Gleixner   locking, kprobes:...
1914
  	raw_spin_lock_init(&rp->lock);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1915
1916
  	INIT_HLIST_HEAD(&rp->free_instances);
  	for (i = 0; i < rp->maxactive; i++) {
f47cd9b55   Abhishek Sagar   kprobes: kretprob...
1917
1918
  		inst = kmalloc(sizeof(struct kretprobe_instance) +
  			       rp->data_size, GFP_KERNEL);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1919
1920
1921
1922
  		if (inst == NULL) {
  			free_rp_inst(rp);
  			return -ENOMEM;
  		}
ef53d9c5e   Srinivasa D S   kprobes: improve ...
1923
1924
  		INIT_HLIST_NODE(&inst->hlist);
  		hlist_add_head(&inst->hlist, &rp->free_instances);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1925
1926
1927
1928
  	}
  
  	rp->nmissed = 0;
  	/* Establish function entry probe point */
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1929
  	ret = register_kprobe(&rp->kp);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1930
  	if (ret != 0)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1931
1932
1933
  		free_rp_inst(rp);
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1934
  EXPORT_SYMBOL_GPL(register_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1935

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1936
  int register_kretprobes(struct kretprobe **rps, int num)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1937
1938
1939
1940
1941
1942
  {
  	int ret = 0, i;
  
  	if (num <= 0)
  		return -EINVAL;
  	for (i = 0; i < num; i++) {
49ad2fd76   Masami Hiramatsu   kprobes: remove c...
1943
  		ret = register_kretprobe(rps[i]);
67dddaad5   Masami Hiramatsu   kprobes: fix erro...
1944
1945
1946
  		if (ret < 0) {
  			if (i > 0)
  				unregister_kretprobes(rps, i);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1947
1948
1949
1950
1951
  			break;
  		}
  	}
  	return ret;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1952
  EXPORT_SYMBOL_GPL(register_kretprobes);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1953

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1954
  void unregister_kretprobe(struct kretprobe *rp)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1955
1956
1957
  {
  	unregister_kretprobes(&rp, 1);
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1958
  EXPORT_SYMBOL_GPL(unregister_kretprobe);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1959

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1960
  void unregister_kretprobes(struct kretprobe **rps, int num)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
  {
  	int i;
  
  	if (num <= 0)
  		return;
  	mutex_lock(&kprobe_mutex);
  	for (i = 0; i < num; i++)
  		if (__unregister_kprobe_top(&rps[i]->kp) < 0)
  			rps[i]->kp.addr = NULL;
  	mutex_unlock(&kprobe_mutex);
ae8b7ce76   Paul E. McKenney   kprobes: Replace ...
1971
  	synchronize_rcu();
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1972
1973
1974
1975
1976
1977
1978
  	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...
1979
  EXPORT_SYMBOL_GPL(unregister_kretprobes);
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1980

9edddaa20   Ananth N Mavinakayanahalli   Kprobes: indicate...
1981
  #else /* CONFIG_KRETPROBES */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1982
  int register_kretprobe(struct kretprobe *rp)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1983
1984
1985
  {
  	return -ENOSYS;
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1986
  EXPORT_SYMBOL_GPL(register_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1987

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1988
  int register_kretprobes(struct kretprobe **rps, int num)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
1989
  {
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1990
  	return -ENOSYS;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
1991
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1992
  EXPORT_SYMBOL_GPL(register_kretprobes);
55479f647   Masami Hiramatsu   kprobes: Allow pr...
1993
  void unregister_kretprobe(struct kretprobe *rp)
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1994
  {
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1995
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
1996
  EXPORT_SYMBOL_GPL(unregister_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
1997

55479f647   Masami Hiramatsu   kprobes: Allow pr...
1998
  void unregister_kretprobes(struct kretprobe **rps, int num)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
1999
2000
  {
  }
99081ab55   Masami Hiramatsu   kprobes: move EXP...
2001
  EXPORT_SYMBOL_GPL(unregister_kretprobes);
4c4308cb9   Christoph Hellwig   kprobes: kretprob...
2002

820aede02   Masami Hiramatsu   kprobes: Use NOKP...
2003
  static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
4a296e07c   Masami Hiramatsu   kprobes: add (un)...
2004
2005
  {
  	return 0;
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2006
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
2007
  NOKPROBE_SYMBOL(pre_handler_kretprobe);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2008

4a296e07c   Masami Hiramatsu   kprobes: add (un)...
2009
  #endif /* CONFIG_KRETPROBES */
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2010
  /* Set the kprobe gone and remove its instruction buffer. */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2011
  static void kill_kprobe(struct kprobe *p)
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2012
2013
  {
  	struct kprobe *kp;
de5bd88d5   Masami Hiramatsu   kprobes: support ...
2014

e7b219bc7   Muchun Song   kprobes: fix kill...
2015
2016
  	if (WARN_ON_ONCE(kprobe_gone(p)))
  		return;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2017
  	p->flags |= KPROBE_FLAG_GONE;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2018
  	if (kprobe_aggrprobe(p)) {
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2019
2020
2021
2022
2023
2024
2025
  		/*
  		 * 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;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2026
  		kill_optimized_kprobe(p);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2027
2028
2029
2030
2031
2032
  	}
  	/*
  	 * 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);
1424f0aa1   Muchun Song   kprobes: Fix NULL...
2033
2034
2035
  
  	/*
  	 * The module is going away. We should disarm the kprobe which
3995f7a60   Masami Hiramatsu   kprobes: Fix to c...
2036
2037
  	 * is using ftrace, because ftrace framework is still available at
  	 * MODULE_STATE_GOING notification.
1424f0aa1   Muchun Song   kprobes: Fix NULL...
2038
  	 */
3995f7a60   Masami Hiramatsu   kprobes: Fix to c...
2039
  	if (kprobe_ftrace(p) && !kprobe_disabled(p) && !kprobes_all_disarmed)
1424f0aa1   Muchun Song   kprobes: Fix NULL...
2040
  		disarm_kprobe_ftrace(p);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2041
  }
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2042
  /* Disable one kprobe */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2043
  int disable_kprobe(struct kprobe *kp)
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2044
2045
  {
  	int ret = 0;
297f9233b   Jessica Yu   kprobes: Propagat...
2046
  	struct kprobe *p;
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2047
2048
  
  	mutex_lock(&kprobe_mutex);
6f0f1dd71   Masami Hiramatsu   kprobes: Cleanup ...
2049
  	/* Disable this kprobe */
297f9233b   Jessica Yu   kprobes: Propagat...
2050
2051
2052
  	p = __disable_kprobe(kp);
  	if (IS_ERR(p))
  		ret = PTR_ERR(p);
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2053

c0614829c   Masami Hiramatsu   kprobes: Move ena...
2054
2055
2056
2057
2058
2059
  	mutex_unlock(&kprobe_mutex);
  	return ret;
  }
  EXPORT_SYMBOL_GPL(disable_kprobe);
  
  /* Enable one kprobe */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2060
  int enable_kprobe(struct kprobe *kp)
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
  {
  	int ret = 0;
  	struct kprobe *p;
  
  	mutex_lock(&kprobe_mutex);
  
  	/* Check whether specified probe is valid. */
  	p = __get_valid_kprobe(kp);
  	if (unlikely(p == NULL)) {
  		ret = -EINVAL;
  		goto out;
  	}
  
  	if (kprobe_gone(kp)) {
  		/* This kprobe has gone, we couldn't enable it. */
  		ret = -EINVAL;
  		goto out;
  	}
  
  	if (p != kp)
  		kp->flags &= ~KPROBE_FLAG_DISABLED;
  
  	if (!kprobes_all_disarmed && kprobe_disabled(p)) {
  		p->flags &= ~KPROBE_FLAG_DISABLED;
12310e343   Jessica Yu   kprobes: Propagat...
2085
2086
2087
  		ret = arm_kprobe(p);
  		if (ret)
  			p->flags |= KPROBE_FLAG_DISABLED;
c0614829c   Masami Hiramatsu   kprobes: Move ena...
2088
2089
2090
2091
2092
2093
  	}
  out:
  	mutex_unlock(&kprobe_mutex);
  	return ret;
  }
  EXPORT_SYMBOL_GPL(enable_kprobe);
4458515b2   Masami Hiramatsu   kprobes: Replace ...
2094
  /* Caller must NOT call this in usual path. This is only for critical case */
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
2095
  void dump_kprobe(struct kprobe *kp)
24851d244   Frederic Weisbecker   tracing/kprobes: ...
2096
  {
4458515b2   Masami Hiramatsu   kprobes: Replace ...
2097
2098
2099
2100
2101
2102
2103
  	pr_err("Dumping kprobe:
  ");
  	pr_err("Name: %s
  Offset: %x
  Address: %pS
  ",
  	       kp->symbol_name, kp->offset, kp->addr);
24851d244   Frederic Weisbecker   tracing/kprobes: ...
2104
  }
820aede02   Masami Hiramatsu   kprobes: Use NOKP...
2105
  NOKPROBE_SYMBOL(dump_kprobe);
24851d244   Frederic Weisbecker   tracing/kprobes: ...
2106

fb1a59fae   Masami Hiramatsu   kprobes: Blacklis...
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
  int kprobe_add_ksym_blacklist(unsigned long entry)
  {
  	struct kprobe_blacklist_entry *ent;
  	unsigned long offset = 0, size = 0;
  
  	if (!kernel_text_address(entry) ||
  	    !kallsyms_lookup_size_offset(entry, &size, &offset))
  		return -EINVAL;
  
  	ent = kmalloc(sizeof(*ent), GFP_KERNEL);
  	if (!ent)
  		return -ENOMEM;
  	ent->start_addr = entry;
  	ent->end_addr = entry + size;
  	INIT_LIST_HEAD(&ent->list);
  	list_add_tail(&ent->list, &kprobe_blacklist);
  
  	return (int)size;
  }
  
  /* Add all symbols in given area into kprobe blacklist */
  int kprobe_add_area_blacklist(unsigned long start, unsigned long end)
  {
  	unsigned long entry;
  	int ret = 0;
  
  	for (entry = start; entry < end; entry += ret) {
  		ret = kprobe_add_ksym_blacklist(entry);
  		if (ret < 0)
  			return ret;
  		if (ret == 0)	/* In case of alias symbol */
  			ret = 1;
  	}
  	return 0;
  }
  
  int __init __weak arch_populate_kprobe_blacklist(void)
  {
  	return 0;
  }
376e24242   Masami Hiramatsu   kprobes: Introduc...
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
  /*
   * Lookup and populate the kprobe_blacklist.
   *
   * Unlike the kretprobe blacklist, we'll need to determine
   * the range of addresses that belong to the said functions,
   * since a kprobe need not necessarily be at the beginning
   * of a function.
   */
  static int __init populate_kprobe_blacklist(unsigned long *start,
  					     unsigned long *end)
  {
fb1a59fae   Masami Hiramatsu   kprobes: Blacklis...
2158
  	unsigned long entry;
376e24242   Masami Hiramatsu   kprobes: Introduc...
2159
  	unsigned long *iter;
fb1a59fae   Masami Hiramatsu   kprobes: Blacklis...
2160
  	int ret;
376e24242   Masami Hiramatsu   kprobes: Introduc...
2161
2162
  
  	for (iter = start; iter < end; iter++) {
d81b4253b   Masami Hiramatsu   kprobes: Fix "Fai...
2163
  		entry = arch_deref_entry_point((void *)*iter);
fb1a59fae   Masami Hiramatsu   kprobes: Blacklis...
2164
2165
  		ret = kprobe_add_ksym_blacklist(entry);
  		if (ret == -EINVAL)
376e24242   Masami Hiramatsu   kprobes: Introduc...
2166
  			continue;
fb1a59fae   Masami Hiramatsu   kprobes: Blacklis...
2167
2168
  		if (ret < 0)
  			return ret;
376e24242   Masami Hiramatsu   kprobes: Introduc...
2169
  	}
fb1a59fae   Masami Hiramatsu   kprobes: Blacklis...
2170
2171
2172
2173
2174
2175
  
  	/* Symbols in __kprobes_text are blacklisted */
  	ret = kprobe_add_area_blacklist((unsigned long)__kprobes_text_start,
  					(unsigned long)__kprobes_text_end);
  
  	return ret ? : arch_populate_kprobe_blacklist();
376e24242   Masami Hiramatsu   kprobes: Introduc...
2176
  }
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2177
  /* Module notifier call back, checking kprobes on the module */
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2178
2179
  static int kprobes_module_callback(struct notifier_block *nb,
  				   unsigned long val, void *data)
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2180
2181
2182
  {
  	struct module *mod = data;
  	struct hlist_head *head;
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2183
2184
  	struct kprobe *p;
  	unsigned int i;
f24659d96   Masami Hiramatsu   kprobes: support ...
2185
  	int checkcore = (val == MODULE_STATE_GOING);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2186

f24659d96   Masami Hiramatsu   kprobes: support ...
2187
  	if (val != MODULE_STATE_GOING && val != MODULE_STATE_LIVE)
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2188
2189
2190
  		return NOTIFY_DONE;
  
  	/*
f24659d96   Masami Hiramatsu   kprobes: support ...
2191
2192
2193
2194
  	 * 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 ...
2195
2196
2197
2198
  	 */
  	mutex_lock(&kprobe_mutex);
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
e7b219bc7   Muchun Song   kprobes: fix kill...
2199
2200
2201
  		hlist_for_each_entry_rcu(p, head, hlist) {
  			if (kprobe_gone(p))
  				continue;
f24659d96   Masami Hiramatsu   kprobes: support ...
2202
2203
2204
  			if (within_module_init((unsigned long)p->addr, mod) ||
  			    (checkcore &&
  			     within_module_core((unsigned long)p->addr, mod))) {
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2205
2206
2207
2208
  				/*
  				 * The vaddr this probe is installed will soon
  				 * be vfreed buy not synced to disk. Hence,
  				 * disarming the breakpoint isn't needed.
545a02819   Steven Rostedt (VMware)   kprobes: Document...
2209
2210
2211
2212
2213
2214
  				 *
  				 * Note, this will also move any optimized probes
  				 * that are pending to be removed from their
  				 * corresponding lists to the freeing_list and
  				 * will not be touched by the delayed
  				 * kprobe_optimizer work handler.
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2215
2216
2217
  				 */
  				kill_kprobe(p);
  			}
e7b219bc7   Muchun Song   kprobes: fix kill...
2218
  		}
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2219
2220
2221
2222
2223
2224
2225
2226
2227
  	}
  	mutex_unlock(&kprobe_mutex);
  	return NOTIFY_DONE;
  }
  
  static struct notifier_block kprobe_module_nb = {
  	.notifier_call = kprobes_module_callback,
  	.priority = 0
  };
376e24242   Masami Hiramatsu   kprobes: Introduc...
2228
2229
2230
  /* Markers of _kprobe_blacklist section */
  extern unsigned long __start_kprobe_blacklist[];
  extern unsigned long __stop_kprobe_blacklist[];
c4ab0a837   Masami Hiramatsu   kprobes: tracing/...
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
  void kprobe_free_init_mem(void)
  {
  	void *start = (void *)(&__init_begin);
  	void *end = (void *)(&__init_end);
  	struct hlist_head *head;
  	struct kprobe *p;
  	int i;
  
  	mutex_lock(&kprobe_mutex);
  
  	/* Kill all kprobes on initmem */
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
  		hlist_for_each_entry(p, head, hlist) {
  			if (start <= (void *)p->addr && (void *)p->addr < end)
  				kill_kprobe(p);
  		}
  	}
  
  	mutex_unlock(&kprobe_mutex);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2252
2253
2254
2255
2256
2257
  static int __init init_kprobes(void)
  {
  	int i, err = 0;
  
  	/* FIXME allocate the probe table, currently defined statically */
  	/* initialize all list heads */
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2258
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2259
  		INIT_HLIST_HEAD(&kprobe_table[i]);
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2260
  		INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
ec484608c   Thomas Gleixner   locking, kprobes:...
2261
  		raw_spin_lock_init(&(kretprobe_table_locks[i].lock));
b94cce926   Hien Nguyen   [PATCH] kprobes: ...
2262
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2263

376e24242   Masami Hiramatsu   kprobes: Introduc...
2264
2265
2266
2267
2268
2269
2270
  	err = populate_kprobe_blacklist(__start_kprobe_blacklist,
  					__stop_kprobe_blacklist);
  	if (err) {
  		pr_err("kprobes: failed to populate blacklist: %d
  ", err);
  		pr_err("Please take care of using kprobes.
  ");
3d8d996e0   Srinivasa Ds   kprobes: prevent ...
2271
  	}
f438d914b   Masami Hiramatsu   kprobes: support ...
2272
2273
2274
  	if (kretprobe_blacklist_size) {
  		/* lookup the function address from its name */
  		for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
49e0b4658   Naveen N. Rao   kprobes: Convert ...
2275
  			kretprobe_blacklist[i].addr =
290e30707   Naveen N. Rao   powerpc/kprobes: ...
2276
  				kprobe_lookup_name(kretprobe_blacklist[i].name, 0);
f438d914b   Masami Hiramatsu   kprobes: support ...
2277
2278
2279
2280
2281
2282
  			if (!kretprobe_blacklist[i].addr)
  				printk("kretprobe: lookup failed: %s
  ",
  				       kretprobe_blacklist[i].name);
  		}
  	}
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
2283
2284
  #if defined(CONFIG_OPTPROBES)
  #if defined(__ARCH_WANT_KPROBES_INSN_SLOT)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2285
2286
2287
  	/* Init kprobe_optinsn_slots */
  	kprobe_optinsn_slots.insn_size = MAX_OPTINSN_SIZE;
  #endif
b2be84df9   Masami Hiramatsu   kprobes: Jump opt...
2288
2289
2290
  	/* By default, kprobes can be optimized */
  	kprobes_allow_optimization = true;
  #endif
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2291

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

6772926be   Rusty Lynch   [PATCH] kprobes: ...
2295
  	err = arch_init_kprobes();
802eae7c8   Rusty Lynch   [PATCH] Return pr...
2296
2297
  	if (!err)
  		err = register_die_notifier(&kprobe_exceptions_nb);
e8386a0cb   Masami Hiramatsu   kprobes: support ...
2298
2299
  	if (!err)
  		err = register_module_notifier(&kprobe_module_nb);
ef53d9c5e   Srinivasa D S   kprobes: improve ...
2300
  	kprobes_initialized = (err == 0);
802eae7c8   Rusty Lynch   [PATCH] Return pr...
2301

8c1c93564   Ananth N Mavinakayanahalli   x86: kprobes: add...
2302
2303
  	if (!err)
  		init_test_probes();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2304
2305
  	return err;
  }
65fc965c7   Masami Hiramatsu   kprobes: Fix to i...
2306
  subsys_initcall(init_kprobes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2307

346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2308
  #ifdef CONFIG_DEBUG_FS
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2309
  static void report_probe(struct seq_file *pi, struct kprobe *p,
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2310
  		const char *sym, int offset, char *modname, struct kprobe *pp)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2311
2312
  {
  	char *kprobe_type;
81365a947   Masami Hiramatsu   kprobes: Show add...
2313
  	void *addr = p->addr;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2314
2315
2316
  
  	if (p->pre_handler == pre_handler_kretprobe)
  		kprobe_type = "r";
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2317
2318
  	else
  		kprobe_type = "k";
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2319

e5541c634   Kees Cook   kprobes: Do not e...
2320
  	if (!kallsyms_show_value(pi->file->f_cred))
81365a947   Masami Hiramatsu   kprobes: Show add...
2321
  		addr = NULL;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2322
  	if (sym)
81365a947   Masami Hiramatsu   kprobes: Show add...
2323
2324
  		seq_printf(pi, "%px  %s  %s+0x%x  %s ",
  			addr, kprobe_type, sym, offset,
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2325
  			(modname ? modname : " "));
81365a947   Masami Hiramatsu   kprobes: Show add...
2326
2327
2328
  	else	/* try to use %pS */
  		seq_printf(pi, "%px  %s  %pS ",
  			addr, kprobe_type, p->addr);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2329
2330
2331
  
  	if (!pp)
  		pp = p;
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
2332
2333
  	seq_printf(pi, "%s%s%s%s
  ",
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2334
2335
  		(kprobe_gone(p) ? "[GONE]" : ""),
  		((kprobe_disabled(p) && !kprobe_gone(p)) ?  "[DISABLED]" : ""),
ae6aa16fd   Masami Hiramatsu   kprobes: introduc...
2336
2337
  		(kprobe_optimized(pp) ? "[OPTIMIZED]" : ""),
  		(kprobe_ftrace(pp) ? "[FTRACE]" : ""));
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2338
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2339
  static void *kprobe_seq_start(struct seq_file *f, loff_t *pos)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2340
2341
2342
  {
  	return (*pos < KPROBE_TABLE_SIZE) ? pos : NULL;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2343
  static void *kprobe_seq_next(struct seq_file *f, void *v, loff_t *pos)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2344
2345
2346
2347
2348
2349
  {
  	(*pos)++;
  	if (*pos >= KPROBE_TABLE_SIZE)
  		return NULL;
  	return pos;
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2350
  static void kprobe_seq_stop(struct seq_file *f, void *v)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2351
2352
2353
  {
  	/* Nothing to do */
  }
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2354
  static int show_kprobe_addr(struct seq_file *pi, void *v)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2355
2356
  {
  	struct hlist_head *head;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2357
2358
2359
  	struct kprobe *p, *kp;
  	const char *sym = NULL;
  	unsigned int i = *(loff_t *) v;
ffb451227   Alexey Dobriyan   Simplify kallsyms...
2360
  	unsigned long offset = 0;
ab7678656   Joe Mario   kprobes: use KSYM...
2361
  	char *modname, namebuf[KSYM_NAME_LEN];
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2362
2363
2364
  
  	head = &kprobe_table[i];
  	preempt_disable();
b67bfe0d4   Sasha Levin   hlist: drop the n...
2365
  	hlist_for_each_entry_rcu(p, head, hlist) {
ffb451227   Alexey Dobriyan   Simplify kallsyms...
2366
  		sym = kallsyms_lookup((unsigned long)p->addr, NULL,
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2367
  					&offset, &modname, namebuf);
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2368
  		if (kprobe_aggrprobe(p)) {
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2369
  			list_for_each_entry_rcu(kp, &p->list, list)
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2370
  				report_probe(pi, kp, sym, offset, modname, p);
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2371
  		} else
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2372
  			report_probe(pi, p, sym, offset, modname, NULL);
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2373
2374
2375
2376
  	}
  	preempt_enable();
  	return 0;
  }
88e9d34c7   James Morris   seq_file: constif...
2377
  static const struct seq_operations kprobes_seq_ops = {
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2378
2379
2380
2381
2382
  	.start = kprobe_seq_start,
  	.next  = kprobe_seq_next,
  	.stop  = kprobe_seq_stop,
  	.show  = show_kprobe_addr
  };
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2383
  static int kprobes_open(struct inode *inode, struct file *filp)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2384
2385
2386
  {
  	return seq_open(filp, &kprobes_seq_ops);
  }
828c09509   Alexey Dobriyan   const: constify r...
2387
  static const struct file_operations debugfs_kprobes_operations = {
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2388
2389
2390
2391
2392
  	.open           = kprobes_open,
  	.read           = seq_read,
  	.llseek         = seq_lseek,
  	.release        = seq_release,
  };
637247403   Masami Hiramatsu   kprobes: Show bla...
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
  /* kprobes/blacklist -- shows which functions can not be probed */
  static void *kprobe_blacklist_seq_start(struct seq_file *m, loff_t *pos)
  {
  	return seq_list_start(&kprobe_blacklist, *pos);
  }
  
  static void *kprobe_blacklist_seq_next(struct seq_file *m, void *v, loff_t *pos)
  {
  	return seq_list_next(v, &kprobe_blacklist, pos);
  }
  
  static int kprobe_blacklist_seq_show(struct seq_file *m, void *v)
  {
  	struct kprobe_blacklist_entry *ent =
  		list_entry(v, struct kprobe_blacklist_entry, list);
ffb9bd68e   Masami Hiramatsu   kprobes: Show bla...
2408
2409
2410
2411
  	/*
  	 * If /proc/kallsyms is not showing kernel address, we won't
  	 * show them here either.
  	 */
e5541c634   Kees Cook   kprobes: Do not e...
2412
  	if (!kallsyms_show_value(m->file->f_cred))
ffb9bd68e   Masami Hiramatsu   kprobes: Show bla...
2413
2414
2415
2416
2417
2418
2419
  		seq_printf(m, "0x%px-0x%px\t%ps
  ", NULL, NULL,
  			   (void *)ent->start_addr);
  	else
  		seq_printf(m, "0x%px-0x%px\t%ps
  ", (void *)ent->start_addr,
  			   (void *)ent->end_addr, (void *)ent->start_addr);
637247403   Masami Hiramatsu   kprobes: Show bla...
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
  	return 0;
  }
  
  static const struct seq_operations kprobe_blacklist_seq_ops = {
  	.start = kprobe_blacklist_seq_start,
  	.next  = kprobe_blacklist_seq_next,
  	.stop  = kprobe_seq_stop,	/* Reuse void function */
  	.show  = kprobe_blacklist_seq_show,
  };
  
  static int kprobe_blacklist_open(struct inode *inode, struct file *filp)
  {
  	return seq_open(filp, &kprobe_blacklist_seq_ops);
  }
  
  static const struct file_operations debugfs_kprobe_blacklist_ops = {
  	.open           = kprobe_blacklist_open,
  	.read           = seq_read,
  	.llseek         = seq_lseek,
  	.release        = seq_release,
  };
12310e343   Jessica Yu   kprobes: Propagat...
2441
  static int arm_all_kprobes(void)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2442
2443
  {
  	struct hlist_head *head;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2444
  	struct kprobe *p;
12310e343   Jessica Yu   kprobes: Propagat...
2445
2446
  	unsigned int i, total = 0, errors = 0;
  	int err, ret = 0;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2447
2448
  
  	mutex_lock(&kprobe_mutex);
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2449
2450
  	/* If kprobes are armed, just return */
  	if (!kprobes_all_disarmed)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2451
  		goto already_enabled;
977ad481b   Wang Nan   kprobes: set kpro...
2452
2453
2454
2455
2456
2457
  	/*
  	 * optimize_kprobe() called by arm_kprobe() checks
  	 * kprobes_all_disarmed, so set kprobes_all_disarmed before
  	 * arm_kprobe.
  	 */
  	kprobes_all_disarmed = false;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2458
  	/* Arming kprobes doesn't optimize kprobe itself */
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2459
2460
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
12310e343   Jessica Yu   kprobes: Propagat...
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
  		/* Arm all kprobes on a best-effort basis */
  		hlist_for_each_entry_rcu(p, head, hlist) {
  			if (!kprobe_disabled(p)) {
  				err = arm_kprobe(p);
  				if (err)  {
  					errors++;
  					ret = err;
  				}
  				total++;
  			}
  		}
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2472
  	}
12310e343   Jessica Yu   kprobes: Propagat...
2473
2474
2475
2476
2477
2478
2479
  	if (errors)
  		pr_warn("Kprobes globally enabled, but failed to arm %d out of %d probes
  ",
  			errors, total);
  	else
  		pr_info("Kprobes globally enabled
  ");
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2480
2481
2482
  
  already_enabled:
  	mutex_unlock(&kprobe_mutex);
12310e343   Jessica Yu   kprobes: Propagat...
2483
  	return ret;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2484
  }
297f9233b   Jessica Yu   kprobes: Propagat...
2485
  static int disarm_all_kprobes(void)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2486
2487
  {
  	struct hlist_head *head;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2488
  	struct kprobe *p;
297f9233b   Jessica Yu   kprobes: Propagat...
2489
2490
  	unsigned int i, total = 0, errors = 0;
  	int err, ret = 0;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2491
2492
  
  	mutex_lock(&kprobe_mutex);
e579abeb5   Masami Hiramatsu   kprobes: rename k...
2493
  	/* If kprobes are already disarmed, just return */
6274de498   Masami Hiramatsu   kprobes: Support ...
2494
2495
  	if (kprobes_all_disarmed) {
  		mutex_unlock(&kprobe_mutex);
297f9233b   Jessica Yu   kprobes: Propagat...
2496
  		return 0;
6274de498   Masami Hiramatsu   kprobes: Support ...
2497
  	}
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2498

e579abeb5   Masami Hiramatsu   kprobes: rename k...
2499
  	kprobes_all_disarmed = true;
afd66255b   Masami Hiramatsu   kprobes: Introduc...
2500

bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2501
2502
  	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
  		head = &kprobe_table[i];
297f9233b   Jessica Yu   kprobes: Propagat...
2503
  		/* Disarm all kprobes on a best-effort basis */
b67bfe0d4   Sasha Levin   hlist: drop the n...
2504
  		hlist_for_each_entry_rcu(p, head, hlist) {
297f9233b   Jessica Yu   kprobes: Propagat...
2505
2506
2507
2508
2509
2510
2511
2512
  			if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p)) {
  				err = disarm_kprobe(p, false);
  				if (err) {
  					errors++;
  					ret = err;
  				}
  				total++;
  			}
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2513
2514
  		}
  	}
297f9233b   Jessica Yu   kprobes: Propagat...
2515
2516
2517
2518
2519
2520
2521
2522
  
  	if (errors)
  		pr_warn("Kprobes globally disabled, but failed to disarm %d out of %d probes
  ",
  			errors, total);
  	else
  		pr_info("Kprobes globally disabled
  ");
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2523
  	mutex_unlock(&kprobe_mutex);
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2524

6274de498   Masami Hiramatsu   kprobes: Support ...
2525
2526
  	/* Wait for disarming all kprobes by optimizer */
  	wait_for_kprobe_optimizer();
297f9233b   Jessica Yu   kprobes: Propagat...
2527
2528
  
  	return ret;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
  }
  
  /*
   * 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...
2540
  	if (!kprobes_all_disarmed)
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
  		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 ...
2554
  	size_t buf_size;
12310e343   Jessica Yu   kprobes: Propagat...
2555
  	int ret = 0;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2556
2557
2558
2559
  
  	buf_size = min(count, (sizeof(buf)-1));
  	if (copy_from_user(buf, user_buf, buf_size))
  		return -EFAULT;
10fb46d5f   Mathias Krause   kprobes: handle e...
2560
  	buf[buf_size] = '\0';
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2561
2562
2563
2564
  	switch (buf[0]) {
  	case 'y':
  	case 'Y':
  	case '1':
12310e343   Jessica Yu   kprobes: Propagat...
2565
  		ret = arm_all_kprobes();
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2566
2567
2568
2569
  		break;
  	case 'n':
  	case 'N':
  	case '0':
297f9233b   Jessica Yu   kprobes: Propagat...
2570
  		ret = disarm_all_kprobes();
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2571
  		break;
10fb46d5f   Mathias Krause   kprobes: handle e...
2572
2573
  	default:
  		return -EINVAL;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2574
  	}
12310e343   Jessica Yu   kprobes: Propagat...
2575
2576
  	if (ret)
  		return ret;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2577
2578
  	return count;
  }
828c09509   Alexey Dobriyan   const: constify r...
2579
  static const struct file_operations fops_kp = {
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2580
2581
  	.read =         read_enabled_file_bool,
  	.write =        write_enabled_file_bool,
6038f373a   Arnd Bergmann   llseek: automatic...
2582
  	.llseek =	default_llseek,
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2583
  };
55479f647   Masami Hiramatsu   kprobes: Allow pr...
2584
  static int __init debugfs_kprobe_init(void)
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2585
  {
8c0fd1fa6   Greg Kroah-Hartman   kprobes: no need ...
2586
  	struct dentry *dir;
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2587
  	unsigned int value = 1;
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2588
2589
  
  	dir = debugfs_create_dir("kprobes", NULL);
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2590

8c0fd1fa6   Greg Kroah-Hartman   kprobes: no need ...
2591
2592
  	debugfs_create_file("list", 0400, dir, NULL,
  			    &debugfs_kprobes_operations);
346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2593

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

8c0fd1fa6   Greg Kroah-Hartman   kprobes: no need ...
2596
2597
  	debugfs_create_file("blacklist", 0400, dir, NULL,
  			    &debugfs_kprobe_blacklist_ops);
bf8f6e5b3   Ananth N Mavinakayanahalli   Kprobes: The ON/O...
2598

346fd59ba   Srinivasa Ds   [PATCH] kprobes: ...
2599
2600
2601
2602
2603
  	return 0;
  }
  
  late_initcall(debugfs_kprobe_init);
  #endif /* CONFIG_DEBUG_FS */