|
@@ -16,6 +16,22 @@ static void *kdump_buf_page;
|
|
|
/* Stores the physical address of elf header of crash image. */
|
|
|
unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
|
|
|
|
|
|
+static inline bool is_crashed_pfn_valid(unsigned long pfn)
|
|
|
+{
|
|
|
+#ifndef CONFIG_X86_PAE
|
|
|
+ /*
|
|
|
+ * non-PAE kdump kernel executed from a PAE one will crop high pte
|
|
|
+ * bits and poke unwanted space counting again from address 0, we
|
|
|
+ * don't want that. pte must fit into unsigned long. In fact the
|
|
|
+ * test checks high 12 bits for being zero (pfn will be shifted left
|
|
|
+ * by PAGE_SHIFT).
|
|
|
+ */
|
|
|
+ return pte_pfn(pfn_pte(pfn, __pgprot(0))) == pfn;
|
|
|
+#else
|
|
|
+ return true;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* copy_oldmem_page - copy one page from "oldmem"
|
|
|
* @pfn: page frame number to be copied
|
|
@@ -41,6 +57,9 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
|
|
|
if (!csize)
|
|
|
return 0;
|
|
|
|
|
|
+ if (!is_crashed_pfn_valid(pfn))
|
|
|
+ return -EFAULT;
|
|
|
+
|
|
|
vaddr = kmap_atomic_pfn(pfn, KM_PTE0);
|
|
|
|
|
|
if (!userbuf) {
|