mirror of
https://github.com/torvalds/linux.git
synced 2024-12-05 02:23:16 +00:00
a4b51ef655
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>
115 lines
2.6 KiB
C
115 lines
2.6 KiB
C
#include <linux/debugfs.h>
|
|
#include <linux/module.h>
|
|
#include <linux/seq_file.h>
|
|
#include <asm/pgtable.h>
|
|
|
|
static int ptdump_show(struct seq_file *m, void *v)
|
|
{
|
|
ptdump_walk_pgd_level_debugfs(m, NULL, false);
|
|
return 0;
|
|
}
|
|
|
|
static int ptdump_open(struct inode *inode, struct file *filp)
|
|
{
|
|
return single_open(filp, ptdump_show, NULL);
|
|
}
|
|
|
|
static const struct file_operations ptdump_fops = {
|
|
.owner = THIS_MODULE,
|
|
.open = ptdump_open,
|
|
.read = seq_read,
|
|
.llseek = seq_lseek,
|
|
.release = single_release,
|
|
};
|
|
|
|
static int ptdump_show_curknl(struct seq_file *m, void *v)
|
|
{
|
|
if (current->mm->pgd) {
|
|
down_read(¤t->mm->mmap_sem);
|
|
ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, false);
|
|
up_read(¤t->mm->mmap_sem);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int ptdump_open_curknl(struct inode *inode, struct file *filp)
|
|
{
|
|
return single_open(filp, ptdump_show_curknl, NULL);
|
|
}
|
|
|
|
static const struct file_operations ptdump_curknl_fops = {
|
|
.owner = THIS_MODULE,
|
|
.open = ptdump_open_curknl,
|
|
.read = seq_read,
|
|
.llseek = seq_lseek,
|
|
.release = single_release,
|
|
};
|
|
|
|
#ifdef CONFIG_PAGE_TABLE_ISOLATION
|
|
static struct dentry *pe_curusr;
|
|
|
|
static int ptdump_show_curusr(struct seq_file *m, void *v)
|
|
{
|
|
if (current->mm->pgd) {
|
|
down_read(¤t->mm->mmap_sem);
|
|
ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, true);
|
|
up_read(¤t->mm->mmap_sem);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int ptdump_open_curusr(struct inode *inode, struct file *filp)
|
|
{
|
|
return single_open(filp, ptdump_show_curusr, NULL);
|
|
}
|
|
|
|
static const struct file_operations ptdump_curusr_fops = {
|
|
.owner = THIS_MODULE,
|
|
.open = ptdump_open_curusr,
|
|
.read = seq_read,
|
|
.llseek = seq_lseek,
|
|
.release = single_release,
|
|
};
|
|
#endif
|
|
|
|
static struct dentry *dir, *pe_knl, *pe_curknl;
|
|
|
|
static int __init pt_dump_debug_init(void)
|
|
{
|
|
dir = debugfs_create_dir("page_tables", NULL);
|
|
if (!dir)
|
|
return -ENOMEM;
|
|
|
|
pe_knl = debugfs_create_file("kernel", 0400, dir, NULL,
|
|
&ptdump_fops);
|
|
if (!pe_knl)
|
|
goto err;
|
|
|
|
pe_curknl = debugfs_create_file("current_kernel", 0400,
|
|
dir, NULL, &ptdump_curknl_fops);
|
|
if (!pe_curknl)
|
|
goto err;
|
|
|
|
#ifdef CONFIG_PAGE_TABLE_ISOLATION
|
|
pe_curusr = debugfs_create_file("current_user", 0400,
|
|
dir, NULL, &ptdump_curusr_fops);
|
|
if (!pe_curusr)
|
|
goto err;
|
|
#endif
|
|
return 0;
|
|
err:
|
|
debugfs_remove_recursive(dir);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
static void __exit pt_dump_debug_exit(void)
|
|
{
|
|
debugfs_remove_recursive(dir);
|
|
}
|
|
|
|
module_init(pt_dump_debug_init);
|
|
module_exit(pt_dump_debug_exit);
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_AUTHOR("Arjan van de Ven <arjan@linux.intel.com>");
|
|
MODULE_DESCRIPTION("Kernel debugging helper that dumps pagetables");
|