linux/arch/x86/mm/debug_pagetables.c
<<
>>
Prefs
   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
   7static int ptdump_show(struct seq_file *m, void *v)
   8{
   9        ptdump_walk_pgd_level_debugfs(m, NULL, false);
  10        return 0;
  11}
  12
  13static int ptdump_open(struct inode *inode, struct file *filp)
  14{
  15        return single_open(filp, ptdump_show, NULL);
  16}
  17
  18static const struct file_operations ptdump_fops = {
  19        .owner          = THIS_MODULE,
  20        .open           = ptdump_open,
  21        .read           = seq_read,
  22        .llseek         = seq_lseek,
  23        .release        = single_release,
  24};
  25
  26static int ptdump_show_curknl(struct seq_file *m, void *v)
  27{
  28        if (current->mm->pgd) {
  29                down_read(&current->mm->mmap_sem);
  30                ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, false);
  31                up_read(&current->mm->mmap_sem);
  32        }
  33        return 0;
  34}
  35
  36static int ptdump_open_curknl(struct inode *inode, struct file *filp)
  37{
  38        return single_open(filp, ptdump_show_curknl, NULL);
  39}
  40
  41static const struct file_operations ptdump_curknl_fops = {
  42        .owner          = THIS_MODULE,
  43        .open           = ptdump_open_curknl,
  44        .read           = seq_read,
  45        .llseek         = seq_lseek,
  46        .release        = single_release,
  47};
  48
  49#ifdef CONFIG_PAGE_TABLE_ISOLATION
  50static struct dentry *pe_curusr;
  51
  52static int ptdump_show_curusr(struct seq_file *m, void *v)
  53{
  54        if (current->mm->pgd) {
  55                down_read(&current->mm->mmap_sem);
  56                ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, true);
  57                up_read(&current->mm->mmap_sem);
  58        }
  59        return 0;
  60}
  61
  62static int ptdump_open_curusr(struct inode *inode, struct file *filp)
  63{
  64        return single_open(filp, ptdump_show_curusr, NULL);
  65}
  66
  67static const struct file_operations ptdump_curusr_fops = {
  68        .owner          = THIS_MODULE,
  69        .open           = ptdump_open_curusr,
  70        .read           = seq_read,
  71        .llseek         = seq_lseek,
  72        .release        = single_release,
  73};
  74#endif
  75
  76#if defined(CONFIG_EFI) && defined(CONFIG_X86_64)
  77static struct dentry *pe_efi;
  78
  79static int ptdump_show_efi(struct seq_file *m, void *v)
  80{
  81        if (efi_mm.pgd)
  82                ptdump_walk_pgd_level_debugfs(m, efi_mm.pgd, false);
  83        return 0;
  84}
  85
  86static int ptdump_open_efi(struct inode *inode, struct file *filp)
  87{
  88        return single_open(filp, ptdump_show_efi, NULL);
  89}
  90
  91static const struct file_operations ptdump_efi_fops = {
  92        .owner          = THIS_MODULE,
  93        .open           = ptdump_open_efi,
  94        .read           = seq_read,
  95        .llseek         = seq_lseek,
  96        .release        = single_release,
  97};
  98#endif
  99
 100static struct dentry *dir, *pe_knl, *pe_curknl;
 101
 102static int __init pt_dump_debug_init(void)
 103{
 104        dir = debugfs_create_dir("page_tables", NULL);
 105        if (!dir)
 106                return -ENOMEM;
 107
 108        pe_knl = debugfs_create_file("kernel", 0400, dir, NULL,
 109                                     &ptdump_fops);
 110        if (!pe_knl)
 111                goto err;
 112
 113        pe_curknl = debugfs_create_file("current_kernel", 0400,
 114                                        dir, NULL, &ptdump_curknl_fops);
 115        if (!pe_curknl)
 116                goto err;
 117
 118#ifdef CONFIG_PAGE_TABLE_ISOLATION
 119        pe_curusr = debugfs_create_file("current_user", 0400,
 120                                        dir, NULL, &ptdump_curusr_fops);
 121        if (!pe_curusr)
 122                goto err;
 123#endif
 124
 125#if defined(CONFIG_EFI) && defined(CONFIG_X86_64)
 126        pe_efi = debugfs_create_file("efi", 0400, dir, NULL, &ptdump_efi_fops);
 127        if (!pe_efi)
 128                goto err;
 129#endif
 130
 131        return 0;
 132err:
 133        debugfs_remove_recursive(dir);
 134        return -ENOMEM;
 135}
 136
 137static void __exit pt_dump_debug_exit(void)
 138{
 139        debugfs_remove_recursive(dir);
 140}
 141
 142module_init(pt_dump_debug_init);
 143module_exit(pt_dump_debug_exit);
 144MODULE_LICENSE("GPL");
 145MODULE_AUTHOR("Arjan van de Ven <arjan@linux.intel.com>");
 146MODULE_DESCRIPTION("Kernel debugging helper that dumps pagetables");
 147