Re: [RFC V2 3/3] mm: Replace pgtable entry prints with new format

From: David Hildenbrand (Arm)

Date: Fri Jun 12 2026 - 07:08:18 EST


On 6/10/26 06:35, Anshuman Khandual wrote:
> Replace all existing pgtable entry prints with recently added new format in
> __print_bad_page_map_pgtable().
>
> Signed-off-by: Anshuman Khandual <anshuman.khandual@xxxxxxx>
> ---
> Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
> Cc: David Hildenbrand <david@xxxxxxxxxx>
> Cc: Lorenzo Stoakes <ljs@xxxxxxxxxx>
> Cc: linux-mm@xxxxxxxxx
> Cc: linux-kernel@xxxxxxxxxxxxxxx
>
> mm/memory.c | 15 +++++----------
> 1 file changed, 5 insertions(+), 10 deletions(-)
>
> diff --git a/mm/memory.c b/mm/memory.c
> index 86a973119bd4..8a25790f7c24 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -521,7 +521,6 @@ static bool is_bad_page_map_ratelimited(void)
>
> static void __print_bad_page_map_pgtable(struct mm_struct *mm, unsigned long addr)
> {
> - unsigned long long pgdv, p4dv, pudv, pmdv;
> p4d_t p4d, *p4dp;
> pud_t pud, *pudp;
> pmd_t pmd, *pmdp;
> @@ -532,34 +531,30 @@ static void __print_bad_page_map_pgtable(struct mm_struct *mm, unsigned long add
> * see locking requirements for print_bad_page_map().
> */
> pgdp = pgd_offset(mm, addr);
> - pgdv = pgd_val(*pgdp);
>
> if (!pgd_present(*pgdp) || pgd_leaf(*pgdp)) {
> - pr_alert("pgd:%08llx\n", pgdv);
> + pr_alert("pgd:%ppgd\n", pgdp);
> return;
> }
>
> p4dp = p4d_offset(pgdp, addr);
> p4d = p4dp_get(p4dp);
> - p4dv = p4d_val(p4d);
>
> if (!p4d_present(p4d) || p4d_leaf(p4d)) {
> - pr_alert("pgd:%08llx p4d:%08llx\n", pgdv, p4dv);
> + pr_alert("pgd:%ppgd p4d:%pp4d\n", pgdp, p4dp);
> return;
> }
>
> pudp = pud_offset(p4dp, addr);
> pud = pudp_get(pudp);
> - pudv = pud_val(pud);
>
> if (!pud_present(pud) || pud_leaf(pud)) {
> - pr_alert("pgd:%08llx p4d:%08llx pud:%08llx\n", pgdv, p4dv, pudv);
> + pr_alert("pgd:%ppgd p4d:%pp4d pud:%ppud\n", pgdp, p4dp, pudp);
> return;
> }
>
> pmdp = pmd_offset(pudp, addr);
> pmd = pmdp_get(pmdp);
> - pmdv = pmd_val(pmd);
>
> /*
> * Dumping the PTE would be nice, but it's tricky with CONFIG_HIGHPTE,
> @@ -567,8 +562,8 @@ static void __print_bad_page_map_pgtable(struct mm_struct *mm, unsigned long add
> * doing another map would be bad. print_bad_page_map() should
> * already take care of printing the PTE.
> */
> - pr_alert("pgd:%08llx p4d:%08llx pud:%08llx pmd:%08llx\n", pgdv,
> - p4dv, pudv, pmdv);
> + pr_alert("pgd:%ppgd p4d:%pp4d pud:%ppud pmd:%ppmd\n", pgdp,
> + p4dp, pudp, pmdp);
> }
>
> /*


After some off-list discussion, I wonder if we can make our life easier.

I think, even with your patch, there is still the case:

pr_alert("BUG: Bad page map in process %s %s:%08llx", current->comm,
pgtable_level_to_str(level), entry);

Where we cast all entries to an "unsigned long" in the callers. We'd have to rework all
that for 128bit entries either way (passing them in some struct instead).

I really just extended what we used to do here in print_bad_pte() before commit ec63a44011d.

Maybe we should just drop the "print the involved page table entries" thing?

I mean, we do have the actual page, and we do have the address in the address space, which
we all print.

Not sure if the actual page table entries are that relevant? Would clean up nicely: