1 #include <linux/debugfs.h> 2 #include <linux/module.h> 3 #include <linux/seq_file.h> 4 #include <asm/pgtable.h> 5 6 static int ptdump_show(struct seq_file *m, void *v) 7 { 8 ptdump_walk_pgd_level_debugfs(m, NULL, false); 9 return 0; 10 } 11 12 static int ptdump_open(struct inode *inode, struct file *filp) 13 { 14 return single_open(filp, ptdump_show, NULL); 15 } 16 17 static const struct file_operations ptdump_fops = { 18 .owner = THIS_MODULE, 19 .open = ptdump_open, 20 .read = seq_read, 21 .llseek = seq_lseek, 22 .release = single_release, 23 }; 24 25 static int ptdump_show_curknl(struct seq_file *m, void *v) 26 { 27 if (current->mm->pgd) { 28 down_read(¤t->mm->mmap_sem); 29 ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, false); 30 up_read(¤t->mm->mmap_sem); 31 } 32 return 0; 33 } 34 35 static int ptdump_open_curknl(struct inode *inode, struct file *filp) 36 { 37 return single_open(filp, ptdump_show_curknl, NULL); 38 } 39 40 static const struct file_operations ptdump_curknl_fops = { 41 .owner = THIS_MODULE, 42 .open = ptdump_open_curknl, 43 .read = seq_read, 44 .llseek = seq_lseek, 45 .release = single_release, 46 }; 47 48 #ifdef CONFIG_PAGE_TABLE_ISOLATION 49 static struct dentry *pe_curusr; 50 51 static int ptdump_show_curusr(struct seq_file *m, void *v) 52 { 53 if (current->mm->pgd) { 54 down_read(¤t->mm->mmap_sem); 55 ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, true); 56 up_read(¤t->mm->mmap_sem); 57 } 58 return 0; 59 } 60 61 static int ptdump_open_curusr(struct inode *inode, struct file *filp) 62 { 63 return single_open(filp, ptdump_show_curusr, NULL); 64 } 65 66 static const struct file_operations ptdump_curusr_fops = { 67 .owner = THIS_MODULE, 68 .open = ptdump_open_curusr, 69 .read = seq_read, 70 .llseek = seq_lseek, 71 .release = single_release, 72 }; 73 #endif 74 75 static struct dentry *dir, *pe_knl, *pe_curknl; 76 77 static int __init pt_dump_debug_init(void) 78 { 79 dir = debugfs_create_dir("page_tables", NULL); 80 if (!dir) 81 return -ENOMEM; 82 83 pe_knl = debugfs_create_file("kernel", 0400, dir, NULL, 84 &ptdump_fops); 85 if (!pe_knl) 86 goto err; 87 88 pe_curknl = debugfs_create_file("current_kernel", 0400, 89 dir, NULL, &ptdump_curknl_fops); 90 if (!pe_curknl) 91 goto err; 92 93 #ifdef CONFIG_PAGE_TABLE_ISOLATION 94 pe_curusr = debugfs_create_file("current_user", 0400, 95 dir, NULL, &ptdump_curusr_fops); 96 if (!pe_curusr) 97 goto err; 98 #endif 99 return 0; 100 err: 101 debugfs_remove_recursive(dir); 102 return -ENOMEM; 103 } 104 105 static void __exit pt_dump_debug_exit(void) 106 { 107 debugfs_remove_recursive(dir); 108 } 109 110 module_init(pt_dump_debug_init); 111 module_exit(pt_dump_debug_exit); 112 MODULE_LICENSE("GPL"); 113 MODULE_AUTHOR("Arjan van de Ven <arjan@linux.intel.com>"); 114 MODULE_DESCRIPTION("Kernel debugging helper that dumps pagetables"); 115