From: Balbir Singh <bsingharora@gmail.com>
To: mpe@ellerman.id.au
Cc: linuxppc-dev@lists.ozlabs.org, Balbir Singh <bsingharora@gmail.com>
Subject: [PATCH v4] powerpc/xmon: Support dumping software pagetables
Date: Mon, 16 Oct 2017 14:37:24 +1100 [thread overview]
Message-ID: <20171016033724.8063-1-bsingharora@gmail.com> (raw)
It would be nice to be able to dump page tables in a particular
context.
eg: dumping vmalloc space:
0:mon> dv 0xd00037fffff00000
pgd @ 0xc0000000017c0000
pgdp @ 0xc0000000017c00d8 = 0x00000000f10b1000
pudp @ 0xc0000000f10b13f8 = 0x00000000f10d0000
pmdp @ 0xc0000000f10d1ff8 = 0x00000000f1102000
ptep @ 0xc0000000f1102780 = 0xc0000000f1ba018e
Maps physical address = 0x00000000f1ba0000
Flags = Accessed Dirty Read Write
This patch does not replicate the complex code of dump_pagetable and
has no support for bolted linear mapping, thats why I've it's called
dump virtual page table support. The format of the PTE can be expanded
even further to add more useful information about the flags in the PTE
if required.
Signed-off-by: Balbir Singh <bsingharora@gmail.com>
[mpe: Bike shed the output format, show the pgdir]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
- Changelog v4:
Fix kbuild error (need highmem.h)
Fix double semicolons in format-pte
arch/powerpc/xmon/xmon.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 112 insertions(+)
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 33351c6..5e30fc3 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -28,6 +28,7 @@
#include <linux/bug.h>
#include <linux/nmi.h>
#include <linux/ctype.h>
+#include <linux/highmem.h>
#include <asm/debugfs.h>
#include <asm/ptrace.h>
@@ -127,6 +128,7 @@ static void byterev(unsigned char *, int);
static void memex(void);
static int bsesc(void);
static void dump(void);
+static void show_pte(unsigned long);
static void prdump(unsigned long, long);
static int ppc_inst_dump(unsigned long, long, int);
static void dump_log_buf(void);
@@ -234,6 +236,7 @@ Commands:\n\
#endif
"\
dr dump stream of raw bytes\n\
+ dv dump virtual address translation \n\
dt dump the tracing buffers (uses printk)\n\
dtc dump the tracing buffers for current CPU (uses printk)\n\
"
@@ -2574,6 +2577,9 @@ dump(void)
dump_log_buf();
} else if (c == 'o') {
dump_opal_msglog();
+ } else if (c == 'v') {
+ /* dump virtual to physical translation */
+ show_pte(adrs);
} else if (c == 'r') {
scanhex(&ndump);
if (ndump == 0)
@@ -2907,6 +2913,112 @@ static void show_task(struct task_struct *tsk)
tsk->comm);
}
+void format_pte(void *ptep, unsigned long pte)
+{
+ printf("ptep @ 0x%016lx = 0x%016lx\n", (unsigned long)ptep, pte);
+ printf("Maps physical address = 0x%016lx\n", pte & PTE_RPN_MASK);
+
+ printf("Flags = %s%s%s%s%s\n",
+ (pte & _PAGE_ACCESSED) ? "Accessed " : "",
+ (pte & _PAGE_DIRTY) ? "Dirty " : "",
+ (pte & _PAGE_READ) ? "Read " : "",
+ (pte & _PAGE_WRITE) ? "Write " : "",
+ (pte & _PAGE_EXEC) ? "Exec " : "");
+}
+
+static void show_pte(unsigned long addr)
+{
+ unsigned long tskv = 0;
+ struct task_struct *tsk = NULL;
+ struct mm_struct *mm;
+ pgd_t *pgdp, *pgdir;
+ pud_t *pudp;
+ pmd_t *pmdp;
+ pte_t *ptep;
+
+ if (!scanhex(&tskv))
+ mm = &init_mm;
+ else
+ tsk = (struct task_struct *)tskv;
+
+ if (tsk == NULL)
+ mm = &init_mm;
+ else
+ mm = tsk->active_mm;
+
+ if (setjmp(bus_error_jmp) != 0) {
+ catch_memory_errors = 0;
+ printf("*** Error dumping pte for task %p\n", tsk);
+ return;
+ }
+
+ catch_memory_errors = 1;
+ sync();
+
+ if (mm == &init_mm) {
+ pgdp = pgd_offset_k(addr);
+ pgdir = pgd_offset_k(0);
+ } else {
+ pgdp = pgd_offset(mm, addr);
+ pgdir = pgd_offset(mm, 0);
+ }
+
+ if (pgd_none(*pgdp)) {
+ printf("no linux page table for address\n");
+ return;
+ }
+
+ printf("pgd @ 0x%016lx\n", pgdir);
+
+ if (pgd_huge(*pgdp)) {
+ format_pte(pgdp, pgd_val(*pgdp));
+ return;
+ }
+ printf("pgdp @ 0x%016lx = 0x%016lx\n", pgdp, pgd_val(*pgdp));
+
+ pudp = pud_offset(pgdp, addr);
+
+ if (pud_none(*pudp)) {
+ printf("No valid PUD\n");
+ return;
+ }
+
+#ifdef CONFIG_HUGETLB_PAGE
+ if (pud_huge(*pudp)) {
+ format_pte(pudp, pud_val(*pudp));
+ return;
+ }
+#endif
+
+ printf("pudp @ 0x%016lx = 0x%016lx\n", pudp, pud_val(*pudp));
+
+ pmdp = pmd_offset(pudp, addr);
+
+ if (pmd_none(*pmdp)) {
+ printf("No valid PMD\n");
+ return;
+ }
+
+#ifdef CONFIG_HUGETLB_PAGE
+ if (pmd_huge(*pmdp)) {
+ format_pte(pmdp, pmd_val(*pmdp));
+ return;
+ }
+#endif
+ printf("pmdp @ 0x%016lx = 0x%016lx\n", pmdp, pmd_val(*pmdp));
+
+ ptep = pte_offset_map(pmdp, addr);
+ if (pte_none(*ptep)) {
+ printf("no valid PTE\n");
+ return;
+ }
+
+ format_pte(ptep, pte_val(*ptep));
+
+ sync();
+ __delay(200);
+ catch_memory_errors = 0;
+}
static void show_tasks(void)
{
unsigned long tskv;
--
2.9.5
reply other threads:[~2017-10-16 3:37 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20171016033724.8063-1-bsingharora@gmail.com \
--to=bsingharora@gmail.com \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=mpe@ellerman.id.au \
/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).