From b9aa74baf40f199da92122fa00663956b0c31830 Mon Sep 17 00:00:00 2001 From: Anatolii Nikulin Date: Fri, 15 Jul 2016 15:48:59 +0300 Subject: [PATCH] rework UIHV init/deinit Depends on manager: fix UIHV start/stop Add enable/disable command for UIHV Change-Id: I8a1474ce3aa86f8c158a7ae7595e8946aa996cb7 Signed-off-by: Anatolii Nikulin --- uihv/uihv_debugfs.c | 48 ++++++++++++++++++++++++++++++++++-- uihv/uihv_module.c | 71 ++++++++++++++++++++++++++++++++++++++++++++--------- uihv/uihv_module.h | 2 ++ 3 files changed, 107 insertions(+), 14 deletions(-) diff --git a/uihv/uihv_debugfs.c b/uihv/uihv_debugfs.c index 0bddf4b..5341503 100644 --- a/uihv/uihv_debugfs.c +++ b/uihv/uihv_debugfs.c @@ -10,6 +10,7 @@ static const char UIHV_FOLDER[] = "uihv"; static const char UIHV_PATH[] = "path"; static const char UIHV_APP_INFO[] = "app_info"; +static const char UIHV_ENABLE[] = "enable"; static struct dentry *uihv_root; @@ -132,13 +133,49 @@ free_buf: static const struct file_operations uihv_app_info_file_ops = { .owner = THIS_MODULE, - .write = write_uihv_app_info, + .write = write_uihv_app_info, }; +static ssize_t write_uihv_enable(struct file *file, + const char __user *user_buf, + size_t len, loff_t *ppos) +{ + ssize_t ret = len; + char *buf; + + buf = kmalloc(len, GFP_KERNEL); + if (!buf) { + ret = -ENOMEM; + goto out; + } + + if (copy_from_user(buf, user_buf, len)) { + ret = -EINVAL; + goto free_buf; + } + + buf[len - 1] = '\0'; + + if (buf[0] == '0') + ret = uihv_disable(); + else + ret = uihv_enable(); + +free_buf: + kfree(buf); + +out: + return ret; +} + +static const struct file_operations uihv_enable_file_ops = { + .owner = THIS_MODULE, + .write = write_uihv_enable, +}; int uihv_dfs_init(void) { - struct dentry *swap_dentry, *root, *path, *app_info; + struct dentry *swap_dentry, *root, *path, *app_info, *uihv_enable; int ret; ret = -ENODEV; @@ -171,6 +208,13 @@ int uihv_dfs_init(void) goto remove; } + uihv_enable = debugfs_create_file(UIHV_ENABLE, UIHV_DEFAULT_PERMS, + root, NULL, &uihv_enable_file_ops); + if (IS_ERR_OR_NULL(uihv_enable)) { + ret = -ENOMEM; + goto remove; + } + return 0; remove: diff --git a/uihv/uihv_module.c b/uihv/uihv_module.c index b0d71dd..dc6b501 100644 --- a/uihv/uihv_module.c +++ b/uihv/uihv_module.c @@ -19,6 +19,8 @@ #define ip_to_proc(ip) page_to_proc((ip)->page) #define urp_to_ip(rp) container_of(rp, struct sspt_ip, retprobe) +static DEFINE_MUTEX(mutex_enable); + static struct dentry *uihv_dentry = NULL; static inline struct pd_t *__get_process_data(struct uretprobe *rp) @@ -45,34 +47,25 @@ struct ui_viewer_data { struct dentry *app_dentry; struct probe_new p_main; struct pf_group *pfg; + bool enable; }; static struct ui_viewer_data __ui_data; static int uihv_data_inst(void) { - int ret; struct pf_group *pfg; pfg = get_pf_group_by_dentry(__ui_data.app_dentry, (void *)__ui_data.app_dentry); - if (pfg == NULL) + if (!pfg) return -ENOMEM; - ret = pin_register(&__ui_data.p_main, pfg, __ui_data.app_dentry); - if (ret) - goto put_g; - __ui_data.pfg = pfg; return 0; -put_g: - put_pf_group(pfg); - return ret; } - - struct dentry *get_dentry(const char *filepath) { struct path path; @@ -95,6 +88,11 @@ int uihv_data_set(const char *app_path, unsigned long main_addr) { struct dentry *dentry; + if (__ui_data.enable) { + pr_err("UIHV already enabled, can't set data\n"); + return -EBUSY; + } + dentry = dentry_by_path(app_path); if (dentry == NULL) return -ENOENT; @@ -102,7 +100,6 @@ int uihv_data_set(const char *app_path, unsigned long main_addr) __ui_data.app_dentry = dentry; __ui_data.p_main.desc = &pin_main; __ui_data.p_main.offset = main_addr; - __ui_data.pfg = NULL; return uihv_data_inst(); } @@ -178,6 +175,54 @@ static int uihv_main_rh(struct uretprobe_instance *ri, struct pt_regs *regs) return 0; } +int uihv_enable(void) +{ + int ret = 0; + + mutex_lock(&mutex_enable); + if (__ui_data.enable) { + pr_err("UIHV already enabled\n"); + ret = -EBUSY; + goto out; + } + + ret = pin_register(&__ui_data.p_main, __ui_data.pfg, + __ui_data.app_dentry); + if (ret) + goto out; + + __ui_data.enable = true; + +out: + mutex_unlock(&mutex_enable); + return ret; +} + +int uihv_disable(void) +{ + int ret = 0; + + mutex_lock(&mutex_enable); + if (!__ui_data.enable) { + pr_err("UIHV already disabled\n"); + ret = -EBUSY; + goto out; + } + + ret = pin_unregister(&__ui_data.p_main, __ui_data.pfg, + __ui_data.app_dentry); + if (ret) + goto out; + + put_pf_group(__ui_data.pfg); + __ui_data.pfg = NULL; + __ui_data.enable = false; + +out: + mutex_unlock(&mutex_enable); + return ret; +} + static int uihv_init(void) { int ret; @@ -191,6 +236,8 @@ static void uihv_exit(void) { if (uihv_dentry != NULL) put_dentry(uihv_dentry); + + uihv_dfs_exit(); } SWAP_LIGHT_INIT_MODULE(NULL, uihv_init, uihv_exit, NULL, NULL); diff --git a/uihv/uihv_module.h b/uihv/uihv_module.h index 9f13552..e6413a7 100644 --- a/uihv/uihv_module.h +++ b/uihv/uihv_module.h @@ -3,5 +3,7 @@ int uihv_data_set(const char *app_path, unsigned long main_addr); int uihv_set_handler(char *path); +int uihv_enable(void); +int uihv_disable(void); #endif /* __UIHV_MODULE_H__ */ -- 2.7.4