diff -Nru makedumpfile-1.6.7/debian/changelog makedumpfile-1.6.7/debian/changelog --- makedumpfile-1.6.7/debian/changelog 2020-08-12 11:53:22.000000000 +0300 +++ makedumpfile-1.6.7/debian/changelog 2021-04-15 22:48:25.000000000 +0300 @@ -1,3 +1,13 @@ +makedumpfile (1:1.6.7-4ubuntu1.1) groovy; urgency=medium + + * Fix makedumpfile failure on arm64 with 5.4 kernels (LP: #1879214) + -d/p/0004-PATCH-arm64-Add-support-for-ARMv8.2-LPA-52-bit-PA-su.patch + -d/p/0005-PATCH-1-3-Use-vmcoreinfo-note-in-proc-kcore-for-mem-.patch + -d/p/0006-PATCH-2-3-arm64-Make-use-of-NUMBER-VA_BITS-in-vmcore.patch + -d/p/0007-PATCH-3-3-arm64-support-flipped-VA-and-52-bit-kernel.patch + + -- Ioanna Alifieraki Thu, 15 Apr 2021 22:48:25 +0300 + makedumpfile (1:1.6.7-4ubuntu1) groovy; urgency=low * Merge from Debian unstable. Remaining changes: diff -Nru makedumpfile-1.6.7/debian/patches/0004-PATCH-arm64-Add-support-for-ARMv8.2-LPA-52-bit-PA-su.patch makedumpfile-1.6.7/debian/patches/0004-PATCH-arm64-Add-support-for-ARMv8.2-LPA-52-bit-PA-su.patch --- makedumpfile-1.6.7/debian/patches/0004-PATCH-arm64-Add-support-for-ARMv8.2-LPA-52-bit-PA-su.patch 1970-01-01 02:00:00.000000000 +0200 +++ makedumpfile-1.6.7/debian/patches/0004-PATCH-arm64-Add-support-for-ARMv8.2-LPA-52-bit-PA-su.patch 2021-04-15 22:47:33.000000000 +0300 @@ -0,0 +1,419 @@ +From da0d25ffa585c9a1adb94562c815daa393b1ee5e Mon Sep 17 00:00:00 2001 +From: Bhupesh Sharma +Date: Thu, 10 Sep 2020 11:03:04 +0530 +Subject: [PATCH] [PATCH] arm64: Add support for ARMv8.2-LPA (52-bit PA + support) + +ARMv8.2-LPA architecture extension (if available on underlying hardware) +can support 52-bit physical addresses, while the kernel virtual +addresses remain 48-bit. + +Make sure that we read the 52-bit PA address capability from +'MAX_PHYSMEM_BITS' variable (if available in vmcoreinfo) and +accordingly change the pte_to_phy() mask values and also traverse +the page-table walk accordingly. + +Also make sure that it works well for the existing 48-bit PA address +platforms and also on environments which use newer kernels with 52-bit +PA support but hardware which is not ARM8.2-LPA compliant. + +Kernel commit 1d50e5d0c505 ("crash_core, vmcoreinfo: Append +'MAX_PHYSMEM_BITS' to vmcoreinfo") already supports adding +'MAX_PHYSMEM_BITS' variable to vmcoreinfo. + +This patch is in accordance with ARMv8 Architecture Reference Manual + +Signed-off-by: Bhupesh Sharma + +Origin: upstream, https://github.com/makedumpfile/makedumpfile/commit/da0d25ffa585c9a1adb94562c815daa393b1ee5e +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=986594 +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1879214 +--- + arch/arm64.c | 294 +++++++++++++++++++++++++++++++++++---------------- + 1 file changed, 205 insertions(+), 89 deletions(-) + +--- a/arch/arm64.c ++++ b/arch/arm64.c +@@ -39,72 +39,184 @@ typedef struct { + unsigned long pte; + } pte_t; + ++#define __pte(x) ((pte_t) { (x) } ) ++#define __pmd(x) ((pmd_t) { (x) } ) ++#define __pud(x) ((pud_t) { (x) } ) ++#define __pgd(x) ((pgd_t) { (x) } ) ++ ++static int lpa_52_bit_support_available; + static int pgtable_level; + static int va_bits; + static unsigned long kimage_voffset; + +-#define SZ_4K (4 * 1024) +-#define SZ_16K (16 * 1024) +-#define SZ_64K (64 * 1024) +-#define SZ_128M (128 * 1024 * 1024) +- +-#define PAGE_OFFSET_36 ((0xffffffffffffffffUL) << 36) +-#define PAGE_OFFSET_39 ((0xffffffffffffffffUL) << 39) +-#define PAGE_OFFSET_42 ((0xffffffffffffffffUL) << 42) +-#define PAGE_OFFSET_47 ((0xffffffffffffffffUL) << 47) +-#define PAGE_OFFSET_48 ((0xffffffffffffffffUL) << 48) ++#define SZ_4K 4096 ++#define SZ_16K 16384 ++#define SZ_64K 65536 ++ ++#define PAGE_OFFSET_36 ((0xffffffffffffffffUL) << 36) ++#define PAGE_OFFSET_39 ((0xffffffffffffffffUL) << 39) ++#define PAGE_OFFSET_42 ((0xffffffffffffffffUL) << 42) ++#define PAGE_OFFSET_47 ((0xffffffffffffffffUL) << 47) ++#define PAGE_OFFSET_48 ((0xffffffffffffffffUL) << 48) ++#define PAGE_OFFSET_52 ((0xffffffffffffffffUL) << 52) + + #define pgd_val(x) ((x).pgd) + #define pud_val(x) (pgd_val((x).pgd)) + #define pmd_val(x) (pud_val((x).pud)) + #define pte_val(x) ((x).pte) + +-#define PAGE_MASK (~(PAGESIZE() - 1)) +-#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) +-#define PMD_SIZE (1UL << PMD_SHIFT) +-#define PMD_MASK (~(PMD_SIZE - 1)) ++/* See 'include/uapi/linux/const.h' for definitions below */ ++#define __AC(X,Y) (X##Y) ++#define _AC(X,Y) __AC(X,Y) ++#define _AT(T,X) ((T)(X)) ++ ++/* See 'include/asm/pgtable-types.h' for definitions below */ ++typedef unsigned long pteval_t; ++typedef unsigned long pmdval_t; ++typedef unsigned long pudval_t; ++typedef unsigned long pgdval_t; ++ ++#define PAGE_SHIFT PAGESHIFT() ++ ++/* See 'arch/arm64/include/asm/pgtable-hwdef.h' for definitions below */ ++ ++#define ARM64_HW_PGTABLE_LEVEL_SHIFT(n) ((PAGE_SHIFT - 3) * (4 - (n)) + 3) ++ ++#define PTRS_PER_PTE (1 << (PAGE_SHIFT - 3)) ++ ++/* ++ * PMD_SHIFT determines the size a level 2 page table entry can map. ++ */ ++#define PMD_SHIFT ARM64_HW_PGTABLE_LEVEL_SHIFT(2) ++#define PMD_SIZE (_AC(1, UL) << PMD_SHIFT) ++#define PMD_MASK (~(PMD_SIZE-1)) + #define PTRS_PER_PMD PTRS_PER_PTE + +-#define PAGE_PRESENT (1 << 0) ++/* ++ * PUD_SHIFT determines the size a level 1 page table entry can map. ++ */ ++#define PUD_SHIFT ARM64_HW_PGTABLE_LEVEL_SHIFT(1) ++#define PUD_SIZE (_AC(1, UL) << PUD_SHIFT) ++#define PUD_MASK (~(PUD_SIZE-1)) ++#define PTRS_PER_PUD PTRS_PER_PTE ++ ++/* ++ * PGDIR_SHIFT determines the size a top-level page table entry can map ++ * (depending on the configuration, this level can be 0, 1 or 2). ++ */ ++#define PGDIR_SHIFT ARM64_HW_PGTABLE_LEVEL_SHIFT(4 - (pgtable_level)) ++#define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT) ++#define PGDIR_MASK (~(PGDIR_SIZE-1)) ++#define PTRS_PER_PGD (1 << ((va_bits) - PGDIR_SHIFT)) ++ ++/* ++ * Section address mask and size definitions. ++ */ + #define SECTIONS_SIZE_BITS 30 +-/* Highest possible physical address supported */ +-#define PHYS_MASK_SHIFT 48 +-#define PHYS_MASK ((1UL << PHYS_MASK_SHIFT) - 1) ++ + /* +- * Remove the highest order bits that are not a part of the +- * physical address in a section ++ * Hardware page table definitions. ++ * ++ * Level 1 descriptor (PUD). + */ +-#define PMD_SECTION_MASK ((1UL << PHYS_MASK_SHIFT) - 1) ++#define PUD_TYPE_TABLE (_AT(pudval_t, 3) << 0) ++#define PUD_TABLE_BIT (_AT(pudval_t, 1) << 1) ++#define PUD_TYPE_MASK (_AT(pudval_t, 3) << 0) ++#define PUD_TYPE_SECT (_AT(pudval_t, 1) << 0) + +-#define PMD_TYPE_MASK 3 +-#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)) +- +-#define pte_index(vaddr) (((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1)) +-#define pmd_page_paddr(pmd) (pmd_val(pmd) & PHYS_MASK & (int32_t)PAGE_MASK) +-#define pte_offset(dir, vaddr) ((pte_t*)pmd_page_paddr((*dir)) + pte_index(vaddr)) ++/* ++ * Level 2 descriptor (PMD). ++ */ ++#define PMD_TYPE_MASK (_AT(pmdval_t, 3) << 0) ++#define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0) ++#define PMD_TYPE_TABLE (_AT(pmdval_t, 3) << 0) ++#define PMD_TYPE_SECT (_AT(pmdval_t, 1) << 0) ++#define PMD_TABLE_BIT (_AT(pmdval_t, 1) << 1) + +-#define pmd_index(vaddr) (((vaddr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) +-#define pud_page_paddr(pud) (pud_val(pud) & PHYS_MASK & (int32_t)PAGE_MASK) +-#define pmd_offset_pgtbl_lvl_2(pud, vaddr) ((pmd_t *)pud) +-#define pmd_offset_pgtbl_lvl_3(pud, vaddr) ((pmd_t *)pud_page_paddr((*pud)) + pmd_index(vaddr)) ++/* ++ * Level 3 descriptor (PTE). ++ */ ++#define PTE_ADDR_LOW (((_AT(pteval_t, 1) << (48 - PAGE_SHIFT)) - 1) << PAGE_SHIFT) ++#define PTE_ADDR_HIGH (_AT(pteval_t, 0xf) << 12) ++ ++static inline unsigned long ++get_pte_addr_mask_arm64(void) ++{ ++ if (lpa_52_bit_support_available) ++ return (PTE_ADDR_LOW | PTE_ADDR_HIGH); ++ else ++ return PTE_ADDR_LOW; ++} ++ ++#define PTE_ADDR_MASK get_pte_addr_mask_arm64() ++ ++#define PAGE_MASK (~(PAGESIZE() - 1)) ++#define PAGE_PRESENT (1 << 0) ++ ++/* Helper API to convert between a physical address and its placement ++ * in a page table entry, taking care of 52-bit addresses. ++ */ ++static inline unsigned long ++__pte_to_phys(pte_t pte) ++{ ++ if (lpa_52_bit_support_available) ++ return ((pte_val(pte) & PTE_ADDR_LOW) | ((pte_val(pte) & PTE_ADDR_HIGH) << 36)); ++ else ++ return (pte_val(pte) & PTE_ADDR_MASK); ++} ++ ++/* Find an entry in a page-table-directory */ ++#define pgd_index(vaddr) (((vaddr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) ++ ++static inline pte_t ++pgd_pte(pgd_t pgd) ++{ ++ return __pte(pgd_val(pgd)); ++} ++ ++#define __pgd_to_phys(pgd) __pte_to_phys(pgd_pte(pgd)) ++#define pgd_offset(pgd, vaddr) ((pgd_t *)(pgd) + pgd_index(vaddr)) ++ ++static inline pte_t pud_pte(pud_t pud) ++{ ++ return __pte(pud_val(pud)); ++} ++ ++static inline unsigned long ++pgd_page_paddr(pgd_t pgd) ++{ ++ return __pgd_to_phys(pgd); ++} + ++/* Find an entry in the first-level page table. */ + #define pud_index(vaddr) (((vaddr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1)) +-#define pgd_page_paddr(pgd) (pgd_val(pgd) & PHYS_MASK & (int32_t)PAGE_MASK) ++#define __pud_to_phys(pud) __pte_to_phys(pud_pte(pud)) ++ ++static inline unsigned long ++pud_page_paddr(pud_t pud) ++{ ++ return __pud_to_phys(pud); ++} ++ ++/* Find an entry in the second-level page table. */ ++#define pmd_index(vaddr) (((vaddr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) ++ ++static inline pte_t pmd_pte(pmd_t pmd) ++{ ++ return __pte(pmd_val(pmd)); ++} ++ ++#define __pmd_to_phys(pmd) __pte_to_phys(pmd_pte(pmd)) ++ ++static inline unsigned long ++pmd_page_paddr(pmd_t pmd) ++{ ++ return __pmd_to_phys(pmd); ++} ++ ++/* Find an entry in the third-level page table. */ ++#define pte_index(vaddr) (((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1)) ++#define pte_offset(dir, vaddr) (pmd_page_paddr((*dir)) + pte_index(vaddr) * sizeof(pte_t)) + + static unsigned long long + __pa(unsigned long vaddr) +@@ -116,32 +228,22 @@ __pa(unsigned long vaddr) + return (vaddr - kimage_voffset); + } + +-static int +-get_pud_shift_arm64(void) ++static pud_t * ++pud_offset(pgd_t *pgda, pgd_t *pgdv, unsigned long vaddr) + { +- if (pgtable_level == 4) +- return ((PAGESHIFT() - 3) * 3 + 3); ++ if (pgtable_level > 3) ++ return (pud_t *)(pgd_page_paddr(*pgdv) + pud_index(vaddr) * sizeof(pud_t)); + else +- return PGDIR_SHIFT; ++ return (pud_t *)(pgda); + } + + static pmd_t * + pmd_offset(pud_t *puda, pud_t *pudv, unsigned long vaddr) + { +- if (pgtable_level == 2) { +- return pmd_offset_pgtbl_lvl_2(puda, vaddr); +- } else { +- return pmd_offset_pgtbl_lvl_3(pudv, vaddr); +- } +-} +- +-static pud_t * +-pud_offset(pgd_t *pgda, pgd_t *pgdv, unsigned long vaddr) +-{ +- if (pgtable_level == 4) +- return ((pud_t *)pgd_page_paddr((*pgdv)) + pud_index(vaddr)); ++ if (pgtable_level > 2) ++ return (pmd_t *)(pud_page_paddr(*pudv) + pmd_index(vaddr) * sizeof(pmd_t)); + else +- return (pud_t *)(pgda); ++ return (pmd_t *)(puda); + } + + static int calculate_plat_config(void) +@@ -246,6 +348,14 @@ get_stext_symbol(void) + int + get_machdep_info_arm64(void) + { ++ /* Determine if the PA address range is 52-bits: ARMv8.2-LPA */ ++ if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER) { ++ info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS); ++ if (info->max_physmem_bits == 52) ++ lpa_52_bit_support_available = 1; ++ } else ++ info->max_physmem_bits = 48; ++ + /* Check if va_bits is still not initialized. If still 0, call + * get_versiondep_info() to initialize the same. + */ +@@ -258,12 +368,11 @@ get_machdep_info_arm64(void) + } + + kimage_voffset = NUMBER(kimage_voffset); +- info->max_physmem_bits = PHYS_MASK_SHIFT; + info->section_size_bits = SECTIONS_SIZE_BITS; + + DEBUG_MSG("kimage_voffset : %lx\n", kimage_voffset); +- DEBUG_MSG("max_physmem_bits : %lx\n", info->max_physmem_bits); +- DEBUG_MSG("section_size_bits: %lx\n", info->section_size_bits); ++ DEBUG_MSG("max_physmem_bits : %ld\n", info->max_physmem_bits); ++ DEBUG_MSG("section_size_bits: %ld\n", info->section_size_bits); + + return TRUE; + } +@@ -321,6 +430,19 @@ get_versiondep_info_arm64(void) + return TRUE; + } + ++/* 1GB section for Page Table level = 4 and Page Size = 4KB */ ++static int ++is_pud_sect(pud_t pud) ++{ ++ return ((pud_val(pud) & PUD_TYPE_MASK) == PUD_TYPE_SECT); ++} ++ ++static int ++is_pmd_sect(pmd_t pmd) ++{ ++ return ((pmd_val(pmd) & PMD_TYPE_MASK) == PMD_TYPE_SECT); ++} ++ + /* + * vaddr_to_paddr_arm64() - translate arbitrary virtual address to physical + * @vaddr: virtual address to translate +@@ -358,10 +480,9 @@ vaddr_to_paddr_arm64(unsigned long vaddr + 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)); ++ if (is_pud_sect(pudv)) { ++ paddr = (pud_page_paddr(pudv) & PUD_MASK) + ++ (vaddr & (PUD_SIZE - 1)); + return paddr; + } + +@@ -371,29 +492,24 @@ vaddr_to_paddr_arm64(unsigned long vaddr + return NOT_PADDR; + } + +- switch (pmd_val(pmdv) & PMD_TYPE_MASK) { +- case PMD_TYPE_TABLE: +- ptea = pte_offset(&pmdv, vaddr); +- /* 64k page */ +- if (!readmem(PADDR, (unsigned long long)ptea, &ptev, sizeof(ptev))) { +- ERRMSG("Can't read pte\n"); +- return NOT_PADDR; +- } ++ if (is_pmd_sect(pmdv)) { ++ paddr = (pmd_page_paddr(pmdv) & PMD_MASK) + ++ (vaddr & (PMD_SIZE - 1)); ++ return paddr; ++ } + +- if (!(pte_val(ptev) & PAGE_PRESENT)) { +- ERRMSG("Can't get a valid pte.\n"); +- return NOT_PADDR; +- } else { ++ ptea = (pte_t *)pte_offset(&pmdv, vaddr); ++ if (!readmem(PADDR, (unsigned long long)ptea, &ptev, sizeof(ptev))) { ++ ERRMSG("Can't read pte\n"); ++ return NOT_PADDR; ++ } + +- paddr = (PAGEBASE(pte_val(ptev)) & PHYS_MASK) +- + (vaddr & (PAGESIZE() - 1)); +- } +- break; +- case PMD_TYPE_SECT: +- /* 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; ++ if (!(pte_val(ptev) & PAGE_PRESENT)) { ++ ERRMSG("Can't get a valid pte.\n"); ++ return NOT_PADDR; ++ } else { ++ paddr = __pte_to_phys(ptev) + ++ (vaddr & (PAGESIZE() - 1)); + } + + return paddr; diff -Nru makedumpfile-1.6.7/debian/patches/0005-PATCH-1-3-Use-vmcoreinfo-note-in-proc-kcore-for-mem-.patch makedumpfile-1.6.7/debian/patches/0005-PATCH-1-3-Use-vmcoreinfo-note-in-proc-kcore-for-mem-.patch --- makedumpfile-1.6.7/debian/patches/0005-PATCH-1-3-Use-vmcoreinfo-note-in-proc-kcore-for-mem-.patch 1970-01-01 02:00:00.000000000 +0200 +++ makedumpfile-1.6.7/debian/patches/0005-PATCH-1-3-Use-vmcoreinfo-note-in-proc-kcore-for-mem-.patch 2021-04-15 22:47:50.000000000 +0300 @@ -0,0 +1,140 @@ +From: Kazuhito Hagio +Date: Fri, 29 Jan 2021 11:40:23 +0900 +Subject: [PATCH 1/3] Use vmcoreinfo note in /proc/kcore for --mem-usage + option + +kernel commit 23c85094fe18 added vmcoreinfo note to /proc/kcore. +Use the vmcoreinfo note to get necessary information, especially +page_offset and phys_base on arm64, for the --mem-usage option. + +Signed-off-by: Kazuhito Hagio + +Origin: upstream, https://github.com/makedumpfile/makedumpfile/commit/d8b701796f0491f2ac4b06c7a5b795c29399efab +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=986594 +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1879214 +--- + elf_info.c | 49 ------------------------------------------------- + elf_info.h | 1 - + makedumpfile.c | 26 +++++++++++++++++++++----- + 3 files changed, 21 insertions(+), 55 deletions(-) + +--- a/elf_info.c ++++ b/elf_info.c +@@ -759,55 +759,6 @@ get_elf32_ehdr(int fd, char *filename, E + return TRUE; + } + +-int +-get_elf_loads(int fd, char *filename) +-{ +- int i, j, phnum, elf_format; +- Elf64_Phdr phdr; +- +- /* +- * Check ELF64 or ELF32. +- */ +- elf_format = check_elf_format(fd, filename, &phnum, &num_pt_loads); +- if (elf_format == ELF64) +- flags_memory |= MEMORY_ELF64; +- else if (elf_format != ELF32) +- return FALSE; +- +- if (!num_pt_loads) { +- ERRMSG("Can't get the number of PT_LOAD.\n"); +- return FALSE; +- } +- +- /* +- * The below file information will be used as /proc/vmcore. +- */ +- fd_memory = fd; +- name_memory = filename; +- +- pt_loads = calloc(sizeof(struct pt_load_segment), num_pt_loads); +- if (pt_loads == NULL) { +- ERRMSG("Can't allocate memory for the PT_LOAD. %s\n", +- strerror(errno)); +- return FALSE; +- } +- for (i = 0, j = 0; i < phnum; i++) { +- if (!get_phdr_memory(i, &phdr)) +- return FALSE; +- +- if (phdr.p_type != PT_LOAD) +- continue; +- +- if (j >= num_pt_loads) +- return FALSE; +- if (!dump_Elf_load(&phdr, j)) +- return FALSE; +- j++; +- } +- +- return TRUE; +-} +- + static int exclude_segment(struct pt_load_segment **pt_loads, + unsigned int *num_pt_loads, uint64_t start, uint64_t end) + { +--- a/elf_info.h ++++ b/elf_info.h +@@ -47,7 +47,6 @@ int get_elf64_ehdr(int fd, char *filenam + int get_elf32_ehdr(int fd, char *filename, Elf32_Ehdr *ehdr); + int get_elf_info(int fd, char *filename); + void free_elf_info(void); +-int get_elf_loads(int fd, char *filename); + int set_kcore_vmcoreinfo(uint64_t vmcoreinfo_addr, uint64_t vmcoreinfo_len); + int get_kcore_dump_loads(void); + +--- a/makedumpfile.c ++++ b/makedumpfile.c +@@ -11351,6 +11351,7 @@ int show_mem_usage(void) + { + uint64_t vmcoreinfo_addr, vmcoreinfo_len; + struct cycle cycle = {0}; ++ int vmcoreinfo = FALSE; + + if (!is_crashkernel_mem_reserved()) { + ERRMSG("No memory is reserved for crashkernel!\n"); +@@ -11362,9 +11363,22 @@ int show_mem_usage(void) + if (!open_files_for_creating_dumpfile()) + return FALSE; + +- if (!get_elf_loads(info->fd_memory, info->name_memory)) ++ if (!get_elf_info(info->fd_memory, info->name_memory)) + return FALSE; + ++ /* ++ * /proc/kcore on Linux 4.19 and later kernels have vmcoreinfo note in ++ * NOTE segment. See commit 23c85094fe18. ++ */ ++ if (has_vmcoreinfo()) { ++ off_t offset; ++ unsigned long size; ++ ++ get_vmcoreinfo(&offset, &size); ++ vmcoreinfo = read_vmcoreinfo_from_vmcore(offset, size, FALSE); ++ DEBUG_MSG("Read vmcoreinfo from NOTE segment: %d\n", vmcoreinfo); ++ } ++ + if (!get_page_offset()) + return FALSE; + +@@ -11372,11 +11386,13 @@ int show_mem_usage(void) + if (!get_phys_base()) + return FALSE; + +- if (!get_sys_kernel_vmcoreinfo(&vmcoreinfo_addr, &vmcoreinfo_len)) +- return FALSE; ++ if (!vmcoreinfo) { ++ if (!get_sys_kernel_vmcoreinfo(&vmcoreinfo_addr, &vmcoreinfo_len)) ++ return FALSE; + +- if (!set_kcore_vmcoreinfo(vmcoreinfo_addr, vmcoreinfo_len)) +- return FALSE; ++ if (!set_kcore_vmcoreinfo(vmcoreinfo_addr, vmcoreinfo_len)) ++ return FALSE; ++ } + + if (!initial()) + return FALSE; diff -Nru makedumpfile-1.6.7/debian/patches/0006-PATCH-2-3-arm64-Make-use-of-NUMBER-VA_BITS-in-vmcore.patch makedumpfile-1.6.7/debian/patches/0006-PATCH-2-3-arm64-Make-use-of-NUMBER-VA_BITS-in-vmcore.patch --- makedumpfile-1.6.7/debian/patches/0006-PATCH-2-3-arm64-Make-use-of-NUMBER-VA_BITS-in-vmcore.patch 1970-01-01 02:00:00.000000000 +0200 +++ makedumpfile-1.6.7/debian/patches/0006-PATCH-2-3-arm64-Make-use-of-NUMBER-VA_BITS-in-vmcore.patch 2021-04-15 22:48:06.000000000 +0300 @@ -0,0 +1,98 @@ +From: Kazuhito Hagio +Date: Fri, 29 Jan 2021 11:40:24 +0900 +Subject: [PATCH 2/3] arm64: Make use of NUMBER(VA_BITS) in vmcoreinfo + +Make use of the NUMBER(VA_BITS) in vmcoreinfo, which was added by +kernel commit 20a166243328 (Linux 4.12 and later kernels), as the +current way of guessing VA_BITS does not work on Linux 5.4 and +later kernels. + +Signed-off-by: Bhupesh Sharma +Signed-off-by: Kazuhito Hagio + +Origin: upstream, https://github.com/makedumpfile/makedumpfile/commit/67d0e1d68f28c567a704fd6b9b8fd696ad3df183 +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=986594 +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1879214 +--- + arch/arm64.c | 63 ++++++++++++++++++++++++++++++++++++++++-------------------- + 1 file changed, 42 insertions(+), 21 deletions(-) + +--- a/arch/arm64.c ++++ b/arch/arm64.c +@@ -345,6 +345,43 @@ get_stext_symbol(void) + return(found ? kallsym : FALSE); + } + ++static int ++get_va_bits_from_stext_arm64(void) ++{ ++ ulong _stext; ++ ++ _stext = get_stext_symbol(); ++ if (!_stext) { ++ ERRMSG("Can't get the symbol of _stext.\n"); ++ return FALSE; ++ } ++ ++ /* ++ * Derive va_bits as per arch/arm64/Kconfig. Note that this is a ++ * best case approximation at the moment, as there can be ++ * inconsistencies in this calculation (for e.g., for 52-bit ++ * kernel VA case, the 48th bit is set in * the _stext symbol). ++ */ ++ if ((_stext & PAGE_OFFSET_48) == PAGE_OFFSET_48) { ++ va_bits = 48; ++ } else if ((_stext & PAGE_OFFSET_47) == PAGE_OFFSET_47) { ++ va_bits = 47; ++ } else if ((_stext & PAGE_OFFSET_42) == PAGE_OFFSET_42) { ++ va_bits = 42; ++ } else if ((_stext & PAGE_OFFSET_39) == PAGE_OFFSET_39) { ++ va_bits = 39; ++ } else if ((_stext & PAGE_OFFSET_36) == PAGE_OFFSET_36) { ++ va_bits = 36; ++ } else { ++ ERRMSG("Cannot find a proper _stext for calculating VA_BITS\n"); ++ return FALSE; ++ } ++ ++ DEBUG_MSG("va_bits : %d (guess from _stext)\n", va_bits); ++ ++ return TRUE; ++} ++ + int + get_machdep_info_arm64(void) + { +@@ -398,27 +435,11 @@ get_xen_info_arm64(void) + int + get_versiondep_info_arm64(void) + { +- ulong _stext; +- +- _stext = get_stext_symbol(); +- if (!_stext) { +- ERRMSG("Can't get the symbol of _stext.\n"); +- return FALSE; +- } +- +- /* Derive va_bits as per arch/arm64/Kconfig */ +- if ((_stext & PAGE_OFFSET_36) == PAGE_OFFSET_36) { +- va_bits = 36; +- } else if ((_stext & PAGE_OFFSET_39) == PAGE_OFFSET_39) { +- va_bits = 39; +- } else if ((_stext & PAGE_OFFSET_42) == PAGE_OFFSET_42) { +- va_bits = 42; +- } else if ((_stext & PAGE_OFFSET_47) == PAGE_OFFSET_47) { +- va_bits = 47; +- } else if ((_stext & PAGE_OFFSET_48) == PAGE_OFFSET_48) { +- va_bits = 48; +- } else { +- ERRMSG("Cannot find a proper _stext for calculating VA_BITS\n"); ++ if (NUMBER(VA_BITS) != NOT_FOUND_NUMBER) { ++ va_bits = NUMBER(VA_BITS); ++ DEBUG_MSG("va_bits : %d (vmcoreinfo)\n", va_bits); ++ } else if (get_va_bits_from_stext_arm64() == FALSE) { ++ ERRMSG("Can't determine va_bits.\n"); + return FALSE; + } + diff -Nru makedumpfile-1.6.7/debian/patches/0007-PATCH-3-3-arm64-support-flipped-VA-and-52-bit-kernel.patch makedumpfile-1.6.7/debian/patches/0007-PATCH-3-3-arm64-support-flipped-VA-and-52-bit-kernel.patch --- makedumpfile-1.6.7/debian/patches/0007-PATCH-3-3-arm64-support-flipped-VA-and-52-bit-kernel.patch 1970-01-01 02:00:00.000000000 +0200 +++ makedumpfile-1.6.7/debian/patches/0007-PATCH-3-3-arm64-support-flipped-VA-and-52-bit-kernel.patch 2021-04-15 22:48:18.000000000 +0300 @@ -0,0 +1,238 @@ +From: Kazuhito Hagio +Date: Fri, 29 Jan 2021 11:40:25 +0900 +Subject: [PATCH 3/3] arm64: support flipped VA and 52-bit kernel VA + +Linux 5.4 and later kernels for arm64 changed the kernel VA space +arrangement and introduced 52-bit kernel VAs by merging branch +commit b333b0ba2346. Support 5.9+ kernels with vmcoreinfo entries +and 5.4+ kernels with best guessing. + +However, the following conditions are not supported for now due to +no necessary information provided from kernel: +(1) 5.4 <= kernels <= 5.8 and + - if PA_BITS=52 && VA_BITS!=52 + - with -x option if vabits_actual=52 +(2) kernels < 5.4 with CONFIG_ARM64_USER_VA_BITS_52=y + +(1) should be supported with kernel commit bbdbc11804ff and +1d50e5d0c5052 adding necessary information to vmcoreinfo. + +Signed-off-by: Bhupesh Sharma +Signed-off-by: Kazuhito Hagio +Reviewed-by: Pingfan Liu + +Origin: upstream, https://github.com/makedumpfile/makedumpfile/commit/a0216b678a95f099a16172cc4a67ad5aa6a89583 +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=986594 +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1879214 +--- + arch/arm64.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++--------- + makedumpfile.c | 2 ++ + makedumpfile.h | 1 + + 3 files changed, 88 insertions(+), 15 deletions(-) + +--- a/arch/arm64.c ++++ b/arch/arm64.c +@@ -47,6 +47,8 @@ typedef struct { + static int lpa_52_bit_support_available; + static int pgtable_level; + static int va_bits; ++static int vabits_actual; ++static int flipped_va; + static unsigned long kimage_voffset; + + #define SZ_4K 4096 +@@ -58,7 +60,6 @@ static unsigned long kimage_voffset; + #define PAGE_OFFSET_42 ((0xffffffffffffffffUL) << 42) + #define PAGE_OFFSET_47 ((0xffffffffffffffffUL) << 47) + #define PAGE_OFFSET_48 ((0xffffffffffffffffUL) << 48) +-#define PAGE_OFFSET_52 ((0xffffffffffffffffUL) << 52) + + #define pgd_val(x) ((x).pgd) + #define pud_val(x) (pgd_val((x).pgd)) +@@ -218,12 +219,20 @@ pmd_page_paddr(pmd_t pmd) + #define pte_index(vaddr) (((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1)) + #define pte_offset(dir, vaddr) (pmd_page_paddr((*dir)) + pte_index(vaddr) * sizeof(pte_t)) + ++/* ++ * The linear kernel range starts at the bottom of the virtual address ++ * space. Testing the top bit for the start of the region is a ++ * sufficient check and avoids having to worry about the tag. ++ */ ++#define is_linear_addr(addr) (flipped_va ? \ ++ (!((unsigned long)(addr) & (1UL << (vabits_actual - 1)))) : \ ++ (!!((unsigned long)(addr) & (1UL << (vabits_actual - 1))))) ++ + static unsigned long long + __pa(unsigned long vaddr) + { +- if (kimage_voffset == NOT_FOUND_NUMBER || +- (vaddr >= PAGE_OFFSET)) +- return (vaddr - PAGE_OFFSET + info->phys_base); ++ if (kimage_voffset == NOT_FOUND_NUMBER || is_linear_addr(vaddr)) ++ return ((vaddr & ~PAGE_OFFSET) + info->phys_base); + else + return (vaddr - kimage_voffset); + } +@@ -253,6 +262,7 @@ static int calculate_plat_config(void) + (PAGESIZE() == SZ_64K && va_bits == 42)) { + pgtable_level = 2; + } else if ((PAGESIZE() == SZ_64K && va_bits == 48) || ++ (PAGESIZE() == SZ_64K && va_bits == 52) || + (PAGESIZE() == SZ_4K && va_bits == 39) || + (PAGESIZE() == SZ_16K && va_bits == 47)) { + pgtable_level = 3; +@@ -263,6 +273,7 @@ static int calculate_plat_config(void) + PAGESIZE(), va_bits); + return FALSE; + } ++ DEBUG_MSG("pgtable_level: %d\n", pgtable_level); + + return TRUE; + } +@@ -270,6 +281,9 @@ static int calculate_plat_config(void) + unsigned long + get_kvbase_arm64(void) + { ++ if (flipped_va) ++ return PAGE_OFFSET; ++ + return (0xffffffffffffffffUL << va_bits); + } + +@@ -382,22 +396,54 @@ get_va_bits_from_stext_arm64(void) + return TRUE; + } + ++static void ++get_page_offset_arm64(void) ++{ ++ ulong page_end; ++ int vabits_min; ++ ++ /* ++ * See arch/arm64/include/asm/memory.h for more details of ++ * the PAGE_OFFSET calculation. ++ */ ++ vabits_min = (va_bits > 48) ? 48 : va_bits; ++ page_end = -(1UL << (vabits_min - 1)); ++ ++ if (SYMBOL(_stext) > page_end) { ++ flipped_va = TRUE; ++ info->page_offset = -(1UL << vabits_actual); ++ } else { ++ flipped_va = FALSE; ++ info->page_offset = -(1UL << (vabits_actual - 1)); ++ } ++ ++ DEBUG_MSG("page_offset : %lx (from page_end check)\n", ++ info->page_offset); ++} ++ + int + get_machdep_info_arm64(void) + { ++ /* Check if va_bits is still not initialized. If still 0, call ++ * get_versiondep_info() to initialize the same. ++ */ ++ if (!va_bits) ++ get_versiondep_info_arm64(); ++ + /* Determine if the PA address range is 52-bits: ARMv8.2-LPA */ + if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER) { + info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS); ++ DEBUG_MSG("max_physmem_bits : %ld (vmcoreinfo)\n", info->max_physmem_bits); + if (info->max_physmem_bits == 52) + lpa_52_bit_support_available = 1; +- } else +- info->max_physmem_bits = 48; ++ } else { ++ if (va_bits == 52) ++ info->max_physmem_bits = 52; /* just guess */ ++ else ++ info->max_physmem_bits = 48; + +- /* Check if va_bits is still not initialized. If still 0, call +- * get_versiondep_info() to initialize the same. +- */ +- if (!va_bits) +- get_versiondep_info_arm64(); ++ DEBUG_MSG("max_physmem_bits : %ld (guess)\n", info->max_physmem_bits); ++ } + + if (!calculate_plat_config()) { + ERRMSG("Can't determine platform config values\n"); +@@ -408,7 +454,6 @@ get_machdep_info_arm64(void) + info->section_size_bits = SECTIONS_SIZE_BITS; + + DEBUG_MSG("kimage_voffset : %lx\n", kimage_voffset); +- DEBUG_MSG("max_physmem_bits : %ld\n", info->max_physmem_bits); + DEBUG_MSG("section_size_bits: %ld\n", info->section_size_bits); + + return TRUE; +@@ -443,10 +488,35 @@ get_versiondep_info_arm64(void) + return FALSE; + } + +- info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1); ++ /* ++ * See TCR_EL1, Translation Control Register (EL1) register ++ * description in the ARMv8 Architecture Reference Manual. ++ * Basically, we can use the TCR_EL1.T1SZ value to determine ++ * the virtual addressing range supported in the kernel-space ++ * (i.e. vabits_actual) since Linux 5.9. ++ */ ++ if (NUMBER(TCR_EL1_T1SZ) != NOT_FOUND_NUMBER) { ++ vabits_actual = 64 - NUMBER(TCR_EL1_T1SZ); ++ DEBUG_MSG("vabits_actual : %d (vmcoreinfo)\n", vabits_actual); ++ } else if ((va_bits == 52) && (SYMBOL(mem_section) != NOT_FOUND_SYMBOL)) { ++ /* ++ * Linux 5.4 through 5.10 have the following linear space: ++ * 48-bit: 0xffff000000000000 - 0xffff7fffffffffff ++ * 52-bit: 0xfff0000000000000 - 0xfff7ffffffffffff ++ * and SYMBOL(mem_section) should be in linear space if ++ * the kernel is configured with COMFIG_SPARSEMEM_EXTREME=y. ++ */ ++ if (SYMBOL(mem_section) & (1UL << (va_bits - 1))) ++ vabits_actual = 48; ++ else ++ vabits_actual = 52; ++ DEBUG_MSG("vabits_actual : %d (guess from mem_section)\n", vabits_actual); ++ } else { ++ vabits_actual = va_bits; ++ DEBUG_MSG("vabits_actual : %d (same as va_bits)\n", vabits_actual); ++ } + +- DEBUG_MSG("va_bits : %d\n", va_bits); +- DEBUG_MSG("page_offset : %lx\n", info->page_offset); ++ get_page_offset_arm64(); + + return TRUE; + } +--- a/makedumpfile.c ++++ b/makedumpfile.c +@@ -2323,6 +2323,7 @@ write_vmcoreinfo_data(void) + WRITE_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR); + #ifdef __aarch64__ + WRITE_NUMBER("VA_BITS", VA_BITS); ++ /* WRITE_NUMBER("TCR_EL1_T1SZ", TCR_EL1_T1SZ); should not exists */ + WRITE_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET); + WRITE_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset); + #endif +@@ -2729,6 +2730,7 @@ read_vmcoreinfo(void) + READ_NUMBER("KERNEL_IMAGE_SIZE", KERNEL_IMAGE_SIZE); + #ifdef __aarch64__ + READ_NUMBER("VA_BITS", VA_BITS); ++ READ_NUMBER("TCR_EL1_T1SZ", TCR_EL1_T1SZ); + READ_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET); + READ_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset); + #endif +--- a/makedumpfile.h ++++ b/makedumpfile.h +@@ -1937,6 +1937,7 @@ struct number_table { + long KERNEL_IMAGE_SIZE; + #ifdef __aarch64__ + long VA_BITS; ++ long TCR_EL1_T1SZ; + unsigned long PHYS_OFFSET; + unsigned long kimage_voffset; + #endif diff -Nru makedumpfile-1.6.7/debian/patches/series makedumpfile-1.6.7/debian/patches/series --- makedumpfile-1.6.7/debian/patches/series 2020-08-12 06:13:08.000000000 +0300 +++ makedumpfile-1.6.7/debian/patches/series 2021-04-15 22:48:11.000000000 +0300 @@ -1,3 +1,7 @@ 0002-adapt-makefile-to-debian.patch 0002-PATCH-Remove-duplicated-variable-definitions.patch 0003-align_PMD_SECTION_MASK_with_PHYS_MASK.patch +0004-PATCH-arm64-Add-support-for-ARMv8.2-LPA-52-bit-PA-su.patch +0005-PATCH-1-3-Use-vmcoreinfo-note-in-proc-kcore-for-mem-.patch +0006-PATCH-2-3-arm64-Make-use-of-NUMBER-VA_BITS-in-vmcore.patch +0007-PATCH-3-3-arm64-support-flipped-VA-and-52-bit-kernel.patch