1 ////////////////////////////////////////////////////////////////////////////////////
3 // FILE: probes_manager.c
6 // This file is C source for SWAP driver.
8 // SEE ALSO: probes_manager.h
9 // AUTHOR: L.Komkov, A.Gerenkov
10 // COMPANY NAME: Samsung Research Center in Moscow
11 // DEPT NAME: Advanced Software Group
12 // CREATED: 2008.02.15
14 // REVISION DATE: 2008.12.03
16 ////////////////////////////////////////////////////////////////////////////////////
18 #include <linux/percpu.h>
20 #include <dbi_kprobes_deps.h>
22 #include "probes_manager.h"
24 /* list of selected non-predefined kernel probes */
25 static HLIST_HEAD(kernel_probes);
27 static int register_kernel_probe(kernel_probe_t *p)
32 ret = dbi_register_jprobe(&p->jprobe);
34 EPRINTF("dbi_register_jprobe(0x%lx) failure %d", p->addr, ret);
38 /* register kretprobe */
39 ret = dbi_register_kretprobe(&p->retprobe);
41 EPRINTF("dbi_register_kretprobe(0x%lx) failure %d",
44 dbi_unregister_jprobe(&p->jprobe);
51 static int unregister_kernel_probe(kernel_probe_t *p)
53 dbi_unregister_kretprobe(&p->retprobe);
54 dbi_unregister_jprobe(&p->jprobe);
59 int set_kernel_probes(void)
63 struct hlist_node *node;
65 swap_hlist_for_each_entry_rcu(p, node, &kernel_probes, hlist) {
66 ret = register_kernel_probe(p);
68 /* return into safe state */
69 /* FIXME: unset for installed probes */
70 unset_kernel_probes();
78 int unset_kernel_probes(void)
81 struct hlist_node *node;
83 swap_hlist_for_each_entry_rcu(p, node, &kernel_probes, hlist)
84 unregister_kernel_probe(p);
89 static kernel_probe_t *create_kern_probe(unsigned long addr)
91 kernel_probe_t *probe = kmalloc(sizeof(*probe), GFP_KERNEL);
93 EPRINTF("no memory for new probe!");
97 memset(probe, 0, sizeof(*probe));
99 probe->jprobe.kp.addr = probe->retprobe.kp.addr = (kprobe_opcode_t *)addr;
100 probe->jprobe.priv_arg = probe->retprobe.priv_arg = probe;
102 INIT_HLIST_NODE(&probe->hlist);
107 static void free_kern_probe(kernel_probe_t *p)
112 /* Searches non-predefined kernel probe in the list. */
113 static kernel_probe_t* find_probe(unsigned long addr)
116 struct hlist_node *node;
118 /* check if such probe does exist */
119 swap_hlist_for_each_entry_rcu(p, node, &kernel_probes, hlist)
126 /* Adds non-predefined kernel probe to the list. */
127 static void add_probe_to_list(kernel_probe_t *p)
129 hlist_add_head_rcu(&p->hlist, &kernel_probes);
132 int add_probe(unsigned long addr,
133 unsigned long pre_handler,
134 unsigned long jp_handler,
135 unsigned long rp_handler)
139 /* check if such probe does already exist */
140 p = find_probe(addr);
142 /* It is not a problem if we have already registered
147 p = create_kern_probe(addr);
151 p->jprobe.pre_entry = (kprobe_pre_entry_handler_t)pre_handler;
152 p->jprobe.entry = (kprobe_opcode_t *)jp_handler;
153 p->retprobe.handler = (kretprobe_handler_t)rp_handler;
155 add_probe_to_list(p);
160 int reset_probes(void)
162 struct hlist_node *node, *tnode;
165 swap_hlist_for_each_entry_safe (p, node, tnode, &kernel_probes, hlist) {
173 static DEFINE_PER_CPU(kernel_probe_t *, gpKernProbe) = NULL;
176 def_jprobe_event_pre_handler (kernel_probe_t * probe, struct pt_regs *regs)
178 __get_cpu_var (gpKernProbe) = probe;
184 def_jprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
187 kernel_probe_t *probe = __get_cpu_var(gpKernProbe);
189 pack_event_info(KS_PROBE_ID, RECORD_ENTRY, "pxxxxxx", probe->addr, arg1, arg2, arg3, arg4, arg5, arg6);
190 dbi_jprobe_return ();
194 def_retprobe_event_handler (struct kretprobe_instance *pi, struct pt_regs *regs, kernel_probe_t * probe)
198 ret_val = regs_return_value(regs);
199 pack_event_info(KS_PROBE_ID, RECORD_RET, "pd", probe->addr, ret_val);
204 int install_kern_otg_probe(unsigned long addr,
205 unsigned long pre_handler,
206 unsigned long jp_handler,
207 unsigned long rp_handler)
212 p = find_probe(addr);
217 p = create_kern_probe(addr);
221 p->jprobe.pre_entry = (kprobe_pre_entry_handler_t)pre_handler;
222 p->jprobe.entry = (kprobe_opcode_t *)jp_handler;
223 p->retprobe.handler = (kretprobe_handler_t)rp_handler;
225 add_probe_to_list(p);
227 ret = register_kernel_probe(p);
229 EPRINTF("Cannot set kernel probe at addr %lx", addr);
235 EXPORT_SYMBOL_GPL(install_kern_otg_probe);