Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

powerpc/crashdump : Fix page frame number check in copy_oldmem_page

In copy_oldmem_page, the current check using max_pfn and min_low_pfn to
decide if the page is backed or not, is not valid when the memory layout is
not continuous.

This happens when running as a QEMU/KVM guest, where RTAS is mapped higher
in the memory. In that case max_pfn points to the end of RTAS, and a hole
between the end of the kdump kernel and RTAS is not backed by PTEs. As a
consequence, the kdump kernel is crashing in copy_oldmem_page when accessing
in a direct way the pages in that hole.

This fix relies on the memblock's service memblock_is_region_memory to
check if the read page is part or not of the directly accessible memory.

Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
Tested-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
CC: <stable@vger.kernel.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

authored by

Laurent Dufour and committed by
Benjamin Herrenschmidt
f5295bd8 41dd03a9

+5 -3
+5 -3
arch/powerpc/kernel/crash_dump.c
··· 98 98 size_t csize, unsigned long offset, int userbuf) 99 99 { 100 100 void *vaddr; 101 + phys_addr_t paddr; 101 102 102 103 if (!csize) 103 104 return 0; 104 105 105 106 csize = min_t(size_t, csize, PAGE_SIZE); 107 + paddr = pfn << PAGE_SHIFT; 106 108 107 - if ((min_low_pfn < pfn) && (pfn < max_pfn)) { 108 - vaddr = __va(pfn << PAGE_SHIFT); 109 + if (memblock_is_region_memory(paddr, csize)) { 110 + vaddr = __va(paddr); 109 111 csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); 110 112 } else { 111 - vaddr = __ioremap(pfn << PAGE_SHIFT, PAGE_SIZE, 0); 113 + vaddr = __ioremap(paddr, PAGE_SIZE, 0); 112 114 csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); 113 115 iounmap(vaddr); 114 116 }