--- dump_pagetables.c~	2010-11-18 23:46:08.400619550 -0800
+++ dump_pagetables.c	2011-04-27 14:53:52.863058527 -0700
@@ -12,6 +12,12 @@
  * of the License.
  */
 
+/* Modularization Hack, 2011 Kees Cook <kees@ubuntu.com>
+      insmod ./dump_pagetables.ko start=0x$(egrep \
+		' (swapper_pg_dir|init_level4_pgt)$' \
+		/boot/System.map-$(uname -r) | cut -d" " -f1)
+ */
+
 #include <linux/debugfs.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -88,6 +94,17 @@ static struct addr_marker address_marker
 #define PUD_LEVEL_MULT (PTRS_PER_PMD * PMD_LEVEL_MULT)
 #define PGD_LEVEL_MULT (PTRS_PER_PUD * PUD_LEVEL_MULT)
 
+static unsigned long pg_start = 0;
+module_param_named(start, pg_start, ulong, 0644);
+MODULE_PARM_DESC(start, "Address of "
+#ifdef CONFIG_X86_64
+				"init_level4_pgt"
+#else
+				"swapper_pg_dir"
+#endif
+			" in the kernel");
+
+
 /*
  * Print a readable form of a pgprot_t to the seq_file
  */
@@ -298,14 +315,19 @@ static void walk_pud_level(struct seq_fi
 
 static void walk_pgd_level(struct seq_file *m)
 {
+/*
 #ifdef CONFIG_X86_64
 	pgd_t *start = (pgd_t *) &init_level4_pgt;
 #else
 	pgd_t *start = swapper_pg_dir;
 #endif
+*/
+	pgd_t *start = (pgd_t *) pg_start;
 	int i;
 	struct pg_state st;
 
+	if (!start)
+		return;
 	memset(&st, 0, sizeof(st));
 
 	for (i = 0; i < PTRS_PER_PGD; i++) {
@@ -340,6 +362,8 @@ static int ptdump_open(struct inode *ino
 	return single_open(filp, ptdump_show, NULL);
 }
 
+static struct dentry *pe = NULL;
+
 static const struct file_operations ptdump_fops = {
 	.open		= ptdump_open,
 	.read		= seq_read,
@@ -347,10 +371,8 @@ static const struct file_operations ptdu
 	.release	= single_release,
 };
 
-static int pt_dump_init(void)
+static int __init pt_dump_init(void)
 {
-	struct dentry *pe;
-
 #ifdef CONFIG_X86_32
 	/* Not a compile-time constant on x86-32 */
 	address_markers[VMALLOC_START_NR].start_address = VMALLOC_START;
@@ -369,7 +391,16 @@ static int pt_dump_init(void)
 	return 0;
 }
 
-__initcall(pt_dump_init);
+static void __exit pt_dump_exit(void)
+{
+	if (pe) {
+		debugfs_remove_recursive(pe);
+		pe = NULL;
+	}
+}
+
+module_init(pt_dump_init);
+module_exit(pt_dump_exit);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Arjan van de Ven <arjan@linux.intel.com>");
 MODULE_DESCRIPTION("Kernel debugging helper that dumps pagetables");
