rework UIHV init/deinit 81/80281/4
authorAnatolii Nikulin <nikulin.a@samsung.com>
Fri, 15 Jul 2016 12:48:59 +0000 (15:48 +0300)
committerAnatolii Nikulin <nikulin.a@samsung.com>
Wed, 20 Jul 2016 06:50:50 +0000 (23:50 -0700)
Depends on manager: fix UIHV start/stop

Add enable/disable command for UIHV

Change-Id: I8a1474ce3aa86f8c158a7ae7595e8946aa996cb7
Signed-off-by: Anatolii Nikulin <nikulin.a@samsung.com>
uihv/uihv_debugfs.c
uihv/uihv_module.c
uihv/uihv_module.h

index 0bddf4b..5341503 100644 (file)
@@ -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:
index b0d71dd..dc6b501 100644 (file)
@@ -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);
index 9f13552..e6413a7 100644 (file)
@@ -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__ */