#include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <linux/sched.h> #include <asm/pgtable.h> static unsigned int processid = 1; module_param(processid, uint, 0); static unsigned long addr = 0; module_param(addr, ulong, 0); static unsigned long get_pfndata(unsigned long entry) { entry &= 0x000FFFFFFFFFF000; return(entry >>= 12); } static int __init pagetable_init(void) { pgd_t *pgd; p4d_t *p4d; pud_t *pud; pmd_t *pmd; pte_t *pte; unsigned long paddr; struct pid *pid = find_get_pid(processid); struct task_struct *task = pid_task(pid, PIDTYPE_PID); struct mm_struct *mm = task->mm; if (pid == NULL) return 0; printk("mm->pgd = %016lx\n", (unsigned long)mm->pgd); printk("CR3 = %010lx\n", get_pfndata(__pa(mm->pgd))); pgd = pgd_offset(mm, addr); if (pgd_none(*pgd) || pgd_bad(*pgd)) return 0; printk("PGD entry = %010lx\n", get_pfndata(pgd_val(*pgd))); p4d = p4d_offset(pgd, addr); if (p4d_none(*p4d) || p4d_bad(*p4d)) return 0; printk("P4D entry = %010lx\n", get_pfndata(p4d_val(*p4d))); pud = pud_offset(p4d, addr); if (pud_none(*pud) || pud_bad(*pud)) return 0; printk("PUD entry = %010lx\n", get_pfndata(pud_val(*pud))); pmd = pmd_offset(pud, addr); if (pmd_none(*pmd) || pmd_bad(*pmd)) return 0; printk("PMD entry = %010lx\n", get_pfndata(pmd_val(*pmd))); pte = pte_offset_map(pmd, addr); if (pte_none(*pte)) return 0; paddr = pte_val(*pte); printk("PTE entry = %010lx\n", get_pfndata(paddr)); paddr = (paddr & 0x000FFFFFFFFFF000) | (addr & 0xFFF); printk("Phys addr = %016lx\n", paddr); return 0; } static void __exit pagetable_exit(void) { } module_init(pagetable_init); module_exit(pagetable_exit); MODULE_AUTHOR("SUEYASU Taizo"); MODULE_DESCRIPTION("pagetable test driver"); MODULE_LICENSE("GPL"); MODULE_PARM_DESC(processid, "PID (0 < processid < 2^22, default=1)"); MODULE_PARM_DESC(addr, "Virtual address, default=0");