]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
arm64: ptdump: Expose the attribute parsing functionality
authorSebastian Ene <sebastianene@google.com>
Mon, 9 Sep 2024 12:47:18 +0000 (12:47 +0000)
committerMarc Zyngier <maz@kernel.org>
Tue, 10 Sep 2024 20:31:59 +0000 (21:31 +0100)
Reuse the descriptor parsing functionality to keep the same output format
as the original ptdump code. In order for this to happen, move the state
tracking objects into a common header.

[maz: Fixed note_page() stub as suggested by Will]

Signed-off-by: Sebastian Ene <sebastianene@google.com>
Acked-by: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20240909124721.1672199-3-sebastianene@google.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/include/asm/ptdump.h
arch/arm64/mm/ptdump.c

index 5b1701c76d1cec2b26f23b198d8528fb2aec8806..aa46b5d2cf85010d5e94c28fb9d65b5b4797173d 100644 (file)
@@ -5,6 +5,8 @@
 #ifndef __ASM_PTDUMP_H
 #define __ASM_PTDUMP_H
 
+#include <linux/ptdump.h>
+
 #ifdef CONFIG_PTDUMP_CORE
 
 #include <linux/mm_types.h>
@@ -21,14 +23,52 @@ struct ptdump_info {
        unsigned long                   base_addr;
 };
 
+struct ptdump_prot_bits {
+       u64             mask;
+       u64             val;
+       const char      *set;
+       const char      *clear;
+};
+
+struct ptdump_pg_level {
+       const struct ptdump_prot_bits *bits;
+       char name[4];
+       int num;
+       u64 mask;
+};
+
+/*
+ * The page dumper groups page table entries of the same type into a single
+ * description. It uses pg_state to track the range information while
+ * iterating over the pte entries. When the continuity is broken it then
+ * dumps out a description of the range.
+ */
+struct ptdump_pg_state {
+       struct ptdump_state ptdump;
+       struct seq_file *seq;
+       const struct addr_marker *marker;
+       const struct mm_struct *mm;
+       unsigned long start_address;
+       int level;
+       u64 current_prot;
+       bool check_wx;
+       unsigned long wx_pages;
+       unsigned long uxn_pages;
+};
+
 void ptdump_walk(struct seq_file *s, struct ptdump_info *info);
+void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
+              u64 val);
 #ifdef CONFIG_PTDUMP_DEBUGFS
 #define EFI_RUNTIME_MAP_END    DEFAULT_MAP_WINDOW_64
 void __init ptdump_debugfs_register(struct ptdump_info *info, const char *name);
 #else
 static inline void ptdump_debugfs_register(struct ptdump_info *info,
                                           const char *name) { }
-#endif
+#endif /* CONFIG_PTDUMP_DEBUGFS */
+#else
+static inline void note_page(struct ptdump_state *pt_st, unsigned long addr,
+                            int level, u64 val) { }
 #endif /* CONFIG_PTDUMP_CORE */
 
 #endif /* __ASM_PTDUMP_H */
index 6986827e0d64519bdddcb706bb36f7e0baf269ab..404751fd30fe5856c16016f930012a592498e39f 100644 (file)
                seq_printf(m, fmt);     \
 })
 
-/*
- * The page dumper groups page table entries of the same type into a single
- * description. It uses pg_state to track the range information while
- * iterating over the pte entries. When the continuity is broken it then
- * dumps out a description of the range.
- */
-struct pg_state {
-       struct ptdump_state ptdump;
-       struct seq_file *seq;
-       const struct addr_marker *marker;
-       const struct mm_struct *mm;
-       unsigned long start_address;
-       int level;
-       u64 current_prot;
-       bool check_wx;
-       unsigned long wx_pages;
-       unsigned long uxn_pages;
-};
-
-struct prot_bits {
-       u64             mask;
-       u64             val;
-       const char      *set;
-       const char      *clear;
-};
-
-static const struct prot_bits pte_bits[] = {
+static const struct ptdump_prot_bits pte_bits[] = {
        {
                .mask   = PTE_VALID,
                .val    = PTE_VALID,
@@ -143,14 +117,7 @@ static const struct prot_bits pte_bits[] = {
        }
 };
 
-struct pg_level {
-       const struct prot_bits *bits;
-       char name[4];
-       int num;
-       u64 mask;
-};
-
-static struct pg_level pg_level[] __ro_after_init = {
+static struct ptdump_pg_level pg_level[] __ro_after_init = {
        { /* pgd */
                .name   = "PGD",
                .bits   = pte_bits,
@@ -174,7 +141,7 @@ static struct pg_level pg_level[] __ro_after_init = {
        },
 };
 
-static void dump_prot(struct pg_state *st, const struct prot_bits *bits,
+static void dump_prot(struct ptdump_pg_state *st, const struct ptdump_prot_bits *bits,
                        size_t num)
 {
        unsigned i;
@@ -192,7 +159,7 @@ static void dump_prot(struct pg_state *st, const struct prot_bits *bits,
        }
 }
 
-static void note_prot_uxn(struct pg_state *st, unsigned long addr)
+static void note_prot_uxn(struct ptdump_pg_state *st, unsigned long addr)
 {
        if (!st->check_wx)
                return;
@@ -206,7 +173,7 @@ static void note_prot_uxn(struct pg_state *st, unsigned long addr)
        st->uxn_pages += (addr - st->start_address) / PAGE_SIZE;
 }
 
-static void note_prot_wx(struct pg_state *st, unsigned long addr)
+static void note_prot_wx(struct ptdump_pg_state *st, unsigned long addr)
 {
        if (!st->check_wx)
                return;
@@ -221,10 +188,10 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr)
        st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
 }
 
-static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
-                     u64 val)
+void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
+              u64 val)
 {
-       struct pg_state *st = container_of(pt_st, struct pg_state, ptdump);
+       struct ptdump_pg_state *st = container_of(pt_st, struct ptdump_pg_state, ptdump);
        static const char units[] = "KMGTPE";
        u64 prot = 0;
 
@@ -286,12 +253,12 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
 void ptdump_walk(struct seq_file *s, struct ptdump_info *info)
 {
        unsigned long end = ~0UL;
-       struct pg_state st;
+       struct ptdump_pg_state st;
 
        if (info->base_addr < TASK_SIZE_64)
                end = TASK_SIZE_64;
 
-       st = (struct pg_state){
+       st = (struct ptdump_pg_state){
                .seq = s,
                .marker = info->markers,
                .mm = info->mm,
@@ -324,7 +291,7 @@ static struct ptdump_info kernel_ptdump_info __ro_after_init = {
 
 bool ptdump_check_wx(void)
 {
-       struct pg_state st = {
+       struct ptdump_pg_state st = {
                .seq = NULL,
                .marker = (struct addr_marker[]) {
                        { 0, NULL},