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/ctype.h>
28 #include <linux/errno.h>
29 #include <linux/sched.h>
30 #include <linux/dcache.h>
32 #include <linux/mm_types.h>
34 #include <linux/err.h>
35 #include <linux/module.h>
36 #include <linux/slab.h>
37 #include <asm/uaccess.h>
38 #include <kprobe/arch/asm/swap_kprobes.h>
39 #include <uprobe/arch/asm/swap_uprobes.h>
41 #include <buffer/swap_buffer_module.h>
42 #include <buffer/swap_buffer_errors.h>
44 #include "swap_writer_module.h"
45 #include "swap_writer_errors.h"
46 #include "kernel_operations.h"
47 #include "debugfs_writer.h"
48 #include "event_filter.h"
52 MSG_PROC_INFO = 0x0001,
53 MSG_TERMINATE = 0x0002,
56 MSG_FUNCTION_ENTRY = 0x0008,
57 MSG_FUNCTION_EXIT = 0x0009,
58 MSG_CONTEXT_SWITCH_ENTRY = 0x0010,
59 MSG_CONTEXT_SWITCH_EXIT = 0x0011,
60 MSG_PROC_MAP = 0x0012,
61 MSG_PROC_UNMAP = 0x0013,
62 MSG_PROC_COMM = 0x0014
65 static char *cpu_buf[NR_CPUS];
66 static u32 seq_num = 0;
67 static unsigned int discarded = 0;
69 int init_msg(size_t buf_size)
73 for (i = 0; i < NR_CPUS; ++i)
74 cpu_buf[i] = kmalloc(buf_size, GFP_KERNEL);
78 EXPORT_SYMBOL_GPL(init_msg);
84 for (i = 0; i < NR_CPUS; ++i)
87 EXPORT_SYMBOL_GPL(uninit_msg);
89 void reset_discarded(void)
93 EXPORT_SYMBOL_GPL(reset_discarded);
95 void reset_seq_num(void)
99 EXPORT_SYMBOL_GPL(reset_seq_num);
101 unsigned int get_discarded_count(void)
105 EXPORT_SYMBOL_GPL(get_discarded_count);
107 static inline char *get_current_buf(void)
109 return cpu_buf[get_cpu()];
112 static inline void put_current_buf(void)
117 static inline u64 timespec2time(struct timespec *ts)
119 return ((u64)ts->tv_nsec) << 32 | ts->tv_sec;
122 /* ============================================================================
123 * = BASIC MESSAGE FORMAT =
124 * ============================================================================
127 struct basic_msg_fmt {
133 } __attribute__((packed));
136 static void print_hex(char *ptr, int len)
140 printk("print_hex:\n");
141 for (i = 0; i < len; ++i) {
142 printk("[%x] [%3d]=%2x\n", &ptr[i], i, ptr[i]);
147 static int write_to_buffer(void *data)
150 struct basic_msg_fmt *bmf = (struct basic_msg_fmt *)data;
152 result = swap_buffer_write(bmf, bmf->len + sizeof(*bmf));
160 static void set_len_msg(char *buf, char *end)
162 struct basic_msg_fmt *bmf = (struct basic_msg_fmt *)buf;
163 bmf->len = end - buf - sizeof(*bmf);
166 static inline void set_seq_num(struct basic_msg_fmt *bmf)
168 bmf->seq_number = seq_num;
172 static inline void set_time(struct basic_msg_fmt *bmf)
177 bmf->time = timespec2time(&ts);
180 static char* pack_basic_msg_fmt(char *buf, enum MSG_ID id)
182 struct basic_msg_fmt *bmf = (struct basic_msg_fmt *)buf;
195 /* ============================================================================
197 * ============================================================================
200 struct proc_info_top {
203 } __attribute__((packed));
205 struct proc_info_bottom {
212 } __attribute__((packed));
214 struct proc_info_part {
217 } __attribute__((packed));
223 } __attribute__((packed));
225 static char *pack_path(char *buf, struct file *file)
227 enum { TMP_BUF_LEN = 512 };
228 char tmp_buf[TMP_BUF_LEN];
234 return strcpy(buf, NA) + sizeof(NA);
236 filename = d_path(&file->f_path, tmp_buf, TMP_BUF_LEN);
237 if (IS_ERR_OR_NULL(filename))
238 return strcpy(buf, NA) + sizeof(NA);
240 len = strlen(filename) + 1;
241 memcpy(buf, filename, len);
246 static char *pack_lib_obj(char *lib_obj, struct vm_area_struct *vma)
248 struct lib_obj *lo = (struct lib_obj *)lib_obj;
250 lo->low_addr = vma->vm_start;
251 lo->high_addr = vma->vm_end;
253 return pack_path(lo->lib_path, vma->vm_file);
256 /* FIXME: check_vma()*/
257 static int check_vma(struct vm_area_struct *vma)
259 return vma->vm_file &&
260 !(vma->vm_pgoff != 0 ||
261 !(vma->vm_flags & VM_EXEC) ||
262 !(vma->vm_flags & (VM_READ | VM_MAYREAD)));
265 static struct vm_area_struct *find_vma_exe_by_dentry(struct mm_struct *mm, struct dentry *dentry)
267 struct vm_area_struct *vma;
269 for (vma = mm->mmap; vma; vma = vma->vm_next) {
270 if (vma->vm_file && (vma->vm_flags & VM_EXEC) &&
271 (vma->vm_file->f_dentry == dentry))
281 static char *pack_shared_kmem(char *lib_obj, struct mm_struct *mm,
284 struct lib_obj *so = (struct lib_obj *)lib_obj;
286 unsigned long start = 0, end = 0;
288 const char *kmem_name = get_shared_kmem(mm, &start, &end);
291 if (kmem_name == NULL)
294 name_len = strlen(kmem_name) + 1;
295 so->low_addr = (u64)start;
296 so->high_addr = (u64)end;
297 memcpy(so->lib_path, kmem_name, name_len);
299 so_obj = so->lib_path + name_len;
304 static char *pack_libs(char *lib_obj, struct mm_struct *mm, u32 *lib_cnt_p)
306 struct vm_area_struct *vma;
308 for (vma = mm->mmap; vma; vma = vma->vm_next) {
309 if (check_vma(vma)) {
310 lib_obj = pack_lib_obj(lib_obj, vma);
318 static char *pack_proc_info_part(char *end_path, struct mm_struct *mm)
320 struct proc_info_part *pip;
324 pip = (struct proc_info_part *)end_path;
327 lib_cnt_p = &pip->lib_cnt;
329 lib_obj = pack_libs(lib_obj, mm, lib_cnt_p);
330 lib_obj = pack_shared_kmem(lib_obj, mm, lib_cnt_p);
335 static char *pack_comm(char *buf, struct task_struct *task)
337 get_task_comm(buf, task);
339 return buf + strlen(buf) + 1;
342 static char *pack_proc_info_top(char *data, struct task_struct *task)
344 struct proc_info_top *pit = (struct proc_info_top *)data;
346 pit->pid = task->tgid;
348 return pack_comm(pit->comm, task);
351 static char *pack_proc_info_bottom(char *data, struct task_struct *task,
352 struct dentry *dentry)
354 struct proc_info_bottom *pib = (struct proc_info_bottom *)data;
355 struct vm_area_struct *vma = find_vma_exe_by_dentry(task->mm, dentry);
356 struct timespec boot_time;
357 struct timespec start_time;
358 char *end_path = NULL;
360 getboottime(&boot_time);
361 start_time = timespec_add(boot_time, task->real_start_time);
363 pib->ppid = task->real_parent->tgid;
364 pib->start_sec = (u32)start_time.tv_sec;
365 pib->start_nsec = (u32)start_time.tv_nsec;
368 pib->low_addr = vma->vm_start;
369 pib->high_addr = vma->vm_end;
370 end_path = pack_path(pib->bin_path, vma->vm_file);
374 end_path = pack_path(pib->bin_path, NULL);
376 return pack_proc_info_part(end_path, task->mm);
379 static char *pack_proc_info(char *payload, struct task_struct *task,
380 struct dentry *dentry)
382 payload = pack_proc_info_top(payload, task);
383 return pack_proc_info_bottom(payload, task, dentry);
386 /* called with down\up\_read(&task->mm->mmap_sem) */
387 int proc_info_msg(struct task_struct *task, struct dentry *dentry)
389 char *buf, *payload, *buf_end;
392 buf = get_current_buf();
393 payload = pack_basic_msg_fmt(buf, MSG_PROC_INFO);
394 buf_end = pack_proc_info(payload, task, dentry);
396 set_len_msg(buf, buf_end);
398 ret = write_to_buffer(buf);
403 EXPORT_SYMBOL_GPL(proc_info_msg);
409 /* ============================================================================
410 * = PROCESS TERMINATE =
411 * ============================================================================
414 struct proc_terminate {
416 } __attribute__((packed));
418 static char *pack_proc_terminate(char *payload, struct task_struct *task)
420 struct proc_terminate *pt = (struct proc_terminate *)payload;
423 return payload + sizeof(*pt);
426 void terminate_msg(struct task_struct *task)
428 char *buf, *payload, *buf_end;
430 buf = get_current_buf();
431 payload = pack_basic_msg_fmt(buf, MSG_TERMINATE);
432 buf_end = pack_proc_terminate(payload, task);
434 set_len_msg(buf, buf_end);
436 write_to_buffer(buf);
439 EXPORT_SYMBOL_GPL(terminate_msg);
445 /* ============================================================================
447 * ============================================================================
454 } __attribute__((packed));
456 static char *pack_proc_map(char *payload, struct vm_area_struct *vma)
458 struct proc_map *pm = (struct proc_map *)payload;
460 pm->pid = current->tgid;
461 pm->low_addr = vma->vm_start;
462 pm->high_addr = vma->vm_end;
464 return pack_path(pm->bin_path, vma->vm_file);
467 void pcoc_map_msg(struct vm_area_struct *vma)
469 char *buf, *payload, *buf_end;
471 buf = get_current_buf();
472 payload = pack_basic_msg_fmt(buf, MSG_PROC_MAP);
473 buf_end = pack_proc_map(payload, vma);
475 set_len_msg(buf, buf_end);
477 write_to_buffer(buf);
480 EXPORT_SYMBOL_GPL(pcoc_map_msg);
486 /* ============================================================================
488 * ============================================================================
494 } __attribute__((packed));
496 static char *pack_proc_unmap(char *payload, unsigned long start,
499 struct proc_unmap *pum = (struct proc_unmap *)payload;
501 pum->pid = current->tgid;
502 pum->low_addr = start;
503 pum->high_addr = end;
505 return payload + sizeof(*pum);
508 void proc_unmap_msg(unsigned long start, unsigned long end)
510 char *buf, *payload, *buf_end;
512 buf = get_current_buf();
513 payload = pack_basic_msg_fmt(buf, MSG_PROC_UNMAP);
514 buf_end = pack_proc_unmap(payload, start, end);
516 set_len_msg(buf, buf_end);
518 write_to_buffer(buf);
521 EXPORT_SYMBOL_GPL(proc_unmap_msg);
527 /* ============================================================================
529 * ============================================================================
534 } __attribute__((packed));
536 static char *pack_proc_comm(char *data, struct task_struct *task)
538 struct proc_comm *pcomm= (struct proc_comm *)data;
540 pcomm->pid = task->tgid;
542 return pack_comm(pcomm->comm, task);
545 void proc_comm_msg(struct task_struct *task)
547 char *buf, *payload, *buf_end;
549 buf = get_current_buf();
550 payload = pack_basic_msg_fmt(buf, MSG_PROC_COMM);
551 buf_end = pack_proc_comm(payload, task);
553 set_len_msg(buf, buf_end);
555 write_to_buffer(buf);
558 EXPORT_SYMBOL_GPL(proc_comm_msg);
564 /* ============================================================================
566 * ============================================================================
574 } __attribute__((packed));
576 static char *pack_sample(char *payload, struct pt_regs *regs)
578 struct sample *s = (struct sample *)payload;
579 struct task_struct *task = current;
582 s->pc_addr = get_regs_ip(regs);
584 s->cpu_num = smp_processor_id();
586 return payload + sizeof(*s);
589 int sample_msg(struct pt_regs *regs)
591 char *buf, *payload, *buf_end;
594 if (!check_event(current))
597 buf = get_current_buf();
598 payload = pack_basic_msg_fmt(buf, MSG_SAMPLE);
599 buf_end = pack_sample(payload, regs);
601 set_len_msg(buf, buf_end);
603 ret = write_to_buffer(buf);
608 EXPORT_SYMBOL_GPL(sample_msg);
613 /* ============================================================================
615 * ============================================================================
618 struct msg_func_entry {
628 } __attribute__((packed));
630 static char *pack_msg_func_entry(char *payload, const char *fmt,
631 unsigned long func_addr, struct pt_regs *regs,
632 enum PROBE_TYPE pt, int sub_type)
634 struct msg_func_entry *mfe = (struct msg_func_entry *)payload;
635 struct task_struct *task = current;
637 mfe->pid = task->tgid;
638 mfe->tid = task->pid;
639 mfe->cpu_num = smp_processor_id();
640 mfe->pc_addr = func_addr;
641 mfe->caller_pc_addr = get_regs_ret_func(regs);
642 mfe->probe_type = pt;
643 mfe->probe_sub_type = sub_type;
644 mfe->cnt_args = strlen(fmt);
646 return payload + sizeof(*mfe);
649 static unsigned long get_arg(struct pt_regs *regs, unsigned long n)
651 return user_mode(regs) ?
652 swap_get_uarg(regs, n) : /* US argument */
653 swap_get_sarg(regs, n); /* sys_call argument */
656 static int pack_args(char *buf, int len, const char *fmt, struct pt_regs *regs)
661 int i, /* the index of the argument */
662 fmt_i, /* format index */
663 fmt_len; /* the number of parameters, in format */
665 fmt_len = strlen(fmt);
667 for (i = 0, fmt_i = 0; fmt_i < fmt_len; ++i, ++fmt_i) {
675 switch (fmt[fmt_i]) {
676 case 'b': /* 1 byte(bool) */
677 *buf = (char)!!get_arg(regs, i);
681 case 'c': /* 1 byte(char) */
682 *buf = (char)get_arg(regs, i);
686 case 'f': /* 4 byte(float) */
687 case 'd': /* 4 byte(int) */
690 tmp_u32 = (u32 *)buf;
691 *tmp_u32 = (u32)get_arg(regs, i);
695 case 'x': /* 8 byte(long) */
696 case 'p': /* 8 byte(pointer) */
699 tmp_u64 = (u64 *)buf;
700 *tmp_u64 = (u64)get_arg(regs, i);
704 case 'w': /* 8 byte(double) */
707 tmp_u64 = (u64 *)buf;
708 *tmp_u64 = get_arg(regs, i);
710 *tmp_u64 |= (u64)get_arg(regs, i) << 32;
714 case 's': /* string end with '\0' */
716 enum { max_str_len = 512 };
717 const char __user *user_s;
720 user_s = (const char __user *)get_arg(regs, i);
721 len_s = strnlen_user(user_s, max_str_len);
725 ret = strncpy_from_user(buf, user_s, len_s);
740 return buf - buf_old;
743 int entry_event(const char *fmt, unsigned long func_addr, struct pt_regs *regs,
744 enum PROBE_TYPE pt, int sub_type)
746 char *buf, *payload, *args, *buf_end;
749 if (pt == PT_KS && !check_event(current))
752 buf = get_current_buf();
753 payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_ENTRY);
754 args = pack_msg_func_entry(payload, fmt, func_addr,
757 /* FIXME: len = 1024 */
758 ret = pack_args(args, 1024, fmt, regs);
760 printk("ERROR: !!!!!\n");
764 buf_end = args + ret;
766 set_len_msg(buf, buf_end);
768 ret = write_to_buffer(buf);
773 EXPORT_SYMBOL_GPL(entry_event);
779 /* ============================================================================
781 * ============================================================================
784 struct msg_func_exit {
791 } __attribute__((packed));
793 static int pack_msg_ret_val(char *buf, int len, char ret_type,
794 struct pt_regs *regs)
796 const char *buf_old = buf;
804 case 'b': /* 1 byte(bool) */
807 *buf = (char)!!get_regs_ret_val(regs);
810 case 'c': /* 1 byte(char) */
813 *buf = (char)get_regs_ret_val(regs);
816 case 'd': /* 4 byte(int) */
819 tmp_u32 = (u32 *)buf;
820 *tmp_u32 = get_regs_ret_val(regs);
823 case 'x': /* 8 byte(long) */
824 case 'p': /* 8 byte(pointer) */
827 tmp_u64 = (u64 *)buf;
828 *tmp_u64 = (u64)get_regs_ret_val(regs);
831 case 's': /* string end with '\0' */
833 enum { max_str_len = 512 };
834 const char __user *user_s;
837 user_s = (const char __user *)get_regs_ret_val(regs);
838 len_s = strnlen_user(user_s, max_str_len);
842 ret = strncpy_from_user(buf, user_s, len_s);
853 case 'f': /* 4 byte(float) */
856 tmp_u32 = (u32 *)buf;
857 *tmp_u32 = swap_get_urp_float(regs);
860 case 'w': /* 8 byte(double) */
863 tmp_u64 = (u64 *)buf;
864 *tmp_u64 = swap_get_urp_double(regs);
871 return buf - buf_old;
875 static int pack_msg_func_exit(char *buf, int len, char ret_type,
876 struct pt_regs *regs, unsigned long func_addr,
877 unsigned long ret_addr)
879 struct msg_func_exit *mfe = (struct msg_func_exit *)buf;
880 struct task_struct *task = current;
883 mfe->pid = task->tgid;
884 mfe->tid = task->pid;
885 mfe->cpu_num = smp_processor_id();
886 mfe->pc_addr = func_addr;
887 mfe->caller_pc_addr = ret_addr;
889 ret = pack_msg_ret_val(mfe->ret_val, len, ret_type, regs);
891 printk("ERROR: packing MSG_FUNCTION_EXIT (ret=%d)\n", ret);
895 return sizeof(*mfe) + ret;
898 int exit_event(char ret_type, struct pt_regs *regs, unsigned long func_addr,
899 unsigned long ret_addr)
901 char *buf, *payload, *buf_end;
904 if (!check_event(current))
907 buf = get_current_buf();
908 payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_EXIT);
909 /* FIXME: len=1024 */
910 ret = pack_msg_func_exit(payload, 1024, ret_type, regs,
911 func_addr, ret_addr);
915 buf_end = payload + ret;
916 set_len_msg(buf, buf_end);
918 ret = write_to_buffer(buf);
923 EXPORT_SYMBOL_GPL(exit_event);
929 /* ============================================================================
931 * ============================================================================
934 struct msg_context_switch {
939 } __attribute__((packed));
941 static char *pack_msg_context_switch(char *payload, struct pt_regs *regs)
943 struct msg_context_switch *mcs = (struct msg_context_switch *)payload;
944 struct task_struct *task = current;
947 mcs->pid = task->tgid;
948 mcs->tid = task->pid;
949 mcs->cpu_num = smp_processor_id();
951 return payload + sizeof(*mcs);
954 static int context_switch(struct pt_regs *regs, enum MSG_ID id)
956 char *buf, *payload, *buf_end;
959 buf = get_current_buf();
960 payload = pack_basic_msg_fmt(buf, id);
961 buf_end = pack_msg_context_switch(payload, regs);
962 set_len_msg(buf, buf_end);
964 ret = write_to_buffer(buf);
970 int switch_entry(struct pt_regs *regs)
972 if (!check_event(current))
975 return context_switch(regs, MSG_CONTEXT_SWITCH_ENTRY);
977 EXPORT_SYMBOL_GPL(switch_entry);
979 int switch_exit(struct pt_regs *regs)
981 if (!check_event(current))
984 return context_switch(regs, MSG_CONTEXT_SWITCH_EXIT);
986 EXPORT_SYMBOL_GPL(switch_exit);
991 /* ============================================================================
993 * ============================================================================
998 } __attribute__((packed));
1000 static char *pack_msg_err(char *payload, const char *fmt, va_list args)
1002 struct msg_err *me = (struct msg_err *)payload;
1005 ret = vsprintf(me->msg, fmt, args);
1009 return payload + sizeof(*me) + ret + 1;
1012 int error_msg(const char *fmt, ...)
1014 char *buf, *payload, *buf_end;
1018 buf = get_current_buf();
1019 payload = pack_basic_msg_fmt(buf, MSG_ERROR);
1021 va_start(args, fmt);
1022 buf_end = pack_msg_err(payload, fmt, args);
1025 set_len_msg(buf, buf_end);
1027 ret = write_to_buffer(buf);
1032 EXPORT_SYMBOL_GPL(error_msg);
1038 /* ============================================================================
1039 * = MESSAGES FROM USER SPACE =
1040 * ============================================================================
1043 int raw_msg(char *buf, size_t len)
1045 struct basic_msg_fmt *bmf = (struct basic_msg_fmt *)buf;
1047 if (sizeof(*bmf) > len)
1050 if (bmf->len + sizeof(*bmf) != len)
1054 write_to_buffer(buf);
1061 /* ============================================================================
1063 * ============================================================================
1066 static int pack_custom_event(char *buf, int len, const char *fmt, va_list args)
1068 enum { max_str_len = 512 };
1070 char *buf_orig = buf;
1072 for (p = fmt; *p != '\0'; p++) {
1083 case 'b': /* 1 byte(bool) */
1086 *buf = !!(char)va_arg(args, int);
1090 case 'c': /* 1 byte(char) */
1093 *buf = (char)va_arg(args, int);
1097 case 'f': /* 4 byte(float) */
1098 case 'd': /* 4 byte(int) */
1101 *(u32 *)buf = va_arg(args, u32);
1105 case 'x': /* 8 byte(long) */
1106 case 'w': /* 8 byte(double) */
1109 *(u64 *)buf = va_arg(args, u64);
1113 case 'p': /* 8 byte(pointer) */
1116 *(u64 *)buf = va_arg(args, unsigned long);
1120 case 's': /* userspace string with '\0' terminating byte */
1122 const char __user *str;
1125 str = va_arg(args, const char __user *);
1126 /* strnlen_user includes '\0' in its return value */
1127 len_s = strnlen_user(str, max_str_len);
1130 /* strncpy_from_user returns the length of the copied
1131 * string (without '\0') */
1132 n = strncpy_from_user(buf, str, len_s - 1);
1141 case 'S': /* kernelspace string with '\0' terminating byte */
1146 str = va_arg(args, const char *);
1147 len_s = strnlen(str, max_str_len);
1148 if (len < len_s + 1) /* + '\0' */
1150 strncpy(buf, str, len_s);
1157 case 'a': /* userspace byte array (len + ptr) */
1159 const void __user *ptr;
1162 len_p = va_arg(args, u32);
1163 if (len < sizeof(len_p) + len_p)
1165 *(u32 *)buf = len_p;
1166 buf += sizeof(len_p);
1167 len -= sizeof(len_p);
1169 ptr = va_arg(args, const void __user *);
1170 n = copy_from_user(buf, ptr, len_p);
1177 case 'A': /* kernelspace byte array (len + ptr) */
1183 len_p = va_arg(args, u32);
1184 if (len < sizeof(len_p) + len_p)
1186 *(u32 *)buf = len_p;
1187 buf += sizeof(len_p);
1188 len -= sizeof(len_p);
1191 ptr = va_arg(args, const void *);
1192 memcpy(buf, ptr, len_p);
1202 return buf - buf_orig;
1205 enum { max_custom_event_size = 2048 };
1207 int custom_entry_event(unsigned long func_addr, struct pt_regs *regs,
1208 int type, int sub_type, const char *fmt, ...)
1210 char *buf, *payload, *args, *buf_end;
1214 buf = get_current_buf();
1215 payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_ENTRY);
1216 args = pack_msg_func_entry(payload, fmt, func_addr,
1217 regs, type, sub_type);
1219 va_start(vargs, fmt);
1220 ret = pack_custom_event(args, max_custom_event_size, fmt, vargs);
1226 buf_end = args + ret;
1227 set_len_msg(buf, buf_end);
1228 ret = write_to_buffer(buf);
1235 EXPORT_SYMBOL_GPL(custom_entry_event);
1237 /* TODO currently this function is a simple wrapper. it will be refactored when
1238 * protocol changes are applied */
1239 int custom_exit_event(unsigned long func_addr, unsigned long ret_addr,
1240 struct pt_regs *regs, const char *fmt, ...)
1242 char *buf, *payload, *buf_end;
1245 buf = get_current_buf();
1246 payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_EXIT);
1247 ret = pack_msg_func_exit(payload, max_custom_event_size,
1248 fmt[0], regs, func_addr, ret_addr);
1252 buf_end = payload + ret;
1253 set_len_msg(buf, buf_end);
1255 ret = write_to_buffer(buf);
1262 EXPORT_SYMBOL_GPL(custom_exit_event);
1264 static int __init swap_writer_module_init(void)
1268 ret = event_filter_init();
1272 ret = init_debugfs_writer();
1274 event_filter_exit();
1279 static void __exit swap_writer_module_exit(void)
1281 exit_debugfs_writer();
1282 event_filter_exit();
1285 module_init(swap_writer_module_init);
1286 module_exit(swap_writer_module_exit);
1288 MODULE_LICENSE("GPL");
1289 MODULE_DESCRIPTION("SWAP Writer module");
1290 MODULE_AUTHOR("Cherkashin V., Aksenov A.S.");