diff --git a/arch/powerpc/mm/ptdump/ptdump.c b/arch/powerpc/mm/ptdump/ptdump.c
index aca354fb670b..63672aa656e8 100644
--- a/arch/powerpc/mm/ptdump/ptdump.c
+++ b/arch/powerpc/mm/ptdump/ptdump.c
@@ -20,6 +20,7 @@
#include <linux/seq_file.h>
#include <asm/fixmap.h>
#include <linux/const.h>
+#include <linux/kasan.h>
#include <asm/page.h>
#include <asm/hugetlb.h>
@@ -317,6 +318,23 @@ static void walk_pud(struct pg_state *st, p4d_t *p4d, unsigned long start)
unsigned long addr;
unsigned int i;
+#if defined(CONFIG_KASAN) && defined(CONFIG_PPC_BOOK3S_64)
+ /*
+ * On radix + KASAN, we want to check for the KASAN "early" shadow
+ * which covers huge quantities of memory with the same set of
+ * read-only PTEs. If it is, we want to note the first page (to see
+ * the status change), and then note the last page. This gives us good
+ * results without spending ages noting the exact same PTEs over 100s of
+ * terabytes of memory.
+ */
+ if (p4d_page(*p4d) == virt_to_page(lm_alias(kasan_early_shadow_pud))) {
+ walk_pmd(st, pud, start);
+ addr = start + (PTRS_PER_PUD - 1) * PUD_SIZE;
+ walk_pmd(st, pud, addr);
+ return;
+ }
+#endif
+
for (i = 0; i < PTRS_PER_PUD; i++, pud++) {
addr = start + i * PUD_SIZE;
if (!pud_none(*pud) && !pud_is_leaf(*pud))