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
> [email protected]
> 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 <[email protected]>
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
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to