2 * writer/swap_writer_module.c
3 * @author Alexander Aksenov <a.aksenov@samsung.com>
4 * @author Vyacheslav Cherkashin
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 * Copyright (C) Samsung Electronics, 2013
26 * @section DESCRIPTION
28 * Packing and writing data.
31 #include <linux/types.h>
32 #include <linux/ctype.h>
33 #include <linux/errno.h>
34 #include <linux/sched.h>
35 #include <linux/dcache.h>
37 #include <linux/mm_types.h>
39 #include <linux/err.h>
40 #include <linux/module.h>
41 #include <linux/slab.h>
43 #include <asm/uaccess.h>
45 #include <master/swap_initializer.h>
46 #include <buffer/swap_buffer_module.h>
47 #include <buffer/swap_buffer_errors.h>
49 #include <swap-asm/swap_kprobes.h>
50 #include <swap-asm/swap_uprobes.h>
52 #include "swap_writer_module.h"
53 #include "swap_writer_errors.h"
54 #include "kernel_operations.h"
55 #include "debugfs_writer.h"
56 #include "event_filter.h"
61 * @brief Supported message IDs.
64 MSG_PROC_INFO = 0x0001, /**< Process info */
65 MSG_TERMINATE = 0x0002, /**< Terminate */
66 MSG_ERROR = 0x0003, /**< Error */
67 MSG_SAMPLE = 0x0004, /**< Sampler event */
68 MSG_FUNCTION_ENTRY = 0x0008, /**< Function entry */
69 MSG_FUNCTION_EXIT = 0x0009, /**< Function return */
70 MSG_CONTEXT_SWITCH_ENTRY = 0x0010, /**< Context switch entry */
71 MSG_CONTEXT_SWITCH_EXIT = 0x0011, /**< Context switch exit */
72 MSG_PROC_MAP = 0x0012, /**< Process map */
73 MSG_PROC_UNMAP = 0x0013, /**< Process unmap */
74 MSG_PROC_COMM = 0x0014 /**< Process comm */
77 static char *cpu_buf[NR_CPUS];
79 static unsigned int discarded;
82 * @brief Initializes new message.
84 * @param buf_size Message buffer size.
87 int init_msg(size_t buf_size)
91 for (i = 0; i < NR_CPUS; ++i)
92 cpu_buf[i] = kmalloc(buf_size, GFP_KERNEL);
96 EXPORT_SYMBOL_GPL(init_msg);
99 * @brief Uninitializes message.
103 void uninit_msg(void)
107 for (i = 0; i < NR_CPUS; ++i)
110 EXPORT_SYMBOL_GPL(uninit_msg);
113 * @brief Sets discarded events count to 0.
117 void reset_discarded(void)
121 EXPORT_SYMBOL_GPL(reset_discarded);
124 * @brief Sets events sequence number to 0.
128 void reset_seq_num(void)
132 EXPORT_SYMBOL_GPL(reset_seq_num);
135 * @brief Gets discarded events count.
137 * @return Discarded events count.
139 unsigned int get_discarded_count(void)
143 EXPORT_SYMBOL_GPL(get_discarded_count);
145 static inline char *get_current_buf(void)
147 return cpu_buf[get_cpu()];
150 static inline void put_current_buf(void)
155 static inline u64 timespec2time(struct timespec *ts)
157 return ((u64)ts->tv_nsec) << 32 | ts->tv_sec;
160 /* ============================================================================
161 * = BASIC MESSAGE FORMAT =
162 * ============================================================================
166 * @struct basic_msg_fmt
167 * @brief Basic message.
169 struct basic_msg_fmt {
170 u32 msg_id; /**< Message ID */
171 u32 seq_number; /**< Sequence number */
172 u64 time; /**< Message time */
173 u32 len; /**< Message length */
174 char payload[0]; /**< Message itself */
178 static void print_hex(char *ptr, int len)
182 printk(KERN_INFO "print_hex:\n");
183 for (i = 0; i < len; ++i)
184 printk(KERN_INFO "[%x] [%3d]=%2x\n", &ptr[i], i, ptr[i]);
188 static int write_to_buffer(void *data)
191 struct basic_msg_fmt *bmf = (struct basic_msg_fmt *)data;
193 result = swap_buffer_write(bmf, bmf->len + sizeof(*bmf));
200 static void set_len_msg(char *buf, char *end)
202 struct basic_msg_fmt *bmf = (struct basic_msg_fmt *)buf;
203 bmf->len = end - buf - sizeof(*bmf);
206 static inline void set_seq_num(struct basic_msg_fmt *bmf)
208 bmf->seq_number = seq_num;
212 static inline void set_time(struct basic_msg_fmt *bmf)
217 bmf->time = timespec2time(&ts);
220 static char *pack_basic_msg_fmt(char *buf, enum MSG_ID id)
222 struct basic_msg_fmt *bmf = (struct basic_msg_fmt *)buf;
235 /* ============================================================================
237 * ============================================================================
241 * @struct proc_info_top
242 * @brief Top proc info part.
244 struct proc_info_top {
245 u32 pid; /**< Process PID */
246 char comm[0]; /**< Message */
250 * @struct proc_info_bottom
251 * @brief Bottom proc info part.
253 struct proc_info_bottom {
254 u32 ppid; /**< Parent PID */
255 u32 start_sec; /**< Start time sec */
256 u32 start_nsec; /**< Start time nsec */
257 u64 low_addr; /**< Low address */
258 u64 high_addr; /**< High address */
259 char bin_path[0]; /**< Binary path */
263 * @struct proc_info_part
264 * @brief Process info part.
266 struct proc_info_part {
267 u32 lib_cnt; /**< Library count */
268 char libs[0]; /**< Libraries */
273 * @brief Library object.
276 u64 low_addr; /**< Low library address */
277 u64 high_addr; /**< High library address */
278 char lib_path[0]; /**< Library path */
281 static char *pack_path(char *buf, struct file *file)
283 enum { TMP_BUF_LEN = 512 };
284 char tmp_buf[TMP_BUF_LEN];
290 return strcpy(buf, NA) + sizeof(NA);
292 filename = d_path(&file->f_path, tmp_buf, TMP_BUF_LEN);
293 if (IS_ERR_OR_NULL(filename))
294 return strcpy(buf, NA) + sizeof(NA);
296 len = strlen(filename) + 1;
297 memcpy(buf, filename, len);
302 static char *pack_lib_obj(char *lib_obj, struct vm_area_struct *vma)
304 struct lib_obj *lo = (struct lib_obj *)lib_obj;
306 lo->low_addr = vma->vm_start;
307 lo->high_addr = vma->vm_end;
309 return pack_path(lo->lib_path, vma->vm_file);
312 /* FIXME: check_vma()*/
313 static int check_vma(struct vm_area_struct *vma)
315 return vma->vm_file &&
316 !(vma->vm_pgoff != 0 ||
317 !(vma->vm_flags & VM_EXEC) ||
318 !(vma->vm_flags & (VM_READ | VM_MAYREAD)));
321 static struct vm_area_struct *find_vma_exe_by_dentry(struct mm_struct *mm,
322 struct dentry *dentry)
324 struct vm_area_struct *vma;
326 for (vma = mm->mmap; vma; vma = vma->vm_next) {
327 if (vma->vm_file && (vma->vm_flags & VM_EXEC) &&
328 (vma->vm_file->f_dentry == dentry))
338 static char *pack_shared_kmem(char *lib_obj,
339 struct mm_struct *mm,
342 struct lib_obj *so = (struct lib_obj *)lib_obj;
344 unsigned long start = 0, end = 0;
346 const char *kmem_name = get_shared_kmem(mm, &start, &end);
349 if (kmem_name == NULL)
352 name_len = strlen(kmem_name) + 1;
353 so->low_addr = (u64)start;
354 so->high_addr = (u64)end;
355 memcpy(so->lib_path, kmem_name, name_len);
357 so_obj = so->lib_path + name_len;
362 static char *pack_libs(char *lib_obj, struct mm_struct *mm, u32 *lib_cnt_p)
364 struct vm_area_struct *vma;
366 for (vma = mm->mmap; vma; vma = vma->vm_next) {
367 if (check_vma(vma)) {
368 lib_obj = pack_lib_obj(lib_obj, vma);
376 static char *pack_proc_info_part(char *end_path, struct mm_struct *mm)
378 struct proc_info_part *pip;
382 pip = (struct proc_info_part *)end_path;
385 lib_cnt_p = &pip->lib_cnt;
387 lib_obj = pack_libs(lib_obj, mm, lib_cnt_p);
388 lib_obj = pack_shared_kmem(lib_obj, mm, lib_cnt_p);
393 static char *pack_comm(char *buf, struct task_struct *task)
395 get_task_comm(buf, task);
397 return buf + strlen(buf) + 1;
400 static char *pack_proc_info_top(char *data, struct task_struct *task)
402 struct proc_info_top *pit = (struct proc_info_top *)data;
404 pit->pid = task->tgid;
406 return pack_comm(pit->comm, task);
409 static char *pack_proc_info_bottom(char *data, struct task_struct *task,
410 struct dentry *dentry)
412 struct proc_info_bottom *pib = (struct proc_info_bottom *)data;
413 struct vm_area_struct *vma = find_vma_exe_by_dentry(task->mm, dentry);
414 struct timespec boot_time;
415 struct timespec start_time;
416 char *end_path = NULL;
418 getboottime(&boot_time);
419 start_time = timespec_add(boot_time, task->real_start_time);
421 pib->ppid = task->real_parent->tgid;
422 pib->start_sec = (u32)start_time.tv_sec;
423 pib->start_nsec = (u32)start_time.tv_nsec;
426 pib->low_addr = vma->vm_start;
427 pib->high_addr = vma->vm_end;
428 end_path = pack_path(pib->bin_path, vma->vm_file);
432 end_path = pack_path(pib->bin_path, NULL);
434 return pack_proc_info_part(end_path, task->mm);
437 static char *pack_proc_info(char *payload, struct task_struct *task,
438 struct dentry *dentry)
440 payload = pack_proc_info_top(payload, task);
441 return pack_proc_info_bottom(payload, task, dentry);
445 * @brief Packs and writes process info message. Called with
446 * down\up\_read(&task->mm->mmap_sem).
448 * @param task Pointer to the target task_struct.
449 * @param dentry Pointer to the task dentry.
450 * @return Written data size on success, negative error code on error.
452 int proc_info_msg(struct task_struct *task, struct dentry *dentry)
454 char *buf, *payload, *buf_end;
457 buf = get_current_buf();
458 payload = pack_basic_msg_fmt(buf, MSG_PROC_INFO);
459 buf_end = pack_proc_info(payload, task, dentry);
461 set_len_msg(buf, buf_end);
463 ret = write_to_buffer(buf);
468 EXPORT_SYMBOL_GPL(proc_info_msg);
474 /* ============================================================================
475 * = PROCESS TERMINATE =
476 * ============================================================================
480 * @struct proc_terminate
481 * @brief Terminate message struct.
483 struct proc_terminate {
484 u32 pid; /**< Process ID */
487 static char *pack_proc_terminate(char *payload, struct task_struct *task)
489 struct proc_terminate *pt = (struct proc_terminate *)payload;
492 return payload + sizeof(*pt);
496 * @brief Packs and writes terminate message.
498 * @param task Target task_struct.
501 void terminate_msg(struct task_struct *task)
503 char *buf, *payload, *buf_end;
505 buf = get_current_buf();
506 payload = pack_basic_msg_fmt(buf, MSG_TERMINATE);
507 buf_end = pack_proc_terminate(payload, task);
509 set_len_msg(buf, buf_end);
511 write_to_buffer(buf);
514 EXPORT_SYMBOL_GPL(terminate_msg);
520 /* ============================================================================
522 * ============================================================================
527 * @brief Process mapping info.
530 u32 pid; /**< Process ID */
531 u64 low_addr; /**< Low address */
532 u64 high_addr; /**< High address */
533 char bin_path[0]; /**< Binary path */
536 static char *pack_proc_map(char *payload, struct vm_area_struct *vma)
538 struct proc_map *pm = (struct proc_map *)payload;
540 pm->pid = current->tgid;
541 pm->low_addr = vma->vm_start;
542 pm->high_addr = vma->vm_end;
544 return pack_path(pm->bin_path, vma->vm_file);
548 * @brief Packs and writes process map message.
550 * @param vma Target memory area.
553 void pcoc_map_msg(struct vm_area_struct *vma)
555 char *buf, *payload, *buf_end;
557 buf = get_current_buf();
558 payload = pack_basic_msg_fmt(buf, MSG_PROC_MAP);
559 buf_end = pack_proc_map(payload, vma);
561 set_len_msg(buf, buf_end);
563 write_to_buffer(buf);
566 EXPORT_SYMBOL_GPL(pcoc_map_msg);
572 /* ============================================================================
574 * ============================================================================
579 * @brief Process mapping info.
582 u32 pid; /**< Process ID */
583 u64 low_addr; /**< Low address */
584 u64 high_addr; /**< High address */
587 static char *pack_proc_unmap(char *payload, unsigned long start,
590 struct proc_unmap *pum = (struct proc_unmap *)payload;
592 pum->pid = current->tgid;
593 pum->low_addr = start;
594 pum->high_addr = end;
596 return payload + sizeof(*pum);
600 * @brief Packs and writes process unmap message.
602 * @param start Unmapping area low address.
603 * @param end Unmapping area high address.
606 void proc_unmap_msg(unsigned long start, unsigned long end)
608 char *buf, *payload, *buf_end;
610 buf = get_current_buf();
611 payload = pack_basic_msg_fmt(buf, MSG_PROC_UNMAP);
612 buf_end = pack_proc_unmap(payload, start, end);
614 set_len_msg(buf, buf_end);
616 write_to_buffer(buf);
619 EXPORT_SYMBOL_GPL(proc_unmap_msg);
625 /* ============================================================================
627 * ============================================================================
632 * @brief Comm message info.
635 u32 pid; /**< Process ID */
636 char comm[0]; /**< Comm */
639 static char *pack_proc_comm(char *data, struct task_struct *task)
641 struct proc_comm *pcomm = (struct proc_comm *)data;
643 pcomm->pid = task->tgid;
645 return pack_comm(pcomm->comm, task);
649 * @brief Packs and writes process comm message.
651 * @param task Target task_struct.
654 void proc_comm_msg(struct task_struct *task)
656 char *buf, *payload, *buf_end;
658 buf = get_current_buf();
659 payload = pack_basic_msg_fmt(buf, MSG_PROC_COMM);
660 buf_end = pack_proc_comm(payload, task);
662 set_len_msg(buf, buf_end);
664 write_to_buffer(buf);
667 EXPORT_SYMBOL_GPL(proc_comm_msg);
673 /* ============================================================================
675 * ============================================================================
680 * @brief Sampler event info.
683 u32 pid; /**< Process ID */
684 u64 pc_addr; /**< Instruction pointer address */
685 u32 tid; /**< Thread ID */
686 u32 cpu_num; /**< CPU number */
689 static char *pack_sample(char *payload, struct pt_regs *regs)
691 struct sample *s = (struct sample *)payload;
692 struct task_struct *task = current;
695 s->pc_addr = get_regs_ip(regs);
697 s->cpu_num = smp_processor_id();
699 return payload + sizeof(*s);
703 * @brief Packs and writes sample message.
705 * @param regs Pointer to CPU register data.
706 * @return Written data size on success, negative error code on error.
708 int sample_msg(struct pt_regs *regs)
710 char *buf, *payload, *buf_end;
713 buf = get_current_buf();
714 payload = pack_basic_msg_fmt(buf, MSG_SAMPLE);
715 buf_end = pack_sample(payload, regs);
717 set_len_msg(buf, buf_end);
719 ret = write_to_buffer(buf);
724 EXPORT_SYMBOL_GPL(sample_msg);
729 /* ============================================================================
731 * ============================================================================
735 * @struct msg_func_entry
736 * @brief Entry event info.
738 struct msg_func_entry {
739 u32 pid; /**< Process ID */
740 u32 tid; /**< Thread ID */
741 u16 probe_type; /**< Probe type */
742 u16 probe_sub_type; /**< Probe subtype */
743 u64 pc_addr; /**< Instruction pointer address. */
744 u64 caller_pc_addr; /**< Return address */
745 u32 cpu_num; /**< CPU number */
746 u32 cnt_args; /**< Count of args */
747 char args[0]; /**< Args format string */
750 static char *pack_msg_func_entry(char *payload, const char *fmt,
751 unsigned long func_addr, struct pt_regs *regs,
752 enum PROBE_TYPE pt, int sub_type)
754 struct msg_func_entry *mfe = (struct msg_func_entry *)payload;
755 struct task_struct *task = current;
757 mfe->pid = task->tgid;
758 mfe->tid = task->pid;
759 mfe->cpu_num = smp_processor_id();
760 mfe->pc_addr = func_addr;
761 mfe->caller_pc_addr = get_regs_ret_func(regs);
762 mfe->probe_type = pt;
763 mfe->probe_sub_type = sub_type;
764 mfe->cnt_args = strlen(fmt);
766 return payload + sizeof(*mfe);
769 static unsigned long get_arg(struct pt_regs *regs, unsigned long n)
771 return user_mode(regs) ?
772 swap_get_uarg(regs, n) : /* US argument */
773 swap_get_sarg(regs, n); /* sys_call argument */
776 static int pack_args(char *buf, int len, const char *fmt, struct pt_regs *regs)
781 int i, /* the index of the argument */
782 fmt_i, /* format index */
783 fmt_len; /* the number of parameters, in format */
785 fmt_len = strlen(fmt);
787 for (i = 0, fmt_i = 0; fmt_i < fmt_len; ++i, ++fmt_i) {
795 switch (fmt[fmt_i]) {
796 case 'b': /* 1 byte(bool) */
797 *buf = (char)!!get_arg(regs, i);
801 case 'c': /* 1 byte(char) */
802 *buf = (char)get_arg(regs, i);
806 case 'f': /* 4 byte(float) */
807 case 'd': /* 4 byte(int) */
810 tmp_u32 = (u32 *)buf;
811 *tmp_u32 = (u32)get_arg(regs, i);
815 case 'x': /* 8 byte(long) */
816 case 'p': /* 8 byte(pointer) */
819 tmp_u64 = (u64 *)buf;
820 *tmp_u64 = (u64)get_arg(regs, i);
824 case 'w': /* 8 byte(double) */
827 tmp_u64 = (u64 *)buf;
828 *tmp_u64 = get_arg(regs, i);
830 *tmp_u64 |= (u64)get_arg(regs, i) << 32;
834 case 's': /* string end with '\0' */
836 enum { max_str_len = 512 };
837 const char __user *user_s;
840 user_s = (const char __user *)get_arg(regs, i);
841 len_s = strnlen_user(user_s, max_str_len);
845 ret = strncpy_from_user(buf, user_s, len_s);
860 return buf - buf_old;
864 * @brief Packs and writes entry event message.
866 * @param fmt Arguments format string.
867 * @param func_addr Function address.
868 * @param regs CPU register data.
869 * @param pt Probe type.
870 * @param sub_type Probe sub type.
871 * @return Written data size on success, negative error code on error.
873 int entry_event(const char *fmt, unsigned long func_addr, struct pt_regs *regs,
874 enum PROBE_TYPE pt, int sub_type)
876 char *buf, *payload, *args, *buf_end;
879 buf = get_current_buf();
880 payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_ENTRY);
881 args = pack_msg_func_entry(payload, fmt, func_addr,
884 /* FIXME: len = 1024 */
885 ret = pack_args(args, 1024, fmt, regs);
887 printk(KERN_INFO "ERROR: !!!!!\n");
891 buf_end = args + ret;
893 set_len_msg(buf, buf_end);
895 ret = write_to_buffer(buf);
902 EXPORT_SYMBOL_GPL(entry_event);
908 /* ============================================================================
910 * ============================================================================
914 * @struct msg_func_exit
915 * @brief Exit event message info.
917 struct msg_func_exit {
920 u16 probe_type; /**< Probe type */
921 u16 probe_sub_type; /**< Probe subtype */
922 u64 pc_addr; /**< Instruction pointer */
923 u64 caller_pc_addr; /**< Return address */
924 u32 cpu_num; /**< CPU number */
925 char ret_val[0]; /**< Return value */
928 static int pack_msg_ret_val(char *buf, int len, char ret_type,
929 struct pt_regs *regs)
931 const char *buf_old = buf;
939 case 'b': /* 1 byte(bool) */
942 *buf = (char)!!get_regs_ret_val(regs);
945 case 'c': /* 1 byte(char) */
948 *buf = (char)get_regs_ret_val(regs);
951 case 'd': /* 4 byte(int) */
954 tmp_u32 = (u32 *)buf;
955 *tmp_u32 = get_regs_ret_val(regs);
958 case 'x': /* 8 byte(long) */
959 case 'p': /* 8 byte(pointer) */
962 tmp_u64 = (u64 *)buf;
963 *tmp_u64 = (u64)get_regs_ret_val(regs);
966 case 's': /* string end with '\0' */
968 enum { max_str_len = 512 };
969 const char __user *user_s;
972 user_s = (const char __user *)get_regs_ret_val(regs);
973 len_s = strnlen_user(user_s, max_str_len);
977 ret = strncpy_from_user(buf, user_s, len_s);
988 case 'f': /* 4 byte(float) */
991 tmp_u32 = (u32 *)buf;
992 *tmp_u32 = swap_get_urp_float(regs);
995 case 'w': /* 8 byte(double) */
998 tmp_u64 = (u64 *)buf;
999 *tmp_u64 = swap_get_urp_double(regs);
1006 return buf - buf_old;
1010 static int pack_msg_func_exit(char *buf, int len, char ret_type,
1011 struct pt_regs *regs, int pt, int sub_type,
1012 unsigned long func_addr, unsigned long ret_addr)
1014 struct msg_func_exit *mfe = (struct msg_func_exit *)buf;
1015 struct task_struct *task = current;
1018 mfe->pid = task->tgid;
1019 mfe->tid = task->pid;
1020 mfe->probe_type = pt;
1021 mfe->probe_sub_type = sub_type;
1022 mfe->cpu_num = smp_processor_id();
1023 mfe->pc_addr = func_addr;
1024 mfe->caller_pc_addr = ret_addr;
1026 ret = pack_msg_ret_val(mfe->ret_val, len, ret_type, regs);
1028 printk(KERN_INFO "ERROR: packing MSG_FUNCTION_EXIT (ret=%d)\n",
1033 return sizeof(*mfe) + ret;
1037 * @brief Packs and writes exit event.
1039 * @param ret_type Return value type.
1040 * @param regs CPU register data.
1041 * @param sub_type Event subtype.
1042 * @param func_addr Function address.
1043 * @param ret_addr Return address.
1044 * @return Written data size on success, negative error code on error.
1046 int exit_event(char ret_type, struct pt_regs *regs, int pt, int sub_type,
1047 unsigned long func_addr, unsigned long ret_addr)
1049 char *buf, *payload, *buf_end;
1052 buf = get_current_buf();
1053 payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_EXIT);
1054 /* FIXME: len=1024 */
1055 ret = pack_msg_func_exit(payload, 1024, ret_type, regs, pt, sub_type,
1056 func_addr, ret_addr);
1060 buf_end = payload + ret;
1061 set_len_msg(buf, buf_end);
1063 ret = write_to_buffer(buf);
1070 EXPORT_SYMBOL_GPL(exit_event);
1076 /* ============================================================================
1077 * = CONTEXT SWITCH =
1078 * ============================================================================
1082 * @struct msg_context_switch
1083 * @brief Context switch message info.
1085 struct msg_context_switch {
1086 u64 pc_addr; /**< Instruction pointer */
1087 u32 pid; /**< PID */
1088 u32 tid; /**< TID */
1089 u32 cpu_num; /**< CPU number */
1092 static char *pack_msg_context_switch(char *payload, struct pt_regs *regs)
1094 struct msg_context_switch *mcs = (struct msg_context_switch *)payload;
1095 struct task_struct *task = current;
1098 mcs->pid = task->tgid;
1099 mcs->tid = task->pid;
1100 mcs->cpu_num = smp_processor_id();
1102 return payload + sizeof(*mcs);
1105 static int context_switch(struct pt_regs *regs, enum MSG_ID id)
1107 char *buf, *payload, *buf_end;
1110 buf = get_current_buf();
1111 payload = pack_basic_msg_fmt(buf, id);
1112 buf_end = pack_msg_context_switch(payload, regs);
1113 set_len_msg(buf, buf_end);
1115 ret = write_to_buffer(buf);
1122 * @brief Packs and writes context switch entry message.
1124 * @param regs CPU register data.
1125 * @return Written data size on success, negative error code on error.
1127 int switch_entry(struct pt_regs *regs)
1129 return context_switch(regs, MSG_CONTEXT_SWITCH_ENTRY);
1131 EXPORT_SYMBOL_GPL(switch_entry);
1134 * @brief Packs and writes context switch exit message.
1136 * @param regs CPU register data.
1137 * @return Written data size on success, negative error code on error.
1139 int switch_exit(struct pt_regs *regs)
1141 return context_switch(regs, MSG_CONTEXT_SWITCH_EXIT);
1143 EXPORT_SYMBOL_GPL(switch_exit);
1148 /* ============================================================================
1150 * ============================================================================
1155 * @brief Error message info.
1158 char msg[0]; /**< Error message string */
1161 static char *pack_msg_err(char *payload, const char *fmt, va_list args)
1163 struct msg_err *me = (struct msg_err *)payload;
1166 ret = vsprintf(me->msg, fmt, args);
1170 return payload + sizeof(*me) + ret + 1;
1174 * @brief Packs and writes error message.
1176 * @param fmt Error string format
1177 * @return Written data size on success, negative error code on error.
1179 int error_msg(const char *fmt, ...)
1181 char *buf, *payload, *buf_end;
1185 buf = get_current_buf();
1186 payload = pack_basic_msg_fmt(buf, MSG_ERROR);
1188 va_start(args, fmt);
1189 buf_end = pack_msg_err(payload, fmt, args);
1192 set_len_msg(buf, buf_end);
1194 ret = write_to_buffer(buf);
1199 EXPORT_SYMBOL_GPL(error_msg);
1205 /* ============================================================================
1206 * = MESSAGES FROM USER SPACE =
1207 * ============================================================================
1211 * @brief Interface for writing messages from user space directly.
1213 * @param buf Pointer to message.
1214 * @param len Message len.
1217 int raw_msg(char *buf, size_t len)
1219 struct basic_msg_fmt *bmf = (struct basic_msg_fmt *)buf;
1221 if (sizeof(*bmf) > len)
1224 if (bmf->len + sizeof(*bmf) != len)
1228 write_to_buffer(buf);
1235 /* ============================================================================
1237 * ============================================================================
1240 static int pack_custom_event(char *buf, int len, const char *fmt, va_list args)
1242 enum { max_str_len = 512 };
1244 char *buf_orig = buf;
1246 for (p = fmt; *p != '\0'; p++) {
1257 case 'b': /* 1 byte(bool) */
1260 *buf = !!(char)va_arg(args, int);
1264 case 'c': /* 1 byte(char) */
1267 *buf = (char)va_arg(args, int);
1271 case 'f': /* 4 byte(float) */
1272 case 'd': /* 4 byte(int) */
1275 *(u32 *)buf = va_arg(args, u32);
1279 case 'x': /* 8 byte(long) */
1280 case 'w': /* 8 byte(double) */
1283 *(u64 *)buf = va_arg(args, u64);
1287 case 'p': /* 8 byte(pointer) */
1290 *(u64 *)buf = va_arg(args, unsigned long);
1294 case 's': /* userspace string with '\0' terminating byte */
1296 const char __user *str;
1299 str = va_arg(args, const char __user *);
1300 /* strnlen_user includes '\0' in its return value */
1301 len_s = strnlen_user(str, max_str_len);
1304 /* strncpy_from_user returns the length of the copied
1305 * string (without '\0') */
1306 n = strncpy_from_user(buf, str, len_s - 1);
1315 case 'S': /* kernelspace string with '\0' terminating byte */
1320 str = va_arg(args, const char *);
1321 len_s = strnlen(str, max_str_len);
1322 if (len < len_s + 1) /* + '\0' */
1324 strncpy(buf, str, len_s);
1331 case 'a': /* userspace byte array (len + ptr) */
1333 const void __user *ptr;
1336 len_p = va_arg(args, u32);
1337 if (len < sizeof(len_p) + len_p)
1339 *(u32 *)buf = len_p;
1340 buf += sizeof(len_p);
1341 len -= sizeof(len_p);
1343 ptr = va_arg(args, const void __user *);
1344 n = copy_from_user(buf, ptr, len_p);
1351 case 'A': /* kernelspace byte array (len + ptr) */
1357 len_p = va_arg(args, u32);
1358 if (len < sizeof(len_p) + len_p)
1360 *(u32 *)buf = len_p;
1361 buf += sizeof(len_p);
1362 len -= sizeof(len_p);
1365 ptr = va_arg(args, const void *);
1366 memcpy(buf, ptr, len_p);
1376 return buf - buf_orig;
1379 enum { max_custom_event_size = 2048 };
1382 * @brief Packs and writes custom entry event.
1384 * @param func_addr Function address.
1385 * @param regs CPU register data.
1386 * @param type Probe type.
1387 * @param sub_type Probe sub type.
1388 * @param fmt Format string.
1389 * @return Written data size on success, negative error code on error.
1391 int custom_entry_event(unsigned long func_addr, struct pt_regs *regs,
1392 int pt, int sub_type, const char *fmt, ...)
1394 char *buf, *payload, *args, *buf_end;
1398 buf = get_current_buf();
1399 payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_ENTRY);
1400 args = pack_msg_func_entry(payload, fmt, func_addr,
1401 regs, pt, sub_type);
1403 va_start(vargs, fmt);
1404 ret = pack_custom_event(args, max_custom_event_size, fmt, vargs);
1410 buf_end = args + ret;
1411 set_len_msg(buf, buf_end);
1412 ret = write_to_buffer(buf);
1419 EXPORT_SYMBOL_GPL(custom_entry_event);
1421 /* TODO currently this function is a simple wrapper. it will be refactored when
1422 * protocol changes are applied */
1425 * @brief Packs and writes custom exit event.
1427 * @param func_addr Function address.
1428 * @param ret_addr Return address.
1429 * @param regs CPU register data.
1430 * @param fmt Format string.
1431 * @return Written data size on success, negative error code on error.
1433 int custom_exit_event(unsigned long func_addr, unsigned long ret_addr,
1434 struct pt_regs *regs, int pt, int sub_type,
1435 const char *fmt, ...)
1437 char *buf, *payload, *buf_end;
1440 buf = get_current_buf();
1441 payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_EXIT);
1442 ret = pack_msg_func_exit(payload, max_custom_event_size,
1443 fmt[0], regs, pt, sub_type,
1444 func_addr, ret_addr);
1448 buf_end = payload + ret;
1449 set_len_msg(buf, buf_end);
1451 ret = write_to_buffer(buf);
1458 EXPORT_SYMBOL_GPL(custom_exit_event);
1460 SWAP_LIGHT_INIT_MODULE(NULL, event_filter_init, event_filter_exit,
1461 init_debugfs_writer, exit_debugfs_writer);
1463 MODULE_LICENSE("GPL");
1464 MODULE_DESCRIPTION("SWAP Writer module");
1465 MODULE_AUTHOR("Cherkashin V., Aksenov A.S.");