Rebase to upstream crash-8.0.5

Release: crash-8.0.5-1

Resolves: RHEL-36577

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
This commit is contained in:
Lianbo Jiang 2024-05-16 17:04:40 +08:00
parent a819e04904
commit 3caa7e97fc
25 changed files with 16 additions and 3133 deletions

1
.gitignore vendored
View File

@ -49,5 +49,6 @@ crash-5.0.6.tar.gz
/crash-8.0.2.tar.gz
/crash-8.0.3.tar.gz
/crash-8.0.4.tar.gz
/crash-8.0.5.tar.gz
/gdb-7.6.tar.gz
/gdb-10.2.tar.gz

View File

@ -1,142 +0,0 @@
From 38acd02c7fc09843ffb10fc2d695cccdd10cc7f6 Mon Sep 17 00:00:00 2001
From: Chengen Du <chengen.du@canonical.com>
Date: Fri, 17 Nov 2023 11:45:33 +0800
Subject: [PATCH 01/14] Fix "rd" command for zram data display in Linux 6.2 and
later
Kernel commit 7ac07a26dea7 ("zram: preparation for multi-zcomp support")
replaced "compressor" member with "comp_algs" in the zram struct.
Without the patch, the "rd" command can triggers the following error:
rd: WARNING: Some pages are swapped out to zram. Please run mod -s zram.
rd: invalid user virtual address: ffff7d23f010 type: "64-bit UVADDR"
Related kernel commit:
84b33bf78889 ("zram: introduce recompress sysfs knob")
Signed-off-by: Chengen Du <chengen.du@canonical.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 1 +
diskdump.c | 47 ++++++++++++++++++++++++++++++-----------------
2 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/defs.h b/defs.h
index 788f63ada739..2cae5b61e589 100644
--- a/defs.h
+++ b/defs.h
@@ -2227,6 +2227,7 @@ struct offset_table { /* stash of commonly-used offsets */
long module_memory_size;
long irq_data_irq;
long zspage_huge;
+ long zram_comp_algs;
};
struct size_table { /* stash of commonly-used sizes */
diff --git a/diskdump.c b/diskdump.c
index 0fe46f4644d0..25054d96313e 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2757,6 +2757,8 @@ diskdump_device_dump_info(FILE *ofp)
static ulong ZRAM_FLAG_SHIFT;
static ulong ZRAM_FLAG_SAME_BIT;
+static ulong ZRAM_COMP_PRIORITY_BIT1;
+static ulong ZRAM_COMP_PRIORITY_MASK;
static void
zram_init(void)
@@ -2765,6 +2767,8 @@ zram_init(void)
MEMBER_OFFSET_INIT(zram_mempoll, "zram", "mem_pool");
MEMBER_OFFSET_INIT(zram_compressor, "zram", "compressor");
+ if (INVALID_MEMBER(zram_compressor))
+ MEMBER_OFFSET_INIT(zram_comp_algs, "zram", "comp_algs");
MEMBER_OFFSET_INIT(zram_table_flag, "zram_table_entry", "flags");
if (INVALID_MEMBER(zram_table_flag))
MEMBER_OFFSET_INIT(zram_table_flag, "zram_table_entry", "value");
@@ -2782,6 +2786,8 @@ zram_init(void)
ZRAM_FLAG_SHIFT = 1 << zram_flag_shift;
ZRAM_FLAG_SAME_BIT = 1 << (zram_flag_shift+1);
+ ZRAM_COMP_PRIORITY_BIT1 = ZRAM_FLAG_SHIFT + 7;
+ ZRAM_COMP_PRIORITY_MASK = 0x3;
if (CRASHDEBUG(1))
fprintf(fp, "zram_flag_shift: %ld\n", zram_flag_shift);
@@ -2981,9 +2987,9 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
ulong zram, zram_table_entry, sector, index, entry, flags, size,
outsize, off;
- if (INVALID_MEMBER(zram_compressor)) {
+ if (INVALID_MEMBER(zram_mempoll)) {
zram_init();
- if (INVALID_MEMBER(zram_compressor)) {
+ if (INVALID_MEMBER(zram_mempoll)) {
error(WARNING,
"Some pages are swapped out to zram. "
"Please run mod -s zram.\n");
@@ -2997,8 +3003,28 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
if (!get_disk_name_private_data(pte_val, vaddr, NULL, &zram))
return 0;
- readmem(zram + OFFSET(zram_compressor), KVADDR, name,
- sizeof(name), "zram compressor", FAULT_ON_ERROR);
+ if (THIS_KERNEL_VERSION >= LINUX(2, 6, 0))
+ swp_offset = (ulonglong)__swp_offset(pte_val);
+ else
+ swp_offset = (ulonglong)SWP_OFFSET(pte_val);
+
+ sector = swp_offset << (PAGESHIFT() - 9);
+ index = sector >> SECTORS_PER_PAGE_SHIFT;
+ readmem(zram, KVADDR, &zram_table_entry,
+ sizeof(void *), "zram_table_entry", FAULT_ON_ERROR);
+ zram_table_entry += (index * SIZE(zram_table_entry));
+ readmem(zram_table_entry + OFFSET(zram_table_flag), KVADDR, &flags,
+ sizeof(void *), "zram_table_flag", FAULT_ON_ERROR);
+ if (VALID_MEMBER(zram_compressor))
+ readmem(zram + OFFSET(zram_compressor), KVADDR, name, sizeof(name),
+ "zram compressor", FAULT_ON_ERROR);
+ else {
+ ulong comp_alg_addr;
+ uint32_t prio = (flags >> ZRAM_COMP_PRIORITY_BIT1) & ZRAM_COMP_PRIORITY_MASK;
+ readmem(zram + OFFSET(zram_comp_algs) + sizeof(const char *) * prio, KVADDR,
+ &comp_alg_addr, sizeof(comp_alg_addr), "zram comp_algs", FAULT_ON_ERROR);
+ read_string(comp_alg_addr, name, sizeof(name));
+ }
if (STREQ(name, "lzo")) {
#ifdef LZO
if (!(dd->flags & LZO_SUPPORTED)) {
@@ -3019,12 +3045,6 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
return 0;
}
- if (THIS_KERNEL_VERSION >= LINUX(2, 6, 0)) {
- swp_offset = (ulonglong)__swp_offset(pte_val);
- } else {
- swp_offset = (ulonglong)SWP_OFFSET(pte_val);
- }
-
zram_buf = (unsigned char *)GETBUF(PAGESIZE());
/* lookup page from swap cache */
off = PAGEOFFSET(vaddr);
@@ -3034,15 +3054,8 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
goto out;
}
- sector = swp_offset << (PAGESHIFT() - 9);
- index = sector >> SECTORS_PER_PAGE_SHIFT;
- readmem(zram, KVADDR, &zram_table_entry,
- sizeof(void *), "zram_table_entry", FAULT_ON_ERROR);
- zram_table_entry += (index * SIZE(zram_table_entry));
readmem(zram_table_entry, KVADDR, &entry,
sizeof(void *), "entry of table", FAULT_ON_ERROR);
- readmem(zram_table_entry + OFFSET(zram_table_flag), KVADDR, &flags,
- sizeof(void *), "zram_table_flag", FAULT_ON_ERROR);
if (!entry || (flags & ZRAM_FLAG_SAME_BIT)) {
int count;
ulong *same_buf = (ulong *)GETBUF(PAGESIZE());
--
2.41.0

View File

@ -1,151 +0,0 @@
From edb2bd52885ccc2fbe3e0825efe0ac55951a7710 Mon Sep 17 00:00:00 2001
From: "qiwu.chen@transsion.com" <qiwu.chen@transsion.com>
Date: Fri, 22 Dec 2023 03:30:33 +0000
Subject: [PATCH 1/6] arm64: support HW Tag-Based KASAN (MTE) mode
Kernel commit 2e903b914797 ("kasan, arm64: implement HW_TAGS runtime")
introduced Hardware Tag-Based KASAN (MTE) mode for ARMv8.5 and later
CPUs, which uses the Top Byte Ignore (TBI) feature of arm64 CPUs to
store a pointer tag in the top byte of kernel pointers.
Currently, crash utility cannot load MTE ramdump due to access invalid
HW Tag-Based kernel virtual addresses. Here's the example error message:
please wait... (gathering kmem slab cache data)
crash: invalid kernel virtual address: f1ffff80c000201c type: "kmem_cache objsize/object_size"
please wait... (gathering task table data)
crash: invalid kernel virtual address: f9ffff8239c2cde0 type: "xa_node shift"
This patch replaces the orignal generic_is_kvaddr() with arm64_is_kvaddr(),
which checks the validity for a HW Tag-Based kvaddr. mte_tag_reset() is
used to convert a Tag-Based kvaddr to untaggged kvaddr in arm64_VTOP()
and arm64_IS_VMALLOC_ADDR().
Signed-off-by: chenqiwu <qiwu.chen@transsion.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
arm64.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++---
defs.h | 1 +
2 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/arm64.c b/arm64.c
index 57965c6cb3c8..6ab10ca9b5be 100644
--- a/arm64.c
+++ b/arm64.c
@@ -102,6 +102,41 @@ struct kernel_range {
static struct kernel_range *arm64_get_va_range(struct machine_specific *ms);
static void arm64_get_struct_page_size(struct machine_specific *ms);
+/* mte tag shift bit */
+#define MTE_TAG_SHIFT 56
+/* native kernel pointers tag */
+#define KASAN_TAG_KERNEL 0xFF
+/* minimum value for random tags */
+#define KASAN_TAG_MIN 0xF0
+/* right shift the tag to MTE_TAG_SHIFT bit */
+#define mte_tag_shifted(tag) ((ulong)(tag) << MTE_TAG_SHIFT)
+/* get the top byte value of the original kvaddr */
+#define mte_tag_get(addr) (unsigned char)((ulong)(addr) >> MTE_TAG_SHIFT)
+/* reset the top byte to get an untaggged kvaddr */
+#define mte_tag_reset(addr) (((ulong)addr & ~mte_tag_shifted(KASAN_TAG_KERNEL)) | \
+ mte_tag_shifted(KASAN_TAG_KERNEL))
+
+static inline bool is_mte_kvaddr(ulong addr)
+{
+ /* check for ARM64_MTE enabled */
+ if (!(machdep->flags & ARM64_MTE))
+ return false;
+
+ /* check the validity of HW Tag-Based kvaddr */
+ if (mte_tag_get(addr) >= KASAN_TAG_MIN && mte_tag_get(addr) < KASAN_TAG_KERNEL)
+ return true;
+
+ return false;
+}
+
+static int arm64_is_kvaddr(ulong addr)
+{
+ if (is_mte_kvaddr(addr))
+ return (mte_tag_reset(addr) >= (ulong)(machdep->kvbase));
+
+ return (addr >= (ulong)(machdep->kvbase));
+}
+
static void arm64_calc_kernel_start(void)
{
struct machine_specific *ms = machdep->machspec;
@@ -182,6 +217,9 @@ arm64_init(int when)
if (kernel_symbol_exists("kimage_voffset"))
machdep->flags |= NEW_VMEMMAP;
+ if (kernel_symbol_exists("cpu_enable_mte"))
+ machdep->flags |= ARM64_MTE;
+
if (!machdep->pagesize && arm64_get_vmcoreinfo(&value, "PAGESIZE", NUM_DEC))
machdep->pagesize = (unsigned int)value;
@@ -262,7 +300,7 @@ arm64_init(int when)
machdep->kvbase = ARM64_VA_START;
ms->userspace_top = ARM64_USERSPACE_TOP;
}
- machdep->is_kvaddr = generic_is_kvaddr;
+ machdep->is_kvaddr = arm64_is_kvaddr;
machdep->kvtop = arm64_kvtop;
/* The defaults */
@@ -975,6 +1013,8 @@ arm64_dump_machdep_table(ulong arg)
fprintf(fp, "%sFLIPPED_VM", others++ ? "|" : "");
if (machdep->flags & HAS_PHYSVIRT_OFFSET)
fprintf(fp, "%sHAS_PHYSVIRT_OFFSET", others++ ? "|" : "");
+ if (machdep->flags & ARM64_MTE)
+ fprintf(fp, "%sARM64_MTE", others++ ? "|" : "");
fprintf(fp, ")\n");
fprintf(fp, " kvbase: %lx\n", machdep->kvbase);
@@ -1023,7 +1063,7 @@ arm64_dump_machdep_table(ulong arg)
fprintf(fp, " dis_filter: arm64_dis_filter()\n");
fprintf(fp, " cmd_mach: arm64_cmd_mach()\n");
fprintf(fp, " get_smp_cpus: arm64_get_smp_cpus()\n");
- fprintf(fp, " is_kvaddr: generic_is_kvaddr()\n");
+ fprintf(fp, " is_kvaddr: arm64_is_kvaddr()\n");
fprintf(fp, " is_uvaddr: arm64_is_uvaddr()\n");
fprintf(fp, " value_to_symbol: generic_machdep_value_to_symbol()\n");
fprintf(fp, " init_kernel_pgd: arm64_init_kernel_pgd\n");
@@ -1633,6 +1673,9 @@ ulong arm64_PTOV(ulong paddr)
ulong
arm64_VTOP(ulong addr)
{
+ if (is_mte_kvaddr(addr))
+ addr = mte_tag_reset(addr);
+
if (machdep->flags & NEW_VMEMMAP) {
if (machdep->machspec->VA_START &&
(addr >= machdep->machspec->kimage_text) &&
@@ -4562,7 +4605,10 @@ int
arm64_IS_VMALLOC_ADDR(ulong vaddr)
{
struct machine_specific *ms = machdep->machspec;
-
+
+ if (is_mte_kvaddr(vaddr))
+ vaddr = mte_tag_reset(vaddr);
+
if ((machdep->flags & NEW_VMEMMAP) &&
(vaddr >= machdep->machspec->kimage_text) &&
(vaddr <= machdep->machspec->kimage_end))
diff --git a/defs.h b/defs.h
index 20237b72a10b..aa8eba83b7f4 100644
--- a/defs.h
+++ b/defs.h
@@ -3348,6 +3348,7 @@ typedef signed int s32;
#define FLIPPED_VM (0x400)
#define HAS_PHYSVIRT_OFFSET (0x800)
#define OVERFLOW_STACKS (0x1000)
+#define ARM64_MTE (0x2000)
/*
* Get kimage_voffset from /dev/crash
--
2.41.0

View File

@ -1,168 +0,0 @@
From d65e5d3eae0dd06a5308a5cb00c05fee60594093 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Mon, 20 Nov 2023 13:22:56 +0900
Subject: [PATCH 02/14] Fix typos in offset_table and missing "help -o" items
A few of zram related members in the offset_table have typos and
irregular naming rule, also they are not present in the "help -o"
output. Let's fix these.
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 8 ++++----
diskdump.c | 24 ++++++++++++------------
memory.c | 2 +-
symbols.c | 12 ++++++++++++
4 files changed, 29 insertions(+), 17 deletions(-)
diff --git a/defs.h b/defs.h
index 2cae5b61e589..5218a94fe4a4 100644
--- a/defs.h
+++ b/defs.h
@@ -2112,13 +2112,13 @@ struct offset_table { /* stash of commonly-used offsets */
long bpf_prog_aux_name;
long page_private;
long swap_info_struct_bdev;
- long zram_mempoll;
+ long zram_mem_pool;
long zram_compressor;
- long zram_table_flag;
- long zspoll_size_class;
+ long zram_table_entry_flags;
+ long zs_pool_size_class;
long size_class_size;
long gendisk_private_data;
- long zram_table_entry;
+ long zram_table_entry; /* unused; but cannot remove */
long module_core_size_rw;
long module_core_size_rx;
long module_init_size_rw;
diff --git a/diskdump.c b/diskdump.c
index 25054d96313e..f20f3ac519a1 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2765,15 +2765,15 @@ zram_init(void)
{
long zram_flag_shift;
- MEMBER_OFFSET_INIT(zram_mempoll, "zram", "mem_pool");
+ MEMBER_OFFSET_INIT(zram_mem_pool, "zram", "mem_pool");
MEMBER_OFFSET_INIT(zram_compressor, "zram", "compressor");
if (INVALID_MEMBER(zram_compressor))
MEMBER_OFFSET_INIT(zram_comp_algs, "zram", "comp_algs");
- MEMBER_OFFSET_INIT(zram_table_flag, "zram_table_entry", "flags");
- if (INVALID_MEMBER(zram_table_flag))
- MEMBER_OFFSET_INIT(zram_table_flag, "zram_table_entry", "value");
+ MEMBER_OFFSET_INIT(zram_table_entry_flags, "zram_table_entry", "flags");
+ if (INVALID_MEMBER(zram_table_entry_flags))
+ MEMBER_OFFSET_INIT(zram_table_entry_flags, "zram_table_entry", "value");
STRUCT_SIZE_INIT(zram_table_entry, "zram_table_entry");
- MEMBER_OFFSET_INIT(zspoll_size_class, "zs_pool", "size_class");
+ MEMBER_OFFSET_INIT(zs_pool_size_class, "zs_pool", "size_class");
MEMBER_OFFSET_INIT(size_class_size, "size_class", "size");
MEMBER_OFFSET_INIT(zspage_huge, "zspage", "huge");
@@ -2826,7 +2826,7 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf)
if (zs_magic != ZSPAGE_MAGIC)
error(FATAL, "zspage magic incorrect: %x\n", zs_magic);
- class = pool + OFFSET(zspoll_size_class);
+ class = pool + OFFSET(zs_pool_size_class);
class += (class_idx * sizeof(void *));
readmem(class, KVADDR, &class, sizeof(void *), "size_class", FAULT_ON_ERROR);
readmem(class + OFFSET(size_class_size), KVADDR,
@@ -2987,9 +2987,9 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
ulong zram, zram_table_entry, sector, index, entry, flags, size,
outsize, off;
- if (INVALID_MEMBER(zram_mempoll)) {
+ if (INVALID_MEMBER(zram_mem_pool)) {
zram_init();
- if (INVALID_MEMBER(zram_mempoll)) {
+ if (INVALID_MEMBER(zram_mem_pool)) {
error(WARNING,
"Some pages are swapped out to zram. "
"Please run mod -s zram.\n");
@@ -3013,8 +3013,8 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
readmem(zram, KVADDR, &zram_table_entry,
sizeof(void *), "zram_table_entry", FAULT_ON_ERROR);
zram_table_entry += (index * SIZE(zram_table_entry));
- readmem(zram_table_entry + OFFSET(zram_table_flag), KVADDR, &flags,
- sizeof(void *), "zram_table_flag", FAULT_ON_ERROR);
+ readmem(zram_table_entry + OFFSET(zram_table_entry_flags), KVADDR, &flags,
+ sizeof(void *), "zram_table_entry.flags", FAULT_ON_ERROR);
if (VALID_MEMBER(zram_compressor))
readmem(zram + OFFSET(zram_compressor), KVADDR, name, sizeof(name),
"zram compressor", FAULT_ON_ERROR);
@@ -3072,8 +3072,8 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
goto out;
}
- readmem(zram + OFFSET(zram_mempoll), KVADDR, &zram,
- sizeof(void *), "zram_mempoll", FAULT_ON_ERROR);
+ readmem(zram + OFFSET(zram_mem_pool), KVADDR, &zram,
+ sizeof(void *), "zram.mem_pool", FAULT_ON_ERROR);
obj_addr = zram_object_addr(zram, entry, zram_buf);
if (obj_addr == NULL) {
diff --git a/memory.c b/memory.c
index 86ccec5e2bac..791194a405d4 100644
--- a/memory.c
+++ b/memory.c
@@ -519,7 +519,7 @@ vm_init(void)
"swap_info_struct", "old_block_size");
MEMBER_OFFSET_INIT(swap_info_struct_bdev, "swap_info_struct", "bdev");
- MEMBER_OFFSET_INIT(zspoll_size_class, "zs_pool", "size_class");
+ MEMBER_OFFSET_INIT(zs_pool_size_class, "zs_pool", "size_class");
MEMBER_OFFSET_INIT(size_class_size, "size_class", "size");
MEMBER_OFFSET_INIT(block_device_bd_inode, "block_device", "bd_inode");
diff --git a/symbols.c b/symbols.c
index 8e8b4c31d915..176c95026f03 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10304,6 +10304,7 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(page_active));
fprintf(fp, " page_compound_head: %ld\n",
OFFSET(page_compound_head));
+ fprintf(fp, " page_private: %ld\n", OFFSET(page_private));
fprintf(fp, " trace_print_flags_mask: %ld\n",
OFFSET(trace_print_flags_mask));
@@ -10330,6 +10331,7 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(swap_info_struct_inuse_pages));
fprintf(fp, "swap_info_struct_old_block_size: %ld\n",
OFFSET(swap_info_struct_old_block_size));
+ fprintf(fp, " swap_info_struct_bdev: %ld\n", OFFSET(swap_info_struct_bdev));
fprintf(fp, " block_device_bd_inode: %ld\n",
OFFSET(block_device_bd_inode));
fprintf(fp, " block_device_bd_list: %ld\n",
@@ -11359,6 +11361,8 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(gendisk_part0));
fprintf(fp, " gendisk_queue: %ld\n",
OFFSET(gendisk_queue));
+ fprintf(fp, " gendisk_private_data: %ld\n", OFFSET(gendisk_private_data));
+
fprintf(fp, " hd_struct_dev: %ld\n",
OFFSET(hd_struct_dev));
fprintf(fp, " hd_struct_dkstats: %ld\n",
@@ -11765,6 +11769,14 @@ dump_offset_table(char *spec, ulong makestruct)
fprintf(fp, " maple_metadata_end: %ld\n", OFFSET(maple_metadata_end));
fprintf(fp, " maple_metadata_gap: %ld\n", OFFSET(maple_metadata_gap));
+ fprintf(fp, " zram_mem_pool: %ld\n", OFFSET(zram_mem_pool));
+ fprintf(fp, " zram_compressor: %ld\n", OFFSET(zram_compressor));
+ fprintf(fp, " zram_comp_algs: %ld\n", OFFSET(zram_comp_algs));
+ fprintf(fp, " zram_table_entry_flags: %ld\n", OFFSET(zram_table_entry_flags));
+ fprintf(fp, " zs_pool_size_class: %ld\n", OFFSET(zs_pool_size_class));
+ fprintf(fp, " size_class_size: %ld\n", OFFSET(size_class_size));
+ fprintf(fp, " zspage_huge: %ld\n", OFFSET(zspage_huge));
+
fprintf(fp, "\n size_table:\n");
fprintf(fp, " page: %ld\n", SIZE(page));
fprintf(fp, " page_flags: %ld\n", SIZE(page_flags));
--
2.41.0

View File

@ -1,334 +0,0 @@
From d86dc6901ce76a0fc29022ed448a4baa83a47dd7 Mon Sep 17 00:00:00 2001
From: Song Shuai <songshuaishuai@tinylab.org>
Date: Wed, 13 Dec 2023 17:45:06 +0800
Subject: [PATCH 2/6] RISCV64: Add support for 'bt -e' option
With this patch we can search the stack for possible kernel and user
mode exception frames via 'bt -e' command.
TEST: a lkdtm DIRECT EXCEPTION vmcore
crash> bt -e
PID: 1 TASK: ff600000000e0000 CPU: 1 COMMAND: "sh"
KERNEL-MODE EXCEPTION FRAME AT: ff200000000138d8
PC: ffffffff805303c0 [lkdtm_EXCEPTION+6]
RA: ffffffff8052fe36 [lkdtm_do_action+16]
SP: ff20000000013cf0 CAUSE: 000000000000000f
epc : ffffffff805303c0 ra : ffffffff8052fe36 sp : ff20000000013cf0
gp : ffffffff814ef848 tp : ff600000000e0000 t0 : 6500000000000000
t1 : 000000000000006c t2 : 6550203a6d74646b s0 : ff20000000013d00
s1 : 000000000000000a a0 : ffffffff814aef40 a1 : c0000000ffffefff
a2 : 0000000000000010 a3 : 0000000000000001 a4 : 5d53ea10ca096e00
a5 : ffffffff805303ba a6 : 0000000000000008 a7 : 0000000000000038
s2 : ff60000001324000 s3 : ffffffff814aef40 s4 : ff20000000013e30
s5 : 000000000000000a s6 : ff20000000013e30 s7 : ff600000000ce000
s8 : 0000555560f0f8a8 s9 : 00007ffff497f6b4 s10: 00007ffff497f6b0
s11: 0000555560fa30e0 t3 : ffffffff81502197 t4 : ffffffff81502197
t5 : ffffffff81502198 t6 : ff20000000013b28
status: 0000000200000120 badaddr: 0000000000000000
cause: 000000000000000f orig_a0: 0000000000000000
USER-MODE EXCEPTION FRAME AT: ff20000000013ee0
PC: 007fff8780431aff RA: 007fff877b168400 SP: 007ffff497f5b000
ORIG_A0: 0000000000000100 SYSCALLNO: 0000000000004000
epc : 007fff8780431aff ra : 007fff877b168400 sp : 007ffff497f5b000
gp : 00555560f5134800 tp : 007fff8774378000 t0 : 0000000000100000
t1 : 00555560e427bc00 t2 : 0000000000271000 s0 : 007ffff497f5e000
s1 : 0000000000000a00 a0 : 0000000000000100 a1 : 00555560faa68000
a2 : 0000000000000a00 a3 : 4000000000000000 a4 : 20000000000000a8
a5 : 0000000000000054 a6 : 0000000000000400 a7 : 0000000000004000
s2 : 00555560faa68000 s3 : 007fff878b33f800 s4 : 0000000000000a00
s5 : 00555560faa68000 s6 : 0000000000000a00 s7 : 00555560f5131400
s8 : 00555560f0f8a800 s9 : 007ffff497f6b400 s10: 007ffff497f6b000
s11: 00555560fa30e000 t3 : 007fff877af1fe00 t4 : 00555560fa6f2000
t5 : 0000000000000100 t6 : 9e1fea5bf8683300
status: 00000200004020b9 badaddr: 0000000000000000
cause: 0000000000000800 orig_a0: 0000000000000100
crash>
Signed-off-by: Song Shuai <songshuaishuai@tinylab.org>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 15 +++--
riscv64.c | 191 +++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 181 insertions(+), 25 deletions(-)
diff --git a/defs.h b/defs.h
index aa8eba83b7f4..9cf9501348ed 100644
--- a/defs.h
+++ b/defs.h
@@ -7011,17 +7011,16 @@ int riscv64_IS_VMALLOC_ADDR(ulong);
#define display_idt_table() \
error(FATAL, "-d option is not applicable to RISCV64 architecture\n")
-/* from arch/riscv/include/asm/ptrace.h */
+/*
+ * regs[0,31] : struct user_regs_struct
+ * from arch/riscv/include/uapi/asm/ptrace.h
+ * regs[0,35] : struct pt_regs
+ * from arch/riscv/include/asm/ptrace.h
+ */
struct riscv64_register {
ulong regs[36];
};
-struct riscv64_pt_regs {
- ulong badvaddr;
- ulong cause;
- ulong epc;
-};
-
struct riscv64_unwind_frame {
ulong fp;
ulong sp;
@@ -7085,6 +7084,8 @@ struct machine_specific {
#define RISCV64_REGS_RA 1
#define RISCV64_REGS_SP 2
#define RISCV64_REGS_FP 8
+#define RISCV64_REGS_STATUS 32
+#define RISCV64_REGS_CAUSE 34
#endif /* RISCV64 */
diff --git a/riscv64.c b/riscv64.c
index 872be594d72b..6097c0029ccc 100644
--- a/riscv64.c
+++ b/riscv64.c
@@ -35,6 +35,7 @@ static int riscv64_kvtop(struct task_context *tc, ulong kvaddr,
static void riscv64_cmd_mach(void);
static void riscv64_stackframe_init(void);
static void riscv64_back_trace_cmd(struct bt_info *bt);
+static int riscv64_eframe_search(struct bt_info *bt);
static int riscv64_get_dumpfile_stack_frame(struct bt_info *bt,
ulong *nip, ulong *ksp);
static void riscv64_get_stack_frame(struct bt_info *bt, ulong *pcp,
@@ -51,6 +52,8 @@ static int riscv64_get_elf_notes(void);
static void riscv64_get_va_range(struct machine_specific *ms);
static void riscv64_get_va_bits(struct machine_specific *ms);
static void riscv64_get_struct_page_size(struct machine_specific *ms);
+static void riscv64_print_exception_frame(struct bt_info *, ulong , int );
+static int riscv64_is_kernel_exception_frame(struct bt_info *, ulong );
#define REG_FMT "%016lx"
#define SZ_2G 0x80000000
@@ -210,6 +213,7 @@ riscv64_dump_machdep_table(ulong arg)
machdep->memsize, machdep->memsize);
fprintf(fp, " bits: %d\n", machdep->bits);
fprintf(fp, " back_trace: riscv64_back_trace_cmd()\n");
+ fprintf(fp, " eframe_search: riscv64_eframe_search()\n");
fprintf(fp, " processor_speed: riscv64_processor_speed()\n");
fprintf(fp, " uvtop: riscv64_uvtop()\n");
fprintf(fp, " kvtop: riscv64_kvtop()\n");
@@ -1398,6 +1402,7 @@ riscv64_init(int when)
machdep->cmd_mach = riscv64_cmd_mach;
machdep->get_stack_frame = riscv64_get_stack_frame;
machdep->back_trace = riscv64_back_trace_cmd;
+ machdep->eframe_search = riscv64_eframe_search;
machdep->vmalloc_start = riscv64_vmalloc_start;
machdep->processor_speed = riscv64_processor_speed;
@@ -1452,25 +1457,10 @@ riscv64_init(int when)
}
}
-/*
- * 'help -r' command output
- */
-void
-riscv64_display_regs_from_elf_notes(int cpu, FILE *ofp)
+/* bool pt_regs : pass 1 to dump pt_regs , pass 0 to dump user_regs_struct */
+static void
+riscv64_dump_pt_regs(struct riscv64_register *regs, FILE *ofp, bool pt_regs)
{
- const struct machine_specific *ms = machdep->machspec;
- struct riscv64_register *regs;
-
- if (!ms->crash_task_regs) {
- error(INFO, "registers not collected for cpu %d\n", cpu);
- return;
- }
-
- regs = &ms->crash_task_regs[cpu];
- if (!regs->regs[RISCV64_REGS_SP] && !regs->regs[RISCV64_REGS_EPC]) {
- error(INFO, "registers not collected for cpu %d\n", cpu);
- return;
- }
/* Print riscv64 32 regs */
fprintf(ofp,
@@ -1496,6 +1486,171 @@ riscv64_display_regs_from_elf_notes(int cpu, FILE *ofp)
regs->regs[24], regs->regs[25], regs->regs[26],
regs->regs[27], regs->regs[28], regs->regs[29],
regs->regs[30], regs->regs[31]);
+
+ if (pt_regs)
+ fprintf(ofp,
+ " status: " REG_FMT " badaddr: " REG_FMT "\n"
+ " cause: " REG_FMT " orig_a0: " REG_FMT "\n",
+ regs->regs[32], regs->regs[33], regs->regs[34],
+ regs->regs[35]);
+}
+
+/*
+ * 'help -r' command output
+ */
+void
+riscv64_display_regs_from_elf_notes(int cpu, FILE *ofp)
+{
+ const struct machine_specific *ms = machdep->machspec;
+ struct riscv64_register *regs;
+
+ if (!ms->crash_task_regs) {
+ error(INFO, "registers not collected for cpu %d\n", cpu);
+ return;
+ }
+
+ regs = &ms->crash_task_regs[cpu];
+ if (!regs->regs[RISCV64_REGS_SP] && !regs->regs[RISCV64_REGS_EPC]) {
+ error(INFO, "registers not collected for cpu %d\n", cpu);
+ return;
+ }
+
+ riscv64_dump_pt_regs(regs, ofp, 0);
+}
+
+#define USER_MODE (0)
+#define KERNEL_MODE (1)
+
+static void
+riscv64_print_exception_frame(struct bt_info *bt, ulong ptr, int mode)
+{
+
+ struct syment *sp;
+ ulong PC, RA, SP, offset;
+ struct riscv64_register *regs;
+
+ regs = (struct riscv64_register *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(ptr))];
+
+ PC = regs->regs[RISCV64_REGS_EPC];
+ RA = regs->regs[RISCV64_REGS_RA];
+ SP = regs->regs[RISCV64_REGS_SP];
+
+ switch (mode) {
+ case USER_MODE:
+ fprintf(fp,
+ " PC: %016lx RA: %016lx SP: %016lx\n"
+ " ORIG_A0: %016lx SYSCALLNO: %016lx\n",
+ PC, RA, SP, regs->regs[35], regs->regs[17]);
+
+ break;
+
+ case KERNEL_MODE:
+ fprintf(fp, " PC: %016lx ", PC);
+ if (is_kernel_text(PC) && (sp = value_search(PC, &offset))) {
+ fprintf(fp, "[%s", sp->name);
+ if (offset)
+ fprintf(fp, (*gdb_output_radix == 16) ?
+ "+0x%lx" : "+%ld", offset);
+ fprintf(fp, "]\n");
+ } else
+ fprintf(fp, "[unknown or invalid address]\n");
+
+ fprintf(fp, " RA: %016lx ", RA);
+ if (is_kernel_text(RA) && (sp = value_search(RA, &offset))) {
+ fprintf(fp, "[%s", sp->name);
+ if (offset)
+ fprintf(fp, (*gdb_output_radix == 16) ?
+ "+0x%lx" : "+%ld", offset);
+ fprintf(fp, "]\n");
+ } else
+ fprintf(fp, "[unknown or invalid address]\n");
+
+ fprintf(fp, " SP: %016lx CAUSE: %016lx\n",
+ SP, regs->regs[RISCV64_REGS_CAUSE]);
+
+ break;
+ }
+
+ riscv64_dump_pt_regs(regs, fp, 1);
+
+}
+
+static int
+riscv64_is_kernel_exception_frame(struct bt_info *bt, ulong stkptr)
+{
+ struct riscv64_register *regs;
+
+ if (stkptr > STACKSIZE() && !INSTACK(stkptr, bt)) {
+ if (CRASHDEBUG(1))
+ error(WARNING, "stkptr: %lx is outside the kernel stack range\n", stkptr);
+ return FALSE;
+ }
+
+ regs = (struct riscv64_register *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(stkptr))];
+
+ if (INSTACK(regs->regs[RISCV64_REGS_SP], bt) &&
+ INSTACK(regs->regs[RISCV64_REGS_FP], bt) &&
+ is_kernel_text(regs->regs[RISCV64_REGS_RA]) &&
+ is_kernel_text(regs->regs[RISCV64_REGS_EPC]) &&
+ ((regs->regs[RISCV64_REGS_STATUS] >> 8) & 0x1) && // sstatus.SPP != 0
+ !((regs->regs[RISCV64_REGS_CAUSE] >> 63) & 0x1 ) && // scause.Interrupt != 1
+ !(regs->regs[RISCV64_REGS_CAUSE] == 0x00000008UL)) { // scause != ecall from U-mode
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static int
+riscv64_dump_kernel_eframes(struct bt_info *bt)
+{
+ ulong ptr;
+ int count;
+
+ /*
+ * use old_regs to avoid the identical contiguous kernel exception frames
+ * created by Linux handle_exception() path ending at riscv_crash_save_regs()
+ */
+ struct riscv64_register *regs, *old_regs;
+
+ count = 0;
+ old_regs = NULL;
+
+ for (ptr = bt->stackbase; ptr < bt->stacktop - SIZE(pt_regs); ptr++) {
+
+ regs = (struct riscv64_register *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(ptr))];
+
+ if (riscv64_is_kernel_exception_frame(bt, ptr)){
+ if (!old_regs || (old_regs &&
+ memcmp(old_regs, regs, sizeof(struct riscv64_register))) != 0){
+ old_regs = regs;
+ fprintf(fp, "\nKERNEL-MODE EXCEPTION FRAME AT: %lx\n", ptr);
+ riscv64_print_exception_frame(bt, ptr, KERNEL_MODE);
+ count++;
+ }
+ }
+ }
+
+ return count;
+}
+
+static int
+riscv64_eframe_search(struct bt_info *bt)
+{
+ ulong ptr;
+ int count;
+
+ count = riscv64_dump_kernel_eframes(bt);
+
+ if (is_kernel_thread(bt->tc->task))
+ return count;
+
+ ptr = bt->stacktop - SIZE(pt_regs);
+ fprintf(fp, "%sUSER-MODE EXCEPTION FRAME AT: %lx\n", count++ ? "\n" : "", ptr);
+ riscv64_print_exception_frame(bt, ptr, USER_MODE);
+
+ return count;
}
#else /* !RISCV64 */
--
2.41.0

View File

@ -1,436 +0,0 @@
From 12fbed3280a147a40e572808b660aa838f3ca372 Mon Sep 17 00:00:00 2001
From: Song Shuai <songshuaishuai@tinylab.org>
Date: Wed, 13 Dec 2023 17:45:07 +0800
Subject: [PATCH 3/6] RISCV64: Add per-cpu IRQ stacks support
This patch introduces per-cpu IRQ stacks for RISCV64 to let
"bt" do backtrace on it and 'bt -E' search eframes on it,
and the 'help -m' command displays the addresses of each
per-cpu IRQ stack.
TEST: a vmcore dumped via hacking the handle_irq_event_percpu()
( Why not using lkdtm INT_HW_IRQ_EN EXCEPTION ?
There is a deadlock[1] in crash_kexec path if use that)
crash> bt
PID: 0 TASK: ffffffff8140db00 CPU: 0 COMMAND: "swapper/0"
#0 [ff20000000003e60] __handle_irq_event_percpu at ffffffff8006462e
#1 [ff20000000003ed0] handle_irq_event_percpu at ffffffff80064702
#2 [ff20000000003ef0] handle_irq_event at ffffffff8006477c
#3 [ff20000000003f20] handle_fasteoi_irq at ffffffff80068664
#4 [ff20000000003f50] generic_handle_domain_irq at ffffffff80063988
#5 [ff20000000003f60] plic_handle_irq at ffffffff8046633e
#6 [ff20000000003fb0] generic_handle_domain_irq at ffffffff80063988
#7 [ff20000000003fc0] riscv_intc_irq at ffffffff80465f8e
#8 [ff20000000003fd0] handle_riscv_irq at ffffffff808361e8
PC: ffffffff80837314 [default_idle_call+50]
RA: ffffffff80837310 [default_idle_call+46]
SP: ffffffff81403da0 CAUSE: 8000000000000009
epc : ffffffff80837314 ra : ffffffff80837310 sp : ffffffff81403da0
gp : ffffffff814ef848 tp : ffffffff8140db00 t0 : ff2000000004bb18
t1 : 0000000000032c73 t2 : ffffffff81200a48 s0 : ffffffff81403db0
s1 : 0000000000000000 a0 : 0000000000000004 a1 : 0000000000000000
a2 : ff6000009f1e7000 a3 : 0000000000002304 a4 : ffffffff80c1c2d8
a5 : 0000000000000000 a6 : ff6000001fe01958 a7 : 00002496ea89dbf1
s2 : ffffffff814f0220 s3 : 0000000000000001 s4 : 000000000000003f
s5 : ffffffff814f03d8 s6 : 0000000000000000 s7 : ffffffff814f00d0
s8 : ffffffff81526f10 s9 : ffffffff80c1d880 s10: 0000000000000000
s11: 0000000000000001 t3 : 0000000000003392 t4 : 0000000000000000
t5 : 0000000000000000 t6 : 0000000000000040
status: 0000000200000120 badaddr: 0000000000000000
cause: 8000000000000009 orig_a0: ffffffff80837310
--- <IRQ stack> ---
#9 [ffffffff81403da0] default_idle_call at ffffffff80837314
#10 [ffffffff81403db0] do_idle at ffffffff8004d0a0
#11 [ffffffff81403e40] cpu_startup_entry at ffffffff8004d21e
#12 [ffffffff81403e60] kernel_init at ffffffff8083746a
#13 [ffffffff81403e70] arch_post_acpi_subsys_init at ffffffff80a006d8
#14 [ffffffff81403e80] console_on_rootfs at ffffffff80a00c92
crash>
crash> bt -E
CPU 0 IRQ STACK:
KERNEL-MODE EXCEPTION FRAME AT: ff20000000003a48
PC: ffffffff8006462e [__handle_irq_event_percpu+30]
RA: ffffffff80064702 [handle_irq_event_percpu+18]
SP: ff20000000003e60 CAUSE: 000000000000000d
epc : ffffffff8006462e ra : ffffffff80064702 sp : ff20000000003e60
gp : ffffffff814ef848 tp : ffffffff8140db00 t0 : 0000000000046600
t1 : ffffffff80836464 t2 : ffffffff81200a48 s0 : ff20000000003ed0
s1 : 0000000000000000 a0 : 0000000000000000 a1 : 0000000000000118
a2 : 0000000000000052 a3 : 0000000000000000 a4 : 0000000000000000
a5 : 0000000000010001 a6 : ff6000001fe01958 a7 : 00002496ea89dbf1
s2 : ff60000000941ab0 s3 : ffffffff814a0658 s4 : ff60000000089230
s5 : ffffffff814a0518 s6 : ffffffff814a0620 s7 : ffffffff80e5f0f8
s8 : ffffffff80fc50b0 s9 : ffffffff80c1d880 s10: 0000000000000000
s11: 0000000000000001 t3 : 0000000000003392 t4 : 0000000000000000
t5 : 0000000000000000 t6 : 0000000000000040
status: 0000000200000100 badaddr: 0000000000000078
cause: 000000000000000d orig_a0: ff20000000003ea0
CPU 1 IRQ STACK: (none found)
crash>
crash> help -m
<snip>
machspec: ced1e0
irq_stack_size: 16384
irq_stacks[0]: ff20000000000000
irq_stacks[1]: ff20000000008000
crash>
[1]: https://lore.kernel.org/linux-riscv/20231208111015.173237-1-songshuaishuai@tinylab.org/
Signed-off-by: Song Shuai <songshuaishuai@tinylab.org>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 7 +-
help.c | 8 +--
riscv64.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 198 insertions(+), 12 deletions(-)
diff --git a/defs.h b/defs.h
index 9cf9501348ed..b71cdbd01b8d 100644
--- a/defs.h
+++ b/defs.h
@@ -3643,6 +3643,8 @@ typedef signed int s32;
#define pmd_index_l5_4k(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
#define pte_index_l5_4k(addr) (((addr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1))
+/* machdep->flags */
+#define KSYMS_START (0x1)
#define VM_L3_4K (0x2)
#define VM_L3_2M (0x4)
#define VM_L3_1G (0x8)
@@ -3652,6 +3654,7 @@ typedef signed int s32;
#define VM_L5_4K (0x80)
#define VM_L5_2M (0x100)
#define VM_L5_1G (0x200)
+#define IRQ_STACKS (0x400)
#define VM_FLAGS (VM_L3_4K | VM_L3_2M | VM_L3_1G | \
VM_L4_4K | VM_L4_2M | VM_L4_1G | \
@@ -7027,8 +7030,6 @@ struct riscv64_unwind_frame {
ulong pc;
};
-#define KSYMS_START (0x1)
-
struct machine_specific {
ulong phys_base;
ulong page_offset;
@@ -7058,6 +7059,8 @@ struct machine_specific {
ulong struct_page_size;
struct riscv64_register *crash_task_regs;
+ ulong irq_stack_size;
+ ulong *irq_stacks;
};
/* from arch/riscv/include/asm/pgtable-bits.h */
#define _PAGE_PRESENT (machdep->machspec->_page_present)
diff --git a/help.c b/help.c
index d80e843703c1..a4319dd2a717 100644
--- a/help.c
+++ b/help.c
@@ -1938,10 +1938,10 @@ char *help_bt[] = {
" fails or the -t option starts too high in the process stack).",
" -l show file and line number of each stack trace text location.",
" -e search the stack for possible kernel and user mode exception frames.",
-" -E search the IRQ stacks (x86, x86_64, arm64, and ppc64), and the",
-" exception stacks (x86_64) for possible exception frames; all other",
-" arguments except for -c will be ignored since this is not a context-",
-" sensitive operation.",
+" -E search the IRQ stacks (x86, x86_64, arm64, riscv64 and ppc64), and",
+" the exception stacks (x86_64) for possible exception frames; all",
+" other arguments except for -c will be ignored since this is not a",
+" context-sensitive operation.",
" -f display all stack data contained in a frame; this option can be",
" used to determine the arguments passed to each function; on ia64,",
" the argument register contents are dumped.",
diff --git a/riscv64.c b/riscv64.c
index 6097c0029ccc..a26b8a43cb29 100644
--- a/riscv64.c
+++ b/riscv64.c
@@ -33,6 +33,7 @@ static int riscv64_uvtop(struct task_context *tc, ulong vaddr,
static int riscv64_kvtop(struct task_context *tc, ulong kvaddr,
physaddr_t *paddr, int verbose);
static void riscv64_cmd_mach(void);
+static void riscv64_irq_stack_init(void);
static void riscv64_stackframe_init(void);
static void riscv64_back_trace_cmd(struct bt_info *bt);
static int riscv64_eframe_search(struct bt_info *bt);
@@ -54,9 +55,15 @@ static void riscv64_get_va_bits(struct machine_specific *ms);
static void riscv64_get_struct_page_size(struct machine_specific *ms);
static void riscv64_print_exception_frame(struct bt_info *, ulong , int );
static int riscv64_is_kernel_exception_frame(struct bt_info *, ulong );
+static int riscv64_on_irq_stack(int , ulong);
+static int riscv64_on_process_stack(struct bt_info *, ulong );
+static void riscv64_set_process_stack(struct bt_info *);
+static void riscv64_set_irq_stack(struct bt_info *);
#define REG_FMT "%016lx"
#define SZ_2G 0x80000000
+#define USER_MODE (0)
+#define KERNEL_MODE (1)
/*
* Holds registers during the crash.
@@ -191,11 +198,14 @@ riscv64_verify_symbol(const char *name, ulong value, char type)
void
riscv64_dump_machdep_table(ulong arg)
{
- int others = 0;
+ const struct machine_specific *ms = machdep->machspec;
+ int others = 0, i = 0;
fprintf(fp, " flags: %lx (", machdep->flags);
if (machdep->flags & KSYMS_START)
fprintf(fp, "%sKSYMS_START", others++ ? "|" : "");
+ if (machdep->flags & IRQ_STACKS)
+ fprintf(fp, "%sIRQ_STACKS", others++ ? "|" : "");
fprintf(fp, ")\n");
fprintf(fp, " kvbase: %lx\n", machdep->kvbase);
@@ -251,6 +261,15 @@ riscv64_dump_machdep_table(ulong arg)
fprintf(fp, " max_physmem_bits: %ld\n", machdep->max_physmem_bits);
fprintf(fp, " sections_per_root: %ld\n", machdep->sections_per_root);
fprintf(fp, " machspec: %lx\n", (ulong)machdep->machspec);
+ if (machdep->flags & IRQ_STACKS) {
+ fprintf(fp, " irq_stack_size: %ld\n", ms->irq_stack_size);
+ for (i = 0; i < kt->cpus; i++)
+ fprintf(fp, " irq_stacks[%d]: %lx\n",
+ i, ms->irq_stacks[i]);
+ } else {
+ fprintf(fp, " irq_stack_size: (unused)\n");
+ fprintf(fp, " irq_stacks: (unused)\n");
+ }
}
static ulong
@@ -665,6 +684,111 @@ riscv64_display_full_frame(struct bt_info *bt, struct riscv64_unwind_frame *curr
fprintf(fp, "\n");
}
+/*
+ * Gather IRQ stack values.
+ */
+static void
+riscv64_irq_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("irq_stack_ptr") &&
+ (sp = per_cpu_symbol_search("irq_stack_ptr")) &&
+ get_symbol_type("irq_stack_ptr", NULL, req)) {
+ if (CRASHDEBUG(1)) {
+ fprintf(fp, "irq_stack_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->irq_stacks = (ulong *)malloc((size_t)(kt->cpus * sizeof(ulong)))))
+ error(FATAL, "cannot malloc irq_stack addresses\n");
+
+ /*
+ * find IRQ_STACK_SIZE (i.e. THREAD_SIZE) via thread_union.stack
+ * or set STACKSIZE() as default.
+ */
+ if (MEMBER_EXISTS("thread_union", "stack")) {
+ if ((sz = MEMBER_SIZE("thread_union", "stack")) > 0)
+ ms->irq_stack_size = sz;
+ } else
+ ms->irq_stack_size = machdep->stacksize;
+
+ machdep->flags |= IRQ_STACKS;
+
+ for (i = 0; i < kt->cpus; i++) {
+ p = kt->__per_cpu_offset[i] + sp->value;
+ if (CRASHDEBUG(1))
+ fprintf(fp, " IRQ stack pointer[%d] is %lx\n", i, p);
+ readmem(p, KVADDR, &(ms->irq_stacks[i]), sizeof(ulong),
+ "IRQ stack pointer", RETURN_ON_ERROR);
+ }
+ }
+}
+
+static int
+riscv64_on_irq_stack(int cpu, ulong stkptr)
+{
+ struct machine_specific *ms = machdep->machspec;
+ ulong * stacks = ms->irq_stacks;
+ ulong stack_size = ms->irq_stack_size;
+
+ if ((cpu >= kt->cpus) || (stacks == NULL) || !stack_size)
+ return FALSE;
+
+ if ((stkptr >= stacks[cpu]) &&
+ (stkptr < (stacks[cpu] + stack_size)))
+ return TRUE;
+
+ return FALSE;
+}
+
+static int
+riscv64_on_process_stack(struct bt_info *bt, ulong stkptr)
+{
+ ulong stackbase, stacktop;
+
+ stackbase = GET_STACKBASE(bt->task);
+ stacktop = GET_STACKTOP(bt->task);
+
+ if ((stkptr >= stackbase) && (stkptr < stacktop))
+ return TRUE;
+
+ return FALSE;
+}
+
+static void
+riscv64_set_irq_stack(struct bt_info *bt)
+{
+ struct machine_specific *ms = machdep->machspec;
+
+ bt->stackbase = ms->irq_stacks[bt->tc->processor];
+ bt->stacktop = bt->stackbase + ms->irq_stack_size;
+ alter_stackbuf(bt);
+}
+
+static void
+riscv64_set_process_stack(struct bt_info *bt)
+{
+ bt->stackbase = GET_STACKBASE(bt->task);
+ bt->stacktop = GET_STACKTOP(bt->task);
+ alter_stackbuf(bt);
+}
+
static void
riscv64_stackframe_init(void)
{
@@ -751,7 +875,7 @@ riscv64_back_trace_cmd(struct bt_info *bt)
{
struct riscv64_unwind_frame current, previous;
struct stackframe curr_frame;
- struct riscv64_register * regs;
+ struct riscv64_register *regs, *irq_regs;
int level = 0;
if (bt->flags & BT_REGS_NOT_FOUND)
@@ -759,6 +883,11 @@ riscv64_back_trace_cmd(struct bt_info *bt)
regs = (struct riscv64_register *) bt->machdep;
+ if (riscv64_on_irq_stack(bt->tc->processor, bt->frameptr)) {
+ riscv64_set_irq_stack(bt);
+ bt->flags |= BT_IRQSTACK;
+ }
+
current.pc = bt->instptr;
current.sp = bt->stkptr;
current.fp = bt->frameptr;
@@ -813,6 +942,35 @@ riscv64_back_trace_cmd(struct bt_info *bt)
current.fp = previous.fp;
current.sp = previous.sp;
+ /*
+ * When backtracing to do_irq(), find the original FP of do_irq()
+ * and then use the saved pt_regs in process stack to continue
+ */
+ if ((bt->flags & BT_IRQSTACK) &&
+ !riscv64_on_irq_stack(bt->tc->processor, current.fp)){
+ if (riscv64_on_process_stack(bt, current.fp)){
+
+ frameptr = (struct stackframe *)current.fp - 1;
+
+ if (!readmem((ulong)frameptr, KVADDR, &curr_frame,
+ sizeof(curr_frame), "get do_irq stack frame", RETURN_ON_ERROR))
+ return;
+
+ riscv64_set_process_stack(bt);
+
+ irq_regs = (struct riscv64_register *)
+ &bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(curr_frame.fp))];
+
+ current.pc = irq_regs->regs[RISCV64_REGS_EPC];
+ current.fp = irq_regs->regs[RISCV64_REGS_FP];
+ current.sp = irq_regs->regs[RISCV64_REGS_SP];
+
+ bt->flags &= ~BT_IRQSTACK;
+ riscv64_print_exception_frame(bt, curr_frame.fp, KERNEL_MODE);
+ fprintf(fp, "--- <IRQ stack> ---\n");
+ }
+ }
+
if (CRASHDEBUG(8))
fprintf(fp, "next %d pc %#lx sp %#lx fp %lx\n",
level, current.pc, current.sp, current.fp);
@@ -1423,6 +1581,8 @@ riscv64_init(int when)
case POST_GDB:
machdep->section_size_bits = _SECTION_SIZE_BITS;
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
+
+ riscv64_irq_stack_init();
riscv64_stackframe_init();
riscv64_page_type_init();
@@ -1518,9 +1678,6 @@ riscv64_display_regs_from_elf_notes(int cpu, FILE *ofp)
riscv64_dump_pt_regs(regs, ofp, 0);
}
-#define USER_MODE (0)
-#define KERNEL_MODE (1)
-
static void
riscv64_print_exception_frame(struct bt_info *bt, ulong ptr, int mode)
{
@@ -1639,7 +1796,33 @@ static int
riscv64_eframe_search(struct bt_info *bt)
{
ulong ptr;
- int count;
+ int count, c;
+ struct machine_specific *ms = machdep->machspec;
+
+ if (bt->flags & BT_EFRAME_SEARCH2) {
+ if (!(machdep->flags & IRQ_STACKS))
+ error(FATAL, "IRQ stacks do not exist in this kernel\n");
+
+ for (c = 0; c < kt->cpus; c++) {
+ if ((bt->flags & BT_CPUMASK) &&
+ !(NUM_IN_BITMAP(bt->cpumask, c)))
+ continue;
+
+ fprintf(fp, "CPU %d IRQ STACK: ", c);
+ bt->stackbase = ms->irq_stacks[c];
+ bt->stacktop = bt->stackbase + ms->irq_stack_size;
+ alter_stackbuf(bt);
+
+ count = riscv64_dump_kernel_eframes(bt);
+
+ if (count)
+ fprintf(fp, "\n");
+ else
+ fprintf(fp, "(none found)\n\n");
+ }
+
+ return 0;
+ }
count = riscv64_dump_kernel_eframes(bt);
--
2.41.0

View File

@ -1,78 +0,0 @@
From 582febffa8b3567339148c2bb916fc70f2fc546e Mon Sep 17 00:00:00 2001
From: Johan Erlandsson <johan.erlandsson@sony.com>
Date: Fri, 20 Oct 2023 19:10:52 +0200
Subject: [PATCH 03/14] zram: Fixes for lookup_swap_cache()
Fix the following three issues:
(1) swap cache missing page tree offset
The radix or xarray start at an offset inside struct address_space.
(2) swap cache entries are pointer to struct page
The entries in radix, xarray (swap cache) are address to struct page.
(3) exclude shadow entries from swap cache lookup
radix or xarray can contain shadow entries from previous page
entries. These should be ignored when looking for a page pointer.
Without the patch,
- lookup_swap_cache() returns NULL since do_xarray() call returns FALSE,
- in try_zram_decompress(), since 'entry' is NULL, page is filled with 0,
if (!entry || (flags & ZRAM_FLAG_SAME_BIT)) {
and pages in swap cache will be seen to be a 'zero' page.
Signed-off-by: Johan Erlandsson <johan.erlandsson@sony.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
diskdump.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/diskdump.c b/diskdump.c
index f20f3ac519a1..660c25729dad 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -27,6 +27,7 @@
#include "diskdump.h"
#include "xen_dom0.h"
#include "vmcore.h"
+#include "maple_tree.h"
#define BITMAP_SECT_LEN 4096
@@ -2877,11 +2878,16 @@ out:
return zram_buf;
}
+static inline bool radix_tree_exceptional_entry(ulong entry)
+{
+ return entry & RADIX_TREE_EXCEPTIONAL_ENTRY;
+}
+
static unsigned char *
lookup_swap_cache(ulonglong pte_val, unsigned char *zram_buf)
{
ulonglong swp_offset;
- ulong swp_type, swp_space, page;
+ ulong swp_type, swp_space;
struct list_pair lp;
physaddr_t paddr;
static int is_xarray = -1;
@@ -2907,10 +2913,13 @@ lookup_swap_cache(ulonglong pte_val, unsigned char *zram_buf)
swp_space += (swp_offset >> SWAP_ADDRESS_SPACE_SHIFT) * SIZE(address_space);
lp.index = swp_offset;
- if ((is_xarray ? do_xarray : do_radix_tree)(swp_space, RADIX_TREE_SEARCH, &lp)) {
- readmem((ulong)lp.value, KVADDR, &page, sizeof(void *),
- "swap_cache page", FAULT_ON_ERROR);
- if (!is_page_ptr(page, &paddr)) {
+ if ((is_xarray ? do_xarray : do_radix_tree)
+ (swp_space+OFFSET(address_space_page_tree), RADIX_TREE_SEARCH, &lp)) {
+ if ((is_xarray ? xa_is_value : radix_tree_exceptional_entry)((ulong)lp.value)) {
+ /* ignore shadow values */
+ return NULL;
+ }
+ if (!is_page_ptr((ulong)lp.value, &paddr)) {
error(WARNING, "radix page: %lx: not a page pointer\n", lp.value);
return NULL;
}
--
2.41.0

View File

@ -1,287 +0,0 @@
From a69496279133705f095f790a9b3425266f88b1d4 Mon Sep 17 00:00:00 2001
From: Song Shuai <songshuaishuai@tinylab.org>
Date: Wed, 13 Dec 2023 17:45:08 +0800
Subject: [PATCH 4/6] RISCV64: Add per-cpu overflow stacks support
The patch introduces per-cpu overflow stacks for RISCV64 to let
"bt" do backtrace on it and the 'help -m' command dispalys the
addresss of each per-cpu overflow stack.
TEST: a lkdtm DIRECT EXHAUST_STACK vmcore
crash> bt
PID: 1 TASK: ff600000000d8000 CPU: 1 COMMAND: "sh"
#0 [ff6000001fc501c0] riscv_crash_save_regs at ffffffff8000a1dc
#1 [ff6000001fc50320] panic at ffffffff808773ec
#2 [ff6000001fc50380] walk_stackframe at ffffffff800056da
PC: ffffffff80876a34 [memset+96]
RA: ffffffff80563dc0 [recursive_loop+68]
SP: ff2000000000fd50 CAUSE: 000000000000000f
epc : ffffffff80876a34 ra : ffffffff80563dc0 sp : ff2000000000fd50
gp : ffffffff81515d38 tp : 0000000000000000 t0 : ff2000000000fd58
t1 : ff600000000d88c8 t2 : 6143203a6d74646b s0 : ff20000000010190
s1 : 0000000000000012 a0 : ff2000000000fd58 a1 : 1212121212121212
a2 : 0000000000000400 a3 : ff20000000010158 a4 : 0000000000000000
a5 : 725bedba92260900 a6 : 000000000130e0f0 a7 : 0000000000000000
s2 : ff2000000000fd58 s3 : ffffffff815170d8 s4 : ff20000000013e60
s5 : 000000000000000e s6 : ff20000000013e60 s7 : 0000000000000000
s8 : ff60000000861000 s9 : 00007fffc3641694 s10: 00007fffc3641690
s11: 00005555796ed240 t3 : 0000000000010297 t4 : ffffffff80c17810
t5 : ffffffff8195e7b8 t6 : ff20000000013b18
status: 0000000200000120 badaddr: ff2000000000fd58
cause: 000000000000000f orig_a0: 0000000000000000
--- <OVERFLOW stack> ---
#3 [ff2000000000fd50] memset at ffffffff80876a34
#4 [ff20000000010190] recursive_loop at ffffffff80563e16
#5 [ff200000000105d0] recursive_loop at ffffffff80563e16
< recursive_loop ...>
#16 [ff20000000013490] recursive_loop at ffffffff80563e16
#17 [ff200000000138d0] recursive_loop at ffffffff80563e16
#18 [ff20000000013d10] lkdtm_EXHAUST_STACK at ffffffff8088005e
#19 [ff20000000013d30] lkdtm_do_action at ffffffff80563292
#20 [ff20000000013d40] direct_entry at ffffffff80563474
#21 [ff20000000013d70] full_proxy_write at ffffffff8032fb3a
#22 [ff20000000013db0] vfs_write at ffffffff801d6414
#23 [ff20000000013e60] ksys_write at ffffffff801d67b8
#24 [ff20000000013eb0] __riscv_sys_write at ffffffff801d6832
#25 [ff20000000013ec0] do_trap_ecall_u at ffffffff80884a20
crash>
crash> help -m
<snip>
irq_stack_size: 16384
irq_stacks[0]: ff20000000000000
irq_stacks[1]: ff20000000008000
overflow_stack_size: 4096
overflow_stacks[0]: ff6000001fa7a510
overflow_stacks[1]: ff6000001fc4f510
crash>
Signed-off-by: Song Shuai <songshuaishuai@tinylab.org>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 6 +++
riscv64.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 118 insertions(+), 1 deletion(-)
diff --git a/defs.h b/defs.h
index b71cdbd01b8d..2a29c07305f2 100644
--- a/defs.h
+++ b/defs.h
@@ -3655,6 +3655,9 @@ typedef signed int s32;
#define VM_L5_2M (0x100)
#define VM_L5_1G (0x200)
#define IRQ_STACKS (0x400)
+#define OVERFLOW_STACKS (0x800)
+
+#define RISCV64_OVERFLOW_STACK_SIZE (1 << 12)
#define VM_FLAGS (VM_L3_4K | VM_L3_2M | VM_L3_1G | \
VM_L4_4K | VM_L4_2M | VM_L4_1G | \
@@ -7061,6 +7064,9 @@ struct machine_specific {
struct riscv64_register *crash_task_regs;
ulong irq_stack_size;
ulong *irq_stacks;
+
+ ulong overflow_stack_size;
+ ulong *overflow_stacks;
};
/* from arch/riscv/include/asm/pgtable-bits.h */
#define _PAGE_PRESENT (machdep->machspec->_page_present)
diff --git a/riscv64.c b/riscv64.c
index a26b8a43cb29..98bf02a59b12 100644
--- a/riscv64.c
+++ b/riscv64.c
@@ -34,6 +34,7 @@ static int riscv64_kvtop(struct task_context *tc, ulong kvaddr,
physaddr_t *paddr, int verbose);
static void riscv64_cmd_mach(void);
static void riscv64_irq_stack_init(void);
+static void riscv64_overflow_stack_init(void);
static void riscv64_stackframe_init(void);
static void riscv64_back_trace_cmd(struct bt_info *bt);
static int riscv64_eframe_search(struct bt_info *bt);
@@ -59,6 +60,8 @@ static int riscv64_on_irq_stack(int , ulong);
static int riscv64_on_process_stack(struct bt_info *, ulong );
static void riscv64_set_process_stack(struct bt_info *);
static void riscv64_set_irq_stack(struct bt_info *);
+static int riscv64_on_overflow_stack(int, ulong);
+static void riscv64_set_overflow_stack(struct bt_info *);
#define REG_FMT "%016lx"
#define SZ_2G 0x80000000
@@ -206,6 +209,8 @@ riscv64_dump_machdep_table(ulong arg)
fprintf(fp, "%sKSYMS_START", others++ ? "|" : "");
if (machdep->flags & IRQ_STACKS)
fprintf(fp, "%sIRQ_STACKS", others++ ? "|" : "");
+ if (machdep->flags & OVERFLOW_STACKS)
+ fprintf(fp, "%sOVERFLOW_STACKS", others++ ? "|" : "");
fprintf(fp, ")\n");
fprintf(fp, " kvbase: %lx\n", machdep->kvbase);
@@ -270,6 +275,15 @@ riscv64_dump_machdep_table(ulong arg)
fprintf(fp, " irq_stack_size: (unused)\n");
fprintf(fp, " irq_stacks: (unused)\n");
}
+ if (machdep->flags & OVERFLOW_STACKS) {
+ fprintf(fp, " overflow_stack_size: %ld\n", ms->overflow_stack_size);
+ for (i = 0; i < kt->cpus; i++)
+ fprintf(fp, " overflow_stacks[%d]: %lx\n",
+ i, ms->overflow_stacks[i]);
+ } else {
+ fprintf(fp, " overflow_stack_size: (unused)\n");
+ fprintf(fp, " overflow_stacks: (unused)\n");
+ }
}
static ulong
@@ -684,6 +698,48 @@ riscv64_display_full_frame(struct bt_info *bt, struct riscv64_unwind_frame *curr
fprintf(fp, "\n");
}
+
+/*
+ * Gather Overflow stack values.
+ */
+static void
+riscv64_overflow_stack_init(void)
+{
+ int i;
+ struct syment *sp;
+ struct gnu_request request, *req;
+ struct machine_specific *ms = machdep->machspec;
+ req = &request;
+
+ if (symbol_exists("overflow_stack") &&
+ (sp = per_cpu_symbol_search("overflow_stack")) &&
+ get_symbol_type("overflow_stack", NULL, req)) {
+ if (CRASHDEBUG(1)) {
+ fprintf(fp, "overflow_stack: \n");
+ fprintf(fp, " type: %x, %s\n",
+ (int)req->typecode,
+ (req->typecode == TYPE_CODE_ARRAY) ?
+ "TYPE_CODE_ARRAY" : "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->overflow_stacks = (ulong *)malloc((size_t)(kt->cpus * sizeof(ulong)))))
+ error(FATAL, "cannot malloc overflow_stack addresses\n");
+
+ ms->overflow_stack_size = RISCV64_OVERFLOW_STACK_SIZE;
+ machdep->flags |= OVERFLOW_STACKS;
+
+ for (i = 0; i < kt->cpus; i++)
+ ms->overflow_stacks[i] = kt->__per_cpu_offset[i] + sp->value;
+ }
+}
+
/*
* Gather IRQ stack values.
*/
@@ -757,6 +813,23 @@ riscv64_on_irq_stack(int cpu, ulong stkptr)
return FALSE;
}
+static int
+riscv64_on_overflow_stack(int cpu, ulong stkptr)
+{
+ struct machine_specific *ms = machdep->machspec;
+ ulong * stacks = ms->overflow_stacks;
+ ulong stack_size = ms->overflow_stack_size;
+
+ if ((cpu >= kt->cpus) || (stacks == NULL) || !stack_size)
+ return FALSE;
+
+ if ((stkptr >= stacks[cpu]) &&
+ (stkptr < (stacks[cpu] + stack_size)))
+ return TRUE;
+
+ return FALSE;
+}
+
static int
riscv64_on_process_stack(struct bt_info *bt, ulong stkptr)
{
@@ -781,6 +854,16 @@ riscv64_set_irq_stack(struct bt_info *bt)
alter_stackbuf(bt);
}
+static void
+riscv64_set_overflow_stack(struct bt_info *bt)
+{
+ struct machine_specific *ms = machdep->machspec;
+
+ bt->stackbase = ms->overflow_stacks[bt->tc->processor];
+ bt->stacktop = bt->stackbase + ms->overflow_stack_size;
+ alter_stackbuf(bt);
+}
+
static void
riscv64_set_process_stack(struct bt_info *bt)
{
@@ -875,7 +958,7 @@ riscv64_back_trace_cmd(struct bt_info *bt)
{
struct riscv64_unwind_frame current, previous;
struct stackframe curr_frame;
- struct riscv64_register *regs, *irq_regs;
+ struct riscv64_register *regs, *irq_regs, *overflow_regs;
int level = 0;
if (bt->flags & BT_REGS_NOT_FOUND)
@@ -888,6 +971,11 @@ riscv64_back_trace_cmd(struct bt_info *bt)
bt->flags |= BT_IRQSTACK;
}
+ if (riscv64_on_overflow_stack(bt->tc->processor, bt->frameptr)) {
+ riscv64_set_overflow_stack(bt);
+ bt->flags |= BT_OVERFLOW_STACK;
+ }
+
current.pc = bt->instptr;
current.sp = bt->stkptr;
current.fp = bt->frameptr;
@@ -971,6 +1059,28 @@ riscv64_back_trace_cmd(struct bt_info *bt)
}
}
+ /*
+ * When backtracing to handle_kernel_stack_overflow()
+ * use pt_regs saved in overflow stack to continue
+ */
+ if ((bt->flags & BT_OVERFLOW_STACK) &&
+ !riscv64_on_overflow_stack(bt->tc->processor, current.fp)) {
+
+ overflow_regs = (struct riscv64_register *)
+ &bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(current.sp))];
+
+ riscv64_print_exception_frame(bt, current.sp, KERNEL_MODE);
+
+ current.pc = overflow_regs->regs[RISCV64_REGS_EPC];
+ current.fp = overflow_regs->regs[RISCV64_REGS_FP];
+ current.sp = overflow_regs->regs[RISCV64_REGS_SP];
+
+ riscv64_set_process_stack(bt);
+
+ bt->flags &= ~BT_OVERFLOW_STACK;
+ fprintf(fp, "--- <OVERFLOW stack> ---\n");
+ }
+
if (CRASHDEBUG(8))
fprintf(fp, "next %d pc %#lx sp %#lx fp %lx\n",
level, current.pc, current.sp, current.fp);
@@ -1583,6 +1693,7 @@ riscv64_init(int when)
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
riscv64_irq_stack_init();
+ riscv64_overflow_stack_init();
riscv64_stackframe_init();
riscv64_page_type_init();
--
2.41.0

View File

@ -1,171 +0,0 @@
From f2ee6fa6c841ddc37ba665909dafbc7294c34d64 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Fri, 17 Nov 2023 15:52:19 +0800
Subject: [PATCH 04/14] symbols: expand all kernel module symtable if not all
expanded previously
There is an issue that, for kernel modules, "dis -rl" fails to display
modules code line number data after execute "bt" command in crash.
Without the patch:
crsah> mod -S
crash> bt
PID: 1500 TASK: ff2bd8b093524000 CPU: 16 COMMAND: "lpfc_worker_0"
#0 [ff2c9f725c39f9e0] machine_kexec at ffffffff8e0686d3
...snip...
#8 [ff2c9f725c39fcc0] __lpfc_sli_release_iocbq_s4 at ffffffffc0f2f425 [lpfc]
...snip...
crash> dis -rl ffffffffc0f60f82
0xffffffffc0f60eb0 <lpfc_nlp_get>: nopl 0x0(%rax,%rax,1) [FTRACE NOP]
0xffffffffc0f60eb5 <lpfc_nlp_get+5>: push %rbp
0xffffffffc0f60eb6 <lpfc_nlp_get+6>: push %rbx
0xffffffffc0f60eb7 <lpfc_nlp_get+7>: test %rdi,%rdi
With the patch:
crash> mod -S
crash> bt
PID: 1500 TASK: ff2bd8b093524000 CPU: 16 COMMAND: "lpfc_worker_0"
#0 [ff2c9f725c39f9e0] machine_kexec at ffffffff8e0686d3
...snip...
#8 [ff2c9f725c39fcc0] __lpfc_sli_release_iocbq_s4 at ffffffffc0f2f425 [lpfc]
...snip...
crash> dis -rl ffffffffc0f60f82
/usr/src/debug/kernel-4.18.0-425.13.1.el8_7/linux-4.18.0-425.13.1.el8_7.x86_64/drivers/scsi/lpfc/lpfc_hbadisc.c: 6756
0xffffffffc0f60eb0 <lpfc_nlp_get>: nopl 0x0(%rax,%rax,1) [FTRACE NOP]
/usr/src/debug/kernel-4.18.0-425.13.1.el8_7/linux-4.18.0-425.13.1.el8_7.x86_64/drivers/scsi/lpfc/lpfc_hbadisc.c: 6759
0xffffffffc0f60eb5 <lpfc_nlp_get+5>: push %rbp
The root cause is, after kernel module been loaded by mod command, the symtable
is not expanded in gdb side. crash bt or dis command will trigger such an
expansion. However the symtable expansion is different for the 2 commands:
The stack trace of "dis -rl" for symtable expanding:
#0 0x00000000008d8d9f in add_compunit_symtab_to_objfile ...
#1 0x00000000006d3293 in buildsym_compunit::end_symtab_with_blockvector ...
#2 0x00000000006d336a in buildsym_compunit::end_symtab_from_static_block ...
#3 0x000000000077e8e9 in process_full_comp_unit ...
#4 process_queue ...
#5 dw2_do_instantiate_symtab ...
#6 0x000000000077ed67 in dw2_instantiate_symtab ...
#7 0x000000000077f75e in dw2_expand_all_symtabs ...
#8 0x00000000008f254d in gdb_get_line_number ...
#9 0x00000000008f22af in gdb_command_funnel_1 ...
#10 0x00000000008f2003 in gdb_command_funnel ...
#11 0x00000000005b7f02 in gdb_interface ...
#12 0x00000000005f5bd8 in get_line_number ...
#13 0x000000000059e574 in cmd_dis ...
The stack trace of "bt" for symtable expanding:
#0 0x00000000008d8d9f in add_compunit_symtab_to_objfile ...
#1 0x00000000006d3293 in buildsym_compunit::end_symtab_with_blockvector ...
#2 0x00000000006d336a in buildsym_compunit::end_symtab_from_static_block ...
#3 0x000000000077e8e9 in process_full_comp_unit ...
#4 process_queue ...
#5 dw2_do_instantiate_symtab ...
#6 0x000000000077ed67 in dw2_instantiate_symtab ...
#7 0x000000000077f8ed in dw2_lookup_symbol ...
#8 0x00000000008e6d03 in lookup_symbol_via_quick_fns ...
#9 0x00000000008e7153 in lookup_symbol_in_objfile ...
#10 0x00000000008e73c6 in lookup_symbol_global_or_static_iterator_cb ...
#11 0x00000000008b99c4 in svr4_iterate_over_objfiles_in_search_order ...
#12 0x00000000008e754e in lookup_global_or_static_symbol ...
#13 0x00000000008e75da in lookup_static_symbol ...
#14 0x00000000008e632c in lookup_symbol_aux ...
#15 0x00000000008e5a7a in lookup_symbol_in_language ...
#16 0x00000000008e5b30 in lookup_symbol ...
#17 0x00000000008f2a4a in gdb_get_datatype ...
#18 0x00000000008f22c0 in gdb_command_funnel_1 ...
#19 0x00000000008f2003 in gdb_command_funnel ...
#20 0x00000000005b7f02 in gdb_interface ...
#21 0x00000000005f8a9f in datatype_info ...
#22 0x0000000000599947 in cpu_map_size ...
#23 0x00000000005a975d in get_cpus_online ...
#24 0x0000000000637a8b in diskdump_get_prstatus_percpu ...
#25 0x000000000062f0e4 in get_netdump_regs_x86_64 ...
#26 0x000000000059fe68 in back_trace ...
#27 0x00000000005ab1cb in cmd_bt ...
For the stacktrace of "dis -rl", it calls dw2_expand_all_symtabs() to expand
all symtable of the objfile, or "*.ko.debug" in our case. However for
the stacktrace of "bt", it doesn't expand all, but only a subset of symtable
which is enough to find a symbol by dw2_lookup_symbol(). As a result, the
objfile->compunit_symtabs, which is the head of a single linked list of
struct compunit_symtab, is not NULL but didn't contain all symtables. It
will not be reinitialized in gdb_get_line_number() by "dis -rl" because
!objfile_has_full_symbols(objfile) check will fail, so it cannot display
the proper code line number data.
Since objfile_has_full_symbols(objfile) check cannot ensure all symbols
been expanded, this patch add a new member as a flag for struct objfile
to record if all symbols have been expanded. The flag will be set only ofter
expand_all_symtabs been called.
Signed-off-by: Tao Liu <ltao@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
gdb-10.2.patch | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/gdb-10.2.patch b/gdb-10.2.patch
index d81030d946e8..2f7d585105aa 100644
--- a/gdb-10.2.patch
+++ b/gdb-10.2.patch
@@ -3187,3 +3187,53 @@ exit 0
result = stringtab + symbol_entry->_n._n_n._n_offset;
}
else
+--- gdb-10.2/gdb/objfiles.h.orig
++++ gdb-10.2/gdb/objfiles.h
+@@ -712,6 +712,8 @@ struct objfile
+ next time. If an objfile does not have the symbols, it will
+ never have them. */
+ bool skip_jit_symbol_lookup = false;
++
++ bool all_symtabs_expanded = false;
+ };
+
+ /* A deleter for objfile. */
+--- gdb-10.2/gdb/symfile.c.orig
++++ gdb-10.2/gdb/symfile.c
+@@ -1133,8 +1133,10 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name,
+ printf_filtered (_("Expanding full symbols from %ps...\n"),
+ styled_string (file_name_style.style (), name));
+
+- if (objfile->sf)
++ if (objfile->sf) {
+ objfile->sf->qf->expand_all_symtabs (objfile);
++ objfile->all_symtabs_expanded = true;
++ }
+ }
+
+ /* Note that we only print a message if we have no symbols and have
+--- gdb-10.2/gdb/symtab.c.orig
++++ gdb-10.2/gdb/symtab.c
+@@ -7097,8 +7097,9 @@ gdb_get_line_number(struct gnu_request *req)
+ */
+ if (req->lm) {
+ objfile = req->lm->loaded_objfile;
+- if (!objfile_has_full_symbols(objfile) && objfile->sf) {
++ if (!objfile->all_symtabs_expanded && objfile->sf) {
+ objfile->sf->qf->expand_all_symtabs(objfile);
++ objfile->all_symtabs_expanded = true;
+ sal = find_pc_line(pc, 0);
+ }
+ }
+@@ -7761,8 +7765,10 @@ iterate_datatypes (struct gnu_request *req)
+ {
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+- if (objfile->sf)
++ if (objfile->sf) {
+ objfile->sf->qf->expand_all_symtabs(objfile);
++ objfile->all_symtabs_expanded = true;
++ }
+
+ for (compunit_symtab *cust : objfile->compunits ())
+ {
--
2.41.0

View File

@ -1,67 +0,0 @@
From 0c5ef6a4a3a2759915ffe72b1366dce2f32f65c5 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Tue, 14 Nov 2023 16:32:07 +0800
Subject: [PATCH 05/14] symbols: skip load .init.* sections if module was
successfully initialized
There might be address overlap of one modules .init.text symbols and
another modules .text symbols. As a result, gdb fails to translate the
address to symbol name correctly:
crash> sym -m virtio_blk | grep MODULE
ffffffffc00a4000 MODULE START: virtio_blk
ffffffffc00a86ec MODULE END: virtio_blk
crash> gdb info address floppy_module_init
Symbol "floppy_module_init" is a function at address 0xffffffffc00a4131.
Since the .init.* sections of a module had been freed by kernel if the
module was initialized successfully, there is no need to load the .init.*
sections data from "*.ko.debug" in gdb to create such an overlap.
lm->mod_init_module_ptr is used as a flag of whether module is freed.
Without the patch:
crash> mod -S
crash> struct blk_mq_ops 0xffffffffc00a7160
struct blk_mq_ops {
queue_rq = 0xffffffffc00a45b0 <floppy_module_init+1151>, <-- translated from module floppy
map_queue = 0xffffffff813015c0 <blk_mq_map_queue>,
...snip...
complete = 0xffffffffc00a4370 <floppy_module_init+575>,
init_request = 0xffffffffc00a4260 <floppy_module_init+303>,
...snip...
}
With the patch:
crash> mod -S
crash> struct blk_mq_ops 0xffffffffc00a7160
struct blk_mq_ops {
queue_rq = 0xffffffffc00a45b0 <virtio_queue_rq>, <-- translated from module virtio_blk
map_queue = 0xffffffff813015c0 <blk_mq_map_queue>,
...snip...
complete = 0xffffffffc00a4370 <virtblk_request_done>,
init_request = 0xffffffffc00a4260 <virtblk_init_request>,
...snip...
}
Signed-off-by: Tao Liu <ltao@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
symbols.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/symbols.c b/symbols.c
index 176c95026f03..5d919910164e 100644
--- a/symbols.c
+++ b/symbols.c
@@ -13295,7 +13295,7 @@ add_symbol_file_kallsyms(struct load_module *lm, struct gnu_request *req)
shift_string_right(req->buf, strlen(buf));
BCOPY(buf, req->buf, strlen(buf));
retval = TRUE;
- } else {
+ } else if (lm->mod_init_module_ptr || !STRNEQ(section_name, ".init.")) {
sprintf(buf, " -s %s 0x%lx", section_name, section_vaddr);
while ((len + strlen(buf)) >= buflen) {
RESIZEBUF(req->buf, buflen, buflen * 2);
--
2.41.0

View File

@ -1,63 +0,0 @@
From aed1b7d3a064112d5c34eff81fa9ca0c50c5c782 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Tue, 16 Jan 2024 17:00:48 +0900
Subject: [PATCH 5/6] x86_64: Fix "bt" command not printing stack trace enough
On recent x86_64 kernels, the check of caller function (BT_CHECK_CALLER)
does not work correctly due to inappropriate direct_call_targets. As a
result, the correct frame is ignored and the remaining frames will be
truncated.
Skip the caller check if ORC unwinder is available, as the check is not
necessary with it.
Without the patch:
crash> bt 493113
PID: 493113 TASK: ff2e34ecbd3ca2c0 CPU: 27 COMMAND: "sriov_fec_daemo"
#0 [ff77abc4e81cfb08] __schedule at ffffffff81b239cb
#1 [ff77abc4e81cfb70] schedule at ffffffff81b23e2d
#2 [ff77abc4e81cfb88] schedule_timeout at ffffffff81b2c9e8
RIP: 000000000047cdbb RSP: 000000c0000975a8 RFLAGS: 00000216
...
With the patch:
crash> bt 493113
PID: 493113 TASK: ff2e34ecbd3ca2c0 CPU: 27 COMMAND: "sriov_fec_daemo"
#0 [ff77abc4e81cfb08] __schedule at ffffffff81b239cb
#1 [ff77abc4e81cfb70] schedule at ffffffff81b23e2d
#2 [ff77abc4e81cfb88] schedule_timeout at ffffffff81b2c9e8
#3 [ff77abc4e81cfbf0] __wait_for_common at ffffffff81b24abb
#4 [ff77abc4e81cfc68] vfio_unregister_group_dev at ffffffffc10e76ae [vfio]
#5 [ff77abc4e81cfca8] vfio_pci_core_unregister_device at ffffffffc11bb599 [vfio_pci_core]
#6 [ff77abc4e81cfcc0] vfio_pci_remove at ffffffffc103e045 [vfio_pci]
#7 [ff77abc4e81cfcd0] pci_device_remove at ffffffff815d7513
...
Reported-by: Crystal Wood <crwood@redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
x86_64.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/x86_64.c b/x86_64.c
index f59991f8c4c5..502817d3b2bd 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -3342,6 +3342,13 @@ x86_64_print_stack_entry(struct bt_info *bt, FILE *ofp, int level,
bt->call_target = name;
+ /*
+ * The caller check below does not work correctly for some kernels,
+ * so skip it if ORC unwinder is available.
+ */
+ if (machdep->flags & ORC)
+ return result;
+
if (is_direct_call_target(bt)) {
if (CRASHDEBUG(2))
fprintf(ofp, "< enable BT_CHECK_CALLER for %s >\n",
--
2.41.0

View File

@ -1,88 +0,0 @@
From 28891d1127542dbb2d5ba16c575e14e741ed73ef Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Thu, 4 Jan 2024 09:20:27 +0800
Subject: [PATCH 6/6] symbols: skip the module if the given address is not
within its address range
Previously, to find a module symbol and its offset by an arbitrary address,
all symbols within the module will be iterated by address ascending order
until the last symbol with a smaller address been noticed.
However if the address is not within the module address range, e.g.
the address is higher than the module's last symbol's address, then
the module can be surely skipped, because its symbol iteration is
unnecessary. This can speed up the kernel module symbols finding and improve
the overall performance.
Without the patch:
$ time echo "bt 8993" | ~/crash-dev/crash vmcore vmlinux
crash> bt 8993
PID: 8993 TASK: ffff927569cc2100 CPU: 2 COMMAND: "WriterPool0"
#0 [ffff927569cd76f0] __schedule at ffffffffb3db78d8
#1 [ffff927569cd7758] schedule_preempt_disabled at ffffffffb3db8bf9
#2 [ffff927569cd7768] __mutex_lock_slowpath at ffffffffb3db6ca7
#3 [ffff927569cd77c0] mutex_lock at ffffffffb3db602f
#4 [ffff927569cd77d8] ucache_retrieve at ffffffffc0cf4409 [secfs2]
...snip the stacktrace of the same module...
#11 [ffff927569cd7ba0] cskal_path_vfs_getattr_nosec at ffffffffc05cae76 [falcon_kal]
...snip...
#13 [ffff927569cd7c40] _ZdlPv at ffffffffc086e751 [falcon_lsm_serviceable]
...snip...
#20 [ffff927569cd7ef8] unload_network_ops_symbols at ffffffffc06f11c0 [falcon_lsm_pinned_14713]
#21 [ffff927569cd7f50] system_call_fastpath at ffffffffb3dc539a
RIP: 00007f2b28ed4023 RSP: 00007f2a45fe7f80 RFLAGS: 00000206
RAX: 0000000000000012 RBX: 00007f2a68302e00 RCX: 00007f2a682546d8
RDX: 0000000000000826 RSI: 00007eb57ea6a000 RDI: 00000000000000e3
RBP: 00007eb57ea6a000 R8: 0000000000000826 R9: 00000002670bdfd2
R10: 00000002670bdfd2 R11: 0000000000000293 R12: 00000002670bdfd2
R13: 00007f29d501a480 R14: 0000000000000826 R15: 00000002670bdfd2
ORIG_RAX: 0000000000000012 CS: 0033 SS: 002b
crash>
real 7m14.826s
user 7m12.502s
sys 0m1.091s
With the patch:
$ time echo "bt 8993" | ~/crash-dev/crash vmcore vmlinux
crash> bt 8993
PID: 8993 TASK: ffff927569cc2100 CPU: 2 COMMAND: "WriterPool0"
#0 [ffff927569cd76f0] __schedule at ffffffffb3db78d8
#1 [ffff927569cd7758] schedule_preempt_disabled at ffffffffb3db8bf9
...snip the same output...
crash>
real 0m8.827s
user 0m7.896s
sys 0m0.938s
Signed-off-by: Tao Liu <ltao@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
symbols.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/symbols.c b/symbols.c
index 5d919910164e..88a3fd156cb5 100644
--- a/symbols.c
+++ b/symbols.c
@@ -5561,7 +5561,7 @@ value_search_module_6_4(ulong value, ulong *offset)
sp = lm->symtable[t];
sp_end = lm->symend[t];
- if (value < sp->value)
+ if (value < sp->value || value > sp_end->value)
continue;
splast = NULL;
@@ -5646,6 +5646,9 @@ retry:
if (sp->value > value) /* invalid -- between modules */
break;
+ if (sp_end->value < value) /* not within the module */
+ continue;
+
/*
* splast will contain the last module symbol encountered.
* Note: "__insmod_"-type symbols will be set in splast only
--
2.41.0

View File

@ -1,47 +0,0 @@
From c15da07526291a5c357010cb4aaf4bde6151e642 Mon Sep 17 00:00:00 2001
From: Johan Erlandsson <johan.erlandsson@sony.com>
Date: Wed, 19 Apr 2023 11:26:04 +0200
Subject: [PATCH 06/14] use NR_SWAPCACHE when nr_swapper_spaces isn't available
In 5.12 the following change was introduced:
b6038942480e ("mm: memcg: add swapcache stat for memcg v2")
Then the variable 'nr_swapper_spaces' is not read (unless
CONFIG_DEBUG_VM=y). In GKI builds this variable is then optimized
out. But the same change provided a new way to obtain the same
information, using NR_SWAPCACHE.
Reported-by: xueguolun <xueguolun@xiaomi.com>
Signed-off-by: Johan Erlandsson <johan.erlandsson@sony.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
memory.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/memory.c b/memory.c
index 791194a405d4..b84e974a3325 100644
--- a/memory.c
+++ b/memory.c
@@ -8486,7 +8486,7 @@ dump_kmeminfo(void)
ulong hugetlb_total_pages, hugetlb_total_free_pages = 0;
int done_hugetlb_calc = 0;
long nr_file_pages, nr_slab;
- ulong swapper_space_nrpages;
+ long swapper_space_nrpages;
ulong pct;
uint tmp;
struct meminfo meminfo;
@@ -8609,7 +8609,9 @@ dump_kmeminfo(void)
char *swapper_space = GETBUF(SIZE(address_space));
swapper_space_nrpages = 0;
- if (symbol_exists("nr_swapper_spaces") &&
+ if (dump_vm_stat("NR_SWAPCACHE", &swapper_space_nrpages, 0)) {
+ ;
+ } else if (symbol_exists("nr_swapper_spaces") &&
(len = get_array_length("nr_swapper_spaces",
NULL, 0))) {
char *nr_swapper_space =
--
2.41.0

View File

@ -1,43 +0,0 @@
From 2e513114e7d77fadc88011f186ef943ccf397d35 Mon Sep 17 00:00:00 2001
From: Alexander Gordeev <agordeev@linux.ibm.com>
Date: Wed, 29 Nov 2023 13:47:34 +0100
Subject: [PATCH 07/14] Fix identity_map_base value dump on S390
Kernel virtual base instead of identity base is printed
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
s390.c | 2 +-
s390x.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/s390.c b/s390.c
index 42f5cc63ae52..a8b2bcca86c7 100644
--- a/s390.c
+++ b/s390.c
@@ -183,7 +183,7 @@ s390_dump_machdep_table(ulong arg)
fprintf(fp, ")\n");
fprintf(fp, " kvbase: %lx\n", machdep->kvbase);
- fprintf(fp, " identity_map_base: %lx\n", machdep->kvbase);
+ fprintf(fp, " identity_map_base: %lx\n", machdep->identity_map_base);
fprintf(fp, " pagesize: %d\n", machdep->pagesize);
fprintf(fp, " pageshift: %d\n", machdep->pageshift);
fprintf(fp, " pagemask: %llx\n", machdep->pagemask);
diff --git a/s390x.c b/s390x.c
index d7ee3755fc0b..096c072186f5 100644
--- a/s390x.c
+++ b/s390x.c
@@ -650,7 +650,7 @@ s390x_dump_machdep_table(ulong arg)
fprintf(fp, ")\n");
fprintf(fp, " kvbase: %lx\n", machdep->kvbase);
- fprintf(fp, " identity_map_base: %lx\n", machdep->kvbase);
+ fprintf(fp, " identity_map_base: %lx\n", machdep->identity_map_base);
fprintf(fp, " pagesize: %d\n", machdep->pagesize);
fprintf(fp, " pageshift: %d\n", machdep->pageshift);
fprintf(fp, " pagemask: %llx\n", machdep->pagemask);
--
2.41.0

View File

@ -1,70 +0,0 @@
From 4c78eb4a9199631fe94845cb3fbd6376aae1251d Mon Sep 17 00:00:00 2001
From: Alexander Gordeev <agordeev@linux.ibm.com>
Date: Wed, 29 Nov 2023 13:47:35 +0100
Subject: [PATCH 08/14] s390x: fix virtual vs physical address confusion
Physical and virtual addresses are the same on S390X.
That led to missing to use PTOV and VTOP macros where
they actually expected.
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
s390x.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/s390x.c b/s390x.c
index 096c072186f5..957b839a5fa9 100644
--- a/s390x.c
+++ b/s390x.c
@@ -311,7 +311,7 @@ static struct s390x_cpu *s390x_cpu_get(struct bt_info *bt)
readmem(lowcore_ptr + cpu * sizeof(long), KVADDR,
&prefix, sizeof(long), "lowcore_ptr", FAULT_ON_ERROR);
for (i = 0; i < s390x_cpu_cnt; i++) {
- if (s390x_cpu_vec[i].prefix == prefix)
+ if (s390x_cpu_vec[i].prefix == VTOP(prefix))
return &s390x_cpu_vec[i];
}
error(FATAL, "cannot determine CPU for task: %lx\n", bt->task);
@@ -985,12 +985,12 @@ int s390x_vtop(ulong table, ulong vaddr, physaddr_t *phys_addr, int verbose)
verbose);
if (!entry)
return FALSE;
- table = entry & ~0xfffULL;
+ table = PTOV(entry & ~0xfffULL);
/* Check if this a 2GB page */
if ((entry & 0x400ULL) && (level == 1)) {
/* Add the 2GB frame offset & return the final value. */
table &= ~0x7fffffffULL;
- *phys_addr = table + (vaddr & 0x7fffffffULL);
+ *phys_addr = VTOP(table + (vaddr & 0x7fffffffULL));
return TRUE;
}
len = entry & 0x3ULL;
@@ -1001,12 +1001,12 @@ int s390x_vtop(ulong table, ulong vaddr, physaddr_t *phys_addr, int verbose)
if (entry & 0x400ULL) {
/* Add the 1MB page offset and return the final value. */
table &= ~0xfffffULL;
- *phys_addr = table + (vaddr & 0xfffffULL);
+ *phys_addr = VTOP(table + (vaddr & 0xfffffULL));
return TRUE;
}
/* Get the page table entry */
- entry = _kl_pg_table_deref_s390x(vaddr, entry & ~0x7ffULL, verbose);
+ entry = _kl_pg_table_deref_s390x(vaddr, PTOV(entry & ~0x7ffULL), verbose);
if (!entry)
return FALSE;
@@ -1033,7 +1033,7 @@ s390x_vmalloc_start(void)
{
unsigned long highmem_addr,high_memory;
highmem_addr=symbol_value("high_memory");
- readmem(highmem_addr, PHYSADDR, &high_memory,sizeof(long),
+ readmem(highmem_addr, KVADDR, &high_memory,sizeof(long),
"highmem",FAULT_ON_ERROR);
return high_memory;
}
--
2.41.0

View File

@ -1,323 +0,0 @@
From d0164e7e480ad2ffd3fe73fe53c46087e5e137a6 Mon Sep 17 00:00:00 2001
From: Alexander Gordeev <agordeev@linux.ibm.com>
Date: Thu, 7 Dec 2023 16:54:06 +0100
Subject: [PATCH 09/14] s390x: uncouple physical and virtual memory spaces
Rework VTOP and PTOV macros to reflect the future
uncoupling of physical and virtual address spaces
in kernel. Existing versions are not affected.
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 20 +++++-
s390x.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 228 insertions(+), 4 deletions(-)
diff --git a/defs.h b/defs.h
index 5218a94fe4a4..20237b72a10b 100644
--- a/defs.h
+++ b/defs.h
@@ -4564,9 +4564,9 @@ struct efi_memory_desc_t {
#define _64BIT_
#define MACHINE_TYPE "S390X"
-#define PTOV(X) ((unsigned long)(X)+(machdep->kvbase))
-#define VTOP(X) ((unsigned long)(X)-(machdep->kvbase))
-#define IS_VMALLOC_ADDR(X) (vt->vmalloc_start && (ulong)(X) >= vt->vmalloc_start)
+#define PTOV(X) s390x_PTOV((ulong)(X))
+#define VTOP(X) s390x_VTOP((ulong)(X))
+#define IS_VMALLOC_ADDR(X) s390x_IS_VMALLOC_ADDR(X)
#define PTRS_PER_PTE 512
#define PTRS_PER_PMD 1024
#define PTRS_PER_PGD 2048
@@ -6827,7 +6827,21 @@ void get_s390_panicmsg(char *);
* s390x.c
*/
#ifdef S390X
+
+struct machine_specific
+{
+ ulong (*virt_to_phys)(ulong vaddr);
+ ulong (*phys_to_virt)(ulong paddr);
+ int (*is_vmalloc_addr)(ulong vaddr);
+ ulong __kaslr_offset_phys;
+ ulong amode31_start;
+ ulong amode31_end;
+};
+
void s390x_init(int);
+ulong s390x_PTOV(ulong);
+ulong s390x_VTOP(ulong);
+int s390x_IS_VMALLOC_ADDR(ulong);
void s390x_dump_machdep_table(ulong);
#define display_idt_table() \
error(FATAL, "-d option is not applicable to S390X architecture\n")
diff --git a/s390x.c b/s390x.c
index 957b839a5fa9..794ae825906d 100644
--- a/s390x.c
+++ b/s390x.c
@@ -47,6 +47,7 @@
#define S390X_PSW_MASK_PSTATE 0x0001000000000000UL
#define S390X_LC_VMCORE_INFO 0xe0c
+#define S390X_LC_OS_INFO 0xe18
/*
* Flags for Region and Segment table entries.
@@ -168,6 +169,19 @@ static struct line_number_hook s390x_line_number_hooks[];
static int s390x_is_uvaddr(ulong, struct task_context *);
static int s390x_get_kvaddr_ranges(struct vaddr_range *);
static int set_s390x_max_physmem_bits(void);
+static ulong s390x_generic_VTOP(ulong vaddr);
+static ulong s390x_generic_PTOV(ulong paddr);
+static int s390x_generic_IS_VMALLOC_ADDR(ulong vaddr);
+static ulong s390x_vr_VTOP(ulong vaddr);
+static ulong s390x_vr_PTOV(ulong paddr);
+static int s390x_vr_IS_VMALLOC_ADDR(ulong vaddr);
+static int s390x_vr_is_kvaddr(ulong);
+
+struct machine_specific s390x_machine_specific = {
+ .virt_to_phys = s390x_generic_VTOP,
+ .phys_to_virt = s390x_generic_PTOV,
+ .is_vmalloc_addr = s390x_generic_IS_VMALLOC_ADDR,
+};
/*
* struct lowcore name (old: "_lowcore", new: "lowcore")
@@ -546,6 +560,191 @@ static void s390x_check_kaslr(void)
free(vmcoreinfo);
}
+#define OS_INFO_VERSION_MAJOR 1
+#define OS_INFO_VERSION_MINOR 1
+
+#define OS_INFO_VMCOREINFO 0
+#define OS_INFO_REIPL_BLOCK 1
+#define OS_INFO_FLAGS_ENTRY 2
+#define OS_INFO_RESERVED 3
+#define OS_INFO_IDENTITY_BASE 4
+#define OS_INFO_KASLR_OFFSET 5
+#define OS_INFO_KASLR_OFF_PHYS 6
+#define OS_INFO_VMEMMAP 7
+#define OS_INFO_AMODE31_START 8
+#define OS_INFO_AMODE31_END 9
+
+struct os_info_entry {
+ union {
+ __u64 addr;
+ __u64 val;
+ };
+ __u64 size;
+ __u32 csum;
+} __attribute__((packed));
+
+struct os_info {
+ __u64 magic;
+ __u32 csum;
+ __u16 version_major;
+ __u16 version_minor;
+ __u64 crashkernel_addr;
+ __u64 crashkernel_size;
+ struct os_info_entry entry[10];
+ __u8 reserved[3864];
+} __attribute__((packed));
+
+struct vm_info {
+ __u64 __identity_base;
+ __u64 __kaslr_offset;
+ __u64 __kaslr_offset_phys;
+ __u64 amode31_start;
+ __u64 amode31_end;
+};
+
+static bool
+vmcoreinfo_read_u64(const char *key, __u64 *val)
+{
+ char *string;
+
+ string = pc->read_vmcoreinfo(key);
+ if (string) {
+ *val = strtoul(string, NULL, 16);
+ free(string);
+ return true;
+ }
+
+ return false;
+}
+
+static bool vmcoreinfo_read_vm_info(struct vm_info *_vm_info)
+{
+ struct vm_info vm_info;
+
+ if (!vmcoreinfo_read_u64("IDENTITYBASE", &vm_info.__identity_base) ||
+ !vmcoreinfo_read_u64("KERNELOFFSET", &vm_info.__kaslr_offset) ||
+ !vmcoreinfo_read_u64("KERNELOFFPHYS", &vm_info.__kaslr_offset_phys) ||
+ !vmcoreinfo_read_u64("SAMODE31", &vm_info.amode31_start) ||
+ !vmcoreinfo_read_u64("EAMODE31", &vm_info.amode31_end))
+ return false;
+
+ *_vm_info = vm_info;
+
+ return true;
+}
+
+static bool os_info_read_vm_info(struct vm_info *vm_info)
+{
+ struct os_info os_info;
+ ulong addr;
+
+ if (!readmem(S390X_LC_OS_INFO, PHYSADDR, &addr,
+ sizeof(addr), "s390x os_info ptr",
+ QUIET|RETURN_ON_ERROR))
+ return false;
+
+ if (addr == 0)
+ return true;
+
+ if (!readmem(addr, PHYSADDR, &os_info,
+ offsetof(struct os_info, reserved), "s390x os_info header",
+ QUIET|RETURN_ON_ERROR))
+ return false;
+
+ vm_info->__identity_base = os_info.entry[OS_INFO_IDENTITY_BASE].val;
+ vm_info->__kaslr_offset = os_info.entry[OS_INFO_KASLR_OFFSET].val;
+ vm_info->__kaslr_offset_phys = os_info.entry[OS_INFO_KASLR_OFF_PHYS].val;
+ vm_info->amode31_start = os_info.entry[OS_INFO_AMODE31_START].val;
+ vm_info->amode31_end = os_info.entry[OS_INFO_AMODE31_END].val;
+
+ return true;
+}
+
+static bool vm_info_empty(struct vm_info *vm_info)
+{
+ return !vm_info->__kaslr_offset;
+}
+
+static bool s390x_init_vm(void)
+{
+ struct vm_info vm_info;
+
+ if (pc->flags & PROC_KCORE) {
+ if (!vmcoreinfo_read_vm_info(&vm_info))
+ return true;
+ } else {
+ if (!os_info_read_vm_info(&vm_info))
+ return false;
+ }
+ if (vm_info_empty(&vm_info))
+ return true;
+
+ machdep->identity_map_base = vm_info.__identity_base;
+ machdep->kvbase = vm_info.__kaslr_offset;
+ machdep->machspec->__kaslr_offset_phys = vm_info.__kaslr_offset_phys;
+ machdep->machspec->amode31_start = vm_info.amode31_start;
+ machdep->machspec->amode31_end = vm_info.amode31_end;
+
+ machdep->is_kvaddr = s390x_vr_is_kvaddr;
+ machdep->machspec->virt_to_phys = s390x_vr_VTOP;
+ machdep->machspec->phys_to_virt = s390x_vr_PTOV;
+ machdep->machspec->is_vmalloc_addr = s390x_vr_IS_VMALLOC_ADDR;
+
+ return true;
+}
+
+static ulong s390x_generic_VTOP(ulong vaddr)
+{
+ return vaddr - machdep->kvbase;
+}
+
+static ulong s390x_generic_PTOV(ulong paddr)
+{
+ return paddr + machdep->kvbase;
+}
+
+static int s390x_generic_IS_VMALLOC_ADDR(ulong vaddr)
+{
+ return vt->vmalloc_start && vaddr >= vt->vmalloc_start;
+}
+
+static ulong s390x_vr_VTOP(ulong vaddr)
+{
+ if (vaddr < LOWCORE_SIZE)
+ return vaddr;
+ if ((vaddr < machdep->machspec->amode31_end) &&
+ (vaddr >= machdep->machspec->amode31_start))
+ return vaddr;
+ if (vaddr < machdep->kvbase)
+ return vaddr - machdep->identity_map_base;
+ return vaddr - machdep->kvbase + machdep->machspec->__kaslr_offset_phys;
+}
+
+static ulong s390x_vr_PTOV(ulong paddr)
+{
+ return paddr + machdep->identity_map_base;
+}
+
+static int s390x_vr_IS_VMALLOC_ADDR(ulong vaddr)
+{
+ return (vaddr >= vt->vmalloc_start && vaddr < machdep->kvbase);
+}
+
+ulong s390x_VTOP(ulong vaddr)
+{
+ return machdep->machspec->virt_to_phys(vaddr);
+}
+
+ulong s390x_PTOV(ulong paddr)
+{
+ return machdep->machspec->phys_to_virt(paddr);
+}
+
+int s390x_IS_VMALLOC_ADDR(ulong vaddr)
+{
+ return machdep->machspec->is_vmalloc_addr(vaddr);
+}
+
/*
* Do all necessary machine-specific setup here. This is called several
* times during initialization.
@@ -560,6 +759,7 @@ s390x_init(int when)
machdep->process_elf_notes = s390x_process_elf_notes;
break;
case PRE_SYMTAB:
+ machdep->machspec = &s390x_machine_specific;
machdep->verify_symbol = s390x_verify_symbol;
if (pc->flags & KERNEL_DEBUG_QUERY)
return;
@@ -587,6 +787,8 @@ s390x_init(int when)
machdep->kvbase = 0;
machdep->identity_map_base = 0;
machdep->is_kvaddr = generic_is_kvaddr;
+ if (!s390x_init_vm())
+ error(FATAL, "cannot initialize VM parameters.");
machdep->is_uvaddr = s390x_is_uvaddr;
machdep->eframe_search = s390x_eframe_search;
machdep->back_trace = s390x_back_trace_cmd;
@@ -681,7 +883,9 @@ s390x_dump_machdep_table(ulong arg)
fprintf(fp, " dis_filter: s390x_dis_filter()\n");
fprintf(fp, " cmd_mach: s390x_cmd_mach()\n");
fprintf(fp, " get_smp_cpus: s390x_get_smp_cpus()\n");
- fprintf(fp, " is_kvaddr: generic_is_kvaddr()\n");
+ fprintf(fp, " is_kvaddr: %s()\n", machdep->is_kvaddr == s390x_vr_is_kvaddr ?
+ "s390x_vr_is_kvaddr" :
+ "generic_is_kvaddr");
fprintf(fp, " is_uvaddr: s390x_is_uvaddr()\n");
fprintf(fp, " verify_paddr: generic_verify_paddr()\n");
fprintf(fp, " get_kvaddr_ranges: s390x_get_kvaddr_ranges()\n");
@@ -702,6 +906,12 @@ s390x_dump_machdep_table(ulong arg)
fprintf(fp, " machspec: %lx\n", (ulong)machdep->machspec);
}
+static int
+s390x_vr_is_kvaddr(ulong vaddr)
+{
+ return (vaddr < LOWCORE_SIZE) || (vaddr >= machdep->identity_map_base);
+}
+
/*
* Check if address is in context's address space
*/
--
2.41.0

View File

@ -1,160 +0,0 @@
From 5187a0320cc54a9cb8b326cf012e69795950a716 Mon Sep 17 00:00:00 2001
From: Song Shuai <songshuaishuai@tinylab.org>
Date: Tue, 12 Dec 2023 18:20:50 +0800
Subject: [PATCH 10/14] RISCV64: Dump NT_PRSTATUS in 'help -n'
With the patch we can get full dump of "struct elf_prstatus" in 'help -n':
```
crash> help -n
<snip>
Elf64_Nhdr:
n_namesz: 5 ("CORE")
n_descsz: 376
n_type: 1 (NT_PRSTATUS)
si.signo: 0 si.code: 0 si.errno: 0
cursig: 0 sigpend: 0 sighold: 0
pid: 1 ppid: 0 pgrp: 0 sid:0
utime: 0.000000 stime: 0.000000
cutime: 0.000000 cstime: 0.000000
epc: ffffffff8000a1dc ra: ffffffff800af958 sp: ff6000001fc501c0
gp: ffffffff81515d38 tp: ff600000000d8000 t0: 6666666666663c5b
t1: ff600000000d88c8 t2: 666666666666663c s0: ff6000001fc50320
s1: ffffffff815170d8 a0: ff6000001fc501c8 a1: c0000000ffffefff
a2: 0000000000000000 a3: 0000000000000001 a4: 0000000000000000
a5: ff60000001782c00 a6: 000000000130e0f0 a7: 0000000000000000
s2: ffffffff81517820 s3: ff6000001fc501c8 s4: 000000000000000f
s5: 0000000000000000 s6: ff20000000013e60 s7: 0000000000000000
s8: ff60000000861000 s9: 00007fffc3641694 s10: 00007fffc3641690
s11: 00005555796ed240 t3: 0000000000010297 t4: ffffffff80c17810
t5: ffffffff8195e7b8 t6: ff6000001fc50048
0000000000000000 0000000000000000
0000000000000000 0000000000000000
0000000000000001 0000000000000000
0000000000000000 0000000000000000
0000000000000000 0000000000000000
0000000000000000 0000000000000000
0000000000000000 0000000000000000
ffffffff8000a1dc ffffffff800af958
ff6000001fc501c0 ffffffff81515d38
ff600000000d8000 6666666666663c5b
<snip>
```
Signed-off-by: Song Shuai <songshuaishuai@tinylab.org>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
netdump.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
diff --git a/netdump.c b/netdump.c
index 390786364959..32586b6809d3 100644
--- a/netdump.c
+++ b/netdump.c
@@ -2578,6 +2578,8 @@ dump_Elf64_Nhdr(Elf64_Off offset, int store)
display_ELF_note(EM_PPC64, PRSTATUS_NOTE, note, nd->ofp);
if (machine_type("ARM64") && (note->n_type == NT_PRSTATUS))
display_ELF_note(EM_AARCH64, PRSTATUS_NOTE, note, nd->ofp);
+ if (machine_type("RISCV64") && (note->n_type == NT_PRSTATUS))
+ display_ELF_note(EM_RISCV, PRSTATUS_NOTE, note, nd->ofp);
}
for (i = lf = 0; i < note->n_descsz/sizeof(ulonglong); i++) {
if (((i%2)==0)) {
@@ -3399,6 +3401,80 @@ display_prstatus_arm64(void *note_ptr, FILE *ofp)
space(sp), pr->pr_reg[33], pr->pr_fpvalid);
}
+struct riscv64_elf_siginfo {
+ int si_signo;
+ int si_code;
+ int si_errno;
+};
+
+struct riscv64_elf_prstatus {
+ struct riscv64_elf_siginfo pr_info;
+ short pr_cursig;
+ unsigned long pr_sigpend;
+ unsigned long pr_sighold;
+ pid_t pr_pid;
+ pid_t pr_ppid;
+ pid_t pr_pgrp;
+ pid_t pr_sid;
+ struct timeval pr_utime;
+ struct timeval pr_stime;
+ struct timeval pr_cutime;
+ struct timeval pr_cstime;
+/* elf_gregset_t pr_reg; => typedef struct user_regs_struct elf_gregset_t; */
+ unsigned long pr_reg[32];
+ int pr_fpvalid;
+};
+
+static void
+display_prstatus_riscv64(void *note_ptr, FILE *ofp)
+{
+ struct riscv64_elf_prstatus *pr;
+ Elf64_Nhdr *note;
+ int sp;
+
+ note = (Elf64_Nhdr *)note_ptr;
+ pr = (struct riscv64_elf_prstatus *)(
+ (char *)note + sizeof(Elf64_Nhdr) + note->n_namesz);
+ pr = (struct riscv64_elf_prstatus *)roundup((ulong)pr, 4);
+ sp = nd->num_prstatus_notes ? 25 : 22;
+
+ fprintf(ofp,
+ "%ssi.signo: %d si.code: %d si.errno: %d\n"
+ "%scursig: %d sigpend: %lx sighold: %lx\n"
+ "%spid: %d ppid: %d pgrp: %d sid:%d\n"
+ "%sutime: %01lld.%06d stime: %01lld.%06d\n"
+ "%scutime: %01lld.%06d cstime: %01lld.%06d\n",
+ space(sp), pr->pr_info.si_signo, pr->pr_info.si_code, pr->pr_info.si_errno,
+ space(sp), pr->pr_cursig, pr->pr_sigpend, pr->pr_sighold,
+ space(sp), pr->pr_pid, pr->pr_ppid, pr->pr_pgrp, pr->pr_sid,
+ space(sp), (long long)pr->pr_utime.tv_sec, (int)pr->pr_utime.tv_usec,
+ (long long)pr->pr_stime.tv_sec, (int)pr->pr_stime.tv_usec,
+ space(sp), (long long)pr->pr_cutime.tv_sec, (int)pr->pr_cutime.tv_usec,
+ (long long)pr->pr_cstime.tv_sec, (int)pr->pr_cstime.tv_usec);
+ fprintf(ofp,
+ "%sepc: %016lx ra: %016lx sp: %016lx\n"
+ "%s gp: %016lx tp: %016lx t0: %016lx\n"
+ "%s t1: %016lx t2: %016lx s0: %016lx\n"
+ "%s s1: %016lx a0: %016lx a1: %016lx\n"
+ "%s a2: %016lx a3: %016lx a4: %016lx\n"
+ "%s a5: %016lx a6: %016lx a7: %016lx\n"
+ "%s s2: %016lx s3: %016lx s4: %016lx\n"
+ "%s s5: %016lx s6: %016lx s7: %016lx\n"
+ "%s s8: %016lx s9: %016lx s10: %016lx\n"
+ "%ss11: %016lx t3: %016lx t4: %016lx\n"
+ "%s t5: %016lx t6: %016lx\n",
+ space(sp), pr->pr_reg[0], pr->pr_reg[1], pr->pr_reg[2],
+ space(sp), pr->pr_reg[3], pr->pr_reg[4], pr->pr_reg[5],
+ space(sp), pr->pr_reg[6], pr->pr_reg[7], pr->pr_reg[8],
+ space(sp), pr->pr_reg[9], pr->pr_reg[10], pr->pr_reg[11],
+ space(sp), pr->pr_reg[12], pr->pr_reg[13], pr->pr_reg[14],
+ space(sp), pr->pr_reg[15], pr->pr_reg[16], pr->pr_reg[17],
+ space(sp), pr->pr_reg[18], pr->pr_reg[19], pr->pr_reg[20],
+ space(sp), pr->pr_reg[21], pr->pr_reg[22], pr->pr_reg[23],
+ space(sp), pr->pr_reg[24], pr->pr_reg[25], pr->pr_reg[26],
+ space(sp), pr->pr_reg[27], pr->pr_reg[28], pr->pr_reg[29],
+ space(sp), pr->pr_reg[30], pr->pr_reg[31]);
+}
void
display_ELF_note(int machine, int type, void *note, FILE *ofp)
@@ -3449,6 +3525,14 @@ display_ELF_note(int machine, int type, void *note, FILE *ofp)
break;
}
break;
+ case EM_RISCV:
+ switch (type)
+ {
+ case PRSTATUS_NOTE:
+ display_prstatus_riscv64(note, ofp);
+ break;
+ }
+ break;
default:
return;
--
2.41.0

View File

@ -1,87 +0,0 @@
From 9b69093e623f1d54c373b1e091900d40576c059b Mon Sep 17 00:00:00 2001
From: Song Shuai <songshuaishuai@tinylab.org>
Date: Tue, 12 Dec 2023 18:20:51 +0800
Subject: [PATCH 11/14] RISCV64: Fix 'bt' output when no ra on the stack top
Same as the Linux commit f766f77a74f5 ("riscv/stacktrace: Fix
stack output without ra on the stack top").
When a function doesn't have a callee, then it will not
push ra into the stack, such as lkdtm functions, so
correct the FP of the second frame and use pt_regs to get
the right PC of the second frame.
Before this patch, the `bt -f` outputs only the first frame with
the wrong PC and FP of next frame:
```
crash> bt -f
PID: 1 TASK: ff600000000e0000 CPU: 1 COMMAND: "sh"
#0 [ff20000000013cf0] lkdtm_EXCEPTION at ffffffff805303c0
[PC: ffffffff805303c0 RA: ff20000000013d10 SP: ff20000000013cf0 SIZE: 16] <- wrong next PC
ff20000000013cf0: 0000000000000001 ff20000000013d10 <- next FP
ff20000000013d00: ff20000000013d40
crash>
```
After this patch, the `bt` outputs the full frames:
```
crash> bt
PID: 1 TASK: ff600000000e0000 CPU: 1 COMMAND: "sh"
#0 [ff20000000013cf0] lkdtm_EXCEPTION at ffffffff805303c0
#1 [ff20000000013d00] lkdtm_do_action at ffffffff8052fe36
#2 [ff20000000013d10] direct_entry at ffffffff80530018
#3 [ff20000000013d40] full_proxy_write at ffffffff80305044
#4 [ff20000000013d80] vfs_write at ffffffff801b68b4
#5 [ff20000000013e30] ksys_write at ffffffff801b6c4a
#6 [ff20000000013e80] __riscv_sys_write at ffffffff801b6cc4
#7 [ff20000000013e90] do_trap_ecall_u at ffffffff80836798
crash>
```
Acked-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Song Shuai <songshuaishuai@tinylab.org>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
riscv64.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/riscv64.c b/riscv64.c
index 0aaa14b2671e..872be594d72b 100644
--- a/riscv64.c
+++ b/riscv64.c
@@ -747,11 +747,14 @@ riscv64_back_trace_cmd(struct bt_info *bt)
{
struct riscv64_unwind_frame current, previous;
struct stackframe curr_frame;
+ struct riscv64_register * regs;
int level = 0;
if (bt->flags & BT_REGS_NOT_FOUND)
return;
+ regs = (struct riscv64_register *) bt->machdep;
+
current.pc = bt->instptr;
current.sp = bt->stkptr;
current.fp = bt->frameptr;
@@ -788,8 +791,16 @@ riscv64_back_trace_cmd(struct bt_info *bt)
sizeof(curr_frame), "get stack frame", RETURN_ON_ERROR))
return;
- previous.pc = curr_frame.ra;
- previous.fp = curr_frame.fp;
+ /* correct PC and FP of the second frame when the first frame has no callee */
+
+ if (regs && (regs->regs[RISCV64_REGS_EPC] == current.pc) && curr_frame.fp & 0x7){
+ previous.pc = regs->regs[RISCV64_REGS_RA];
+ previous.fp = curr_frame.ra;
+ } else {
+ previous.pc = curr_frame.ra;
+ previous.fp = curr_frame.fp;
+ }
+
previous.sp = current.fp;
riscv64_dump_backtrace_entry(bt, symbol, &current, &previous, level++);
--
2.41.0

View File

@ -1,265 +0,0 @@
From 19d3c56c9fca9dea49dced0414becc6d1b12e9fc Mon Sep 17 00:00:00 2001
From: Huang Shijie <shijie@os.amperecomputing.com>
Date: Thu, 14 Dec 2023 15:15:20 +0800
Subject: [PATCH 12/14] arm64: rewrite the arm64_get_vmcoreinfo_ul to
arm64_get_vmcoreinfo
Rewrite the arm64_get_vmcoreinfo_ul to arm64_get_vmcoreinfo,
add a new parameter "base" for it.
Also use it to simplify the arm64 code.
Signed-off-by: Huang Shijie <shijie@os.amperecomputing.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
arm64.c | 99 +++++++++++++++++++++++----------------------------------
1 file changed, 39 insertions(+), 60 deletions(-)
diff --git a/arm64.c b/arm64.c
index 2b6b0e588d4e..57965c6cb3c8 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 int arm64_get_vmcoreinfo(unsigned long *vaddr, const char *label, int base);
struct kernel_range {
unsigned long modules_vaddr, modules_end;
@@ -124,7 +125,6 @@ void
arm64_init(int when)
{
ulong value;
- char *string;
struct machine_specific *ms;
#if defined(__x86_64__)
@@ -160,11 +160,8 @@ arm64_init(int when)
if (!ms->kimage_voffset && STREQ(pc->live_memsrc, "/dev/crash"))
ioctl(pc->mfd, DEV_CRASH_ARCH_DATA, &ms->kimage_voffset);
- if (!ms->kimage_voffset &&
- (string = pc->read_vmcoreinfo("NUMBER(kimage_voffset)"))) {
- ms->kimage_voffset = htol(string, QUIET, NULL);
- free(string);
- }
+ if (!ms->kimage_voffset)
+ arm64_get_vmcoreinfo(&ms->kimage_voffset, "NUMBER(kimage_voffset)", NUM_HEX);
if (ms->kimage_voffset ||
(ACTIVE() && (symbol_value_from_proc_kallsyms("kimage_voffset") != BADVAL))) {
@@ -185,11 +182,8 @@ arm64_init(int when)
if (kernel_symbol_exists("kimage_voffset"))
machdep->flags |= NEW_VMEMMAP;
- if (!machdep->pagesize &&
- (string = pc->read_vmcoreinfo("PAGESIZE"))) {
- machdep->pagesize = atoi(string);
- free(string);
- }
+ if (!machdep->pagesize && arm64_get_vmcoreinfo(&value, "PAGESIZE", NUM_DEC))
+ machdep->pagesize = (unsigned int)value;
if (!machdep->pagesize) {
/*
@@ -443,9 +437,8 @@ arm64_init(int when)
arm64_get_section_size_bits();
if (!machdep->max_physmem_bits) {
- if ((string = pc->read_vmcoreinfo("NUMBER(MAX_PHYSMEM_BITS)"))) {
- machdep->max_physmem_bits = atol(string);
- free(string);
+ if (arm64_get_vmcoreinfo(&machdep->max_physmem_bits, "NUMBER(MAX_PHYSMEM_BITS)", NUM_DEC)) {
+ /* nothing */
} else if (machdep->machspec->VA_BITS == 52) /* guess */
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_52;
else if (THIS_KERNEL_VERSION >= LINUX(3,17,0))
@@ -573,16 +566,28 @@ static int arm64_get_struct_page_max_shift(struct machine_specific *ms)
}
/* Return TRUE if we succeed, return FALSE on failure. */
-static int arm64_get_vmcoreinfo_ul(unsigned long *vaddr, const char* label)
+static int
+arm64_get_vmcoreinfo(unsigned long *vaddr, const char *label, int base)
{
+ int err = 0;
char *string = pc->read_vmcoreinfo(label);
if (!string)
return FALSE;
- *vaddr = strtoul(string, NULL, 0);
+ switch (base) {
+ case NUM_HEX:
+ *vaddr = strtoul(string, NULL, 16);
+ break;
+ case NUM_DEC:
+ *vaddr = strtoul(string, NULL, 10);
+ break;
+ default:
+ err++;
+ error(INFO, "Unknown type:%#x, (NUM_HEX|NUM_DEC)\n", base);
+ }
free(string);
- return TRUE;
+ return err ? FALSE: TRUE;
}
/*
@@ -594,21 +599,21 @@ static struct kernel_range *arm64_get_range_v5_18(struct machine_specific *ms)
struct kernel_range *r = &tmp_range;
/* Get the MODULES_VADDR ~ MODULES_END */
- if (!arm64_get_vmcoreinfo_ul(&r->modules_vaddr, "NUMBER(MODULES_VADDR)"))
+ if (!arm64_get_vmcoreinfo(&r->modules_vaddr, "NUMBER(MODULES_VADDR)", NUM_HEX))
return NULL;
- if (!arm64_get_vmcoreinfo_ul(&r->modules_end, "NUMBER(MODULES_END)"))
+ if (!arm64_get_vmcoreinfo(&r->modules_end, "NUMBER(MODULES_END)", NUM_HEX))
return NULL;
/* Get the VMEMMAP_START ~ VMEMMAP_END */
- if (!arm64_get_vmcoreinfo_ul(&r->vmemmap_vaddr, "NUMBER(VMEMMAP_START)"))
+ if (!arm64_get_vmcoreinfo(&r->vmemmap_vaddr, "NUMBER(VMEMMAP_START)", NUM_HEX))
return NULL;
- if (!arm64_get_vmcoreinfo_ul(&r->vmemmap_end, "NUMBER(VMEMMAP_END)"))
+ if (!arm64_get_vmcoreinfo(&r->vmemmap_end, "NUMBER(VMEMMAP_END)", NUM_HEX))
return NULL;
/* Get the VMALLOC_START ~ VMALLOC_END */
- if (!arm64_get_vmcoreinfo_ul(&r->vmalloc_start_addr, "NUMBER(VMALLOC_START)"))
+ if (!arm64_get_vmcoreinfo(&r->vmalloc_start_addr, "NUMBER(VMALLOC_START)", NUM_HEX))
return NULL;
- if (!arm64_get_vmcoreinfo_ul(&r->vmalloc_end, "NUMBER(VMALLOC_END)"))
+ if (!arm64_get_vmcoreinfo(&r->vmalloc_end, "NUMBER(VMALLOC_END)", NUM_HEX))
return NULL;
return r;
@@ -888,12 +893,7 @@ range_failed:
/* Get the size of struct page {} */
static void arm64_get_struct_page_size(struct machine_specific *ms)
{
- char *string;
-
- string = pc->read_vmcoreinfo("SIZE(page)");
- if (string)
- ms->struct_page_size = atol(string);
- free(string);
+ arm64_get_vmcoreinfo(&ms->struct_page_size, "SIZE(page)", NUM_DEC);
}
/*
@@ -1469,16 +1469,12 @@ arm64_calc_phys_offset(void)
physaddr_t paddr;
ulong vaddr;
struct syment *sp;
- char *string;
if ((machdep->flags & NEW_VMEMMAP) &&
ms->kimage_voffset && (sp = kernel_symbol_search("memstart_addr"))) {
if (pc->flags & PROC_KCORE) {
- if ((string = pc->read_vmcoreinfo("NUMBER(PHYS_OFFSET)"))) {
- ms->phys_offset = htol(string, QUIET, NULL);
- free(string);
+ if (arm64_get_vmcoreinfo(&ms->phys_offset, "NUMBER(PHYS_OFFSET)", NUM_HEX))
return;
- }
vaddr = symbol_value_from_proc_kallsyms("memstart_addr");
if (vaddr == BADVAL)
vaddr = sp->value;
@@ -1560,9 +1556,8 @@ arm64_get_section_size_bits(void)
} else
machdep->section_size_bits = _SECTION_SIZE_BITS;
- if ((string = pc->read_vmcoreinfo("NUMBER(SECTION_SIZE_BITS)"))) {
- machdep->section_size_bits = atol(string);
- free(string);
+ if (arm64_get_vmcoreinfo(&machdep->section_size_bits, "NUMBER(SECTION_SIZE_BITS)", NUM_DEC)) {
+ /* nothing */
} else if (kt->ikconfig_flags & IKCONFIG_AVAIL) {
if ((ret = get_kernel_config("CONFIG_MEMORY_HOTPLUG", NULL)) == IKCONFIG_Y) {
if ((ret = get_kernel_config("CONFIG_HOTPLUG_SIZE_BITS", &string)) == IKCONFIG_STR)
@@ -1581,15 +1576,11 @@ arm64_get_section_size_bits(void)
static int
arm64_kdump_phys_base(ulong *phys_offset)
{
- char *string;
struct syment *sp;
physaddr_t paddr;
- if ((string = pc->read_vmcoreinfo("NUMBER(PHYS_OFFSET)"))) {
- *phys_offset = htol(string, QUIET, NULL);
- free(string);
+ if (arm64_get_vmcoreinfo(phys_offset, "NUMBER(PHYS_OFFSET)", NUM_HEX))
return TRUE;
- }
if ((machdep->flags & NEW_VMEMMAP) &&
machdep->machspec->kimage_voffset &&
@@ -4592,10 +4583,9 @@ static int
arm64_set_va_bits_by_tcr(void)
{
ulong value;
- char *string;
- if ((string = pc->read_vmcoreinfo("NUMBER(TCR_EL1_T1SZ)")) ||
- (string = pc->read_vmcoreinfo("NUMBER(tcr_el1_t1sz)"))) {
+ if (arm64_get_vmcoreinfo(&value, "NUMBER(TCR_EL1_T1SZ)", NUM_HEX) ||
+ arm64_get_vmcoreinfo(&value, "NUMBER(tcr_el1_t1sz)", NUM_HEX)) {
/* See ARMv8 ARM for the description of
* TCR_EL1.T1SZ and how it can be used
* to calculate the vabits_actual
@@ -4604,10 +4594,9 @@ arm64_set_va_bits_by_tcr(void)
* Basically:
* vabits_actual = 64 - T1SZ;
*/
- value = 64 - strtoll(string, NULL, 0);
+ value = 64 - value;
if (CRASHDEBUG(1))
fprintf(fp, "vmcoreinfo : vabits_actual: %ld\n", value);
- free(string);
machdep->machspec->VA_BITS_ACTUAL = value;
machdep->machspec->VA_BITS = value;
machdep->machspec->VA_START = _VA_START(machdep->machspec->VA_BITS_ACTUAL);
@@ -4623,13 +4612,8 @@ arm64_calc_VA_BITS(void)
int bitval;
struct syment *sp;
ulong vabits_actual, value;
- char *string;
- if ((string = pc->read_vmcoreinfo("NUMBER(VA_BITS)"))) {
- value = atol(string);
- free(string);
- machdep->machspec->CONFIG_ARM64_VA_BITS = value;
- }
+ arm64_get_vmcoreinfo(&machdep->machspec->CONFIG_ARM64_VA_BITS, "NUMBER(VA_BITS)", NUM_DEC);
if (kernel_symbol_exists("vabits_actual")) {
if (pc->flags & PROC_KCORE) {
@@ -4754,9 +4738,7 @@ arm64_calc_virtual_memory_ranges(void)
ulong PUD_SIZE = UNINITIALIZED;
if (!machdep->machspec->CONFIG_ARM64_VA_BITS) {
- if ((string = pc->read_vmcoreinfo("NUMBER(VA_BITS)"))) {
- value = atol(string);
- free(string);
+ if (arm64_get_vmcoreinfo(&value, "NUMBER(VA_BITS)", NUM_DEC)) {
machdep->machspec->CONFIG_ARM64_VA_BITS = value;
} else if (kt->ikconfig_flags & IKCONFIG_AVAIL) {
if ((ret = get_kernel_config("CONFIG_ARM64_VA_BITS",
@@ -4852,11 +4834,8 @@ arm64_swp_offset(ulong pte)
static void arm64_calc_KERNELPACMASK(void)
{
ulong value;
- char *string;
- if ((string = pc->read_vmcoreinfo("NUMBER(KERNELPACMASK)"))) {
- value = htol(string, QUIET, NULL);
- free(string);
+ if (arm64_get_vmcoreinfo(&value, "NUMBER(KERNELPACMASK)", NUM_HEX)) {
machdep->machspec->CONFIG_ARM64_KERNELPACMASK = value;
if (CRASHDEBUG(1))
fprintf(fp, "CONFIG_ARM64_KERNELPACMASK: %lx\n", value);
--
2.41.0

View File

@ -1,36 +0,0 @@
From 38435c3acec075b076353ca28f557a0dfe1341c3 Mon Sep 17 00:00:00 2001
From: Li Zhijian <lizhijian@fujitsu.com>
Date: Fri, 15 Dec 2023 10:44:21 +0800
Subject: [PATCH 13/14] help.c: Remove "kmem -l" help messages
"kmem -l" option has existed when crash git project initialization, but
its help message was not accurate (extra arguments a|i|ic|id was missing).
In addition, those symbols required by the -l option were for very old
kernels, at least 2.6 kernels don't contain them. Also, this option has
not been fixed for a long time.
Instead of document this option, hide it from help messages.
Signed-off-by: Li Zhijian <lizhijian@fujitsu.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
help.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/help.c b/help.c
index cc7ab20e343e..d80e843703c1 100644
--- a/help.c
+++ b/help.c
@@ -6888,8 +6888,6 @@ char *help_kmem[] = {
" members of the associated page struct are displayed.",
" address when used with -c, the address must be a page pointer address;",
" the page_hash_table entry containing the page is displayed.",
-" address when used with -l, the address must be a page pointer address;",
-" the page address is displayed if it is contained with the list.",
" address when used with -v, the address can be a mapped kernel virtual",
" address or physical address; the mapped region containing the",
" address is displayed.\n",
--
2.41.0

View File

@ -1,65 +0,0 @@
From 53d2577cef98b76b122aade94349637a11e06138 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Tue, 26 Dec 2023 09:19:28 +0800
Subject: [PATCH 14/14] x86_64: check bt->bptr before calculate framesize
Previously the value of bt->bptr is not checked, which may led to a
wrong prev_sp and framesize. As a result, bt->stackbuf[] will be
accessed out of range, and segfault.
Before:
crash> set debug 1
crash> bt
...snip...
--- <NMI exception stack> ---
#8 [ffffffff9a603e10] __switch_to_asm at ffffffff99800214
rsp: ffffffff9a603e10 textaddr: ffffffff99800214 -> spo: 0 bpo: 0 spr: 0 bpr: 0 type: 0 end: 0
#9 [ffffffff9a603e40] __schedule at ffffffff9960dfb1
rsp: ffffffff9a603e40 textaddr: ffffffff9960dfb1 -> spo: 16 bpo: -16 spr: 4 bpr: 1 type: 0 end: 0
rsp: ffffffff9a603e40 rbp: ffffb9ca076e7ca8 prev_sp: ffffb9ca076e7cb8 framesize: 1829650024
Segmentation fault (core dumped)
(gdb) p/x bt->stackbase
$1 = 0xffffffff9a600000
(gdb) p/x bt->stacktop
$2 = 0xffffffff9a604000
After:
crash> set debug 1
crash> bt
...snip...
--- <NMI exception stack> ---
#8 [ffffffff9a603e10] __switch_to_asm at ffffffff99800214
rsp: ffffffff9a603e10 textaddr: ffffffff99800214 -> spo: 0 bpo: 0 spr: 0 bpr: 0 type: 0 end: 0
#9 [ffffffff9a603e40] __schedule at ffffffff9960dfb1
rsp: ffffffff9a603e40 textaddr: ffffffff9960dfb1 -> spo: 16 bpo: -16 spr: 4 bpr: 1 type: 0 end: 0
#10 [ffffffff9a603e98] schedule_idle at ffffffff9960e87c
rsp: ffffffff9a603e98 textaddr: ffffffff9960e87c -> spo: 8 bpo: 0 spr: 5 bpr: 0 type: 0 end: 0
rsp: ffffffff9a603e98 prev_sp: ffffffff9a603ea8 framesize: 0
...snip...
Check bt->bptr value before calculate framesize. Only bt->bptr within
the range of bt->stackbase and bt->stacktop will be regarded as valid.
Signed-off-by: Tao Liu <ltao@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
x86_64.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/x86_64.c b/x86_64.c
index 42ade4817ad9..f59991f8c4c5 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -8649,7 +8649,7 @@ x86_64_get_framesize(struct bt_info *bt, ulong textaddr, ulong rsp, char *stack_
if (CRASHDEBUG(1))
fprintf(fp, "rsp: %lx prev_sp: %lx framesize: %d\n",
rsp, prev_sp, framesize);
- } else if ((korc->sp_reg == ORC_REG_BP) && bt->bptr) {
+ } else if ((korc->sp_reg == ORC_REG_BP) && bt->bptr && INSTACK(bt->bptr, bt)) {
prev_sp = bt->bptr + korc->sp_offset;
framesize = (prev_sp - (rsp + 8) - 8);
if (CRASHDEBUG(1))
--
2.41.0

View File

@ -1,5 +1,5 @@
--- crash-8.0.4/Makefile.orig
+++ crash-8.0.4/Makefile
--- crash-8.0.5/Makefile.orig
+++ crash-8.0.5/Makefile
@@ -204,7 +204,7 @@ GDB_FLAGS=
# TARGET_CFLAGS will be configured automatically by configure
TARGET_CFLAGS=
@ -18,8 +18,8 @@
@echo "../../${PROGRAM} ../../${PROGRAM}lib.a" > ${GDB}/gdb/mergeobj
@rm -f ${PROGRAM}
@if [ ! -f ${GDB}/config.status ]; then \
--- crash-8.0.4/configure.c.orig
+++ crash-8.0.4/configure.c
--- crash-8.0.5/configure.c.orig
+++ crash-8.0.5/configure.c
@@ -810,7 +810,8 @@ build_configure(struct supported_gdb_version *sp)
fprintf(fp2, "%s\n", sp->GDB);
sprintf(target_data.gdb_version, "%s", &sp->GDB[4]);

View File

@ -3,8 +3,8 @@
#
Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles
Name: crash
Version: 8.0.4
Release: 4%{?dist}
Version: 8.0.5
Release: 1%{?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
@ -18,27 +18,7 @@ Requires: binutils
Provides: bundled(libiberty)
Provides: bundled(gdb) = 10.2
Patch0: lzo_snappy_zstd.patch
Patch1: crash-8.0.4_build.patch
Patch2: 0001-Fix-rd-command-for-zram-data-display-in-Linux-6.2-an.patch
Patch3: 0002-Fix-typos-in-offset_table-and-missing-help-o-items.patch
Patch4: 0003-zram-Fixes-for-lookup_swap_cache.patch
Patch5: 0004-symbols-expand-all-kernel-module-symtable-if-not-all.patch
Patch6: 0005-symbols-skip-load-.init.-sections-if-module-was-succ.patch
Patch7: 0006-use-NR_SWAPCACHE-when-nr_swapper_spaces-isn-t-availa.patch
Patch8: 0007-Fix-identity_map_base-value-dump-on-S390.patch
Patch9: 0008-s390x-fix-virtual-vs-physical-address-confusion.patch
Patch10: 0009-s390x-uncouple-physical-and-virtual-memory-spaces.patch
Patch11: 0010-RISCV64-Dump-NT_PRSTATUS-in-help-n.patch
Patch12: 0011-RISCV64-Fix-bt-output-when-no-ra-on-the-stack-top.patch
Patch13: 0012-arm64-rewrite-the-arm64_get_vmcoreinfo_ul-to-arm64_g.patch
Patch14: 0013-help.c-Remove-kmem-l-help-messages.patch
Patch15: 0014-x86_64-check-bt-bptr-before-calculate-framesize.patch
Patch16: 0001-arm64-support-HW-Tag-Based-KASAN-MTE-mode.patch
Patch17: 0002-RISCV64-Add-support-for-bt-e-option.patch
Patch18: 0003-RISCV64-Add-per-cpu-IRQ-stacks-support.patch
Patch19: 0004-RISCV64-Add-per-cpu-overflow-stacks-support.patch
Patch20: 0005-x86_64-Fix-bt-command-not-printing-stack-trace-enoug.patch
Patch21: 0006-symbols-skip-the-module-if-the-given-address-is-not-.patch
Patch1: crash-8.0.5_build.patch
%description
The core analysis suite is a self-contained tool that can be used to
@ -60,26 +40,6 @@ offered by Mission Critical Linux, or the LKCD kernel patch.
%setup -n %{name}-%{version} -q
%patch -P 0 -p1 -b lzo_snappy_zstd.patch
%patch -P 1 -p1
%patch -P 2 -p1
%patch -P 3 -p1
%patch -P 4 -p1
%patch -P 5 -p1
%patch -P 6 -p1
%patch -P 7 -p1
%patch -P 8 -p1
%patch -P 9 -p1
%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
%patch -P 18 -p1
%patch -P 19 -p1
%patch -P 20 -p1
%patch -P 21 -p1
%build
@ -105,6 +65,9 @@ cp -p defs.h %{buildroot}%{_includedir}/crash
%{_includedir}/*
%changelog
* Thu May 16 2024 Lianbo Jiang <lijiang@redhat.com> - 8.0.5-1
- Rebase to upstream crash 8.0.5
* Wed Jan 24 2024 Fedora Release Engineering <releng@fedoraproject.org> - 8.0.4-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild

View File

@ -1,5 +1,5 @@
--- crash-8.0.4/Makefile.orig
+++ crash-8.0.4/Makefile
--- crash-8.0.5/Makefile.orig
+++ crash-8.0.5/Makefile
@@ -256,7 +256,7 @@ all: make_configure
gdb_merge: force
@if [ ! -f ${GDB}/README ]; then \
@ -9,8 +9,8 @@
@echo "../../${PROGRAM} ../../${PROGRAM}lib.a" > ${GDB}/gdb/mergeobj
@rm -f ${PROGRAM}
@if [ ! -f ${GDB}/config.status ]; then \
--- crash-8.0.4/diskdump.c.orig
+++ crash-8.0.4/diskdump.c
--- crash-8.0.5/diskdump.c.orig
+++ crash-8.0.5/diskdump.c
@@ -23,6 +23,9 @@
* GNU General Public License for more details.
*/

View File

@ -1,2 +1,2 @@
SHA512 (crash-8.0.4.tar.gz) = a08589026515990eee555af6eeba0457433fe41263512ed67dfcac1cf49a8f61dc794081f4984700d8dfed228440a1d7928fdd1f5cf4ae8a45cf39eb49d3470b
SHA512 (crash-8.0.5.tar.gz) = 0e199899fcc479eeebd1177a88dfe26725d9f63361d5ff7dbf9cb0f8425d3c6b8d60aada0a4312f61eecfe0ed0cca346034e12accbf5896446db8d9fb7d55e05
SHA512 (gdb-10.2.tar.gz) = aa89caf47c1c84366020377d47e7c51ddbc48e5b7686f244e38797c8eb88411cf57fcdc37eb669961efb41ceeac4181747f429625fd1acce7712cb9a1fea9c41