2019-05-19 13:08:20 +01:00
// SPDX-License-Identifier: GPL-2.0-only
2015-11-19 17:07:55 -08:00
# include <linux/debugfs.h>
2018-03-12 09:43:54 +00:00
# include <linux/efi.h>
2015-11-19 17:07:55 -08:00
# include <linux/module.h>
# include <linux/seq_file.h>
# include <asm/pgtable.h>
static int ptdump_show ( struct seq_file * m , void * v )
{
2017-12-04 15:08:06 +01:00
ptdump_walk_pgd_level_debugfs ( m , NULL , false ) ;
2015-11-19 17:07:55 -08:00
return 0 ;
}
2018-11-19 10:43:34 -05:00
DEFINE_SHOW_ATTRIBUTE ( ptdump ) ;
2015-11-19 17:07:55 -08:00
2018-11-19 10:43:34 -05:00
static int ptdump_curknl_show ( struct seq_file * m , void * v )
2017-12-04 15:08:06 +01:00
{
if ( current - > mm - > pgd ) {
down_read ( & current - > mm - > mmap_sem ) ;
ptdump_walk_pgd_level_debugfs ( m , current - > mm - > pgd , false ) ;
up_read ( & current - > mm - > mmap_sem ) ;
}
return 0 ;
}
2018-11-19 10:43:34 -05:00
DEFINE_SHOW_ATTRIBUTE ( ptdump_curknl ) ;
2017-12-04 15:08:06 +01:00
# ifdef CONFIG_PAGE_TABLE_ISOLATION
2018-11-19 10:43:34 -05:00
static int ptdump_curusr_show ( struct seq_file * m , void * v )
2017-12-04 15:08:06 +01:00
{
if ( current - > mm - > pgd ) {
down_read ( & current - > mm - > mmap_sem ) ;
ptdump_walk_pgd_level_debugfs ( m , current - > mm - > pgd , true ) ;
up_read ( & current - > mm - > mmap_sem ) ;
}
return 0 ;
}
2018-11-19 10:43:34 -05:00
DEFINE_SHOW_ATTRIBUTE ( ptdump_curusr ) ;
2017-12-04 15:08:06 +01:00
# endif
2018-01-31 07:56:22 -08:00
# if defined(CONFIG_EFI) && defined(CONFIG_X86_64)
2018-11-19 10:43:34 -05:00
static int ptdump_efi_show ( struct seq_file * m , void * v )
2018-01-31 07:56:22 -08:00
{
2018-03-12 09:43:54 +00:00
if ( efi_mm . pgd )
ptdump_walk_pgd_level_debugfs ( m , efi_mm . pgd , false ) ;
2018-01-31 07:56:22 -08:00
return 0 ;
}
2018-11-19 10:43:34 -05:00
DEFINE_SHOW_ATTRIBUTE ( ptdump_efi ) ;
2018-01-31 07:56:22 -08:00
# endif
2019-01-22 15:35:40 +01:00
static struct dentry * dir ;
2015-11-19 17:07:55 -08:00
static int __init pt_dump_debug_init ( void )
{
2017-12-04 15:08:04 +01:00
dir = debugfs_create_dir ( " page_tables " , NULL ) ;
2017-12-04 15:08:06 +01:00
2019-01-22 15:35:40 +01:00
debugfs_create_file ( " kernel " , 0400 , dir , NULL , & ptdump_fops ) ;
debugfs_create_file ( " current_kernel " , 0400 , dir , NULL ,
& ptdump_curknl_fops ) ;
2017-12-04 15:08:06 +01:00
# ifdef CONFIG_PAGE_TABLE_ISOLATION
2019-01-22 15:35:40 +01:00
debugfs_create_file ( " current_user " , 0400 , dir , NULL ,
& ptdump_curusr_fops ) ;
2017-12-04 15:08:06 +01:00
# endif
2018-01-31 07:56:22 -08:00
# if defined(CONFIG_EFI) && defined(CONFIG_X86_64)
2019-01-22 15:35:40 +01:00
debugfs_create_file ( " efi " , 0400 , dir , NULL , & ptdump_efi_fops ) ;
2018-01-31 07:56:22 -08:00
# endif
2015-11-19 17:07:55 -08:00
return 0 ;
}
static void __exit pt_dump_debug_exit ( void )
{
2017-12-04 15:08:04 +01:00
debugfs_remove_recursive ( dir ) ;
2015-11-19 17:07:55 -08:00
}
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 " ) ;