18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * mm/memtrace_ashmem.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2022 Huawei Technologies Co., Ltd. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci#include <linux/fs.h> 88c2ecf20Sopenharmony_ci#include <linux/proc_fs.h> 98c2ecf20Sopenharmony_ci#include <linux/seq_file.h> 108c2ecf20Sopenharmony_ci#include <linux/fdtable.h> 118c2ecf20Sopenharmony_ci#include <linux/sched/task.h> 128c2ecf20Sopenharmony_ci#include <linux/sched/signal.h> 138c2ecf20Sopenharmony_ci#include <linux/memcheck.h> 148c2ecf20Sopenharmony_ci#include "../drivers/staging/android/ashmem.h" 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cistatic int ashmem_debug_process_info_open(struct inode *inode, 178c2ecf20Sopenharmony_ci struct file *file); 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistruct ashmem_debug_process_info_args { 208c2ecf20Sopenharmony_ci struct seq_file *seq; 218c2ecf20Sopenharmony_ci struct task_struct *tsk; 228c2ecf20Sopenharmony_ci}; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_cistatic const struct proc_ops debug_process_ashmem_info_fops = { 258c2ecf20Sopenharmony_ci .proc_open = ashmem_debug_process_info_open, 268c2ecf20Sopenharmony_ci .proc_read = seq_read, 278c2ecf20Sopenharmony_ci .proc_lseek = seq_lseek, 288c2ecf20Sopenharmony_ci .proc_release = single_release, 298c2ecf20Sopenharmony_ci}; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cistatic int ashmem_debug_process_info_cb(const void *data, 328c2ecf20Sopenharmony_ci struct file *f, unsigned int fd) 338c2ecf20Sopenharmony_ci{ 348c2ecf20Sopenharmony_ci const struct ashmem_debug_process_info_args *args = data; 358c2ecf20Sopenharmony_ci struct task_struct *tsk = args->tsk; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci if (!is_ashmem_file(f)) 388c2ecf20Sopenharmony_ci return 0; 398c2ecf20Sopenharmony_ci seq_printf(args->seq, 408c2ecf20Sopenharmony_ci "%s %u %u %s %zu\n", 418c2ecf20Sopenharmony_ci tsk->comm, tsk->pid, fd, 428c2ecf20Sopenharmony_ci get_ashmem_name_by_file(f), 438c2ecf20Sopenharmony_ci get_ashmem_size_by_file(f)); 448c2ecf20Sopenharmony_ci return 0; 458c2ecf20Sopenharmony_ci} 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic int ashmem_debug_process_info_show(struct seq_file *s, void *d) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci struct task_struct *tsk = NULL; 508c2ecf20Sopenharmony_ci struct ashmem_debug_process_info_args cb_args; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci seq_puts(s, "Process ashmem detail info:\n"); 538c2ecf20Sopenharmony_ci seq_puts(s, "----------------------------------------------------\n"); 548c2ecf20Sopenharmony_ci seq_printf(s, "%s %s %s %s %s\n", 558c2ecf20Sopenharmony_ci "Process name", "Process ID", 568c2ecf20Sopenharmony_ci "fd", "ashmem_name", "size"); 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci ashmem_mutex_lock(); 598c2ecf20Sopenharmony_ci rcu_read_lock(); 608c2ecf20Sopenharmony_ci for_each_process(tsk) { 618c2ecf20Sopenharmony_ci if (tsk->flags & PF_KTHREAD) 628c2ecf20Sopenharmony_ci continue; 638c2ecf20Sopenharmony_ci cb_args.seq = s; 648c2ecf20Sopenharmony_ci cb_args.tsk = tsk; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci task_lock(tsk); 678c2ecf20Sopenharmony_ci iterate_fd(tsk->files, 0, 688c2ecf20Sopenharmony_ci ashmem_debug_process_info_cb, (void *)&cb_args); 698c2ecf20Sopenharmony_ci task_unlock(tsk); 708c2ecf20Sopenharmony_ci } 718c2ecf20Sopenharmony_ci rcu_read_unlock(); 728c2ecf20Sopenharmony_ci ashmem_mutex_unlock(); 738c2ecf20Sopenharmony_ci seq_puts(s, "----------------------------------------------------\n"); 748c2ecf20Sopenharmony_ci return 0; 758c2ecf20Sopenharmony_ci} 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_cistatic int ashmem_debug_process_info_open(struct inode *inode, 788c2ecf20Sopenharmony_ci struct file *file) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci return single_open(file, ashmem_debug_process_info_show, 818c2ecf20Sopenharmony_ci inode->i_private); 828c2ecf20Sopenharmony_ci} 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_civoid init_ashmem_process_info(void) 858c2ecf20Sopenharmony_ci{ 868c2ecf20Sopenharmony_ci struct proc_dir_entry *entry = NULL; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci entry = proc_create_data("ashmem_process_info", 0444, 898c2ecf20Sopenharmony_ci NULL, &debug_process_ashmem_info_fops, NULL); 908c2ecf20Sopenharmony_ci if (!entry) 918c2ecf20Sopenharmony_ci pr_err("Failed to create ashmem debug info\n"); 928c2ecf20Sopenharmony_ci} 938c2ecf20Sopenharmony_ci 94