st->prot_levels[level] = effective;
 }
 
+static void effective_prot_pte(struct ptdump_state *st, pte_t pte)
+{
+       effective_prot(st, 4, pte_val(pte));
+}
+
+static void effective_prot_pmd(struct ptdump_state *st, pmd_t pmd)
+{
+       effective_prot(st, 3, pmd_val(pmd));
+}
+
+static void effective_prot_pud(struct ptdump_state *st, pud_t pud)
+{
+       effective_prot(st, 2, pud_val(pud));
+}
+
+static void effective_prot_p4d(struct ptdump_state *st, p4d_t p4d)
+{
+       effective_prot(st, 1, p4d_val(p4d));
+}
+
+static void effective_prot_pgd(struct ptdump_state *st, pgd_t pgd)
+{
+       effective_prot(st, 0, pgd_val(pgd));
+}
+
+
 /*
  * This function gets called on a break in a continuous series
  * of PTE entries; the next one is different so we need to
                        .note_page_p4d = note_page_p4d,
                        .note_page_pgd = note_page_pgd,
                        .note_page_flush = note_page_flush,
-                       .effective_prot = effective_prot,
+                       .effective_prot_pte = effective_prot_pte,
+                       .effective_prot_pmd = effective_prot_pmd,
+                       .effective_prot_pud = effective_prot_pud,
+                       .effective_prot_p4d = effective_prot_p4d,
+                       .effective_prot_pgd = effective_prot_pgd,
                        .range          = ptdump_ranges
                },
                .level = -1,
 
        void (*note_page_p4d)(struct ptdump_state *st, unsigned long addr, p4d_t p4d);
        void (*note_page_pgd)(struct ptdump_state *st, unsigned long addr, pgd_t pgd);
        void (*note_page_flush)(struct ptdump_state *st);
-       void (*effective_prot)(struct ptdump_state *st, int level, u64 val);
+       void (*effective_prot_pte)(struct ptdump_state *st, pte_t pte);
+       void (*effective_prot_pmd)(struct ptdump_state *st, pmd_t pmd);
+       void (*effective_prot_pud)(struct ptdump_state *st, pud_t pud);
+       void (*effective_prot_p4d)(struct ptdump_state *st, p4d_t p4d);
+       void (*effective_prot_pgd)(struct ptdump_state *st, pgd_t pgd);
        const struct ptdump_range *range;
 };
 
 
                return note_kasan_page_table(walk, addr);
 #endif
 
-       if (st->effective_prot)
-               st->effective_prot(st, 0, pgd_val(val));
+       if (st->effective_prot_pgd)
+               st->effective_prot_pgd(st, val);
 
        if (pgd_leaf(val)) {
                st->note_page_pgd(st, addr, val);
                return note_kasan_page_table(walk, addr);
 #endif
 
-       if (st->effective_prot)
-               st->effective_prot(st, 1, p4d_val(val));
+       if (st->effective_prot_p4d)
+               st->effective_prot_p4d(st, val);
 
        if (p4d_leaf(val)) {
                st->note_page_p4d(st, addr, val);
                return note_kasan_page_table(walk, addr);
 #endif
 
-       if (st->effective_prot)
-               st->effective_prot(st, 2, pud_val(val));
+       if (st->effective_prot_pud)
+               st->effective_prot_pud(st, val);
 
        if (pud_leaf(val)) {
                st->note_page_pud(st, addr, val);
                return note_kasan_page_table(walk, addr);
 #endif
 
-       if (st->effective_prot)
-               st->effective_prot(st, 3, pmd_val(val));
+       if (st->effective_prot_pmd)
+               st->effective_prot_pmd(st, val);
        if (pmd_leaf(val)) {
                st->note_page_pmd(st, addr, val);
                walk->action = ACTION_CONTINUE;
        struct ptdump_state *st = walk->private;
        pte_t val = ptep_get_lockless(pte);
 
-       if (st->effective_prot)
-               st->effective_prot(st, 4, pte_val(val));
+       if (st->effective_prot_pte)
+               st->effective_prot_pte(st, val);
 
        st->note_page_pte(st, addr, val);