From: "David Hildenbrand (Arm)" <[email protected]> The behaviour of pXdp_get() will change with generic compile-time folded page tables. To prepare for that, rework effective_prot() to ignore any folded page tables entries, as it will unconditionally get called by ptdump core with pXd_val(pXdp_get()), and we really should be ignoring that value for folded entries.
For this, introduce ptdump_pt_level_first() to identify the first real page-table level and update effective_prot with higher_prot only when the current entry is not folded nor the first level. There should be no functional change. Signed-off-by: Yeoreum Yun <[email protected]> --- arch/x86/mm/dump_pagetables.c | 5 ++++- include/linux/ptdump.h | 1 + mm/ptdump.c | 11 +++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c index 2afa7a23340e..4e545988953a 100644 --- a/arch/x86/mm/dump_pagetables.c +++ b/arch/x86/mm/dump_pagetables.c @@ -27,6 +27,7 @@ */ struct pg_state { struct ptdump_state ptdump; + int first_level; int level; pgprotval_t current_prot; pgprotval_t effective_prot; @@ -254,7 +255,7 @@ static void effective_prot(struct ptdump_state *pt_st, int level, u64 val) pgprotval_t prot = val & PTE_FLAGS_MASK; pgprotval_t effective; - if (level > 0) { + if (level > st->first_level) { pgprotval_t higher_prot = st->prot_levels[level - 1]; effective = (higher_prot & prot & (_PAGE_USER | _PAGE_RW)) | @@ -455,6 +456,8 @@ bool ptdump_walk_pgd_level_core(struct seq_file *m, .seq = m }; + st.first_level = ptdump_pt_level_first(mm); + ptdump_walk_pgd(&st.ptdump, mm, pgd); if (!checkwx) diff --git a/include/linux/ptdump.h b/include/linux/ptdump.h index 240bd3bff18d..26fa624eac44 100644 --- a/include/linux/ptdump.h +++ b/include/linux/ptdump.h @@ -29,6 +29,7 @@ bool ptdump_walk_pgd_level_core(struct seq_file *m, struct mm_struct *mm, pgd_t *pgd, bool checkwx, bool dmesg); void ptdump_walk_pgd(struct ptdump_state *st, struct mm_struct *mm, pgd_t *pgd); +int ptdump_pt_level_first(struct mm_struct *mm); bool ptdump_check_wx(void); static inline void debug_checkwx(void) diff --git a/mm/ptdump.c b/mm/ptdump.c index 5851096e6f65..96676c90430f 100644 --- a/mm/ptdump.c +++ b/mm/ptdump.c @@ -197,6 +197,17 @@ void ptdump_walk_pgd(struct ptdump_state *st, struct mm_struct *mm, pgd_t *pgd) st->note_page_flush(st); } +int ptdump_pt_level_first(struct mm_struct *mm) +{ + if (mm_pmd_folded(mm)) + return 3; + if (mm_pud_folded(mm)) + return 2; + if (mm_p4d_folded(mm)) + return 1; + return 0; +} + static int check_wx_show(struct seq_file *m, void *v) { if (ptdump_check_wx()) -- 2.43.0

