Commit f9fde787 authored by Michael Ellerman's avatar Michael Ellerman Committed by Greg Kroah-Hartman

powerpc/mm: Fix crash in page table dump with huge pages

commit bfb9956a upstream.

The page table dump code doesn't know about huge pages, so currently
it crashes (or walks random memory, usually leading to a crash), if it
finds a huge page. On Book3S we only see huge pages in the Linux page
tables when we're using the P9 Radix MMU.

Teaching the code to properly handle huge pages is a bit more involved,
so for now just prevent the crash.

Fixes: 8eb07b18 ("powerpc/mm: Dump linux pagetables")
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1d19e3f1
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
*/ */
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/hugetlb.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/sched.h> #include <linux/sched.h>
...@@ -331,7 +332,7 @@ static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start) ...@@ -331,7 +332,7 @@ static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start)
for (i = 0; i < PTRS_PER_PMD; i++, pmd++) { for (i = 0; i < PTRS_PER_PMD; i++, pmd++) {
addr = start + i * PMD_SIZE; addr = start + i * PMD_SIZE;
if (!pmd_none(*pmd)) if (!pmd_none(*pmd) && !pmd_huge(*pmd))
/* pmd exists */ /* pmd exists */
walk_pte(st, pmd, addr); walk_pte(st, pmd, addr);
else else
...@@ -347,7 +348,7 @@ static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start) ...@@ -347,7 +348,7 @@ static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start)
for (i = 0; i < PTRS_PER_PUD; i++, pud++) { for (i = 0; i < PTRS_PER_PUD; i++, pud++) {
addr = start + i * PUD_SIZE; addr = start + i * PUD_SIZE;
if (!pud_none(*pud)) if (!pud_none(*pud) && !pud_huge(*pud))
/* pud exists */ /* pud exists */
walk_pmd(st, pud, addr); walk_pmd(st, pud, addr);
else else
...@@ -367,7 +368,7 @@ static void walk_pagetables(struct pg_state *st) ...@@ -367,7 +368,7 @@ static void walk_pagetables(struct pg_state *st)
*/ */
for (i = 0; i < PTRS_PER_PGD; i++, pgd++) { for (i = 0; i < PTRS_PER_PGD; i++, pgd++) {
addr = KERN_VIRT_START + i * PGDIR_SIZE; addr = KERN_VIRT_START + i * PGDIR_SIZE;
if (!pgd_none(*pgd)) if (!pgd_none(*pgd) && !pgd_huge(*pgd))
/* pgd exists */ /* pgd exists */
walk_pud(st, pgd, addr); walk_pud(st, pgd, addr);
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment