1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * mm/memtrace_ashmem.c
4 *
5 * Copyright (c) 2022 Huawei Technologies Co., Ltd.
6 */
7 #include <linux/fs.h>
8 #include <linux/proc_fs.h>
9 #include <linux/seq_file.h>
10 #include <linux/fdtable.h>
11 #include <linux/sched/task.h>
12 #include <linux/sched/signal.h>
13 #include <linux/memcheck.h>
14 #include "../drivers/staging/android/ashmem.h"
15
16 static int ashmem_debug_process_info_open(struct inode *inode,
17 struct file *file);
18
19 struct ashmem_debug_process_info_args {
20 struct seq_file *seq;
21 struct task_struct *tsk;
22 };
23
24 static const struct proc_ops debug_process_ashmem_info_fops = {
25 .proc_open = ashmem_debug_process_info_open,
26 .proc_read = seq_read,
27 .proc_lseek = seq_lseek,
28 .proc_release = single_release,
29 };
30
ashmem_debug_process_info_cb(const void * data,struct file * f,unsigned int fd)31 static int ashmem_debug_process_info_cb(const void *data,
32 struct file *f, unsigned int fd)
33 {
34 const struct ashmem_debug_process_info_args *args = data;
35 struct task_struct *tsk = args->tsk;
36
37 if (!is_ashmem_file(f))
38 return 0;
39 seq_printf(args->seq,
40 "%s %u %u %s %zu\n",
41 tsk->comm, tsk->pid, fd,
42 get_ashmem_name_by_file(f),
43 get_ashmem_size_by_file(f));
44 return 0;
45 }
46
ashmem_debug_process_info_show(struct seq_file * s,void * d)47 static int ashmem_debug_process_info_show(struct seq_file *s, void *d)
48 {
49 struct task_struct *tsk = NULL;
50 struct ashmem_debug_process_info_args cb_args;
51
52 seq_puts(s, "Process ashmem detail info:\n");
53 seq_puts(s, "----------------------------------------------------\n");
54 seq_printf(s, "%s %s %s %s %s\n",
55 "Process name", "Process ID",
56 "fd", "ashmem_name", "size");
57
58 ashmem_mutex_lock();
59 rcu_read_lock();
60 for_each_process(tsk) {
61 if (tsk->flags & PF_KTHREAD)
62 continue;
63 cb_args.seq = s;
64 cb_args.tsk = tsk;
65
66 task_lock(tsk);
67 iterate_fd(tsk->files, 0,
68 ashmem_debug_process_info_cb, (void *)&cb_args);
69 task_unlock(tsk);
70 }
71 rcu_read_unlock();
72 ashmem_mutex_unlock();
73 seq_puts(s, "----------------------------------------------------\n");
74 return 0;
75 }
76
ashmem_debug_process_info_open(struct inode * inode,struct file * file)77 static int ashmem_debug_process_info_open(struct inode *inode,
78 struct file *file)
79 {
80 return single_open(file, ashmem_debug_process_info_show,
81 inode->i_private);
82 }
83
init_ashmem_process_info(void)84 void init_ashmem_process_info(void)
85 {
86 struct proc_dir_entry *entry = NULL;
87
88 entry = proc_create_data("ashmem_process_info", 0444,
89 NULL, &debug_process_ashmem_info_fops, NULL);
90 if (!entry)
91 pr_err("Failed to create ashmem debug info\n");
92 }
93
94