Fix bug: Filed to generate the vmcore file in the ARM architecture
Fix bug: Filed to generate the vmcore-dmesg.txt file in the ARM architecture Signed-off-by: yang_zhuang_zhuang <1162011203@qq.com>
This commit is contained in:
parent
488c402d6a
commit
98f6e4b451
@ -0,0 +1,143 @@
|
||||
From d8b701796f0491f2ac4b06c7a5b795c29399efab Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Fri, 29 Jan 2021 11:40:23 +0900
|
||||
Subject: [PATCH] [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 <k-hagio-ab@nec.com>
|
||||
---
|
||||
elf_info.c | 49 -------------------------------------------------
|
||||
elf_info.h | 1 -
|
||||
makedumpfile.c | 26 +++++++++++++++++++++-----
|
||||
3 files changed, 21 insertions(+), 55 deletions(-)
|
||||
|
||||
diff --git a/elf_info.c b/elf_info.c
|
||||
index a6624b5..e8affb7 100644
|
||||
--- a/makedumpfile-1.6.7/elf_info.c
|
||||
+++ b/makedumpfile-1.6.7/elf_info.c
|
||||
@@ -698,55 +698,6 @@ get_elf32_ehdr(int fd, char *filename, Elf32_Ehdr *ehdr)
|
||||
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)
|
||||
{
|
||||
diff --git a/elf_info.h b/elf_info.h
|
||||
index d9b5d05..d5416b3 100644
|
||||
--- a/makedumpfile-1.6.7/elf_info.h
|
||||
+++ b/makedumpfile-1.6.7/elf_info.h
|
||||
@@ -44,7 +44,6 @@ int get_elf64_ehdr(int fd, char *filename, Elf64_Ehdr *ehdr);
|
||||
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);
|
||||
|
||||
diff --git a/makedumpfile.c b/makedumpfile.c
|
||||
index ba0003a..768eda4 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.c
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.c
|
||||
@@ -11445,6 +11445,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");
|
||||
@@ -11456,9 +11457,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;
|
||||
|
||||
@@ -11466,11 +11480,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;
|
||||
@ -0,0 +1,97 @@
|
||||
From 67d0e1d68f28c567a704fd6b9b8fd696ad3df183 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Fri, 29 Jan 2021 11:40:24 +0900
|
||||
Subject: [PATCH] [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 <bhsharma@redhat.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
arch/arm64.c | 63 ++++++++++++++++++++++++++++++++++------------------
|
||||
1 file changed, 42 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64.c b/arch/arm64.c
|
||||
index 3d7b416..2916b4f 100644
|
||||
--- a/makedumpfile-1.6.7/arch/arm64.c
|
||||
+++ b/makedumpfile-1.6.7/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;
|
||||
}
|
||||
|
||||
@ -0,0 +1,241 @@
|
||||
From a0216b678a95f099a16172cc4a67ad5aa6a89583 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Fri, 29 Jan 2021 11:40:25 +0900
|
||||
Subject: [PATCH] [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 <bhsharma@redhat.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Reviewed-by: Pingfan Liu <piliu@redhat.com>
|
||||
---
|
||||
arch/arm64.c | 100 +++++++++++++++++++++++++++++++++++++++++--------
|
||||
makedumpfile.c | 2 +
|
||||
makedumpfile.h | 1 +
|
||||
3 files changed, 88 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64.c b/arch/arm64.c
|
||||
index 2916b4f..1072178 100644
|
||||
--- a/makedumpfile-1.6.7/arch/arm64.c
|
||||
+++ b/makedumpfile-1.6.7/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;
|
||||
}
|
||||
diff --git a/makedumpfile.c b/makedumpfile.c
|
||||
index 768eda4..fcd766b 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.c
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.c
|
||||
@@ -2397,6 +2397,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
|
||||
@@ -2836,6 +2837,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
|
||||
diff --git a/makedumpfile.h b/makedumpfile.h
|
||||
index 0ed6417..97a5554 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.h
|
||||
+++ b/makedumpfile-1.6.7makedumpfile.h
|
||||
@@ -2049,6 +2049,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
|
||||
33
backport-PATCH-Align-PMD_SECTION_MASK-with-PHYS_MASK.patch
Normal file
33
backport-PATCH-Align-PMD_SECTION_MASK-with-PHYS_MASK.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From 7242ae4cb5288df626f464ced0a8b60fd669100b Mon Sep 17 00:00:00 2001
|
||||
From: Michal Suchanek <msuchanek@suse.de>
|
||||
Date: Mon, 16 Mar 2020 19:39:58 +0100
|
||||
Subject: [PATCH] [PATCH] Align PMD_SECTION_MASK with PHYS_MASK
|
||||
|
||||
Reportedly on some arm64 systems makedumpfile loops forever exhausting
|
||||
all memory when filtering kernel core. It turns out the reason is it
|
||||
cannot resolve some addresses because the PMD mask is wrong. When
|
||||
physical address mask allows up to 48bits pmd mask should allow the
|
||||
same.
|
||||
I suppose you would need a system that needs physical addresses over 1TB
|
||||
to be able to reproduce this. This may be either because you have a lot
|
||||
of memory or because the firmware mapped some memory above 1TB for some
|
||||
reason.
|
||||
|
||||
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
|
||||
---
|
||||
arch/arm64.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm64.c b/arch/arm64.c
|
||||
index 43164cc..54d60b4 100644
|
||||
--- a/makedumpfile-1.6.7/arch/arm64.c
|
||||
+++ b/makedumpfile-1.6.7/arch/arm64.c
|
||||
@@ -81,7 +81,7 @@ static unsigned long kimage_voffset;
|
||||
* Remove the highest order bits that are not a part of the
|
||||
* physical address in a section
|
||||
*/
|
||||
-#define PMD_SECTION_MASK ((1UL << 40) - 1)
|
||||
+#define PMD_SECTION_MASK ((1UL << PHYS_MASK_SHIFT) - 1)
|
||||
|
||||
#define PMD_TYPE_MASK 3
|
||||
#define PMD_TYPE_SECT 1
|
||||
@ -0,0 +1,413 @@
|
||||
From da0d25ffa585c9a1adb94562c815daa393b1ee5e Mon Sep 17 00:00:00 2001
|
||||
From: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
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 <bhsharma@redhat.com>
|
||||
---
|
||||
arch/arm64.c | 294 +++++++++++++++++++++++++++++++++++----------------
|
||||
1 file changed, 205 insertions(+), 89 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64.c b/arch/arm64.c
|
||||
index 54d60b4..3d7b416 100644
|
||||
--- a/makedumpfile-1.6.7/arch/arm64.c
|
||||
+++ b/makedumpfile-1.6.7/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 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_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)
|
||||
+
|
||||
+/*
|
||||
+ * Hardware page table definitions.
|
||||
+ *
|
||||
+ * Level 1 descriptor (PUD).
|
||||
+ */
|
||||
+#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)
|
||||
+
|
||||
/*
|
||||
- * Remove the highest order bits that are not a part of the
|
||||
- * physical address in a section
|
||||
+ * Level 2 descriptor (PMD).
|
||||
*/
|
||||
-#define PMD_SECTION_MASK ((1UL << PHYS_MASK_SHIFT) - 1)
|
||||
+#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_TYPE_MASK 3
|
||||
-#define PMD_TYPE_SECT 1
|
||||
-#define PMD_TYPE_TABLE 3
|
||||
+/*
|
||||
+ * 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)
|
||||
|
||||
-#define PUD_TYPE_MASK 3
|
||||
-#define PUD_TYPE_SECT 1
|
||||
-#define PUD_TYPE_TABLE 3
|
||||
+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 pgd_index(vaddr) (((vaddr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
|
||||
-#define pgd_offset(pgdir, vaddr) ((pgd_t *)(pgdir) + pgd_index(vaddr))
|
||||
+#define PTE_ADDR_MASK get_pte_addr_mask_arm64()
|
||||
|
||||
-#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))
|
||||
+#define PAGE_MASK (~(PAGESIZE() - 1))
|
||||
+#define PAGE_PRESENT (1 << 0)
|
||||
|
||||
-#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))
|
||||
+/* 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;
|
||||
492
backport-print-add-support-for-lockless-ringbuffer.patch
Normal file
492
backport-print-add-support-for-lockless-ringbuffer.patch
Normal file
@ -0,0 +1,492 @@
|
||||
From 4149df9005f2cdd2ecf70058dfe7d72f48c3a68c Mon Sep 17 00:00:00 2001
|
||||
From: John Ogness <john.ogness@linutronix.de>
|
||||
Date: Wed, 25 Nov 2020 23:26:59 +0106
|
||||
Subject: printk: add support for lockless ringbuffer
|
||||
|
||||
Linux 5.10 moved to a new lockless ringbuffer. The new ringbuffer
|
||||
is structured completely different to the previous iterations.
|
||||
Add support for retrieving the ringbuffer using vmcoreinfo. The
|
||||
new ringbuffer is detected based on the availability of the
|
||||
"prb" symbol.
|
||||
|
||||
Signed-off-by: John Ogness <john.ogness@linutronix.de>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
---
|
||||
util_lib/elf_info.c | 438 +++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 437 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
|
||||
index 7803a94..2f23a44 100644
|
||||
--- a/util_lib/elf_info.c
|
||||
+++ b/util_lib/elf_info.c
|
||||
@@ -27,6 +27,32 @@ static int num_pt_loads;
|
||||
|
||||
static char osrelease[4096];
|
||||
|
||||
+/* VMCOREINFO symbols for lockless printk ringbuffer */
|
||||
+static loff_t prb_vaddr;
|
||||
+static size_t printk_ringbuffer_sz;
|
||||
+static size_t prb_desc_sz;
|
||||
+static size_t printk_info_sz;
|
||||
+static uint64_t printk_ringbuffer_desc_ring_offset;
|
||||
+static uint64_t printk_ringbuffer_text_data_ring_offset;
|
||||
+static uint64_t prb_desc_ring_count_bits_offset;
|
||||
+static uint64_t prb_desc_ring_descs_offset;
|
||||
+static uint64_t prb_desc_ring_infos_offset;
|
||||
+static uint64_t prb_data_ring_size_bits_offset;
|
||||
+static uint64_t prb_data_ring_data_offset;
|
||||
+static uint64_t prb_desc_ring_head_id_offset;
|
||||
+static uint64_t prb_desc_ring_tail_id_offset;
|
||||
+static uint64_t atomic_long_t_counter_offset;
|
||||
+static uint64_t prb_desc_state_var_offset;
|
||||
+static uint64_t prb_desc_info_offset;
|
||||
+static uint64_t prb_desc_text_blk_lpos_offset;
|
||||
+static uint64_t prb_data_blk_lpos_begin_offset;
|
||||
+static uint64_t prb_data_blk_lpos_next_offset;
|
||||
+static uint64_t printk_info_seq_offset;
|
||||
+static uint64_t printk_info_caller_id_offset;
|
||||
+static uint64_t printk_info_ts_nsec_offset;
|
||||
+static uint64_t printk_info_level_offset;
|
||||
+static uint64_t printk_info_text_len_offset;
|
||||
+
|
||||
static loff_t log_buf_vaddr;
|
||||
static loff_t log_end_vaddr;
|
||||
static loff_t log_buf_len_vaddr;
|
||||
@@ -304,6 +330,7 @@ void scan_vmcoreinfo(char *start, size_t size)
|
||||
size_t len;
|
||||
loff_t *vaddr;
|
||||
} symbol[] = {
|
||||
+ SYMBOL(prb),
|
||||
SYMBOL(log_buf),
|
||||
SYMBOL(log_end),
|
||||
SYMBOL(log_buf_len),
|
||||
@@ -361,6 +388,119 @@ void scan_vmcoreinfo(char *start, size_t size)
|
||||
*symbol[i].vaddr = vaddr;
|
||||
}
|
||||
|
||||
+ str = "SIZE(printk_ringbuffer)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_ringbuffer_sz = strtoull(pos + strlen(str),
|
||||
+ NULL, 10);
|
||||
+
|
||||
+ str = "SIZE(prb_desc)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_sz = strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "SIZE(printk_info)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_info_sz = strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(printk_ringbuffer.desc_ring)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_ringbuffer_desc_ring_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(printk_ringbuffer.text_data_ring)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_ringbuffer_text_data_ring_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_desc_ring.count_bits)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_ring_count_bits_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_desc_ring.descs)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_ring_descs_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_desc_ring.infos)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_ring_infos_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_data_ring.size_bits)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_data_ring_size_bits_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_data_ring.data)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_data_ring_data_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_desc_ring.head_id)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_ring_head_id_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_desc_ring.tail_id)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_ring_tail_id_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(atomic_long_t.counter)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ atomic_long_t_counter_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_desc.state_var)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_state_var_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_desc.info)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_info_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_desc.text_blk_lpos)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_text_blk_lpos_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_data_blk_lpos.begin)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_data_blk_lpos_begin_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_data_blk_lpos.next)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_data_blk_lpos_next_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(printk_info.seq)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_info_seq_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(printk_info.caller_id)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_info_caller_id_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(printk_info.ts_nsec)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_info_ts_nsec_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(printk_info.level)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_info_level_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(printk_info.text_len)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_info_text_len_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
/* Check for "SIZE(printk_log)" or older "SIZE(log)=" */
|
||||
str = "SIZE(log)=";
|
||||
if (memcmp(str, pos, strlen(str)) == 0)
|
||||
@@ -746,9 +886,305 @@ static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int))
|
||||
handler(out_buf, len);
|
||||
}
|
||||
|
||||
+/* convenience struct for passing many values to helper functions */
|
||||
+struct prb_map {
|
||||
+ char *prb;
|
||||
+
|
||||
+ char *desc_ring;
|
||||
+ unsigned long desc_ring_count;
|
||||
+ char *descs;
|
||||
+
|
||||
+ char *infos;
|
||||
+
|
||||
+ char *text_data_ring;
|
||||
+ unsigned long text_data_ring_size;
|
||||
+ char *text_data;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * desc_state and DESC_* definitions taken from kernel source:
|
||||
+ *
|
||||
+ * kernel/printk/printk_ringbuffer.h
|
||||
+ *
|
||||
+ * DESC_* definitions modified to provide 32-bit and 64-bit variants.
|
||||
+ */
|
||||
+
|
||||
+/* The possible responses of a descriptor state-query. */
|
||||
+enum desc_state {
|
||||
+ desc_miss = -1, /* ID mismatch (pseudo state) */
|
||||
+ desc_reserved = 0x0, /* reserved, in use by writer */
|
||||
+ desc_committed = 0x1, /* committed by writer, could get reopened */
|
||||
+ desc_finalized = 0x2, /* committed, no further modification allowed */
|
||||
+ desc_reusable = 0x3, /* free, not yet used by any writer */
|
||||
+};
|
||||
+
|
||||
+#define DESC_SV_BITS (sizeof(uint64_t) * 8)
|
||||
+#define DESC_FLAGS_SHIFT (DESC_SV_BITS - 2)
|
||||
+#define DESC_FLAGS_MASK (3UL << DESC_FLAGS_SHIFT)
|
||||
+#define DESC_STATE(sv) (3UL & (sv >> DESC_FLAGS_SHIFT))
|
||||
+#define DESC_ID_MASK (~DESC_FLAGS_MASK)
|
||||
+#define DESC_ID(sv) ((sv) & DESC_ID_MASK)
|
||||
+
|
||||
+#define DESC32_SV_BITS (sizeof(uint32_t) * 8)
|
||||
+#define DESC32_FLAGS_SHIFT (DESC32_SV_BITS - 2)
|
||||
+#define DESC32_FLAGS_MASK (3UL << DESC32_FLAGS_SHIFT)
|
||||
+#define DESC32_STATE(sv) (3UL & (sv >> DESC32_FLAGS_SHIFT))
|
||||
+#define DESC32_ID_MASK (~DESC32_FLAGS_MASK)
|
||||
+#define DESC32_ID(sv) ((sv) & DESC32_ID_MASK)
|
||||
+
|
||||
+/*
|
||||
+ * get_desc_state() taken from kernel source:
|
||||
+ *
|
||||
+ * kernel/printk/printk_ringbuffer.c
|
||||
+ *
|
||||
+ * get_desc32_state() added as 32-bit variant.
|
||||
+ */
|
||||
+
|
||||
+/* Query the state of a descriptor. */
|
||||
+static enum desc_state get_desc_state(unsigned long id,
|
||||
+ uint64_t state_val)
|
||||
+{
|
||||
+ if (id != DESC_ID(state_val))
|
||||
+ return desc_miss;
|
||||
+
|
||||
+ return DESC_STATE(state_val);
|
||||
+}
|
||||
+
|
||||
+static enum desc_state get_desc32_state(unsigned long id,
|
||||
+ uint64_t state_val)
|
||||
+{
|
||||
+ if (id != DESC32_ID(state_val))
|
||||
+ return desc_miss;
|
||||
+
|
||||
+ return DESC32_STATE(state_val);
|
||||
+}
|
||||
+
|
||||
+static bool record_committed(unsigned long id, uint64_t state_var)
|
||||
+{
|
||||
+ enum desc_state state;
|
||||
+
|
||||
+ if (machine_pointer_bits() == 32)
|
||||
+ state = get_desc32_state(id, state_var);
|
||||
+ else
|
||||
+ state = get_desc_state(id, state_var);
|
||||
+
|
||||
+ return (state == desc_committed || state == desc_finalized);
|
||||
+}
|
||||
+
|
||||
+static uint64_t id_inc(uint64_t id)
|
||||
+{
|
||||
+ id++;
|
||||
+
|
||||
+ if (machine_pointer_bits() == 32)
|
||||
+ return (id & DESC32_ID_MASK);
|
||||
+
|
||||
+ return (id & DESC_ID_MASK);
|
||||
+}
|
||||
+
|
||||
+static uint64_t get_ulong(char *addr)
|
||||
+{
|
||||
+ if (machine_pointer_bits() == 32)
|
||||
+ return struct_val_u32(addr, 0);
|
||||
+ return struct_val_u64(addr, 0);
|
||||
+}
|
||||
+
|
||||
+static uint64_t sizeof_ulong(void)
|
||||
+{
|
||||
+ return (machine_pointer_bits() >> 3);
|
||||
+}
|
||||
+
|
||||
+static void dump_record(struct prb_map *m, unsigned long id,
|
||||
+ void (*handler)(char*, unsigned int))
|
||||
+{
|
||||
+#define OUT_BUF_SIZE 4096
|
||||
+ char out_buf[OUT_BUF_SIZE];
|
||||
+ imaxdiv_t imaxdiv_usec;
|
||||
+ imaxdiv_t imaxdiv_sec;
|
||||
+ uint32_t offset = 0;
|
||||
+ unsigned short len;
|
||||
+ uint64_t state_var;
|
||||
+ uint64_t ts_nsec;
|
||||
+ uint64_t begin;
|
||||
+ uint64_t next;
|
||||
+ char *info;
|
||||
+ char *text;
|
||||
+ char *desc;
|
||||
+ int i;
|
||||
+
|
||||
+ desc = m->descs + ((id % m->desc_ring_count) * prb_desc_sz);
|
||||
+ info = m->infos + ((id % m->desc_ring_count) * printk_info_sz);
|
||||
+
|
||||
+ /* skip non-committed record */
|
||||
+ state_var = get_ulong(desc + prb_desc_state_var_offset +
|
||||
+ atomic_long_t_counter_offset);
|
||||
+ if (!record_committed(id, state_var))
|
||||
+ return;
|
||||
+
|
||||
+ begin = get_ulong(desc + prb_desc_text_blk_lpos_offset +
|
||||
+ prb_data_blk_lpos_begin_offset) %
|
||||
+ m->text_data_ring_size;
|
||||
+ next = get_ulong(desc + prb_desc_text_blk_lpos_offset +
|
||||
+ prb_data_blk_lpos_next_offset) %
|
||||
+ m->text_data_ring_size;
|
||||
+
|
||||
+ ts_nsec = struct_val_u64(info, printk_info_ts_nsec_offset);
|
||||
+ imaxdiv_sec = imaxdiv(ts_nsec, 1000000000);
|
||||
+ imaxdiv_usec = imaxdiv(imaxdiv_sec.rem, 1000);
|
||||
+
|
||||
+ offset += sprintf(out_buf + offset, "[%5llu.%06llu] ",
|
||||
+ (long long unsigned int)imaxdiv_sec.quot,
|
||||
+ (long long unsigned int)imaxdiv_usec.quot);
|
||||
+
|
||||
+ /* skip data-less text blocks */
|
||||
+ if (begin == next)
|
||||
+ goto out;
|
||||
+
|
||||
+ len = struct_val_u16(info, printk_info_text_len_offset);
|
||||
+
|
||||
+ /* handle wrapping data block */
|
||||
+ if (begin > next)
|
||||
+ begin = 0;
|
||||
+
|
||||
+ /* skip over descriptor ID */
|
||||
+ begin += sizeof_ulong();
|
||||
+
|
||||
+ /* handle truncated messages */
|
||||
+ if (next - begin < len)
|
||||
+ len = next - begin;
|
||||
+
|
||||
+ text = m->text_data + begin;
|
||||
+
|
||||
+ /* escape non-printable characters */
|
||||
+ for (i = 0; i < len; i++) {
|
||||
+ unsigned char c = text[i];
|
||||
+
|
||||
+ if (!isprint(c) && !isspace(c))
|
||||
+ offset += sprintf(out_buf + offset, "\\x%02x", c);
|
||||
+ else
|
||||
+ out_buf[offset++] = c;
|
||||
+
|
||||
+ if (offset >= OUT_BUF_SIZE - 64) {
|
||||
+ if (handler)
|
||||
+ handler(out_buf, offset);
|
||||
+ offset = 0;
|
||||
+ }
|
||||
+ }
|
||||
+out:
|
||||
+ out_buf[offset++] = '\n';
|
||||
+
|
||||
+ if (offset && handler)
|
||||
+ handler(out_buf, offset);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Handle the lockless printk_ringbuffer.
|
||||
+ */
|
||||
+static void dump_dmesg_lockless(int fd, void (*handler)(char*, unsigned int))
|
||||
+{
|
||||
+ struct prb_map m;
|
||||
+ uint64_t head_id;
|
||||
+ uint64_t tail_id;
|
||||
+ uint64_t kaddr;
|
||||
+ uint64_t id;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* setup printk_ringbuffer */
|
||||
+ kaddr = read_file_pointer(fd, vaddr_to_offset(prb_vaddr));
|
||||
+ m.prb = calloc(1, printk_ringbuffer_sz);
|
||||
+ if (!m.prb) {
|
||||
+ fprintf(stderr, "Failed to malloc %lu bytes for prb: %s\n",
|
||||
+ printk_ringbuffer_sz, strerror(errno));
|
||||
+ exit(64);
|
||||
+ }
|
||||
+ ret = pread(fd, m.prb, printk_ringbuffer_sz, vaddr_to_offset(kaddr));
|
||||
+ if (ret != printk_ringbuffer_sz) {
|
||||
+ fprintf(stderr, "Failed to read prb of size %lu bytes: %s\n",
|
||||
+ printk_ringbuffer_sz, strerror(errno));
|
||||
+ exit(65);
|
||||
+ }
|
||||
+
|
||||
+ /* setup descriptor ring */
|
||||
+ m.desc_ring = m.prb + printk_ringbuffer_desc_ring_offset;
|
||||
+ m.desc_ring_count = 1 << struct_val_u32(m.desc_ring,
|
||||
+ prb_desc_ring_count_bits_offset);
|
||||
+ kaddr = get_ulong(m.desc_ring + prb_desc_ring_descs_offset);
|
||||
+ m.descs = calloc(1, prb_desc_sz * m.desc_ring_count);
|
||||
+ if (!m.descs) {
|
||||
+ fprintf(stderr, "Failed to malloc %lu bytes for descs: %s\n",
|
||||
+ prb_desc_sz * m.desc_ring_count, strerror(errno));
|
||||
+ exit(64);
|
||||
+ }
|
||||
+ ret = pread(fd, m.descs, prb_desc_sz * m.desc_ring_count,
|
||||
+ vaddr_to_offset(kaddr));
|
||||
+ if (ret != prb_desc_sz * m.desc_ring_count) {
|
||||
+ fprintf(stderr,
|
||||
+ "Failed to read descs of size %lu bytes: %s\n",
|
||||
+ prb_desc_sz * m.desc_ring_count, strerror(errno));
|
||||
+ exit(65);
|
||||
+ }
|
||||
+
|
||||
+ /* setup info ring */
|
||||
+ kaddr = get_ulong(m.prb + prb_desc_ring_infos_offset);
|
||||
+ m.infos = calloc(1, printk_info_sz * m.desc_ring_count);
|
||||
+ if (!m.infos) {
|
||||
+ fprintf(stderr, "Failed to malloc %lu bytes for infos: %s\n",
|
||||
+ printk_info_sz * m.desc_ring_count, strerror(errno));
|
||||
+ exit(64);
|
||||
+ }
|
||||
+ ret = pread(fd, m.infos, printk_info_sz * m.desc_ring_count,
|
||||
+ vaddr_to_offset(kaddr));
|
||||
+ if (ret != printk_info_sz * m.desc_ring_count) {
|
||||
+ fprintf(stderr,
|
||||
+ "Failed to read infos of size %lu bytes: %s\n",
|
||||
+ printk_info_sz * m.desc_ring_count, strerror(errno));
|
||||
+ exit(65);
|
||||
+ }
|
||||
+
|
||||
+ /* setup text data ring */
|
||||
+ m.text_data_ring = m.prb + printk_ringbuffer_text_data_ring_offset;
|
||||
+ m.text_data_ring_size = 1 << struct_val_u32(m.text_data_ring,
|
||||
+ prb_data_ring_size_bits_offset);
|
||||
+ kaddr = get_ulong(m.text_data_ring + prb_data_ring_data_offset);
|
||||
+ m.text_data = calloc(1, m.text_data_ring_size);
|
||||
+ if (!m.text_data) {
|
||||
+ fprintf(stderr,
|
||||
+ "Failed to malloc %lu bytes for text_data: %s\n",
|
||||
+ m.text_data_ring_size, strerror(errno));
|
||||
+ exit(64);
|
||||
+ }
|
||||
+ ret = pread(fd, m.text_data, m.text_data_ring_size,
|
||||
+ vaddr_to_offset(kaddr));
|
||||
+ if (ret != m.text_data_ring_size) {
|
||||
+ fprintf(stderr,
|
||||
+ "Failed to read text_data of size %lu bytes: %s\n",
|
||||
+ m.text_data_ring_size, strerror(errno));
|
||||
+ exit(65);
|
||||
+ }
|
||||
+
|
||||
+ /* ready to go */
|
||||
+
|
||||
+ tail_id = get_ulong(m.desc_ring + prb_desc_ring_tail_id_offset +
|
||||
+ atomic_long_t_counter_offset);
|
||||
+ head_id = get_ulong(m.desc_ring + prb_desc_ring_head_id_offset +
|
||||
+ atomic_long_t_counter_offset);
|
||||
+
|
||||
+ for (id = tail_id; id != head_id; id = id_inc(id))
|
||||
+ dump_record(&m, id, handler);
|
||||
+
|
||||
+ /* dump head record */
|
||||
+ dump_record(&m, id, handler);
|
||||
+
|
||||
+ free(m.text_data);
|
||||
+ free(m.infos);
|
||||
+ free(m.descs);
|
||||
+ free(m.prb);
|
||||
+}
|
||||
+
|
||||
void dump_dmesg(int fd, void (*handler)(char*, unsigned int))
|
||||
{
|
||||
- if (log_first_idx_vaddr)
|
||||
+ if (prb_vaddr)
|
||||
+ dump_dmesg_lockless(fd, handler);
|
||||
+ else if (log_first_idx_vaddr)
|
||||
dump_dmesg_structured(fd, handler);
|
||||
else
|
||||
dump_dmesg_legacy(fd, handler);
|
||||
--
|
||||
cgit 1.2.3-1.el7
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
From daa57a0d1aa31fad5811ba70d37e1ed23773151e Mon Sep 17 00:00:00 2001
|
||||
From: kangenbo <kangenbo@huawei.com>
|
||||
Date: Wed, 30 Jan 2019 15:50:31 +0800
|
||||
Subject: [PATCH] kexec-tools: get the paddr of mem_section return error address
|
||||
|
||||
reason: get the paddr of mem_section return error address
|
||||
|
||||
Signed-off-by: kangenbo <kangenbo@huawei.com>
|
||||
---
|
||||
makedumpfile-1.6.7/arch/arm64.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/makedumpfile-1.6.7/arch/arm64.c b/makedumpfile-1.6.7/arch/arm64.c
|
||||
index 2fd3e18..cc59e63 100644
|
||||
--- a/makedumpfile-1.6.7/arch/arm64.c
|
||||
+++ b/makedumpfile-1.6.7/arch/arm64.c
|
||||
@@ -336,7 +336,7 @@ vaddr_to_paddr_arm64(unsigned long vaddr)
|
||||
|
||||
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))
|
||||
+ paddr = (pud_val(pudv) & (PUD_MASK & PHYS_MASK))
|
||||
+ (vaddr & (PUD_SIZE - 1));
|
||||
return paddr;
|
||||
}
|
||||
@@ -367,7 +367,7 @@ vaddr_to_paddr_arm64(unsigned long vaddr)
|
||||
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))
|
||||
+ paddr = (pmd_val(pmdv) & (PMD_MASK & PHYS_MASK))
|
||||
+ (vaddr & (PMD_SIZE - 1));
|
||||
break;
|
||||
}
|
||||
--
|
||||
1.7.12.4
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
Name: kexec-tools
|
||||
Version: 2.0.20
|
||||
Release: 5
|
||||
Release: 6
|
||||
License: GPLv2
|
||||
Summary: The kexec/kdump userspace component
|
||||
URL: https://www.kernel.org/
|
||||
@ -94,14 +94,20 @@ Patch18: arm64-support-more-than-one-crash-kernel-regions.patch
|
||||
%endif
|
||||
|
||||
Patch19: add-secure-compile-options-for-makedumpfile.patch
|
||||
Patch20: bugfix-get-the-paddr-of-mem_section-return-error-address.patch
|
||||
Patch21: fix-header-offset-overflow-when-large-pfn.patch
|
||||
Patch22: kexec-Add-quick-kexec-support.patch
|
||||
Patch20: fix-header-offset-overflow-when-large-pfn.patch
|
||||
Patch21: kexec-Add-quick-kexec-support.patch
|
||||
|
||||
%ifarch aarch64
|
||||
Patch23: kexec-Quick-kexec-implementation-for-arm64.patch
|
||||
Patch22: kexec-Quick-kexec-implementation-for-arm64.patch
|
||||
%endif
|
||||
|
||||
Patch23: backport-PATCH-Align-PMD_SECTION_MASK-with-PHYS_MASK.patch
|
||||
Patch24: backport-PATCH-arm64-Add-support-for-ARMv8.2-LPA-52-bit-PA-su.patch
|
||||
Patch25: backport-PATCH-1-3-Use-vmcoreinfo-note-in-proc-kcore-for-mem-.patch
|
||||
Patch26: backport-PATCH-2-3-arm64-Make-use-of-NUMBER-VA_BITS-in-vmcore.patch
|
||||
Patch27: backport-PATCH-3-3-arm64-support-flipped-VA-and-52-bit-kernel.patch
|
||||
Patch28: backport-print-add-support-for-lockless-ringbuffer.patch
|
||||
|
||||
%description
|
||||
kexec-tools provides /sbin/kexec binary that facilitates a new
|
||||
kernel to boot using the kernel's kexec feature either on a
|
||||
@ -149,12 +155,18 @@ tar -z -x -v -f %{SOURCE19}
|
||||
%patch19 -p1
|
||||
%patch20 -p1
|
||||
%patch21 -p1
|
||||
%patch22 -p1
|
||||
|
||||
%ifarch aarch64
|
||||
%patch23 -p1
|
||||
%patch22 -p1
|
||||
%endif
|
||||
|
||||
%patch23 -p1
|
||||
%patch24 -p1
|
||||
%patch25 -p1
|
||||
%patch26 -p1
|
||||
%patch27 -p1
|
||||
%patch28 -p1
|
||||
|
||||
%build
|
||||
autoreconf
|
||||
%configure --sbindir=/usr/sbin \
|
||||
@ -339,6 +351,13 @@ done
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Sat Mar 27 2021 yangzhuangzhuang <yangzhuangzhuang1@huawei.com> - 2.0.20-6
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:Fix bug: Filed to generate the vmcore file in the ARM architecture
|
||||
Fix bug: Filed to generate the vmcore-dmesg.txt file in the ARM architecture
|
||||
|
||||
* Mon Mar 22 2021 yangzhuangzhuang <yangzhuangzhuang1@huawei.com> - 2.0.20-5
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user