[FIX] Ksyms: Fix warnings
[kernel/swap-modules.git] / us_manager / helper.c
index 0c4307b..7ee6c1e 100644 (file)
  */
 
 
-#include <dbi_kprobes.h>
-#include <dbi_kprobes_deps.h>
-#include <ksyms.h>
+#include <kprobe/dbi_kprobes.h>
+#include <kprobe/dbi_kprobes_deps.h>
+#include <ksyms/ksyms.h>
+#include <writer/kernel_operations.h>
+#include <writer/swap_writer_module.h>
 #include "us_slot_manager.h"
 #include "sspt/sspt.h"
 #include "helper.h"
@@ -48,13 +50,7 @@ static int entry_handler_mf(struct kretprobe_instance *ri, struct pt_regs *regs)
 {
        struct pf_data *data = (struct pf_data *)ri->data;
 
-#if defined(CONFIG_X86)
-       data->addr = regs->EREG(cx);
-#elif defined(CONFIG_ARM)
-       data->addr = regs->ARM_r2;
-#else
-#error this architecture is not supported
-#endif
+       data->addr = swap_get_karg(regs, 2);
 
        return 0;
 }
@@ -62,10 +58,9 @@ static int entry_handler_mf(struct kretprobe_instance *ri, struct pt_regs *regs)
 /* Detects when IPs are really loaded into phy mem and installs probes. */
 static int ret_handler_mf(struct kretprobe_instance *ri, struct pt_regs *regs)
 {
-       struct task_struct *task;
+       struct task_struct *task = current;
        unsigned long page_addr;
 
-       task = current->group_leader;
        if (is_kthread(task))
                return 0;
 
@@ -114,12 +109,6 @@ static int ret_handler_cp(struct kretprobe_instance *ri, struct pt_regs *regs)
 
        if(task->mm != current->mm) {   /* check flags CLONE_VM */
                rm_uprobes_child(task);
-
-               /*
-                * Ignoring page_addr, because it is
-                * first calling call_page_fault()
-                */
-               call_page_fault(task, 0xbadc0de);
        }
 out:
        return 0;
@@ -140,16 +129,7 @@ static struct kretprobe cp_kretprobe = {
 /* Detects when target process removes IPs. */
 static int mr_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
-       struct sspt_proc *proc = NULL;
-       struct task_struct *task;
-
-#if defined(CONFIG_X86)
-       task = (struct task_struct *)regs->EREG(ax);
-#elif defined(CONFIG_ARM)
-       task = (struct task_struct *)regs->ARM_r0;
-#else
-#error this architecture is not supported
-#endif
+       struct task_struct *task = (struct task_struct *)swap_get_karg(regs, 0);
 
        if (is_kthread(task))
                goto out;
@@ -174,94 +154,111 @@ static struct kprobe mr_kprobe = {
  *                                 do_munmap()                                *
  ******************************************************************************
  */
+struct unmap_data {
+       unsigned long start;
+       size_t len;
+};
 
-static int remove_unmap_probes(struct task_struct *task, struct sspt_proc *proc, unsigned long start, size_t len)
+static void remove_unmap_probes(struct sspt_proc *proc, struct unmap_data *umd)
 {
-       struct mm_struct *mm = task->mm;
-       struct vm_area_struct *vma;
-
-       /* FIXME: not implemented */
-       return 0;
-
-       if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE - start) {
-               return -EINVAL;
-       }
-
-       if ((len = PAGE_ALIGN(len)) == 0) {
-               return -EINVAL;
-       }
+       struct task_struct *task = proc->task;
+       unsigned long start = umd->start;
+       size_t len = PAGE_ALIGN(umd->len);
+       LIST_HEAD(head);
 
-       vma = find_vma(mm, start);
-       if (vma && check_vma(vma)) {
-               struct sspt_file *file;
+       if (sspt_proc_get_files_by_region(proc, &head, start, len)) {
+               struct sspt_file *file, *n;
                unsigned long end = start + len;
-               struct dentry *dentry = vma->vm_file->f_dentry;
 
-               file = sspt_proc_find_file(proc, dentry);
-               if (file) {
-                       if (vma->vm_start == start || vma->vm_end == end) {
-                               sspt_file_uninstall(file, task, US_UNREGS_PROBE);
-                               file->loaded = 0;
+               list_for_each_entry_safe(file, n, &head, list) {
+                       if (file->vm_start >= end)
+                               continue;
+
+                       if (file->vm_start >= start) {
+                               sspt_file_uninstall(file, task, US_UNINSTALL);
                        } else {
-                               unsigned long page_addr;
-                               struct sspt_page *page;
-
-                               for (page_addr = vma->vm_start; page_addr < vma->vm_end; page_addr += PAGE_SIZE) {
-                                       page = sspt_find_page_mapped(file, page_addr);
-                                       if (page) {
-                                               sspt_unregister_page(page, US_UNREGS_PROBE, task);
-                                       }
-                               }
-
-                               if (sspt_file_check_install_pages(file)) {
-                                       file->loaded = 0;
-                               }
+                               /* TODO: uninstall pages: start..file->vm_end */
                        }
                }
+
+               sspt_proc_insert_files(proc, &head);
+
+               proc_unmap_msg(start, end);
        }
+}
+
+
+static int entry_handler_unmap(struct kretprobe_instance *ri,
+                              struct pt_regs *regs)
+{
+       struct unmap_data *data = (struct unmap_data *)ri->data;
+
+       data->start = swap_get_karg(regs, 1);
+       data->len = (size_t)swap_get_karg(regs, 2);
 
        return 0;
 }
 
-/* Detects when target removes IPs. */
-static int unmap_pre_handler(struct kprobe *p, struct pt_regs *regs)
+static int ret_handler_unmap(struct kretprobe_instance *ri,
+                            struct pt_regs *regs)
 {
-       /* for ARM */
-       struct mm_struct *mm;
-       unsigned long start;
-       size_t len;
+       struct task_struct *task;
+       struct sspt_proc *proc;
 
-#if defined(CONFIG_X86)
-       mm = (struct mm_struct *)regs->EREG(ax);
-       start = regs->EREG(dx);
-       len = (size_t)regs->EREG(cx);
-#elif defined(CONFIG_ARM)
-       mm = (struct mm_struct *)regs->ARM_r0;
-       start = regs->ARM_r1;
-       len = (size_t)regs->ARM_r2;
-#else
-#error this architecture is not supported
-#endif
-
-       struct sspt_proc *proc = NULL;
-       struct task_struct *task = current;
+       task = current->group_leader;
+       if (is_kthread(task) ||
+           get_regs_ret_val(regs))
+               return 0;
 
+       proc = sspt_proc_get_by_task(task);
+       if (proc)
+               remove_unmap_probes(proc, (struct unmap_data *)ri->data);
+
+       return 0;
+}
+
+static struct kretprobe unmap_kretprobe = {
+       .entry_handler = entry_handler_unmap,
+       .handler = ret_handler_unmap,
+       .data_size = sizeof(struct unmap_data)
+};
+
+
+
+/*
+ ******************************************************************************
+ *                               do_mmap_pgoff()                              *
+ ******************************************************************************
+ */
+static int ret_handler_mmap(struct kretprobe_instance *ri,
+                           struct pt_regs *regs)
+{
+       struct sspt_proc *proc;
+       struct task_struct *task;
+       unsigned long start_addr;
+       struct vm_area_struct *vma;
+
+       task = current->group_leader;
        if (is_kthread(task))
-               goto out;
+               return 0;
+
+       start_addr = (unsigned long)get_regs_ret_val(regs);
+       if (IS_ERR_VALUE(start_addr))
+               return 0;
 
        proc = sspt_proc_get_by_task(task);
-       if (proc) {
-               if (remove_unmap_probes(task, proc, start, len)) {
-                       printk("ERROR do_munmap: start=%lx, len=%x\n", start, len);
-               }
-       }
+       if (proc == NULL)
+               return 0;
+
+       vma = find_vma_intersection(task->mm, start_addr, start_addr + 1);
+       if (vma && check_vma(vma))
+               pcoc_map_msg(vma);
 
-out:
        return 0;
 }
 
-static struct kprobe unmap_kprobe = {
-       .pre_handler = unmap_pre_handler
+static struct kretprobe mmap_kretprobe = {
+       .handler = ret_handler_mmap
 };
 
 
@@ -271,7 +268,7 @@ int register_helper(void)
        int ret = 0;
 
        /* install kprobe on 'do_munmap' to detect when for remove user space probes */
-       ret = dbi_register_kprobe(&unmap_kprobe);
+       ret = dbi_register_kretprobe(&unmap_kretprobe);
        if (ret) {
                printk("dbi_register_kprobe(do_munmap) result=%d!\n", ret);
                return ret;
@@ -292,15 +289,26 @@ int register_helper(void)
                goto unregister_mr;
        }
 
+       /* install kretprobe on 'do_mmap_pgoff' to detect when mapping file */
+       ret = dbi_register_kretprobe(&mmap_kretprobe);
+       if (ret) {
+               printk("dbi_register_kretprobe(do_mmap_pgoff) result=%d!\n", ret);
+               goto unregister_cp;
+       }
+
        /* install kretprobe on 'handle_mm_fault' to detect when they will be loaded */
        ret = dbi_register_kretprobe(&mf_kretprobe);
        if (ret) {
                printk("dbi_register_kretprobe(do_page_fault) result=%d!\n", ret);
-               goto unregister_cp;
+               goto unregister_mmap;
        }
 
        return ret;
 
+
+unregister_mmap:
+       dbi_unregister_kretprobe(&mmap_kretprobe);
+
 unregister_cp:
        dbi_unregister_kretprobe(&cp_kretprobe);
 
@@ -308,7 +316,7 @@ unregister_mr:
        dbi_unregister_kprobe(&mr_kprobe);
 
 unregister_unmap:
-       dbi_unregister_kprobe(&unmap_kprobe);
+       dbi_unregister_kretprobe(&unmap_kretprobe);
 
        return ret;
 }
@@ -318,14 +326,17 @@ void unregister_helper(void)
        /* uninstall kretprobe with 'handle_mm_fault' */
        dbi_unregister_kretprobe(&mf_kretprobe);
 
+       /* uninstall kretprobe with 'do_mmap_pgoff' */
+       dbi_unregister_kretprobe(&mmap_kretprobe);
+
        /* uninstall kretprobe with 'copy_process' */
        dbi_unregister_kretprobe(&cp_kretprobe);
 
        /* uninstall kprobe with 'mm_release' */
        dbi_unregister_kprobe(&mr_kprobe);
 
-       /* uninstall kprobe with 'do_munmap' */
-       dbi_unregister_kprobe(&unmap_kprobe);
+       /* uninstall kretprobe with 'do_munmap' */
+       dbi_unregister_kretprobe(&unmap_kretprobe);
 }
 
 int init_helper(void)
@@ -357,7 +368,14 @@ int init_helper(void)
                printk("Cannot find address for do_munmap function!\n");
                return -EINVAL;
        }
-       unmap_kprobe.addr = (kprobe_opcode_t *)addr;
+       unmap_kretprobe.kp.addr = (kprobe_opcode_t *)addr;
+
+       addr = swap_ksyms("do_mmap_pgoff");
+       if (addr == 0) {
+               printk("Cannot find address for do_mmap_pgoff function!\n");
+               return -EINVAL;
+       }
+       mmap_kretprobe.kp.addr = (kprobe_opcode_t *)addr;
 
        return 0;
 }