3 * @author Vyacheslav Cherkashin
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * Copyright (C) Samsung Electronics, 2013
25 * @section DESCRIPTION
27 * User-space instrumentation controls.
31 #include <linux/slab.h>
32 #include <linux/module.h>
33 #include <linux/version.h>
34 #include <linux/err.h>
35 #include <linux/errno.h>
36 #include <us_manager/pf/pf_group.h>
37 #include <us_manager/probes/probes.h>
39 #include "msg_parser.h"
45 struct list_head list;
50 static LIST_HEAD(pfg_item_list);
51 static DEFINE_SPINLOCK(pfg_item_lock);
54 static struct pfg_msg_cb msg_cb = {
55 .msg_info = usm_msg_info,
56 .msg_status_info = usm_msg_status_info,
57 .msg_term = usm_msg_term,
58 .msg_map = usm_msg_map,
59 .msg_unmap = usm_msg_unmap
62 static struct pfg_item *pfg_item_create(struct pf_group *pfg)
65 struct pfg_item *item;
67 ret = pfg_msg_cb_set(pfg, &msg_cb);
71 item = kmalloc(sizeof(*item), GFP_KERNEL);
73 return ERR_PTR(-ENOMEM);
75 INIT_LIST_HEAD(&item->list);
81 static void pfg_item_free(struct pfg_item *item)
83 pfg_msg_cb_reset(item->pfg);
87 /* called with pfg_item_lock held */
88 static bool pfg_check(struct pf_group *pfg)
90 struct pfg_item *item;
92 list_for_each_entry(item, &pfg_item_list, list) {
100 static int pfg_add(struct pf_group *pfg)
104 spin_lock(&pfg_item_lock);
105 already = pfg_check(pfg);
106 spin_unlock(&pfg_item_lock);
111 struct pfg_item *item;
113 item = pfg_item_create(pfg);
115 return PTR_ERR(item);
117 spin_lock(&pfg_item_lock);
118 list_add(&item->list, &pfg_item_list);
119 spin_unlock(&pfg_item_lock);
125 void pfg_put_all(void)
128 struct pfg_item *item, *n;
130 spin_lock(&pfg_item_lock);
131 list_splice_init(&pfg_item_list, &tmp_list);
132 spin_unlock(&pfg_item_lock);
134 list_for_each_entry_safe(item, n, &tmp_list, list) {
135 struct pf_group *pfg = item->pfg;
137 list_del(&item->list);
143 static int mod_func_inst(struct func_inst_data *func, struct pf_group *pfg,
144 struct dentry *dentry, enum MOD_TYPE mt)
150 ret = pf_register_probe(pfg, dentry, func->addr,
154 ret = pf_unregister_probe(pfg, dentry, func->addr);
157 printk(KERN_INFO "ERROR: mod_type=0x%x\n", mt);
164 static int mod_lib_inst(struct lib_inst_data *lib, struct pf_group *pfg,
168 struct dentry *dentry;
170 dentry = dentry_by_path(lib->path);
171 if (dentry == NULL) {
172 printk(KERN_INFO "Cannot get dentry by path %s\n", lib->path);
176 for (i = 0; i < lib->cnt_func; ++i) {
177 ret = mod_func_inst(lib->func[i], pfg, dentry, mt);
179 printk(KERN_INFO "Cannot mod func inst, ret = %d\n",
188 static int get_pfg_by_app_info(struct app_info_data *app_info,
189 struct pf_group **pfg)
191 struct dentry *dentry;
193 dentry = dentry_by_path(app_info->exec_path);
197 switch (app_info->app_type) {
199 if (app_info->tgid == 0) {
200 if (app_info->exec_path[0] == '\0')
201 *pfg = get_pf_group_dumb(dentry);
205 *pfg = get_pf_group_by_tgid(app_info->tgid, dentry);
207 case AT_TIZEN_WEB_APP:
208 *pfg = get_pf_group_by_comm(app_info->app_id, dentry);
210 case AT_TIZEN_NATIVE_APP:
213 *pfg = get_pf_group_by_dentry(dentry, dentry);
216 printk(KERN_INFO "ERROR: app_type=0x%x\n", app_info->app_type);
223 static int mod_us_app_inst(struct app_inst_data *app_inst, enum MOD_TYPE mt)
226 struct pf_group *pfg;
227 struct dentry *dentry;
229 ret = get_pfg_by_app_info(app_inst->app_info, &pfg);
231 printk(KERN_INFO "Cannot get pfg by app info, ret = %d\n", ret);
238 printk(KERN_INFO "Cannot pfg_add, ret=%d\n", ret);
242 for (i = 0; i < app_inst->cnt_func; ++i) {
244 dentry = dentry_by_path(app_inst->app_info->exec_path);
245 if (dentry == NULL) {
246 printk(KERN_INFO "Cannot find dentry by path %s\n",
247 app_inst->app_info->exec_path);
251 ret = mod_func_inst(app_inst->func[i], pfg, dentry, mt);
253 printk(KERN_INFO "Cannot mod func inst, ret = %d\n",
259 for (i = 0; i < app_inst->cnt_lib; ++i) {
260 ret = mod_lib_inst(app_inst->lib[i], pfg, mt);
262 printk(KERN_INFO "Cannot mod lib inst, ret = %d\n",
272 * @brief Registers probes.
274 * @param us_inst Pointer to the target us_inst_data struct.
275 * @param mt Modificator, indicates whether we install or remove probes.
276 * @return 0 on suceess, error code on error.
278 int mod_us_inst(struct us_inst_data *us_inst, enum MOD_TYPE mt)
283 for (i = 0; i < us_inst->cnt; ++i) {
284 ret = mod_us_app_inst(us_inst->app_inst[i], mt);
286 printk(KERN_INFO "Cannot mod us app inst, ret = %d\n",