b0d71ddf2d60f92774cf0f4b6b36f5eeb10ae682
[kernel/swap-modules.git] / uihv / uihv_module.c
1 #include <linux/namei.h>
2 #include <us_manager/us_manager_common.h>
3 #include <us_manager/pf/pf_group.h>
4 #include <us_manager/sspt/sspt_page.h>
5 #include <us_manager/sspt/sspt_file.h>
6 #include <us_manager/sspt/sspt_proc.h>
7 #include <us_manager/sspt/sspt_ip.h>
8 #include <us_manager/callbacks.h>
9 #include <us_manager/probes/probe_info_new.h>
10 #include <writer/kernel_operations.h>
11 #include <master/swap_initializer.h>
12 #include <writer/swap_msg.h>
13 #include <loader/loader.h>
14 #include "uihv.h"
15 #include "uihv_module.h"
16 #include "uihv_debugfs.h"
17
18 #define page_to_proc(page) ((page)->file->proc)
19 #define ip_to_proc(ip) page_to_proc((ip)->page)
20 #define urp_to_ip(rp) container_of(rp, struct sspt_ip, retprobe)
21
22 static struct dentry *uihv_dentry = NULL;
23
24 static inline struct pd_t *__get_process_data(struct uretprobe *rp)
25 {
26         struct sspt_ip *ip = urp_to_ip(rp);
27         struct sspt_proc *proc = ip_to_proc(ip);
28
29         return lpd_get(proc);
30 }
31
32
33 /* ============================================================================
34  * =                               ui_viewer                                  =
35  * ============================================================================
36  */
37
38 /* main handler for ui viewer */
39 static int uihv_main_eh(struct uretprobe_instance *ri, struct pt_regs *regs);
40 static int uihv_main_rh(struct uretprobe_instance *ri, struct pt_regs *regs);
41 static struct probe_desc pin_main = MAKE_URPROBE(uihv_main_eh,
42                                                      uihv_main_rh, 0);
43
44 struct ui_viewer_data {
45         struct dentry *app_dentry;
46         struct probe_new p_main;
47         struct pf_group *pfg;
48 };
49
50 static struct ui_viewer_data __ui_data;
51
52 static int uihv_data_inst(void)
53 {
54         int ret;
55         struct pf_group *pfg;
56
57         pfg = get_pf_group_by_dentry(__ui_data.app_dentry,
58                                      (void *)__ui_data.app_dentry);
59         if (pfg == NULL)
60                 return -ENOMEM;
61
62         ret = pin_register(&__ui_data.p_main, pfg, __ui_data.app_dentry);
63         if (ret)
64                 goto put_g;
65
66         __ui_data.pfg = pfg;
67
68         return 0;
69 put_g:
70         put_pf_group(pfg);
71         return ret;
72 }
73
74
75
76 struct dentry *get_dentry(const char *filepath)
77 {
78         struct path path;
79         struct dentry *dentry = NULL;
80
81         if (kern_path(filepath, LOOKUP_FOLLOW, &path) == 0) {
82                 dentry = dget(path.dentry);
83                 path_put(&path);
84         }
85
86         return dentry;
87 }
88
89 void put_dentry(struct dentry *dentry)
90 {
91         dput(dentry);
92 }
93
94 int uihv_data_set(const char *app_path, unsigned long main_addr)
95 {
96         struct dentry *dentry;
97
98         dentry = dentry_by_path(app_path);
99         if (dentry == NULL)
100                 return -ENOENT;
101
102         __ui_data.app_dentry = dentry;
103         __ui_data.p_main.desc = &pin_main;
104         __ui_data.p_main.offset = main_addr;
105         __ui_data.pfg = NULL;
106
107         return uihv_data_inst();
108 }
109
110 int uihv_set_handler(char *path)
111 {
112         struct dentry *dentry;
113         int ret;
114
115         if (uihv_dentry != NULL)
116                 put_dentry(uihv_dentry);
117
118         dentry = get_dentry(path);
119         if (dentry == NULL) {
120                 printk(KERN_WARNING UIHV_PREFIX "Error! Cannot get handler %s\n",
121                            path);
122                 return -EINVAL;
123         }
124
125         ret = loader_add_handler(path);
126         if (ret != 0)
127                 return ret;
128
129         uihv_dentry = dentry;
130
131         return 0;
132 }
133
134
135
136 /* ============================================================================
137  * =                          ui viewer handlers                              =
138  * ============================================================================
139  */
140 static int uihv_main_eh(struct uretprobe_instance *ri, struct pt_regs *regs)
141 {
142         struct pd_t *pd = __get_process_data(ri->rp);
143         struct hd_t *hd;
144         unsigned long old_pc = swap_get_instr_ptr(regs);
145         unsigned long vaddr = 0;
146
147         if (uihv_dentry == NULL)
148                 return 0;
149
150         hd = lpd_get_hd(pd, uihv_dentry);
151         if (hd == NULL)
152                 return 0;
153
154         if (lpd_get_state(hd) == NOT_LOADED)
155                 vaddr = loader_not_loaded_entry(ri, regs, pd, hd);
156
157         loader_set_priv_origin(ri, vaddr);
158
159         /* PC change check */
160         return old_pc != swap_get_instr_ptr(regs);
161 }
162
163 static int uihv_main_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
164 {
165         struct pd_t *pd = __get_process_data(ri->rp);
166         struct hd_t *hd;
167
168         if (uihv_dentry == NULL)
169                 return 0;
170
171         hd = lpd_get_hd(pd, uihv_dentry);
172         if (hd == NULL)
173                 return 0;
174
175         if (lpd_get_state(hd) == LOADING)
176                 loader_loading_ret(ri, regs, pd, hd);
177
178         return 0;
179 }
180
181 static int uihv_init(void)
182 {
183         int ret;
184
185         ret = uihv_dfs_init();
186
187         return ret;
188 }
189
190 static void uihv_exit(void)
191 {
192         if (uihv_dentry != NULL)
193                 put_dentry(uihv_dentry);
194 }
195
196 SWAP_LIGHT_INIT_MODULE(NULL, uihv_init, uihv_exit, NULL, NULL);
197 MODULE_LICENSE("GPL");
198 MODULE_DESCRIPTION("SWAP UI Hierarchy Viewer");
199 MODULE_AUTHOR("Alexander Aksenov <a.aksenov@samsung.com>, Anastasia Lypa");