From 69e9aab1ff93a859309fcf263c6b87d92dad8c5c Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Wed, 12 Jul 2017 09:40:30 +0100 Subject: [PATCH] ptdump, need make arch ifdefs --- kernel_module/Makefile | 8 +++ kernel_module/README.md | 1 + kernel_module/page_table_dump.c | 98 +++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 kernel_module/page_table_dump.c diff --git a/kernel_module/Makefile b/kernel_module/Makefile index a4e48d9..eaf60d8 100644 --- a/kernel_module/Makefile +++ b/kernel_module/Makefile @@ -1,6 +1,14 @@ obj-m += $(addsuffix .o, $(notdir $(basename $(wildcard $(BR2_EXTERNAL_KERNEL_MODULE_PATH)/*.c)))) ccflags-y := -DDEBUG -g -std=gnu99 -Wno-declaration-after-statement +#ifneq ($(BR2_ARCH), x86_64) +# obj-m := $(filter-out page_table_dump.o, $(obj-m)) +#endif +# +#ifneq ($(BR2_ARCH), arm) +# obj-m := $(filter-out platform_device.o, $(obj-m)) +#endif + .PHONY: all clean all: diff --git a/kernel_module/README.md b/kernel_module/README.md index 8913db3..2315b56 100644 --- a/kernel_module/README.md +++ b/kernel_module/README.md @@ -25,6 +25,7 @@ 1. [dep](dep.c) 1. [dep2](dep2.c) 1. [character_device](character_device.c) + 1. [page_table_dump](page_table_dump.c) 1. Hardware device drivers 1. [pci_min](pci_min.c) 1. [pci](pci.c) diff --git a/kernel_module/page_table_dump.c b/kernel_module/page_table_dump.c new file mode 100644 index 0000000..fc9e9a0 --- /dev/null +++ b/kernel_module/page_table_dump.c @@ -0,0 +1,98 @@ +/* +Adapted from: https://github.com/jethrogb/ptdump + +TODO: use kernel constants instead of hard-coding everything to make this +more platform independent. +*/ + +#error + +#include +#include +#include +#include + +#define pte_address(p) ((p)&0x000ffffffffff000UL) +typedef unsigned long long ullong; + +static void output(void* p, void* data, ullong len) { + seq_write((struct seq_file *)p, data, len); +} + +static ullong * read_page(void* p, ullong address) { + return (ullong*)phys_to_virt(address); +} + +static ullong* ptdump_dump(void *p, ullong address) { + ullong* page = read_page(p, address); + if (page) { + output(p, &address, 8); + output(p, page, 4096); + } + return page; +} + +static void ptdump_page(void *p, ullong address, int levels_remaining); + +static void ptdump_recurse(void *p, ullong* page, int levels_remaining) { + int i; + for (i = 0; i < 512; i++) { + if ((page[i] & 1) && !(page[i] & (1 << 7))) + ptdump_page(p, pte_address(page[i]), levels_remaining - 1); + } +} + +static void ptdump_page(void *p, ullong address, int levels_remaining) { + ullong* page = ptdump_dump(p, address); + if (!page) return; + if (levels_remaining > 0) + ptdump_recurse(p, page, levels_remaining); +} + +static ullong get_base(void* p) { + return read_cr3(); +} + +static void ptdump(void *p, int levels) { + ptdump_page(p, get_base(p), levels); +} + +static int do_ptdump(struct seq_file *m, void* v) { + ptdump(m, (int)(unsigned long)(m->private)); + return 0; +} + +static int ptdump_open(struct inode *inode, struct file *fp) { + return single_open(fp, do_ptdump, PDE_DATA(inode)); +} + +static const struct file_operations ptdump_fops = { + .open = ptdump_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static struct proc_dir_entry *proc_page_table0; +static struct proc_dir_entry *proc_page_table1; +static struct proc_dir_entry *proc_page_table2; +static struct proc_dir_entry *proc_page_table3; + +static int __init ptdump_module_init(void) { + proc_page_table0 = proc_create_data("page_table_0", 0444, NULL, &ptdump_fops,(void*)0); + proc_page_table1 = proc_create_data("page_table_1", 0444, NULL, &ptdump_fops,(void*)1); + proc_page_table2 = proc_create_data("page_table_2", 0444, NULL, &ptdump_fops,(void*)2); + proc_page_table3 = proc_create_data("page_table_3", 0444, NULL, &ptdump_fops,(void*)3); + return 0; +} + +static void __exit ptdump_module_exit(void) { + proc_remove(proc_page_table0); + proc_remove(proc_page_table1); + proc_remove(proc_page_table2); + proc_remove(proc_page_table3); +} + +module_init(ptdump_module_init); +module_exit(ptdump_module_exit); +MODULE_LICENSE("GPL");