From 3f5a50917235a2de9380b1b43b93b35a121b2e70 Mon Sep 17 00:00:00 2001 From: Tao Liu Date: Wed, 7 Aug 2024 15:56:38 +1200 Subject: [PATCH] Rebase to upstream crash-8.0.5 f615f8fab7bf3 Release: crash-8.0.5-5 Resolves: RHEL-33667 Signed-off-by: Tao Liu --- ...potential-segfault-when-unwind-frame.patch | 68 +++++ ...mand-show-wrong-stacktrace-on-ramdum.patch | 126 +++++++++ ...on-of-support-for-16K-page-with-3-le.patch | 261 ++++++++++++++++++ ...rch64-fix-incorrect-code-in-the-main.patch | 44 +++ ...q-a-exceeding-the-memory-range-issue.patch | 139 ++++++++++ crash.spec | 15 +- 6 files changed, 652 insertions(+), 1 deletion(-) create mode 100644 0001-arm64-fix-a-potential-segfault-when-unwind-frame.patch create mode 100644 0002-arm64-Fix-bt-command-show-wrong-stacktrace-on-ramdum.patch create mode 100644 0003-arm64-Introduction-of-support-for-16K-page-with-3-le.patch create mode 100644 0004-LoongArch64-fix-incorrect-code-in-the-main.patch create mode 100644 0005-Fix-irq-a-exceeding-the-memory-range-issue.patch diff --git a/0001-arm64-fix-a-potential-segfault-when-unwind-frame.patch b/0001-arm64-fix-a-potential-segfault-when-unwind-frame.patch new file mode 100644 index 0000000..e474730 --- /dev/null +++ b/0001-arm64-fix-a-potential-segfault-when-unwind-frame.patch @@ -0,0 +1,68 @@ +From af895b219876b293d551e6dec825aba3905c0588 Mon Sep 17 00:00:00 2001 +From: "qiwu.chen" +Date: Wed, 24 Jul 2024 01:36:09 +0000 +Subject: [PATCH 1/5] arm64: fix a potential segfault when unwind frame + +The range of frame->fp is checked insufficiently, which may lead to a wrong +next fp. As a result, bt->stackbuf will be accessed out of range, and segfault. + + crash> bt + [Detaching after fork from child process 11409] + PID: 7661 TASK: ffffff81858aa500 CPU: 4 COMMAND: "sh" + #0 [ffffffc008003f50] local_cpu_stop at ffffffdd7669444c + + Thread 1 "crash" received signal SIGSEGV, Segmentation fault. + 0x00005555558266cc in arm64_unwind_frame (bt=0x7fffffffd8f0, frame=0x7fffffffd080) at + arm64.c:2821 + 2821 frame->fp = GET_STACK_ULONG(fp); + (gdb) bt + arm64.c:2821 + out>) at main.c:1338 + gdb_interface.c:81 + (gdb) p /x *(struct bt_info*) 0x7fffffffd8f0 + $3 = {task = 0xffffff81858aa500, flags = 0x0, instptr = 0xffffffdd76694450, stkptr = + 0xffffffc008003f40, bptr = 0x0, stackbase = 0xffffffc027288000, + stacktop = 0xffffffc02728c000, stackbuf = 0x555556115a40, tc = 0x55559d16fdc0, hp = 0x0, + textlist = 0x0, ref = 0x0, frameptr = 0xffffffc008003f50, + call_target = 0x0, machdep = 0x0, debug = 0x0, eframe_ip = 0x0, radix = 0x0, cpumask = + 0x0} + (gdb) p /x *(struct arm64_stackframe*) 0x7fffffffd080 + $4 = {fp = 0xffffffc008003f50, sp = 0xffffffc008003f60, pc = 0xffffffdd76694450} + crash> bt -S 0xffffffc008003f50 + PID: 7661 TASK: ffffff81858aa500 CPU: 4 COMMAND: "sh" + bt: non-process stack address for this task: ffffffc008003f50 + (valid range: ffffffc027288000 - ffffffc02728c000) + +Check frame->fp value sufficiently before access it. Only frame->fp within +the range of bt->stackbase and bt->stacktop will be regarded as valid. + +Signed-off-by: qiwu.chen +--- + arm64.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arm64.c b/arm64.c +index b3040d7..624dba2 100644 +--- a/arm64.c ++++ b/arm64.c +@@ -2814,7 +2814,7 @@ arm64_unwind_frame(struct bt_info *bt, struct arm64_stackframe *frame) + low = frame->sp; + high = (low + stack_mask) & ~(stack_mask); + +- if (fp < low || fp > high || fp & 0xf) ++ if (fp < low || fp > high || fp & 0xf || !INSTACK(fp, bt)) + return FALSE; + + frame->sp = fp + 0x10; +@@ -3024,7 +3024,7 @@ arm64_unwind_frame_v2(struct bt_info *bt, struct arm64_stackframe *frame, + low = frame->sp; + high = (low + stack_mask) & ~(stack_mask); + +- if (fp < low || fp > high || fp & 0xf) ++ if (fp < low || fp > high || fp & 0xf || !INSTACK(fp, bt)) + return FALSE; + + if (CRASHDEBUG(1)) +-- +2.40.1 + diff --git a/0002-arm64-Fix-bt-command-show-wrong-stacktrace-on-ramdum.patch b/0002-arm64-Fix-bt-command-show-wrong-stacktrace-on-ramdum.patch new file mode 100644 index 0000000..f7297e5 --- /dev/null +++ b/0002-arm64-Fix-bt-command-show-wrong-stacktrace-on-ramdum.patch @@ -0,0 +1,126 @@ +From 1c6da3eaff820708d4286324051d153a01766b02 Mon Sep 17 00:00:00 2001 +From: bevis_chen +Date: Thu, 25 Jul 2024 09:38:59 +0800 +Subject: [PATCH 2/5] arm64: Fix bt command show wrong stacktrace on ramdump + source + +For ramdump(Qcom phone device) case with the kernel option +CONFIG_ARM64_PTR_AUTH_KERNEL enabled, the bt command may print +incorrect stacktrace as below: + + crash> bt 16930 + PID: 16930 TASK: ffffff89b3eada00 CPU: 2 COMMAND: "Firebase Backgr" + #0 [ffffffc034c437f0] __switch_to at ffffffe0036832d4 + #1 [ffffffc034c43850] __kvm_nvhe_$d.2314 at 6be732e004cf05a0 + #2 [ffffffc034c438b0] __kvm_nvhe_$d.2314 at 86c54c6004ceff80 + #3 [ffffffc034c43950] __kvm_nvhe_$d.2314 at 55d6f96003a7b120 + ... + PC: 00000073f5294840 LR: 00000070d8f39ba4 SP: 00000070d4afd5d0 + X29: 00000070d4afd600 X28: b4000071efcda7f0 X27: 00000070d4afe000 + X26: 0000000000000000 X25: 00000070d9616000 X24: 0000000000000000 + X23: 0000000000000000 X22: 0000000000000000 X21: 0000000000000000 + X20: b40000728fd27520 X19: b40000728fd27550 X18: 000000702daba000 + X17: 00000073f5294820 X16: 00000070d940f9d8 X15: 00000000000000bf + X14: 0000000000000000 X13: 00000070d8ad2fac X12: b40000718fce5040 + X11: 0000000000000000 X10: 0000000000000070 X9: 0000000000000001 + X8: 0000000000000062 X7: 0000000000000020 X6: 0000000000000000 + X5: 0000000000000000 X4: 0000000000000000 X3: 0000000000000000 + X2: 0000000000000002 X1: 0000000000000080 X0: b40000728fd27550 + ORIG_X0: b40000728fd27550 SYSCALLNO: ffffffff PSTATE: 40001000 + +Crash tool can not get the KERNELPACMASK value from the vmcoreinfo, need +to calculate its value based on the vabits. + +With the patch: + + crash> bt 16930 + PID: 16930 TASK: ffffff89b3eada00 CPU: 2 COMMAND: "Firebase Backgr" + #0 [ffffffc034c437f0] __switch_to at ffffffe0036832d4 + #1 [ffffffc034c43850] __schedule at ffffffe004cf05a0 + #2 [ffffffc034c438b0] preempt_schedule_common at ffffffe004ceff80 + #3 [ffffffc034c43950] unmap_page_range at ffffffe003a7b120 + #4 [ffffffc034c439f0] unmap_vmas at ffffffe003a80a64 + #5 [ffffffc034c43ac0] exit_mmap at ffffffe003a945c4 + #6 [ffffffc034c43b10] __mmput at ffffffe00372c818 + #7 [ffffffc034c43b40] mmput at ffffffe00372c0d0 + #8 [ffffffc034c43b90] exit_mm at ffffffe00373d0ac + #9 [ffffffc034c43c00] do_exit at ffffffe00373bedc + PC: 00000073f5294840 LR: 00000070d8f39ba4 SP: 00000070d4afd5d0 + X29: 00000070d4afd600 X28: b4000071efcda7f0 X27: 00000070d4afe000 + X26: 0000000000000000 X25: 00000070d9616000 X24: 0000000000000000 + X23: 0000000000000000 X22: 0000000000000000 X21: 0000000000000000 + X20: b40000728fd27520 X19: b40000728fd27550 X18: 000000702daba000 + X17: 00000073f5294820 X16: 00000070d940f9d8 X15: 00000000000000bf + X14: 0000000000000000 X13: 00000070d8ad2fac X12: b40000718fce5040 + X11: 0000000000000000 X10: 0000000000000070 X9: 0000000000000001 + X8: 0000000000000062 X7: 0000000000000020 X6: 0000000000000000 + X5: 0000000000000000 X4: 0000000000000000 X3: 0000000000000000 + X2: 0000000000000002 X1: 0000000000000080 X0: b40000728fd27550 + ORIG_X0: b40000728fd27550 SYSCALLNO: ffffffff PSTATE: 40001000 + +Related kernel commits: +689eae42afd7 ("arm64: mask PAC bits of __builtin_return_address") +de1702f65feb ("arm64: move PAC masks to ") + +Signed-off-by: bevis_chen +--- + arm64.c | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +diff --git a/arm64.c b/arm64.c +index 624dba2..78e6609 100644 +--- a/arm64.c ++++ b/arm64.c +@@ -92,6 +92,7 @@ static void arm64_get_crash_notes(void); + static void arm64_calc_VA_BITS(void); + static int arm64_is_uvaddr(ulong, struct task_context *); + static void arm64_calc_KERNELPACMASK(void); ++static void arm64_recalc_KERNELPACMASK(void); + static int arm64_get_vmcoreinfo(unsigned long *vaddr, const char *label, int base); + + struct kernel_range { +@@ -581,6 +582,16 @@ arm64_init(int when) + if (!machdep->hz) + machdep->hz = 100; + ++ ++ /* ++ * Let's calculate the KERNELPACMASK value based on the ++ * vabits, see: ++ * arch/arm64/kernel/vmcore_info.c ++ * arch/arm64/include/asm/pointer_auth.h ++ */ ++ if(!machdep->machspec->CONFIG_ARM64_KERNELPACMASK) ++ arm64_recalc_KERNELPACMASK(); ++ + arm64_irq_stack_init(); + arm64_overflow_stack_init(); + arm64_stackframe_init(); +@@ -4921,6 +4932,24 @@ static void arm64_calc_KERNELPACMASK(void) + } + } + ++#define GENMASK_UL(h, l) \ ++ (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) ++ ++static void arm64_recalc_KERNELPACMASK(void){ ++ /* ++ * Check if PAC is enabled according to the existence of ++ * kernel symbol 'ptrauth_keys_kernel'. ++ */ ++ if (STRUCT_EXISTS("ptrauth_keys_kernel") && ++ machdep->machspec->VA_BITS_ACTUAL){ ++ machdep->machspec->CONFIG_ARM64_KERNELPACMASK = ++ GENMASK_UL(63, machdep->machspec->VA_BITS_ACTUAL); ++ if (CRASHDEBUG(1)) ++ fprintf(fp, "CONFIG_ARM64_KERNELPACMASK: %lx\n", ++ machdep->machspec->CONFIG_ARM64_KERNELPACMASK); ++ } ++} ++ + #endif /* ARM64 */ + + +-- +2.40.1 + diff --git a/0003-arm64-Introduction-of-support-for-16K-page-with-3-le.patch b/0003-arm64-Introduction-of-support-for-16K-page-with-3-le.patch new file mode 100644 index 0000000..8019c4a --- /dev/null +++ b/0003-arm64-Introduction-of-support-for-16K-page-with-3-le.patch @@ -0,0 +1,261 @@ +From 93d7f647c45b80b584db815f78b7130508642c60 Mon Sep 17 00:00:00 2001 +From: Kuan-Ying Lee +Date: Sat, 13 Jul 2024 21:22:52 +0800 +Subject: [PATCH 3/5] arm64: Introduction of support for 16K page with 3-level + table support + +Introduction of ARM64 support for 16K page size with 3-level page +table and 47 VA bits. + +Signed-off-by: Kuan-Ying Lee +--- + arm64.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- + defs.h | 16 ++++++++ + 2 files changed, 126 insertions(+), 4 deletions(-) + +diff --git a/arm64.c b/arm64.c +index 78e6609..067c879 100644 +--- a/arm64.c ++++ b/arm64.c +@@ -42,6 +42,7 @@ static int arm64_kvtop(struct task_context *, ulong, physaddr_t *, int); + static int arm64_uvtop(struct task_context *, ulong, physaddr_t *, int); + static int arm64_vtop_2level_64k(ulong, ulong, physaddr_t *, int); + static int arm64_vtop_3level_64k(ulong, ulong, physaddr_t *, int); ++static int arm64_vtop_3level_16k(ulong, ulong, physaddr_t *, int); + static int arm64_vtop_3level_4k(ulong, ulong, physaddr_t *, int); + static int arm64_vtop_4level_4k(ulong, ulong, physaddr_t *, int); + static ulong arm64_get_task_pgd(ulong); +@@ -262,8 +263,7 @@ arm64_init(int when) + machdep->pagesize = 4096; + break; + case 2: +- /* TODO: machdep->pagesize = 16384; */ +- error(FATAL, "16K pages not supported."); ++ machdep->pagesize = 16384; + break; + case 3: + machdep->pagesize = 65536; +@@ -393,6 +393,26 @@ arm64_init(int when) + error(FATAL, "cannot malloc ptbl space."); + break; + ++ case 16384: ++ if (machdep->machspec->VA_BITS > PGDIR_SHIFT_L3_16K) { ++ machdep->flags |= VM_L3_16K; ++ if (!machdep->ptrs_per_pgd) ++ machdep->ptrs_per_pgd = PTRS_PER_PGD_L3_16K; ++ if ((machdep->pgd = ++ (char *)malloc(machdep->ptrs_per_pgd * 8)) == NULL) ++ error(FATAL, "cannot malloc pgd space."); ++ if ((machdep->pmd = ++ (char *)malloc(PTRS_PER_PMD_L3_16K * 8)) == NULL) ++ error(FATAL, "cannot malloc pmd space."); ++ if ((machdep->ptbl = ++ (char *)malloc(PTRS_PER_PTE_L3_16K * 8)) == NULL) ++ error(FATAL, "cannot malloc ptbl space."); ++ } else { ++ error(FATAL, "we only support 47 bits, 3 level for 16K page now."); ++ } ++ machdep->pud = NULL; /* not used */ ++ break; ++ + case 65536: + if (kernel_symbol_exists("idmap_ptrs_per_pgd") && + readmem(symbol_value("idmap_ptrs_per_pgd"), KVADDR, +@@ -1029,6 +1049,8 @@ arm64_dump_machdep_table(ulong arg) + fprintf(fp, "%sVM_L2_64K", others++ ? "|" : ""); + if (machdep->flags & VM_L3_64K) + fprintf(fp, "%sVM_L3_64K", others++ ? "|" : ""); ++ if (machdep->flags & VM_L3_16K) ++ fprintf(fp, "%sVM_L3_16K", others++ ? "|" : ""); + if (machdep->flags & VM_L3_4K) + fprintf(fp, "%sVM_L3_4K", others++ ? "|" : ""); + if (machdep->flags & VM_L4_4K) +@@ -1076,6 +1098,8 @@ arm64_dump_machdep_table(ulong arg) + "arm64_vtop_3level_4k" : + machdep->flags & VM_L4_4K ? + "arm64_vtop_4level_4k" : ++ machdep->flags & VM_L3_16K ? ++ "arm64_vtop_3level_16k" : + machdep->flags & VM_L3_64K ? + "arm64_vtop_3level_64k" : "arm64_vtop_2level_64k"); + fprintf(fp, " kvtop: arm64_kvtop()->%s()\n", +@@ -1083,6 +1107,8 @@ arm64_dump_machdep_table(ulong arg) + "arm64_vtop_3level_4k" : + machdep->flags & VM_L4_4K ? + "arm64_vtop_4level_4k" : ++ machdep->flags & VM_L3_16K ? ++ "arm64_vtop_3level_16k" : + machdep->flags & VM_L3_64K ? + "arm64_vtop_3level_64k" : "arm64_vtop_2level_64k"); + fprintf(fp, " get_task_pgd: arm64_get_task_pgd()\n"); +@@ -1118,6 +1144,7 @@ arm64_dump_machdep_table(ulong arg) + fprintf(fp, " last_pgd_read: %lx\n", machdep->last_pgd_read); + fprintf(fp, " last_pud_read: "); + if ((PAGESIZE() == 65536) || ++ (PAGESIZE() == 16384) || + ((PAGESIZE() == 4096) && !(machdep->flags & VM_L4_4K))) + fprintf(fp, "(not used)\n"); + else +@@ -1772,7 +1799,7 @@ arm64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbos + kernel_pgd = vt->kernel_pgd[0]; + *paddr = 0; + +- switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K)) ++ switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K|VM_L3_16K)) + { + case VM_L2_64K: + return arm64_vtop_2level_64k(kernel_pgd, kvaddr, paddr, verbose); +@@ -1782,6 +1809,8 @@ arm64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbos + return arm64_vtop_3level_4k(kernel_pgd, kvaddr, paddr, verbose); + case VM_L4_4K: + return arm64_vtop_4level_4k(kernel_pgd, kvaddr, paddr, verbose); ++ case VM_L3_16K: ++ return arm64_vtop_3level_16k(kernel_pgd, kvaddr, paddr, verbose); + default: + return FALSE; + } +@@ -1797,7 +1826,7 @@ arm64_uvtop(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, int verbos + + *paddr = 0; + +- switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K)) ++ switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K|VM_L3_16K)) + { + case VM_L2_64K: + return arm64_vtop_2level_64k(user_pgd, uvaddr, paddr, verbose); +@@ -1807,6 +1836,8 @@ arm64_uvtop(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, int verbos + return arm64_vtop_3level_4k(user_pgd, uvaddr, paddr, verbose); + case VM_L4_4K: + return arm64_vtop_4level_4k(user_pgd, uvaddr, paddr, verbose); ++ case VM_L3_16K: ++ return arm64_vtop_3level_16k(user_pgd, uvaddr, paddr, verbose); + default: + return FALSE; + } +@@ -1823,6 +1854,7 @@ arm64_uvtop(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, int verbos + #define PMD_TYPE_SECT 1 + #define PMD_TYPE_TABLE 2 + #define SECTION_PAGE_MASK_2MB ((long)(~((MEGABYTES(2))-1))) ++#define SECTION_PAGE_MASK_32MB ((long)(~((MEGABYTES(32))-1))) + #define SECTION_PAGE_MASK_512MB ((long)(~((MEGABYTES(512))-1))) + #define SECTION_PAGE_MASK_1GB ((long)(~((GIGABYTES(1))-1))) + +@@ -1965,6 +1997,80 @@ no_page: + return FALSE; + } + ++static int ++arm64_vtop_3level_16k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose) ++{ ++ ulong *pgd_base, *pgd_ptr, pgd_val; ++ ulong *pmd_base, *pmd_ptr, pmd_val; ++ ulong *pte_base, *pte_ptr, pte_val; ++ ++ if (verbose) ++ fprintf(fp, "PAGE DIRECTORY: %lx\n", pgd); ++ ++ pgd_base = (ulong *)pgd; ++ FILL_PGD(pgd_base, KVADDR, machdep->ptrs_per_pgd * sizeof(ulong)); ++ pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L3_16K) & (machdep->ptrs_per_pgd - 1)); ++ pgd_val = ULONG(machdep->pgd + PGDIR_OFFSET_L3_16K(pgd_ptr)); ++ if (verbose) ++ fprintf(fp, " PGD: %lx => %lx\n", (ulong)pgd_ptr, pgd_val); ++ if (!pgd_val) ++ goto no_page; ++ ++ /* ++ * #define __PAGETABLE_PUD_FOLDED ++ */ ++ ++ pmd_base = (ulong *)PTOV(PTE_TO_PHYS(pgd_val)); ++ FILL_PMD(pmd_base, KVADDR, PTRS_PER_PMD_L3_16K * sizeof(ulong)); ++ pmd_ptr = pmd_base + (((vaddr) >> PMD_SHIFT_L3_16K) & (PTRS_PER_PMD_L3_16K - 1)); ++ pmd_val = ULONG(machdep->pmd + PAGEOFFSET(pmd_ptr)); ++ if (verbose) ++ fprintf(fp, " PMD: %lx => %lx\n", (ulong)pmd_ptr, pmd_val); ++ if (!pmd_val) ++ goto no_page; ++ ++ if ((pmd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) { ++ ulong sectionbase = PTE_TO_PHYS(pmd_val) & SECTION_PAGE_MASK_32MB; ++ if (verbose) { ++ fprintf(fp, " PAGE: %lx (32MB%s)\n\n", sectionbase, ++ IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" : ""); ++ arm64_translate_pte(pmd_val, 0, 0); ++ } ++ *paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_32MB); ++ return TRUE; ++ } ++ ++ pte_base = (ulong *)PTOV(PTE_TO_PHYS(pmd_val)); ++ FILL_PTBL(pte_base, KVADDR, PTRS_PER_PTE_L3_16K * sizeof(ulong)); ++ pte_ptr = pte_base + (((vaddr) >> machdep->pageshift) & (PTRS_PER_PTE_L3_16K - 1)); ++ pte_val = ULONG(machdep->ptbl + PAGEOFFSET(pte_ptr)); ++ if (verbose) ++ fprintf(fp, " PTE: %lx => %lx\n", (ulong)pte_ptr, pte_val); ++ if (!pte_val) ++ goto no_page; ++ ++ if (pte_val & PTE_VALID) { ++ *paddr = PTE_TO_PHYS(pte_val) + PAGEOFFSET(vaddr); ++ if (verbose) { ++ fprintf(fp, " PAGE: %lx %s\n\n", PAGEBASE(*paddr), ++ IS_ZEROPAGE(PAGEBASE(*paddr)) ? "(ZERO PAGE)" : ""); ++ arm64_translate_pte(pte_val, 0, 0); ++ } ++ } else { ++ if (IS_UVADDR(vaddr, NULL)) ++ *paddr = pte_val; ++ if (verbose) { ++ fprintf(fp, "\n"); ++ arm64_translate_pte(pte_val, 0, 0); ++ } ++ goto no_page; ++ } ++ ++ return TRUE; ++no_page: ++ return FALSE; ++} ++ + static int + arm64_vtop_3level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose) + { +diff --git a/defs.h b/defs.h +index 49e6923..1b7649d 100644 +--- a/defs.h ++++ b/defs.h +@@ -3302,6 +3302,21 @@ typedef signed int s32; + #define PGDIR_MASK_48VA (~(PGDIR_SIZE_48VA - 1)) + #define PGDIR_OFFSET_48VA(X) (((ulong)(X)) & (PGDIR_SIZE_48VA - 1)) + ++/* ++ * 3-levels / 16K pages ++ * 47-bit VA ++ */ ++#define PTRS_PER_PGD_L3_16K ((1UL) << (47 - 36)) ++#define PTRS_PER_PMD_L3_16K (2048) ++#define PTRS_PER_PTE_L3_16K (2048) ++#define PGDIR_SHIFT_L3_16K (36) ++#define PGDIR_SIZE_L3_16K ((1UL) << PGDIR_SHIFT_L3_16K) ++#define PGDIR_MASK_L3_16K (~(PGDIR_SIZE_L3_16K-1)) ++#define PMD_SHIFT_L3_16K (25) ++#define PMD_SIZE_L3_16K (1UL << PMD_SHIFT_L3_16K) ++#define PMD_MASK_L3_16K (~(PMD_SIZE_L3_16K-1)) ++#define PGDIR_OFFSET_L3_16K(X) (((ulong)(X)) & ((machdep->ptrs_per_pgd * 8) - 1)) ++ + /* + * 3-levels / 64K pages + */ +@@ -3367,6 +3382,7 @@ typedef signed int s32; + #define HAS_PHYSVIRT_OFFSET (0x800) + #define OVERFLOW_STACKS (0x1000) + #define ARM64_MTE (0x2000) ++#define VM_L3_16K (0x4000) + + /* + * Get kimage_voffset from /dev/crash +-- +2.40.1 + diff --git a/0004-LoongArch64-fix-incorrect-code-in-the-main.patch b/0004-LoongArch64-fix-incorrect-code-in-the-main.patch new file mode 100644 index 0000000..2986ff5 --- /dev/null +++ b/0004-LoongArch64-fix-incorrect-code-in-the-main.patch @@ -0,0 +1,44 @@ +From 38f26cc8b9304e79e7f8adb5fd8e6a533c70cfd2 Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Tue, 6 Aug 2024 14:31:45 +0800 +Subject: [PATCH 4/5] LoongArch64: fix incorrect code in the main() + +The commit c3939d2e1930 contains incorrect code that starts with "+", +for example: +- !machine_type("S390X") && !machine_type("RISCV64")) ++ !machine_type("S390X") && !machine_type("RISCV64") && +++ !machine_type("LOONGARCH64")) + +See the main() in the main.c +... + } else if (STREQ(long_options[option_index].name, "kaslr")) { + if (!machine_type("X86_64") && + !machine_type("ARM64") && !machine_type("X86") && + !machine_type("S390X") && !machine_type("RISCV64") && ++ !machine_type("LOONGARCH64")) + +Let's remove it from the main(). + +Link: https://lists.crash-utility.osci.io/archives/list/devel@lists.crash-utility.osci.io/message/LH3IRUA6ZDVFZFLWKW5EWR3DKE6MY25Z/ +Fixes: c3939d2e1930 ("LoongArch64: Add "--kaslr" command line option support") +Signed-off-by: Lianbo Jiang +--- + main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/main.c b/main.c +index 0b6b927..71bcc15 100644 +--- a/main.c ++++ b/main.c +@@ -229,7 +229,7 @@ main(int argc, char **argv) + if (!machine_type("X86_64") && + !machine_type("ARM64") && !machine_type("X86") && + !machine_type("S390X") && !machine_type("RISCV64") && +-+ !machine_type("LOONGARCH64")) ++ !machine_type("LOONGARCH64")) + error(INFO, "--kaslr not valid " + "with this machine type.\n"); + else if (STREQ(optarg, "auto")) +-- +2.40.1 + diff --git a/0005-Fix-irq-a-exceeding-the-memory-range-issue.patch b/0005-Fix-irq-a-exceeding-the-memory-range-issue.patch new file mode 100644 index 0000000..4d26f5b --- /dev/null +++ b/0005-Fix-irq-a-exceeding-the-memory-range-issue.patch @@ -0,0 +1,139 @@ +From f615f8fab7bf3d2d5d5cb00518124a06e6846be4 Mon Sep 17 00:00:00 2001 +From: Tao Liu +Date: Wed, 17 Jul 2024 16:17:00 +1200 +Subject: [PATCH 5/5] Fix "irq -a" exceeding the memory range issue + +Previously without the patch, there was an error observed as follows: + + crash> irq -a + IRQ NAME AFFINITY + 0 timer 0-191 + 4 ttyS0 0-23,96-119 + ... + 84 smartpqi 72-73,168 + irq: page excluded: kernel virtual address: ffff97d03ffff000 type: "irq_desc affinity" + +The reason is the reading of irq affinity exceeded the memory range, see +the following debug info: + + Thread 1 "crash" hit Breakpoint 1, generic_get_irq_affinity (irq=85) at kernel.c:7373 + 7375 irq_desc_addr = get_irq_desc_addr(irq); + (gdb) p/x irq_desc_addr + $1 = 0xffff97d03f21e800 + + crash> struct irq_desc 0xffff97d03f21e800 + struct irq_desc { + irq_common_data = { + state_use_accessors = 425755136, + node = 3, + handler_data = 0x0, + msi_desc = 0xffff97ca51b83480, + affinity = 0xffff97d03fffee60, + effective_affinity = 0xffff97d03fffe6c0 + }, + + crash> whatis cpumask_t + typedef struct cpumask { + unsigned long bits[128]; + } cpumask_t; + SIZE: 1024 + +In order to get the affinity, crash will read the memory range 0xffff97d03fffee60 +~ 0xffff97d03fffee60 + 1024(0x400) by line: + + readmem(affinity_ptr, KVADDR, affinity, len, + "irq_desc affinity", FAULT_ON_ERROR); + +However the reading will exceed the effective memory range: + + crash> kmem 0xffff97d03fffee60 + CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME + ffff97c900044400 32 123297 162944 1273 4k kmalloc-32 + SLAB MEMORY NODE TOTAL ALLOCATED FREE + fffffca460ffff80 ffff97d03fffe000 3 128 81 47 + FREE / [ALLOCATED] + [ffff97d03fffee60] + + PAGE PHYSICAL MAPPING INDEX CNT FLAGS + fffffca460ffff80 83fffe000 dead000000000001 ffff97d03fffe340 1 d7ffffe0000800 slab + + crash> kmem ffff97d03ffff000 + PAGE PHYSICAL MAPPING INDEX CNT FLAGS + fffffca460ffffc0 83ffff000 0 0 1 d7ffffe0004000 reserved + + crash> dmesg + ... + [ 0.000000] BIOS-e820: [mem 0x00000000fe000000-0x00000000fe00ffff] reserved + [ 0.000000] BIOS-e820: [mem 0x0000000100000000-0x000000083fffefff] usable + [ 0.000000] BIOS-e820: [mem 0x000000083ffff000-0x000000083fffffff] reserved + ... + +The beginning physical address, aka 0x83fffe000, is located in the usable +area and is readable, however the later physical address, starting from +0x83ffff000, is located in reserved region and not readable. In fact, +the affinity member is allocated by alloc_cpumask_var_node(), for the 192 CPUs +system, the allocated size is only 24, and we can see it is within +the kmalloc-32 slab. So it is incorrect to read 1024 length(given by +STRUCT_SIZE("cpumask_t")), only 24 is enough. + +Since there are plenty of places in crash which takes the value of +STRUCT_SIZE("cpumask_t"), and works fine for the past, this patch will +not modify them all, only the one which encountered this issue(hunk in +kernel.c), and the one with the same DIV_ROUND_UP() (hunk in tools.c). + +Signed-off-by: Tao Liu +--- + kernel.c | 8 +++++--- + tools.c | 10 +++++++--- + 2 files changed, 12 insertions(+), 6 deletions(-) + +diff --git a/kernel.c b/kernel.c +index 8a9d498..adb19ad 100644 +--- a/kernel.c ++++ b/kernel.c +@@ -7362,7 +7362,7 @@ void + generic_get_irq_affinity(int irq) + { + ulong irq_desc_addr; +- long len; ++ long len, len_cpumask; + ulong affinity_ptr; + ulong *affinity; + ulong tmp_addr; +@@ -7382,8 +7382,10 @@ generic_get_irq_affinity(int irq) + if (!action) + return; + +- if ((len = STRUCT_SIZE("cpumask_t")) < 0) +- len = DIV_ROUND_UP(kt->cpus, BITS_PER_LONG) * sizeof(ulong); ++ len = DIV_ROUND_UP(kt->cpus, BITS_PER_LONG) * sizeof(ulong); ++ len_cpumask = STRUCT_SIZE("cpumask_t"); ++ if (len_cpumask > 0) ++ len = len_cpumask > len ? len : len_cpumask; + + affinity = (ulong *)GETBUF(len); + if (VALID_MEMBER(irq_common_data_affinity)) +diff --git a/tools.c b/tools.c +index 1022d57..2b78b95 100644 +--- a/tools.c ++++ b/tools.c +@@ -6718,9 +6718,13 @@ swap64(uint64_t val, int swap) + ulong * + get_cpumask_buf(void) + { +- int cpulen; +- if ((cpulen = STRUCT_SIZE("cpumask_t")) < 0) +- cpulen = DIV_ROUND_UP(kt->cpus, BITS_PER_LONG) * sizeof(ulong); ++ int cpulen, len_cpumask; ++ ++ cpulen = DIV_ROUND_UP(kt->cpus, BITS_PER_LONG) * sizeof(ulong); ++ len_cpumask = STRUCT_SIZE("cpumask_t"); ++ if (len_cpumask > 0) ++ cpulen = len_cpumask > cpulen ? cpulen : len_cpumask; ++ + return (ulong *)GETBUF(cpulen); + } + +-- +2.40.1 + diff --git a/crash.spec b/crash.spec index 9447eb6..96d8f2d 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: 8.0.5 -Release: 4%{?dist} +Release: 5%{?dist} License: GPL-3.0-only Source0: https://github.com/crash-utility/crash/archive/crash-%{version}.tar.gz Source1: http://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.gz @@ -30,6 +30,11 @@ Patch9: 0008-Fix-for-failing-to-load-kernel-module.patch Patch10: 0009-X86-64-fix-a-regression-issue-about-kernel-stack-pad.patch Patch11: 0001-Fix-kmem-i-and-swap-commands-on-Linux-6.10-rc1-and-l.patch Patch12: 0002-List-enable-LIST_HEAD_FORMAT-for-r-option.patch +Patch13: 0001-arm64-fix-a-potential-segfault-when-unwind-frame.patch +Patch14: 0002-arm64-Fix-bt-command-show-wrong-stacktrace-on-ramdum.patch +Patch15: 0003-arm64-Introduction-of-support-for-16K-page-with-3-le.patch +Patch16: 0004-LoongArch64-fix-incorrect-code-in-the-main.patch +Patch17: 0005-Fix-irq-a-exceeding-the-memory-range-issue.patch %description The core analysis suite is a self-contained tool that can be used to @@ -62,6 +67,11 @@ offered by Mission Critical Linux, or the LKCD kernel patch. %patch -P 10 -p1 %patch -P 11 -p1 %patch -P 12 -p1 +%patch -P 13 -p1 +%patch -P 14 -p1 +%patch -P 15 -p1 +%patch -P 16 -p1 +%patch -P 17 -p1 %build @@ -87,6 +97,9 @@ cp -p defs.h %{buildroot}%{_includedir}/crash %{_includedir}/* %changelog +* Wed Aug 7 2024 Tao Liu - 8.0.5-5 +- Rebase to upstream crash 8.0.5 f615f8fab7bf3 + * Wed Jul 3 2024 Tao Liu - 8.0.5-4 - Rebase to upstream crash 8.0.5 ce4ddc742fbdd