1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: Thomas Gleixner <tglx@linutronix.de>
3 Date: Mon, 4 Dec 2017 15:08:06 +0100
4 Subject: [PATCH] x86/mm/dump_pagetables: Allow dumping current pagetables
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
11 Add two debugfs files which allow to dump the pagetable of the current
14 current_kernel dumps the regular page table. This is the page table which
15 is normally shared between kernel and user space. If kernel page table
16 isolation is enabled this is the kernel space mapping.
18 If kernel page table isolation is enabled the second file, current_user,
19 dumps the user space page table.
21 These files allow to verify the resulting page tables for page table
22 isolation, but even in the normal case its useful to be able to inspect
23 user space page tables of current for debugging purposes.
25 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
26 Cc: Andy Lutomirski <luto@kernel.org>
27 Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
28 Cc: Borislav Petkov <bp@alien8.de>
29 Cc: Brian Gerst <brgerst@gmail.com>
30 Cc: Dave Hansen <dave.hansen@linux.intel.com>
31 Cc: David Laight <David.Laight@aculab.com>
32 Cc: Denys Vlasenko <dvlasenk@redhat.com>
33 Cc: Eduardo Valentin <eduval@amazon.com>
34 Cc: Greg KH <gregkh@linuxfoundation.org>
35 Cc: H. Peter Anvin <hpa@zytor.com>
36 Cc: Josh Poimboeuf <jpoimboe@redhat.com>
37 Cc: Juergen Gross <jgross@suse.com>
38 Cc: Linus Torvalds <torvalds@linux-foundation.org>
39 Cc: Peter Zijlstra <peterz@infradead.org>
40 Cc: Will Deacon <will.deacon@arm.com>
41 Cc: aliguori@amazon.com
42 Cc: daniel.gruss@iaik.tugraz.at
44 Cc: keescook@google.com
45 Cc: linux-mm@kvack.org
46 Signed-off-by: Ingo Molnar <mingo@kernel.org>
47 (cherry picked from commit a4b51ef6552c704764684cef7e753162dc87c5fa)
48 Signed-off-by: Andy Whitcroft <apw@canonical.com>
49 Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
50 (cherry picked from commit e31e0526cb47bd1d848fc3fdb10d2aeb909e46b5)
51 Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
53 arch/x86/include/asm/pgtable.h | 2 +-
54 arch/x86/mm/debug_pagetables.c | 71 +++++++++++++++++++++++++++++++++++++++---
55 arch/x86/mm/dump_pagetables.c | 6 +++-
56 3 files changed, 73 insertions(+), 6 deletions(-)
58 diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
59 index 4f5eb81cf8be..1f9e7fea3c06 100644
60 --- a/arch/x86/include/asm/pgtable.h
61 +++ b/arch/x86/include/asm/pgtable.h
63 #include <asm/x86_init.h>
65 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
66 -void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
67 +void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd, bool user);
68 void ptdump_walk_pgd_level_checkwx(void);
70 #ifdef CONFIG_DEBUG_WX
71 diff --git a/arch/x86/mm/debug_pagetables.c b/arch/x86/mm/debug_pagetables.c
72 index 8e70c1599e51..421f2664ffa0 100644
73 --- a/arch/x86/mm/debug_pagetables.c
74 +++ b/arch/x86/mm/debug_pagetables.c
77 static int ptdump_show(struct seq_file *m, void *v)
79 - ptdump_walk_pgd_level_debugfs(m, NULL);
80 + ptdump_walk_pgd_level_debugfs(m, NULL, false);
84 @@ -22,7 +22,57 @@ static const struct file_operations ptdump_fops = {
85 .release = single_release,
88 -static struct dentry *dir, *pe;
89 +static int ptdump_show_curknl(struct seq_file *m, void *v)
91 + if (current->mm->pgd) {
92 + down_read(¤t->mm->mmap_sem);
93 + ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, false);
94 + up_read(¤t->mm->mmap_sem);
99 +static int ptdump_open_curknl(struct inode *inode, struct file *filp)
101 + return single_open(filp, ptdump_show_curknl, NULL);
104 +static const struct file_operations ptdump_curknl_fops = {
105 + .owner = THIS_MODULE,
106 + .open = ptdump_open_curknl,
108 + .llseek = seq_lseek,
109 + .release = single_release,
112 +#ifdef CONFIG_PAGE_TABLE_ISOLATION
113 +static struct dentry *pe_curusr;
115 +static int ptdump_show_curusr(struct seq_file *m, void *v)
117 + if (current->mm->pgd) {
118 + down_read(¤t->mm->mmap_sem);
119 + ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, true);
120 + up_read(¤t->mm->mmap_sem);
125 +static int ptdump_open_curusr(struct inode *inode, struct file *filp)
127 + return single_open(filp, ptdump_show_curusr, NULL);
130 +static const struct file_operations ptdump_curusr_fops = {
131 + .owner = THIS_MODULE,
132 + .open = ptdump_open_curusr,
134 + .llseek = seq_lseek,
135 + .release = single_release,
139 +static struct dentry *dir, *pe_knl, *pe_curknl;
141 static int __init pt_dump_debug_init(void)
143 @@ -30,9 +80,22 @@ static int __init pt_dump_debug_init(void)
147 - pe = debugfs_create_file("kernel", 0400, dir, NULL, &ptdump_fops);
149 + pe_knl = debugfs_create_file("kernel", 0400, dir, NULL,
154 + pe_curknl = debugfs_create_file("current_kernel", 0400,
155 + dir, NULL, &ptdump_curknl_fops);
159 +#ifdef CONFIG_PAGE_TABLE_ISOLATION
160 + pe_curusr = debugfs_create_file("current_user", 0400,
161 + dir, NULL, &ptdump_curusr_fops);
167 debugfs_remove_recursive(dir);
168 diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
169 index 7b022ad37c4e..12b93d350480 100644
170 --- a/arch/x86/mm/dump_pagetables.c
171 +++ b/arch/x86/mm/dump_pagetables.c
172 @@ -511,8 +511,12 @@ void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
173 ptdump_walk_pgd_level_core(m, pgd, false, true);
176 -void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
177 +void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd, bool user)
179 +#ifdef CONFIG_PAGE_TABLE_ISOLATION
180 + if (user && static_cpu_has(X86_FEATURE_PTI))
181 + pgd = kernel_to_user_pgdp(pgd);
183 ptdump_walk_pgd_level_core(m, pgd, false, false);
185 EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);