]> git.ipfire.org Git - thirdparty/linux.git/blobdiff - arch/x86/mm/dump_pagetables.c
x86: mm: ptdump: calculate effective permissions correctly
[thirdparty/linux.git] / arch / x86 / mm / dump_pagetables.c
index 69309cd56fdf3fb28c8b7732297471ba69f46686..33093fdedb02d28602f2f634338adc16dea7eee6 100644 (file)
@@ -249,10 +249,22 @@ static void note_wx(struct pg_state *st, unsigned long addr)
                  (void *)st->start_address);
 }
 
-static inline pgprotval_t effective_prot(pgprotval_t prot1, pgprotval_t prot2)
+static void effective_prot(struct ptdump_state *pt_st, int level, u64 val)
 {
-       return (prot1 & prot2 & (_PAGE_USER | _PAGE_RW)) |
-              ((prot1 | prot2) & _PAGE_NX);
+       struct pg_state *st = container_of(pt_st, struct pg_state, ptdump);
+       pgprotval_t prot = val & PTE_FLAGS_MASK;
+       pgprotval_t effective;
+
+       if (level > 0) {
+               pgprotval_t higher_prot = st->prot_levels[level - 1];
+
+               effective = (higher_prot & prot & (_PAGE_USER | _PAGE_RW)) |
+                           ((higher_prot | prot) & _PAGE_NX);
+       } else {
+               effective = prot;
+       }
+
+       st->prot_levels[level] = effective;
 }
 
 /*
@@ -270,16 +282,10 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
        struct seq_file *m = st->seq;
 
        new_prot = val & PTE_FLAGS_MASK;
-
-       if (level > 0) {
-               new_eff = effective_prot(st->prot_levels[level - 1],
-                                        new_prot);
-       } else {
-               new_eff = new_prot;
-       }
-
-       if (level >= 0)
-               st->prot_levels[level] = new_eff;
+       if (!val)
+               new_eff = 0;
+       else
+               new_eff = st->prot_levels[level];
 
        /*
         * If we have a "break" in the series, we need to flush the state that
@@ -374,6 +380,7 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m,
        struct pg_state st = {
                .ptdump = {
                        .note_page      = note_page,
+                       .effective_prot = effective_prot,
                        .range          = ptdump_ranges
                },
                .level = -1,