3 * modules/writer/swap_writer_module.c
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 * Copyright (C) Samsung Electronics, 2013
21 * 2013 Alexander Aksenov <a.aksenov@samsung.com>, Vyacheslav Cherkashin:
22 * SWAP Writer module implement
26 #include <linux/types.h>
27 #include <linux/errno.h>
28 #include <linux/sched.h>
29 #include <linux/dcache.h>
31 #include <linux/mm_types.h>
33 #include <linux/err.h>
34 #include <linux/module.h>
35 #include <linux/slab.h>
36 #include <asm/uaccess.h>
37 #include <kprobe/arch/asm/dbi_kprobes.h>
38 #include <uprobe/arch/asm/swap_uprobes.h>
40 #include <buffer/swap_buffer_module.h>
41 #include <buffer/swap_buffer_errors.h>
43 #include "swap_writer_module.h"
44 #include "swap_writer_errors.h"
45 #include "kernel_operations.h"
46 #include "debugfs_writer.h"
47 #include "event_filter.h"
51 MSG_PROC_INFO = 0x0001,
52 MSG_TERMINATE = 0x0002,
55 MSG_FUNCTION_ENTRY = 0x0008,
56 MSG_FUNCTION_EXIT = 0x0009,
57 MSG_CONTEXT_SWITCH_ENTRY = 0x0010,
58 MSG_CONTEXT_SWITCH_EXIT = 0x0011,
59 MSG_PROC_MAP = 0x0012,
60 MSG_PROC_UNMAP = 0x0013
63 static char *cpu_buf[NR_CPUS];
64 static u32 seq_num = 0;
65 static unsigned int discarded = 0;
67 int init_msg(size_t buf_size)
71 for (i = 0; i < NR_CPUS; ++i)
72 cpu_buf[i] = kmalloc(buf_size, GFP_KERNEL);
76 EXPORT_SYMBOL_GPL(init_msg);
82 for (i = 0; i < NR_CPUS; ++i)
85 EXPORT_SYMBOL_GPL(uninit_msg);
87 void reset_discarded(void)
91 EXPORT_SYMBOL_GPL(reset_discarded);
93 void reset_seq_num(void)
97 EXPORT_SYMBOL_GPL(reset_seq_num);
99 unsigned int get_discarded_count(void)
103 EXPORT_SYMBOL_GPL(get_discarded_count);
105 static inline char *get_current_buf(void)
107 return cpu_buf[get_cpu()];
110 static inline void put_current_buf(void)
115 static inline u64 timespec2time(struct timespec *ts)
117 return ((u64)ts->tv_nsec) << 32 | ts->tv_sec;
120 /* ============================================================================
121 * = BASIC MESSAGE FORMAT =
122 * ============================================================================
125 struct basic_msg_fmt {
131 } __attribute__((packed));
134 static void print_hex(char *ptr, int len)
138 printk("print_hex:\n");
139 for (i = 0; i < len; ++i) {
140 printk("[%x] [%3d]=%2x\n", &ptr[i], i, ptr[i]);
145 static int write_to_buffer(void *data)
148 struct basic_msg_fmt *bmf = (struct basic_msg_fmt *)data;
150 result = swap_buffer_write(bmf, bmf->len + sizeof(*bmf));
158 static void set_len_msg(char *buf, char *end)
160 struct basic_msg_fmt *bmf = (struct basic_msg_fmt *)buf;
161 bmf->len = end - buf - sizeof(*bmf);
164 static inline void set_seq_num(struct basic_msg_fmt *bmf)
166 bmf->seq_number = seq_num;
170 static inline void set_time(struct basic_msg_fmt *bmf)
175 bmf->time = timespec2time(&ts);
178 static char* pack_basic_msg_fmt(char *buf, enum MSG_ID id)
180 struct basic_msg_fmt *bmf = (struct basic_msg_fmt *)buf;
193 /* ============================================================================
195 * ============================================================================
206 } __attribute__((packed));
208 struct proc_info_part {
211 } __attribute__((packed));
217 } __attribute__((packed));
219 static char *pack_path(char *buf, struct file *file)
221 enum { TMP_BUF_LEN = 512 };
222 char tmp_buf[TMP_BUF_LEN];
228 return strcpy(buf, NA) + sizeof(NA);
230 filename = d_path(&file->f_path, tmp_buf, TMP_BUF_LEN);
231 if (IS_ERR_OR_NULL(filename))
232 return strcpy(buf, NA) + sizeof(NA);
234 len = strlen(filename) + 1;
235 memcpy(buf, filename, len);
240 static char *pack_lib_obj(char *lib_obj, struct vm_area_struct *vma)
242 struct lib_obj *lo = (struct lib_obj *)lib_obj;
244 lo->low_addr = vma->vm_start;
245 lo->high_addr = vma->vm_end;
247 return pack_path(lo->lib_path, vma->vm_file);
250 /* FIXME: check_vma()*/
251 static int check_vma(struct vm_area_struct *vma)
253 return vma->vm_file &&
254 !(vma->vm_pgoff != 0 ||
255 !(vma->vm_flags & VM_EXEC) ||
256 !(vma->vm_flags & (VM_READ | VM_MAYREAD)));
259 static struct vm_area_struct *find_vma_exe_by_dentry(struct mm_struct *mm, struct dentry *dentry)
261 struct vm_area_struct *vma;
263 for (vma = mm->mmap; vma; vma = vma->vm_next) {
264 if (vma->vm_file && (vma->vm_flags & VM_EXEC) &&
265 (vma->vm_file->f_dentry == dentry))
275 static char *pack_shared_kmem(char *lib_obj, struct mm_struct *mm,
278 struct lib_obj *so = (struct lib_obj *)lib_obj;
280 unsigned long start = 0, end = 0;
282 const char *kmem_name = get_shared_kmem(mm, &start, &end);
285 if (kmem_name == NULL)
288 name_len = strlen(kmem_name) + 1;
289 so->low_addr = (u64)start;
290 so->high_addr = (u64)end;
291 memcpy(so->lib_path, kmem_name, name_len);
293 so_obj = so->lib_path + name_len;
298 static char *pack_libs(char *lib_obj, struct mm_struct *mm, u32 *lib_cnt_p)
300 struct vm_area_struct *vma;
302 for (vma = mm->mmap; vma; vma = vma->vm_next) {
303 if (check_vma(vma)) {
304 lib_obj = pack_lib_obj(lib_obj, vma);
312 static char *pack_proc_info_part(char *end_path, struct mm_struct *mm)
314 struct proc_info_part *pip;
318 pip = (struct proc_info_part *)end_path;
321 lib_cnt_p = &pip->lib_cnt;
323 lib_obj = pack_libs(lib_obj, mm, lib_cnt_p);
324 lib_obj = pack_shared_kmem(lib_obj, mm, lib_cnt_p);
329 static char *pack_proc_info(char *payload, struct task_struct *task,
330 struct dentry *dentry)
332 struct proc_info *pi = (struct proc_info *)payload;
333 struct vm_area_struct *vma = find_vma_exe_by_dentry(task->mm, dentry);
334 struct timespec boot_time;
335 struct timespec start_time;
336 char *end_path = NULL;
338 getboottime(&boot_time);
339 start_time = timespec_add(boot_time, task->real_start_time);
341 pi->pid = task->tgid;
342 pi->ppid = task->real_parent->tgid;
343 pi->start_sec = (u32)start_time.tv_sec;
344 pi->start_nsec = (u32)start_time.tv_nsec;
347 pi->low_addr = vma->vm_start;
348 pi->high_addr = vma->vm_end;
349 end_path = pack_path(pi->bin_path, vma->vm_file);
353 end_path = pack_path(pi->bin_path, NULL);
355 return pack_proc_info_part(end_path, task->mm);
358 /* called with down\up\_read(&task->mm->mmap_sem) */
359 int proc_info_msg(struct task_struct *task, struct dentry *dentry)
361 char *buf, *payload, *buf_end;
364 buf = get_current_buf();
365 payload = pack_basic_msg_fmt(buf, MSG_PROC_INFO);
366 buf_end = pack_proc_info(payload, task, dentry);
368 set_len_msg(buf, buf_end);
370 ret = write_to_buffer(buf);
375 EXPORT_SYMBOL_GPL(proc_info_msg);
381 /* ============================================================================
382 * = PROCESS TERMINATE =
383 * ============================================================================
386 struct proc_terminate {
388 } __attribute__((packed));
390 static char *pack_proc_terminate(char *payload, struct task_struct *task)
392 struct proc_terminate *pt = (struct proc_terminate *)payload;
395 return payload + sizeof(*pt);
398 void terminate_msg(struct task_struct *task)
400 char *buf, *payload, *buf_end;
402 buf = get_current_buf();
403 payload = pack_basic_msg_fmt(buf, MSG_TERMINATE);
404 buf_end = pack_proc_terminate(payload, task);
406 set_len_msg(buf, buf_end);
408 write_to_buffer(buf);
411 EXPORT_SYMBOL_GPL(terminate_msg);
417 /* ============================================================================
419 * ============================================================================
426 } __attribute__((packed));
428 static char *pack_proc_map(char *payload, struct vm_area_struct *vma)
430 struct proc_map *pm = (struct proc_map *)payload;
432 pm->pid = current->tgid;
433 pm->low_addr = vma->vm_start;
434 pm->high_addr = vma->vm_end;
436 return pack_path(pm->bin_path, vma->vm_file);
439 void pcoc_map_msg(struct vm_area_struct *vma)
441 char *buf, *payload, *buf_end;
443 buf = get_current_buf();
444 payload = pack_basic_msg_fmt(buf, MSG_PROC_MAP);
445 buf_end = pack_proc_map(payload, vma);
447 set_len_msg(buf, buf_end);
449 write_to_buffer(buf);
452 EXPORT_SYMBOL_GPL(pcoc_map_msg);
458 /* ============================================================================
460 * ============================================================================
466 } __attribute__((packed));
468 static char *pack_proc_unmap(char *payload, unsigned long start,
471 struct proc_unmap *pum = (struct proc_unmap *)payload;
473 pum->pid = current->tgid;
474 pum->low_addr = start;
475 pum->high_addr = end;
477 return payload + sizeof(*pum);
480 void proc_unmap_msg(unsigned long start, unsigned long end)
482 char *buf, *payload, *buf_end;
484 buf = get_current_buf();
485 payload = pack_basic_msg_fmt(buf, MSG_PROC_UNMAP);
486 buf_end = pack_proc_unmap(payload, start, end);
488 set_len_msg(buf, buf_end);
490 write_to_buffer(buf);
493 EXPORT_SYMBOL_GPL(proc_unmap_msg);
499 /* ============================================================================
501 * ============================================================================
509 } __attribute__((packed));
511 static char *pack_sample(char *payload, struct pt_regs *regs)
513 struct sample *s = (struct sample *)payload;
514 struct task_struct *task = current;
517 s->pc_addr = get_regs_ip(regs);
519 s->cpu_num = smp_processor_id();
521 return payload + sizeof(*s);
524 int sample_msg(struct pt_regs *regs)
526 char *buf, *payload, *buf_end;
529 if (!check_event(current))
532 buf = get_current_buf();
533 payload = pack_basic_msg_fmt(buf, MSG_SAMPLE);
534 buf_end = pack_sample(payload, regs);
536 set_len_msg(buf, buf_end);
538 ret = write_to_buffer(buf);
543 EXPORT_SYMBOL_GPL(sample_msg);
548 /* ============================================================================
550 * ============================================================================
553 struct msg_func_entry {
563 } __attribute__((packed));
565 static char *pack_msg_func_entry(char *payload, const char *fmt,
566 unsigned long func_addr, struct pt_regs *regs,
567 enum PROBE_TYPE pt, int sub_type)
569 struct msg_func_entry *mfe = (struct msg_func_entry *)payload;
570 struct task_struct *task = current;
572 mfe->pid = task->tgid;
573 mfe->tid = task->pid;
574 mfe->cpu_num = smp_processor_id();
575 mfe->pc_addr = func_addr;
576 mfe->caller_pc_addr = get_regs_ret_func(regs);
577 mfe->probe_type = pt;
578 mfe->probe_sub_type = sub_type;
579 mfe->cnt_args = strlen(fmt);
581 return payload + sizeof(*mfe);
584 static unsigned long get_arg(struct pt_regs *regs, unsigned long n)
586 return user_mode(regs) ?
587 swap_get_uarg(regs, n) : /* US argument */
588 swap_get_sarg(regs, n); /* sys_call argument */
591 static int pack_args(char *buf, int len, const char *fmt, struct pt_regs *regs)
596 int i, /* the index of the argument */
597 fmt_i, /* format index */
598 fmt_len; /* the number of parameters, in format */
600 fmt_len = strlen(fmt);
602 for (i = 0, fmt_i = 0; fmt_i < fmt_len; ++i, ++fmt_i) {
610 switch (fmt[fmt_i]) {
611 case 'b': /* 1 byte(bool) */
612 *buf = (char)!!get_arg(regs, i);
616 case 'c': /* 1 byte(char) */
617 *buf = (char)get_arg(regs, i);
621 case 'f': /* 4 byte(float) */
622 case 'd': /* 4 byte(int) */
625 tmp_u32 = (u32 *)buf;
626 *tmp_u32 = (u32)get_arg(regs, i);
630 case 'x': /* 8 byte(long) */
631 case 'p': /* 8 byte(pointer) */
634 tmp_u64 = (u64 *)buf;
635 *tmp_u64 = (u64)get_arg(regs, i);
639 case 'w': /* 8 byte(double) */
642 tmp_u64 = (u64 *)buf;
643 *tmp_u64 = get_arg(regs, i);
645 *tmp_u64 |= (u64)get_arg(regs, i) << 32;
649 case 's': /* string end with '\0' */
651 enum { max_str_len = 512 };
652 const char __user *user_s;
655 user_s = (const char __user *)get_arg(regs, i);
656 len_s = strnlen_user(user_s, max_str_len);
660 ret = strncpy_from_user(buf, user_s, len_s);
675 return buf - buf_old;
678 int entry_event(const char *fmt, unsigned long func_addr, struct pt_regs *regs,
679 enum PROBE_TYPE pt, int sub_type)
681 char *buf, *payload, *args, *buf_end;
684 if (pt == PT_KS && !check_event(current))
687 buf = get_current_buf();
688 payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_ENTRY);
689 args = pack_msg_func_entry(payload, fmt, func_addr,
692 /* FIXME: len = 1024 */
693 ret = pack_args(args, 1024, fmt, regs);
695 printk("ERROR: !!!!!\n");
699 buf_end = args + ret;
701 set_len_msg(buf, buf_end);
703 ret = write_to_buffer(buf);
708 EXPORT_SYMBOL_GPL(entry_event);
714 /* ============================================================================
716 * ============================================================================
719 struct msg_func_exit {
726 } __attribute__((packed));
728 static int pack_msg_ret_val(char *buf, int len, char ret_type,
729 struct pt_regs *regs)
731 const char *buf_old = buf;
739 case 'b': /* 1 byte(bool) */
742 *buf = (char)!!get_regs_ret_val(regs);
745 case 'c': /* 1 byte(char) */
748 *buf = (char)get_regs_ret_val(regs);
751 case 'd': /* 4 byte(int) */
754 tmp_u32 = (u32 *)buf;
755 *tmp_u32 = get_regs_ret_val(regs);
758 case 'x': /* 8 byte(long) */
759 case 'p': /* 8 byte(pointer) */
762 tmp_u64 = (u64 *)buf;
763 *tmp_u64 = (u64)get_regs_ret_val(regs);
766 case 's': /* string end with '\0' */
768 enum { max_str_len = 512 };
769 const char __user *user_s;
772 user_s = (const char __user *)get_regs_ret_val(regs);
773 len_s = strnlen_user(user_s, max_str_len);
777 ret = strncpy_from_user(buf, user_s, len_s);
788 case 'f': /* 4 byte(float) */
791 tmp_u32 = (u32 *)buf;
792 *tmp_u32 = swap_get_urp_float(regs);
795 case 'w': /* 8 byte(double) */
798 tmp_u64 = (u64 *)buf;
799 *tmp_u64 = swap_get_urp_double(regs);
806 return buf - buf_old;
810 static int pack_msg_func_exit(char *buf, int len, char ret_type,
811 struct pt_regs *regs, unsigned long func_addr,
812 unsigned long ret_addr)
814 struct msg_func_exit *mfe = (struct msg_func_exit *)buf;
815 struct task_struct *task = current;
818 mfe->pid = task->tgid;
819 mfe->tid = task->pid;
820 mfe->cpu_num = smp_processor_id();
821 mfe->pc_addr = func_addr;
822 mfe->caller_pc_addr = ret_addr;
824 ret = pack_msg_ret_val(mfe->ret_val, len, ret_type, regs);
826 printk("ERROR: packing MSG_FUNCTION_EXIT (ret=%d)\n", ret);
830 return sizeof(*mfe) + ret;
833 int exit_event(char ret_type, struct pt_regs *regs, unsigned long func_addr,
834 unsigned long ret_addr)
836 char *buf, *payload, *buf_end;
839 if (!check_event(current))
842 buf = get_current_buf();
843 payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_EXIT);
844 /* FIXME: len=1024 */
845 ret = pack_msg_func_exit(payload, 1024, ret_type, regs,
846 func_addr, ret_addr);
850 buf_end = payload + ret;
851 set_len_msg(buf, buf_end);
853 ret = write_to_buffer(buf);
858 EXPORT_SYMBOL_GPL(exit_event);
864 /* ============================================================================
866 * ============================================================================
869 struct msg_context_switch {
874 } __attribute__((packed));
876 static char *pack_msg_context_switch(char *payload, struct pt_regs *regs)
878 struct msg_context_switch *mcs = (struct msg_context_switch *)payload;
879 struct task_struct *task = current;
882 mcs->pid = task->tgid;
883 mcs->tid = task->pid;
884 mcs->cpu_num = smp_processor_id();
886 return payload + sizeof(*mcs);
889 static int context_switch(struct pt_regs *regs, enum MSG_ID id)
891 char *buf, *payload, *buf_end;
894 buf = get_current_buf();
895 payload = pack_basic_msg_fmt(buf, id);
896 buf_end = pack_msg_context_switch(payload, regs);
897 set_len_msg(buf, buf_end);
899 ret = write_to_buffer(buf);
905 int switch_entry(struct pt_regs *regs)
907 if (!check_event(current))
910 return context_switch(regs, MSG_CONTEXT_SWITCH_ENTRY);
912 EXPORT_SYMBOL_GPL(switch_entry);
914 int switch_exit(struct pt_regs *regs)
916 if (!check_event(current))
919 return context_switch(regs, MSG_CONTEXT_SWITCH_EXIT);
921 EXPORT_SYMBOL_GPL(switch_exit);
926 /* ============================================================================
928 * ============================================================================
933 } __attribute__((packed));
935 static char *pack_msg_err(char *payload, const char *fmt, va_list args)
937 struct msg_err *me = (struct msg_err *)payload;
940 ret = vsprintf(me->msg, fmt, args);
944 return payload + sizeof(*me) + ret + 1;
947 int error_msg(const char *fmt, ...)
949 char *buf, *payload, *buf_end;
953 buf = get_current_buf();
954 payload = pack_basic_msg_fmt(buf, MSG_ERROR);
957 buf_end = pack_msg_err(payload, fmt, args);
960 set_len_msg(buf, buf_end);
962 ret = write_to_buffer(buf);
967 EXPORT_SYMBOL_GPL(error_msg);
973 /* ============================================================================
974 * = MESSAGES FROM USER SPACE =
975 * ============================================================================
978 int raw_msg(char *buf, size_t len)
980 struct basic_msg_fmt *bmf = (struct basic_msg_fmt *)buf;
982 if (sizeof(*bmf) > len)
985 if (bmf->len + sizeof(*bmf) != len)
989 write_to_buffer(buf);
994 static int __init swap_writer_module_init(void)
998 ret = event_filter_init();
1002 ret = init_debugfs_writer();
1004 event_filter_exit();
1009 static void __exit swap_writer_module_exit(void)
1011 exit_debugfs_writer();
1012 event_filter_exit();
1015 module_init(swap_writer_module_init);
1016 module_exit(swap_writer_module_exit);
1018 MODULE_LICENSE("GPL");
1019 MODULE_DESCRIPTION("SWAP Writer module");
1020 MODULE_AUTHOR("Cherkashin V., Aksenov A.S.");