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"
25 probes_manager_init (void)
28 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38)
29 spin_lock_init(&ec_spinlock);
30 spin_lock_init(&ec_probe_spinlock);
31 #endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
37 return storage_init ();
41 probes_manager_down (void)
43 detach_selected_probes ();
48 static int register_kernel_probe(kernel_probe_t *p)
53 ret = dbi_register_jprobe(&p->jprobe);
55 EPRINTF("dbi_register_jprobe(0x%lx) failure %d", p->addr, ret);
59 /* register kretprobe */
60 ret = dbi_register_kretprobe(&p->retprobe);
62 EPRINTF("dbi_register_kretprobe(0x%lx) failure %d",
65 dbi_unregister_jprobe(&p->jprobe);
72 static int unregister_kernel_probe(kernel_probe_t *p)
74 dbi_unregister_kretprobe(&p->retprobe);
75 dbi_unregister_jprobe(&p->jprobe);
81 attach_selected_probes (void)
84 int partial_result = 0;
86 struct hlist_node *node;
88 swap_hlist_for_each_entry_rcu (p, node, &kernel_probes, hlist)
90 partial_result = register_kernel_probe (p);
93 result = partial_result;
94 detach_selected_probes (); // return into safe state
103 detach_selected_probes (void)
106 struct hlist_node *node;
108 swap_hlist_for_each_entry_rcu (p, node, &kernel_probes, hlist)
109 unregister_kernel_probe (p);
110 swap_hlist_for_each_entry_rcu (p, node, &otg_kernel_probes, hlist) {
111 unregister_kernel_probe(p);
118 add_probe (unsigned long addr)
121 kernel_probe_t **pprobe = NULL;
123 DPRINTF("add probe at 0x%0x\n", addr);
124 if (EC_STATE_IDLE != ec_info.ec_state)
126 EPRINTF("Probes addition is allowed in IDLE state only.");
130 result = add_probe_to_list (addr, pprobe);
135 int reset_probes(void)
137 struct hlist_node *node, *tnode;
140 swap_hlist_for_each_entry_safe (p, node, tnode, &kernel_probes, hlist) {
145 swap_hlist_for_each_entry_safe (p, node, tnode, &otg_kernel_probes, hlist) {
154 remove_probe (unsigned long addr)
158 if (EC_STATE_IDLE != ec_info.ec_state)
160 EPRINTF("Probes addition is allowed in IDLE state only.");
164 result = remove_probe_from_list (addr);
169 static DEFINE_PER_CPU(kernel_probe_t *, gpKernProbe) = NULL;
172 def_jprobe_event_pre_handler (kernel_probe_t * probe, struct pt_regs *regs)
174 __get_cpu_var (gpKernProbe) = probe;
180 def_jprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
183 kernel_probe_t *probe = __get_cpu_var(gpKernProbe);
185 pack_event_info(KS_PROBE_ID, RECORD_ENTRY, "pxxxxxx", probe->addr, arg1, arg2, arg3, arg4, arg5, arg6);
186 dbi_jprobe_return ();
190 def_retprobe_event_handler (struct kretprobe_instance *pi, struct pt_regs *regs, kernel_probe_t * probe)
194 ret_val = regs_return_value(regs);
195 pack_event_info(KS_PROBE_ID, RECORD_RET, "pd", probe->addr, ret_val);
200 int install_kern_otg_probe(unsigned long addr,
201 unsigned long pre_handler,
202 unsigned long jp_handler,
203 unsigned long rp_handler)
205 kernel_probe_t *new_probe = NULL;
206 kernel_probe_t *probe;
209 probe = find_probe(addr);
211 /* It is not a problem if we have already registered
216 new_probe = kmalloc(sizeof (kernel_probe_t), GFP_ATOMIC);
218 EPRINTF("No memory for new probe");
221 memset(new_probe, 0, sizeof(kernel_probe_t));
223 new_probe->addr = addr;
224 new_probe->jprobe.kp.addr = new_probe->retprobe.kp.addr = (kprobe_opcode_t *)addr;
225 new_probe->jprobe.priv_arg = new_probe->retprobe.priv_arg = new_probe;
228 new_probe->jprobe.pre_entry =
229 (kprobe_pre_entry_handler_t)
232 new_probe->jprobe.pre_entry =
233 (kprobe_pre_entry_handler_t)
234 def_jprobe_event_pre_handler;
238 new_probe->jprobe.entry = (kprobe_opcode_t *)jp_handler;
240 new_probe->jprobe.entry =
242 def_jprobe_event_handler;
246 new_probe->retprobe.handler = (kretprobe_handler_t)rp_handler;
248 new_probe->retprobe.handler =
249 (kretprobe_handler_t)
250 def_retprobe_event_handler;
253 INIT_HLIST_NODE (&new_probe->hlist);
254 hlist_add_head_rcu (&new_probe->hlist, &kernel_probes);
256 ret = register_kernel_probe(new_probe);
258 EPRINTF("Cannot set kernel probe at addr %lx", addr);
264 EXPORT_SYMBOL_GPL(install_kern_otg_probe);