2 * Kernel Probes (KProbes)
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 * Copyright (C) IBM Corporation, 2002, 2004
21 * 2002-Oct Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel
22 * Probes initial implementation (includes suggestions from
24 * 2004-Aug Updated by Prasanna S Panchamukhi <prasanna@in.ibm.com> with
25 * hlists and exceptions notifier as suggested by Andi Kleen.
26 * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
27 * interface to access function arguments.
28 * 2004-Sep Prasanna S Panchamukhi <prasanna@in.ibm.com> Changed Kprobes
29 * exceptions notifier to be first on the priority list.
31 #include <linux/kprobes.h>
32 #include <linux/spinlock.h>
33 #include <linux/hash.h>
34 #include <linux/init.h>
35 #include <linux/module.h>
36 #include <asm/cacheflush.h>
37 #include <asm/errno.h>
38 #include <asm/kdebug.h>
40 #define KPROBE_HASH_BITS 6
41 #define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS)
43 static struct hlist_head kprobe_table
[KPROBE_TABLE_SIZE
];
45 unsigned int kprobe_cpu
= NR_CPUS
;
46 static DEFINE_SPINLOCK(kprobe_lock
);
47 static struct kprobe
*curr_kprobe
;
49 /* Locks kprobe: irqs must be disabled */
50 void lock_kprobes(void)
52 spin_lock(&kprobe_lock
);
53 kprobe_cpu
= smp_processor_id();
56 void unlock_kprobes(void)
59 spin_unlock(&kprobe_lock
);
62 /* You have to be holding the kprobe_lock */
63 struct kprobe
*get_kprobe(void *addr
)
65 struct hlist_head
*head
;
66 struct hlist_node
*node
;
68 head
= &kprobe_table
[hash_ptr(addr
, KPROBE_HASH_BITS
)];
69 hlist_for_each(node
, head
) {
70 struct kprobe
*p
= hlist_entry(node
, struct kprobe
, hlist
);
78 * Aggregate handlers for multiple kprobes support - these handlers
79 * take care of invoking the individual kprobe handlers on p->list
81 int aggr_pre_handler(struct kprobe
*p
, struct pt_regs
*regs
)
85 list_for_each_entry(kp
, &p
->list
, list
) {
86 if (kp
->pre_handler
) {
88 kp
->pre_handler(kp
, regs
);
95 void aggr_post_handler(struct kprobe
*p
, struct pt_regs
*regs
,
100 list_for_each_entry(kp
, &p
->list
, list
) {
101 if (kp
->post_handler
) {
103 kp
->post_handler(kp
, regs
, flags
);
110 int aggr_fault_handler(struct kprobe
*p
, struct pt_regs
*regs
, int trapnr
)
113 * if we faulted "during" the execution of a user specified
114 * probe handler, invoke just that probe's fault handler
116 if (curr_kprobe
&& curr_kprobe
->fault_handler
) {
117 if (curr_kprobe
->fault_handler(curr_kprobe
, regs
, trapnr
))
124 * Fill in the required fields of the "manager kprobe". Replace the
125 * earlier kprobe in the hlist with the manager kprobe
127 static inline void add_aggr_kprobe(struct kprobe
*ap
, struct kprobe
*p
)
130 ap
->opcode
= p
->opcode
;
131 memcpy(&ap
->ainsn
, &p
->ainsn
, sizeof(struct arch_specific_insn
));
133 ap
->pre_handler
= aggr_pre_handler
;
134 ap
->post_handler
= aggr_post_handler
;
135 ap
->fault_handler
= aggr_fault_handler
;
137 INIT_LIST_HEAD(&ap
->list
);
138 list_add(&p
->list
, &ap
->list
);
140 INIT_HLIST_NODE(&ap
->hlist
);
141 hlist_del(&p
->hlist
);
142 hlist_add_head(&ap
->hlist
,
143 &kprobe_table
[hash_ptr(ap
->addr
, KPROBE_HASH_BITS
)]);
147 * This is the second or subsequent kprobe at the address - handle
149 * TODO: Move kcalloc outside the spinlock
151 static int register_aggr_kprobe(struct kprobe
*old_p
, struct kprobe
*p
)
156 if (old_p
->break_handler
|| p
->break_handler
) {
157 ret
= -EEXIST
; /* kprobe and jprobe can't (yet) coexist */
158 } else if (old_p
->pre_handler
== aggr_pre_handler
) {
159 list_add(&p
->list
, &old_p
->list
);
161 ap
= kcalloc(1, sizeof(struct kprobe
), GFP_ATOMIC
);
164 add_aggr_kprobe(ap
, old_p
);
165 list_add(&p
->list
, &ap
->list
);
170 /* kprobe removal house-keeping routines */
171 static inline void cleanup_kprobe(struct kprobe
*p
, unsigned long flags
)
173 *p
->addr
= p
->opcode
;
174 hlist_del(&p
->hlist
);
175 flush_icache_range((unsigned long) p
->addr
,
176 (unsigned long) p
->addr
+ sizeof(kprobe_opcode_t
));
177 spin_unlock_irqrestore(&kprobe_lock
, flags
);
178 arch_remove_kprobe(p
);
181 static inline void cleanup_aggr_kprobe(struct kprobe
*old_p
,
182 struct kprobe
*p
, unsigned long flags
)
185 if (list_empty(&old_p
->list
)) {
186 cleanup_kprobe(old_p
, flags
);
189 spin_unlock_irqrestore(&kprobe_lock
, flags
);
192 int register_kprobe(struct kprobe
*p
)
195 unsigned long flags
= 0;
196 struct kprobe
*old_p
;
198 if ((ret
= arch_prepare_kprobe(p
)) != 0) {
201 spin_lock_irqsave(&kprobe_lock
, flags
);
202 old_p
= get_kprobe(p
->addr
);
204 ret
= register_aggr_kprobe(old_p
, p
);
209 INIT_HLIST_NODE(&p
->hlist
);
210 hlist_add_head(&p
->hlist
,
211 &kprobe_table
[hash_ptr(p
->addr
, KPROBE_HASH_BITS
)]);
213 p
->opcode
= *p
->addr
;
214 *p
->addr
= BREAKPOINT_INSTRUCTION
;
215 flush_icache_range((unsigned long) p
->addr
,
216 (unsigned long) p
->addr
+ sizeof(kprobe_opcode_t
));
218 spin_unlock_irqrestore(&kprobe_lock
, flags
);
221 arch_remove_kprobe(p
);
225 void unregister_kprobe(struct kprobe
*p
)
228 struct kprobe
*old_p
;
230 spin_lock_irqsave(&kprobe_lock
, flags
);
231 old_p
= get_kprobe(p
->addr
);
233 if (old_p
->pre_handler
== aggr_pre_handler
)
234 cleanup_aggr_kprobe(old_p
, p
, flags
);
236 cleanup_kprobe(p
, flags
);
238 spin_unlock_irqrestore(&kprobe_lock
, flags
);
241 static struct notifier_block kprobe_exceptions_nb
= {
242 .notifier_call
= kprobe_exceptions_notify
,
243 .priority
= 0x7fffffff /* we need to notified first */
246 int register_jprobe(struct jprobe
*jp
)
248 /* Todo: Verify probepoint is a function entry point */
249 jp
->kp
.pre_handler
= setjmp_pre_handler
;
250 jp
->kp
.break_handler
= longjmp_break_handler
;
252 return register_kprobe(&jp
->kp
);
255 void unregister_jprobe(struct jprobe
*jp
)
257 unregister_kprobe(&jp
->kp
);
260 static int __init
init_kprobes(void)
264 /* FIXME allocate the probe table, currently defined statically */
265 /* initialize all list heads */
266 for (i
= 0; i
< KPROBE_TABLE_SIZE
; i
++)
267 INIT_HLIST_HEAD(&kprobe_table
[i
]);
269 err
= register_die_notifier(&kprobe_exceptions_nb
);
273 __initcall(init_kprobes
);
275 EXPORT_SYMBOL_GPL(register_kprobe
);
276 EXPORT_SYMBOL_GPL(unregister_kprobe
);
277 EXPORT_SYMBOL_GPL(register_jprobe
);
278 EXPORT_SYMBOL_GPL(unregister_jprobe
);
279 EXPORT_SYMBOL_GPL(jprobe_return
);