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