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