18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci#include <linux/debugfs.h> 38c2ecf20Sopenharmony_ci#include <linux/efi.h> 48c2ecf20Sopenharmony_ci#include <linux/module.h> 58c2ecf20Sopenharmony_ci#include <linux/seq_file.h> 68c2ecf20Sopenharmony_ci#include <linux/pgtable.h> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_cistatic int ptdump_show(struct seq_file *m, void *v) 98c2ecf20Sopenharmony_ci{ 108c2ecf20Sopenharmony_ci ptdump_walk_pgd_level_debugfs(m, &init_mm, false); 118c2ecf20Sopenharmony_ci return 0; 128c2ecf20Sopenharmony_ci} 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(ptdump); 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cistatic int ptdump_curknl_show(struct seq_file *m, void *v) 178c2ecf20Sopenharmony_ci{ 188c2ecf20Sopenharmony_ci if (current->mm->pgd) 198c2ecf20Sopenharmony_ci ptdump_walk_pgd_level_debugfs(m, current->mm, false); 208c2ecf20Sopenharmony_ci return 0; 218c2ecf20Sopenharmony_ci} 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(ptdump_curknl); 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#ifdef CONFIG_PAGE_TABLE_ISOLATION 268c2ecf20Sopenharmony_cistatic int ptdump_curusr_show(struct seq_file *m, void *v) 278c2ecf20Sopenharmony_ci{ 288c2ecf20Sopenharmony_ci if (current->mm->pgd) 298c2ecf20Sopenharmony_ci ptdump_walk_pgd_level_debugfs(m, current->mm, true); 308c2ecf20Sopenharmony_ci return 0; 318c2ecf20Sopenharmony_ci} 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(ptdump_curusr); 348c2ecf20Sopenharmony_ci#endif 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci#if defined(CONFIG_EFI) && defined(CONFIG_X86_64) 378c2ecf20Sopenharmony_cistatic int ptdump_efi_show(struct seq_file *m, void *v) 388c2ecf20Sopenharmony_ci{ 398c2ecf20Sopenharmony_ci if (efi_mm.pgd) 408c2ecf20Sopenharmony_ci ptdump_walk_pgd_level_debugfs(m, &efi_mm, false); 418c2ecf20Sopenharmony_ci return 0; 428c2ecf20Sopenharmony_ci} 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(ptdump_efi); 458c2ecf20Sopenharmony_ci#endif 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic struct dentry *dir; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cistatic int __init pt_dump_debug_init(void) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci dir = debugfs_create_dir("page_tables", NULL); 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci debugfs_create_file("kernel", 0400, dir, NULL, &ptdump_fops); 548c2ecf20Sopenharmony_ci debugfs_create_file("current_kernel", 0400, dir, NULL, 558c2ecf20Sopenharmony_ci &ptdump_curknl_fops); 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci#ifdef CONFIG_PAGE_TABLE_ISOLATION 588c2ecf20Sopenharmony_ci debugfs_create_file("current_user", 0400, dir, NULL, 598c2ecf20Sopenharmony_ci &ptdump_curusr_fops); 608c2ecf20Sopenharmony_ci#endif 618c2ecf20Sopenharmony_ci#if defined(CONFIG_EFI) && defined(CONFIG_X86_64) 628c2ecf20Sopenharmony_ci debugfs_create_file("efi", 0400, dir, NULL, &ptdump_efi_fops); 638c2ecf20Sopenharmony_ci#endif 648c2ecf20Sopenharmony_ci return 0; 658c2ecf20Sopenharmony_ci} 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_cistatic void __exit pt_dump_debug_exit(void) 688c2ecf20Sopenharmony_ci{ 698c2ecf20Sopenharmony_ci debugfs_remove_recursive(dir); 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_cimodule_init(pt_dump_debug_init); 738c2ecf20Sopenharmony_cimodule_exit(pt_dump_debug_exit); 748c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 758c2ecf20Sopenharmony_ciMODULE_AUTHOR("Arjan van de Ven <arjan@linux.intel.com>"); 768c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Kernel debugging helper that dumps pagetables"); 77