History

mm: ptdump: reduce level numbers by 1 in note_page()

Rather than having to increment the 'depth' number by 1 in ptdump_hole(), let's change the meaning of 'level' in note_page() since that makes the code simplier. Note that for x86, the level numbers were previously increased by 1 in commit 45dcd2091363 ("x86/mm/dump_pagetables: Fix printout of p4d level") and the comment "Bit 7 has a different meaning" was not updated, so this change also makes the code match the comment again.

Steven Price committed 6 years ago

Commit f8f0d0b1 parent 9c7869c4 files · +22 −20Browse files

Unified · Split

4 files
  1. arch/arm64/mm/dump.c +3 −3
  2. arch/x86/mm/dump_pagetables.c +10 −9
  3. include/linux/ptdump.h +1 −0
  4. mm/ptdump.c +8 −8
arch/arm64/mm/dump.c+3−3
@@ -176,8 +176,7 @@ struct pg_level { · 175 unmodified lines
176176 };
177177
178178 static struct pg_level pg_level[] = {
179− {
180− }, { /* pgd */
179+ { /* pgd */
181180 .name = "PGD",
182181 .bits = pte_bits,
183182 .num = ARRAY_SIZE(pte_bits),
@@ -257,7 +256,7 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level, · 73 unmodified lines
257256 if (level >= 0)
258257 prot = val & pg_level[level].mask;
259258
260− if (!st->level) {
259+ if (st->level == -1) {
261260 st->level = level;
262261 st->current_prot = prot;
263262 st->start_address = addr;
@@ -351,6 +350,7 @@ void ptdump_check_wx(void) · 87 unmodified lines
351350 { 0, NULL},
352351 { -1, NULL},
353352 },
353+ .level = -1,
354354 .check_wx = true,
355355 .ptdump = {
356356 .note_page = note_page,
arch/x86/mm/dump_pagetables.c+10−9
@@ -180,7 +180,7 @@ static struct addr_marker address_markers[] = { · 179 unmodified lines
180180 static void printk_prot(struct seq_file *m, pgprotval_t pr, int level, bool dmsg)
181181 {
182182 static const char * const level_name[] =
183− { "cr3", "pgd", "p4d", "pud", "pmd", "pte" };
183+ { "pgd", "p4d", "pud", "pmd", "pte" };
184184
185185 if (!(pr & _PAGE_PRESENT)) {
186186 /* Not present */
@@ -204,12 +204,12 @@ static void printk_prot(struct seq_file *m, pgprotval_t pr, int level, bool dmsg · 17 unmodified lines
204204 pt_dump_cont_printf(m, dmsg, " ");
205205
206206 /* Bit 7 has a different meaning on level 3 vs 4 */
207− if (level <= 4 && pr & _PAGE_PSE)
207+ if (level <= 3 && pr & _PAGE_PSE)
208208 pt_dump_cont_printf(m, dmsg, "PSE ");
209209 else
210210 pt_dump_cont_printf(m, dmsg, " ");
211− if ((level == 5 && pr & _PAGE_PAT) ||
212− ((level == 4 || level == 3) && pr & _PAGE_PAT_LARGE))
211+ if ((level == 4 && pr & _PAGE_PAT) ||
212+ ((level == 3 || level == 2) && pr & _PAGE_PAT_LARGE))
213213 pt_dump_cont_printf(m, dmsg, "PAT ");
214214 else
215215 pt_dump_cont_printf(m, dmsg, " ");
@@ -271,15 +271,15 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level, · 55 unmodified lines
271271
272272 new_prot = val & PTE_FLAGS_MASK;
273273
274− if (level > 1) {
275− new_eff = effective_prot(st->prot_levels[level - 2],
274+ if (level > 0) {
275+ new_eff = effective_prot(st->prot_levels[level - 1],
276276 new_prot);
277277 } else {
278278 new_eff = new_prot;
279279 }
280280
281− if (level > 0)
282− st->prot_levels[level - 1] = new_eff;
281+ if (level >= 0)
282+ st->prot_levels[level] = new_eff;
283283
284284 /*
285285 * If we have a "break" in the series, we need to flush the state that
@@ -289,7 +289,7 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level, · 3 unmodified lines
289289 cur = st->current_prot;
290290 eff = st->effective_prot;
291291
292− if (!st->level) {
292+ if (st->level == -1) {
293293 /* First entry */
294294 st->current_prot = new_prot;
295295 st->effective_prot = new_eff;
@@ -380,6 +380,7 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd, · 84 unmodified lines
380380 .note_page = note_page,
381381 .range = ptdump_ranges
382382 },
383+ .level = -1,
383384 .to_dmesg = dmesg,
384385 .check_wx = checkwx,
385386 .seq = m
include/linux/ptdump.h+1−0
@@ -11,6 +11,7 @@ struct ptdump_range { · 10 unmodified lines
1111 };
1212
1313 struct ptdump_state {
14+ /* level is 0:PGD to 4:PTE, or -1 if unknown */
1415 void (*note_page)(struct ptdump_state *st, unsigned long addr,
1516 int level, unsigned long val);
1617 const struct ptdump_range *range;
mm/ptdump.c+8−8
@@ -17,7 +17,7 @@ static inline int note_kasan_page_table(struct mm_walk *walk, · 16 unmodified lines
1717 {
1818 struct ptdump_state *st = walk->private;
1919
20− st->note_page(st, addr, 5, pte_val(kasan_early_shadow_pte[0]));
20+ st->note_page(st, addr, 4, pte_val(kasan_early_shadow_pte[0]));
2121
2222 walk->action = ACTION_CONTINUE;
2323
@@ -37,7 +37,7 @@ static int ptdump_pgd_entry(pgd_t *pgd, unsigned long addr, · 13 unmodified lines
3737 #endif
3838
3939 if (pgd_leaf(val))
40− st->note_page(st, addr, 1, pgd_val(val));
40+ st->note_page(st, addr, 0, pgd_val(val));
4141
4242 return 0;
4343 }
@@ -54,7 +54,7 @@ static int ptdump_p4d_entry(p4d_t *p4d, unsigned long addr, · 10 unmodified lines
5454 #endif
5555
5656 if (p4d_leaf(val))
57− st->note_page(st, addr, 2, p4d_val(val));
57+ st->note_page(st, addr, 1, p4d_val(val));
5858
5959 return 0;
6060 }
@@ -71,7 +71,7 @@ static int ptdump_pud_entry(pud_t *pud, unsigned long addr, · 10 unmodified lines
7171 #endif
7272
7373 if (pud_leaf(val))
74− st->note_page(st, addr, 3, pud_val(val));
74+ st->note_page(st, addr, 2, pud_val(val));
7575
7676 return 0;
7777 }
@@ -88,7 +88,7 @@ static int ptdump_pmd_entry(pmd_t *pmd, unsigned long addr, · 10 unmodified lines
8888 #endif
8989
9090 if (pmd_leaf(val))
91− st->note_page(st, addr, 4, pmd_val(val));
91+ st->note_page(st, addr, 3, pmd_val(val));
9292
9393 return 0;
9494 }
@@ -98,7 +98,7 @@ static int ptdump_pte_entry(pte_t *pte, unsigned long addr, · 3 unmodified lines
9898 {
9999 struct ptdump_state *st = walk->private;
100100
101− st->note_page(st, addr, 5, pte_val(READ_ONCE(*pte)));
101+ st->note_page(st, addr, 4, pte_val(READ_ONCE(*pte)));
102102
103103 return 0;
104104 }
@@ -108,7 +108,7 @@ static int ptdump_hole(unsigned long addr, unsigned long next, · 3 unmodified lines
108108 {
109109 struct ptdump_state *st = walk->private;
110110
111− st->note_page(st, addr, depth + 1, 0);
111+ st->note_page(st, addr, depth, 0);
112112
113113 return 0;
114114 }
@@ -135,5 +135,5 @@ void ptdump_walk_pgd(struct ptdump_state *st, struct mm_struct *mm) · 20 unmodified lines
135135 up_read(&mm->mmap_sem);
136136
137137 /* Flush out the last page */
138− st->note_page(st, 0, 0, 0);
138+ st->note_page(st, 0, -1, 0);
139139 }