Skip to content

Commit a4b51ef

Browse files
KAGA-KOKOIngo Molnar
authored andcommitted
x86/mm/dump_pagetables: Allow dumping current pagetables
Add two debugfs files which allow to dump the pagetable of the current task. current_kernel dumps the regular page table. This is the page table which is normally shared between kernel and user space. If kernel page table isolation is enabled this is the kernel space mapping. If kernel page table isolation is enabled the second file, current_user, dumps the user space page table. These files allow to verify the resulting page tables for page table isolation, but even in the normal case its useful to be able to inspect user space page tables of current for debugging purposes. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Andy Lutomirski <luto@kernel.org> Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: David Laight <David.Laight@aculab.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: Eduardo Valentin <eduval@amazon.com> Cc: Greg KH <gregkh@linuxfoundation.org> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Juergen Gross <jgross@suse.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Will Deacon <will.deacon@arm.com> Cc: aliguori@amazon.com Cc: daniel.gruss@iaik.tugraz.at Cc: hughd@google.com Cc: keescook@google.com Cc: linux-mm@kvack.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent b4bf4f9 commit a4b51ef

File tree

3 files changed

+73
-6
lines changed

3 files changed

+73
-6
lines changed

arch/x86/include/asm/pgtable.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD];
2828
int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
2929

3030
void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
31-
void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
31+
void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd, bool user);
3232
void ptdump_walk_pgd_level_checkwx(void);
3333

3434
#ifdef CONFIG_DEBUG_WX

arch/x86/mm/debug_pagetables.c

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
static int ptdump_show(struct seq_file *m, void *v)
77
{
8-
ptdump_walk_pgd_level_debugfs(m, NULL);
8+
ptdump_walk_pgd_level_debugfs(m, NULL, false);
99
return 0;
1010
}
1111

@@ -22,17 +22,80 @@ static const struct file_operations ptdump_fops = {
2222
.release = single_release,
2323
};
2424

25-
static struct dentry *dir, *pe;
25+
static int ptdump_show_curknl(struct seq_file *m, void *v)
26+
{
27+
if (current->mm->pgd) {
28+
down_read(&current->mm->mmap_sem);
29+
ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, false);
30+
up_read(&current->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(&current->mm->mmap_sem);
55+
ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, true);
56+
up_read(&current->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;
2676

2777
static int __init pt_dump_debug_init(void)
2878
{
2979
dir = debugfs_create_dir("page_tables", NULL);
3080
if (!dir)
3181
return -ENOMEM;
3282

33-
pe = debugfs_create_file("kernel", 0400, dir, NULL, &ptdump_fops);
34-
if (!pe)
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)
3597
goto err;
98+
#endif
3699
return 0;
37100
err:
38101
debugfs_remove_recursive(dir);

arch/x86/mm/dump_pagetables.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,12 @@ void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
530530
ptdump_walk_pgd_level_core(m, pgd, false, true);
531531
}
532532

533-
void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
533+
void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd, bool user)
534534
{
535+
#ifdef CONFIG_PAGE_TABLE_ISOLATION
536+
if (user && static_cpu_has(X86_FEATURE_PTI))
537+
pgd = kernel_to_user_pgdp(pgd);
538+
#endif
535539
ptdump_walk_pgd_level_core(m, pgd, false, false);
536540
}
537541
EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);

0 commit comments

Comments
 (0)