Re: [ARM64][patch v5] Auto calculate kimage_voffset by kaslr offset

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2017/3/17 22:25, Dave Anderson wrote:
>
> ----- Original Message -----
>> However, that is why I am interested in your live system initialization
>> of kimage_voffset -- for live system access using /dev/mem, /proc/kcore,
>> or an older version of the /dev/crash driver that did not have the ioctl()
>> to read kimage_voffset.  But, in order to do that, arm64_calc_kimage_voffset()
>> needs to be able to handle all /proc/iomem cases to correctly calculate
>> PHYS_OFFSET.
> Or better stated, your arm64_calc_kimage_voffset() needs to be able to handle all
> /proc/iomem cases to correctly calculate kimage_voffset.  Because on the 4.8
> kernel, it does not work.
>
> Dave
>
> --
> Crash-utility mailing list
> Crash-utility@xxxxxxxxxx
> https://www.redhat.com/mailman/listinfo/crash-utility
Dave,

Sorry for my misunderstanding of PHYS_OFFSET,  actually kimage_voffset 
is the offset between kernel virtual address and physical address. So, 
to calculate it need find out which physical address is mapping to 
VA_START, not PHYS_OFFSET.

Please check patch v5, it should be OK for live system.

Thanks,
Yueyi




From e25004764456e20d8121f9ccc105fb7d408f1948 Mon Sep 17 00:00:00 2001
From: Yueyi Li <liyueyi@xxxxxxxx>
Date: Tue, 14 Mar 2017 21:25:21 +0800
Subject: [PATCH] [ARM64][patch] Auto calculate kimage_voffset by kaslr offset

ARM64 kimage_voffset can be calculated if kernel ASLR offset is known.
Add a function to auto calculate kimage_voffset when '--kaslr=<offset>'
was set.
---
 arm64.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/arm64.c b/arm64.c
index 6eaf96d..01e43e5 100644
--- a/arm64.c
+++ b/arm64.c
@@ -27,6 +27,7 @@
 static struct machine_specific arm64_machine_specific = { 0 };
 static int arm64_verify_symbol(const char *, ulong, char);
 static void arm64_parse_cmdline_args(void);
+static void arm64_calc_kimage_voffset(void);
 static void arm64_calc_phys_offset(void);
 static void arm64_calc_virtual_memory_ranges(void);
 static int arm64_kdump_phys_base(ulong *);
@@ -324,6 +325,9 @@ arm64_init(int when)
 		machdep->init_kernel_pgd = arm64_init_kernel_pgd;
 
 		/* use machdep parameters */
+		arm64_calc_kimage_voffset();
+
+		/* use machdep parameters */
 		arm64_calc_phys_offset();
 	
 		if (CRASHDEBUG(1)) {
@@ -735,6 +739,83 @@ arm64_parse_cmdline_args(void)
 	}
 }
 
+static void
+arm64_calc_kimage_voffset(void)
+{
+	struct machine_specific *ms = machdep->machspec;
+	ulong offset;
+
+	if (ms->kimage_voffset) /* vmcoreinfo or --machdep override */
+		return;
+
+	if (!(kt->flags2 & KASLR) || !(kt->flags & RELOC_SET)) /*Calculate kiamge_voffset when KASLR enabled.*/
+		return;
+
+	if(ACTIVE()){
+		char buf[BUFSIZE];
+		char *p1;
+		int errflag;
+		FILE *iomem;
+		ulong kernel_code_range;
+		ulong memory_end;
+		ulong memory_start;
+
+		if ((iomem = fopen("/proc/iomem", "r")) == NULL)
+			return;
+
+		kernel_code_range = symbol_value("__init_begin") - symbol_value("_text");
+
+		errflag = 1;
+		while (fgets(buf, BUFSIZE, iomem)) {
+			if (strstr(buf, ": System RAM")) {
+				clean_line(buf);
+
+				/*get end address of system ram region*/
+				if (!(p1 = strstr(buf, ":")))
+					continue;
+				*(p1-1) = NULLCHAR;
+				if (!(p1 = strstr(buf, "-")))
+					continue;
+				memory_end = htol(p1+1, RETURN_ON_ERROR | QUIET, NULL);
+				if (BADADDR == memory_end)
+					continue;
+
+				/*get start address of system ram region*/
+				*p1 = NULLCHAR;
+				memory_start = htol(buf, RETURN_ON_ERROR | QUIET, NULL);
+				if (BADADDR == memory_start)
+					continue;
+
+				/* system ram region is too small to load kernel code, find next region*/
+				if((memory_end - memory_start) < kernel_code_range)
+					continue;
+
+				errflag = 0;
+				break;
+			}
+		}
+		fclose(iomem);
+
+		if (errflag)
+			return;
+
+		offset = memory_start;
+	}else if (DISKDUMP_DUMPFILE())
+		return;
+	else if (KDUMP_DUMPFILE())
+		arm_kdump_phys_base(&offset);    /*Get start address of first memory block*/
+	else{
+		error(WARNING,
+			"kimage_voffset cannot be determined from the dumpfile.\n");
+		error(CONT,
+			"Using default value of 0.  If this is not correct, then try\n");
+		error(CONT,
+			"using the command line option: --machdep kimage_voffset=<addr>\n");
+		return;
+	}
+
+	ms->kimage_voffset = ms->vmalloc_start_addr + (kt->relocate * -1) - offset;
+}
 
 static void
 arm64_calc_phys_offset(void)
@@ -817,6 +898,7 @@ arm64_calc_phys_offset(void)
 }
 
 
+
 /*
  *  Determine PHYS_OFFSET either by reading VMCOREINFO or the kernel
  *  symbol, otherwise borrow the 32-bit ARM functionality.
-- 
1.9.1

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux