[Makedumpfile PATCH v3 2/2] x86_64: calculate page_offset in case of re-filtering/sadump/virsh dump

Pratyush Anand panand at redhat.com
Wed May 24 18:50:29 PDT 2017


we do not call get_elf_info() in case of refiltering and sadump.
Therefore, we will not have any pt_load in that case, and so we get:

get_page_offset_x86_64: Can't get any pt_load to calculate page offset.

However, we will have vmcoreinfo and vmlinux information in case of
re-filtering. So, we are able to find kaslr offset and we can get
page_offset_base address. Thus we can read the page offset as well.

If kaslr is not enabled and also we do not have valid PT_LOAD to
calculate page offset  then use old method to find fixed page
offset.

In case of virsh dump virtual addresses in PT_LOAD are 0. Ignore such
addresses for the page_offset calculation.

Suggested-by: HATAYAMA Daisuke <d.hatayama at jp.fujitsu.com>
Signed-off-by: Pratyush Anand <panand at redhat.com>
---
 arch/x86_64.c | 36 +++++++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/arch/x86_64.c b/arch/x86_64.c
index fd2e8ac154d6..18384a8dd684 100644
--- a/arch/x86_64.c
+++ b/arch/x86_64.c
@@ -75,17 +75,39 @@ get_page_offset_x86_64(void)
 	int i;
 	unsigned long long phys_start;
 	unsigned long long virt_start;
+	unsigned long page_offset_base;
+
+	if (info->kaslr_offset) {
+		page_offset_base = get_symbol_addr("page_offset_base");
+		page_offset_base += info->kaslr_offset;
+		if (!readmem(VADDR, page_offset_base, &info->page_offset,
+					sizeof(info->page_offset))) {
+			 ERRMSG("Can't read page_offset_base.\n");
+			 return FALSE;
+		}
+		return TRUE;
+	}
 
-	for (i = 0; get_pt_load(i, &phys_start, NULL, &virt_start, NULL); i++) {
-		if (virt_start < __START_KERNEL_map
-				&& phys_start != NOT_PADDR) {
-			info->page_offset = virt_start - phys_start;
-			return TRUE;
+	if (get_num_pt_loads()) {
+		for (i = 0;
+			get_pt_load(i, &phys_start, NULL, &virt_start, NULL);
+			i++) {
+			if (virt_start != NOT_KV_ADDR
+					&& virt_start < __START_KERNEL_map
+					&& phys_start != NOT_PADDR) {
+				info->page_offset = virt_start - phys_start;
+				return TRUE;
+			}
 		}
 	}
 
-	ERRMSG("Can't get any pt_load to calculate page offset.\n");
-	return FALSE;
+	if (info->kernel_version < KERNEL_VERSION(2, 6, 27)) {
+		info->page_offset = __PAGE_OFFSET_ORIG;
+	} else {
+		info->page_offset = __PAGE_OFFSET_2_6_27;
+	}
+
+	return TRUE;
 }
 
 int
-- 
2.9.3




More information about the kexec mailing list