linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: ard.biesheuvel@linaro.org (Ard Biesheuvel)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 5/6] arm: mm: dump: make page table dumping reusable
Date: Fri, 22 Apr 2016 18:48:07 +0200	[thread overview]
Message-ID: <1461343688-8552-6-git-send-email-ard.biesheuvel@linaro.org> (raw)
In-Reply-To: <1461343688-8552-1-git-send-email-ard.biesheuvel@linaro.org>

For debugging purposes, it would be nice if we could export page tables
other than the swapper_pg_dir to userspace. To enable this, this patch
refactors the ARM page table dumping code such that multiple tables
may be registered with the framework, and exported under debugfs.

(this is a port of Mark Rutland's arm64 patch that does the same)

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm/include/asm/ptdump.h | 44 ++++++++++++++
 arch/arm/mm/dump.c            | 60 ++++++++++++--------
 2 files changed, 81 insertions(+), 23 deletions(-)

diff --git a/arch/arm/include/asm/ptdump.h b/arch/arm/include/asm/ptdump.h
new file mode 100644
index 000000000000..2df5737b2cc7
--- /dev/null
+++ b/arch/arm/include/asm/ptdump.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __ASM_PTDUMP_H
+#define __ASM_PTDUMP_H
+
+#ifdef CONFIG_ARM_PTDUMP
+
+#include <linux/mm_types.h>
+
+struct addr_marker {
+	unsigned long start_address;
+	char *name;
+};
+
+struct ptdump_info {
+	struct mm_struct		*mm;
+	const struct addr_marker	*markers;
+	unsigned long			base_addr;
+	unsigned long			max_addr;
+};
+
+int ptdump_register(struct ptdump_info *info, const char *name);
+
+#else
+static inline int ptdump_register(struct ptdump_info *info, const char *name)
+{
+	return 0;
+}
+#endif /* CONFIG_ARM_PTDUMP */
+
+#endif /* __ASM_PTDUMP_H */
diff --git a/arch/arm/mm/dump.c b/arch/arm/mm/dump.c
index 9fe8e241335c..0c1ff61440aa 100644
--- a/arch/arm/mm/dump.c
+++ b/arch/arm/mm/dump.c
@@ -19,11 +19,7 @@
 
 #include <asm/fixmap.h>
 #include <asm/pgtable.h>
-
-struct addr_marker {
-	unsigned long start_address;
-	const char *name;
-};
+#include <asm/ptdump.h>
 
 static struct addr_marker address_markers[] = {
 	{ MODULES_VADDR,	"Modules" },
@@ -266,7 +262,8 @@ static void walk_pte(struct pg_state *st, pmd_t *pmd, unsigned long start)
 	}
 }
 
-static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start)
+static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start,
+		     unsigned long max)
 {
 	pmd_t *pmd = pmd_offset(pud, 0);
 	unsigned long addr;
@@ -274,6 +271,8 @@ static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start)
 
 	for (i = 0; i < PTRS_PER_PMD; i++, pmd++) {
 		addr = start + i * PMD_SIZE;
+		if (addr > max)
+			break;
 		if (pmd_none(*pmd) || pmd_large(*pmd) || !pmd_present(*pmd))
 			note_page(st, addr, 3, pmd_val(*pmd));
 		else
@@ -284,7 +283,8 @@ static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start)
 	}
 }
 
-static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start)
+static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start,
+		     unsigned long max)
 {
 	pud_t *pud = pud_offset(pgd, 0);
 	unsigned long addr;
@@ -292,46 +292,51 @@ static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start)
 
 	for (i = 0; i < PTRS_PER_PUD; i++, pud++) {
 		addr = start + i * PUD_SIZE;
+		if (addr > max)
+			break;
 		if (!pud_none(*pud)) {
-			walk_pmd(st, pud, addr);
+			walk_pmd(st, pud, addr, max);
 		} else {
 			note_page(st, addr, 2, pud_val(*pud));
 		}
 	}
 }
 
