2015-11-19 17:07:55 -08:00
# 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 )
{
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 ;
}
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 ,
} ;
2017-12-04 15:08:06 +01:00
static int ptdump_show_curknl ( struct seq_file * m , void * v )
{
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 ;
}
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 ( & current - > mm - > mmap_sem ) ;
ptdump_walk_pgd_level_debugfs ( m , current - > mm - > pgd , true ) ;
up_read ( & current - > 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 ;
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 ) ;
if ( ! dir )
2015-11-19 17:07:55 -08:00
return - ENOMEM ;
2017-12-04 15:08:06 +01:00
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 )
2017-12-04 15:08:04 +01:00
goto err ;
2017-12-04 15:08:06 +01:00
# endif
2015-11-19 17:07:55 -08:00
return 0 ;
2017-12-04 15:08:04 +01:00
err :
debugfs_remove_recursive ( dir ) ;
return - ENOMEM ;
2015-11-19 17:07:55 -08:00
}
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 " ) ;