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>
15 #include "uihv_module.h"
16 #include "uihv_debugfs.h"
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)
22 static DEFINE_MUTEX(mutex_enable);
24 static struct dentry *uihv_dentry = NULL;
26 static inline struct pd_t *__get_process_data(struct uretprobe *rp)
28 struct sspt_ip *ip = urp_to_ip(rp);
29 struct sspt_proc *proc = ip_to_proc(ip);
35 /* ============================================================================
37 * ============================================================================
40 /* main handler for ui viewer */
41 static int uihv_main_eh(struct uretprobe_instance *ri, struct pt_regs *regs);
42 static int uihv_main_rh(struct uretprobe_instance *ri, struct pt_regs *regs);
43 static struct probe_desc pin_main = MAKE_URPROBE(uihv_main_eh,
46 struct ui_viewer_data {
47 struct dentry *app_dentry;
48 struct probe_new p_main;
53 static struct ui_viewer_data __ui_data;
55 static int uihv_data_inst(void)
59 pfg = get_pf_group_by_dentry(__ui_data.app_dentry,
60 (void *)__ui_data.app_dentry);
69 struct dentry *get_dentry(const char *filepath)
72 struct dentry *dentry = NULL;
74 if (kern_path(filepath, LOOKUP_FOLLOW, &path) == 0) {
75 dentry = dget(path.dentry);
82 void put_dentry(struct dentry *dentry)
87 int uihv_data_set(const char *app_path, unsigned long main_addr)
89 struct dentry *dentry;
91 if (__ui_data.enable) {
92 pr_err("UIHV already enabled, can't set data\n");
96 dentry = dentry_by_path(app_path);
100 __ui_data.app_dentry = dentry;
101 __ui_data.p_main.desc = &pin_main;
102 __ui_data.p_main.offset = main_addr;
104 return uihv_data_inst();
107 int uihv_set_handler(char *path)
109 struct dentry *dentry;
112 if (uihv_dentry != NULL)
113 put_dentry(uihv_dentry);
115 dentry = get_dentry(path);
116 if (dentry == NULL) {
117 printk(KERN_WARNING UIHV_PREFIX "Error! Cannot get handler %s\n",
122 ret = loader_add_handler(path);
126 uihv_dentry = dentry;
133 /* ============================================================================
134 * = ui viewer handlers =
135 * ============================================================================
137 static int uihv_main_eh(struct uretprobe_instance *ri, struct pt_regs *regs)
139 struct pd_t *pd = __get_process_data(ri->rp);
141 unsigned long old_pc = swap_get_instr_ptr(regs);
142 unsigned long vaddr = 0;
144 if (uihv_dentry == NULL)
147 hd = lpd_get_hd(pd, uihv_dentry);
151 if (lpd_get_state(hd) == NOT_LOADED)
152 vaddr = loader_not_loaded_entry(ri, regs, pd, hd);
154 loader_set_priv_origin(ri, vaddr);
156 /* PC change check */
157 return old_pc != swap_get_instr_ptr(regs);
160 static int uihv_main_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
162 struct pd_t *pd = __get_process_data(ri->rp);
165 if (uihv_dentry == NULL)
168 hd = lpd_get_hd(pd, uihv_dentry);
172 if (lpd_get_state(hd) == LOADING)
173 loader_loading_ret(ri, regs, pd, hd);
178 int uihv_enable(void)
182 mutex_lock(&mutex_enable);
183 if (__ui_data.enable) {
184 pr_err("UIHV already enabled\n");
189 ret = pin_register(&__ui_data.p_main, __ui_data.pfg,
190 __ui_data.app_dentry);
194 __ui_data.enable = true;
197 mutex_unlock(&mutex_enable);
201 int uihv_disable(void)
205 mutex_lock(&mutex_enable);
206 if (!__ui_data.enable) {
207 pr_err("UIHV already disabled\n");
212 ret = pin_unregister(&__ui_data.p_main, __ui_data.pfg,
213 __ui_data.app_dentry);
217 put_pf_group(__ui_data.pfg);
218 __ui_data.pfg = NULL;
219 __ui_data.enable = false;
222 mutex_unlock(&mutex_enable);
226 static int uihv_init(void)
230 ret = uihv_dfs_init();
235 static void uihv_exit(void)
237 if (uihv_dentry != NULL)
238 put_dentry(uihv_dentry);
243 SWAP_LIGHT_INIT_MODULE(NULL, uihv_init, uihv_exit, NULL, NULL);
244 MODULE_LICENSE("GPL");
245 MODULE_DESCRIPTION("SWAP UI Hierarchy Viewer");
246 MODULE_AUTHOR("Alexander Aksenov <a.aksenov@samsung.com>, Anastasia Lypa");