OSDN Git Service

powerpc: dump as a single line areas mapping a single physical page.
authorChristophe Leroy <christophe.leroy@c-s.fr>
Mon, 18 Feb 2019 12:25:20 +0000 (12:25 +0000)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 21 Feb 2019 13:10:16 +0000 (00:10 +1100)
When using KASAN, there are parts of the shadow area where all
pages are mapped to the kasan_early_shadow_page. It is pointless
to dump one line for each of those pages (in the example below there
are 7168 entries pointing to the same physical page).

~# cat /sys/kernel/debug/kernel_page_tables
 ...
---[ kasan shadow mem start ]---
0xf7c00000-0xf8bfffff 0x06fac000       16M        rw       present           dirty  accessed
0xf8c00000-0xf8c03fff 0x00cd0000       16K        r        present           dirty  accessed
0xf8c04000-0xf8c07fff 0x00cd0000       16K        r        present           dirty  accessed
0xf8c08000-0xf8c0bfff 0x00cd0000       16K        r        present           dirty  accessed
0xf8c0c000-0xf8c0ffff 0x00cd0000       16K        r        present           dirty  accessed
0xf8c10000-0xf8c13fff 0x00cd0000       16K        r        present           dirty  accessed
 ... 7168 identical lines
0xffbfc000-0xffbfffff 0x00cd0000       16K        r        present           dirty  accessed
---[ kasan shadow mem end ]---
 ...

This patch modifies linux table dump to dump as a single line areas
where all addresses points to the same physical page. That physical
address is put inside [] to show that all virt pages points to the
same phys page.

~# cat /sys/kernel/debug/kernel_page_tables
 ...
---[ kasan shadow mem start ]---
0xf7c00000-0xf8bfffff  0x06fac000        16M        rw       present           dirty  accessed
0xf8c00000-0xffbfffff [0x00cd0000]       16K        r        present           dirty  accessed
---[ kasan shadow mem end ]---
 ...

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/mm/dump_linuxpagetables.c

index 6aa4166..b0da447 100644 (file)
@@ -143,14 +143,19 @@ static void dump_addr(struct pg_state *st, unsigned long addr)
        unsigned long delta;
 
 #ifdef CONFIG_PPC64
-       seq_printf(st->seq, "0x%016lx-0x%016lx ", st->start_address, addr-1);
-       seq_printf(st->seq, "0x%016lx ", st->start_pa);
+#define REG            "0x%016lx"
 #else
-       seq_printf(st->seq, "0x%08lx-0x%08lx ", st->start_address, addr - 1);
-       seq_printf(st->seq, "0x%08lx ", st->start_pa);
+#define REG            "0x%08lx"
 #endif
 
-       delta = (addr - st->start_address) >> 10;
+       seq_printf(st->seq, REG "-" REG " ", st->start_address, addr - 1);
+       if (st->start_pa == st->last_pa && st->start_address + PAGE_SIZE != addr) {
+               seq_printf(st->seq, "[" REG "]", st->start_pa);
+               delta = PAGE_SIZE >> 10;
+       } else {
+               seq_printf(st->seq, " " REG " ", st->start_pa);
+               delta = (addr - st->start_address) >> 10;
+       }
        /* Work out what appropriate unit to use */
        while (!(delta & 1023) && unit[1]) {
                delta >>= 10;
@@ -184,7 +189,8 @@ static void note_page(struct pg_state *st, unsigned long addr,
         */
        } else if (flag != st->current_flags || level != st->level ||
                   addr >= st->marker[1].start_address ||
-                  pa != st->last_pa + PAGE_SIZE) {
+                  (pa != st->last_pa + PAGE_SIZE &&
+                   (pa != st->start_pa || st->start_pa != st->last_pa))) {
 
                /* Check the PTE flags */
                if (st->current_flags) {