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 "proc_filters.h"
30 #include <us_manager/img/img_proc.h>
31 #include <us_manager/img/img_file.h>
32 #include <us_manager/img/img_ip.h>
33 #include <us_manager/sspt/sspt_proc.h>
34 #include <us_manager/helper.h>
35 #include <writer/swap_writer_module.h>
38 struct list_head list;
39 struct img_proc *i_proc;
40 struct proc_filter *filter;
43 struct list_head proc_list;
47 struct list_head list;
48 struct sspt_proc *proc;
51 static LIST_HEAD(pfg_list);
53 /* struct pl_struct */
54 static struct pl_struct *create_pl_struct(struct sspt_proc *proc)
56 struct pl_struct *pls = kmalloc(sizeof(*pls), GFP_KERNEL);
58 INIT_LIST_HEAD(&pls->list);
64 static void free_pl_struct(struct pl_struct *pls)
69 static void add_pl_struct(struct pf_group *pfg, struct pl_struct *pls)
71 list_add(&pls->list, &pfg->proc_list);
74 static void del_pl_struct(struct pl_struct *pls)
79 void copy_proc_form_img_to_sspt(struct img_proc *i_proc, struct sspt_proc *proc)
81 struct sspt_file *file;
82 struct img_file *i_file;
85 list_for_each_entry(i_file, &i_proc->file_list, list) {
86 file = sspt_proc_find_file_or_new(proc, i_file->dentry);
88 list_for_each_entry(i_ip, &i_file->ip_list, list)
89 sspt_file_add_ip(file, i_ip->addr, i_ip->args,
94 static struct pl_struct *find_pl_struct(struct pf_group *pfg,
95 struct task_struct *task)
97 struct pl_struct *pls;
99 list_for_each_entry(pls, &pfg->proc_list, list) {
100 if (pls->proc->tgid == task->tgid)
107 static struct sspt_proc *get_proc_by_pfg(struct pf_group *pfg,
108 struct task_struct *task)
110 struct pl_struct *pls;
112 pls = find_pl_struct(pfg, task);
119 static struct sspt_proc *new_proc_by_pfg(struct pf_group *pfg,
120 struct task_struct *task)
122 struct pl_struct *pls;
123 struct sspt_proc *proc;
125 proc = sspt_proc_get_by_task_or_new(task, pfg->filter->priv);
126 copy_proc_form_img_to_sspt(pfg->i_proc, proc);
128 pls = create_pl_struct(proc);
129 add_pl_struct(pfg, pls);
133 /* struct pl_struct */
135 static struct pf_group *create_pfg(struct proc_filter *filter)
137 struct pf_group *pfg = kmalloc(sizeof(*pfg), GFP_KERNEL);
139 INIT_LIST_HEAD(&pfg->list);
140 pfg->filter = filter;
141 pfg->i_proc = create_img_proc();
142 INIT_LIST_HEAD(&pfg->proc_list);
147 static void free_pfg(struct pf_group *pfg)
153 static void add_pfg_by_list(struct pf_group *pfg)
155 list_add(&pfg->list, &pfg_list);
158 static void del_pfg_by_list(struct pf_group *pfg)
160 list_del(&pfg->list);
163 struct pf_group *get_pf_group_by_dentry(struct dentry *dentry, void *priv)
165 struct pf_group *pfg;
166 struct proc_filter *filter;
168 list_for_each_entry(pfg, &pfg_list, list) {
169 if (check_pf_by_dentry(pfg->filter, dentry))
173 filter = create_pf_by_dentry(dentry, priv);
174 pfg = create_pfg(filter);
176 add_pfg_by_list(pfg);
180 EXPORT_SYMBOL_GPL(get_pf_group_by_dentry);
182 struct pf_group *get_pf_group_by_tgid(pid_t tgid, void *priv)
184 struct pf_group *pfg;
185 struct proc_filter *filter;
187 list_for_each_entry(pfg, &pfg_list, list) {
188 if (check_pf_by_tgid(pfg->filter, tgid))
192 filter = create_pf_by_tgid(tgid, priv);
193 pfg = create_pfg(filter);
195 add_pfg_by_list(pfg);
199 EXPORT_SYMBOL_GPL(get_pf_group_by_tgid);
201 struct pf_group *get_pf_group_dumb(void *priv)
203 struct pf_group *pfg;
204 struct proc_filter *filter;
206 list_for_each_entry(pfg, &pfg_list, list) {
207 if (check_pf_dumb(pfg->filter))
211 filter = create_pf_dumb(pfg->filter);
212 pfg = create_pfg(filter);
214 add_pfg_by_list(pfg);
218 EXPORT_SYMBOL_GPL(get_pf_group_dumb);
220 void put_pf_group(struct pf_group *pfg)
225 int pf_register_probe(struct pf_group *pfg, struct dentry *dentry,
226 unsigned long offset, const char *args, char ret_type)
228 return img_proc_add_ip(pfg->i_proc, dentry, offset, args, ret_type);
230 EXPORT_SYMBOL_GPL(pf_register_probe);
232 int pf_unregister_probe(struct pf_group *pfg, struct dentry *dentry,
233 unsigned long offset)
235 return img_proc_del_ip(pfg->i_proc, dentry, offset);
237 EXPORT_SYMBOL_GPL(pf_unregister_probe);
239 void call_page_fault(struct task_struct *task, unsigned long page_addr)
241 struct pf_group *pfg, *pfg_first = NULL;
242 struct sspt_proc *proc = NULL;
244 list_for_each_entry(pfg, &pfg_list, list) {
245 if (check_task_f(pfg->filter, task) == NULL)
248 proc = get_proc_by_pfg(pfg, task);
249 if (proc == NULL && task->tgid == task->pid) {
250 proc = new_proc_by_pfg(pfg, task);
257 struct dentry *dentry;
259 dentry = get_dentry_by_pf(pfg_first->filter);
260 if (dentry == NULL) {
261 dentry = task->mm->exe_file ?
262 task->mm->exe_file->f_dentry :
266 proc_info_msg(task, dentry);
267 sspt_proc_install(proc);
269 sspt_proc_install_page(proc, page_addr);
274 void uninstall_proc(struct sspt_proc *proc)
276 struct task_struct *task = proc->task;
277 struct pf_group *pfg;
278 struct pl_struct *pls;
280 list_for_each_entry(pfg, &pfg_list, list) {
281 pls = find_pl_struct(pfg, task);
289 BUG_ON(task->mm == NULL);
290 sspt_proc_uninstall(proc, task, US_UNREGS_PROBE);
293 sspt_proc_free(proc);
296 void call_mm_release(struct task_struct *task)
298 struct sspt_proc *proc;
300 proc = sspt_proc_get_by_task(task);
302 /* TODO: uninstall_proc - is not atomic context */
303 uninstall_proc(proc);
306 void uninstall_page(unsigned long addr)
311 void install_all(void)
313 struct task_struct *task;
314 int tmp_oops_in_progress;
316 tmp_oops_in_progress = oops_in_progress;
317 oops_in_progress = 1;
319 for_each_process(task) {
320 if (task->tgid != task->pid)
323 if (is_kthread(task))
326 call_page_fault(task, 0xba00baab);
329 oops_in_progress = tmp_oops_in_progress;
332 static void clean_pfg(void)
334 struct pf_group *pfg, *n;
336 list_for_each_entry_safe(pfg, n, &pfg_list, list) {
337 del_pfg_by_list(pfg);
342 static void on_each_uninstall_proc(struct sspt_proc *proc, void *data)
344 uninstall_proc(proc);
347 void uninstall_all(void)
350 on_each_proc_no_lock(on_each_uninstall_proc, NULL);
355 void pfg_print(struct pf_group *pfg)
357 img_proc_print(pfg->i_proc);
359 EXPORT_SYMBOL_GPL(pfg_print);