Update to the latest upstream <f53b73e8380b>

Release: crash-7.3.0-2

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
This commit is contained in:
Lianbo Jiang 2021-07-13 16:27:16 +08:00
parent 32e9f5fc21
commit 42254b004a
17 changed files with 1408 additions and 1 deletions

View File

@ -0,0 +1,50 @@
From a7ecf2467f953b632713f38ab8104596755bca8c Mon Sep 17 00:00:00 2001
From: John Donnelly <john.p.donnelly@oracle.com>
Date: Wed, 12 May 2021 14:48:03 -0700
Subject: [PATCH 01/16] arm64: Add lowercase tcr_el1_t1sz
Commit 1c45cea "arm64: Change tcr_el1_t1sz variable name to
TCR_EL1_T1SZ", renamed the variable to upper case, but there are
kernels in existence that still have the lower case name, which
breaks crash backwards compatibility.
Resolves: https://github.com/crash-utility/crash/pull/82
Signed-off-by: John Donnelly <john.p.donnelly@oracle.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
arm64.c | 3 ++-
netdump.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arm64.c b/arm64.c
index 4787fa61e3e5..8934961b109d 100644
--- a/arm64.c
+++ b/arm64.c
@@ -3936,7 +3936,8 @@ arm64_calc_VA_BITS(void)
} else if (ACTIVE())
error(FATAL, "cannot determine VA_BITS_ACTUAL: please use /proc/kcore\n");
else {
- if ((string = pc->read_vmcoreinfo("NUMBER(TCR_EL1_T1SZ)"))) {
+ if ((string = pc->read_vmcoreinfo("NUMBER(TCR_EL1_T1SZ)")) ||
+ (string = pc->read_vmcoreinfo("NUMBER(tcr_el1_t1sz)"))) {
/* See ARMv8 ARM for the description of
* TCR_EL1.T1SZ and how it can be used
* to calculate the vabits_actual
diff --git a/netdump.c b/netdump.c
index c1c9cbfaed94..aaea945aaca7 100644
--- a/netdump.c
+++ b/netdump.c
@@ -1921,7 +1921,8 @@ vmcoreinfo_read_string(const char *key)
sprintf(value, "%ld", nd->arch_data2 & 0xffffffff);
return value;
}
- if (STREQ(key, "NUMBER(TCR_EL1_T1SZ)") && nd->arch_data2) {
+ if ((STREQ(key, "NUMBER(TCR_EL1_T1SZ)") ||
+ STREQ(key, "NUMBER(tcr_el1_t1sz)")) && nd->arch_data2) {
value = calloc(VADDR_PRLEN+1, sizeof(char));
sprintf(value, "%lld", ((ulonglong)nd->arch_data2 >> 32) & 0xffffffff);
pc->read_vmcoreinfo = no_vmcoreinfo;
--
2.30.2

View File

@ -0,0 +1,59 @@
From 647a5c33e1c94054d7b63168cd6c12901591cb77 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Thu, 27 May 2021 18:02:11 +0800
Subject: [PATCH 02/16] Fix for "kmem -s|-S" option on Linux 5.7 and later
kernels
Linux 5.7 and later kernels that contain kernel commit 1ad53d9fa3f6
("slub: improve bit diffusion for freelist ptr obfuscation") changed
the calculation formula in the freelist_ptr(), which added a swab()
call to mix bits a little more. When kernel is configured with the
"CONFIG_SLAB_FREELIST_HARDENED=y", without the patch, the "kmem -s|-S"
options display wrong statistics and state whether slab objects are
in use or free and can print the following errors:
crash> kmem -s
CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
87201e00 528 0 0 0 8k xfs_dqtrx
87201f00 496 0 0 0 8k xfs_dquot
kmem: xfs_buf: slab: 37202e6e900 invalid freepointer: b844bab900001d70
kmem: xfs_buf: slab: 3720250fd80 invalid freepointer: b8603f9400001370
...
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
memory.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/memory.c b/memory.c
index 8c6bbe409922..a3cf8a86728d 100644
--- a/memory.c
+++ b/memory.c
@@ -20,6 +20,7 @@
#include <sys/mman.h>
#include <ctype.h>
#include <netinet/in.h>
+#include <byteswap.h>
struct meminfo { /* general purpose memory information structure */
ulong cache; /* used by the various memory searching/dumping */
@@ -19336,10 +19337,14 @@ count_free_objects(struct meminfo *si, ulong freelist)
static ulong
freelist_ptr(struct meminfo *si, ulong ptr, ulong ptr_addr)
{
- if (VALID_MEMBER(kmem_cache_random))
+ if (VALID_MEMBER(kmem_cache_random)) {
/* CONFIG_SLAB_FREELIST_HARDENED */
+
+ if (THIS_KERNEL_VERSION >= LINUX(5,7,0))
+ ptr_addr = (sizeof(long) == 8) ? bswap_64(ptr_addr)
+ : bswap_32(ptr_addr);
return (ptr ^ si->random ^ ptr_addr);
- else
+ } else
return ptr;
}
--
2.30.2

View File

@ -0,0 +1,102 @@
From 0b5435e10161345cf713ed447a155a611a1b408b Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Wed, 26 May 2021 17:33:13 +0900
Subject: [PATCH 03/16] memory: Add support for SECTION_TAINT_ZONE_DEVICE flag
Fix for "kmem -n|-p" options on Linux 5.12-rc1 and later kernels
that contain commit 1f90a3477df3f ("mm: teach pfn_to_online_page()
about ZONE_DEVICE section collisions"). Without the patch, the
"kmem -n" option incorrectly shows mem_map addresses containing the
flag in bit 5 as part of the virtual address, and also the "kmem -p"
option shows page structures at wrong position. With the patch,
the "kmem -n" option displays the new "D" state flag.
Without the patch:
crash> kmem -n
...
NR SECTION CODED_MEM_MAP MEM_MAP STATE PFN
1040 ffff9edf3ffd4100 ffffe2bcc0000010 ffffe2bd42000010 PMOE 34078720
^ ^
crash> kmem -p
PAGE PHYSICAL MAPPING INDEX CNT FLAGS
ffffe2bd42000010 2080000000 400040 1ffffffff 9961471 dead000000000122 referenced,active,error
ffffe2bd42000050 2080001000 800080 1ffffffff 9961471 dead000000000122 referenced,active,error
ffffe2bd42000090 2080002000 0 1ffffffff 9961471 dead000000000122 referenced,active,error
^^
With the patch:
crash> kmem -n
...
NR SECTION CODED_MEM_MAP MEM_MAP STATE PFN
1040 ffff9edf3ffd4100 ffffe2bcc0000000 ffffe2bd42000000 PMOED 34078720
crash> kmem -p
PAGE PHYSICAL MAPPING INDEX CNT FLAGS
ffffe2bd42000000 2080000000 ffff9ebfc0044100 0 1 97ffffc0000200 slab
ffffe2bd42000040 2080001000 ffff9ebfc0044400 0 1 97ffffc0000200 slab
ffffe2bd42000080 2080002000 0 0 1 97ffffc0000000
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
help.c | 11 +++++++----
memory.c | 15 +++++++++------
2 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/help.c b/help.c
index e0c84087add3..9649cc81fa36 100644
--- a/help.c
+++ b/help.c
@@ -6584,10 +6584,13 @@ char *help_kmem[] = {
" kernels, the vm_zone_stat, vm_node_stat and vm_numa_stat tables,",
" the cumulative page_states counter values if they exist, and/or ",
" the cumulative, vm_event_states counter values if they exist.",
-" -n display memory node, memory section, and memory block data",
-" and state; the state of each memory section state is encoded",
-" as \"P\", \"M\", \"O\" and/or \"E\", meaning SECTION_MARKED_PRESENT,",
-" SECTION_HAS_MEM_MAP, SECTION_IS_ONLINE and SECTION_IS_EARLY.",
+" -n display memory node, memory section, memory block data and state;",
+" the state of each memory section is shown as the following flags:",
+" \"P\": SECTION_MARKED_PRESENT",
+" \"M\": SECTION_HAS_MEM_MAP",
+" \"O\": SECTION_IS_ONLINE",
+" \"E\": SECTION_IS_EARLY",
+" \"D\": SECTION_TAINT_ZONE_DEVICE",
" -z displays per-zone memory statistics.",
" -o displays each cpu's offset value that is added to per-cpu symbol",
" values to translate them into kernel virtual addresses.",
diff --git a/memory.c b/memory.c
index a3cf8a86728d..2c4f9790f498 100644
--- a/memory.c
+++ b/memory.c
@@ -17270,12 +17270,13 @@ nr_to_section(ulong nr)
* which results in PFN_SECTION_SHIFT equal 6.
* To sum it up, at least 6 bits are available.
*/
-#define SECTION_MARKED_PRESENT (1UL<<0)
-#define SECTION_HAS_MEM_MAP (1UL<<1)
-#define SECTION_IS_ONLINE (1UL<<2)
-#define SECTION_IS_EARLY (1UL<<3)
-#define SECTION_MAP_LAST_BIT (1UL<<4)
-#define SECTION_MAP_MASK (~(SECTION_MAP_LAST_BIT-1))
+#define SECTION_MARKED_PRESENT (1UL<<0)
+#define SECTION_HAS_MEM_MAP (1UL<<1)
+#define SECTION_IS_ONLINE (1UL<<2)
+#define SECTION_IS_EARLY (1UL<<3)
+#define SECTION_TAINT_ZONE_DEVICE (1UL<<4)
+#define SECTION_MAP_LAST_BIT (1UL<<5)
+#define SECTION_MAP_MASK (~(SECTION_MAP_LAST_BIT-1))
int
@@ -17373,6 +17374,8 @@ fill_mem_section_state(ulong state, char *buf)
bufidx += sprintf(buf + bufidx, "%s", "O");
if (state & SECTION_IS_EARLY)
bufidx += sprintf(buf + bufidx, "%s", "E");
+ if (state & SECTION_TAINT_ZONE_DEVICE)
+ bufidx += sprintf(buf + bufidx, "%s", "D");
}
void
--
2.30.2

View File

@ -0,0 +1,50 @@
From ec44b902d3467e7b86ee39e2d7d472b9cb202148 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Mon, 31 May 2021 14:08:28 +0900
Subject: [PATCH 04/16] memory: Fix for "kmem -n" option to display NID
correctly
The nid member of struct memory_block is a 4-byte integer, but read
and printed as a 8-byte integer on 64-bit machines. Without the
patch, the option displays wrong NIDs.
crash> kmem -n
...
MEM_BLOCK NAME PHYSICAL RANGE NODE STATE START_SECTION_NO
ffff9edeff2b9400 memory0 0 - 7fffffff 14195095130662240256 ONLINE 0
ffff9edeff2bb400 memory2 100000000 - 17fffffff 14195094718345379840 ONLINE 32
The issue seems to appear on Linux 5.12 and later kernels that contain
commit e9a2e48e8704c ("drivers/base/memory: don't store phys_device
in memory blocks"), which changed the arrangement of the members of
struct memory_block.
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
memory.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/memory.c b/memory.c
index 2c4f9790f498..cbe90eebe748 100644
--- a/memory.c
+++ b/memory.c
@@ -17568,13 +17568,13 @@ print_memory_block(ulong memory_block)
if (MEMBER_EXISTS("memory_block", "nid")) {
readmem(memory_block + OFFSET(memory_block_nid), KVADDR, &nid,
- sizeof(void *), "memory_block nid", FAULT_ON_ERROR);
+ sizeof(int), "memory_block nid", FAULT_ON_ERROR);
fprintf(fp, " %s %s %s %s %s %s\n",
mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
MKSTR(memory_block)),
mkstring(buf2, 12, CENTER, name),
parangebuf,
- mkstring(buf5, strlen("NODE"), CENTER|LONG_DEC,
+ mkstring(buf5, strlen("NODE"), CENTER|INT_DEC,
MKSTR(nid)),
mkstring(buf6, strlen("OFFLINE"), LJUST,
statebuf),
--
2.30.2

View File

@ -0,0 +1,103 @@
From 704623dfde43da98ffb354b3d7f450cd012a8215 Mon Sep 17 00:00:00 2001
From: Youling Tang <tangyouling@loongson.cn>
Date: Thu, 3 Jun 2021 16:07:41 +0800
Subject: [PATCH 05/16] defs.h: Fix the value of TIF_SIGPENDING macro
Correct the change of the value of TIF_SIGPENDING macro between
different kernel versions.
TIF_SIGPENDING changes with the kernel version as follows:
ARM 2 -> 0 at v2.6.23
MIPS 2 -> 1 at v2.6.23
MIPS64 2 -> 1 at v2.6.23
PPC 2 -> 1 at v2.6.23
IA64 1 -> 0 at v2.6.23
PPC64 2 -> 1 at v2.6.23
S390 2 -> 1 at v3.16
S390X 2 -> 1 at v3.16
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/defs.h b/defs.h
index 396d61aaf532..3502c6d6e90c 100644
--- a/defs.h
+++ b/defs.h
@@ -2997,7 +2997,7 @@ typedef struct QEMUCPUState QEMUCPUState;
#define __swp_type(entry) SWP_TYPE(entry)
#define __swp_offset(entry) SWP_OFFSET(entry)
-#define TIF_SIGPENDING (2)
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 0 : 2)
#define _SECTION_SIZE_BITS 28
#define _MAX_PHYSMEM_BITS 32
@@ -3377,7 +3377,7 @@ struct arm64_stackframe {
#define __swp_type(entry) SWP_TYPE(entry)
#define __swp_offset(entry) SWP_OFFSET(entry)
-#define TIF_SIGPENDING (2)
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 1 : 2)
#define _SECTION_SIZE_BITS 26
#define _MAX_PHYSMEM_BITS 32
@@ -3416,7 +3416,7 @@ struct arm64_stackframe {
#define __swp_type(entry) SWP_TYPE(entry)
#define __swp_offset(entry) SWP_OFFSET(entry)
-#define TIF_SIGPENDING (2)
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 1 : 2)
#define _SECTION_SIZE_BITS 28
#define _MAX_PHYSMEM_BITS 48
@@ -3884,7 +3884,7 @@ struct machine_specific {
#define __swp_type(entry) SWP_TYPE(entry)
#define __swp_offset(entry) SWP_OFFSET(entry)
-#define TIF_SIGPENDING (2)
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 1 : 2)
#define _SECTION_SIZE_BITS 24
#define _MAX_PHYSMEM_BITS 44
@@ -4079,7 +4079,7 @@ struct efi_memory_desc_t {
#define __swp_type(entry) ((entry >> 2) & 0x7f)
#define __swp_offset(entry) ((entry << 1) >> 10)
-#define TIF_SIGPENDING (1)
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 0 : 1)
#define KERNEL_TR_PAGE_SIZE (1 << _PAGE_SIZE_64M)
#define KERNEL_TR_PAGE_MASK (~(KERNEL_TR_PAGE_SIZE - 1))
@@ -4219,7 +4219,7 @@ struct efi_memory_desc_t {
#define PTE_RPN_MASK (machdep->machspec->pte_rpn_mask)
#define PTE_RPN_SHIFT (machdep->machspec->pte_rpn_shift)
-#define TIF_SIGPENDING (2)
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 1 : 2)
#define SWP_TYPE(entry) (((entry) >> 1) & 0x7f)
#define SWP_OFFSET(entry) ((entry) >> 8)
@@ -4259,7 +4259,7 @@ struct efi_memory_desc_t {
#define __swp_type(entry) SWP_TYPE(entry)
#define __swp_offset(entry) SWP_OFFSET(entry)
-#define TIF_SIGPENDING (2)
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(3,16,0) ? 1 : 2)
#define _SECTION_SIZE_BITS 25
#define _MAX_PHYSMEM_BITS 31
@@ -4284,7 +4284,7 @@ struct efi_memory_desc_t {
#define __swp_type(entry) SWP_TYPE(entry)
#define __swp_offset(entry) SWP_OFFSET(entry)
-#define TIF_SIGPENDING (2)
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(3,16,0) ? 1 : 2)
#define _SECTION_SIZE_BITS 28
#define _MAX_PHYSMEM_BITS_OLD 42
--
2.30.2

View File

@ -0,0 +1,81 @@
From 859d1c0e8a6618634cbc1fe7ee2b082a6a3c99a1 Mon Sep 17 00:00:00 2001
From: Youling Tang <tangyouling@loongson.cn>
Date: Fri, 23 Apr 2021 15:40:41 +0800
Subject: [PATCH 06/16] MIPS32/64: Add 'irq' command support
Add support for the 'irq' series of commands in the MIPS32/64
architecture, except for the 'irq -d' command, others can be
used. Without the patch, the 'irq' command fails as follows:
irq: cannot determine number of IRQs
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
mips.c | 10 ++++++++--
mips64.c | 14 ++++++++++++++
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/mips.c b/mips.c
index f73dfaddf34e..d6602e3c2b0e 100644
--- a/mips.c
+++ b/mips.c
@@ -1126,8 +1126,14 @@ mips_init(int when)
machdep->get_irq_affinity = generic_get_irq_affinity;
machdep->section_size_bits = _SECTION_SIZE_BITS;
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
- ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc,
- "irq_desc", NULL, 0);
+
+ if (symbol_exists("irq_desc"))
+ ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc,
+ "irq_desc", NULL, 0);
+ else if (kernel_symbol_exists("nr_irqs"))
+ get_symbol_data("nr_irqs", sizeof(unsigned int),
+ &machdep->nr_irqs);
+
mips_stackframe_init();
if (!machdep->hz)
diff --git a/mips64.c b/mips64.c
index 62ed799f479a..b1d6acfbd609 100644
--- a/mips64.c
+++ b/mips64.c
@@ -1160,6 +1160,9 @@ mips64_dump_machdep_table(ulong arg)
fprintf(fp, " is_task_addr: mips64_is_task_addr()\n");
fprintf(fp, " verify_symbol: mips64_verify_symbol()\n");
fprintf(fp, " dis_filter: generic_dis_filter()\n");
+ fprintf(fp, " dump_irq: generic_dump_irq()\n");
+ fprintf(fp, " show_interrupts: generic_show_interrupts()\n");
+ fprintf(fp, " get_irq_affinity: generic_get_irq_affinity()\n");
fprintf(fp, " cmd_mach: mips64_cmd_mach()\n");
fprintf(fp, " get_smp_cpus: mips64_get_smp_cpus()\n");
fprintf(fp, " is_kvaddr: generic_is_kvaddr()\n");
@@ -1246,6 +1249,9 @@ mips64_init(int when)
machdep->is_task_addr = mips64_is_task_addr;
machdep->get_smp_cpus = mips64_get_smp_cpus;
machdep->dis_filter = generic_dis_filter;
+ machdep->dump_irq = generic_dump_irq;
+ machdep->show_interrupts = generic_show_interrupts;
+ machdep->get_irq_affinity = generic_get_irq_affinity;
machdep->value_to_symbol = generic_machdep_value_to_symbol;
machdep->init_kernel_pgd = NULL;
break;
@@ -1257,6 +1263,14 @@ mips64_init(int when)
mips64_stackframe_init();
if (!machdep->hz)
machdep->hz = 250;
+
+ if (symbol_exists("irq_desc"))
+ ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc,
+ "irq_desc", NULL, 0);
+ else if (kernel_symbol_exists("nr_irqs"))
+ get_symbol_data("nr_irqs", sizeof(unsigned int),
+ &machdep->nr_irqs);
+
MEMBER_OFFSET_INIT(elf_prstatus_pr_reg, "elf_prstatus",
"pr_reg");
STRUCT_SIZE_INIT(note_buf, "note_buf_t");
--
2.30.2

View File

@ -0,0 +1,67 @@
From c15a1e025e62134094ba0ac600263d75673d5a22 Mon Sep 17 00:00:00 2001
From: Youling Tang <tangyouling@loongson.cn>
Date: Fri, 23 Apr 2021 15:42:11 +0800
Subject: [PATCH 07/16] MIPS64: three fixes for MIPS64 kernels
Three fixes for MIPS64 kernels:
(1) To support ramdumps, add the machine_type() check for MIPS64 in
ramdump_to_elf().
(2) To fix a stuck issue when invoking crash with "-d1" or larger
debug value, add the machine_type() check to get the correct
dump NOTE offsets.
(3) Fix the reference file path to the definition of the pt_regs
structure, to which mips64_regster refers.
[ kh: merged three patches into one ]
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 2 +-
diskdump.c | 2 +-
ramdump.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/defs.h b/defs.h
index 3502c6d6e90c..148b03e14455 100644
--- a/defs.h
+++ b/defs.h
@@ -6488,7 +6488,7 @@ void mips64_dump_machdep_table(ulong);
#define display_idt_table() \
error(FATAL, "-d option is not applicable to MIPS64 architecture\n")
-/* from arch/mips/include/uapi/asm/ptrace.h */
+/* from arch/mips/include/asm/ptrace.h */
struct mips64_register {
ulong regs[45];
};
diff --git a/diskdump.c b/diskdump.c
index 3effb52771c6..668069585080 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -1700,7 +1700,7 @@ dump_note_offsets(FILE *fp)
qemu = FALSE;
if (machine_type("X86_64") || machine_type("S390X") ||
machine_type("ARM64") || machine_type("PPC64") ||
- machine_type("SPARC64")) {
+ machine_type("SPARC64") || machine_type("MIPS64")) {
note64 = (void *)dd->notes_buf + tot;
len = sizeof(Elf64_Nhdr);
if (STRNEQ((char *)note64 + len, "QEMU"))
diff --git a/ramdump.c b/ramdump.c
index 4c4a920a8281..a206fcbbab3c 100644
--- a/ramdump.c
+++ b/ramdump.c
@@ -184,7 +184,7 @@ char *ramdump_to_elf(void)
e_machine = EM_ARM;
else if (machine_type("ARM64"))
e_machine = EM_AARCH64;
- else if (machine_type("MIPS"))
+ else if (machine_type("MIPS") || machine_type("MIPS64"))
e_machine = EM_MIPS;
else if (machine_type("X86_64"))
e_machine = EM_X86_64;
--
2.30.2

View File

@ -0,0 +1,36 @@
From e61841a8b86ac551c314f74f4b82daae84f99700 Mon Sep 17 00:00:00 2001
From: Luc Chouinard <lucchouina@gmail.com>
Date: Wed, 9 Jun 2021 07:59:40 -0400
Subject: [PATCH 08/16] extensions/eppic.mk: Enable use of alternate eppic
branch
Made significant changes and fixes to eppic.
Using options in the clone command break due to args parsing.
Use separate variable for clone options.
Closes: https://github.com/crash-utility/crash/pull/86
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
extensions/eppic.mk | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/extensions/eppic.mk b/extensions/eppic.mk
index bda69da6706f..b9c046b710ad 100644
--- a/extensions/eppic.mk
+++ b/extensions/eppic.mk
@@ -35,10 +35,10 @@ all:
if [ -f "$(GIT)" ]; \
then \
if [ -n "$(EPPIC_GIT_URL)" ]; then \
- git clone "$(EPPIC_GIT_URL)" eppic; \
+ git clone $(EPPIC_GIT_OPTIONS) $(EPPIC_GIT_URL) eppic; \
else \
if ping -c 1 -W 5 github.com >/dev/null ; then \
- git clone https://github.com/lucchouina/eppic.git eppic; \
+ git clone $(EPPIC_GIT_OPTIONS) https://github.com/lucchouina/eppic.git eppic; \
fi; \
fi; \
else \
--
2.30.2

View File

@ -0,0 +1,156 @@
From f091b5e76d2d6e81b12cd40df7b5863c9e2efed1 Mon Sep 17 00:00:00 2001
From: Firo Yang <firo.yang@suse.com>
Date: Tue, 25 May 2021 18:17:37 +0800
Subject: [PATCH 09/16] list: add -O option for specifying head node offset
The -O option is very useful to specify the embedded head node's
offset which is different to the offset of other nodes embedded,
e.g. dentry.d_subdirs (the head node) and dentry.d_child.
[ kh: did some cosmetic adjustments ]
Signed-off-by: Firo Yang <firo.yang@suse.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 1 +
help.c | 32 +++++++++++++++++++++++++++++++-
tools.c | 32 +++++++++++++++++++++++++++++---
3 files changed, 61 insertions(+), 4 deletions(-)
diff --git a/defs.h b/defs.h
index 148b03e14455..42c8074e6ac6 100644
--- a/defs.h
+++ b/defs.h
@@ -2613,6 +2613,7 @@ struct list_data { /* generic structure used by do_list() to walk */
#define LIST_PARSE_MEMBER (VERBOSE << 13)
#define LIST_READ_MEMBER (VERBOSE << 14)
#define LIST_BRENT_ALGO (VERBOSE << 15)
+#define LIST_HEAD_OFFSET_ENTERED (VERBOSE << 16)
struct tree_data {
ulong flags;
diff --git a/help.c b/help.c
index 9649cc81fa36..99be7cb4e17c 100644
--- a/help.c
+++ b/help.c
@@ -5716,7 +5716,7 @@ char *help__list[] = {
"list",
"linked list",
"[[-o] offset][-e end][-[s|S] struct[.member[,member] [-l offset]] -[x|d]]"
-"\n [-r|-B] [-h|-H] start",
+"\n [-r|-B] [-h [-O head_offset]|-H] start",
" ",
" This command dumps the contents of a linked list. The entries in a linked",
" list are typically data structures that are tied together in one of two",
@@ -5800,6 +5800,15 @@ char *help__list[] = {
" -S struct Similar to -s, but instead of parsing gdb output, member values",
" are read directly from memory, so the command works much faster",
" for 1-, 2-, 4-, and 8-byte members.",
+" -O offset Only used in conjunction with -h; it specifies the offset of",
+" head node list_head embedded within a data structure which is",
+" different than the offset of list_head of other nodes embedded",
+" within a data structure.",
+" The offset may be entered in either of the following manners:",
+"",
+" 1. in \"structure.member\" format.",
+" 2. a number of bytes.",
+"",
" -l offset Only used in conjunction with -s, if the start address argument",
" is a pointer to an embedded list head (or any other similar list",
" linkage structure whose first member points to the next linkage",
@@ -6116,6 +6125,27 @@ char *help__list[] = {
" comm = \"sudo\"",
" ffff88005ac10180",
" comm = \"crash\"",
+"",
+" To display a liked list whose head node and other nodes are embedded within",
+" either same or different data structures resulting in different offsets for",
+" head node and other nodes, e.g. dentry.d_subdirs and dentry.d_child, the",
+" -O option can be used:",
+"",
+" %s> list -o dentry.d_child -s dentry.d_name.name -O dentry.d_subdirs -h ffff9c585b81a180",
+" ffff9c585b9cb140",
+" d_name.name = 0xffff9c585b9cb178 ccc.txt",
+" ffff9c585b9cb980",
+" d_name.name = 0xffff9c585b9cb9b8 bbb.txt",
+" ffff9c585b9cb740",
+" d_name.name = 0xffff9c585b9cb778 aaa.txt",
+"",
+" The dentry.d_subdirs example above is equal to the following sequence:",
+"",
+" %s> struct -o dentry.d_subdirs ffff9c585b81a180",
+" struct dentry {",
+" [ffff9c585b81a220] struct list_head d_subdirs;",
+" }",
+" %s> list -o dentry.d_child -s dentry.d_name.name -H ffff9c585b81a220",
NULL
};
diff --git a/tools.c b/tools.c
index a26b101f6481..6fa3c70bac2b 100644
--- a/tools.c
+++ b/tools.c
@@ -3343,6 +3343,7 @@ void
cmd_list(void)
{
int c;
+ long head_member_offset = 0; /* offset for head like denty.d_subdirs */
struct list_data list_data, *ld;
struct datatype_member struct_member, *sm;
struct syment *sp;
@@ -3353,7 +3354,7 @@ cmd_list(void)
BZERO(ld, sizeof(struct list_data));
struct_list_offset = 0;
- while ((c = getopt(argcnt, args, "BHhrs:S:e:o:xdl:")) != EOF) {
+ while ((c = getopt(argcnt, args, "BHhrs:S:e:o:O:xdl:")) != EOF) {
switch(c)
{
case 'B':
@@ -3394,6 +3395,20 @@ cmd_list(void)
optarg);
break;
+ case 'O':
+ if (ld->flags & LIST_HEAD_OFFSET_ENTERED)
+ error(FATAL, "offset value %d (0x%lx) already entered\n",
+ head_member_offset, head_member_offset);
+ else if (IS_A_NUMBER(optarg))
+ head_member_offset = stol(optarg, FAULT_ON_ERROR, NULL);
+ else if (arg_to_datatype(optarg, sm, RETURN_ON_ERROR) > 1)
+ head_member_offset = sm->member_offset;
+ else
+ error(FATAL, "invalid -O argument: %s\n", optarg);
+
+ ld->flags |= LIST_HEAD_OFFSET_ENTERED;
+ break;
+
case 'o':
if (ld->flags & LIST_OFFSET_ENTERED)
error(FATAL,
@@ -3599,8 +3614,19 @@ next_arg:
fprintf(fp, "(empty)\n");
return;
}
- } else
- ld->start += ld->list_head_offset;
+ } else {
+ if (ld->flags & LIST_HEAD_OFFSET_ENTERED) {
+ if (!ld->end)
+ ld->end = ld->start + head_member_offset;
+ readmem(ld->start + head_member_offset, KVADDR, &ld->start,
+ sizeof(void *), "LIST_HEAD contents", FAULT_ON_ERROR);
+ if (ld->start == ld->end) {
+ fprintf(fp, "(empty)\n");
+ return;
+ }
+ } else
+ ld->start += ld->list_head_offset;
+ }
}
ld->flags &= ~(LIST_OFFSET_ENTERED|LIST_START_ENTERED);
--
2.30.2

View File

@ -0,0 +1,132 @@
From eaf14f852ae79f7745934e213661f1c6abac711e Mon Sep 17 00:00:00 2001
From: Greg Edwards <gedwards@ddn.com>
Date: Wed, 23 Jun 2021 13:50:47 -0600
Subject: [PATCH 10/16] Fix 'waitq' command for Linux 4.13 and later kernels
The wait queue structs and members were renamed in 4.13 in commits:
ac6424b981bc ("sched/wait: Rename wait_queue_t => wait_queue_entry_t")
9d9d676f595b ("sched/wait: Standardize internal naming of wait-queue heads")
2055da97389a ("sched/wait: Disambiguate wq_entry->task_list and wq_head->task_list naming")
Add support to the 'waitq' command for these more recent kernels.
[ kh: suppressed compilation warnings ]
Signed-off-by: Greg Edwards <gedwards@ddn.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 4 ++++
kernel.c | 27 +++++++++++++++++++++++----
symbols.c | 10 +++++++++-
3 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/defs.h b/defs.h
index 42c8074e6ac6..6bb00e29d811 100644
--- a/defs.h
+++ b/defs.h
@@ -2138,6 +2138,9 @@ struct offset_table { /* stash of commonly-used offsets */
long atomic_long_t_counter;
long block_device_bd_device;
long block_device_bd_stats;
+ long wait_queue_entry_private;
+ long wait_queue_head_head;
+ long wait_queue_entry_entry;
};
struct size_table { /* stash of commonly-used sizes */
@@ -2300,6 +2303,7 @@ struct size_table { /* stash of commonly-used sizes */
long printk_info;
long printk_ringbuffer;
long prb_desc;
+ long wait_queue_entry;
};
struct array_table {
diff --git a/kernel.c b/kernel.c
index 528f6ee524f6..e123f760e036 100644
--- a/kernel.c
+++ b/kernel.c
@@ -615,7 +615,15 @@ kernel_init()
kt->flags |= TVEC_BASES_V1;
STRUCT_SIZE_INIT(__wait_queue, "__wait_queue");
- if (VALID_STRUCT(__wait_queue)) {
+ STRUCT_SIZE_INIT(wait_queue_entry, "wait_queue_entry");
+ if (VALID_STRUCT(wait_queue_entry)) {
+ MEMBER_OFFSET_INIT(wait_queue_entry_private,
+ "wait_queue_entry", "private");
+ MEMBER_OFFSET_INIT(wait_queue_head_head,
+ "wait_queue_head", "head");
+ MEMBER_OFFSET_INIT(wait_queue_entry_entry,
+ "wait_queue_entry", "entry");
+ } else if (VALID_STRUCT(__wait_queue)) {
if (MEMBER_EXISTS("__wait_queue", "task"))
MEMBER_OFFSET_INIT(__wait_queue_task,
"__wait_queue", "task");
@@ -9367,9 +9375,9 @@ dump_waitq(ulong wq, char *wq_name)
struct list_data list_data, *ld;
ulong *wq_list; /* addr of wait queue element */
ulong next_offset; /* next pointer of wq element */
- ulong task_offset; /* offset of task in wq element */
+ ulong task_offset = 0; /* offset of task in wq element */
int cnt; /* # elems on Queue */
- int start_index; /* where to start in wq array */
+ int start_index = -1; /* where to start in wq array */
int i;
ld = &list_data;
@@ -9397,9 +9405,20 @@ dump_waitq(ulong wq, char *wq_name)
ld->list_head_offset = OFFSET(__wait_queue_task_list);
ld->member_offset = next_offset;
+ start_index = 1;
+ } else if (VALID_STRUCT(wait_queue_entry)) {
+ ulong head_offset;
+
+ next_offset = OFFSET(list_head_next);
+ task_offset = OFFSET(wait_queue_entry_private);
+ head_offset = OFFSET(wait_queue_head_head);
+ ld->end = ld->start = wq + head_offset + next_offset;
+ ld->list_head_offset = OFFSET(wait_queue_entry_entry);
+ ld->member_offset = next_offset;
+
start_index = 1;
} else {
- return;
+ error(FATAL, "cannot determine wait queue structures\n");
}
hq_open();
diff --git a/symbols.c b/symbols.c
index 370d4c3e8ac0..67c135f12984 100644
--- a/symbols.c
+++ b/symbols.c
@@ -9817,7 +9817,13 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(__wait_queue_head_task_list));
fprintf(fp, " __wait_queue_task_list: %ld\n",
OFFSET(__wait_queue_task_list));
-
+ fprintf(fp, " wait_queue_entry_private: %ld\n",
+ OFFSET(wait_queue_entry_private));
+ fprintf(fp, " wait_queue_head_head: %ld\n",
+ OFFSET(wait_queue_head_head));
+ fprintf(fp, " wait_queue_entry_entry: %ld\n",
+ OFFSET(wait_queue_entry_entry));
+
fprintf(fp, " pglist_data_node_zones: %ld\n",
OFFSET(pglist_data_node_zones));
fprintf(fp, " pglist_data_node_mem_map: %ld\n",
@@ -10717,6 +10723,8 @@ dump_offset_table(char *spec, ulong makestruct)
fprintf(fp, " wait_queue: %ld\n", SIZE(wait_queue));
fprintf(fp, " __wait_queue: %ld\n",
SIZE(__wait_queue));
+ fprintf(fp, " wait_queue_entry: %ld\n",
+ SIZE(wait_queue_entry));
fprintf(fp, " device: %ld\n", SIZE(device));
fprintf(fp, " net_device: %ld\n", SIZE(net_device));
--
2.30.2

View File

@ -0,0 +1,90 @@
From 4badc6229c69f5cd9da7eb7bdf400a53ec6db01a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Tesa=C5=99=C3=ADk?= <ptesarik@suse.cz>
Date: Fri, 25 Jun 2021 17:21:18 +0200
Subject: [PATCH 11/16] Fix pvops Xen detection for kernels >= v4.20
Kernel commit 5c83511bdb9832c86be20fb86b783356e2f58062 removed
pv_init_ops, and later commit 054ac8ad5ebe4a69e1f0e842483821ddbe560121
removed the Xen-specific paravirt patch function. As a result, pvops Xen
dumps are no longer recognized as Xen dumps, and virtual-to-physical
translation fails.
Use the value of xen_start_info to determine whether the kernel is
running in Xen PV mode. This pointer is set during the initialization of
a PV domain. Kudos to Juergen Gross, who suggested this check.
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
kernel.c | 34 ++++++++++++++++++++++++++++------
1 file changed, 28 insertions(+), 6 deletions(-)
diff --git a/kernel.c b/kernel.c
index e123f760e036..36fdea29b1cb 100644
--- a/kernel.c
+++ b/kernel.c
@@ -95,6 +95,7 @@ static ulong __dump_audit(char *);
static void dump_audit(void);
static char *vmcoreinfo_read_string(const char *);
static void check_vmcoreinfo(void);
+static int is_pvops_xen(void);
/*
@@ -109,7 +110,6 @@ kernel_init()
char *rqstruct;
char *rq_timestamp_name = NULL;
char *irq_desc_type_name;
- ulong pv_init_ops;
struct gnu_request req;
if (pc->flags & KERNEL_DEBUG_QUERY)
@@ -169,11 +169,7 @@ kernel_init()
error(FATAL, "cannot malloc m2p page.");
}
- if (PVOPS() && symbol_exists("pv_init_ops") &&
- readmem(symbol_value("pv_init_ops"), KVADDR, &pv_init_ops,
- sizeof(void *), "pv_init_ops", RETURN_ON_ERROR) &&
- ((p1 = value_symbol(pv_init_ops)) &&
- (STREQ(p1, "xen_patch") || STREQ(p1, "paravirt_patch_default")))) {
+ if (is_pvops_xen()) {
kt->flags |= ARCH_XEN | ARCH_PVOPS_XEN;
kt->xen_flags |= WRITABLE_PAGE_TABLES;
if (machine_type("X86"))
@@ -10709,6 +10705,32 @@ paravirt_init(void)
}
}
+static int
+is_pvops_xen(void)
+{
+ ulong addr;
+ char *sym;
+
+ if (!PVOPS())
+ return FALSE;
+
+ if (symbol_exists("pv_init_ops") &&
+ readmem(symbol_value("pv_init_ops"), KVADDR, &addr,
+ sizeof(void *), "pv_init_ops", RETURN_ON_ERROR) &&
+ (sym = value_symbol(addr)) &&
+ (STREQ(sym, "xen_patch") ||
+ STREQ(sym, "paravirt_patch_default")))
+ return TRUE;
+
+ if (symbol_exists("xen_start_info") &&
+ readmem(symbol_value("xen_start_info"), KVADDR, &addr,
+ sizeof(void *), "xen_start_info", RETURN_ON_ERROR) &&
+ addr != 0)
+ return TRUE;
+
+ return FALSE;
+}
+
/*
* Get the kernel's xtime timespec from its relevant location.
*/
--
2.30.2

View File

@ -0,0 +1,77 @@
From d6b4f36d6b22b70fb14e692f36d20910ef5563c1 Mon Sep 17 00:00:00 2001
From: Alexander Egorenkov <egorenar@linux.ibm.com>
Date: Tue, 29 Jun 2021 08:39:00 +0200
Subject: [PATCH 12/16] Handle task_struct state member changes for kernels >=
5.14-rc1
Kernel commit 2f064a59a11ff9bc22e52e9678bc601404c7cb34 ("sched: Change
task_struct::state") renamed the member state of task_struct to __state
and its type changed from long to unsigned int. Without the patch,
crash fails to start up with the following error:
crash: invalid structure member offset: task_struct_state
FILE: task.c LINE: 5929 FUNCTION: task_state()
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 1 +
symbols.c | 1 +
task.c | 10 +++++++++-
3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/defs.h b/defs.h
index 6bb00e29d811..5d32954905c2 100644
--- a/defs.h
+++ b/defs.h
@@ -2304,6 +2304,7 @@ struct size_table { /* stash of commonly-used sizes */
long printk_ringbuffer;
long prb_desc;
long wait_queue_entry;
+ long task_struct_state;
};
struct array_table {
diff --git a/symbols.c b/symbols.c
index 67c135f12984..bf6d94db84af 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10678,6 +10678,7 @@ dump_offset_table(char *spec, ulong makestruct)
SIZE(page_cache_bucket));
fprintf(fp, " pt_regs: %ld\n", SIZE(pt_regs));
fprintf(fp, " task_struct: %ld\n", SIZE(task_struct));
+ fprintf(fp, " task_struct_state: %ld\n", SIZE(task_struct_state));
fprintf(fp, " task_struct_flags: %ld\n", SIZE(task_struct_flags));
fprintf(fp, " task_struct_policy: %ld\n", SIZE(task_struct_policy));
fprintf(fp, " thread_info: %ld\n", SIZE(thread_info));
diff --git a/task.c b/task.c
index 36cf259e5d7b..672b41697e75 100644
--- a/task.c
+++ b/task.c
@@ -297,6 +297,11 @@ task_init(void)
}
MEMBER_OFFSET_INIT(task_struct_state, "task_struct", "state");
+ MEMBER_SIZE_INIT(task_struct_state, "task_struct", "state");
+ if (INVALID_MEMBER(task_struct_state)) {
+ MEMBER_OFFSET_INIT(task_struct_state, "task_struct", "__state");
+ MEMBER_SIZE_INIT(task_struct_state, "task_struct", "__state");
+ }
MEMBER_OFFSET_INIT(task_struct_exit_state, "task_struct", "exit_state");
MEMBER_OFFSET_INIT(task_struct_pid, "task_struct", "pid");
MEMBER_OFFSET_INIT(task_struct_comm, "task_struct", "comm");
@@ -5926,7 +5931,10 @@ task_state(ulong task)
if (!tt->last_task_read)
return 0;
- state = ULONG(tt->task_struct + OFFSET(task_struct_state));
+ if (SIZE(task_struct_state) == sizeof(ulong))
+ state = ULONG(tt->task_struct + OFFSET(task_struct_state));
+ else
+ state = UINT(tt->task_struct + OFFSET(task_struct_state));
exit_state = VALID_MEMBER(task_struct_exit_state) ?
ULONG(tt->task_struct + OFFSET(task_struct_exit_state)) : 0;
--
2.30.2

View File

@ -0,0 +1,62 @@
From 5719afc7a40868418405a87a2711088556e68a3b Mon Sep 17 00:00:00 2001
From: Pingfan Liu <piliu@redhat.com>
Date: Fri, 2 Jul 2021 10:14:21 +0800
Subject: [PATCH 13/16] arm64: rename ARM64_PAGE_OFFSET_ACTUAL to
ARM64_FLIP_PAGE_OFFSET_ACTUAL
Reflect the flipped layout of kernel VA, which is introduced by
kernel commit 14c127c957c1 ("arm64: mm: Flip kernel VA space").
Signed-off-by: Pingfan Liu <piliu@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
arm64.c | 10 ++++++----
defs.h | 3 ++-
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/arm64.c b/arm64.c
index 8934961b109d..9fe1a4a3bddb 100644
--- a/arm64.c
+++ b/arm64.c
@@ -217,10 +217,12 @@ arm64_init(int when)
arm64_calc_VA_BITS();
arm64_calc_KERNELPACMASK();
ms = machdep->machspec;
+
+ /* vabits_actual introduced after mm flip, so it should be flipped layout */
if (ms->VA_BITS_ACTUAL) {
- ms->page_offset = ARM64_PAGE_OFFSET_ACTUAL;
- machdep->identity_map_base = ARM64_PAGE_OFFSET_ACTUAL;
- machdep->kvbase = ARM64_PAGE_OFFSET_ACTUAL;
+ ms->page_offset = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
+ machdep->identity_map_base = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
+ machdep->kvbase = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
ms->userspace_top = ARM64_USERSPACE_TOP_ACTUAL;
} else {
ms->page_offset = ARM64_PAGE_OFFSET;
@@ -401,7 +403,7 @@ arm64_init(int when)
fprintf(fp, "CONFIG_ARM64_VA_BITS: %ld\n", ms->CONFIG_ARM64_VA_BITS);
fprintf(fp, " VA_BITS_ACTUAL: %ld\n", ms->VA_BITS_ACTUAL);
fprintf(fp, "(calculated) VA_BITS: %ld\n", ms->VA_BITS);
- fprintf(fp, " PAGE_OFFSET: %lx\n", ARM64_PAGE_OFFSET_ACTUAL);
+ fprintf(fp, " PAGE_OFFSET: %lx\n", ARM64_FLIP_PAGE_OFFSET_ACTUAL);
fprintf(fp, " VA_START: %lx\n", ms->VA_START);
fprintf(fp, " modules: %lx - %lx\n", ms->modules_vaddr, ms->modules_end);
fprintf(fp, " vmalloc: %lx - %lx\n", ms->vmalloc_start_addr, ms->vmalloc_end);
diff --git a/defs.h b/defs.h
index 5d32954905c2..eb7ce6aea331 100644
--- a/defs.h
+++ b/defs.h
@@ -3233,7 +3233,8 @@ typedef signed int s32;
#define ARM64_PAGE_OFFSET ((0xffffffffffffffffUL) \
<< (machdep->machspec->VA_BITS - 1))
-#define ARM64_PAGE_OFFSET_ACTUAL ((0xffffffffffffffffUL) \
+/* kernels >= v5.4 the kernel VA space is flipped */
+#define ARM64_FLIP_PAGE_OFFSET_ACTUAL ((0xffffffffffffffffUL) \
- ((1UL) << machdep->machspec->VA_BITS_ACTUAL) + 1)
#define ARM64_USERSPACE_TOP ((1UL) << machdep->machspec->VA_BITS)
--
2.30.2

View File

@ -0,0 +1,57 @@
From 167d37e347fe35c6f7db826e8539e192c4375564 Mon Sep 17 00:00:00 2001
From: Pingfan Liu <piliu@redhat.com>
Date: Fri, 2 Jul 2021 10:14:22 +0800
Subject: [PATCH 14/16] arm64: assign page_offset with VA_BITS kernel
configuration value
On RHEL9, crash hits a bug when executing "crash /proc/kcore":
seek error: kernel virtual address: ffff6a0f3fff0000 type: "pmd page"
The kernel virtual address does not vary with vabits_actual, instead,
is determined by configuration value. But crash does not observe this
fact.
Since vabits_actual related kernel commit is introduced after arm64
mm layout flip commit, so changes are safe under the condition if
(ms->VA_BITS_ACTUAL), and keep the else branch untouched.
Signed-off-by: Pingfan Liu <piliu@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
arm64.c | 7 ++++---
defs.h | 1 +
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arm64.c b/arm64.c
index 9fe1a4a3bddb..149db36cd119 100644
--- a/arm64.c
+++ b/arm64.c
@@ -220,9 +220,10 @@ arm64_init(int when)
/* vabits_actual introduced after mm flip, so it should be flipped layout */
if (ms->VA_BITS_ACTUAL) {
- ms->page_offset = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
- machdep->identity_map_base = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
- machdep->kvbase = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
+ ms->page_offset = ARM64_FLIP_PAGE_OFFSET;
+ /* useless on arm64 */
+ machdep->identity_map_base = ARM64_FLIP_PAGE_OFFSET;
+ machdep->kvbase = ARM64_FLIP_PAGE_OFFSET;
ms->userspace_top = ARM64_USERSPACE_TOP_ACTUAL;
} else {
ms->page_offset = ARM64_PAGE_OFFSET;
diff --git a/defs.h b/defs.h
index eb7ce6aea331..b7b20af4bcf9 100644
--- a/defs.h
+++ b/defs.h
@@ -3234,6 +3234,7 @@ typedef signed int s32;
#define ARM64_PAGE_OFFSET ((0xffffffffffffffffUL) \
<< (machdep->machspec->VA_BITS - 1))
/* kernels >= v5.4 the kernel VA space is flipped */
+#define ARM64_FLIP_PAGE_OFFSET (-(1UL) << machdep->machspec->CONFIG_ARM64_VA_BITS)
#define ARM64_FLIP_PAGE_OFFSET_ACTUAL ((0xffffffffffffffffUL) \
- ((1UL) << machdep->machspec->VA_BITS_ACTUAL) + 1)
--
2.30.2

View File

@ -0,0 +1,84 @@
From bf1379a8b6ff8d6a8fa12978f7194f15f85c4380 Mon Sep 17 00:00:00 2001
From: Pingfan Liu <piliu@redhat.com>
Date: Fri, 2 Jul 2021 10:14:23 +0800
Subject: [PATCH 15/16] arm64: use dedicated bits to record the VA space layout
changes
arm64 memory layout experiences big changes due to the following kernel
commits in date descending order:
5. 7bc1a0f9e176 arm64: mm: use single quantity to represent the PA to VA translation
4. b6d00d47e81a arm64: mm: Introduce 52-bit Kernel VAs
3. 5383cc6efed1 arm64: mm: Introduce vabits_actual
2. 14c127c957c1 arm64: mm: Flip kernel VA space
1. f80fb3a3d508 arm64: add support for kernel ASLR
For 1, crash has already used NEW_VMEMMAP to trace it.
For 2, crash lacks a flag to tag it and handle it differently.
For 3, two important kernel variables vabits_actual and physvirt_offset
are introduced.
For 4, since it comes immediately after 3, crash-utility does not need
to distinguish it.
For 5, kernel variable phyvirt_offset is removed
These changes have effects on PTOV()/VTOP() formula. So introducing
two bits HAS_PHYSVIRT_OFFSET and FLIPPED_VM as hint to apply different
formula.
Signed-off-by: Pingfan Liu <piliu@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
arm64.c | 10 ++++++++++
defs.h | 2 ++
2 files changed, 12 insertions(+)
diff --git a/arm64.c b/arm64.c
index 149db36cd119..b04369f6d4d8 100644
--- a/arm64.c
+++ b/arm64.c
@@ -563,6 +563,10 @@ arm64_dump_machdep_table(ulong arg)
fprintf(fp, "%sMACHDEP_BT_TEXT", others++ ? "|" : "");
if (machdep->flags & NEW_VMEMMAP)
fprintf(fp, "%sNEW_VMEMMAP", others++ ? "|" : "");
+ if (machdep->flags & FLIPPED_VM)
+ fprintf(fp, "%sFLIPPED_VM", others++ ? "|" : "");
+ if (machdep->flags & HAS_PHYSVIRT_OFFSET)
+ fprintf(fp, "%sHAS_PHYSVIRT_OFFSET", others++ ? "|" : "");
fprintf(fp, ")\n");
fprintf(fp, " kvbase: %lx\n", machdep->kvbase);
@@ -997,6 +1001,7 @@ arm64_calc_physvirt_offset(void)
if (READMEM(pc->mfd, &physvirt_offset, sizeof(physvirt_offset),
sp->value, sp->value -
machdep->machspec->kimage_voffset) > 0) {
+ machdep->flags |= HAS_PHYSVIRT_OFFSET;
ms->physvirt_offset = physvirt_offset;
}
}
@@ -3963,6 +3968,11 @@ arm64_calc_VA_BITS(void)
error(FATAL, "cannot determine VA_BITS_ACTUAL\n");
}
+ /*
+ * The mm flip commit is introduced before 52-bits VA, which is before the
+ * commit to export NUMBER(TCR_EL1_T1SZ)
+ */
+ machdep->flags |= FLIPPED_VM;
return;
}
diff --git a/defs.h b/defs.h
index b7b20af4bcf9..eca145cb881c 100644
--- a/defs.h
+++ b/defs.h
@@ -3214,6 +3214,8 @@ typedef signed int s32;
#define NEW_VMEMMAP (0x80)
#define VM_L4_4K (0x100)
#define UNW_4_14 (0x200)
+#define FLIPPED_VM (0x400)
+#define HAS_PHYSVIRT_OFFSET (0x800)
/*
* Get kimage_voffset from /dev/crash
--
2.30.2

View File

@ -0,0 +1,166 @@
From f53b73e8380bca054cebd2b61ff118c46609429b Mon Sep 17 00:00:00 2001
From: Pingfan Liu <piliu@redhat.com>
Date: Fri, 2 Jul 2021 10:14:24 +0800
Subject: [PATCH 16/16] arm64: implement switchable PTOV()/VTOP() for kernels
>= 5.10
Crash encounters a bug like the following:
...
SECTION_SIZE_BITS: 30
CONFIG_ARM64_VA_BITS: 52
VA_BITS_ACTUAL: 48
(calculated) VA_BITS: 48
PAGE_OFFSET: ffff000000000000
VA_START: ffff800000000000
modules: ffff800008000000 - ffff80000fffffff
vmalloc: ffff800010000000 - ffffffdfdffeffff
kernel image: ffff800010000000 - ffff800012750000
vmemmap: ffffffdfffe00000 - ffffffffffffffff
<readmem: ffff800011c53bc8, KVADDR, "nr_irqs", 4, (FOE), b47bdc>
<read_kdump: addr: ffff800011c53bc8 paddr: eb453bc8 cnt: 4>
read_netdump: addr: ffff800011c53bc8 paddr: eb453bc8 cnt: 4 offset: 1c73bc8
irq_stack_ptr:
type: 1, TYPE_CODE_PTR
target_typecode: 8, TYPE_CODE_INT
target_length: 8
length: 8
GNU_GET_DATATYPE[thread_union]: returned via gdb_error_hook
<readmem: ffff000b779c0050, KVADDR, "IRQ stack pointer", 8, (ROE), 3a37bea0>
<read_kdump: addr: ffff000b779c0050 paddr: fff1000bf79c0050 cnt: 8>
read_netdump: READ_ERROR: offset not found for paddr: fff1000bf79c0050
crash: read error: kernel virtual address: ffff000b779c0050 type: "IRQ stack pointer"
...
Apparently, for a normal system, the 'paddr: fff1000bf79c0050' is
unreasonable.
This bug connects with kernel commit 7bc1a0f9e176 ("arm64: mm: use
single quantity to represent the PA to VA translation"), which removed
physvirt_offset kernel variable and changed the PTOV()/VTOP() formulas.
Implement switchable PTOV()/VTOP() to cope with different kernel
version.
Signed-off-by: Pingfan Liu <piliu@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
arm64.c | 37 +++++++++++++++++++++++++++++++++----
defs.h | 9 ++++-----
2 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/arm64.c b/arm64.c
index b04369f6d4d8..d73d5c5a4fed 100644
--- a/arm64.c
+++ b/arm64.c
@@ -994,8 +994,6 @@ arm64_calc_physvirt_offset(void)
ulong physvirt_offset;
struct syment *sp;
- ms->physvirt_offset = ms->phys_offset - ms->page_offset;
-
if ((sp = kernel_symbol_search("physvirt_offset")) &&
machdep->machspec->kimage_voffset) {
if (READMEM(pc->mfd, &physvirt_offset, sizeof(physvirt_offset),
@@ -1003,8 +1001,13 @@ arm64_calc_physvirt_offset(void)
machdep->machspec->kimage_voffset) > 0) {
machdep->flags |= HAS_PHYSVIRT_OFFSET;
ms->physvirt_offset = physvirt_offset;
+ return;
}
}
+
+ /* Useless if no symbol 'physvirt_offset', just keep semantics */
+ ms->physvirt_offset = ms->phys_offset - ms->page_offset;
+
}
static void
@@ -1051,6 +1054,7 @@ arm64_calc_phys_offset(void)
if (READMEM(pc->mfd, &phys_offset, sizeof(phys_offset),
vaddr, paddr) > 0) {
ms->phys_offset = phys_offset;
+
return;
}
}
@@ -1178,6 +1182,21 @@ arm64_init_kernel_pgd(void)
vt->kernel_pgd[i] = value;
}
+ulong arm64_PTOV(ulong paddr)
+{
+ struct machine_specific *ms = machdep->machspec;
+
+ /*
+ * Either older kernel before kernel has 'physvirt_offset' or newer
+ * kernel which removes 'physvirt_offset' has the same formula:
+ * #define __phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET) | PAGE_OFFSET)
+ */
+ if (!(machdep->flags & HAS_PHYSVIRT_OFFSET))
+ return (paddr - ms->phys_offset) | PAGE_OFFSET;
+ else
+ return paddr - ms->physvirt_offset;
+}
+
ulong
arm64_VTOP(ulong addr)
{
@@ -1188,8 +1207,18 @@ arm64_VTOP(ulong addr)
return addr - machdep->machspec->kimage_voffset;
}
- if (addr >= machdep->machspec->page_offset)
- return addr + machdep->machspec->physvirt_offset;
+ if (addr >= machdep->machspec->page_offset) {
+ if (machdep->flags & HAS_PHYSVIRT_OFFSET) {
+ return addr + machdep->machspec->physvirt_offset;
+ } else {
+ /*
+ * Either older kernel before kernel has 'physvirt_offset' or newer
+ * kernel which removes 'physvirt_offset' has the same formula:
+ * #define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)
+ */
+ return (addr & ~PAGE_OFFSET) + machdep->machspec->phys_offset;
+ }
+ }
else if (machdep->machspec->kimage_voffset)
return addr - machdep->machspec->kimage_voffset;
else /* no randomness */
diff --git a/defs.h b/defs.h
index eca145cb881c..c91177a245fd 100644
--- a/defs.h
+++ b/defs.h
@@ -3092,11 +3092,6 @@ typedef u64 pte_t;
#define _64BIT_
#define MACHINE_TYPE "ARM64"
-#define PTOV(X) \
- ((unsigned long)(X) - (machdep->machspec->physvirt_offset))
-
-#define VTOP(X) arm64_VTOP((ulong)(X))
-
#define USERSPACE_TOP (machdep->machspec->userspace_top)
#define PAGE_OFFSET (machdep->machspec->page_offset)
#define VMALLOC_START (machdep->machspec->vmalloc_start_addr)
@@ -3106,6 +3101,9 @@ typedef u64 pte_t;
#define MODULES_VADDR (machdep->machspec->modules_vaddr)
#define MODULES_END (machdep->machspec->modules_end)
+#define PTOV(X) arm64_PTOV((ulong)(X))
+#define VTOP(X) arm64_VTOP((ulong)(X))
+
#define IS_VMALLOC_ADDR(X) arm64_IS_VMALLOC_ADDR((ulong)(X))
#define PAGEBASE(X) (((ulong)(X)) & (ulong)machdep->pagemask)
@@ -5910,6 +5908,7 @@ void unwind_backtrace(struct bt_info *);
void arm64_init(int);
void arm64_dump_machdep_table(ulong);
ulong arm64_VTOP(ulong);
+ulong arm64_PTOV(ulong);
int arm64_IS_VMALLOC_ADDR(ulong);
ulong arm64_swp_type(ulong);
ulong arm64_swp_offset(ulong);
--
2.30.2

View File

@ -4,7 +4,7 @@
Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles
Name: crash
Version: 7.3.0
Release: 1%{?dist}
Release: 2%{?dist}
License: GPLv3
Source0: https://github.com/crash-utility/crash/archive/crash-%{version}.tar.gz
Source1: http://ftp.gnu.org/gnu/gdb/gdb-7.6.tar.gz
@ -18,6 +18,22 @@ Requires: binutils
Provides: bundled(libiberty)
Provides: bundled(gdb) = 7.6
Patch0: lzo_snappy.patch
Patch1: 0001-arm64-Add-lowercase-tcr_el1_t1sz.patch
Patch2: 0002-Fix-for-kmem-s-S-option-on-Linux-5.7-and-later-kerne.patch
Patch3: 0003-memory-Add-support-for-SECTION_TAINT_ZONE_DEVICE-fla.patch
Patch4: 0004-memory-Fix-for-kmem-n-option-to-display-NID-correctl.patch
Patch5: 0005-defs.h-Fix-the-value-of-TIF_SIGPENDING-macro.patch
Patch6: 0006-MIPS32-64-Add-irq-command-support.patch
Patch7: 0007-MIPS64-three-fixes-for-MIPS64-kernels.patch
Patch8: 0008-extensions-eppic.mk-Enable-use-of-alternate-eppic-br.patch
Patch9: 0009-list-add-O-option-for-specifying-head-node-offset.patch
Patch10: 0010-Fix-waitq-command-for-Linux-4.13-and-later-kernels.patch
Patch11: 0011-Fix-pvops-Xen-detection-for-kernels-v4.20.patch
Patch12: 0012-Handle-task_struct-state-member-changes-for-kernels-.patch
Patch13: 0013-arm64-rename-ARM64_PAGE_OFFSET_ACTUAL-to-ARM64_FLIP_.patch
Patch14: 0014-arm64-assign-page_offset-with-VA_BITS-kernel-configu.patch
Patch15: 0015-arm64-use-dedicated-bits-to-record-the-VA-space-layo.patch
Patch16: 0016-arm64-implement-switchable-PTOV-VTOP-for-kernels-5.1.patch
%description
The core analysis suite is a self-contained tool that can be used to
@ -38,6 +54,22 @@ offered by Mission Critical Linux, or the LKCD kernel patch.
%prep
%setup -n %{name}-%{version} -q
%patch0 -p1 -b lzo_snappy.patch
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%build
# This package has an internal copy of GDB which has broken configure code for
@ -69,6 +101,9 @@ cp -p defs.h %{buildroot}%{_includedir}/crash
%{_includedir}/*
%changelog
* Tue Jul 13 2021 Lianbo Jiang <lijiang@redhat.com> - 7.3.0-2
- Update to the latest upstream <f53b73e8380b>
* Fri May 07 2021 Lianbo Jiang <lijiang@redhat.com> - 7.3.0-1
- Rebase to upstream 7.3.0