Commit 48dd73c5 authored by Mark Rutland's avatar Mark Rutland Committed by Will Deacon

arm64: mm: dump: log span level

The page table dump code logs spans of entries at the same level
(pgd/pud/pmd/pte) which have the same attributes. While we log the
(decoded) attributes, we don't log the level, which leaves the output
ambiguous and/or confusing in some cases.

For example:

0xffff800800000000-0xffff800980000000           6G       RW NX SHD AF        BLK UXN MEM/NORMAL

If using 4K pages, this may describe a span of 6 1G block entries at the
PGD/PUD level, or 3072 2M block entries at the PMD level.

This patch adds the page table level to each output line, removing this
ambiguity. For the example above, this will produce:

0xffffffc800000000-0xffffffc980000000           6G PUD       RW NX SHD AF        BLK UXN MEM/NORMAL

When 3 level tables are in use, and we use the asm-generic/nopud.h
definitions, the dump code treats each entry in the PGD as a 1 element
table at the PUD level, and logs spans as being PUDs, which can be
confusing. To counteract this, the "PUD" mnemonic is replaced with "PGD"
when CONFIG_PGTABLE_LEVELS <= 3. Likewise for "PMD" when
CONFIG_PGTABLE_LEVELS <= 2.
Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Huang Shijie <shijie.huang@arm.com>
Cc: Laura Abbott <labbott@fedoraproject.org>
Cc: Steve Capper <steve.capper@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent a13e3a5b
...@@ -150,6 +150,7 @@ static const struct prot_bits pte_bits[] = { ...@@ -150,6 +150,7 @@ static const struct prot_bits pte_bits[] = {
struct pg_level { struct pg_level {
const struct prot_bits *bits; const struct prot_bits *bits;
const char *name;
size_t num; size_t num;
u64 mask; u64 mask;
}; };
...@@ -157,15 +158,19 @@ struct pg_level { ...@@ -157,15 +158,19 @@ struct pg_level {
static struct pg_level pg_level[] = { static struct pg_level pg_level[] = {
{ {
}, { /* pgd */ }, { /* pgd */
.name = "PGD",
.bits = pte_bits, .bits = pte_bits,
.num = ARRAY_SIZE(pte_bits), .num = ARRAY_SIZE(pte_bits),
}, { /* pud */ }, { /* pud */
.name = (CONFIG_PGTABLE_LEVELS > 3) ? "PUD" : "PGD",
.bits = pte_bits, .bits = pte_bits,
.num = ARRAY_SIZE(pte_bits), .num = ARRAY_SIZE(pte_bits),
}, { /* pmd */ }, { /* pmd */
.name = (CONFIG_PGTABLE_LEVELS > 2) ? "PMD" : "PGD",
.bits = pte_bits, .bits = pte_bits,
.num = ARRAY_SIZE(pte_bits), .num = ARRAY_SIZE(pte_bits),
}, { /* pte */ }, { /* pte */
.name = "PTE",
.bits = pte_bits, .bits = pte_bits,
.num = ARRAY_SIZE(pte_bits), .num = ARRAY_SIZE(pte_bits),
}, },
...@@ -214,7 +219,8 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level, ...@@ -214,7 +219,8 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level,
delta >>= 10; delta >>= 10;
unit++; unit++;
} }
seq_printf(st->seq, "%9lu%c", delta, *unit); seq_printf(st->seq, "%9lu%c %s", delta, *unit,
pg_level[st->level].name);
if (pg_level[st->level].bits) if (pg_level[st->level].bits)
dump_prot(st, pg_level[st->level].bits, dump_prot(st, pg_level[st->level].bits,
pg_level[st->level].num); pg_level[st->level].num);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment