Hello community,
here is the log from the commit of package makedumpfile for openSUSE:Factory checked in at 2018-01-30 15:39:26
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/makedumpfile (Old)
and /work/SRC/openSUSE:Factory/.makedumpfile.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "makedumpfile"
Tue Jan 30 15:39:26 2018 rev:65 rq:570629 version:1.6.3
Changes:
--------
--- /work/SRC/openSUSE:Factory/makedumpfile/makedumpfile.changes 2018-01-16 09:32:17.369996555 +0100
+++ /work/SRC/openSUSE:Factory/.makedumpfile.new/makedumpfile.changes 2018-01-30 15:39:27.364463901 +0100
@@ -1,0 +2,28 @@
+Mon Jan 29 14:01:03 UTC 2018 - ptesarik@suse.com
+
+- makedumpfile-always-use-bigger-SECTION_MAP_MASK.patch: Always use
+ bigger SECTION_MAP_MASK (bsc#1066811, bsc#1067703).
+
+-------------------------------------------------------------------
+Mon Jan 29 13:49:43 UTC 2018 - ptesarik@suse.com
+
+- Update to 1.6.3
+ * Support kernels up to 4.14.8 (bsc#1068864).
+ * 86_64: handle renamed init_level4_pgt -> init_top_pgt
+ * Fix SECTION_MAP_MASK for kernel >= v.13
+ * book3s/ppc64: Lower the max real address to 53 bits for
+ kernels >= v4.11
+ * Support symbol __cpu_online_mask
+ * ppc64: update hash page table geometry
+- Drop upstreamed patches:
+ * makedumpfile-Fix-SECTION_MAP_MASK-for-kernel-v.13.patch
+ * makedumpfile-handle-renamed-init_level4_pgt-init_top_pgt.patch
+ * makedumpfile-ppc64-update-hash-page-table-geometry.patch
+ * makedumpfile-book3s-ppc64-Lower-the-max-real-address-to-53-bits.patch
+ * makedumpfile-__cpu_online_mask-symbol.patch
+ * makedumpfile-vtop4_x86_64_pagetable.patch
+ * makedumpfile-fix-KASLR-for-sadump.patch
+ * makedumpfile-fix-KASLR-for-sadump-while-kdump.patch
+ * makedumpfile-support-4.12.patch
+
+-------------------------------------------------------------------
Old:
----
makedumpfile-1.6.2.tar.gz
makedumpfile-Fix-SECTION_MAP_MASK-for-kernel-v.13.patch
makedumpfile-__cpu_online_mask-symbol.patch
makedumpfile-book3s-ppc64-Lower-the-max-real-address-to-53-bits.patch
makedumpfile-fix-KASLR-for-sadump-while-kdump.patch
makedumpfile-fix-KASLR-for-sadump.patch
makedumpfile-handle-renamed-init_level4_pgt-init_top_pgt.patch
makedumpfile-ppc64-update-hash-page-table-geometry.patch
makedumpfile-vtop4_x86_64_pagetable.patch
New:
----
makedumpfile-1.6.3.tar.gz
makedumpfile-always-use-bigger-SECTION_MAP_MASK.patch
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ makedumpfile.spec ++++++
--- /var/tmp/diff_new_pack.UvDSG1/_old 2018-01-30 15:39:27.940437011 +0100
+++ /var/tmp/diff_new_pack.UvDSG1/_new 2018-01-30 15:39:27.944436824 +0100
@@ -29,7 +29,7 @@
%endif
Name: makedumpfile
-Version: 1.6.2
+Version: 1.6.3
Release: 0
Summary: Partial kernel dump
License: GPL-2.0
@@ -38,15 +38,8 @@
Source: https://sourceforge.net/projects/makedumpfile/files/makedumpfile/%{version}/%{name}-%{version}.tar.gz
Source99: %{name}-rpmlintrc
Patch0: %{name}-coptflags.diff
-Patch1: %{name}-Fix-SECTION_MAP_MASK-for-kernel-v.13.patch
-Patch2: %{name}-override-libtinfo.patch
-Patch3: %{name}-handle-renamed-init_level4_pgt-init_top_pgt.patch
-Patch4: %{name}-ppc64-update-hash-page-table-geometry.patch
-Patch5: %{name}-book3s-ppc64-Lower-the-max-real-address-to-53-bits.patch
-Patch6: %{name}-__cpu_online_mask-symbol.patch
-Patch7: %{name}-vtop4_x86_64_pagetable.patch
-Patch8: %{name}-fix-KASLR-for-sadump.patch
-Patch9: %{name}-fix-KASLR-for-sadump-while-kdump.patch
+Patch1: %{name}-override-libtinfo.patch
+Patch2: %{name}-always-use-bigger-SECTION_MAP_MASK.patch
BuildRequires: libdw-devel
BuildRequires: libebl-devel
BuildRequires: libelf-devel
@@ -77,13 +70,6 @@
%patch0 -p1
%patch1 -p1
%patch2 -p1
-%patch3 -p1
-%patch4 -p1
-%patch5 -p1
-%patch6 -p1
-%patch7 -p1
-%patch8 -p1
-%patch9 -p1
%build
%if %{have_snappy}
++++++ makedumpfile-1.6.2.tar.gz -> makedumpfile-1.6.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.2/Makefile new/makedumpfile-1.6.3/Makefile
--- old/makedumpfile-1.6.2/Makefile 2017-07-26 09:49:08.000000000 +0200
+++ new/makedumpfile-1.6.3/Makefile 2018-01-26 02:30:25.000000000 +0100
@@ -1,7 +1,7 @@
# makedumpfile
-VERSION=1.6.2
-DATE=27 Jul 2017
+VERSION=1.6.3
+DATE=29 Jun 2018
# Honour the environment variable CC
ifeq ($(strip $CC),)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.2/README new/makedumpfile-1.6.3/README
--- old/makedumpfile-1.6.2/README 2017-07-26 09:49:08.000000000 +0200
+++ new/makedumpfile-1.6.3/README 2018-01-26 02:30:25.000000000 +0100
@@ -119,6 +119,9 @@
4.9 | OK | ** | | | | ** | | -- | OK | OK | | |
4.10 | OK | ** | | | | ** | | -- | OK | OK | | |
4.11 | OK | ** | | | | ** | | -- | OK | OK | | |
+ 4.12 | OK | ** | | | | ** | | -- | OK | OK | | |
+ 4.13 | OK | ** | | | | ** | | -- | OK | OK | | |
+ 4.14 | OK | ** | | | | ** | | -- | OK | OK | | |
OK : Support.
-- : Not support.
@@ -192,8 +195,7 @@
* BUG REPORT
If finding some bugs, please send the information to the following:
Masaki Tachibana
- Minoru Usui
+ Takuya Nakayama
Daisuke Nishimura
- Atsushi Kumagai
kexec-ml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.2/arch/arm64.c new/makedumpfile-1.6.3/arch/arm64.c
--- old/makedumpfile-1.6.2/arch/arm64.c 2017-07-26 09:49:08.000000000 +0200
+++ new/makedumpfile-1.6.3/arch/arm64.c 2018-01-26 02:30:25.000000000 +0100
@@ -57,6 +57,8 @@
#define PGDIR_SHIFT ((PAGESHIFT() - 3) * pgtable_level + 3)
#define PTRS_PER_PGD (1 << (va_bits - PGDIR_SHIFT))
#define PUD_SHIFT get_pud_shift_arm64()
+#define PUD_SIZE (1UL << PUD_SHIFT)
+#define PUD_MASK (~(PUD_SIZE - 1))
#define PTRS_PER_PTE (1 << (PAGESHIFT() - 3))
#define PTRS_PER_PUD PTRS_PER_PTE
#define PMD_SHIFT ((PAGESHIFT() - 3) * 2 + 3)
@@ -79,6 +81,10 @@
#define PMD_TYPE_SECT 1
#define PMD_TYPE_TABLE 3
+#define PUD_TYPE_MASK 3
+#define PUD_TYPE_SECT 1
+#define PUD_TYPE_TABLE 3
+
#define pgd_index(vaddr) (((vaddr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
#define pgd_offset(pgdir, vaddr) ((pgd_t *)(pgdir) + pgd_index(vaddr))
@@ -253,6 +259,13 @@
return NOT_PADDR;
}
+ if ((pud_val(pudv) & PUD_TYPE_MASK) == PUD_TYPE_SECT) {
+ /* 1GB section for Page Table level = 4 and Page Size = 4KB */
+ paddr = (pud_val(pudv) & (PUD_MASK & PMD_SECTION_MASK))
+ + (vaddr & (PUD_SIZE - 1));
+ return paddr;
+ }
+
pmda = pmd_offset(puda, &pudv, vaddr);
if (!readmem(PADDR, (unsigned long long)pmda, &pmdv, sizeof(pmdv))) {
ERRMSG("Can't read pmd\n");
@@ -278,7 +291,7 @@
}
break;
case PMD_TYPE_SECT:
- /* 1GB section */
+ /* 512MB section for Page Table level = 3 and Page Size = 64KB*/
paddr = (pmd_val(pmdv) & (PMD_MASK & PMD_SECTION_MASK))
+ (vaddr & (PMD_SIZE - 1));
break;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.2/arch/ppc64.c new/makedumpfile-1.6.3/arch/ppc64.c
--- old/makedumpfile-1.6.2/arch/ppc64.c 2017-07-26 09:49:08.000000000 +0200
+++ new/makedumpfile-1.6.3/arch/ppc64.c 2018-01-26 02:30:25.000000000 +0100
@@ -245,10 +245,16 @@
} else if (info->kernel_version >= KERNEL_VERSION(4, 6, 0)) {
info->l1_index_size = PTE_INDEX_SIZE_L4_64K_3_10;
- info->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_6;
- info->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_6;
- info->l4_index_size = PGD_INDEX_SIZE_L4_64K_3_10;
+ if (info->kernel_version >= KERNEL_VERSION(4, 12, 0)) {
+ info->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_12;
+ info->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_12;
+ info->l4_index_size = PGD_INDEX_SIZE_L4_64K_4_12;
+ } else {
+ info->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_6;
+ info->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_6;
+ info->l4_index_size = PGD_INDEX_SIZE_L4_64K_3_10;
+ }
} else if (info->kernel_version >= KERNEL_VERSION(3, 10, 0)) {
info->l1_index_size = PTE_INDEX_SIZE_L4_64K_3_10;
info->l2_index_size = PMD_INDEX_SIZE_L4_64K_3_10;
@@ -307,11 +313,17 @@
}
info->pte_rpn_mask = PTE_RPN_MASK_DEFAULT;
- if (info->kernel_version >= KERNEL_VERSION(4, 6, 0)) {
+ if ((info->kernel_version >= KERNEL_VERSION(4, 6, 0)) &&
+ (info->kernel_version < KERNEL_VERSION(4, 11, 0))) {
info->pte_rpn_mask = PTE_RPN_MASK_L4_4_6;
info->pte_rpn_shift = PTE_RPN_SHIFT_L4_4_6;
}
+ if (info->kernel_version >= KERNEL_VERSION(4, 11, 0)) {
+ info->pte_rpn_mask = PTE_RPN_MASK_L4_4_11;
+ info->pte_rpn_shift = PTE_RPN_SHIFT_L4_4_11;
+ }
+
/*
* Compute ptrs per each level
*/
@@ -576,6 +588,7 @@
ERRMSG("Can't initialize for vmalloc translation\n");
return FALSE;
}
+ info->page_offset = __PAGE_OFFSET;
return TRUE;
}
@@ -616,4 +629,40 @@
return ppc64_vtop_level4(vaddr);
}
+int arch_crashkernel_mem_size_ppc64()
+{
+ const char f_crashsize[] = "/proc/device-tree/chosen/linux,crashkernel-size";
+ const char f_crashbase[] = "/proc/device-tree/chosen/linux,crashkernel-base";
+ unsigned long crashk_sz_be, crashk_sz;
+ unsigned long crashk_base_be, crashk_base;
+ uint swap;
+ FILE *fp, *fpb;
+
+ fp = fopen(f_crashsize, "r");
+ if (!fp) {
+ ERRMSG("Cannot open %s\n", f_crashsize);
+ return FALSE;
+ }
+ fpb = fopen(f_crashbase, "r");
+ if (!fp) {
+ ERRMSG("Cannot open %s\n", f_crashbase);
+ fclose(fp);
+ return FALSE;
+ }
+
+ fread(&crashk_sz_be, sizeof(crashk_sz_be), 1, fp);
+ fread(&crashk_base_be, sizeof(crashk_base_be), 1, fpb);
+ fclose(fp);
+ fclose(fpb);
+ /* dev tree is always big endian */
+ swap = !is_bigendian();
+ crashk_sz = swap64(crashk_sz_be, swap);
+ crashk_base = swap64(crashk_base_be, swap);
+ crash_reserved_mem_nr = 1;
+ crash_reserved_mem[0].start = crashk_base;
+ crash_reserved_mem[0].end = crashk_base + crashk_sz - 1;
+
+ return TRUE;
+}
+
#endif /* powerpc64 */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.2/arch/x86_64.c new/makedumpfile-1.6.3/arch/x86_64.c
--- old/makedumpfile-1.6.2/arch/x86_64.c 2017-07-26 09:49:08.000000000 +0200
+++ new/makedumpfile-1.6.3/arch/x86_64.c 2018-01-26 02:30:25.000000000 +0100
@@ -255,20 +255,15 @@
* Translate a virtual address to a physical address by using 4 levels paging.
*/
unsigned long long
-vtop4_x86_64(unsigned long vaddr)
+__vtop4_x86_64(unsigned long vaddr, unsigned long pagetable)
{
unsigned long page_dir, pml4, pgd_paddr, pgd_pte, pmd_paddr, pmd_pte;
unsigned long pte_paddr, pte;
- if (SYMBOL(init_level4_pgt) == NOT_FOUND_SYMBOL) {
- ERRMSG("Can't get the symbol of init_level4_pgt.\n");
- return NOT_PADDR;
- }
-
/*
* Get PGD.
*/
- page_dir = SYMBOL(init_level4_pgt) - __START_KERNEL_map + info->phys_base;
+ page_dir = pagetable;
if (is_xen_memory()) {
page_dir = ptom_xen(page_dir);
if (page_dir == NOT_PADDR)
@@ -346,6 +341,37 @@
return (pte & ENTRY_MASK) + PAGEOFFSET(vaddr);
}
+unsigned long long
+vtop4_x86_64(unsigned long vaddr)
+{
+ unsigned long pagetable;
+ unsigned long init_level4_pgt;
+
+ if (SYMBOL(init_level4_pgt) != NOT_FOUND_SYMBOL)
+ init_level4_pgt = SYMBOL(init_level4_pgt);
+ else if (SYMBOL(init_top_pgt) != NOT_FOUND_SYMBOL)
+ init_level4_pgt = SYMBOL(init_top_pgt);
+ else {
+ ERRMSG("Can't get the symbol of init_level4_pgt.\n");
+ return NOT_PADDR;
+ }
+
+ if (SYMBOL(level4_kernel_pgt) != NOT_FOUND_SYMBOL) {
+ ERRMSG("Kernel is built with 5-level page tables\n");
+ return NOT_PADDR;
+ }
+
+ pagetable = init_level4_pgt - __START_KERNEL_map + info->phys_base;
+
+ return __vtop4_x86_64(vaddr, pagetable);
+}
+
+unsigned long long
+vtop4_x86_64_pagetable(unsigned long vaddr, unsigned long pagetable)
+{
+ return __vtop4_x86_64(vaddr, pagetable);
+}
+
/*
* for Xen extraction
*/
@@ -549,8 +575,16 @@
struct vmap_pfns *vmapp, *vmaphead = NULL, *cur, *tail;
init_level4_pgt = SYMBOL(init_level4_pgt);
+ if (init_level4_pgt == NOT_FOUND_SYMBOL)
+ init_level4_pgt = SYMBOL(init_top_pgt);
+
if (init_level4_pgt == NOT_FOUND_SYMBOL) {
- ERRMSG("init_level4_pgt not found\n");
+ ERRMSG("init_level4_pgt/init_top_pgt not found\n");
+ return FAILED;
+ }
+
+ if (SYMBOL(level4_kernel_pgt) != NOT_FOUND_SYMBOL) {
+ ERRMSG("kernel is configured for 5-level page tables\n");
return FAILED;
}
pagestructsize = size_table.page;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.2/elf_info.c new/makedumpfile-1.6.3/elf_info.c
--- old/makedumpfile-1.6.2/elf_info.c 2017-07-26 09:49:08.000000000 +0200
+++ new/makedumpfile-1.6.3/elf_info.c 2018-01-26 02:30:25.000000000 +0100
@@ -810,8 +810,8 @@
int i, j, tidx = -1;
unsigned long long vstart, vend, kvstart, kvend;
struct pt_load_segment temp_seg = {0};
- kvstart = (ulong)start | PAGE_OFFSET;
- kvend = (ulong)end | PAGE_OFFSET;
+ kvstart = (ulong)start + PAGE_OFFSET;
+ kvend = (ulong)end + PAGE_OFFSET;
unsigned long size;
for (i = 0; i < (*num_pt_loads); i++) {
@@ -820,26 +820,26 @@
if (kvstart < vend && kvend > vstart) {
if (kvstart != vstart && kvend != vend) {
/* Split load segment */
- temp_seg.phys_start = end + 1;
+ temp_seg.phys_start = end;
temp_seg.phys_end = (*pt_loads)[i].phys_end;
- temp_seg.virt_start = kvend + 1;
+ temp_seg.virt_start = kvend;
temp_seg.virt_end = vend;
temp_seg.file_offset = (*pt_loads)[i].file_offset
+ temp_seg.virt_start - (*pt_loads)[i].virt_start;
temp_seg.file_size = temp_seg.phys_end
- temp_seg.phys_start;
- (*pt_loads)[i].virt_end = kvstart - 1;
- (*pt_loads)[i].phys_end = start - 1;
+ (*pt_loads)[i].virt_end = kvstart;
+ (*pt_loads)[i].phys_end = start;
(*pt_loads)[i].file_size -= temp_seg.file_size;
tidx = i+1;
} else if (kvstart != vstart) {
- (*pt_loads)[i].phys_end = start - 1;
- (*pt_loads)[i].virt_end = kvstart - 1;
+ (*pt_loads)[i].phys_end = start;
+ (*pt_loads)[i].virt_end = kvstart;
} else {
- (*pt_loads)[i].phys_start = end + 1;
- (*pt_loads)[i].virt_start = kvend + 1;
+ (*pt_loads)[i].phys_start = end;
+ (*pt_loads)[i].virt_start = kvend;
}
(*pt_loads)[i].file_size -= (end -start);
}
@@ -917,7 +917,7 @@
for (i = 0; i < crash_reserved_mem_nr; i++) {
exclude_segment(&pt_loads, &num_pt_loads,
- crash_reserved_mem[i].start, crash_reserved_mem[i].end);
+ crash_reserved_mem[i].start, crash_reserved_mem[i].end + 1);
}
max_file_offset = 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.2/makedumpfile.8 new/makedumpfile-1.6.3/makedumpfile.8
--- old/makedumpfile-1.6.2/makedumpfile.8 2017-07-26 09:49:08.000000000 +0200
+++ new/makedumpfile-1.6.3/makedumpfile.8 2018-01-26 02:30:25.000000000 +0100
@@ -1,4 +1,4 @@
-.TH MAKEDUMPFILE 8 "27 Jul 2017" "makedumpfile v1.6.2" "Linux System Administrator's Manual"
+.TH MAKEDUMPFILE 8 "29 Jun 2018" "makedumpfile v1.6.3" "Linux System Administrator's Manual"
.SH NAME
makedumpfile \- make a small dumpfile of kdump
.SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.2/makedumpfile.c new/makedumpfile-1.6.3/makedumpfile.c
--- old/makedumpfile-1.6.2/makedumpfile.c 2017-07-26 09:49:08.000000000 +0200
+++ new/makedumpfile-1.6.3/makedumpfile.c 2018-01-26 02:30:25.000000000 +0100
@@ -1089,6 +1089,21 @@
return TRUE;
}
+static int populate_kernel_version(void)
+{
+ struct utsname utsname;
+
+ if (uname(&utsname)) {
+ ERRMSG("Cannot get name and information about current kernel : %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+
+ info->kernel_version = get_kernel_version(utsname.release);
+
+ return TRUE;
+}
+
int
check_release(void)
{
@@ -1486,6 +1501,8 @@
SYMBOL_INIT(_stext, "_stext");
SYMBOL_INIT(swapper_pg_dir, "swapper_pg_dir");
SYMBOL_INIT(init_level4_pgt, "init_level4_pgt");
+ SYMBOL_INIT(level4_kernel_pgt, "level4_kernel_pgt");
+ SYMBOL_INIT(init_top_pgt, "init_top_pgt");
SYMBOL_INIT(vmlist, "vmlist");
SYMBOL_INIT(vmap_area_list, "vmap_area_list");
SYMBOL_INIT(node_online_map, "node_online_map");
@@ -1517,8 +1534,13 @@
SYMBOL_INIT(__per_cpu_load, "__per_cpu_load");
SYMBOL_INIT(__per_cpu_offset, "__per_cpu_offset");
SYMBOL_INIT(cpu_online_mask, "cpu_online_mask");
- if (SYMBOL(cpu_online_mask) == NOT_FOUND_SYMBOL)
- SYMBOL_INIT(cpu_online_mask, "cpu_online_map");
+ SYMBOL_INIT(__cpu_online_mask, "__cpu_online_mask");
+ if (SYMBOL(cpu_online_mask) == NOT_FOUND_SYMBOL) {
+ if (SYMBOL(__cpu_online_mask) == NOT_FOUND_SYMBOL)
+ SYMBOL_INIT(cpu_online_mask, "cpu_online_map");
+ else
+ SYMBOL_INIT(cpu_online_mask, "__cpu_online_mask");
+ }
SYMBOL_INIT(kexec_crash_image, "kexec_crash_image");
SYMBOL_INIT(node_remap_start_vaddr, "node_remap_start_vaddr");
SYMBOL_INIT(node_remap_end_vaddr, "node_remap_end_vaddr");
@@ -1547,6 +1569,10 @@
SYMBOL_INIT(demote_segment_4k, "demote_segment_4k");
SYMBOL_INIT(cur_cpu_spec, "cur_cpu_spec");
+ SYMBOL_INIT(divide_error, "divide_error");
+ SYMBOL_INIT(idt_table, "idt_table");
+ SYMBOL_INIT(saved_command_line, "saved_command_line");
+
return TRUE;
}
@@ -2105,6 +2131,8 @@
WRITE_SYMBOL("_stext", _stext);
WRITE_SYMBOL("swapper_pg_dir", swapper_pg_dir);
WRITE_SYMBOL("init_level4_pgt", init_level4_pgt);
+ WRITE_SYMBOL("level4_kernel_pgt", level4_kernel_pgt);
+ WRITE_SYMBOL("init_top_pgt", init_top_pgt);
WRITE_SYMBOL("vmlist", vmlist);
WRITE_SYMBOL("vmap_area_list", vmap_area_list);
WRITE_SYMBOL("node_online_map", node_online_map);
@@ -2242,6 +2270,13 @@
WRITE_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset);
#endif
+ if (info->phys_base)
+ fprintf(info->file_vmcoreinfo, "%s%lu\n", STR_NUMBER("phys_base"),
+ info->phys_base);
+ if (info->kaslr_offset)
+ fprintf(info->file_vmcoreinfo, "%s%lx\n", STR_KERNELOFFSET,
+ info->kaslr_offset);
+
/*
* write the source file of 1st kernel
*/
@@ -2500,6 +2535,8 @@
READ_SYMBOL("_stext", _stext);
READ_SYMBOL("swapper_pg_dir", swapper_pg_dir);
READ_SYMBOL("init_level4_pgt", init_level4_pgt);
+ READ_SYMBOL("level4_kernel_pgt", level4_kernel_pgt);
+ READ_SYMBOL("init_top_pgt", init_top_pgt);
READ_SYMBOL("vmlist", vmlist);
READ_SYMBOL("vmap_area_list", vmap_area_list);
READ_SYMBOL("node_online_map", node_online_map);
@@ -3300,7 +3337,10 @@
return NOT_KV_ADDR;
}
map = ULONG(mem_section + OFFSET(mem_section.section_mem_map));
- map &= SECTION_MAP_MASK;
+ if (info->kernel_version < KERNEL_VERSION(4, 13, 0))
+ map &= SECTION_MAP_MASK_4_12;
+ else
+ map &= SECTION_MAP_MASK;
free(mem_section);
return map;
@@ -4203,7 +4243,7 @@
int byte, bit;
static int warning = 0;
- if (pfn < cycle->start_pfn || cycle->end_pfn <= pfn) {
+ if (!is_cyclic_region(pfn, cycle)) {
if (warning == 0) {
MSG("WARNING: PFN out of cycle range. (pfn:%llx, ", pfn);
MSG("cycle:[%llx-%llx])\n", cycle->start_pfn, cycle->end_pfn);
@@ -9401,15 +9441,15 @@
int
initial_xen(void)
{
- int xen_info_required = TRUE;
- off_t offset;
- unsigned long size;
-
#if defined(__powerpc64__) || defined(__powerpc32__)
MSG("\n");
MSG("Xen is not supported on powerpc.\n");
return FALSE;
#else
+ int xen_info_required = TRUE;
+ off_t offset;
+ unsigned long size;
+
#ifndef __x86_64__
if (DL_EXCLUDE_ZERO < info->max_dump_level) {
MSG("Dump_level is invalid. It should be 0 or 1.\n");
@@ -10925,6 +10965,9 @@
{
int ret;
+ if (arch_crashkernel_mem_size())
+ return TRUE;
+
ret = iomem_for_each_line("Crash kernel\n",
crashkernel_mem_callback, NULL);
crash_reserved_mem_nr = ret;
@@ -10934,20 +10977,14 @@
static int get_page_offset(void)
{
- struct utsname utsname;
- if (uname(&utsname)) {
- ERRMSG("Cannot get name and information about current kernel : %s",
- strerror(errno));
+ if (!populate_kernel_version())
return FALSE;
- }
- info->kernel_version = get_kernel_version(utsname.release);
get_versiondep_info();
return TRUE;
}
-
/* Returns the physical address of start of crash notes buffer for a kernel. */
static int get_sys_kernel_vmcoreinfo(uint64_t *addr, uint64_t *len)
{
@@ -11324,6 +11361,9 @@
MSG("Try `makedumpfile --help' for more information.\n");
goto out;
}
+ if (!populate_kernel_version())
+ goto out;
+
if (info->kernel_version < KERNEL_VERSION(4, 11, 0) &&
!info->flag_force) {
MSG("mem-usage not supported for this kernel.\n");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.2/makedumpfile.conf.5 new/makedumpfile-1.6.3/makedumpfile.conf.5
--- old/makedumpfile-1.6.2/makedumpfile.conf.5 2017-07-26 09:49:08.000000000 +0200
+++ new/makedumpfile-1.6.3/makedumpfile.conf.5 2018-01-26 02:30:25.000000000 +0100
@@ -1,4 +1,4 @@
-.TH MAKEDUMPFILE.CONF 5 "27 Jul 2017" "makedumpfile v1.6.2" "Linux System Administrator's Manual"
+.TH MAKEDUMPFILE.CONF 5 "29 Jun 2018" "makedumpfile v1.6.3" "Linux System Administrator's Manual"
.SH NAME
makedumpfile.conf \- The filter configuration file for makedumpfile(8).
.SH DESCRIPTION
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.2/makedumpfile.h new/makedumpfile-1.6.3/makedumpfile.h
--- old/makedumpfile-1.6.2/makedumpfile.h 2017-07-26 09:49:08.000000000 +0200
+++ new/makedumpfile-1.6.3/makedumpfile.h 2018-01-26 02:30:25.000000000 +0100
@@ -45,6 +45,7 @@
#include "sadump_mod.h"
#include
#include
+#include
#define VMEMMAPSTART 0xffffea0000000000UL
#define BITS_PER_WORD 64
@@ -183,7 +184,9 @@
#define SECTIONS_PER_ROOT() (info->sections_per_root)
#define SECTION_ROOT_MASK() (SECTIONS_PER_ROOT() - 1)
#define SECTION_NR_TO_ROOT(sec) ((sec) / SECTIONS_PER_ROOT())
-#define SECTION_MAP_LAST_BIT (1UL<<2)
+#define SECTION_IS_ONLINE (1UL<<2)
+#define SECTION_MAP_LAST_BIT (1UL<<3)
+#define SECTION_MAP_MASK_4_12 (~(SECTION_IS_ONLINE-1))
#define SECTION_MAP_MASK (~(SECTION_MAP_LAST_BIT-1))
#define NR_SECTION_ROOTS() divideup(num_section, SECTIONS_PER_ROOT())
#define SECTION_NR_TO_PFN(sec) ((sec) << PFN_SECTION_SHIFT())
@@ -475,7 +478,7 @@
#define KVER_MIN_SHIFT 16
#define KERNEL_VERSION(x,y,z) (((x) << KVER_MAJ_SHIFT) | ((y) << KVER_MIN_SHIFT) | (z))
#define OLDEST_VERSION KERNEL_VERSION(2, 6, 15)/* linux-2.6.15 */
-#define LATEST_VERSION KERNEL_VERSION(4, 11, 7)/* linux-4.11.7 */
+#define LATEST_VERSION KERNEL_VERSION(4, 14, 8)/* linux-4.14.8 */
/*
* vmcoreinfo in /proc/vmcore
@@ -666,6 +669,9 @@
#define PGD_INDEX_SIZE_L4_64K_3_10 12
#define PMD_INDEX_SIZE_L4_64K_4_6 5
#define PUD_INDEX_SIZE_L4_64K_4_6 5
+#define PMD_INDEX_SIZE_L4_64K_4_12 10
+#define PUD_INDEX_SIZE_L4_64K_4_12 7
+#define PGD_INDEX_SIZE_L4_64K_4_12 8
#define PTE_INDEX_SIZE_RADIX_64K 5
#define PMD_INDEX_SIZE_RADIX_64K 9
#define PUD_INDEX_SIZE_RADIX_64K 9
@@ -689,6 +695,11 @@
#define PUD_MASKED_BITS_4_7 0xc0000000000000ffUL
#define PMD_MASKED_BITS_4_7 0xc0000000000000ffUL
+#define PTE_RPN_SIZE_L4_4_11 53
+#define PTE_RPN_MASK_L4_4_11 \
+ (((1UL << PTE_RPN_SIZE_L4_4_11) - 1) & ~((1UL << info->page_shift) - 1))
+#define PTE_RPN_SHIFT_L4_4_11 info->page_shift
+
/*
* Supported MMU types
*/
@@ -933,6 +944,7 @@
#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)
+#define arch_crashkernel_mem_size() stub_false()
#endif /* aarch64 */
#ifdef __arm__
@@ -946,6 +958,7 @@
#define get_kaslr_offset(X) stub_false()
#define vaddr_to_paddr(X) vaddr_to_paddr_arm(X)
#define is_phys_addr(X) stub_true_ul(X)
+#define arch_crashkernel_mem_size() stub_false()
#endif /* arm */
#ifdef __x86__
@@ -959,6 +972,7 @@
#define get_kaslr_offset(X) stub_false()
#define vaddr_to_paddr(X) vaddr_to_paddr_x86(X)
#define is_phys_addr(X) stub_true_ul(X)
+#define arch_crashkernel_mem_size() stub_false()
#endif /* x86 */
#ifdef __x86_64__
@@ -967,6 +981,7 @@
int get_machdep_info_x86_64(void);
int get_versiondep_info_x86_64(void);
unsigned long long vtop4_x86_64(unsigned long vaddr);
+unsigned long long vtop4_x86_64_pagetable(unsigned long vaddr, unsigned long pagetable);
#define find_vmemmap() find_vmemmap_x86_64()
#define get_phys_base() get_phys_base_x86_64()
#define get_machdep_info() get_machdep_info_x86_64()
@@ -974,12 +989,14 @@
#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)
+#define arch_crashkernel_mem_size() stub_false()
#endif /* x86_64 */
#ifdef __powerpc64__ /* powerpc64 */
int get_machdep_info_ppc64(void);
int get_versiondep_info_ppc64(void);
unsigned long long vaddr_to_paddr_ppc64(unsigned long vaddr);
+int arch_crashkernel_mem_size_ppc64(void);
#define find_vmemmap() stub_false()
#define get_phys_base() stub_true()
#define get_machdep_info() get_machdep_info_ppc64()
@@ -987,6 +1004,7 @@
#define get_kaslr_offset(X) stub_false()
#define vaddr_to_paddr(X) vaddr_to_paddr_ppc64(X)
#define is_phys_addr(X) stub_true_ul(X)
+#define arch_crashkernel_mem_size() arch_crashkernel_mem_size_ppc64()
#endif /* powerpc64 */
#ifdef __powerpc32__ /* powerpc32 */
@@ -999,6 +1017,7 @@
#define get_kaslr_offset(X) stub_false()
#define vaddr_to_paddr(X) vaddr_to_paddr_ppc(X)
#define is_phys_addr(X) stub_true_ul(X)
+#define arch_crashkernel_mem_size() stub_false()
#endif /* powerpc32 */
#ifdef __s390x__ /* s390x */
@@ -1012,6 +1031,7 @@
#define get_kaslr_offset(X) stub_false()
#define vaddr_to_paddr(X) vaddr_to_paddr_s390x(X)
#define is_phys_addr(X) is_iomem_phys_addr_s390x(X)
+#define arch_crashkernel_mem_size() stub_false()
#endif /* s390x */
#ifdef __ia64__ /* ia64 */
@@ -1026,6 +1046,7 @@
#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)
+#define arch_crashkernel_mem_size() stub_false()
#endif /* ia64 */
#ifdef __sparc64__ /* sparc64 */
@@ -1038,6 +1059,7 @@
#define get_versiondep_info() get_versiondep_info_sparc64()
#define vaddr_to_paddr(X) vaddr_to_paddr_sparc64(X)
#define is_phys_addr(X) stub_true_ul(X)
+#define arch_crashkernel_mem_size() stub_false()
#endif /* sparc64 */
typedef unsigned long long mdf_pfn_t;
@@ -1517,6 +1539,8 @@
unsigned long long _stext;
unsigned long long swapper_pg_dir;
unsigned long long init_level4_pgt;
+ unsigned long long level4_kernel_pgt;
+ unsigned long long init_top_pgt;
unsigned long long vmlist;
unsigned long long vmap_area_list;
unsigned long long phys_base;
@@ -1578,7 +1602,11 @@
unsigned long long __per_cpu_offset;
unsigned long long __per_cpu_load;
unsigned long long cpu_online_mask;
+ unsigned long long __cpu_online_mask;
unsigned long long kexec_crash_image;
+ unsigned long long divide_error;
+ unsigned long long idt_table;
+ unsigned long long saved_command_line;
/*
* symbols on ppc64 arch
@@ -1939,7 +1967,8 @@
unsigned long base,
unsigned long length),
void *data);
-
+int is_bigendian(void);
+int get_symbol_info(void);
/*
* for Xen extraction
@@ -2096,11 +2125,20 @@
}
static inline int
-is_dumpable_buffer(struct dump_bitmap *bitmap, mdf_pfn_t pfn, struct cycle *cycle)
+is_cyclic_region(mdf_pfn_t pfn, struct cycle *cycle)
{
if (pfn < cycle->start_pfn || cycle->end_pfn <= pfn)
return FALSE;
else
+ return TRUE;
+}
+
+static inline int
+is_dumpable_buffer(struct dump_bitmap *bitmap, mdf_pfn_t pfn, struct cycle *cycle)
+{
+ if (!is_cyclic_region(pfn, cycle))
+ return FALSE;
+ else
return is_on(bitmap->buf, pfn - cycle->start_pfn);
}
@@ -2140,15 +2178,6 @@
}
static inline int
-is_cyclic_region(mdf_pfn_t pfn, struct cycle *cycle)
-{
- if (pfn < cycle->start_pfn || cycle->end_pfn <= pfn)
- return FALSE;
- else
- return TRUE;
-}
-
-static inline int
is_zero_page(unsigned char *buf, long page_size)
{
size_t i;
@@ -2244,7 +2273,7 @@
#define OPT_DEBUG 'D'
#define OPT_DUMP_LEVEL 'd'
#define OPT_ELF_DUMPFILE 'E'
-#define OPT_EXCLUDE_UNUSED_VM 'e'
+#define OPT_EXCLUDE_UNUSED_VM 'e'
#define OPT_FLATTEN 'F'
#define OPT_FORCE 'f'
#define OPT_GENERATE_VMCOREINFO 'g'
@@ -2271,10 +2300,10 @@
#define OPT_EPPIC OPT_START+11
#define OPT_NON_MMAP OPT_START+12
#define OPT_MEM_USAGE OPT_START+13
-#define OPT_SPLITBLOCK_SIZE OPT_START+14
+#define OPT_SPLITBLOCK_SIZE OPT_START+14
#define OPT_WORKING_DIR OPT_START+15
-#define OPT_NUM_THREADS OPT_START+16
-#define OPT_PARTIAL_DMESG OPT_START+17
+#define OPT_NUM_THREADS OPT_START+16
+#define OPT_PARTIAL_DMESG OPT_START+17
/*
* Function Prototype.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.2/makedumpfile.spec new/makedumpfile-1.6.3/makedumpfile.spec
--- old/makedumpfile-1.6.2/makedumpfile.spec 2017-07-26 09:49:08.000000000 +0200
+++ new/makedumpfile-1.6.3/makedumpfile.spec 2018-01-26 02:30:25.000000000 +0100
@@ -1,6 +1,6 @@
Name: makedumpfile
Summary: makedumpfile package
-Version: 1.6.2
+Version: 1.6.3
Release: 1
Group: Applications/Text
License: GPL
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/makedumpfile-1.6.2/sadump_info.c new/makedumpfile-1.6.3/sadump_info.c
--- old/makedumpfile-1.6.2/sadump_info.c 2017-07-26 09:49:08.000000000 +0200
+++ new/makedumpfile-1.6.3/sadump_info.c 2018-01-26 02:30:25.000000000 +0100
@@ -953,7 +953,8 @@
return FALSE;
}
- if (SIZE(cpumask) == NOT_FOUND_STRUCTURE)
+ if ((SIZE(cpumask) == NOT_FOUND_STRUCTURE) ||
+ (SYMBOL(__cpu_online_mask) != NOT_FOUND_SYMBOL))
cpu_online_mask_addr = SYMBOL(cpu_online_mask);
else {
@@ -1034,6 +1035,409 @@
#ifdef __x86_64__
+/*
+ * Get address of vector0 interrupt handler (Devide Error) form Interrupt
+ * Descriptor Table.
+ */
+static unsigned long
+get_vec0_addr(ulong idtr)
+{
+ struct gate_struct64 {
+ uint16_t offset_low;
+ uint16_t segment;
+ uint32_t ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
+ uint16_t offset_middle;
+ uint32_t offset_high;
+ uint32_t zero1;
+ } __attribute__((packed)) gate;
+
+ readmem(PADDR, idtr, &gate, sizeof(gate));
+
+ return ((ulong)gate.offset_high << 32)
+ + ((ulong)gate.offset_middle << 16)
+ + gate.offset_low;
+}
+
+/*
+ * Parse a string of [size[KMG]@]offset[KMG]
+ * Import from Linux kernel(lib/cmdline.c)
+ */
+static ulong memparse(char *ptr, char **retptr)
+{
+ char *endptr;
+
+ unsigned long long ret = strtoull(ptr, &endptr, 0);
+
+ switch (*endptr) {
+ case 'E':
+ case 'e':
+ ret <<= 10;
+ case 'P':
+ case 'p':
+ ret <<= 10;
+ case 'T':
+ case 't':
+ ret <<= 10;
+ case 'G':
+ case 'g':
+ ret <<= 10;
+ case 'M':
+ case 'm':
+ ret <<= 10;
+ case 'K':
+ case 'k':
+ ret <<= 10;
+ endptr++;
+ default:
+ break;
+ }
+
+ if (retptr)
+ *retptr = endptr;
+
+ return ret;
+}
+
+/*
+ * Find "elfcorehdr=" in the boot parameter of kernel and return the address
+ * of elfcorehdr.
+ */
+static ulong
+get_elfcorehdr(ulong cr3)
+{
+ char cmdline[BUFSIZE], *ptr;
+ ulong cmdline_vaddr;
+ ulong cmdline_paddr;
+ ulong buf_vaddr, buf_paddr;
+ char *end;
+ ulong elfcorehdr_addr = 0, elfcorehdr_size = 0;
+
+ if (SYMBOL(saved_command_line) == NOT_FOUND_SYMBOL) {
+ ERRMSG("Can't get the symbol of saved_command_line.\n");
+ return 0;
+ }
+ cmdline_vaddr = SYMBOL(saved_command_line);
+ if ((cmdline_paddr = vtop4_x86_64_pagetable(cmdline_vaddr, cr3)) == NOT_PADDR)
+ return 0;
+
+ DEBUG_MSG("sadump: cmdline vaddr: %lx\n", cmdline_vaddr);
+ DEBUG_MSG("sadump: cmdline paddr: %lx\n", cmdline_paddr);
+
+ if (!readmem(PADDR, cmdline_paddr, &buf_vaddr, sizeof(ulong)))
+ return 0;
+
+ if ((buf_paddr = vtop4_x86_64_pagetable(buf_vaddr, cr3)) == NOT_PADDR)
+ return 0;
+
+ DEBUG_MSG("sadump: cmdline buf vaddr: %lx\n", buf_vaddr);
+ DEBUG_MSG("sadump: cmdline buf paddr: %lx\n", buf_paddr);
+
+ memset(cmdline, 0, BUFSIZE);
+ if (!readmem(PADDR, buf_paddr, cmdline, BUFSIZE))
+ return 0;
+
+ ptr = strstr(cmdline, "elfcorehdr=");
+ if (!ptr)
+ return 0;
+
+ DEBUG_MSG("sadump: 2nd kernel detected.\n");
+
+ ptr += strlen("elfcorehdr=");
+ elfcorehdr_addr = memparse(ptr, &end);
+ if (*end == '@') {
+ elfcorehdr_size = elfcorehdr_addr;
+ elfcorehdr_addr = memparse(end + 1, &end);
+ }
+
+ DEBUG_MSG("sadump: elfcorehdr_addr: %lx\n", elfcorehdr_addr);
+ DEBUG_MSG("sadump: elfcorehdr_size: %lx\n", elfcorehdr_size);
+
+ return elfcorehdr_addr;
+}
+
+/*
+ * Get vmcoreinfo from elfcorehdr.
+ * Some codes are imported from Linux kernel(fs/proc/vmcore.c)
+ */
+static int
+get_vmcoreinfo_in_kdump_kernel(ulong elfcorehdr, ulong *addr, int *len)
+{
+ unsigned char e_ident[EI_NIDENT];
+ Elf64_Ehdr ehdr;
+ Elf64_Phdr phdr;
+ Elf64_Nhdr nhdr;
+ ulong ptr;
+ ulong nhdr_offset = 0;
+ int i;
+
+ if (!readmem(PADDR, elfcorehdr, e_ident, EI_NIDENT))
+ return FALSE;
+
+ if (e_ident[EI_CLASS] != ELFCLASS64) {
+ ERRMSG("Only ELFCLASS64 is supportd\n");
+ return FALSE;
+ }
+
+ if (!readmem(PADDR, elfcorehdr, &ehdr, sizeof(ehdr)))
+ return FALSE;
+
+ /* Sanity Check */
+ if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 ||
+ (ehdr.e_type != ET_CORE) ||
+ ehdr.e_ident[EI_CLASS] != ELFCLASS64 ||
+ ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
+ ehdr.e_version != EV_CURRENT ||
+ ehdr.e_ehsize != sizeof(Elf64_Ehdr) ||
+ ehdr.e_phentsize != sizeof(Elf64_Phdr) ||
+ ehdr.e_phnum == 0) {
+ ERRMSG("Invalid elf header\n");
+ return FALSE;
+ }
+
+ ptr = elfcorehdr + ehdr.e_phoff;
+ for (i = 0; i < ehdr.e_phnum; i++) {
+ ulong offset;
+ char name[16];
+
+ if (!readmem(PADDR, ptr, &phdr, sizeof(phdr)))
+ return FALSE;
+
+ ptr += sizeof(phdr);
+ if (phdr.p_type != PT_NOTE)
+ continue;
+
+ offset = phdr.p_offset;
+ if (!readmem(PADDR, offset, &nhdr, sizeof(nhdr)))
+ return FALSE;
+
+ offset += divideup(sizeof(Elf64_Nhdr), sizeof(Elf64_Word))*
+ sizeof(Elf64_Word);
+ memset(name, 0, sizeof(name));
+ if (!readmem(PADDR, offset, name, sizeof(name)))
+ return FALSE;
+
+ if(!strcmp(name, "VMCOREINFO")) {
+ nhdr_offset = offset;
+ break;
+ }
+ }
+
+ if (!nhdr_offset)
+ return FALSE;
+
+ *addr = nhdr_offset +
+ divideup(nhdr.n_namesz, sizeof(Elf64_Word))*
+ sizeof(Elf64_Word);
+ *len = nhdr.n_descsz;
+
+ DEBUG_MSG("sadump: vmcoreinfo addr: %lx\n", *addr);
+ DEBUG_MSG("sadump: vmcoreinfo len: %d\n", *len);
+
+ return TRUE;
+}
+
+/*
+ * Check if current kaslr_offset/phys_base is for 1st kernel or 2nd kernel.
+ * If we are in 2nd kernel, get kaslr_offset/phys_base from vmcoreinfo.
+ *
+ * 1. Get command line and try to retrieve "elfcorehdr=" boot parameter
+ * 2. If "elfcorehdr=" is not found in command line, we are in 1st kernel.
+ * There is nothing to do.
+ * 3. If "elfcorehdr=" is found, we are in 2nd kernel. Find vmcoreinfo
+ * using "elfcorehdr=" and retrieve kaslr_offset/phys_base from vmcoreinfo.
+ */
+int
+get_kaslr_offset_from_vmcoreinfo(ulong cr3, ulong *kaslr_offset,
+ ulong *phys_base)
+{
+ ulong elfcorehdr_addr = 0;
+ ulong vmcoreinfo_addr;
+ int vmcoreinfo_len;
+ char *buf, *pos;
+ int ret = FALSE;
+
+ elfcorehdr_addr = get_elfcorehdr(cr3);
+ if (!elfcorehdr_addr)
+ return FALSE;
+
+ if (!get_vmcoreinfo_in_kdump_kernel(elfcorehdr_addr, &vmcoreinfo_addr,
+ &vmcoreinfo_len))
+ return FALSE;
+
+ if (!vmcoreinfo_len)
+ return FALSE;
+
+ DEBUG_MSG("sadump: Find vmcoreinfo in kdump memory\n");
+
+ if (!(buf = malloc(vmcoreinfo_len))) {
+ ERRMSG("Can't allocate vmcoreinfo buffer.\n");
+ return FALSE;
+ }
+
+ if (!readmem(PADDR, vmcoreinfo_addr, buf, vmcoreinfo_len))
+ goto finish;
+
+ pos = strstr(buf, STR_NUMBER("phys_base"));
+ if (!pos)
+ goto finish;
+ *phys_base = strtoull(pos + strlen(STR_NUMBER("phys_base")), NULL, 0);
+
+ pos = strstr(buf, STR_KERNELOFFSET);
+ if (!pos)
+ goto finish;
+ *kaslr_offset = strtoull(pos + strlen(STR_KERNELOFFSET), NULL, 16);
+ ret = TRUE;
+
+finish:
+ free(buf);
+ return ret;
+}
+
+/*
+ * Calculate kaslr_offset and phys_base
+ *
+ * kaslr_offset:
+ * The difference between original address in vmlinux and actual address
+ * placed randomly by kaslr feature. To be more accurate,
+ * kaslr_offset = actual address - original address
+ *
+ * phys_base:
+ * Physical address where the kerenel is placed. In other words, it's a
+ * physical address of __START_KERNEL_map. This is also decided randomly by
+ * kaslr.
+ *
+ * kaslr offset and phys_base are calculated as follows:
+ *
+ * kaslr_offset:
+ * 1) Get IDTR and CR3 value from the dump header.
+ * 2) Get a virtual address of IDT from IDTR value
+ * --- (A)
+ * 3) Translate (A) to physical address using CR3, which points a top of
+ * page table.
+ * --- (B)
+ * 4) Get an address of vector0 (Devide Error) interrupt handler from
+ * IDT, which are pointed by (B).
+ * --- (C)
+ * 5) Get an address of symbol "divide_error" form vmlinux
+ * --- (D)
+ *
+ * Now we have two addresses:
+ * (C)-> Actual address of "divide_error"
+ * (D)-> Original address of "divide_error" in the vmlinux
+ *
+ * kaslr_offset can be calculated by the difference between these two
+ * value.
+ *
+ * phys_base;
+ * 1) Get IDT virtual address from vmlinux
+ * --- (E)
+ *
+ * So phys_base can be calculated using relationship of directly mapped
+ * address.
+ *
+ * phys_base =
+ * Physical address(B) -
+ * (Virtual address(E) + kaslr_offset - __START_KERNEL_map)
+ *
+ * Note that the address (A) cannot be used instead of (E) because (A) is
+ * not direct map address, it's a fixed map address.
+ *
+ * This solution works in most every case, but does not work in the
+ * following case.
+ *
+ * 1) If the dump is captured on early stage of kernel boot, IDTR points
+ * early IDT table(early_idts) instead of normal IDT(idt_table).
+ * 2) If the dump is captured whle kdump is working, IDTR points
+ * IDT table of 2nd kernel, not 1st kernel.
+ *
+ * Current implementation does not support the case 1), need
+ * enhancement in the future. For the case 2), get kaslr_offset and
+ * phys_base as follows.
+ *
+ * 1) Get kaslr_offset and phys_base using the above solution.
+ * 2) Get kernel boot parameter from "saved_command_line"
+ * 3) If "elfcorehdr=" is not included in boot parameter, we are in the
+ * first kernel, nothing to do any more.
+ * 4) If "elfcorehdr=" is included in boot parameter, we are in the 2nd
+ * kernel. Retrieve vmcoreinfo from address of "elfcorehdr=" and
+ * get kaslr_offset and phys_base from vmcoreinfo.
+ */
+int
+calc_kaslr_offset(void)
+{
+ struct sadump_header *sh = si->sh_memory;
+ uint64_t idtr = 0, cr3 = 0, idtr_paddr;
+ struct sadump_smram_cpu_state smram, zero;
+ int apicid;
+ unsigned long divide_error_vmcore, divide_error_vmlinux;
+ unsigned long kaslr_offset, phys_base;
+ unsigned long kaslr_offset_kdump, phys_base_kdump;
+
+ memset(&zero, 0, sizeof(zero));
+ for (apicid = 0; apicid < sh->nr_cpus; ++apicid) {
+ if (!get_smram_cpu_state(apicid, &smram)) {
+ ERRMSG("get_smram_cpu_state error\n");
+ return FALSE;
+ }
+
+ if (memcmp(&smram, &zero, sizeof(smram)) != 0)
+ break;
+ }
+ if (apicid >= sh->nr_cpus) {
+ ERRMSG("Can't get smram state\n");
+ return FALSE;
+ }
+
+ idtr = ((uint64_t)smram.IdtUpper)<<32 | (uint64_t)smram.IdtLower;
+ cr3 = smram.Cr3;
+
+ /* Convert virtual address of IDT table to physical address */
+ if ((idtr_paddr = vtop4_x86_64_pagetable(idtr, cr3)) == NOT_PADDR)
+ return FALSE;
+
+ /* Now we can calculate kaslr_offset and phys_base */
+ divide_error_vmlinux = SYMBOL(divide_error);
+ divide_error_vmcore = get_vec0_addr(idtr_paddr);
+ kaslr_offset = divide_error_vmcore - divide_error_vmlinux;
+ phys_base = idtr_paddr -
+ (SYMBOL(idt_table) + kaslr_offset - __START_KERNEL_map);
+
+ info->kaslr_offset = kaslr_offset;
+ info->phys_base = phys_base;
+
+ DEBUG_MSG("sadump: idtr=%" PRIx64 "\n", idtr);
+ DEBUG_MSG("sadump: cr3=%" PRIx64 "\n", cr3);
+ DEBUG_MSG("sadump: idtr(phys)=%" PRIx64 "\n", idtr_paddr);
+ DEBUG_MSG("sadump: devide_error(vmlinux)=%lx\n",
+ divide_error_vmlinux);
+ DEBUG_MSG("sadump: devide_error(vmcore)=%lx\n",
+ divide_error_vmcore);
+
+ /* Reload symbol */
+ if (!get_symbol_info())
+ return FALSE;
+
+ /*
+ * Check if current kaslr_offset/phys_base is for 1st kernel or 2nd
+ * kernel. If we are in 2nd kernel, get kaslr_offset/phys_base
+ * from vmcoreinfo
+ */
+ if (get_kaslr_offset_from_vmcoreinfo(cr3, &kaslr_offset_kdump,
+ &phys_base_kdump)) {
+ info->kaslr_offset = kaslr_offset_kdump;
+ info->phys_base = phys_base_kdump;
+
+ /* Reload symbol */
+ if (!get_symbol_info())
+ return FALSE;
+ }
+
+ DEBUG_MSG("sadump: kaslr_offset=%lx\n", info->kaslr_offset);
+ DEBUG_MSG("sadump: phys_base=%lx\n", info->phys_base);
+
+ return TRUE;
+}
+
int
sadump_virt_phys_base(void)
{
@@ -1064,6 +1468,9 @@
}
failed:
+ if (calc_kaslr_offset())
+ return TRUE;
+
info->phys_base = 0;
DEBUG_MSG("sadump: failed to calculate phys_base; default to 0\n");
@@ -1517,10 +1924,14 @@
if (!readmem(VADDR, SYMBOL(x86_bios_cpu_apicid_early_ptr),
&early_ptr, sizeof(early_ptr)))
return FALSE;
-
+ /*
+ * Note: SYMBOL(name) value is adjusted by info->kaslr_offset,
+ * but per_cpu symbol does not need to be adjusted becasue it
+ * is not affected by kaslr.
+ */
apicid_addr = early_ptr
? SYMBOL(x86_bios_cpu_apicid_early_map)+cpu*sizeof(uint16_t)
- : per_cpu_ptr(SYMBOL(x86_bios_cpu_apicid), cpu);
+ : per_cpu_ptr(SYMBOL(x86_bios_cpu_apicid) - info->kaslr_offset, cpu);
if (!readmem(VADDR, apicid_addr, &apicid_u16, sizeof(uint16_t)))
return FALSE;
++++++ makedumpfile-always-use-bigger-SECTION_MAP_MASK.patch ++++++
From: Petr Tesarik
Date: Mon, 29 Jan 2018 14:59:28 +0200
Subject: Always use bigger SECTION_MAP_MASK
References: bsc#1066811, bsc#1067703
Upstream: not yet
Since kernel commit 2d070eab2e82 merely reused a previously unused bit, it
is safe to mask it off for all kernel versions, because it had always been
zero (even in kernels < 4.13).
Signed-off-by: Petr Tesarik
---
makedumpfile.c | 5 +----
makedumpfile.h | 1 -
2 files changed, 1 insertion(+), 5 deletions(-)
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -3337,10 +3337,7 @@ section_mem_map_addr(unsigned long addr)
return NOT_KV_ADDR;
}
map = ULONG(mem_section + OFFSET(mem_section.section_mem_map));
- if (info->kernel_version < KERNEL_VERSION(4, 13, 0))
- map &= SECTION_MAP_MASK_4_12;
- else
- map &= SECTION_MAP_MASK;
+ map &= SECTION_MAP_MASK;
free(mem_section);
return map;
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -186,7 +186,6 @@ isAnon(unsigned long mapping)
#define SECTION_NR_TO_ROOT(sec) ((sec) / SECTIONS_PER_ROOT())
#define SECTION_IS_ONLINE (1UL<<2)
#define SECTION_MAP_LAST_BIT (1UL<<3)
-#define SECTION_MAP_MASK_4_12 (~(SECTION_IS_ONLINE-1))
#define SECTION_MAP_MASK (~(SECTION_MAP_LAST_BIT-1))
#define NR_SECTION_ROOTS() divideup(num_section, SECTIONS_PER_ROOT())
#define SECTION_NR_TO_PFN(sec) ((sec) << PFN_SECTION_SHIFT())