* [PATCH v2] powerpc/xmon: support dumping software pagetables
@ 2017-07-24 7:23 Balbir Singh
0 siblings, 0 replies; 3+ messages in thread
From: Balbir Singh @ 2017-07-24 7:23 UTC (permalink / raw)
To: linuxppc-dev, mpe
It would be nice to be able to dump page tables in a
particular context.
Example use cases
Dumping PTE contents to see the keys (useful for debugging)
0:mon> dv 0x7ffff7f70000 c00000003b585080
PGD@0xc00000003ab651f8->0x000000003a255800
PUD@0xc00000003a255bf8->0x000000003aa84000
PMD@0xc00000003aa85fb8->0x000000003a823000
physical address->0x00000000012c0000, PTE->0xce800000012c0504
PTE flags A: :R: :
For Hugepages, the output shows the PMD as PTE
0:mon> dv 0x7ffff6000000 c00000003b585080
PGD@0xc00000003ab651f8->0x000000003a255800
PUD@0xc00000003a255bf8->0x000000003aa84000
physical address->0x0000000032000000, PTE->0xdc80000032002386
PTE flags A:D:R:W:
Dumping vmalloc space
0:mon> dv 0xd000000000000000
PGD@0xc0000000012b0000->0x00000000bc170400
PUD@0xc0000000bc170400->0x000000007e184000
PMD@0xc00000007e184000->0x00000000bc180000
physical address->0x000000003d2b0000, PTE->0xc08000003d2b018e
PTE flags A:D:R:W:
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>
---
arch/powerpc/xmon/xmon.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 119 insertions(+)
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 5341556..c84448c 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -126,6 +126,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);
@@ -233,6 +234,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\
"
#ifdef CONFIG_PPC_POWERNV
@@ -2554,6 +2556,9 @@ dump(void)
} else if (c == 't') {
ftrace_dump(DUMP_ALL);
tracing_on();
+ } else if (c == 'v') {
+ /* dump virtual to physical translation */
+ show_pte(adrs);
} else if (c == 'r') {
scanhex(&ndump);
if (ndump == 0)
@@ -2887,6 +2892,120 @@ static void show_task(struct task_struct *tsk)
tsk->comm);
}
+static inline char *show_pte_flag(unsigned long pte, unsigned long flag,
+ char *str)
+{
+ if (pte & flag)
+ return str;
+ else
+ return " ";
+}
+
+void format_pte(unsigned long pte)
+{
+ unsigned long pa = pte & PTE_RPN_MASK;
+
+ printf("physical address->0x%016lx, PTE->0x%016lx\n", pa, pte);
+
+ printf("PTE flags %s:%s:%s:%s:%s\n",
+ show_pte_flag(pte, _PAGE_ACCESSED, "A"),
+ show_pte_flag(pte, _PAGE_DIRTY, "D"),
+ show_pte_flag(pte, _PAGE_READ, "R"),
+ show_pte_flag(pte, _PAGE_WRITE, "W"),
+ show_pte_flag(pte, _PAGE_EXEC, "X"));
+
+ /* TODO add KEY support once the bits are baked in */
+}
+
+static void show_pte(unsigned long addr)
+{
+ unsigned long tskv = 0;
+ struct task_struct *tsk = NULL;
+ struct mm_struct *mm;
+ pgd_t *pgdp;
+ 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);
+ else
+ pgdp = pgd_offset(mm, addr);
+
+ if (pgd_none(*pgdp)) {
+ printf("no linux page table for address\n");
+ return;
+ }
+
+ if (pgd_huge(*pgdp)) {
+ format_pte(pgd_val(*pgdp));
+ return;
+ }
+ printf("PGD@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(pud_val(*pudp));
+ return;
+ }
+#endif
+
+ printf("PUD@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(pmd_val(*pmdp));
+ return;
+ }
+#endif
+ printf("PMD@0x%016lx->0x%016lx\n", pmdp, pmd_val(*pmdp));
+
+ /* pte_offset_map is the same as pte_offset_kernel */
+ ptep = pte_offset_kernel(pmdp, addr);
+ if (pte_none(*ptep)) {
+ printf("no valid PTE\n");
+ return;
+ }
+
+ format_pte(pte_val(*ptep));
+
+ sync();
+ __delay(200);
+ catch_memory_errors = 0;
+}
static void show_tasks(void)
{
unsigned long tskv;
--
2.9.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v2] powerpc/xmon: Support dumping software pagetables
@ 2017-10-16 3:33 Balbir Singh
2017-10-16 3:36 ` Balbir Singh
0 siblings, 1 reply; 3+ messages in thread
From: Balbir Singh @ 2017-10-16 3:33 UTC (permalink / raw)
To: mpe; +Cc: linuxppc-dev, Balbir Singh
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 v2
- fix powerpc 32 build error, include highmem.h
- remove double semicolon's 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
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v2] powerpc/xmon: Support dumping software pagetables
2017-10-16 3:33 [PATCH v2] powerpc/xmon: Support dumping software pagetables Balbir Singh
@ 2017-10-16 3:36 ` Balbir Singh
0 siblings, 0 replies; 3+ messages in thread
From: Balbir Singh @ 2017-10-16 3:36 UTC (permalink / raw)
To: Michael Ellerman
Cc: open list:LINUX FOR POWERPC (32-BIT AND 64-BIT), Balbir Singh
On Mon, Oct 16, 2017 at 2:33 PM, Balbir Singh <bsingharora@gmail.com> wrote:
> It would be nice to be able to dump page tables in a particular
> context.
>
Should be v4 and not v2.. resending
Balbir
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2017-10-16 3:36 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-10-16 3:33 [PATCH v2] powerpc/xmon: Support dumping software pagetables Balbir Singh
2017-10-16 3:36 ` Balbir Singh
-- strict thread matches above, loose matches on Subject: below --
2017-07-24 7:23 [PATCH v2] powerpc/xmon: support " Balbir Singh
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).