Rebase to upstream crash-8.0.5 f615f8fab7bf3

Release: crash-8.0.5-5

Resolves: RHEL-33667

Signed-off-by: Tao Liu <ltao@redhat.com>
This commit is contained in:
Tao Liu 2024-08-07 15:56:38 +12:00
parent af40e9be44
commit 3f5a509172
6 changed files with 652 additions and 1 deletions

View File

@ -0,0 +1,68 @@
From af895b219876b293d551e6dec825aba3905c0588 Mon Sep 17 00:00:00 2001
From: "qiwu.chen" <qiwu.chen@transsion.com>
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 <qiwu.chen@transsion.com>
---
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

View File

@ -0,0 +1,126 @@
From 1c6da3eaff820708d4286324051d153a01766b02 Mon Sep 17 00:00:00 2001
From: bevis_chen <bevis_chen@asus.com>
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 <asm/pointer_auth.h>")
Signed-off-by: bevis_chen <bevis_chen@asus.com>
---
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

View File

@ -0,0 +1,261 @@
From 93d7f647c45b80b584db815f78b7130508642c60 Mon Sep 17 00:00:00 2001
From: Kuan-Ying Lee <kuan-ying.lee@canonical.com>
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 <kuan-ying.lee@canonical.com>
---
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

View File

@ -0,0 +1,44 @@
From 38f26cc8b9304e79e7f8adb5fd8e6a533c70cfd2 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
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 <lijiang@redhat.com>
---
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

View File

@ -0,0 +1,139 @@
From f615f8fab7bf3d2d5d5cb00518124a06e6846be4 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
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 <ltao@redhat.com>
---
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

View File

@ -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 <ltao@redhat.com> - 8.0.5-5
- Rebase to upstream crash 8.0.5 f615f8fab7bf3
* Wed Jul 3 2024 Tao Liu <ltao@redhat.com> - 8.0.5-4
- Rebase to upstream crash 8.0.5 ce4ddc742fbdd