[PATCH Makedumpfile 10/10] arm64: fix memory layout as per changes in v4.6 kernel

Pratyush Anand panand at redhat.com
Tue Oct 25 00:23:02 PDT 2016


arm64 memory layout has been changed since 4.6 kernel because of KASLR
support patches.

kimage_voffset is needed to calculate "virtual to physical".

Signed-off-by: Pratyush Anand <panand at redhat.com>
---
 arch/arm64.c   | 16 ++++++++++++++--
 makedumpfile.c |  2 ++
 makedumpfile.h |  1 +
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/arch/arm64.c b/arch/arm64.c
index df58e92536e2..958f57f8e203 100644
--- a/arch/arm64.c
+++ b/arch/arm64.c
@@ -41,10 +41,12 @@ typedef struct {
 
 static int pgtable_level;
 static int va_bits;
+static unsigned long kimage_voffset;
 
 #define SZ_4K			(4 * 1024)
 #define SZ_16K			(16 * 1024)
 #define SZ_64K			(64 * 1024)
+#define SZ_128M			(128 * 1024 * 1024)
 
 #define pgd_val(x)		((x).pgd)
 #define pud_val(x)		(pgd_val((x).pgd))
@@ -77,8 +79,6 @@ static int va_bits;
 #define PMD_TYPE_SECT		1
 #define PMD_TYPE_TABLE		3
 
-#define __pa(vaddr) 			((vaddr) - PAGE_OFFSET + info->phys_base)
-
 #define pgd_index(vaddr) 		(((vaddr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
 #define pgd_offset(pgdir, vaddr)	((pgd_t *)(pgdir) + pgd_index(vaddr))
 
@@ -94,6 +94,16 @@ static int va_bits;
 #define pud_index(vaddr)		(((vaddr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
 #define pgd_page_paddr(pgd)		(pgd_val(pgd) & PHYS_MASK & (int32_t)PAGE_MASK)
 
+static unsigned long long
+__pa(unsigned long vaddr)
+{
+	if (kimage_voffset == NOT_FOUND_NUMBER ||
+			(vaddr >= PAGE_OFFSET))
+		return (vaddr - PAGE_OFFSET + info->phys_base);
+	else
+		return (vaddr - kimage_voffset);
+}
+
 static int
 get_pud_shift_arm64(void)
 {
@@ -169,10 +179,12 @@ get_machdep_info_arm64(void)
 		return FALSE;
 	}
 
+	kimage_voffset = NUMBER(kimage_voffset);
 	info->max_physmem_bits = PHYS_MASK_SHIFT;
 	info->section_size_bits = SECTIONS_SIZE_BITS;
 	info->page_offset = 0xffffffffffffffffUL << (va_bits - 1);
 
+	DEBUG_MSG("kimage_voffset   : %lx\n", kimage_voffset);
 	DEBUG_MSG("max_physmem_bits : %lx\n", info->max_physmem_bits);
 	DEBUG_MSG("section_size_bits: %lx\n", info->section_size_bits);
 	DEBUG_MSG("page_offset      : %lx\n", info->page_offset);
diff --git a/makedumpfile.c b/makedumpfile.c
index df413f066348..1fa9a63359c4 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -2266,6 +2266,7 @@ write_vmcoreinfo_data(void)
 #ifdef __aarch64__
 	WRITE_NUMBER("VA_BITS", VA_BITS);
 	WRITE_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET);
+	WRITE_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset);
 #endif
 
 	/*
@@ -2652,6 +2653,7 @@ read_vmcoreinfo(void)
 #ifdef __aarch64__
 	READ_NUMBER("VA_BITS", VA_BITS);
 	READ_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET);
+	READ_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset);
 #endif
 
 	READ_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR);
diff --git a/makedumpfile.h b/makedumpfile.h
index 8ddc2c43cc29..f0154226bcb8 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -1737,6 +1737,7 @@ struct number_table {
 #ifdef __aarch64__
 	long 	VA_BITS;
 	unsigned long	PHYS_OFFSET;
+	unsigned long	kimage_voffset;
 #endif
 };
 
-- 
2.7.4




More information about the kexec mailing list