Commit f5295bd8 authored by Laurent Dufour's avatar Laurent Dufour Committed by Benjamin Herrenschmidt

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: default avatarLaurent Dufour <ldufour@linux.vnet.ibm.com>
Tested-by: default avatarMahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
CC: <stable@vger.kernel.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 41dd03a9
...@@ -98,17 +98,19 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, ...@@ -98,17 +98,19 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
size_t csize, unsigned long offset, int userbuf) size_t csize, unsigned long offset, int userbuf)
{ {
void *vaddr; void *vaddr;
phys_addr_t paddr;
if (!csize) if (!csize)
return 0; return 0;
csize = min_t(size_t, csize, PAGE_SIZE); csize = min_t(size_t, csize, PAGE_SIZE);
paddr = pfn << PAGE_SHIFT;
if ((min_low_pfn < pfn) && (pfn < max_pfn)) { if (memblock_is_region_memory(paddr, csize)) {
vaddr = __va(pfn << PAGE_SHIFT); vaddr = __va(paddr);
csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf);
} else { } else {
vaddr = __ioremap(pfn << PAGE_SHIFT, PAGE_SIZE, 0); vaddr = __ioremap(paddr, PAGE_SIZE, 0);
csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf);
iounmap(vaddr); iounmap(vaddr);
} }
......
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