2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 * Copyright (C) Samsung Electronics, 2015
18 * 2015 Vyacheslav Cherkashin <v.cherkashin@samsung.com>
24 #include <linux/stat.h>
25 #include <linux/sched.h>
26 #include <linux/dcache.h>
27 #include <linux/fdtable.h>
28 #include <writer/swap_msg.h>
29 #include <us_manager/sspt/sspt.h> /* ... check_vma() */
32 #define USM_PREFIX KERN_INFO "[USM] "
35 static struct files_struct *(*swap_get_files_struct)(struct task_struct *);
36 static void (*swap_put_files_struct)(struct files_struct *fs);
38 int usm_msg_once(void)
42 sym = "get_files_struct";
43 swap_get_files_struct = (void *)swap_ksyms(sym);
44 if (swap_get_files_struct == NULL)
47 sym = "put_files_struct";
48 swap_put_files_struct = (void *)swap_ksyms(sym);
49 if (swap_put_files_struct == NULL)
55 printk("ERROR: symbol '%s' not found\n", sym);
69 static void kmem_info_fill(struct kmem_info *info, struct mm_struct *mm)
71 #if defined(CONFIG_ARM)
72 info->name = "[vectors]";
73 info->start = CONFIG_VECTORS_BASE;
74 info->end = CONFIG_VECTORS_BASE + PAGE_SIZE;
75 #elif defined(CONFIG_X86_32)
77 struct vm_area_struct *vma_vdso;
79 vdso = (unsigned long)mm->context.vdso;
80 vma_vdso = find_vma_intersection(mm, vdso, vdso + 1);
82 info->name = "[vdso]";
83 info->start = vma_vdso->vm_start;
84 info->end = vma_vdso->vm_end;
86 printk(USM_PREFIX "Cannot get VDSO mapping\n");
92 #endif /* CONFIG_arch */
96 static int pack_path(void *data, size_t size, struct file *file)
98 enum { TMP_BUF_LEN = 512 };
99 char tmp_buf[TMP_BUF_LEN];
100 const char NA[] = "N/A";
101 const char *filename;
102 size_t len = sizeof(NA);
109 path_get(&file->f_path);
110 filename = d_path(&file->f_path, tmp_buf, TMP_BUF_LEN);
111 path_put(&file->f_path);
113 if (IS_ERR_OR_NULL(filename)) {
118 len = strlen(filename) + 1;
124 memcpy(data, filename, len);
132 /* ============================================================================
133 * = MSG_PROCESS_INFO =
134 * ============================================================================
136 struct proc_info_top {
141 struct proc_info_bottom {
155 static int pack_lib_obj(void *data, size_t size, struct vm_area_struct *vma)
158 struct lib_obj *obj = (struct lib_obj *)data;
160 if (size < sizeof(*obj))
163 obj->low_addr = vma->vm_start;
164 obj->high_addr = vma->vm_end;
165 size -= sizeof(*obj);
167 ret = pack_path(obj->lib_path, size, vma->vm_file);
171 return ret + sizeof(*obj);
174 static int pack_shared_kmem(void *data, size_t size, struct mm_struct *mm)
176 struct lib_obj *obj = (struct lib_obj *)data;
177 struct kmem_info info;
178 size_t name_len, obj_size;
180 if (size < sizeof(*obj))
183 kmem_info_fill(&info, mm);
185 if (info.name == NULL)
188 obj->low_addr = (u64)info.start;
189 obj->high_addr = (u64)info.end;
191 name_len = strlen(info.name) + 1;
192 obj_size = sizeof(*obj) + name_len;
196 memcpy(obj->lib_path, info.name, name_len);
201 static int pack_libs(void *data, size_t size, struct mm_struct *mm)
204 struct vm_area_struct *vma;
205 u32 *lib_cnt = (u32 *)data;
206 const size_t old_size = size;
208 if (size < sizeof(*lib_cnt))
211 /* packing libraries count */
213 data += sizeof(*lib_cnt);
214 size -= sizeof(*lib_cnt);
216 /* packing libraries */
217 for (vma = mm->mmap; vma; vma = vma->vm_next) {
218 if (check_vma(vma)) {
219 ret = pack_lib_obj(data, size, vma);
229 /* packing shared kernel memory */
230 ret = pack_shared_kmem(data, size, mm);
237 return old_size - size;
240 static struct vm_area_struct *find_vma_exe_by_dentry(struct mm_struct *mm,
241 struct dentry *dentry)
243 struct vm_area_struct *vma;
245 for (vma = mm->mmap; vma; vma = vma->vm_next) {
246 if (vma->vm_file && (vma->vm_flags & VM_EXEC) &&
247 (vma->vm_file->f_dentry == dentry))
257 static int pack_proc_info_top(void *data, size_t size,
258 struct task_struct *task)
260 struct proc_info_top *pit = (struct proc_info_top *)data;
262 if (size < sizeof(*pit) + sizeof(task->comm))
265 pit->pid = task->tgid;
266 get_task_comm(pit->comm, task);
268 return sizeof(*pit) + strlen(pit->comm) + 1;
271 static int pack_proc_info_bottom(void *data, size_t size,
272 struct task_struct *task,
273 struct dentry *dentry)
275 struct proc_info_bottom *pib = (struct proc_info_bottom *)data;
276 struct vm_area_struct *vma = find_vma_exe_by_dentry(task->mm, dentry);
277 struct timespec boot_time;
278 struct timespec start_time;
281 if (size < sizeof(*pib))
284 getboottime(&boot_time);
285 start_time = timespec_add(boot_time, task->real_start_time);
287 pib->ppid = task->real_parent->tgid;
288 pib->start_time = swap_msg_spec2time(&start_time);
291 pib->low_addr = vma->vm_start;
292 pib->high_addr = vma->vm_end;
293 ret = pack_path(pib->bin_path, size, vma->vm_file);
297 ret = pack_path(pib->bin_path, size, NULL);
303 return sizeof(*pib) + ret;
306 static int pack_proc_info(void *data, size_t size, struct task_struct *task,
307 struct dentry *dentry)
310 const size_t old_size = size;
312 ret = pack_proc_info_top(data, size, task);
319 ret = pack_proc_info_bottom(data, size, task, dentry);
326 ret = pack_libs(data, size, task->mm);
330 return old_size - size + ret;
333 /* Called with down\up\_read(&task->mm->mmap_sem). */
334 void usm_msg_info(struct task_struct *task, struct dentry *dentry)
341 m = swap_msg_get(MSG_PROC_INFO);
342 p = swap_msg_payload(m);
343 size = swap_msg_size(m);
345 ret = pack_proc_info(p, size, task, dentry);
347 printk(USM_PREFIX "ERROR: message process info packing, "
352 swap_msg_flush(m, ret);
362 /* ============================================================================
364 * ============================================================================
366 struct proc_terminate {
370 void usm_msg_term(struct task_struct *task)
373 struct proc_terminate *term;
375 m = swap_msg_get(MSG_TERMINATE);
377 term = swap_msg_payload(m);
378 term->pid = task->pid;
380 swap_msg_flush(m, sizeof(*term));
388 /* ============================================================================
389 * = MSG_PROCESS_MAP =
390 * ============================================================================
399 static int pack_proc_map(void *data, size_t size, struct vm_area_struct *vma)
401 struct proc_map *map = (struct proc_map *)data;
404 map->pid = current->tgid;
405 map->low_addr = vma->vm_start;
406 map->high_addr = vma->vm_end;
408 ret = pack_path(map->bin_path, size - sizeof(*map), vma->vm_file);
412 return ret + sizeof(*map);
415 void usm_msg_map(struct vm_area_struct *vma)
422 m = swap_msg_get(MSG_PROC_MAP);
423 p = swap_msg_payload(m);
424 size = swap_msg_size(m);
426 ret = pack_proc_map(p, size, vma);
428 printk(USM_PREFIX "ERROR: message process mapping packing, "
433 swap_msg_flush(m, ret);
443 /* ============================================================================
444 * = MSG_PROCESS_UNMAP =
445 * ============================================================================
453 void usm_msg_unmap(unsigned long start, unsigned long end)
456 struct proc_unmap *unmap;
458 m = swap_msg_get(MSG_PROC_UNMAP);
460 unmap = swap_msg_payload(m);
461 unmap->pid = current->tgid;
462 unmap->low_addr = (u64)start;
463 unmap->high_addr = (u64)end;
465 swap_msg_flush(m, sizeof(*unmap));
473 /* ============================================================================
474 * = MSG_PROCESS_COMM =
475 * ============================================================================
482 void usm_msg_comm(struct task_struct *task)
487 m = swap_msg_get(MSG_PROC_COMM);
489 c = swap_msg_payload(m);
491 get_task_comm(c->comm, task);
493 swap_msg_flush(m, sizeof(*c) + strlen(c->comm) + 1);
501 /* ============================================================================
502 * = MSG_PROCESS_STATUS_INFO =
503 * ============================================================================
511 static int pack_ofile(void *data, size_t size, int fd, struct file *file,
517 if (size < sizeof(*ofile))
520 ofile = (struct ofile *)data;
522 ofile->size = (u64)fsize;
524 ret = pack_path(ofile->path, size - sizeof(*ofile), file);
528 return sizeof(*ofile) + ret;
531 static int pack_status_info(void *data, size_t size, struct task_struct *task)
535 struct files_struct *files;
536 const size_t old_size = size;
538 files = swap_get_files_struct(task);
543 *((u32 *)data) = (u32)task->tgid;
547 /* pack file count */
548 file_cnt = (u32 *)data;
555 for (fd = 0; fd < files_fdtable(files)->max_fds; ++fd) {
560 file = fcheck_files(files, fd);
564 inode = file->f_path.dentry->d_inode;
565 /* check inode and if it is a regular file */
566 if (inode == NULL || !S_ISREG(inode->i_mode))
569 fsize = inode->i_size;
572 ret = pack_ofile(data, size, fd, file, fsize);
583 ret = old_size - size;
586 swap_put_files_struct(files);
590 void usm_msg_status_info(struct task_struct *task)
597 m = swap_msg_get(MSG_PROCESS_STATUS_INFO);
599 data = swap_msg_payload(m);
600 size = swap_msg_size(m);
601 ret = pack_status_info(data, size, task);
603 printk(USM_PREFIX "ERROR: MSG_PROCESS_STATUS_INFO "
604 "packing, ret=%d\n", ret);
608 swap_msg_flush(m, ret);