diff --git a/0001-arm64-Add-lowercase-tcr_el1_t1sz.patch b/0001-arm64-Add-lowercase-tcr_el1_t1sz.patch new file mode 100644 index 0000000..a785e03 --- /dev/null +++ b/0001-arm64-Add-lowercase-tcr_el1_t1sz.patch @@ -0,0 +1,50 @@ +From a7ecf2467f953b632713f38ab8104596755bca8c Mon Sep 17 00:00:00 2001 +From: John Donnelly +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 +Signed-off-by: Kazuhito Hagio +Signed-off-by: Lianbo Jiang +--- + 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 + diff --git a/0002-Fix-for-kmem-s-S-option-on-Linux-5.7-and-later-kerne.patch b/0002-Fix-for-kmem-s-S-option-on-Linux-5.7-and-later-kerne.patch new file mode 100644 index 0000000..f796248 --- /dev/null +++ b/0002-Fix-for-kmem-s-S-option-on-Linux-5.7-and-later-kerne.patch @@ -0,0 +1,59 @@ +From 647a5c33e1c94054d7b63168cd6c12901591cb77 Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +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 +--- + 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 + #include + #include ++#include + + 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 + diff --git a/0003-memory-Add-support-for-SECTION_TAINT_ZONE_DEVICE-fla.patch b/0003-memory-Add-support-for-SECTION_TAINT_ZONE_DEVICE-fla.patch new file mode 100644 index 0000000..ff4ba48 --- /dev/null +++ b/0003-memory-Add-support-for-SECTION_TAINT_ZONE_DEVICE-fla.patch @@ -0,0 +1,102 @@ +From 0b5435e10161345cf713ed447a155a611a1b408b Mon Sep 17 00:00:00 2001 +From: Kazuhito Hagio +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 +Signed-off-by: Lianbo Jiang +--- + 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 + diff --git a/0004-memory-Fix-for-kmem-n-option-to-display-NID-correctl.patch b/0004-memory-Fix-for-kmem-n-option-to-display-NID-correctl.patch new file mode 100644 index 0000000..3c50b2c --- /dev/null +++ b/0004-memory-Fix-for-kmem-n-option-to-display-NID-correctl.patch @@ -0,0 +1,50 @@ +From ec44b902d3467e7b86ee39e2d7d472b9cb202148 Mon Sep 17 00:00:00 2001 +From: Kazuhito Hagio +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 +Signed-off-by: Lianbo Jiang +--- + 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 + diff --git a/0005-defs.h-Fix-the-value-of-TIF_SIGPENDING-macro.patch b/0005-defs.h-Fix-the-value-of-TIF_SIGPENDING-macro.patch new file mode 100644 index 0000000..923a840 --- /dev/null +++ b/0005-defs.h-Fix-the-value-of-TIF_SIGPENDING-macro.patch @@ -0,0 +1,103 @@ +From 704623dfde43da98ffb354b3d7f450cd012a8215 Mon Sep 17 00:00:00 2001 +From: Youling Tang +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 +Signed-off-by: Lianbo Jiang +--- + 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 + diff --git a/0006-MIPS32-64-Add-irq-command-support.patch b/0006-MIPS32-64-Add-irq-command-support.patch new file mode 100644 index 0000000..f6d1c8d --- /dev/null +++ b/0006-MIPS32-64-Add-irq-command-support.patch @@ -0,0 +1,81 @@ +From 859d1c0e8a6618634cbc1fe7ee2b082a6a3c99a1 Mon Sep 17 00:00:00 2001 +From: Youling Tang +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 +Signed-off-by: Lianbo Jiang +--- + 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 + diff --git a/0007-MIPS64-three-fixes-for-MIPS64-kernels.patch b/0007-MIPS64-three-fixes-for-MIPS64-kernels.patch new file mode 100644 index 0000000..05abd42 --- /dev/null +++ b/0007-MIPS64-three-fixes-for-MIPS64-kernels.patch @@ -0,0 +1,67 @@ +From c15a1e025e62134094ba0ac600263d75673d5a22 Mon Sep 17 00:00:00 2001 +From: Youling Tang +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 +Signed-off-by: Kazuhito Hagio +Signed-off-by: Lianbo Jiang +--- + 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 + diff --git a/0008-extensions-eppic.mk-Enable-use-of-alternate-eppic-br.patch b/0008-extensions-eppic.mk-Enable-use-of-alternate-eppic-br.patch new file mode 100644 index 0000000..f6c9636 --- /dev/null +++ b/0008-extensions-eppic.mk-Enable-use-of-alternate-eppic-br.patch @@ -0,0 +1,36 @@ +From e61841a8b86ac551c314f74f4b82daae84f99700 Mon Sep 17 00:00:00 2001 +From: Luc Chouinard +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 +--- + 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 + diff --git a/0009-list-add-O-option-for-specifying-head-node-offset.patch b/0009-list-add-O-option-for-specifying-head-node-offset.patch new file mode 100644 index 0000000..c687af1 --- /dev/null +++ b/0009-list-add-O-option-for-specifying-head-node-offset.patch @@ -0,0 +1,156 @@ +From f091b5e76d2d6e81b12cd40df7b5863c9e2efed1 Mon Sep 17 00:00:00 2001 +From: Firo Yang +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 +Signed-off-by: Kazuhito Hagio +Signed-off-by: Lianbo Jiang +--- + 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 + diff --git a/0010-Fix-waitq-command-for-Linux-4.13-and-later-kernels.patch b/0010-Fix-waitq-command-for-Linux-4.13-and-later-kernels.patch new file mode 100644 index 0000000..3cdbc46 --- /dev/null +++ b/0010-Fix-waitq-command-for-Linux-4.13-and-later-kernels.patch @@ -0,0 +1,132 @@ +From eaf14f852ae79f7745934e213661f1c6abac711e Mon Sep 17 00:00:00 2001 +From: Greg Edwards +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 +Signed-off-by: Kazuhito Hagio +Signed-off-by: Lianbo Jiang +--- + 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 + diff --git a/0011-Fix-pvops-Xen-detection-for-kernels-v4.20.patch b/0011-Fix-pvops-Xen-detection-for-kernels-v4.20.patch new file mode 100644 index 0000000..203359a --- /dev/null +++ b/0011-Fix-pvops-Xen-detection-for-kernels-v4.20.patch @@ -0,0 +1,90 @@ +From 4badc6229c69f5cd9da7eb7bdf400a53ec6db01a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20Tesa=C5=99=C3=ADk?= +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 +Signed-off-by: Lianbo Jiang +--- + 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 + diff --git a/0012-Handle-task_struct-state-member-changes-for-kernels-.patch b/0012-Handle-task_struct-state-member-changes-for-kernels-.patch new file mode 100644 index 0000000..c58bfc3 --- /dev/null +++ b/0012-Handle-task_struct-state-member-changes-for-kernels-.patch @@ -0,0 +1,77 @@ +From d6b4f36d6b22b70fb14e692f36d20910ef5563c1 Mon Sep 17 00:00:00 2001 +From: Alexander Egorenkov +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 +Signed-off-by: Lianbo Jiang +--- + 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 + diff --git a/0013-arm64-rename-ARM64_PAGE_OFFSET_ACTUAL-to-ARM64_FLIP_.patch b/0013-arm64-rename-ARM64_PAGE_OFFSET_ACTUAL-to-ARM64_FLIP_.patch new file mode 100644 index 0000000..21b77bf --- /dev/null +++ b/0013-arm64-rename-ARM64_PAGE_OFFSET_ACTUAL-to-ARM64_FLIP_.patch @@ -0,0 +1,62 @@ +From 5719afc7a40868418405a87a2711088556e68a3b Mon Sep 17 00:00:00 2001 +From: Pingfan Liu +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 +Signed-off-by: Lianbo Jiang +--- + 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 + diff --git a/0014-arm64-assign-page_offset-with-VA_BITS-kernel-configu.patch b/0014-arm64-assign-page_offset-with-VA_BITS-kernel-configu.patch new file mode 100644 index 0000000..65c2f8e --- /dev/null +++ b/0014-arm64-assign-page_offset-with-VA_BITS-kernel-configu.patch @@ -0,0 +1,57 @@ +From 167d37e347fe35c6f7db826e8539e192c4375564 Mon Sep 17 00:00:00 2001 +From: Pingfan Liu +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 +Signed-off-by: Lianbo Jiang +--- + 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 + diff --git a/0015-arm64-use-dedicated-bits-to-record-the-VA-space-layo.patch b/0015-arm64-use-dedicated-bits-to-record-the-VA-space-layo.patch new file mode 100644 index 0000000..58e655e --- /dev/null +++ b/0015-arm64-use-dedicated-bits-to-record-the-VA-space-layo.patch @@ -0,0 +1,84 @@ +From bf1379a8b6ff8d6a8fa12978f7194f15f85c4380 Mon Sep 17 00:00:00 2001 +From: Pingfan Liu +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 +Signed-off-by: Lianbo Jiang +--- + 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 + diff --git a/0016-arm64-implement-switchable-PTOV-VTOP-for-kernels-5.1.patch b/0016-arm64-implement-switchable-PTOV-VTOP-for-kernels-5.1.patch new file mode 100644 index 0000000..7b3a4e4 --- /dev/null +++ b/0016-arm64-implement-switchable-PTOV-VTOP-for-kernels-5.1.patch @@ -0,0 +1,166 @@ +From f53b73e8380bca054cebd2b61ff118c46609429b Mon Sep 17 00:00:00 2001 +From: Pingfan Liu +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 + + + + 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 + + + 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 +Signed-off-by: Lianbo Jiang +--- + 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 + diff --git a/crash.spec b/crash.spec index e255302..0a0357f 100644 --- a/crash.spec +++ b/crash.spec @@ -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 - 7.3.0-2 +- Update to the latest upstream + * Fri May 07 2021 Lianbo Jiang - 7.3.0-1 - Rebase to upstream 7.3.0