Merge branch 'tizen_2.4_dev' into tizen 62/70162/1
authorDmitry Kovalenko <d.kovalenko@samsung.com>
Tue, 17 May 2016 14:58:39 +0000 (17:58 +0300)
committerDmitry Kovalenko <d.kovalenko@samsung.com>
Tue, 17 May 2016 14:58:39 +0000 (17:58 +0300)
Change-Id: Ia6a12395c6f82ee2131de1edf9d3e8990238f0f5

1  2 
energy/energy.c
fbiprobe/fbiprobe.c
kprobe/swap_kprobes.h
kprobe/swap_kprobes_deps.h
loader/loader_pd.c
packaging/swap-modules.spec
preload/preload_control.c
us_manager/sspt/sspt_proc.c
webprobe/webprobe.c

diff --combined energy/energy.c
@@@ -295,7 -295,7 +295,7 @@@ static struct energy_data *get_energy_d
        void *data = NULL;
        struct sspt_proc *proc;
  
-       proc = sspt_proc_get_by_task(task);
+       proc = sspt_proc_by_task(task);
        if (proc)
                data = sspt_get_feature_data(proc->feature, feature_id);
  
@@@ -332,8 -332,8 +332,8 @@@ static int check_file(int fd
        file = fget(fd);
        if (file) {
                int magic = 0;
 -              if (file->f_dentry && file->f_dentry->d_sb)
 -                      magic = file->f_dentry->d_sb->s_magic;
 +              if (file->f_path.dentry && file->f_path.dentry->d_sb)
 +                      magic = file->f_path.dentry->d_sb->s_magic;
  
                fput(file);
  
diff --combined fbiprobe/fbiprobe.c
@@@ -43,7 -43,7 +43,7 @@@
  #include <us_manager/probes/register_probes.h>
  
  #include <uprobe/swap_uprobes.h>
- #include <us_manager/sspt/ip.h>
+ #include <us_manager/sspt/sspt_ip.h>
  
  #include <kprobe/swap_kprobes_deps.h>
  #include <linux/module.h>
@@@ -204,7 -204,7 +204,7 @@@ static struct vm_area_struct *find_vma_
        /* TODO FILTER vma */
        for (vma = mm->mmap; vma; vma = vma->vm_next) {
                if (vma->vm_file &&
 -                 (vma->vm_file->f_dentry == dentry))
 +                 (vma->vm_file->f_path.dentry == dentry))
                        /* found */
                        goto exit;
        }
@@@ -216,7 -216,7 +216,7 @@@ exit
  }
  
  static int fbi_probe_get_data_from_direct_addr(const struct fbi_var_data *fbi_i,
-                                              struct us_ip *ip,
+                                              struct sspt_ip *ip,
                                               struct pt_regs *regs)
  {
        struct vm_area_struct *vma;
@@@ -257,7 -257,7 +257,7 @@@ exit
  
  static int fbi_probe_handler(struct uprobe *p, struct pt_regs *regs)
  {
-       struct us_ip *ip = container_of(p, struct us_ip, uprobe);
+       struct sspt_ip *ip = container_of(p, struct sspt_ip, uprobe);
        struct fbi_info *fbi_i = &ip->desc->info.fbi_i;
        struct fbi_var_data *fbi_d = NULL;
        uint8_t i;
@@@ -305,28 -305,28 +305,28 @@@ void fbi_probe_cleanup(struct probe_inf
        fbi_i->vars = NULL;
  }
  
- void fbi_probe_init(struct us_ip *ip)
+ void fbi_probe_init(struct sspt_ip *ip)
  {
        ip->uprobe.pre_handler = (uprobe_pre_handler_t)fbi_probe_handler;
  }
  
- void fbi_probe_uninit(struct us_ip *ip)
+ void fbi_probe_uninit(struct sspt_ip *ip)
  {
        if (ip != NULL)
                fbi_probe_cleanup(&ip->desc->info);
  }
  
- static int fbi_probe_register_probe(struct us_ip *ip)
+ static int fbi_probe_register_probe(struct sspt_ip *ip)
  {
        return swap_register_uprobe(&ip->uprobe);
  }
  
- static void fbi_probe_unregister_probe(struct us_ip *ip, int disarm)
+ static void fbi_probe_unregister_probe(struct sspt_ip *ip, int disarm)
  {
        __swap_unregister_uprobe(&ip->uprobe, disarm);
  }
  
- static struct uprobe *fbi_probe_get_uprobe(struct us_ip *ip)
+ static struct uprobe *fbi_probe_get_uprobe(struct sspt_ip *ip)
  {
        return &ip->uprobe;
  }
diff --combined kprobe/swap_kprobes.h
  #include <swap-asm/swap_kprobes.h>
  
  
 -#ifdef CONFIG_ARM
 -
 -#define regs_return_value(regs)     ((regs)->ARM_r0)
 -
 -#endif
 -
 -
  /* kprobe_status settings */
  /** Kprobe hit active */
  #define KPROBE_HIT_ACTIVE     0x00000001
@@@ -282,15 -289,14 +282,14 @@@ void swap_unregister_kretprobes_bottom(
  int trampoline_probe_handler (struct kprobe *p, struct pt_regs *regs);
  
  
- DECLARE_PER_CPU(struct kprobe *, swap_current_kprobe);
  extern atomic_t kprobe_count;
  extern unsigned long sched_addr;
  
  struct kprobe *swap_kprobe_running(void);
+ void swap_kprobe_running_set(struct kprobe *p);
  void swap_reset_current_kprobe(void);
  struct kprobe_ctlblk *swap_get_kprobe_ctlblk(void);
  
- void prepare_singlestep(struct kprobe *p, struct pt_regs *regs);
  
  #endif /* _SWAP_KPROBES_H */
  
@@@ -33,7 -33,6 +33,7 @@@
  #define _SWAP_KPROBES_DEPS_H
  
  #include <linux/version.h>    /* LINUX_VERSION_CODE, KERNEL_VERSION() */
 +#include <linux/mm.h>
  #include <linux/hugetlb.h>
  #include <linux/mempolicy.h>
  #include <linux/highmem.h>
  #endif
  
  
- /*
-  * TODO: possibly unnided
-  *       check and remove swap_preempt_enable_no_resched() call
-  */
- #if (defined(MODULE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)))
- #ifdef CONFIG_PREEMPT_COUNT
- #define swap_preempt_enable_no_resched() \
- do { \
-       barrier(); \
-       preempt_count_dec(); \
- } while (0)
- #else /* !CONFIG_PREEMPT_COUNT */
- #define swap_preempt_enable_no_resched() barrier()
- #endif /* CONFIG_PREEMPT_COUNT */
- #else /* !(defined(MODULE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) */
- #define swap_preempt_enable_no_resched() preempt_enable_no_resched()
- #endif /* !(defined(MODULE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) */
  #if LINUX_VERSION_CODE > KERNEL_VERSION(3, 1, 0)
      #define task_job(task) (task->jobctl)
  #else /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 1, 0) */
@@@ -156,14 -132,5 +133,14 @@@ unsigned long swap_do_mmap_pgoff(struc
                                 unsigned long flags, unsigned long pgoff);
  #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0) */
  
 +#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 16, 0)
 +#define swap_hlist_add_after(node, prev) hlist_add_behind(node, prev)
 +#else /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 16, 0) */
 +#define swap_hlist_add_after(node, prev) hlist_add_after(node, prev)
 +#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 16, 0) */
 +
 +#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 18, 0)
 +#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
 +#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 18, 0) */
  
  #endif /* _SWAP_KPROBES_DEPS_H */
diff --combined loader/loader_pd.c
@@@ -4,15 -4,16 +4,16 @@@
  #include <linux/fs.h>
  #include <linux/mm.h>
  #include <linux/mman.h>
+ #include <linux/module.h>
  #include <linux/hardirq.h>
  #include <linux/list.h>
  #include <us_manager/us_manager_common.h>
  #include <us_manager/sspt/sspt_proc.h>
- #include "preload_pd.h"
- #include "preload_threads.h"
- #include "preload_debugfs.h"
- #include "preload_storage.h"
- #include "preload.h"
+ #include "loader_pd.h"
+ #include "loader.h"
+ #include "loader_debugfs.h"
+ #include "loader_storage.h"
+ #include "loader_defs.h"
  
  struct pd_t {
        unsigned long loader_base;
@@@ -36,8 -37,7 +37,8 @@@ static inline bool check_vma(struct vm_
  {
        struct file *file = vma->vm_file;
  
 -      return (file && (vma->vm_flags & VM_EXEC) && (file->f_dentry == dentry));
 +      return (file && (vma->vm_flags & VM_EXEC) &&
 +              (file->f_path.dentry == dentry));
  }
  
  static inline unsigned long __get_loader_base(struct pd_t *pd)
@@@ -137,7 -137,7 +138,7 @@@ static struct pd_t *__create_pd(void
                            MAP_ANONYMOUS | MAP_PRIVATE, 0);
        up_write(&current->mm->mmap_sem);
        if (IS_ERR_VALUE(page)) {
-               printk(KERN_ERR PRELOAD_PREFIX
+               printk(KERN_ERR LOADER_PREFIX
                       "Cannot alloc page for %u\n", current->tgid);
                goto create_pd_fail;
        }
@@@ -161,7 -161,7 +162,7 @@@ static size_t __copy_path(char *src, un
  
        /* set handler path */
        if (copy_to_user((void __user *)dest, src, len) != 0) {
-               printk(KERN_ERR PRELOAD_PREFIX
+               printk(KERN_ERR LOADER_PREFIX
                       "Cannot copy string to user!\n");
                return 0;
        }
  static void __set_ld_mapped(struct pd_t *pd, struct mm_struct *mm)
  {
        struct vm_area_struct *vma;
-       struct dentry *ld = preload_debugfs_get_loader_dentry();
+       struct dentry *ld = ld_get_loader_dentry();
  
        down_read(&mm->mmap_sem);
        if (ld) {
@@@ -213,7 -213,7 +214,7 @@@ static int __get_handlers(struct pd_t *
        size_t len;
        int ret = 0;
  
-       handlers = preload_storage_get_handlers();
+       handlers = ls_get_handlers();
        if (handlers == NULL)
                return -EINVAL;
  
  
                hd = kzalloc(sizeof(*hd), GFP_ATOMIC);
                if (hd == NULL) {
-                       printk(KERN_ERR PRELOAD_PREFIX "No atomic mem!\n");
+                       printk(KERN_ERR LOADER_PREFIX "No atomic mem!\n");
                        ret = -ENOMEM;
                        goto get_handlers_out;
                }
                hd->dentry = bin->dentry;
                hd->offset = offset;
                __set_handler_mapped(hd, task->mm);
-               __set_attempts(hd, PRELOAD_MAX_ATTEMPTS);
+               __set_attempts(hd, LOADER_MAX_ATTEMPTS);
                list_add_tail(&hd->list, &pd->handlers);
  
                /* inc handlers path's on page */
  
  get_handlers_out:
        /* TODO Cleanup already created */
-       preload_storage_put_handlers();
+       ls_put_handlers();
  
        return ret;
  }
  
  
  
- enum ps_t preload_pd_get_state(struct hd_t *hd)
+ enum ps_t lpd_get_state(struct hd_t *hd)
  {
        if (hd == NULL)
                return 0;
  
        return __get_state(hd);
  }
+ EXPORT_SYMBOL_GPL(lpd_get_state);
  
- void preload_pd_set_state(struct hd_t *hd, enum ps_t state)
+ void lpd_set_state(struct hd_t *hd, enum ps_t state)
  {
        if (hd == NULL) {
-               printk(PRELOAD_PREFIX "%d: No handler data! Current %d %s\n",
+               printk(LOADER_PREFIX "%d: No handler data! Current %d %s\n",
                       __LINE__, current->tgid, current->comm);
                return;
        }
        __set_state(hd, state);
  }
  
- unsigned long preload_pd_get_loader_base(struct pd_t *pd)
+ unsigned long lpd_get_loader_base(struct pd_t *pd)
  {
        if (pd == NULL)
                return 0;
        return __get_loader_base(pd);
  }
  
- void preload_pd_set_loader_base(struct pd_t *pd, unsigned long vaddr)
+ void lpd_set_loader_base(struct pd_t *pd, unsigned long vaddr)
  {
        __set_loader_base(pd, vaddr);
  }
  
- unsigned long preload_pd_get_handlers_base(struct hd_t *hd)
+ unsigned long lpd_get_handlers_base(struct hd_t *hd)
  {
        if (hd == NULL)
                return 0;
  
        return __get_handlers_base(hd);
  }
+ EXPORT_SYMBOL_GPL(lpd_get_handlers_base);
  
- void preload_pd_set_handlers_base(struct hd_t *hd, unsigned long vaddr)
+ void lpd_set_handlers_base(struct hd_t *hd, unsigned long vaddr)
  {
        __set_handlers_base(hd, vaddr);
  }
  
- char __user *preload_pd_get_path(struct pd_t *pd, struct hd_t *hd)
+ char __user *lpd_get_path(struct pd_t *pd, struct hd_t *hd)
  {
        unsigned long page = __get_data_page(pd);
        unsigned long offset = __get_offset(hd);
  
  
  
- void *preload_pd_get_handle(struct hd_t *hd)
+ void *lpd_get_handle(struct hd_t *hd)
  {
        if (hd == NULL)
                return NULL;
        return __get_handle(hd);
  }
  
- void preload_pd_set_handle(struct hd_t *hd, void __user *handle)
+ void lpd_set_handle(struct hd_t *hd, void __user *handle)
  {
        if (hd == NULL) {
-               printk(PRELOAD_PREFIX "%d: No handler data! Current %d %s\n",
+               printk(LOADER_PREFIX "%d: No handler data! Current %d %s\n",
                       __LINE__, current->tgid, current->comm);
                return;
        }
        __set_handle(hd, handle);
  }
  
- long preload_pd_get_attempts(struct hd_t *hd)
+ long lpd_get_attempts(struct hd_t *hd)
  {
        if (hd == NULL)
                return -EINVAL;
        return __get_attempts(hd);
  }
  
- void preload_pd_dec_attempts(struct hd_t *hd)
+ void lpd_dec_attempts(struct hd_t *hd)
  {
        long attempts;
  
        if (hd == NULL) {
-               printk(PRELOAD_PREFIX "%d: No handler data! Current %d %s\n",
+               printk(LOADER_PREFIX "%d: No handler data! Current %d %s\n",
                       __LINE__, current->tgid, current->comm);
                return;
        }
        __set_attempts(hd, attempts);
  }
  
- struct dentry *preload_pd_get_dentry(struct hd_t *hd)
+ struct dentry *lpd_get_dentry(struct hd_t *hd)
  {
        return hd->dentry;
  }
  
- struct pd_t *preload_pd_get_parent_pd(struct hd_t *hd)
+ struct pd_t *lpd_get_parent_pd(struct hd_t *hd)
  {
        return hd->parent;
  }
+ EXPORT_SYMBOL_GPL(lpd_get_parent_pd);
  
- struct pd_t *preload_pd_get(struct sspt_proc *proc)
+ struct pd_t *lpd_get(struct sspt_proc *proc)
  {
        return (struct pd_t *)proc->private_data;
  }
+ EXPORT_SYMBOL_GPL(lpd_get);
  
- struct hd_t *preload_pd_get_hd(struct pd_t *pd, struct dentry *dentry)
+ struct hd_t *lpd_get_hd(struct pd_t *pd, struct dentry *dentry)
  {
        struct hd_t *hd;
  
  
        return NULL;
  }
+ EXPORT_SYMBOL_GPL(lpd_get_hd);
  
  static struct pd_t *do_create_pd(struct task_struct *task)
  {
@@@ -400,7 -405,7 +406,7 @@@ free_pd
        kfree(pd);
  
  create_pd_exit:
-       printk(KERN_ERR PRELOAD_PREFIX "do_pd_create_pd: error=%d\n", ret);
+       printk(KERN_ERR LOADER_PREFIX "do_pd_create_pd: error=%d\n", ret);
        return NULL;
  }
  
@@@ -408,7 -413,7 +414,7 @@@ static void *pd_create(struct sspt_pro
  {
        struct pd_t *pd;
  
-       pd = do_create_pd(proc->task);
+       pd = do_create_pd(proc->leader);
  
        return (void *)pd;
  }
@@@ -423,7 -428,7 +429,7 @@@ struct sspt_proc_cb pd_cb = 
        .priv_destroy = pd_destroy
  };
  
- int preload_pd_init(void)
+ int lpd_init(void)
  {
        int ret;
  
        return ret;
  }
  
- void preload_pd_uninit(void)
+ void lpd_uninit(void)
  {
        sspt_proc_cb_set(NULL);
  
@@@ -9,39 -9,28 +9,39 @@@ Source: swap-modules-3.0.tar.g
  
  BuildRequires: perl
  BuildRequires: python
 -%ifarch %{arm}
 -    %if "%{?tizen_profile_name}" == "tv"
 -BuildConflicts: vd_kernel-headers
 +Provides: swap-modules
 +
 +%if "%{_repository}" == "emulator32" || "%{_repository}" == "emulator32-wayland"
 +BuildRequires: emulator-kernel-devel
 +  %define build_arch i386
 +  %define kernel_path /usr/src/linux-kernel-build-3.14.25
 +%else
 +
 +  %if "%{_repository}" == "target-TM1"
 +BuildRequires: kernel-devel-3.10-sc7730
 +    %define build_arch arm
 +    %define kernel_path /boot/kernel/devel/kernel-devel-tizen_tm1
 +  %else
 +
 +    %if "%{_repository}" == "target-circle"
 +BuildRequires: kernel-devel-3.4-exynos3250
 +      %define build_arch arm
 +      %define kernel_path /boot/kernel/devel/kernel-devel-tizen_wc1
 +    %else
 +
 +      %if "%{TIZEN_PRODUCT_TV}" == "1"
  BuildRequires: tztv-hawk-kmodules-devel
          %define build_arch arm
          %define kernel_path /usr/include/kernel_header/debug
 -    %else
 -        %if "%{?tizen_profile_name}" == "mobile"
 -ExcludeArch: %{arm}
 -        %else
 -            %if "%{?tizen_profile_name}" == "wearable"
 -ExcludeArch: %{arm}
 -            %endif
 -        %endif
 +      %else
 +
 +ExclusiveArch:
 +      %endif
      %endif
 -%else #i386
 -    %define build_arch i386
 -BuildRequires: emulator-kernel-devel
 -    %define kernel_path /usr/src/linux-kernel-build-3.14.25
 +  %endif
  %endif
  
 -Provides: swap-modules
 +
  %description
  Kernel modules for SWAP
  
@@@ -68,7 -57,9 +68,9 @@@ install -m 666 energy/swap_energy.ko -
  install -m 666 parser/swap_message_parser.ko -t %{buildroot}/opt/swap/sdk
  install -m 666 retprobe/swap_retprobe.ko -t %{buildroot}/opt/swap/sdk
  install -m 666 webprobe/swap_webprobe.ko -t %{buildroot}/opt/swap/sdk
+ install -m 666 loader/swap_loader.ko -t %{buildroot}/opt/swap/sdk
  install -m 666 preload/swap_preload.ko -t %{buildroot}/opt/swap/sdk
+ install -m 666 uihv/swap_uihv.ko -t %{buildroot}/opt/swap/sdk
  install -m 666 fbiprobe/swap_fbiprobe.ko -t %{buildroot}/opt/swap/sdk
  install -m 666 wsp/swap_wsp.ko -t %{buildroot}/opt/swap/sdk
  install -m 666 nsp/swap_nsp.ko -t %{buildroot}/opt/swap/sdk
@@@ -95,7 -86,9 +97,9 @@@ cp LICENSE.GPL-2.0+ %{buildroot}/usr/sh
  /opt/swap/sdk/swap_message_parser.ko
  /opt/swap/sdk/swap_retprobe.ko
  /opt/swap/sdk/swap_webprobe.ko
+ /opt/swap/sdk/swap_loader.ko
  /opt/swap/sdk/swap_preload.ko
+ /opt/swap/sdk/swap_uihv.ko
  /opt/swap/sdk/swap_fbiprobe.ko
  /opt/swap/sdk/swap_wsp.ko
  /opt/swap/sdk/swap_nsp.ko
@@@ -3,12 -3,12 +3,12 @@@
  #include <linux/limits.h>
  #include <linux/list.h>
  
- #include <us_manager/sspt/ip.h>
+ #include <us_manager/sspt/sspt_ip.h>
  
  #include "preload.h"
+ #include "preload_module.h"
  #include "preload_control.h"
  #include "preload_probe.h"
- #include "preload_module.h"
  
  struct bin_desc {
        struct list_head list;
@@@ -147,7 -147,7 +147,7 @@@ static struct dentry *__get_caller_dent
        if (unlikely(vma == NULL || vma->vm_file == NULL))
                goto get_caller_dentry_fail;
  
 -      return vma->vm_file->f_dentry;
 +      return vma->vm_file->f_path.dentry;
  
  get_caller_dentry_fail:
  
@@@ -202,7 -202,7 +202,7 @@@ out
  
  
  /* Called only form handlers. If we're there, then it is instrumented. */
- enum preload_call_type preload_control_call_type_always_inst(void *caller)
+ enum preload_call_type pc_call_type_always_inst(void *caller)
  {
        if (__is_instrumented(caller))
                return INTERNAL_CALL;
  
  }
  
- enum preload_call_type preload_control_call_type(struct us_ip *ip, void *caller)
+ enum preload_call_type pc_call_type(struct sspt_ip *ip, void *caller)
  {
        if (__is_instrumented(caller))
                return INTERNAL_CALL;
        return NOT_INSTRUMENTED;
  }
  
- int preload_control_add_instrumented_binary(char *filename)
+ int pc_add_instrumented_binary(char *filename)
  {
        struct dentry *dentry = get_dentry(filename);
        int res = 0;
        return res > 0 ? 0 : res;
  }
  
- int preload_control_clean_instrumented_bins(void)
+ int pc_clean_instrumented_bins(void)
  {
        __free_binaries(&target);
  
        return 0;
  }
  
- int preload_control_add_ignored_binary(char *filename)
+ int pc_add_ignored_binary(char *filename)
  {
        struct dentry *dentry = get_dentry(filename);
        int res = 0;
        return res > 0 ? 0 : res;
  }
  
- int preload_control_clean_ignored_bins(void)
+ int pc_clean_ignored_bins(void)
  {
        __free_binaries(&ignored);
  
        return 0;
  }
  
- unsigned int preload_control_get_target_names(char ***filenames_p)
+ unsigned int pc_get_target_names(char ***filenames_p)
  {
        return __get_names(&target, filenames_p);
  }
  
- void preload_control_release_target_names(char ***filenames_p)
+ void pc_release_target_names(char ***filenames_p)
  {
        kfree(*filenames_p);
  }
  
- unsigned int preload_control_get_ignored_names(char ***filenames_p)
+ unsigned int pc_get_ignored_names(char ***filenames_p)
  {
        return __get_names(&ignored, filenames_p);
  }
  
- void preload_control_release_ignored_names(char ***filenames_p)
+ void pc_release_ignored_names(char ***filenames_p)
  {
        kfree(*filenames_p);
  }
  
- bool preload_control_check_dentry_is_ignored(struct dentry *dentry)
+ bool pc_check_dentry_is_ignored(struct dentry *dentry)
  {
        struct bin_desc *p;
        bool ret = false;
        return ret;
  }
  
- int preload_control_init(void)
+ int pc_init(void)
  {
        return 0;
  }
  
- void preload_control_exit(void)
+ void pc_exit(void)
  {
        __free_binaries(&target);
        __free_binaries(&ignored);
@@@ -31,6 -31,7 +31,7 @@@
  #include <linux/module.h>
  #include <linux/slab.h>
  #include <linux/list.h>
+ #include <kprobe/swap_ktd.h>
  #include <us_manager/us_slot_manager.h>
  
  static LIST_HEAD(proc_probes_list);
@@@ -82,17 -83,92 +83,92 @@@ void sspt_proc_write_unlock(void
        write_unlock(&sspt_proc_rwlock);
  }
  
+ struct ktd_proc {
+       struct sspt_proc *proc;
+       spinlock_t lock;
+ };
  
- /**
-  * @brief Create sspt_proc struct
-  *
-  * @param task Pointer to the task_struct struct
-  * @param priv Private data
-  * @return Pointer to the created sspt_proc struct
-  */
- struct sspt_proc *sspt_proc_create(struct task_struct *task)
+ static void ktd_init(struct task_struct *task, void *data)
+ {
+       struct ktd_proc *kproc = (struct ktd_proc *)data;
+       kproc->proc = NULL;
+       spin_lock_init(&kproc->lock);
+ }
+ static void ktd_exit(struct task_struct *task, void *data)
+ {
+       struct ktd_proc *kproc = (struct ktd_proc *)data;
+       WARN_ON(kproc->proc);
+ }
+ struct ktask_data ktd = {
+       .init = ktd_init,
+       .exit = ktd_exit,
+       .size = sizeof(struct ktd_proc),
+ };
+ static struct ktd_proc *kproc_by_task(struct task_struct *task)
+ {
+       return (struct ktd_proc *)swap_ktd(&ktd, task);
+ }
+ int sspt_proc_init(void)
+ {
+       return swap_ktd_reg(&ktd);
+ }
+ void sspt_proc_uninit(void)
  {
-       struct sspt_proc *proc = kzalloc(sizeof(*proc), GFP_ATOMIC);
+       swap_ktd_unreg(&ktd);
+ }
+ void sspt_change_leader(struct task_struct *prev, struct task_struct *next)
+ {
+       struct ktd_proc *prev_kproc;
+       prev_kproc = kproc_by_task(prev);
+       spin_lock(&prev_kproc->lock);
+       if (prev_kproc->proc) {
+               struct ktd_proc *next_kproc;
+               next_kproc = kproc_by_task(next);
+               get_task_struct(next);
+               /* Change the keeper sspt_proc */
+               BUG_ON(next_kproc->proc);
+               spin_lock(&next_kproc->lock);
+               next_kproc->proc = prev_kproc->proc;
+               prev_kproc->proc = NULL;
+               spin_unlock(&next_kproc->lock);
+               /* Set new the task leader to sspt_proc */
+               next_kproc->proc->leader = next;
+               put_task_struct(prev);
+       }
+       spin_unlock(&prev_kproc->lock);
+ }
+ static void sspt_reset_proc(struct task_struct *task)
+ {
+       struct ktd_proc *kproc;
+       kproc = kproc_by_task(task->group_leader);
+       spin_lock(&kproc->lock);
+       kproc->proc = NULL;
+       spin_unlock(&kproc->lock);
+ }
+ static struct sspt_proc *sspt_proc_create(struct task_struct *leader)
+ {
+       struct sspt_proc *proc = kzalloc(sizeof(*proc), GFP_KERNEL);
  
        if (proc) {
                proc->feature = sspt_create_feature();
                }
  
                INIT_LIST_HEAD(&proc->list);
-               proc->tgid = task->tgid;
-               proc->task = task->group_leader;
-               proc->sm = create_sm_us(task);
-               INIT_LIST_HEAD(&proc->file_list);
-               rwlock_init(&proc->filter_lock);
-               INIT_LIST_HEAD(&proc->filter_list);
+               INIT_LIST_HEAD(&proc->files.head);
+               init_rwsem(&proc->files.sem);
+               proc->tgid = leader->tgid;
+               proc->leader = leader;
+               /* FIXME: change the task leader */
+               proc->sm = create_sm_us(leader);
+               mutex_init(&proc->filters.mtx);
+               INIT_LIST_HEAD(&proc->filters.head);
                atomic_set(&proc->usage, 1);
  
-               get_task_struct(proc->task);
+               get_task_struct(proc->leader);
  
-               /* add to list */
-               list_add(&proc->list, &proc_probes_list);
+               proc->suspect.after_exec = 1;
+               proc->suspect.after_fork = 0;
        }
  
        return proc;
  }
  
+ static void sspt_proc_free(struct sspt_proc *proc)
+ {
+       put_task_struct(proc->leader);
+       free_sm_us(proc->sm);
+       sspt_destroy_feature(proc->feature);
+       kfree(proc);
+ }
  /**
   * @brief Remove sspt_proc struct
   *
@@@ -133,14 -219,17 +219,17 @@@ void sspt_proc_cleanup(struct sspt_pro
  
        sspt_proc_del_all_filters(proc);
  
-       list_for_each_entry_safe(file, n, &proc->file_list, list) {
+       down_write(&proc->files.sem);
+       list_for_each_entry_safe(file, n, &proc->files.head, list) {
                list_del(&file->list);
                sspt_file_free(file);
        }
+       up_write(&proc->files.sem);
  
        sspt_destroy_feature(proc->feature);
  
        free_sm_us(proc->sm);
+       sspt_reset_proc(proc->leader);
        sspt_proc_put(proc);
  }
  
@@@ -163,43 -252,36 +252,36 @@@ void sspt_proc_put(struct sspt_proc *pr
                        proc->__task = NULL;
                }
  
-               put_task_struct(proc->task);
+               WARN_ON(kproc_by_task(proc->leader)->proc);
+               put_task_struct(proc->leader);
                kfree(proc);
        }
  }
+ EXPORT_SYMBOL_GPL(sspt_proc_put);
+ struct sspt_proc *sspt_proc_by_task(struct task_struct *task)
+ {
+       return kproc_by_task(task->group_leader)->proc;
+ }
+ EXPORT_SYMBOL_GPL(sspt_proc_by_task);
  
  struct sspt_proc *sspt_proc_get_by_task(struct task_struct *task)
  {
+       struct ktd_proc *kproc = kproc_by_task(task->group_leader);
        struct sspt_proc *proc;
  
-       sspt_proc_read_lock();
-       proc = sspt_proc_get_by_task_no_lock(task);
-       sspt_proc_read_unlock();
+       spin_lock(&kproc->lock);
+       proc = kproc->proc;
+       if (proc)
+               sspt_proc_get(proc);
+       spin_unlock(&kproc->lock);
  
        return proc;
  }
  EXPORT_SYMBOL_GPL(sspt_proc_get_by_task);
  
  /**
-  * @brief Get sspt_proc by task
-  *
-  * @param task Pointer on the task_struct struct
-  * @return Pointer on the sspt_proc struct
-  */
- struct sspt_proc *sspt_proc_get_by_task_no_lock(struct task_struct *task)
- {
-       struct sspt_proc *proc, *tmp;
-       list_for_each_entry_safe(proc, tmp, &proc_probes_list, list) {
-               if (proc->tgid == task->tgid)
-                       return proc;
-       }
-       return NULL;
- }
- EXPORT_SYMBOL_GPL(sspt_proc_get_by_task_no_lock);
- /**
   * @brief Call func() on each proc (no lock)
   *
   * @param func Callback
@@@ -239,36 -321,52 +321,52 @@@ EXPORT_SYMBOL_GPL(on_each_proc)
   */
  struct sspt_proc *sspt_proc_get_by_task_or_new(struct task_struct *task)
  {
+       static DEFINE_MUTEX(local_mutex);
+       struct ktd_proc *kproc;
        struct sspt_proc *proc;
+       struct task_struct *leader = task->group_leader;
  
-       sspt_proc_write_lock();
-       proc = sspt_proc_get_by_task_no_lock(task);
-       if (proc == NULL)
-               proc = sspt_proc_create(task);
-       sspt_proc_write_unlock();
+       kproc = kproc_by_task(leader);
+       if (kproc->proc)
+               goto out;
  
-       return proc;
+       proc = sspt_proc_create(leader);
+       spin_lock(&kproc->lock);
+       if (kproc->proc == NULL) {
+               sspt_proc_get(proc);
+               kproc->proc = proc;
+               proc = NULL;
+               sspt_proc_write_lock();
+               list_add(&kproc->proc->list, &proc_probes_list);
+               sspt_proc_write_unlock();
+       }
+       spin_unlock(&kproc->lock);
+       if (proc)
+               sspt_proc_free(proc);
+ out:
+       return kproc->proc;
  }
  
  /**
-  * @brief Free all sspt_proc
+  * @brief Check sspt_proc on empty
   *
   * @return Pointer on the sspt_proc struct
   */
- void sspt_proc_free_all(void)
+ void sspt_proc_check_empty(void)
  {
-       struct sspt_proc *proc, *n;
-       list_for_each_entry_safe(proc, n, &proc_probes_list, list) {
-               list_del(&proc->list);
-               sspt_proc_cleanup(proc);
-       }
+       WARN_ON(!list_empty(&proc_probes_list));
  }
  
  static void sspt_proc_add_file(struct sspt_proc *proc, struct sspt_file *file)
  {
-       list_add(&file->list, &proc->file_list);
+       down_write(&proc->files.sem);
+       list_add(&file->list, &proc->files.head);
        file->proc = proc;
+       up_write(&proc->files.sem);
  }
  
  /**
@@@ -305,12 -403,17 +403,17 @@@ struct sspt_file *sspt_proc_find_file(s
  {
        struct sspt_file *file;
  
-       list_for_each_entry(file, &proc->file_list, list) {
+       down_read(&proc->files.sem);
+       list_for_each_entry(file, &proc->files.head, list) {
                if (dentry == file->dentry)
-                       return file;
+                       goto unlock;
        }
+       file = NULL;
  
-       return NULL;
+ unlock:
+       up_read(&proc->files.sem);
+       return file;
  }
  
  /**
   */
  void sspt_proc_install_page(struct sspt_proc *proc, unsigned long page_addr)
  {
-       struct mm_struct *mm = proc->task->mm;
+       struct mm_struct *mm = proc->leader->mm;
        struct vm_area_struct *vma;
  
        vma = find_vma_intersection(mm, page_addr, page_addr + 1);
        if (vma && check_vma(vma)) {
 -              struct dentry *dentry = vma->vm_file->f_dentry;
 +              struct dentry *dentry = vma->vm_file->f_path.dentry;
                struct sspt_file *file = sspt_proc_find_file(proc, dentry);
                if (file) {
                        struct sspt_page *page;
  void sspt_proc_install(struct sspt_proc *proc)
  {
        struct vm_area_struct *vma;
-       struct mm_struct *mm = proc->task->mm;
+       struct mm_struct *mm = proc->leader->mm;
  
        proc->first_install = 1;
  
        for (vma = mm->mmap; vma; vma = vma->vm_next) {
                if (check_vma(vma)) {
 -                      struct dentry *dentry = vma->vm_file->f_dentry;
 +                      struct dentry *dentry = vma->vm_file->f_path.dentry;
                        struct sspt_file *file =
                                sspt_proc_find_file(proc, dentry);
                        if (file) {
@@@ -382,14 -485,16 +485,16 @@@ int sspt_proc_uninstall(struct sspt_pro
        int err = 0;
        struct sspt_file *file;
  
-       list_for_each_entry_rcu(file, &proc->file_list, list) {
+       down_read(&proc->files.sem);
+       list_for_each_entry(file, &proc->files.head, list) {
                err = sspt_file_uninstall(file, task, flag);
                if (err != 0) {
                        printk(KERN_INFO "ERROR sspt_proc_uninstall: err=%d\n",
                               err);
-                       return err;
+                       break;
                }
        }
+       up_read(&proc->files.sem);
  
        return err;
  }
@@@ -419,12 -524,14 +524,14 @@@ int sspt_proc_get_files_by_region(struc
        struct sspt_file *file, *n;
        unsigned long end = start + len;
  
-       list_for_each_entry_safe(file, n, &proc->file_list, list) {
+       down_write(&proc->files.sem);
+       list_for_each_entry_safe(file, n, &proc->files.head, list) {
                if (intersection(file->vm_start, file->vm_end, start, end)) {
                        ret = 1;
                        list_move(&file->list, head);
                }
        }
+       up_write(&proc->files.sem);
  
        return ret;
  }
   */
  void sspt_proc_insert_files(struct sspt_proc *proc, struct list_head *head)
  {
-       list_splice(head, &proc->file_list);
+       down_write(&proc->files.sem);
+       list_splice(head, &proc->files.head);
+       up_write(&proc->files.sem);
  }
  
  /**
@@@ -454,7 -563,7 +563,7 @@@ void sspt_proc_add_filter(struct sspt_p
  
        f = sspt_filter_create(proc, pfg);
        if (f)
-               list_add(&f->list, &proc->filter_list);
+               list_add(&f->list, &proc->filters.head);
  }
  
  /**
@@@ -468,14 -577,14 +577,14 @@@ void sspt_proc_del_filter(struct sspt_p
  {
        struct sspt_filter *fl, *tmp;
  
-       write_lock(&proc->filter_lock);
-       list_for_each_entry_safe(fl, tmp, &proc->filter_list, list) {
+       mutex_lock(&proc->filters.mtx);
+       list_for_each_entry_safe(fl, tmp, &proc->filters.head, list) {
                if (fl->pfg == pfg) {
                        list_del(&fl->list);
                        sspt_filter_free(fl);
                }
        }
-       write_unlock(&proc->filter_lock);
+       mutex_unlock(&proc->filters.mtx);
  }
  
  /**
@@@ -488,12 -597,12 +597,12 @@@ void sspt_proc_del_all_filters(struct s
  {
        struct sspt_filter *fl, *tmp;
  
-       write_lock(&proc->filter_lock);
-       list_for_each_entry_safe(fl, tmp, &proc->filter_list, list) {
+       mutex_lock(&proc->filters.mtx);
+       list_for_each_entry_safe(fl, tmp, &proc->filters.head, list) {
                list_del(&fl->list);
                sspt_filter_free(fl);
        }
-       write_unlock(&proc->filter_lock);
+       mutex_unlock(&proc->filters.mtx);
  }
  
  /**
@@@ -507,7 -616,7 +616,7 @@@ bool sspt_proc_is_filter_new(struct ssp
  {
        struct sspt_filter *fl;
  
-       list_for_each_entry(fl, &proc->filter_list, list)
+       list_for_each_entry(fl, &proc->filters.head, list)
                if (fl->pfg == pfg)
                        return false;
  
@@@ -520,17 -629,19 +629,19 @@@ void sspt_proc_on_each_filter(struct ss
  {
        struct sspt_filter *fl;
  
-       list_for_each_entry(fl, &proc->filter_list, list)
+       list_for_each_entry(fl, &proc->filters.head, list)
                func(fl, data);
  }
  
  void sspt_proc_on_each_ip(struct sspt_proc *proc,
-                         void (*func)(struct us_ip *, void *), void *data)
+                         void (*func)(struct sspt_ip *, void *), void *data)
  {
        struct sspt_file *file;
  
-       list_for_each_entry(file, &proc->file_list, list)
+       down_read(&proc->files.sem);
+       list_for_each_entry(file, &proc->files.head, list)
                sspt_file_on_each_ip(file, func, data);
+       up_read(&proc->files.sem);
  }
  
  static void is_send_event(struct sspt_filter *f, void *data)
diff --combined webprobe/webprobe.c
@@@ -29,7 -29,7 +29,7 @@@
  
  
  #include <us_manager/us_manager.h>
- #include <us_manager/sspt/ip.h>
+ #include <us_manager/sspt/sspt_ip.h>
  #include <us_manager/probes/register_probes.h>
  #include <us_manager/sspt/sspt.h>
  #include <uprobe/swap_uprobes.h>
@@@ -59,17 -59,17 +59,17 @@@ static void webprobe_cleanup(struct pro
  {
  }
  
- static struct uprobe *webprobe_get_uprobe(struct us_ip *ip)
+ static struct uprobe *webprobe_get_uprobe(struct sspt_ip *ip)
  {
        return &ip->retprobe.up;
  }
  
- static int webprobe_register_probe(struct us_ip *ip)
+ static int webprobe_register_probe(struct sspt_ip *ip)
  {
        return swap_register_uretprobe(&ip->retprobe);
  }
  
- static void webprobe_unregister_probe(struct us_ip *ip, int disarm)
+ static void webprobe_unregister_probe(struct sspt_ip *ip, int disarm)
  {
        if (ip->orig_addr == inspserver_addr_local)
                web_func_inst_remove(INSPSERVER_START);
@@@ -85,21 -85,21 +85,21 @@@ static int web_entry_handler(struct ure
                             struct pt_regs *regs)
  {
        struct uretprobe *rp = ri->rp;
-       struct us_ip *ip;
+       struct sspt_ip *ip;
        unsigned long vaddr, page_vaddr;
        struct vm_area_struct *vma;
  
        if (rp == NULL)
                return 0;
  
-       ip = container_of(rp, struct us_ip, retprobe);
+       ip = container_of(rp, struct sspt_ip, retprobe);
        vaddr = (unsigned long)ip->orig_addr;
        page_vaddr = vaddr & PAGE_MASK;
  
        vma = find_vma_intersection(current->mm, page_vaddr, page_vaddr + 1);
        if (vma && check_vma(vma)) {
                unsigned long addr = vaddr - vma->vm_start;
 -              struct dentry *d = vma->vm_file->f_dentry;
 +              struct dentry *d = vma->vm_file->f_path.dentry;
  
                if (addr == web_prof_addr(WILL_EXECUTE) &&
                    d == web_prof_lib_dentry()) {
  static int web_ret_handler(struct uretprobe_instance *ri, struct pt_regs *regs)
  {
        struct uretprobe *rp = ri->rp;
-       struct us_ip *ip;
+       struct sspt_ip *ip;
        unsigned long vaddr, page_vaddr;
        struct vm_area_struct *vma;
  
        if (rp == NULL)
                return 0;
  
-       ip = container_of(rp, struct us_ip, retprobe);
+       ip = container_of(rp, struct sspt_ip, retprobe);
        vaddr = (unsigned long)ip->orig_addr;
        page_vaddr = vaddr & PAGE_MASK;
  
        vma = find_vma_intersection(current->mm, page_vaddr, page_vaddr + 1);
        if (vma && check_vma(vma)) {
                unsigned long addr = vaddr - vma->vm_start;
 -              struct dentry *d = vma->vm_file->f_dentry;
 +              struct dentry *d = vma->vm_file->f_path.dentry;
  
                if (addr == web_prof_addr(INSPSERVER_START) &&
                    d == web_prof_lib_dentry()) {
        return 0;
  }
  
- static void webprobe_init(struct us_ip *ip)
+ static void webprobe_init(struct sspt_ip *ip)
  {
        ip->retprobe.entry_handler = web_entry_handler;
        ip->retprobe.handler = web_ret_handler;
        ip->retprobe.maxactive = 0;
  }
  
- static void webprobe_uninit(struct us_ip *ip)
+ static void webprobe_uninit(struct sspt_ip *ip)
  {
        webprobe_cleanup(&ip->desc->info);
  }