Hello Pratyush, >If we have to erase a symbol from vmcore whose address is not present in >vmcoreinfo, then we need to pass vmlinux as well to get the symbol >address. >When kaslr is enabled, virtual address of all the kernel symbols are >randomized with an offset. vmlinux always has a static address, but all >the arch specific calculation are based on run time kernel address. So >we need to find a way to translate symbol address from vmlinux to kernel >run time address. > >without this patch: > # cat > scrub.conf << EOF > [vmlinux] > erase jiffies > erase init_task.utime > for tsk in init_task.tasks.next within task_struct:tasks > erase tsk.utime > endfor > EOF > > # makedumpfile --split -d 5 -x vmlinux --config scrub.conf vmcore dumpfile_{1,2,3} > > readpage_kdump_compressed: pfn(f97ea) is excluded from vmcore. > readmem: type_addr: 1, addr:f97eaff8, size:8 > vtop4_x86_64: Can't get pml4 (page_dir:f97eaff8). > readmem: Can't convert a virtual address(ffffffff819f1284) to physical address. > readmem: type_addr: 0, addr:ffffffff819f1284, size:390 > check_release: Can't get the address of system_utsname. > >After this patch check_release() is ok, and also we are able to erase >symbol from vmcore. > >Signed-off-by: Pratyush Anand <panand at redhat.com> >--- > arch/x86_64.c | 36 ++++++++++++++++++++++++++++++++++++ > erase_info.c | 1 + > makedumpfile.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ > makedumpfile.h | 16 ++++++++++++++++ > 4 files changed, 106 insertions(+) > >diff --git a/arch/x86_64.c b/arch/x86_64.c >index e978a36f8878..fd2e8ac154d6 100644 >--- a/arch/x86_64.c >+++ b/arch/x86_64.c >@@ -33,6 +33,42 @@ get_xen_p2m_mfn(void) > return NOT_FOUND_LONG_VALUE; > } > >+unsigned long >+get_kaslr_offset_x86_64(unsigned long vaddr) >+{ >+ unsigned int i; >+ char buf[BUFSIZE_FGETS], *endp; >+ >+ if (!info->kaslr_offset && info->file_vmcoreinfo) { >+ if (fseek(info->file_vmcoreinfo, 0, SEEK_SET) < 0) { >+ ERRMSG("Can't seek the vmcoreinfo file(%s). %s\n", >+ info->name_vmcoreinfo, strerror(errno)); >+ return FALSE; >+ } >+ >+ while (fgets(buf, BUFSIZE_FGETS, info->file_vmcoreinfo)) { >+ i = strlen(buf); >+ if (!i) >+ break; >+ if (buf[i - 1] == '\n') >+ buf[i - 1] = '\0'; >+ if (strncmp(buf, STR_KERNELOFFSET, >+ strlen(STR_KERNELOFFSET)) == 0) >+ info->kaslr_offset = >+ strtoul(buf+strlen(STR_KERNELOFFSET),&endp,16); >+ } >+ } >+ if (vaddr >= __START_KERNEL_map && >+ vaddr < __START_KERNEL_map + info->kaslr_offset) >+ return info->kaslr_offset; >+ else >+ /* >+ * TODO: we need to check if it is vmalloc/vmmemmap/module >+ * address, we will have different offset >+ */ >+ return 0; >+} >+ > static int > get_page_offset_x86_64(void) > { >diff --git a/erase_info.c b/erase_info.c >index f2ba9149e93e..60abfa1a1adf 100644 >--- a/erase_info.c >+++ b/erase_info.c >@@ -1088,6 +1088,7 @@ resolve_config_entry(struct config_entry *ce, unsigned long long base_vaddr, > ce->line, ce->name); > return FALSE; > } >+ ce->sym_addr += get_kaslr_offset(ce->sym_addr); > ce->type_name = get_symbol_type_name(ce->name, > DWARF_INFO_GET_SYMBOL_TYPE, > &ce->size, &ce->type_flag); >diff --git a/makedumpfile.c b/makedumpfile.c >index 301772a8820c..4986d098d69a 100644 >--- a/makedumpfile.c >+++ b/makedumpfile.c >@@ -2099,6 +2099,13 @@ void > write_vmcoreinfo_data(void) > { > /* >+ * write 1st kernel's KERNELOFFSET >+ */ >+ if (info->kaslr_offset) >+ fprintf(info->file_vmcoreinfo, "%s%lx\n", STR_KERNELOFFSET, >+ info->kaslr_offset); When will this data written to VMCOREINFO file be used ? info->kaslr_offset is necessary for vmlinux but -x and -i are exclusive. Thanks, Atsushi Kumagai >+ /* > * write 1st kernel's OSRELEASE > */ > fprintf(info->file_vmcoreinfo, "%s%s\n", STR_OSRELEASE, >@@ -3782,6 +3789,46 @@ free_for_parallel() > } > > int >+find_kaslr_offsets() >+{ >+ off_t offset; >+ unsigned long size; >+ int ret = FALSE; >+ >+ get_vmcoreinfo(&offset, &size); >+ >+ if (!(info->name_vmcoreinfo = strdup(FILENAME_VMCOREINFO))) { >+ MSG("Can't duplicate strings(%s).\n", FILENAME_VMCOREINFO); >+ return FALSE; >+ } >+ if (!copy_vmcoreinfo(offset, size)) >+ goto out; >+ >+ if (!open_vmcoreinfo("r")) >+ goto out; >+ >+ unlink(info->name_vmcoreinfo); >+ >+ /* >+ * This arch specific function should update info->kaslr_offset. If >+ * kaslr is not enabled then offset will be set to 0. arch specific >+ * function might need to read from vmcoreinfo, therefore we have >+ * called this function between open_vmcoreinfo() and >+ * close_vmcoreinfo() >+ */ >+ get_kaslr_offset(SYMBOL(_stext)); >+ >+ close_vmcoreinfo(); >+ >+ ret = TRUE; >+out: >+ free(info->name_vmcoreinfo); >+ info->name_vmcoreinfo = NULL; >+ >+ return ret; >+} >+ >+int > initial(void) > { > off_t offset; >@@ -3833,6 +3880,9 @@ initial(void) > set_dwarf_debuginfo("vmlinux", NULL, > info->name_vmlinux, info->fd_vmlinux); > >+ if (has_vmcoreinfo() && !find_kaslr_offsets()) >+ return FALSE; >+ > if (!get_symbol_info()) > return FALSE; > >@@ -8635,6 +8685,7 @@ close_vmcoreinfo(void) > if(fclose(info->file_vmcoreinfo) < 0) > ERRMSG("Can't close the vmcoreinfo file(%s). %s\n", > info->name_vmcoreinfo, strerror(errno)); >+ info->file_vmcoreinfo = NULL; > } > > void >@@ -11026,11 +11077,13 @@ main(int argc, char *argv[]) > strerror(errno)); > goto out; > } >+ info->file_vmcoreinfo = NULL; > info->fd_vmlinux = -1; > info->fd_xen_syms = -1; > info->fd_memory = -1; > info->fd_dumpfile = -1; > info->fd_bitmap = -1; >+ info->kaslr_offset = 0; > initialize_tables(); > > /* >diff --git a/makedumpfile.h b/makedumpfile.h >index e32e567018f6..9f16becadd55 100644 >--- a/makedumpfile.h >+++ b/makedumpfile.h >@@ -253,10 +253,14 @@ static inline int string_exists(char *s) { return (s ? TRUE : FALSE); } > #define SYMBOL_INIT(symbol, str_symbol) \ > do { \ > SYMBOL(symbol) = get_symbol_addr(str_symbol); \ >+ if (SYMBOL(symbol) != NOT_FOUND_SYMBOL) \ >+ SYMBOL(symbol) += info->kaslr_offset; \ > } while (0) > #define SYMBOL_INIT_NEXT(symbol, str_symbol) \ > do { \ > SYMBOL(symbol) = get_next_symbol_addr(str_symbol); \ >+ if (SYMBOL(symbol) != NOT_FOUND_SYMBOL) \ >+ SYMBOL(symbol) += info->kaslr_offset; \ > } while (0) > #define WRITE_SYMBOL(str_symbol, symbol) \ > do { \ >@@ -495,6 +499,7 @@ do { \ > #define STR_CONFIG_X86_PAE "CONFIG_X86_PAE=y" > #define STR_CONFIG_PGTABLE_4 "CONFIG_PGTABLE_4=y" > #define STR_CONFIG_PGTABLE_3 "CONFIG_PGTABLE_3=y" >+#define STR_KERNELOFFSET "KERNELOFFSET=" > > /* > * common value >@@ -838,6 +843,7 @@ int get_xen_info_arm64(void); > #define get_phys_base() get_phys_base_arm64() > #define get_machdep_info() get_machdep_info_arm64() > #define get_versiondep_info() get_versiondep_info_arm64() >+#define get_kaslr_offset(X) FALSE > #define get_xen_basic_info_arch(X) get_xen_basic_info_arm64(X) > #define get_xen_info_arch(X) get_xen_info_arm64(X) > #define is_phys_addr(X) stub_true_ul(X) >@@ -851,6 +857,7 @@ unsigned long long vaddr_to_paddr_arm(unsigned long vaddr); > #define get_phys_base() get_phys_base_arm() > #define get_machdep_info() get_machdep_info_arm() > #define get_versiondep_info() stub_true() >+#define get_kaslr_offset(X) FALSE > #define vaddr_to_paddr(X) vaddr_to_paddr_arm(X) > #define is_phys_addr(X) stub_true_ul(X) > #endif /* arm */ >@@ -863,11 +870,13 @@ unsigned long long vaddr_to_paddr_x86(unsigned long vaddr); > #define get_phys_base() stub_true() > #define get_machdep_info() get_machdep_info_x86() > #define get_versiondep_info() get_versiondep_info_x86() >+#define get_kaslr_offset(X) FALSE > #define vaddr_to_paddr(X) vaddr_to_paddr_x86(X) > #define is_phys_addr(X) stub_true_ul(X) > #endif /* x86 */ > > #ifdef __x86_64__ >+unsigned long get_kaslr_offset_x86_64(unsigned long vaddr); > int get_phys_base_x86_64(void); > int get_machdep_info_x86_64(void); > int get_versiondep_info_x86_64(void); >@@ -876,6 +885,7 @@ unsigned long long vtop4_x86_64(unsigned long vaddr); > #define get_phys_base() get_phys_base_x86_64() > #define get_machdep_info() get_machdep_info_x86_64() > #define get_versiondep_info() get_versiondep_info_x86_64() >+#define get_kaslr_offset(X) get_kaslr_offset_x86_64(X) > #define vaddr_to_paddr(X) vtop4_x86_64(X) > #define is_phys_addr(X) stub_true_ul(X) > #endif /* x86_64 */ >@@ -888,6 +898,7 @@ unsigned long long vaddr_to_paddr_ppc64(unsigned long vaddr); > #define get_phys_base() stub_true() > #define get_machdep_info() get_machdep_info_ppc64() > #define get_versiondep_info() get_versiondep_info_ppc64() >+#define get_kaslr_offset(X) FALSE > #define vaddr_to_paddr(X) vaddr_to_paddr_ppc64(X) > #define is_phys_addr(X) stub_true_ul(X) > #endif /* powerpc64 */ >@@ -899,6 +910,7 @@ unsigned long long vaddr_to_paddr_ppc(unsigned long vaddr); > #define get_phys_base() stub_true() > #define get_machdep_info() get_machdep_info_ppc() > #define get_versiondep_info() stub_true() >+#define get_kaslr_offset(X) FALSE > #define vaddr_to_paddr(X) vaddr_to_paddr_ppc(X) > #define is_phys_addr(X) stub_true_ul(X) > #endif /* powerpc32 */ >@@ -911,6 +923,7 @@ int is_iomem_phys_addr_s390x(unsigned long addr); > #define get_phys_base() stub_true() > #define get_machdep_info() get_machdep_info_s390x() > #define get_versiondep_info() stub_true() >+#define get_kaslr_offset(X) FALSE > #define vaddr_to_paddr(X) vaddr_to_paddr_s390x(X) > #define is_phys_addr(X) is_iomem_phys_addr_s390x(X) > #endif /* s390x */ >@@ -923,6 +936,7 @@ unsigned long long vaddr_to_paddr_ia64(unsigned long vaddr); > #define get_machdep_info() get_machdep_info_ia64() > #define get_phys_base() get_phys_base_ia64() > #define get_versiondep_info() stub_true() >+#define get_kaslr_offset(X) FALSE > #define vaddr_to_paddr(X) vaddr_to_paddr_ia64(X) > #define VADDR_REGION(X) (((unsigned long)(X)) >> REGION_SHIFT) > #define is_phys_addr(X) stub_true_ul(X) >@@ -1152,6 +1166,7 @@ struct DumpInfo { > int vmemmap_psize; > int vmemmap_cnt; > struct ppc64_vmemmap *vmemmap_list; >+ unsigned long kaslr_offset; > > /* > * page table info for ppc64 >@@ -1803,6 +1818,7 @@ struct memory_range { > struct memory_range crash_reserved_mem[CRASH_RESERVED_MEM_NR]; > int crash_reserved_mem_nr; > >+unsigned long read_vmcoreinfo_symbol(char *str_symbol); > int readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size); > int get_str_osrelease_from_vmlinux(void); > int read_vmcoreinfo_xen(void); >-- >2.9.3 >