diff --git a/0001-arm64-rename-ARM64_PAGE_OFFSET_ACTUAL-to-ARM64_FLIP_.patch b/0001-arm64-rename-ARM64_PAGE_OFFSET_ACTUAL-to-ARM64_FLIP_.patch new file mode 100644 index 0000000000000000000000000000000000000000..532021cc8861f329394d729f5089380527a16427 --- /dev/null +++ b/0001-arm64-rename-ARM64_PAGE_OFFSET_ACTUAL-to-ARM64_FLIP_.patch @@ -0,0 +1,61 @@ +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/0002-arm64-assign-page_offset-with-VA_BITS-kernel-configu.patch b/0002-arm64-assign-page_offset-with-VA_BITS-kernel-configu.patch new file mode 100644 index 0000000000000000000000000000000000000000..6de98e26be587dcb340849d0b80ce7ce22f4d552 --- /dev/null +++ b/0002-arm64-assign-page_offset-with-VA_BITS-kernel-configu.patch @@ -0,0 +1,56 @@ +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/0003-arm64-use-dedicated-bits-to-record-the-VA-space-layo.patch b/0003-arm64-use-dedicated-bits-to-record-the-VA-space-layo.patch new file mode 100644 index 0000000000000000000000000000000000000000..ef35bddb7c8a5539e243eeb1f9b6899b4cd7ac90 --- /dev/null +++ b/0003-arm64-use-dedicated-bits-to-record-the-VA-space-layo.patch @@ -0,0 +1,83 @@ +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/0004-arm64-implement-switchable-PTOV-VTOP-for-kernels-5.1.patch b/0004-arm64-implement-switchable-PTOV-VTOP-for-kernels-5.1.patch new file mode 100644 index 0000000000000000000000000000000000000000..0b3ec7183b82b1d56eb5f2715c1f4c6a8894f681 --- /dev/null +++ b/0004-arm64-implement-switchable-PTOV-VTOP-for-kernels-5.1.patch @@ -0,0 +1,165 @@ +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/add-SDEI-stack-resolution.patch b/add-SDEI-stack-resolution.patch deleted file mode 100644 index bfd04f68ad59ae58cb8c7070a21419d2982627d5..0000000000000000000000000000000000000000 --- a/add-SDEI-stack-resolution.patch +++ /dev/null @@ -1,368 +0,0 @@ -From e43071b6ceaa4fe20c65befe1b5685b68dc9f33f Mon Sep 17 00:00:00 2001 -From: Jialong Chen -Date: Wed, 5 Jun 2019 21:25:34 +0800 -Subject: [PATCH] crash: add SDEI stack resolution -reason: The kernel adds NMI dog detection, and the NMI interrupt stack uses a separate SDEI stack. -When the NMI dog is called, the kernel stack will switch to the sdei stack. -If the crash reads the stack data, the stack data cannot be parsed normally. - -normal call trace as follows: -PID: 55429 TASK: ffff802772e3ae80 CPU: 19 COMMAND: "insmod" - #0 [ffff00000d4e3c70] __crash_kexec at ffff0000081b4ac0 - #1 [ffff00000d4e3e00] panic at ffff0000080ebd0c - #2 [ffff00000d4e3ee0] nmi_panic at ffff0000080eb864 - #3 [ffff00000d4e3f00] watchdog_hardlockup_check at ffff0000081ecd6c - #4 [ffff00000d4e3f40] sdei_watchdog_callback at ffff0000080a411c - #5 [ffff00000d4e3f60] sdei_event_handler at ffff0000087971ec - #6 [ffff00000d4e3f90] __sdei_handler at ffff000008995964 - #7 [ffff00000d4e3ff0] __sdei_asm_handler at ffff0000080862dc ---- --- - #8 [ffff0000ccad3b70] __delay at ffff000008973658 - #9 [ffff0000ccad3ba0] __const_udelay at ffff0000089735e8 -#10 [ffff0000ccad3bb0] init_module at ffff0000009c6038 [test] -#11 [ffff0000ccad3bd0] do_one_initcall at ffff000008084ae0 -#12 [ffff0000ccad3c60] do_init_module at ffff0000081b1418 -#13 [ffff0000ccad3c90] load_module at ffff0000081afc54 -#14 [ffff0000ccad3d80] __se_sys_finit_module at ffff0000081b0134 -#15 [ffff0000ccad3e40] __arm64_sys_finit_module at ffff0000081b01a0 -#16 [ffff0000ccad3e60] el0_svc_common at ffff000008097b44 -#17 [ffff0000ccad3ea0] el0_svc_handler at ffff000008097c34 -#18 [ffff0000ccad3ff0] el0_svc at ffff000008084144 - -Signed-off-by: Jialong Chen ---- - arm64.c | 210 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- - defs.h | 3 + - 2 files changed, 209 insertions(+), 4 deletions(-) - -diff --git a/arm64.c b/arm64.c -index fdf77bd..cc32d9d 100644 ---- a/arm64.c -+++ b/arm64.c -@@ -87,6 +87,10 @@ static void arm64_calc_VA_BITS(void); - static int arm64_is_uvaddr(ulong, struct task_context *); - static void arm64_calc_KERNELPACMASK(void); - -+static int arm64_in_sdei_normal_stack(int cpu, ulong stkptr); -+static void arm64_set_sdei_normal_stack(struct bt_info *bt); -+static void arm64_sdei_stack_init(void); -+static int arm64_in_kdump_text_on_sdei_stack(struct bt_info *bt); - - /* - * Do all necessary machine-specific setup here. This is called several times -@@ -461,6 +465,7 @@ arm64_init(int when) - - arm64_irq_stack_init(); - arm64_stackframe_init(); -+ arm64_sdei_stack_init(); - break; - - case POST_VM: -@@ -1655,6 +1660,70 @@ arm64_irq_stack_init(void) - readmem(p, KVADDR, &(ms->irq_stacks[i]), sizeof(ulong), - "IRQ stack pointer", RETURN_ON_ERROR); - } -+ } -+} -+ -+/* -+ * Gather IRQ stack values. -+ */ -+static void -+arm64_sdei_stack_init(void) -+{ -+ int i; -+ struct syment *sp; -+ struct gnu_request request, *req; -+ struct machine_specific *ms = machdep->machspec; -+ ulong p, sz; -+ req = &request; -+ -+ if (symbol_exists("sdei_stack_normal_ptr") && -+ (sp = per_cpu_symbol_search("sdei_stack_normal_ptr")) && -+ get_symbol_type("sdei_stack_normal_ptr", NULL, req)) { -+ /* v4.14 and later with CONFIG_VMAP_STACK enabled */ -+ if (CRASHDEBUG(1)) { -+ fprintf(fp, "sdei_stack_normal_ptr: \n"); -+ fprintf(fp, " type: %x, %s\n", -+ (int)req->typecode, -+ (req->typecode == TYPE_CODE_PTR) ? -+ "TYPE_CODE_PTR" : "other"); -+ fprintf(fp, " target_typecode: %x, %s\n", -+ (int)req->target_typecode, -+ req->target_typecode == TYPE_CODE_INT ? -+ "TYPE_CODE_INT" : "other"); -+ fprintf(fp, " target_length: %ld\n", -+ req->target_length); -+ fprintf(fp, " length: %ld\n", req->length); -+ } -+ -+ if (!(ms->sdei_stacks = (ulong *)malloc((size_t)(kt->cpus * sizeof(ulong))))) -+ error(FATAL, "cannot malloc irq_stack addresses\n"); -+ -+ /* -+ * Determining the IRQ_STACK_SIZE is tricky, but for now -+ * 4.14 kernel has: -+ * -+ * #define IRQ_STACK_SIZE THREAD_SIZE -+ * -+ * and finding a solid usage of THREAD_SIZE is hard, but: -+ * -+ * union thread_union { -+ * ... -+ * unsigned long stack[THREAD_SIZE/sizeof(long)]; -+ * }; -+ */ -+ if (MEMBER_EXISTS("thread_union", "stack")) { -+ if ((sz = MEMBER_SIZE("thread_union", "stack")) > 0) -+ ms->sdei_stack_size = sz; -+ } else -+ ms->sdei_stack_size = ARM64_IRQ_STACK_SIZE; -+ -+ machdep->flags |= IRQ_STACKS; -+ -+ for (i = 0; i < kt->cpus; i++) { -+ p = kt->__per_cpu_offset[i] + sp->value; -+ readmem(p, KVADDR, &(ms->sdei_stacks[i]), sizeof(ulong), -+ "SDEI stack pointer", RETURN_ON_ERROR); -+ } - } - } - -@@ -2173,7 +2242,7 @@ arm64_unwind_frame(struct bt_info *bt, struct arm64_stackframe *frame) - { - unsigned long high, low, fp; - unsigned long stack_mask; -- unsigned long irq_stack_ptr, orig_sp; -+ unsigned long irq_stack_ptr, orig_sp, sdei_stack_ptr; - struct arm64_pt_regs *ptregs; - struct machine_specific *ms = machdep->machspec; - -@@ -2203,7 +2272,8 @@ arm64_unwind_frame(struct bt_info *bt, struct arm64_stackframe *frame) - - if (machdep->flags & UNW_4_14) { - if ((bt->flags & BT_IRQSTACK) && -- !arm64_on_irq_stack(bt->tc->processor, frame->fp)) { -+ !arm64_on_irq_stack(bt->tc->processor, frame->fp) && -+ !arm64_in_sdei_normal_stack(bt->tc->processor, frame->fp)) { - if (arm64_on_process_stack(bt, frame->fp)) { - arm64_set_process_stack(bt); - -@@ -2243,6 +2313,7 @@ arm64_unwind_frame(struct bt_info *bt, struct arm64_stackframe *frame) - * orig_sp = IRQ_STACK_TO_TASK_STACK(irq_stack_ptr); (pt_regs pointer on process stack) - */ - irq_stack_ptr = ms->irq_stacks[bt->tc->processor] + ms->irq_stack_size - 16; -+ sdei_stack_ptr = ms->sdei_stacks[bt->tc->processor] + ms->sdei_stack_size - 16; - - if (frame->sp == irq_stack_ptr) { - orig_sp = GET_STACK_ULONG(irq_stack_ptr - 8); -@@ -2263,6 +2334,25 @@ arm64_unwind_frame(struct bt_info *bt, struct arm64_stackframe *frame) - frame->fp, INSTACK(frame->fp, bt) ? "" : " (?)"); - return FALSE; - } -+ } else if (frame->sp == sdei_stack_ptr) { -+ orig_sp = GET_STACK_ULONG(sdei_stack_ptr - 8); -+ arm64_set_process_stack(bt); -+ if (INSTACK(orig_sp, bt) && (INSTACK(frame->fp, bt) || (frame->fp == 0))) { -+ ptregs = (struct arm64_pt_regs *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(orig_sp))]; -+ frame->sp = orig_sp; -+ frame->pc = ptregs->pc; -+ bt->bptr = fp; -+ if (CRASHDEBUG(1)) -+ error(INFO, -+ "arm64_unwind_frame: switch stacks: fp: %lx sp: %lx pc: %lx\n", -+ frame->fp, frame->sp, frame->pc); -+ } else { -+ error(WARNING, -+ "arm64_unwind_frame: on IRQ stack: oriq_sp: %lx%s fp: %lx%s\n", -+ orig_sp, INSTACK(orig_sp, bt) ? "" : " (?)", -+ frame->fp, INSTACK(frame->fp, bt) ? "" : " (?)"); -+ return FALSE; -+ } - } - - return TRUE; -@@ -2602,6 +2692,10 @@ arm64_back_trace_cmd(struct bt_info *bt) - arm64_set_irq_stack(bt); - bt->flags |= BT_IRQSTACK; - } -+ if (arm64_in_sdei_normal_stack(bt->tc->processor, bt->bptr)) { -+ arm64_set_sdei_normal_stack(bt); -+ bt->flags |= BT_IRQSTACK; -+ } - stackframe.fp = GET_STACK_ULONG(bt->bptr - 8); - stackframe.pc = GET_STACK_ULONG(bt->bptr); - stackframe.sp = bt->bptr + 8; -@@ -2611,6 +2705,10 @@ arm64_back_trace_cmd(struct bt_info *bt) - arm64_set_irq_stack(bt); - bt->flags |= BT_IRQSTACK; - } -+ if (arm64_in_sdei_normal_stack(bt->tc->processor, bt->hp->esp)) { -+ arm64_set_sdei_normal_stack(bt); -+ bt->flags |= BT_IRQSTACK; -+ } - stackframe.fp = GET_STACK_ULONG(bt->hp->esp - 8); - stackframe.pc = bt->hp->eip ? - bt->hp->eip : GET_STACK_ULONG(bt->hp->esp); -@@ -2621,6 +2719,10 @@ arm64_back_trace_cmd(struct bt_info *bt) - arm64_set_irq_stack(bt); - bt->flags |= BT_IRQSTACK; - } -+ if (arm64_in_sdei_normal_stack(bt->tc->processor, bt->frameptr)) { -+ arm64_set_sdei_normal_stack(bt); -+ bt->flags |= BT_IRQSTACK; -+ } - stackframe.sp = bt->stkptr; - stackframe.pc = bt->instptr; - stackframe.fp = bt->frameptr; -@@ -2682,7 +2784,8 @@ arm64_back_trace_cmd(struct bt_info *bt) - } - - if ((bt->flags & BT_IRQSTACK) && -- !arm64_on_irq_stack(bt->tc->processor, stackframe.fp)) { -+ !arm64_on_irq_stack(bt->tc->processor, stackframe.fp) && -+ !arm64_in_sdei_normal_stack(bt->tc->processor, stackframe.fp)) { - bt->flags &= ~BT_IRQSTACK; - if (arm64_switch_stack(bt, &stackframe, ofp) == USER_MODE) - break; -@@ -2965,6 +3068,81 @@ arm64_in_kdump_text(struct bt_info *bt, struct arm64_stackframe *frame) - } - - static int -+arm64_in_kdump_text_on_sdei_stack(struct bt_info *bt) -+{ -+ int cpu; -+ ulong stackbase; -+ char *stackbuf; -+ ulong *ptr, *start, *base; -+ struct machine_specific *ms; -+ -+ if ((machdep->flags & (IRQ_STACKS|KDUMP_ENABLED)) != (IRQ_STACKS|KDUMP_ENABLED)) -+ return FALSE; -+ -+ ms = machdep->machspec; -+ if (!ms->sdei_stacks) -+ return FALSE; -+ cpu = bt->tc->processor; -+ stackbase = ms->sdei_stacks[cpu]; -+ stackbuf = GETBUF(ms->sdei_stack_size); -+ -+ if (!readmem(stackbase, KVADDR, stackbuf, -+ ms->sdei_stack_size, "IRQ stack contents", RETURN_ON_ERROR)) { -+ error(INFO, "read of IRQ stack at %lx failed\n", stackbase); -+ FREEBUF(stackbuf); -+ return FALSE; -+ } -+ -+ base = (ulong *)stackbuf; -+ start = (ulong *)(stackbuf + ms->sdei_stack_size); -+ -+ for (ptr = start - 8; ptr >= base; ptr--) { -+ if (bt->flags & BT_OPT_BACK_TRACE) { -+ if ((*ptr >= ms->crash_kexec_start) && -+ (*ptr < ms->crash_kexec_end) && -+ INSTACK(*(ptr - 1), bt)) { -+ bt->bptr = ((ulong)(ptr - 1) - (ulong)base) + stackbase; -+ if (CRASHDEBUG(1)) -+ fprintf(fp, "%lx: %lx (crash_kexec on IRQ stack)\n", -+ bt->bptr, *ptr); -+ FREEBUF(stackbuf); -+ return TRUE; -+ } -+ if ((*ptr >= ms->crash_save_cpu_start) && -+ (*ptr < ms->crash_save_cpu_end) && -+ INSTACK(*(ptr - 1), bt)) { -+ bt->bptr = ((ulong)(ptr - 1) - (ulong)base) + stackbase; -+ if (CRASHDEBUG(1)) -+ fprintf(fp, "%lx: %lx (crash_save_cpu on IRQ stack)\n", -+ bt->bptr, *ptr); -+ FREEBUF(stackbuf); -+ return TRUE; -+ } -+ } else { -+ if ((*ptr >= ms->crash_kexec_start) && (*ptr < ms->crash_kexec_end)) { -+ bt->bptr = ((ulong)ptr - (ulong)base) + stackbase; -+ if (CRASHDEBUG(1)) -+ fprintf(fp, "%lx: %lx (crash_kexec on IRQ stack)\n", -+ bt->bptr, *ptr); -+ FREEBUF(stackbuf); -+ return TRUE; -+ } -+ if ((*ptr >= ms->crash_save_cpu_start) && (*ptr < ms->crash_save_cpu_end)) { -+ bt->bptr = ((ulong)ptr - (ulong)base) + stackbase; -+ if (CRASHDEBUG(1)) -+ fprintf(fp, "%lx: %lx (crash_save_cpu on IRQ stack)\n", -+ bt->bptr, *ptr); -+ FREEBUF(stackbuf); -+ return TRUE; -+ } -+ } -+ } -+ -+ FREEBUF(stackbuf); -+ return FALSE; -+} -+ -+static int - arm64_in_kdump_text_on_irq_stack(struct bt_info *bt) - { - int cpu; -@@ -3111,7 +3287,8 @@ try_kernel: - } - - if (arm64_in_kdump_text(bt, frame) || -- arm64_in_kdump_text_on_irq_stack(bt)) -+ arm64_in_kdump_text_on_irq_stack(bt) || -+ arm64_in_kdump_text_on_sdei_stack(bt)) - bt->flags |= BT_KDUMP_ADJUST; - - return TRUE; -@@ -3804,6 +3981,31 @@ arm64_in_alternate_stack(int cpu, ulong stkptr) - return FALSE; - } - -+static int -+arm64_in_sdei_normal_stack(int cpu, ulong stkptr) -+{ -+ struct machine_specific *ms = machdep->machspec; -+ -+ if (!ms->sdei_stack_size || (cpu >= kt->cpus)) -+ return FALSE; -+ -+ if ((stkptr >= ms->sdei_stacks[cpu]) && -+ (stkptr < (ms->sdei_stacks[cpu] + ms->sdei_stack_size))) -+ return TRUE; -+ -+ return FALSE; -+} -+ -+static void -+arm64_set_sdei_normal_stack(struct bt_info *bt) -+{ -+ struct machine_specific *ms = machdep->machspec; -+ -+ bt->stackbase = ms->sdei_stacks[bt->tc->processor]; -+ bt->stacktop = bt->stackbase + ms->sdei_stack_size; -+ alter_stackbuf(bt); -+} -+ - static void - arm64_set_irq_stack(struct bt_info *bt) - { -diff --git a/defs.h b/defs.h -index 9594950..9cd5ffa 100644 ---- a/defs.h -+++ b/defs.h -@@ -3283,6 +3283,9 @@ struct machine_specific { - ulong irq_stack_size; - ulong *irq_stacks; - char *irq_stackbuf; -+ ulong sdei_stack_size; -+ ulong *sdei_stacks; -+ char *sdei_stackbuf; - ulong __irqentry_text_start; - ulong __irqentry_text_end; - /* for exception vector code */ --- -2.13.7 - diff --git a/crash.spec b/crash.spec index a579f53ec5f2689609882a37ab9fa42f34e8022f..73a7fafe3dbfaf262557f31dba05a6cfcb737c9f 100644 --- a/crash.spec +++ b/crash.spec @@ -1,6 +1,6 @@ Name: crash Version: 7.3.0 -Release: 1 +Release: 2 Summary: Linux kernel crash utility. License: GPLv3 URL: https://crash-utility.github.io @@ -9,8 +9,10 @@ Source1: http://ftp.gnu.org/gnu/gdb/gdb-7.6.tar.gz Patch0: lzo_snappy.patch Patch1: use_system_readline_v3.patch - -Patch9000: add-SDEI-stack-resolution.patch +Patch2: 0001-arm64-rename-ARM64_PAGE_OFFSET_ACTUAL-to-ARM64_FLIP_.patch +Patch3: 0002-arm64-assign-page_offset-with-VA_BITS-kernel-configu.patch +Patch4: 0003-arm64-use-dedicated-bits-to-record-the-VA-space-layo.patch +Patch5: 0004-arm64-implement-switchable-PTOV-VTOP-for-kernels-5.1.patch BuildRequires: ncurses-devel zlib-devel lzo-devel snappy-devel BuildRequires: gcc gcc-c++ bison readline-devel m4 @@ -76,6 +78,9 @@ install -D -m 0644 defs.h %{buildroot}%{_includedir}/%{name}/defs.h %{_mandir}/man8/crash.8* %changelog +* Thu Dec 30 2021 zhouwenpei - 7.3.0-2 +- fix seek error "IRQ stack pointer" + * Fri Dec 24 2021 zhouwenpei - 7.3.0-1 - Upgrade version to 7.3.0