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