[IMPROVE] Implement SWAP Writer
authorAlexander Aksenov <a.aksenov@samsung.com>
Sat, 13 Jul 2013 13:32:12 +0000 (17:32 +0400)
committerAlexander Aksenov <a.aksenov@samsung.com>
Sat, 13 Jul 2013 13:32:12 +0000 (17:32 +0400)
writer/Kbuild [new file with mode: 0644]
writer/Makefile.am [new file with mode: 0644]
writer/kernel_operations.h [new file with mode: 0644]
writer/swap_writer_errors.h [new file with mode: 0644]
writer/swap_writer_module.c
writer/swap_writer_module.h [new file with mode: 0644]

diff --git a/writer/Kbuild b/writer/Kbuild
new file mode 100644 (file)
index 0000000..5b775c5
--- /dev/null
@@ -0,0 +1,4 @@
+EXTRA_CFLAGS := $(extra_cflags)
+
+obj-m := swap_writer.o
+swap_writer-y := swap_writer_module.o
diff --git a/writer/Makefile.am b/writer/Makefile.am
new file mode 100644 (file)
index 0000000..fb267e5
--- /dev/null
@@ -0,0 +1,23 @@
+board_opt = -DBOARD_@BOARD@
+target_kernel_src = @KERNEL@
+target_arch = @ARCH@
+module_dir = $(realpath $(top_srcdir)/src/modules/writer)
+module_name = swap_writer
+cross_compiler = $(subst gcc,,$(CC))
+
+inlude_opt = -I$(realpath $(top_srcdir)/src/modules/)
+extra_cflags = "$(inlude_opt) $(board_opt)"
+
+all-local:
+       $(MAKE) CROSS_COMPILE=$(cross_compiler) ARCH=$(target_arch) extra_cflags=$(extra_cflags) \
+               $(AM_MAKEFLAGS) -C $(target_kernel_src) M=$(module_dir) modules
+
+       echo "generate data for version patching <$(OBJDUMP)><$(READELF)>"
+       PATH=$(PATH) $(top_srcdir)/src/modules/driver/patchko.sh -g $(module_dir)/$(module_name).ko $(OBJDUMP) $(READELF)
+
+clean-local:
+       $(MAKE) CROSS_COMPILE=$(cross_compiler) ARCH=$(target_arch) $(AM_MAKEFLAGS) -C $(target_kernel_src) M=$(module_dir) clean
+
+install-exec-local:
+       install -m 644 $(module_dir)/$(module_name).ko $(prefix)
+       install -m 644 $(module_dir)/$(module_name).ko.addr $(prefix)
diff --git a/writer/kernel_operations.h b/writer/kernel_operations.h
new file mode 100644 (file)
index 0000000..4c15279
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  SWAP Writer Module
+ *  modules/writer/kernel_operations.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) Samsung Electronics, 2013
+ *
+ * 2013         Alexander Aksenov <a.aksenov@samsung.com>: SWAP Writer implementation
+ *
+ */
+
+/* Kernel functions wrap */
+
+#ifndef __KERNEL_OPERATIONS_H__
+#define __KERNEL_OPERATIONS_H__
+
+#include <linux/kernel.h>
+#include <asm/ptrace.h>
+
+/* MESSAGES */
+
+#define print_debug(msg, args...) \
+       printk(KERN_DEBUG "SWAP_WRITER DEBUG : " msg, ##args)
+#define print_msg(msg, args...)   \
+       printk(KERN_INFO "SWAP_WRITER : " msg, ##args)
+#define print_warn(msg, args...)  \
+       printk(KERN_WARNING "SWAP_WRITER WARNING : " msg, ##args)
+#define print_err(msg, args...)   \
+       printk(KERN_ERR "SWAP_WRITER ERROR : " msg, ##args)
+#define print_crit(msg, args...)  \
+       printk(KERN_CRIT "SWAP_WRITER CRITICAL : " msg, ##args)
+
+/* ARCH-DEPENDED OPERATIONS */
+
+#ifdef CONFIG_ARM
+
+#define get_regs_ip(regs)       regs->ARM_pc
+#define get_regs_ret_func(regs) regs->ARM_lr
+#define get_regs_ret_val(regs)  get_regs_r0(regs)
+#define get_regs_r0(regs)       regs->ARM_r0
+#define get_regs_r1(regs)       regs->ARM_r1
+#define get_regs_r2(regs)       regs->ARM_r2
+#define get_regs_r3(regs)       regs->ARM_r3
+
+#elif CONFIG_X86_32
+
+#define get_regs_ip(regs)       regs->ip
+//TODO Ret function address for x86!
+#define get_regs_ret_func(regs) 0
+#define get_regs_ret_val(regs)  0
+#define get_regs_r0(regs)       0
+#define get_regs_r1(regs)       0
+#define get_regs_r2(regs)       0
+#define get_regs_r3(regs)       0
+
+#endif /* CONFIG_arch */
+
+
+
+#endif /* __KERNEL_OPERATIONS_H__ */
diff --git a/writer/swap_writer_errors.h b/writer/swap_writer_errors.h
new file mode 100644 (file)
index 0000000..65c8991
--- /dev/null
@@ -0,0 +1,3 @@
+enum _swap_writer_errors {
+    E_SW_SUCCESS = 0        /* Success */
+};
index 6a561fe..1e259cb 100644 (file)
@@ -2,14 +2,16 @@
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/dcache.h>
+#include <linux/mm.h>
 #include <linux/mm_types.h>
 #include <linux/fs.h>
 #include <linux/err.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
-#include <buffer/swap_buffer_module.h>
-#include <buffer/swap_buffer_errors.h>
+#include "../buffer/swap_buffer_module.h"
+#include "../buffer/swap_buffer_errors.h"
 
 #include "swap_writer_module.h"
 #include "swap_writer_errors.h"
@@ -39,6 +41,7 @@ int init_msg(size_t buf_size)
 
        return E_SW_SUCCESS;
 }
+EXPORT_SYMBOL_GPL(init_msg);
 
 void uninit_msg(void)
 {
@@ -47,6 +50,7 @@ void uninit_msg(void)
        for (i = 0; i < NR_CPUS; ++i)
                kfree(cpu_buf[i]);
 }
+EXPORT_SYMBOL_GPL(uninit_msg);
 
 static char *get_current_buf(void)
 {
@@ -189,7 +193,13 @@ static char *pack_lib_obj(char *lib_obj, struct vm_area_struct *vma)
 }
 
 /* FIXME: check_vma()*/
-#include "../../us_manager/sspt/sspt.h"
+static int check_vma(struct vm_area_struct *vma)
+{
+       return vma->vm_file && !(vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC) || (vma->vm_flags & VM_ACCOUNT) ||
+                       !(vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) ||
+                       !(vma->vm_flags & (VM_READ | VM_MAYREAD)));
+}
+
 static char *pack_proc_info_part(char *bin_path, struct mm_struct *mm)
 {
        struct proc_info_part *pip;
@@ -241,7 +251,7 @@ void proc_info_msg(struct task_struct *task)
 
        set_len_msg(buf, buf_end);
 }
-
+EXPORT_SYMBOL_GPL(proc_info_msg);
 
 
 
@@ -258,14 +268,13 @@ struct sample {
        u32 cpu_num;
 } __attribute__((packed));
 
-static char *pack_sample(char *payload, struct pt_regs *regs,
-                        struct task_struct *task)
+static char *pack_sample(char *payload, struct pt_regs *regs)
 {
        struct sample *s = (struct sample *)payload;
        struct task_struct *task = current;
 
        s->pid = task->tgid;
-       s->pc_addr = get_current_op(regs);
+       s->pc_addr = get_regs_ip(regs);
        s->tid = task->pid;
        s->cpu_num = task_cpu(current);
 
@@ -282,7 +291,7 @@ void sample_msg(struct pt_regs *regs)
 
        set_len_msg(buf, buf_end);
 }
-
+EXPORT_SYMBOL_GPL(sample_msg);
 
 
 
@@ -313,8 +322,9 @@ static char *pack_msg_func_entry(char *payload, const char *fmt, struct pt_regs
        mfe->pid = task->tgid;
        mfe->tid = task->pid;
        mfe->cpu_num = task_cpu(task);
-       mfe->pc_addr = regs->ARM_pc;
-       mfe->caller_pc_addr = regs->ARM_lr;
+       mfe->pc_addr = get_regs_ip(regs);
+//TODO ret address for x86!
+       mfe->caller_pc_addr = get_regs_ret_func(regs);
        mfe->probe_type = pt;
        mfe->probe_sub_type = pst;
        mfe->cnt_args = strlen(fmt);
@@ -329,13 +339,17 @@ static int get_args(unsigned long args[], int cnt, struct pt_regs *regs)
        arg_in_regs = cnt < 3 ? cnt : 3;
        switch (arg_in_regs) {
        case 3:
-               args[3] = regs->ARM_r3;
+//TODO x86
+               args[3] = get_regs_r3(regs);
        case 2:
-               args[2] = regs->ARM_r2;
+//TODO x86
+               args[2] = get_regs_r2(regs);
        case 1:
-               args[1] = regs->ARM_r1;
+//TODO x86
+               args[1] = get_regs_r1(regs);
        case 0:
-               args[0] = regs->ARM_r0;
+//TODO x86
+               args[0] = get_regs_r0(regs);
        }
 
        /* FIXME: cnt > 4 */
@@ -476,8 +490,9 @@ static char *pack_msg_func_exit(char *payload, struct pt_regs *regs)
        mfe->pid = task->tgid;
        mfe->tid = task->pid;
        mfe->cpu_num = task_cpu(task);
-       mfe->pc_addr = regs->ARM_pc;
-       mfe->ret_val = regs->ARM_r0;
+       mfe->pc_addr = get_regs_ip(regs);
+//TODO x86
+       mfe->ret_val = get_regs_r0(regs);
 
        return payload + sizeof(*mfe);
 }
@@ -514,7 +529,7 @@ static char *pack_msg_context_switch(char *payload, struct pt_regs *regs)
        struct msg_context_switch *mcs = (struct msg_context_switch *)payload;
        struct task_struct *task = current;
 
-       mcs->pc_addr = regs->ARM_pc;
+       mcs->pc_addr = get_regs_ip(regs);
        mcs->pid = task->tgid;
        mcs->tid = task->pid;
        mcs->cpu_num = task_cpu(task);
@@ -536,12 +551,13 @@ void switch_entry(struct pt_regs *regs)
 {
        context_switch(regs, MSG_CONTEXT_SWITCH_ENTRY);
 }
+EXPORT_SYMBOL_GPL(switch_entry);
 
 void switch_exit(struct pt_regs *regs)
 {
        context_switch(regs, MSG_CONTEXT_SWITCH_EXIT);
 }
-
+EXPORT_SYMBOL_GPL(switch_exit);
 
 
 
@@ -581,6 +597,7 @@ void error_msg(const char *fmt, ...)
 
        set_len_msg(buf, buf_end);
 }
+EXPORT_SYMBOL_GPL(error_msg);
 
 static int __init swap_writer_module_init(void)
 {
diff --git a/writer/swap_writer_module.h b/writer/swap_writer_module.h
new file mode 100644 (file)
index 0000000..1d014d8
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _SWAP_MSG_H
+#define _SWAP_MSG_H
+
+#include <linux/types.h>
+
+enum PROBE_TYPE {
+       PT_US   = 1,
+       PT_KS   = 3
+};
+
+enum PROBE_SUB_TYPE {
+       PST_NONE        = 0,
+       PST_KS_FILE     = 1,
+       PST_KS_IPC      = 2,
+       PST_KS_PROCESS  = 3,
+       PST_KS_SIGNAL   = 4,
+       PST_KS_NETWORK  = 5,
+       PST_KS_DESK     = 6
+};
+
+struct pt_regs;
+
+int init_msg(size_t buf_size);
+void uninit_msg(void);
+
+void proc_info_msg(struct task_struct *task);
+void sample_msg(struct pt_regs *regs);
+
+void entry_event(const char *fmt, struct pt_regs *regs,
+                enum PROBE_TYPE pt, enum PROBE_SUB_TYPE pst);
+void exit_event(struct pt_regs *regs);
+
+void switch_entry(struct pt_regs *regs);
+void switch_exit(struct pt_regs *regs);
+
+void error_msg(const char *fmt, ...);
+
+#endif /* _SWAP_MSG_H */