On 2017/3/18 4:27, Dave Anderson wrote:
>
> ----- Original Message -----
>> 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,
>>
>> 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
>
> Yueyi,
>
> Yes, thanks, this patch does select the correct "offset" for
> use by your calculation.  On both the 4.8 and 4.10 kernels,
> the System RAM segment at 0x4000200000 is selected.
>
> However, I wonder if it would be simpler to just select the
> System RAM segment that *contains* the "Kernel code" segment,
> which would follow it in /proc/iomem:
>
> 4.8 kernel:
>    
>    4000000000-40001fffff : System RAM
>    4000200000-43fa59ffff : System RAM
>      4000280000-4000c7ffff : Kernel code
>      4000d90000-400166ffff : Kernel data
>    43fa5a0000-43fa9dffff : System RAM
>    43fa9e0000-43ff99ffff : System RAM
>    43ff9a0000-43ff9affff : System RAM
>    43ff9b0000-43ff9bffff : System RAM
>    43ff9c0000-43ff9effff : System RAM
>    43ff9f0000-43ffffffff : System RAM
>    
> 4.10 kernel:
>    
>    4000000000-40001fffff : reserved
>    4000200000-4001ffffff : System RAM
>      4000280000-4000ccffff : Kernel code
>      4000e00000-40016effff : Kernel data
>    40023b0000-4ff733ffff : System RAM
>    4ff7340000-4ff77cffff : reserved
>    4ff77d0000-4ff792ffff : System RAM
>    4ff7930000-4ff7e7ffff : reserved
>    4ff7e80000-4ff7e8ffff : System RAM
>    4ff7e90000-4ff7efffff : reserved
>    4ff7f10000-4ff800ffff : reserved
>    4ff8010000-4fffffffff : System RAM
>
> In other words, just walk through the /proc/iomem entries, saving
> the System RAM start address as you go.  Then when "Kernel code" is
> found, use the last RAM start address.
>
> And a couple other things...
>
> For backwards compatibility (i.e., kernels without kimage_voffset),
> the call from arm64_init() should be conditional like this:
>
>       if (machdep->flags & NEW_VMEMMAP)
>                 arm64_calc_kimage_voffset();
>
> And for live systems without /dev/crash, it wouldn't be necessary to
> add "--kaslr=0" to the command line if arm64_calc_kimage_voffset() started
> something like this:
>
>    static void
>    arm64_calc_kimage_voffset(void)
>    {
>            struct machine_specific *ms = machdep->machspec;
>            ulong offset;
>    
>            if (ms->kimage_voffset) /* vmcoreinfo, --machdep override, or 
> ioctl */
>                    return;
>    
>            if (DUMPFILE()) {
>                    if (!(kt->flags2 & KASLR) || !(kt->flags & RELOC_SET))
>                            return;
>            }
>    ...
>    
> What do you think?
>
> Thanks,
>    Dave
>
> --
> Crash-utility mailing list
> Crash-utility@redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility

Agreed, I have made change as your recommendation.  For NEW_VMEMMAP,  
always calculate kimage_voffset if it not be given.

Thanks,
Yueyi








From 47060ef9f16ba64584f0a9222eba9271d34f9031 Mon Sep 17 00:00:00 2001
From: Yueyi Li <liyu...@live.com>
Date: Tue, 14 Mar 2017 21:25:21 +0800
Subject: [PATCH] [ARM64][patch] Auto calculate kimage_voffset.

For some use case such as VMCOREINFO or /dev/crash is not support,
kimage_voffset can not be read directly, then try to calculate it.
---
 arm64.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/arm64.c b/arm64.c
index 6eaf96d..01edc36 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 *);
@@ -216,6 +217,8 @@ arm64_init(int when)
                                                + ARM64_MODULES_VSIZE -1;
 
                        ms->vmalloc_start_addr = ms->modules_end + 1;
+
+                       arm64_calc_kimage_voffset();
                } else {
                        ms->modules_vaddr = ARM64_PAGE_OFFSET - MEGABYTES(64);
                        ms->modules_end = ARM64_PAGE_OFFSET - 1;
@@ -735,6 +738,68 @@ arm64_parse_cmdline_args(void)
        }
 }
 
+static void
+arm64_calc_kimage_voffset(void)
+{
+       struct machine_specific *ms = machdep->machspec;
+       ulong phys_addr;
+
+       if (ms->kimage_voffset) /* vmcoreinfo or --machdep override */
+               return;
+
+       if(ACTIVE()){
+               char buf[BUFSIZE];
+               char *p1;
+               int errflag;
+               FILE *iomem;
+
+               if ((iomem = fopen("/proc/iomem", "r")) == NULL)
+                       return;
+
+               errflag = 1;
+               while (fgets(buf, BUFSIZE, iomem)) {
+                       if(strstr(buf, ": Kernel code")) {
+                               errflag = 0;
+                               break;
+                       }
+                       if (strstr(buf, ": System RAM")) {
+                               clean_line(buf);
+
+                               if (!(p1 = strstr(buf, "-")))
+                                       continue;
+
+                               *p1 = NULLCHAR;
+
+                               phys_addr = htol(buf, RETURN_ON_ERROR | QUIET, 
NULL);
+                               if (BADADDR == phys_addr)
+                                       continue;
+                       }
+               }
+               fclose(iomem);
+
+               if (errflag)
+                       return;
+
+       }else if (DISKDUMP_DUMPFILE())
+               return;
+       else if (KDUMP_DUMPFILE())
+               arm_kdump_phys_base(&phys_addr);    /*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 - phys_addr;
+
+       if ((kt->flags2 & KASLR) && (kt->flags & RELOC_SET))
+               ms->kimage_voffset += (kt->relocate * -1);
+
+}
 
 static void
 arm64_calc_phys_offset(void)
-- 
1.9.1

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

Reply via email to