3 * modules/us_manager/pf/pf_group.c
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) Samsung Electronics, 2013
21 * 2013 Vyacheslav Cherkashin: SWAP us_manager implement
26 #include <linux/module.h>
27 #include <linux/slab.h>
28 #include <linux/list.h>
29 #include <linux/namei.h>
30 #include <linux/mman.h>
31 #include <linux/spinlock.h>
33 #include "proc_filters.h"
34 #include "../sspt/sspt_filter.h"
35 #include "../us_manager_common.h"
36 #include <us_manager/img/img_proc.h>
37 #include <us_manager/img/img_file.h>
38 #include <us_manager/img/img_ip.h>
39 #include <us_manager/sspt/sspt_proc.h>
40 #include <us_manager/helper.h>
43 struct list_head list;
44 struct img_proc *i_proc;
45 struct proc_filter filter;
46 struct pfg_msg_cb *msg_cb;
49 spinlock_t pl_lock; /* for proc_list */
50 struct list_head proc_list;
54 struct list_head list;
55 struct sspt_proc *proc;
58 static LIST_HEAD(pfg_list);
59 static DEFINE_RWLOCK(pfg_list_lock);
61 /* struct pl_struct */
62 static struct pl_struct *create_pl_struct(struct sspt_proc *proc)
64 struct pl_struct *pls = kmalloc(sizeof(*pls), GFP_ATOMIC);
67 INIT_LIST_HEAD(&pls->list);
68 pls->proc = sspt_proc_get(proc);
74 static void free_pl_struct(struct pl_struct *pls)
76 sspt_proc_put(pls->proc);
79 /* struct pl_struct */
81 static struct pf_group *pfg_create(void)
83 struct pf_group *pfg = kmalloc(sizeof(*pfg), GFP_ATOMIC);
88 pfg->i_proc = create_img_proc();
89 if (pfg->i_proc == NULL)
92 INIT_LIST_HEAD(&pfg->list);
93 memset(&pfg->filter, 0, sizeof(pfg->filter));
94 spin_lock_init(&pfg->pl_lock);
95 INIT_LIST_HEAD(&pfg->proc_list);
97 atomic_set(&pfg->usage, 1);
108 static void pfg_free(struct pf_group *pfg)
110 struct pl_struct *pl, *n;
112 free_img_proc(pfg->i_proc);
113 free_pf(&pfg->filter);
114 list_for_each_entry_safe(pl, n, &pfg->proc_list, list) {
115 sspt_proc_del_filter(pl->proc, pfg);
122 static int pfg_add_proc(struct pf_group *pfg, struct sspt_proc *proc)
124 struct pl_struct *pls;
126 pls = create_pl_struct(proc);
130 spin_lock(&pfg->pl_lock);
131 list_add(&pls->list, &pfg->proc_list);
132 spin_unlock(&pfg->pl_lock);
138 /* called with pfg_list_lock held */
139 static void pfg_add_to_list(struct pf_group *pfg)
141 list_add(&pfg->list, &pfg_list);
144 /* called with pfg_list_lock held */
145 static void pfg_del_from_list(struct pf_group *pfg)
147 list_del(&pfg->list);
151 static void msg_info(struct sspt_filter *f, void *data)
153 if (f->pfg_is_inst == false) {
154 struct pfg_msg_cb *cb;
156 f->pfg_is_inst = true;
158 cb = pfg_msg_cb_get(f->pfg);
160 struct dentry *dentry;
162 dentry = (struct dentry *)f->pfg->filter.priv;
165 cb->msg_info(f->proc->task, dentry);
167 if (cb->msg_status_info)
168 cb->msg_status_info(f->proc->task);
173 static void first_install(struct task_struct *task, struct sspt_proc *proc)
175 sspt_proc_priv_create(proc);
177 down_write(&task->mm->mmap_sem);
178 sspt_proc_on_each_filter(proc, msg_info, NULL);
179 sspt_proc_install(proc);
180 up_write(&task->mm->mmap_sem);
183 static void subsequent_install(struct task_struct *task,
184 struct sspt_proc *proc, unsigned long page_addr)
186 down_write(&task->mm->mmap_sem);
187 sspt_proc_install_page(proc, page_addr);
188 up_write(&task->mm->mmap_sem);
192 * @brief Get dentry struct by path
194 * @param path Path to file
195 * @return Pointer on dentry struct on NULL
197 struct dentry *dentry_by_path(const char *path)
199 struct dentry *dentry;
201 if (kern_path(path, LOOKUP_FOLLOW, &st_path) != 0) {
202 printk("failed to lookup dentry for path %s!\n", path);
206 dentry = st_path.dentry;
210 EXPORT_SYMBOL_GPL(dentry_by_path);
213 int pfg_msg_cb_set(struct pf_group *pfg, struct pfg_msg_cb *msg_cb)
218 pfg->msg_cb = msg_cb;
222 EXPORT_SYMBOL_GPL(pfg_msg_cb_set);
224 void pfg_msg_cb_reset(struct pf_group *pfg)
228 EXPORT_SYMBOL_GPL(pfg_msg_cb_reset);
230 struct pfg_msg_cb *pfg_msg_cb_get(struct pf_group *pfg)
236 * @brief Get pf_group struct by dentry
238 * @param dentry Dentry of file
239 * @param priv Private data
240 * @return Pointer on pf_group struct
242 struct pf_group *get_pf_group_by_dentry(struct dentry *dentry, void *priv)
244 struct pf_group *pfg;
246 write_lock(&pfg_list_lock);
247 list_for_each_entry(pfg, &pfg_list, list) {
248 if (check_pf_by_dentry(&pfg->filter, dentry)) {
249 atomic_inc(&pfg->usage);
258 set_pf_by_dentry(&pfg->filter, dentry, priv);
260 pfg_add_to_list(pfg);
263 write_unlock(&pfg_list_lock);
266 EXPORT_SYMBOL_GPL(get_pf_group_by_dentry);
269 * @brief Get pf_group struct by TGID
271 * @param tgid Thread group ID
272 * @param priv Private data
273 * @return Pointer on pf_group struct
275 struct pf_group *get_pf_group_by_tgid(pid_t tgid, void *priv)
277 struct pf_group *pfg;
279 write_lock(&pfg_list_lock);
280 list_for_each_entry(pfg, &pfg_list, list) {
281 if (check_pf_by_tgid(&pfg->filter, tgid)) {
282 atomic_inc(&pfg->usage);
291 set_pf_by_tgid(&pfg->filter, tgid, priv);
293 pfg_add_to_list(pfg);
296 write_unlock(&pfg_list_lock);
299 EXPORT_SYMBOL_GPL(get_pf_group_by_tgid);
302 * @brief Get pf_group struct by comm
304 * @param comm Task comm
305 * @param priv Private data
306 * @return Pointer on pf_group struct
308 struct pf_group *get_pf_group_by_comm(char *comm, void *priv)
311 struct pf_group *pfg;
313 write_lock(&pfg_list_lock);
314 list_for_each_entry(pfg, &pfg_list, list) {
315 if (check_pf_by_comm(&pfg->filter, comm)) {
316 atomic_inc(&pfg->usage);
325 ret = set_pf_by_comm(&pfg->filter, comm, priv);
327 printk(KERN_ERR "ERROR: set_pf_by_comm, ret=%d\n", ret);
333 pfg_add_to_list(pfg);
335 write_unlock(&pfg_list_lock);
338 EXPORT_SYMBOL_GPL(get_pf_group_by_comm);
341 * @brief Get pf_group struct for each process
343 * @param priv Private data
344 * @return Pointer on pf_group struct
346 struct pf_group *get_pf_group_dumb(void *priv)
348 struct pf_group *pfg;
350 write_lock(&pfg_list_lock);
351 list_for_each_entry(pfg, &pfg_list, list) {
352 if (check_pf_dumb(&pfg->filter)) {
353 atomic_inc(&pfg->usage);
362 set_pf_dumb(&pfg->filter, priv);
364 pfg_add_to_list(pfg);
367 write_unlock(&pfg_list_lock);
370 EXPORT_SYMBOL_GPL(get_pf_group_dumb);
373 * @brief Put pf_group struct
375 * @param pfg Pointer to the pf_group struct
378 void put_pf_group(struct pf_group *pfg)
380 if (atomic_dec_and_test(&pfg->usage)) {
381 write_lock(&pfg_list_lock);
382 pfg_del_from_list(pfg);
383 write_unlock(&pfg_list_lock);
388 EXPORT_SYMBOL_GPL(put_pf_group);
391 * @brief Register prober for pf_grpup struct
393 * @param pfg Pointer to the pf_group struct
394 * @param dentry Dentry of file
395 * @param offset Function offset
396 * @param probe_info Pointer to the related probe_info struct
399 int pf_register_probe(struct pf_group *pfg, struct dentry *dentry,
400 unsigned long offset, struct probe_info *probe_i)
402 return img_proc_add_ip(pfg->i_proc, dentry, offset, probe_i);
404 EXPORT_SYMBOL_GPL(pf_register_probe);
407 * @brief Unregister prober from pf_grpup struct
409 * @param pfg Pointer to the pf_group struct
410 * @param dentry Dentry of file
411 * @param offset Function offset
414 int pf_unregister_probe(struct pf_group *pfg, struct dentry *dentry,
415 unsigned long offset)
417 return img_proc_del_ip(pfg->i_proc, dentry, offset);
419 EXPORT_SYMBOL_GPL(pf_unregister_probe);
422 * @brief Check the task, to meet the filter criteria
424 * @prarm task Pointer on the task_struct struct
429 int check_task_on_filters(struct task_struct *task)
432 struct pf_group *pfg;
434 read_lock(&pfg_list_lock);
435 list_for_each_entry(pfg, &pfg_list, list) {
436 if (check_task_f(&pfg->filter, task)) {
443 read_unlock(&pfg_list_lock);
454 static enum pf_inst_flag pfg_check_task(struct task_struct *task)
456 struct pf_group *pfg;
457 struct sspt_proc *proc = NULL;
458 enum pf_inst_flag flag = PIF_NONE;
460 read_lock(&pfg_list_lock);
461 list_for_each_entry(pfg, &pfg_list, list) {
462 if (check_task_f(&pfg->filter, task) == NULL)
466 proc = sspt_proc_get_by_task(task);
469 flag = flag == PIF_NONE ? PIF_SECOND : flag;
470 } else if (task->tgid == task->pid) {
471 proc = sspt_proc_get_by_task_or_new(task);
473 printk(KERN_ERR "cannot create sspt_proc\n");
480 write_lock(&proc->filter_lock);
481 if (sspt_proc_is_filter_new(proc, pfg)) {
482 img_proc_copy_to_sspt(pfg->i_proc, proc);
483 sspt_proc_add_filter(proc, pfg);
484 pfg_add_proc(pfg, proc);
485 flag = flag == PIF_FIRST ? flag : PIF_ADD_PFG;
487 write_unlock(&proc->filter_lock);
490 read_unlock(&pfg_list_lock);
496 * @brief Check task and install probes on demand
498 * @prarm task Pointer on the task_struct struct
501 void check_task_and_install(struct task_struct *task)
503 struct sspt_proc *proc;
504 enum pf_inst_flag flag;
506 flag = pfg_check_task(task);
510 proc = sspt_proc_get_by_task(task);
512 first_install(task, proc);
522 * @brief Check task and install probes on demand
524 * @prarm task Pointer on the task_struct struct
525 * @param page_addr Page fault address
528 void call_page_fault(struct task_struct *task, unsigned long page_addr)
530 struct sspt_proc *proc;
531 enum pf_inst_flag flag;
533 flag = pfg_check_task(task);
537 proc = sspt_proc_get_by_task(task);
539 first_install(task, proc);
543 proc = sspt_proc_get_by_task(task);
545 subsequent_install(task, proc, page_addr);
554 * @brief Uninstall probes from the sspt_proc struct
556 * @prarm proc Pointer on the sspt_proc struct
560 /* called with sspt_proc_write_lock() */
561 void uninstall_proc(struct sspt_proc *proc)
563 struct task_struct *task = proc->task;
565 sspt_proc_uninstall(proc, task, US_UNREGS_PROBE);
566 sspt_proc_cleanup(proc);
570 * @brief Remove probes from the task on demand
572 * @prarm task Pointer on the task_struct struct
575 void call_mm_release(struct task_struct *task)
577 struct sspt_proc *proc;
579 sspt_proc_write_lock();
580 proc = sspt_proc_get_by_task_no_lock(task);
582 list_del(&proc->list);
583 sspt_proc_write_unlock();
586 uninstall_proc(proc);
590 * @brief Legacy code, it is need remove
592 * @param addr Page address
595 void uninstall_page(unsigned long addr)
601 * @brief Install probes on running processes
605 void install_all(void)
607 /* TODO: to be implemented */
611 * @brief Uninstall probes from all processes
615 void uninstall_all(void)
617 struct list_head *proc_list = sspt_proc_list();
619 sspt_proc_write_lock();
620 while (!list_empty(proc_list)) {
621 struct sspt_proc *proc;
622 proc = list_first_entry(proc_list, struct sspt_proc, list);
624 list_del(&proc->list);
626 sspt_proc_write_unlock();
627 uninstall_proc(proc);
628 sspt_proc_write_lock();
630 sspt_proc_write_unlock();
633 static void __do_get_proc(struct sspt_proc *proc, void *data)
635 get_task_struct(proc->task);
636 proc->__task = proc->task;
637 proc->__mm = get_task_mm(proc->task);
640 static void __do_put_proc(struct sspt_proc *proc, void *data)
648 put_task_struct(proc->__task);
653 void get_all_procs(void)
655 sspt_proc_read_lock();
656 on_each_proc_no_lock(__do_get_proc, NULL);
657 sspt_proc_read_unlock();
660 void put_all_procs(void)
662 sspt_proc_read_lock();
663 on_each_proc_no_lock(__do_put_proc, NULL);
664 sspt_proc_read_unlock();
670 * @param pfg Pointer to the pf_group struct
675 void pfg_print(struct pf_group *pfg)
677 img_proc_print(pfg->i_proc);
679 EXPORT_SYMBOL_GPL(pfg_print);