Skip to content

Commit aaa2295

Browse files
oohalmpe
authored andcommitted
powerpc/mm: Add physical address to Linux page table dump
The current page table dumper scans the Linux page tables and coalesces mappings with adjacent virtual addresses and similar PTE flags. This behaviour is somewhat broken when you consider the IOREMAP space where entirely unrelated mappings will appear to be virtually contiguous. This patch modifies the range coalescing so that only ranges that are both physically and virtually contiguous are combined. This patch also adds to the dump output the physical address at the start of each range. Fixes: 8eb07b1 ("powerpc/mm: Dump linux pagetables") Signed-off-by: Oliver O'Halloran <oohall@gmail.com> [mpe: Print the physicall address with 0x like the other addresses] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
1 parent 70538ea commit aaa2295

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

arch/powerpc/mm/dump_linuxpagetables.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ struct pg_state {
5656
struct seq_file *seq;
5757
const struct addr_marker *marker;
5858
unsigned long start_address;
59+
unsigned long start_pa;
60+
unsigned long last_pa;
5961
unsigned int level;
6062
u64 current_flags;
6163
};
@@ -265,7 +267,9 @@ static void dump_addr(struct pg_state *st, unsigned long addr)
265267
const char *unit = units;
266268
unsigned long delta;
267269

268-
seq_printf(st->seq, "0x%016lx-0x%016lx ", st->start_address, addr-1);
270+
seq_printf(st->seq, "0x%016lx-0x%016lx ", st->start_address, addr-1);
271+
seq_printf(st->seq, "0x%016lx ", st->start_pa);
272+
269273
delta = (addr - st->start_address) >> 10;
270274
/* Work out what appropriate unit to use */
271275
while (!(delta & 1023) && unit[1]) {
@@ -280,21 +284,27 @@ static void note_page(struct pg_state *st, unsigned long addr,
280284
unsigned int level, u64 val)
281285
{
282286
u64 flag = val & pg_level[level].mask;
287+
u64 pa = val & PTE_RPN_MASK;
288+
283289
/* At first no level is set */
284290
if (!st->level) {
285291
st->level = level;
286292
st->current_flags = flag;
287293
st->start_address = addr;
294+
st->start_pa = pa;
295+
st->last_pa = pa;
288296
seq_printf(st->seq, "---[ %s ]---\n", st->marker->name);
289297
/*
290298
* Dump the section of virtual memory when:
291299
* - the PTE flags from one entry to the next differs.
292300
* - we change levels in the tree.
293301
* - the address is in a different section of memory and is thus
294302
* used for a different purpose, regardless of the flags.
303+
* - the pa of this page is not adjacent to the last inspected page
295304
*/
296305
} else if (flag != st->current_flags || level != st->level ||
297-
addr >= st->marker[1].start_address) {
306+
addr >= st->marker[1].start_address ||
307+
pa != st->last_pa + PAGE_SIZE) {
298308

299309
/* Check the PTE flags */
300310
if (st->current_flags) {
@@ -318,8 +328,12 @@ static void note_page(struct pg_state *st, unsigned long addr,
318328
seq_printf(st->seq, "---[ %s ]---\n", st->marker->name);
319329
}
320330
st->start_address = addr;
331+
st->start_pa = pa;
332+
st->last_pa = pa;
321333
st->current_flags = flag;
322334
st->level = level;
335+
} else {
336+
st->last_pa = pa;
323337
}
324338
}
325339

0 commit comments

Comments
 (0)