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 down_read(&mm->mmap_sem);
264 for (vma = mm->mmap; vma; vma = vma->vm_next) {
265 if (vma->vm_file && (vma->vm_flags & VM_EXEC) &&
266 (vma->vm_file->f_dentry == dentry))
272 up_read(&mm->mmap_sem);
277 static char *pack_shared_kmem(char *lib_obj, struct mm_struct *mm,
280 struct lib_obj *so = (struct lib_obj *)lib_obj;
282 unsigned long start = 0, end = 0;
284 const char *kmem_name = get_shared_kmem(mm, &start, &end);
287 if (kmem_name == NULL)
290 name_len = strlen(kmem_name) + 1;
291 so->low_addr = (u64)start;
292 so->high_addr = (u64)end;
293 memcpy(so->lib_path, kmem_name, name_len);
295 so_obj = so->lib_path + name_len;
300 static char *pack_libs(char *lib_obj, struct mm_struct *mm, u32 *lib_cnt_p)
302 struct vm_area_struct *vma;
304 down_read(&mm->mmap_sem);
305 for (vma = mm->mmap; vma; vma = vma->vm_next) {
306 if (check_vma(vma)) {
307 lib_obj = pack_lib_obj(lib_obj, vma);
311 up_read(&mm->mmap_sem);
316 static char *pack_proc_info_part(char *end_path, struct mm_struct *mm)
318 struct proc_info_part *pip;
322 pip = (struct proc_info_part *)end_path;
325 lib_cnt_p = &pip->lib_cnt;
327 lib_obj = pack_libs(lib_obj, mm, lib_cnt_p);
328 lib_obj = pack_shared_kmem(lib_obj, mm, lib_cnt_p);
333 static char *pack_proc_info(char *payload, struct task_struct *task,
334 struct dentry *dentry)
336 struct proc_info *pi = (struct proc_info *)payload;
337 struct vm_area_struct *vma = find_vma_exe_by_dentry(task->mm, dentry);
338 struct timespec boot_time;
339 struct timespec start_time;
340 char *end_path = NULL;
342 getboottime(&boot_time);
343 start_time = timespec_add(boot_time, task->real_start_time);
345 pi->pid = task->tgid;
346 pi->ppid = task->real_parent->tgid;
347 pi->start_sec = (u32)start_time.tv_sec;
348 pi->start_nsec = (u32)start_time.tv_nsec;
351 pi->low_addr = vma->vm_start;
352 pi->high_addr = vma->vm_end;
353 end_path = pack_path(pi->bin_path, vma->vm_file);
357 end_path = pack_path(pi->bin_path, NULL);
359 return pack_proc_info_part(end_path, task->mm);
362 int proc_info_msg(struct task_struct *task, struct dentry *dentry)
364 char *buf, *payload, *buf_end;
367 buf = get_current_buf();
368 payload = pack_basic_msg_fmt(buf, MSG_PROC_INFO);
369 buf_end = pack_proc_info(payload, task, dentry);
371 set_len_msg(buf, buf_end);
373 ret = write_to_buffer(buf);
378 EXPORT_SYMBOL_GPL(proc_info_msg);
384 /* ============================================================================
385 * = PROCESS TERMINATE =
386 * ============================================================================
389 struct proc_terminate {
391 } __attribute__((packed));
393 static char *pack_proc_terminate(char *payload, struct task_struct *task)
395 struct proc_terminate *pt = (struct proc_terminate *)payload;
398 return payload + sizeof(*pt);
401 void terminate_msg(struct task_struct *task)
403 char *buf, *payload, *buf_end;
405 buf = get_current_buf();
406 payload = pack_basic_msg_fmt(buf, MSG_TERMINATE);
407 buf_end = pack_proc_terminate(payload, task);
409 set_len_msg(buf, buf_end);
411 write_to_buffer(buf);
414 EXPORT_SYMBOL_GPL(terminate_msg);
420 /* ============================================================================
422 * ============================================================================
429 } __attribute__((packed));
431 static char *pack_proc_map(char *payload, struct vm_area_struct *vma)
433 struct proc_map *pm = (struct proc_map *)payload;
435 pm->pid = current->tgid;
436 pm->low_addr = vma->vm_start;
437 pm->high_addr = vma->vm_end;
439 return pack_path(pm->bin_path, vma->vm_file);
442 void pcoc_map_msg(struct vm_area_struct *vma)
444 char *buf, *payload, *buf_end;
446 buf = get_current_buf();
447 payload = pack_basic_msg_fmt(buf, MSG_PROC_MAP);
448 buf_end = pack_proc_map(payload, vma);
450 set_len_msg(buf, buf_end);
452 write_to_buffer(buf);
455 EXPORT_SYMBOL_GPL(pcoc_map_msg);
461 /* ============================================================================
463 * ============================================================================
469 } __attribute__((packed));
471 static char *pack_proc_unmap(char *payload, unsigned long start,
474 struct proc_unmap *pum = (struct proc_unmap *)payload;
476 pum->pid = current->tgid;
477 pum->low_addr = start;
478 pum->high_addr = end;
480 return payload + sizeof(*pum);
483 void proc_unmap_msg(unsigned long start, unsigned long end)
485 char *buf, *payload, *buf_end;
487 buf = get_current_buf();
488 payload = pack_basic_msg_fmt(buf, MSG_PROC_UNMAP);
489 buf_end = pack_proc_unmap(payload, start, end);
491 set_len_msg(buf, buf_end);
493 write_to_buffer(buf);
496 EXPORT_SYMBOL_GPL(proc_unmap_msg);
502 /* ============================================================================
504 * ============================================================================
512 } __attribute__((packed));
514 static char *pack_sample(char *payload, struct pt_regs *regs)
516 struct sample *s = (struct sample *)payload;
517 struct task_struct *task = current;
520 s->pc_addr = get_regs_ip(regs);
522 s->cpu_num = smp_processor_id();
524 return payload + sizeof(*s);
527 int sample_msg(struct pt_regs *regs)
529 char *buf, *payload, *buf_end;
532 if (!check_event(current))
535 buf = get_current_buf();
536 payload = pack_basic_msg_fmt(buf, MSG_SAMPLE);
537 buf_end = pack_sample(payload, regs);
539 set_len_msg(buf, buf_end);
541 ret = write_to_buffer(buf);
546 EXPORT_SYMBOL_GPL(sample_msg);
551 /* ============================================================================
553 * ============================================================================
556 struct msg_func_entry {
566 } __attribute__((packed));
568 static char *pack_msg_func_entry(char *payload, const char *fmt,
569 unsigned long func_addr, struct pt_regs *regs,
570 enum PROBE_TYPE pt, int sub_type)
572 struct msg_func_entry *mfe = (struct msg_func_entry *)payload;
573 struct task_struct *task = current;
575 mfe->pid = task->tgid;
576 mfe->tid = task->pid;
577 mfe->cpu_num = smp_processor_id();
578 mfe->pc_addr = func_addr;
579 mfe->caller_pc_addr = get_regs_ret_func(regs);
580 mfe->probe_type = pt;
581 mfe->probe_sub_type = sub_type;
582 mfe->cnt_args = strlen(fmt);
584 return payload + sizeof(*mfe);
587 static unsigned long get_arg(struct pt_regs *regs, unsigned long n)
589 return user_mode(regs) ?
590 swap_get_uarg(regs, n) : /* US argument */
591 swap_get_sarg(regs, n); /* sys_call argument */
594 static int pack_args(char *buf, int len, const char *fmt, struct pt_regs *regs)
599 int i, /* the index of the argument */
600 fmt_i, /* format index */
601 fmt_len; /* the number of parameters, in format */
603 fmt_len = strlen(fmt);
605 for (i = 0, fmt_i = 0; fmt_i < fmt_len; ++i, ++fmt_i) {
613 switch (fmt[fmt_i]) {
614 case 'b': /* 1 byte(bool) */
615 *buf = (char)!!get_arg(regs, i);
619 case 'c': /* 1 byte(char) */
620 *buf = (char)get_arg(regs, i);
624 case 'f': /* 4 byte(float) */
625 case 'd': /* 4 byte(int) */
628 tmp_u32 = (u32 *)buf;
629 *tmp_u32 = (u32)get_arg(regs, i);
633 case 'x': /* 8 byte(long) */
634 case 'p': /* 8 byte(pointer) */
637 tmp_u64 = (u64 *)buf;
638 *tmp_u64 = (u64)get_arg(regs, i);
642 case 'w': /* 8 byte(double) */
645 tmp_u64 = (u64 *)buf;
646 *tmp_u64 = get_arg(regs, i);
648 *tmp_u64 |= (u64)get_arg(regs, i) << 32;
652 case 's': /* string end with '\0' */
654 enum { max_str_len = 512 };
655 const char __user *user_s;
658 user_s = (const char __user *)get_arg(regs, i);
659 len_s = strnlen_user(user_s, max_str_len);
663 ret = strncpy_from_user(buf, user_s, len_s);
678 return buf - buf_old;
681 int entry_event(const char *fmt, unsigned long func_addr, struct pt_regs *regs,
682 enum PROBE_TYPE pt, int sub_type)
684 char *buf, *payload, *args, *buf_end;
687 if (pt == PT_KS && !check_event(current))
690 buf = get_current_buf();
691 payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_ENTRY);
692 args = pack_msg_func_entry(payload, fmt, func_addr,
695 /* FIXME: len = 1024 */
696 ret = pack_args(args, 1024, fmt, regs);
698 printk("ERROR: !!!!!\n");
702 buf_end = args + ret;
704 set_len_msg(buf, buf_end);
706 ret = write_to_buffer(buf);
711 EXPORT_SYMBOL_GPL(entry_event);
717 /* ============================================================================
719 * ============================================================================
722 struct msg_func_exit {
729 } __attribute__((packed));
731 static int pack_msg_ret_val(char *buf, int len, char ret_type,
732 struct pt_regs *regs)
734 const char *buf_old = buf;
742 case 'b': /* 1 byte(bool) */
745 *buf = (char)!!get_regs_ret_val(regs);
748 case 'c': /* 1 byte(char) */
751 *buf = (char)get_regs_ret_val(regs);
754 case 'd': /* 4 byte(int) */
757 tmp_u32 = (u32 *)buf;
758 *tmp_u32 = get_regs_ret_val(regs);
761 case 'x': /* 8 byte(long) */
762 case 'p': /* 8 byte(pointer) */
765 tmp_u64 = (u64 *)buf;
766 *tmp_u64 = (u64)get_regs_ret_val(regs);
769 case 's': /* string end with '\0' */
771 enum { max_str_len = 512 };
772 const char __user *user_s;
775 user_s = (const char __user *)get_regs_ret_val(regs);
776 len_s = strnlen_user(user_s, max_str_len);
780 ret = strncpy_from_user(buf, user_s, len_s);
791 case 'f': /* 4 byte(float) */
794 tmp_u32 = (u32 *)buf;
795 *tmp_u32 = swap_get_urp_float(regs);
798 case 'w': /* 8 byte(double) */
801 tmp_u64 = (u64 *)buf;
802 *tmp_u64 = swap_get_urp_double(regs);
809 return buf - buf_old;
813 static int pack_msg_func_exit(char *buf, int len, char ret_type,
814 struct pt_regs *regs, unsigned long func_addr,
815 unsigned long ret_addr)
817 struct msg_func_exit *mfe = (struct msg_func_exit *)buf;
818 struct task_struct *task = current;
821 mfe->pid = task->tgid;
822 mfe->tid = task->pid;
823 mfe->cpu_num = smp_processor_id();
824 mfe->pc_addr = func_addr;
825 mfe->caller_pc_addr = ret_addr;
827 ret = pack_msg_ret_val(mfe->ret_val, len, ret_type, regs);
829 printk("ERROR: packing MSG_FUNCTION_EXIT (ret=%d)\n", ret);
833 return sizeof(*mfe) + ret;
836 int exit_event(char ret_type, struct pt_regs *regs, unsigned long func_addr,
837 unsigned long ret_addr)
839 char *buf, *payload, *buf_end;
842 if (!check_event(current))
845 buf = get_current_buf();
846 payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_EXIT);
847 /* FIXME: len=1024 */
848 ret = pack_msg_func_exit(payload, 1024, ret_type, regs,
849 func_addr, ret_addr);
853 buf_end = payload + ret;
854 set_len_msg(buf, buf_end);
856 ret = write_to_buffer(buf);
861 EXPORT_SYMBOL_GPL(exit_event);
867 /* ============================================================================
869 * ============================================================================
872 struct msg_context_switch {
877 } __attribute__((packed));
879 static char *pack_msg_context_switch(char *payload, struct pt_regs *regs)
881 struct msg_context_switch *mcs = (struct msg_context_switch *)payload;
882 struct task_struct *task = current;
885 mcs->pid = task->tgid;
886 mcs->tid = task->pid;
887 mcs->cpu_num = smp_processor_id();
889 return payload + sizeof(*mcs);
892 static int context_switch(struct pt_regs *regs, enum MSG_ID id)
894 char *buf, *payload, *buf_end;
897 buf = get_current_buf();
898 payload = pack_basic_msg_fmt(buf, id);
899 buf_end = pack_msg_context_switch(payload, regs);
900 set_len_msg(buf, buf_end);
902 ret = write_to_buffer(buf);
908 int switch_entry(struct pt_regs *regs)
910 if (!check_event(current))
913 return context_switch(regs, MSG_CONTEXT_SWITCH_ENTRY);
915 EXPORT_SYMBOL_GPL(switch_entry);
917 int switch_exit(struct pt_regs *regs)
919 if (!check_event(current))
922 return context_switch(regs, MSG_CONTEXT_SWITCH_EXIT);
924 EXPORT_SYMBOL_GPL(switch_exit);
929 /* ============================================================================
931 * ============================================================================
936 } __attribute__((packed));
938 static char *pack_msg_err(char *payload, const char *fmt, va_list args)
940 struct msg_err *me = (struct msg_err *)payload;
943 ret = vsprintf(me->msg, fmt, args);
947 return payload + sizeof(*me) + ret + 1;
950 int error_msg(const char *fmt, ...)
952 char *buf, *payload, *buf_end;
956 buf = get_current_buf();
957 payload = pack_basic_msg_fmt(buf, MSG_ERROR);
960 buf_end = pack_msg_err(payload, fmt, args);
963 set_len_msg(buf, buf_end);
965 ret = write_to_buffer(buf);
970 EXPORT_SYMBOL_GPL(error_msg);
976 /* ============================================================================
977 * = MESSAGES FROM USER SPACE =
978 * ============================================================================
981 int raw_msg(char *buf, size_t len)
983 struct basic_msg_fmt *bmf = (struct basic_msg_fmt *)buf;
985 if (sizeof(*bmf) > len)
988 if (bmf->len + sizeof(*bmf) != len)
992 write_to_buffer(buf);
997 static int __init swap_writer_module_init(void)
1001 ret = event_filter_init();
1005 ret = init_debugfs_writer();
1007 event_filter_exit();
1012 static void __exit swap_writer_module_exit(void)
1014 exit_debugfs_writer();
1015 event_filter_exit();
1018 module_init(swap_writer_module_init);
1019 module_exit(swap_writer_module_exit);
1021 MODULE_LICENSE("GPL");
1022 MODULE_DESCRIPTION("SWAP Writer module");
1023 MODULE_AUTHOR("Cherkashin V., Aksenov A.S.");