-static void walk_pgd(struct seq_file *m)
+static void walk_pgd(struct pg_state *st, struct mm_struct *mm, unsigned long max)
 {
-	pgd_t *pgd = swapper_pg_dir;
-	struct pg_state st;
+	pgd_t *pgd = pgd_offset(mm, 0UL);
 	unsigned long addr;
 	unsigned i;
 
-	memset(&st, 0, sizeof(st));
-	st.seq = m;
-	st.marker = address_markers;
-
 	for (i = 0; i < PTRS_PER_PGD; i++, pgd++) {
 		addr = i * PGDIR_SIZE;
+		if (addr > max)
+			break;
 		if (!pgd_none(*pgd)) {
-			walk_pud(&st, pgd, addr);
+			walk_pud(st, pgd, addr, max);
 		} else {
-			note_page(&st, addr, 1, pgd_val(*pgd));
+			note_page(st, addr, 1, pgd_val(*pgd));
 		}
 	}
 
-	note_page(&st, 0, 0, 0);
+	note_page(st, 0, 0, 0);
 }
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-	walk_pgd(m);
+	struct ptdump_info *info = m->private;
+	struct pg_state st = {
+		.seq = m,
+		.marker = info->markers,
+	};
+
+	walk_pgd(&st, info->mm, info->max_addr);
 	return 0;
 }
 
 static int ptdump_open(struct inode *inode, struct file *file)
 {
-	return single_open(file, ptdump_show, NULL);
+	return single_open(file, ptdump_show, inode->i_private);
 }
 
 static const struct file_operations ptdump_fops = {
@@ -341,7 +346,7 @@ static const struct file_operations ptdump_fops = {
 	.release	= single_release,
 };
 
-static int ptdump_init(void)
+int ptdump_register(struct ptdump_info *info, const char *name)
 {
 	struct dentry *pe;
 	unsigned i, j;
@@ -353,8 +358,17 @@ static int ptdump_init(void)
 
 	address_markers[2].start_address = VMALLOC_START;
 
-	pe = debugfs_create_file("kernel_page_tables", 0400, NULL, NULL,
-				 &ptdump_fops);
+	pe = debugfs_create_file(name, 0400, NULL, info, &ptdump_fops);
 	return pe ? 0 : -ENOMEM;
 }
+
+static struct ptdump_info kernel_ptdump_info = {
+	.mm		= &init_mm,
+	.markers	= address_markers,
+};
+
+static int ptdump_init(void)
+{
+	return ptdump_register(&kernel_ptdump_info, "kernel_page_tables");
+}
 __initcall(ptdump_init);
-- 
2.7.4

  parent reply	other threads:[~2016-04-22 16:48 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-22 16:48 [PATCH v2 0/6] arm64/ARM pt dumper changes Ard Biesheuvel
2016-04-22 16:48 ` [PATCH v2 1/6] arm64: ptdump: use static initializers for vmemmap region boundaries Ard Biesheuvel
2016-04-22 17:07   ` Mark Rutland
2016-04-22 16:48 ` [PATCH v2 2/6] arm64: ptdump: add region marker for kasan shadow region Ard Biesheuvel
2016-04-22 17:09   ` Mark Rutland
2016-04-22 16:48 ` [PATCH v2 3/6] arm64: ptdump: fold string literals into address_markers[] and pte_bits[] Ard Biesheuvel
2016-04-22 16:48 ` [PATCH v2 4/6] arm64: mm: dump: make page table dumping reusable Ard Biesheuvel
2016-04-25 11:07   ` Will Deacon
2016-05-13 12:56     ` Mark Rutland
2016-05-31 13:25       ` Will Deacon
2016-04-22 16:48 ` Ard Biesheuvel [this message]
2016-04-22 16:48 ` [PATCH v2 6/6] efi/arm*: add support to dump the EFI page tables Ard Biesheuvel
2016-04-22 17:01   ` Mark Rutland
2016-04-22 17:20     ` Ard Biesheuvel
2016-04-22 17:25       ` Mark Rutland
2016-04-25 11:26         ` Ard Biesheuvel
2016-04-27 20:12           ` Russell King - ARM Linux
2016-04-26 11:29 ` [PATCH v2 0/6] arm64/ARM pt dumper changes Will Deacon
2016-04-26 11:34   ` Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1461343688-8552-6-git-send-email-ard.biesheuvel@linaro.org \
    --to=ard.biesheuvel@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).