Import from AlmaLinux stable repository

This commit is contained in:
eabdullin 2024-05-31 16:33:05 +00:00
parent 02c0380c05
commit 2a3aec2e2a
64 changed files with 1807 additions and 4488 deletions

View File

@ -1,2 +0,0 @@
aab889c6471bfc42cf2b1d065a881ea33d8ba0b7 SOURCES/crash-7.3.2.tar.gz
026f4c9e1c8152a2773354551c523acd32d7f00e SOURCES/gdb-7.6.tar.gz

4
.gitignore vendored
View File

@ -1,2 +1,2 @@
SOURCES/crash-7.3.2.tar.gz
SOURCES/gdb-7.6.tar.gz
SOURCES/crash-8.0.4.tar.gz
SOURCES/gdb-10.2.tar.gz

View File

@ -1,146 +0,0 @@
From f623cad20b092002d627a03451ea256add2e53d0 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Wed, 15 Jun 2022 10:50:13 +0900
Subject: [PATCH 01/28] Fix for "dev" command on Linux 5.11 and later
The following kernel commits eventually removed the bdev_map array in
Linux v5.11 kernel:
e418de3abcda ("block: switch gendisk lookup to a simple xarray")
22ae8ce8b892 ("block: simplify bdev/disk lookup in blkdev_get")
Without the patch, the "dev" command fails to dump block device data
with the following error:
crash> dev
...
dev: blkdevs or all_bdevs: symbols do not exist
To get block device's gendisk, search blockdev_superblock.s_inodes
instead of bdev_map.
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
dev.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 72 insertions(+), 5 deletions(-)
diff --git a/dev.c b/dev.c
index db97f8aebdc2..75d30bd022a1 100644
--- a/dev.c
+++ b/dev.c
@@ -24,6 +24,7 @@ static void dump_blkdevs_v2(ulong);
static void dump_blkdevs_v3(ulong);
static ulong search_cdev_map_probes(char *, int, int, ulong *);
static ulong search_bdev_map_probes(char *, int, int, ulong *);
+static ulong search_blockdev_inodes(int, ulong *);
static void do_pci(void);
static void do_pci2(void);
static void do_io(void);
@@ -493,9 +494,10 @@ dump_blkdevs(ulong flags)
ulong ops;
} blkdevs[MAX_DEV], *bp;
- if (kernel_symbol_exists("major_names") &&
- kernel_symbol_exists("bdev_map")) {
- dump_blkdevs_v3(flags);
+ if (kernel_symbol_exists("major_names") &&
+ (kernel_symbol_exists("bdev_map") ||
+ kernel_symbol_exists("blockdev_superblock"))) {
+ dump_blkdevs_v3(flags);
return;
}
@@ -717,6 +719,7 @@ dump_blkdevs_v3(ulong flags)
char buf[BUFSIZE];
uint major;
ulong gendisk, addr, fops;
+ int use_bdev_map = kernel_symbol_exists("bdev_map");
if (!(len = get_array_length("major_names", NULL, 0)))
len = MAX_DEV;
@@ -745,8 +748,11 @@ dump_blkdevs_v3(ulong flags)
strncpy(buf, blk_major_name_buf +
OFFSET(blk_major_name_name), 16);
- fops = search_bdev_map_probes(buf, major == i ? major : i,
- UNUSED, &gendisk);
+ if (use_bdev_map)
+ fops = search_bdev_map_probes(buf, major == i ? major : i,
+ UNUSED, &gendisk);
+ else /* v5.11 and later */
+ fops = search_blockdev_inodes(major, &gendisk);
if (CRASHDEBUG(1))
fprintf(fp, "blk_major_name: %lx block major: %d name: %s gendisk: %lx fops: %lx\n",
@@ -829,6 +835,67 @@ search_bdev_map_probes(char *name, int major, int minor, ulong *gendisk)
return fops;
}
+/* For bdev_inode. See block/bdev.c */
+#define I_BDEV(inode) (inode - SIZE(block_device))
+
+static ulong
+search_blockdev_inodes(int major, ulong *gendisk)
+{
+ struct list_data list_data, *ld;
+ ulong addr, bd_sb, disk, fops = 0;
+ int i, inode_count, gendisk_major;
+ char *gendisk_buf;
+
+ ld = &list_data;
+ BZERO(ld, sizeof(struct list_data));
+
+ get_symbol_data("blockdev_superblock", sizeof(void *), &bd_sb);
+
+ addr = bd_sb + OFFSET(super_block_s_inodes);
+ if (!readmem(addr, KVADDR, &ld->start, sizeof(ulong),
+ "blockdev_superblock.s_inodes", QUIET|RETURN_ON_ERROR))
+ return 0;
+
+ if (empty_list(ld->start))
+ return 0;
+
+ ld->flags |= LIST_ALLOCATE;
+ ld->end = bd_sb + OFFSET(super_block_s_inodes);
+ ld->list_head_offset = OFFSET(inode_i_sb_list);
+
+ inode_count = do_list(ld);
+
+ gendisk_buf = GETBUF(SIZE(gendisk));
+
+ for (i = 0; i < inode_count; i++) {
+ addr = I_BDEV(ld->list_ptr[i]) + OFFSET(block_device_bd_disk);
+ if (!readmem(addr, KVADDR, &disk, sizeof(ulong),
+ "block_device.bd_disk", QUIET|RETURN_ON_ERROR))
+ continue;
+
+ if (!disk)
+ continue;
+
+ if (!readmem(disk, KVADDR, gendisk_buf, SIZE(gendisk),
+ "gendisk buffer", QUIET|RETURN_ON_ERROR))
+ continue;
+
+ gendisk_major = INT(gendisk_buf + OFFSET(gendisk_major));
+ if (gendisk_major != major)
+ continue;
+
+ fops = ULONG(gendisk_buf + OFFSET(gendisk_fops));
+ if (fops) {
+ *gendisk = disk;
+ break;
+ }
+ }
+
+ FREEBUF(ld->list_ptr);
+ FREEBUF(gendisk_buf);
+ return fops;
+}
+
void
dump_dev_table(void)
{
--
2.37.1

View File

@ -0,0 +1,142 @@
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,31 +0,0 @@
From ae52398a13fa9a238279114ed671c7c514c154ee Mon Sep 17 00:00:00 2001
From: Sourabh Jain <sourabhjain@linux.ibm.com>
Date: Mon, 9 May 2022 12:49:56 +0530
Subject: [PATCH 01/18] ppc64: update the NR_CPUS to 8192
Since the kernel commit 2d8ae638bb86 ("powerpc: Make the NR_CPUS max 8192")
the NR_CPUS on Linux kernel ranges from 1-8192. So let's match NR_CPUS with
the max NR_CPUS count on the Linux kernel.
Signed-off-by: Sourabh Jain <sourabhjain@linux.ibm.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/defs.h b/defs.h
index 1e8360d65a3b..a6735d07b32f 100644
--- a/defs.h
+++ b/defs.h
@@ -136,7 +136,7 @@
#define NR_CPUS (4096)
#endif
#ifdef PPC64
-#define NR_CPUS (2048)
+#define NR_CPUS (8192)
#endif
#ifdef S390
#define NR_CPUS (512)
--
2.30.2

View File

@ -1,84 +0,0 @@
From 6bc60e8cc87701c8f68c1cda56dd7120b5565700 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Wed, 22 Jun 2022 08:32:59 +0900
Subject: [PATCH 02/28] Extend field length of task attributes
Nowadays, some machines have many CPU cores and memory, and some
distributions have a larger kernel.pid_max parameter, e.g. 7 digits.
This impairs the readability of a few commands, especially "ps" and
"ps -l|-m" options.
Let's extend the field length of the task attributes, PID, CPU, VSZ,
and RSS to improve the readability.
Without the patch:
crash> ps
PID PPID CPU TASK ST %MEM VSZ RSS COMM
...
2802197 2699997 2 ffff916f63c40000 IN 0.0 307212 10688 timer
2802277 1 0 ffff9161a25bb080 IN 0.0 169040 2744 gpg-agent
2806711 3167854 10 ffff9167fc498000 IN 0.0 127208 6508 su
2806719 2806711 1 ffff91633c3a48c0 IN 0.0 29452 6416 bash
2988346 1 5 ffff916f7c629840 IN 2.8 9342476 1917384 qemu-kvm
With the patch:
crash> ps
PID PPID CPU TASK ST %MEM VSZ RSS COMM
...
2802197 2699997 2 ffff916f63c40000 IN 0.0 307212 10688 timer
2802277 1 0 ffff9161a25bb080 IN 0.0 169040 2744 gpg-agent
2806711 3167854 10 ffff9167fc498000 IN 0.0 127208 6508 su
2806719 2806711 1 ffff91633c3a48c0 IN 0.0 29452 6416 bash
2988346 1 5 ffff916f7c629840 IN 2.8 9342476 1917384 qemu-kvm
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
task.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/task.c b/task.c
index 864c838637ee..071c787fbfa5 100644
--- a/task.c
+++ b/task.c
@@ -3828,7 +3828,7 @@ show_ps_data(ulong flag, struct task_context *tc, struct psinfo *psi)
} else
fprintf(fp, " ");
- fprintf(fp, "%5ld %5ld %2s %s %3s",
+ fprintf(fp, "%7ld %7ld %3s %s %3s",
tc->pid, task_to_pid(tc->ptask),
task_cpu(tc->processor, buf2, !VERBOSE),
task_pointer_string(tc, flag & PS_KSTACKP, buf3),
@@ -3838,8 +3838,8 @@ show_ps_data(ulong flag, struct task_context *tc, struct psinfo *psi)
if (strlen(buf1) == 3)
mkstring(buf1, 4, CENTER|RJUST, NULL);
fprintf(fp, "%s ", buf1);
- fprintf(fp, "%7ld ", (tm->total_vm * PAGESIZE())/1024);
- fprintf(fp, "%6ld ", (tm->rss * PAGESIZE())/1024);
+ fprintf(fp, "%8ld ", (tm->total_vm * PAGESIZE())/1024);
+ fprintf(fp, "%8ld ", (tm->rss * PAGESIZE())/1024);
if (is_kernel_thread(tc->task))
fprintf(fp, "[%s]\n", tc->comm);
else
@@ -3856,7 +3856,7 @@ show_ps(ulong flag, struct psinfo *psi)
if (!(flag & ((PS_EXCLUSIVE & ~PS_ACTIVE)|PS_NO_HEADER)))
fprintf(fp,
- " PID PPID CPU %s ST %%MEM VSZ RSS COMM\n",
+ " PID PPID CPU %s ST %%MEM VSZ RSS COMM\n",
flag & PS_KSTACKP ?
mkstring(buf, VADDR_PRLEN, CENTER|RJUST, "KSTACKP") :
mkstring(buf, VADDR_PRLEN, CENTER, "TASK"));
@@ -7713,7 +7713,7 @@ print_task_header(FILE *out, struct task_context *tc, int newline)
char buf[BUFSIZE];
char buf1[BUFSIZE];
- fprintf(out, "%sPID: %-5ld TASK: %s CPU: %-2s COMMAND: \"%s\"\n",
+ fprintf(out, "%sPID: %-7ld TASK: %s CPU: %-3s COMMAND: \"%s\"\n",
newline ? "\n" : "", tc->pid,
mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(tc->task)),
task_cpu(tc->processor, buf, !VERBOSE), tc->comm);
--
2.37.1

View File

@ -0,0 +1,168 @@
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,62 +0,0 @@
From 364b2e413c69daf189d2bc0238e3ba9b0dcbd937 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Mon, 23 May 2022 18:04:13 +0800
Subject: [PATCH 02/18] sbitmapq: remove struct and member validation in
sbitmapq_init()
Let's remove the struct and member validation from sbitmapq_init(), which
will help the crash to display the actual error when the sbitmapq fails.
Without the patch:
crash> sbitmapq ffff8e99d0dc8010
sbitmapq: command not supported or applicable on this architecture or kernel
With the patch:
crash> sbitmapq ffff8e99d0dc8010
sbitmapq: invalid structure member offset: sbitmap_queue_alloc_hint
FILE: sbitmap.c LINE: 365 FUNCTION: sbitmap_queue_context_load()
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
sbitmap.c | 24 ------------------------
1 file changed, 24 deletions(-)
diff --git a/sbitmap.c b/sbitmap.c
index 96a61e6c2c71..7693eef6cebd 100644
--- a/sbitmap.c
+++ b/sbitmap.c
@@ -525,30 +525,6 @@ void sbitmapq_init(void)
MEMBER_OFFSET_INIT(sbq_wait_state_wait_cnt, "sbq_wait_state", "wait_cnt");
MEMBER_OFFSET_INIT(sbq_wait_state_wait, "sbq_wait_state", "wait");
- if (!VALID_SIZE(sbitmap_word) ||
- !VALID_SIZE(sbitmap) ||
- !VALID_SIZE(sbitmap_queue) ||
- !VALID_SIZE(sbq_wait_state) ||
- INVALID_MEMBER(sbitmap_word_depth) ||
- INVALID_MEMBER(sbitmap_word_word) ||
- INVALID_MEMBER(sbitmap_word_cleared) ||
- INVALID_MEMBER(sbitmap_depth) ||
- INVALID_MEMBER(sbitmap_shift) ||
- INVALID_MEMBER(sbitmap_map_nr) ||
- INVALID_MEMBER(sbitmap_map) ||
- INVALID_MEMBER(sbitmap_queue_sb) ||
- INVALID_MEMBER(sbitmap_queue_alloc_hint) ||
- INVALID_MEMBER(sbitmap_queue_wake_batch) ||
- INVALID_MEMBER(sbitmap_queue_wake_index) ||
- INVALID_MEMBER(sbitmap_queue_ws) ||
- INVALID_MEMBER(sbitmap_queue_ws_active) ||
- INVALID_MEMBER(sbitmap_queue_round_robin) ||
- INVALID_MEMBER(sbitmap_queue_min_shallow_depth) ||
- INVALID_MEMBER(sbq_wait_state_wait_cnt) ||
- INVALID_MEMBER(sbq_wait_state_wait)) {
- command_not_supported();
- }
-
sb_flags |= SB_FLAG_INIT;
}
--
2.30.2

View File

@ -1,45 +0,0 @@
From 1c918c621e48f53ea69a143aabc59c8366102236 Mon Sep 17 00:00:00 2001
From: Hari Bathini <hbathini@linux.ibm.com>
Date: Mon, 4 Jul 2022 10:55:41 +0530
Subject: [PATCH 03/28] ppc64: fix bt for '-S' case
Passing '-S' option to 'bt' command was intended to specify the stack
pointer manually. But get_stack_frame() handling on ppc64 is ignoring
this option altogether. Fix it.
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
ppc64.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/ppc64.c b/ppc64.c
index 975caa53b812..0e1d8678eef5 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -2330,6 +2330,22 @@ ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
if (!pt_regs || !pt_regs->gpr[1]) {
+ if (bt_in->hp) {
+ if (bt_in->hp->esp) {
+ *ksp = bt_in->hp->esp;
+ if (!bt_in->hp->eip) {
+ if (IS_KVADDR(*ksp)) {
+ readmem(*ksp+16, KVADDR, &unip, sizeof(ulong),
+ "Regs NIP value", FAULT_ON_ERROR);
+ *nip = unip;
+ }
+ } else
+ *nip = bt_in->hp->eip;
+
+ }
+ return TRUE;
+ }
+
/*
* Not collected regs. May be the corresponding CPU not
* responded to an IPI in case of KDump OR f/w has not
--
2.37.1

View File

@ -1,118 +0,0 @@
From a295cb40cd5d24fb5995cc78d29c5def3843d285 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Mon, 23 May 2022 18:04:14 +0800
Subject: [PATCH 03/18] sbitmapq: fix invalid offset for
"sbitmap_queue_alloc_hint" on Linux v5.13-rc1
Kernel commit c548e62bcf6a ("scsi: sbitmap: Move allocation hint
into sbitmap") moved the alloc_hint member from struct sbitmap_queue
to struct sbitmap. Without the patch, the sbitmapq will fail:
crash> sbitmapq 0xffff8e99d0dc8010
sbitmapq: invalid structure member offset: sbitmap_queue_alloc_hint
FILE: sbitmap.c LINE: 365 FUNCTION: sbitmap_queue_context_load()
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 2 ++
sbitmap.c | 14 ++++++++++++--
symbols.c | 2 ++
3 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/defs.h b/defs.h
index a6735d07b32f..0aeb98c4f654 100644
--- a/defs.h
+++ b/defs.h
@@ -2168,6 +2168,7 @@ struct offset_table { /* stash of commonly-used offsets */
long sbitmap_queue_min_shallow_depth;
long sbq_wait_state_wait_cnt;
long sbq_wait_state_wait;
+ long sbitmap_alloc_hint;
};
struct size_table { /* stash of commonly-used sizes */
@@ -5907,6 +5908,7 @@ struct sbitmap_context {
unsigned shift;
unsigned map_nr;
ulong map_addr;
+ ulong alloc_hint;
};
typedef bool (*sbitmap_for_each_fn)(unsigned int idx, void *p);
diff --git a/sbitmap.c b/sbitmap.c
index 7693eef6cebd..2921d5447c65 100644
--- a/sbitmap.c
+++ b/sbitmap.c
@@ -285,6 +285,7 @@ void sbitmap_for_each_set(const struct sbitmap_context *sc,
static void sbitmap_queue_show(const struct sbitmap_queue_context *sqc,
const struct sbitmap_context *sc)
{
+ ulong alloc_hint_addr = 0;
int cpus = get_cpus_possible();
int sbq_wait_state_size, wait_cnt_off, wait_off, list_head_off;
char *sbq_wait_state_buf;
@@ -297,6 +298,11 @@ static void sbitmap_queue_show(const struct sbitmap_queue_context *sqc,
fprintf(fp, "bits_per_word = %u\n", 1U << sc->shift);
fprintf(fp, "map_nr = %u\n", sc->map_nr);
+ if (VALID_MEMBER(sbitmap_queue_alloc_hint))
+ alloc_hint_addr = sqc->alloc_hint;
+ else if (VALID_MEMBER(sbitmap_alloc_hint)) /* 5.13 and later */
+ alloc_hint_addr = sc->alloc_hint;
+
fputs("alloc_hint = {", fp);
first = true;
for (i = 0; i < cpus; i++) {
@@ -307,7 +313,7 @@ static void sbitmap_queue_show(const struct sbitmap_queue_context *sqc,
fprintf(fp, ", ");
first = false;
- ptr = kt->__per_cpu_offset[i] + sqc->alloc_hint;
+ ptr = kt->__per_cpu_offset[i] + alloc_hint_addr;
readmem(ptr, KVADDR, &val, sizeof(val), "alloc_hint", FAULT_ON_ERROR);
fprintf(fp, "%u", val);
@@ -362,7 +368,8 @@ static void sbitmap_queue_context_load(ulong addr, struct sbitmap_queue_context
error(FATAL, "cannot read sbitmap_queue\n");
}
- sqc->alloc_hint = ULONG(sbitmap_queue_buf + OFFSET(sbitmap_queue_alloc_hint));
+ if (VALID_MEMBER(sbitmap_queue_alloc_hint))
+ sqc->alloc_hint = ULONG(sbitmap_queue_buf + OFFSET(sbitmap_queue_alloc_hint));
sqc->wake_batch = UINT(sbitmap_queue_buf + OFFSET(sbitmap_queue_wake_batch));
sqc->wake_index = INT(sbitmap_queue_buf + OFFSET(sbitmap_queue_wake_index));
sqc->ws_addr = ULONG(sbitmap_queue_buf + OFFSET(sbitmap_queue_ws));
@@ -387,6 +394,8 @@ void sbitmap_context_load(ulong addr, struct sbitmap_context *sc)
sc->shift = UINT(sbitmap_buf + OFFSET(sbitmap_shift));
sc->map_nr = UINT(sbitmap_buf + OFFSET(sbitmap_map_nr));
sc->map_addr = ULONG(sbitmap_buf + OFFSET(sbitmap_map));
+ if (VALID_MEMBER(sbitmap_alloc_hint))
+ sc->alloc_hint = ULONG(sbitmap_buf + OFFSET(sbitmap_alloc_hint));
FREEBUF(sbitmap_buf);
}
@@ -512,6 +521,7 @@ void sbitmapq_init(void)
MEMBER_OFFSET_INIT(sbitmap_shift, "sbitmap", "shift");
MEMBER_OFFSET_INIT(sbitmap_map_nr, "sbitmap", "map_nr");
MEMBER_OFFSET_INIT(sbitmap_map, "sbitmap", "map");
+ MEMBER_OFFSET_INIT(sbitmap_alloc_hint, "sbitmap", "alloc_hint");
MEMBER_OFFSET_INIT(sbitmap_queue_sb, "sbitmap_queue", "sb");
MEMBER_OFFSET_INIT(sbitmap_queue_alloc_hint, "sbitmap_queue", "alloc_hint");
diff --git a/symbols.c b/symbols.c
index ba5e2741347d..fd0eb06899f0 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10708,6 +10708,8 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(sbitmap_map_nr));
fprintf(fp, " sbitmap_map: %ld\n",
OFFSET(sbitmap_map));
+ fprintf(fp, " sbitmap_alloc_hint: %ld\n",
+ OFFSET(sbitmap_alloc_hint));
fprintf(fp, " sbitmap_queue_sb: %ld\n",
OFFSET(sbitmap_queue_sb));
fprintf(fp, " sbitmap_queue_alloc_hint: %ld\n",
--
2.30.2

View File

@ -0,0 +1,78 @@
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,147 +0,0 @@
From 6a89173a25450b679e4a713793b2ed36b077fe56 Mon Sep 17 00:00:00 2001
From: Hari Bathini <hbathini@linux.ibm.com>
Date: Mon, 4 Jul 2022 10:55:42 +0530
Subject: [PATCH 04/28] ppc64: dynamically allocate h/w interrupt stack
Only older kernel (v2.4) used h/w interrupt stack to store frames when
CPU received IPI. Memory used for this in 'struct machine_specific' is
useless for later kernels. For the sake of backward compatibility keep
h/w interrupt stack but dynamically allocate memory for it and save
some bytes from being wasted.
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 2 +-
ppc64.c | 51 +++++++++++++++++++++------------------------------
2 files changed, 22 insertions(+), 31 deletions(-)
diff --git a/defs.h b/defs.h
index c524a05d8105..d8fbeb89e335 100644
--- a/defs.h
+++ b/defs.h
@@ -6311,7 +6311,7 @@ struct ppc64_vmemmap {
* Used to store the HW interrupt stack. It is only for 2.4.
*/
struct machine_specific {
- ulong hwintrstack[NR_CPUS];
+ ulong *hwintrstack;
char *hwstackbuf;
uint hwstacksize;
diff --git a/ppc64.c b/ppc64.c
index 0e1d8678eef5..272eb207074a 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -256,7 +256,7 @@ static int set_ppc64_max_physmem_bits(void)
}
struct machine_specific ppc64_machine_specific = {
- .hwintrstack = { 0 },
+ .hwintrstack = NULL,
.hwstackbuf = 0,
.hwstacksize = 0,
.pte_rpn_shift = PTE_RPN_SHIFT_DEFAULT,
@@ -275,7 +275,7 @@ struct machine_specific ppc64_machine_specific = {
};
struct machine_specific book3e_machine_specific = {
- .hwintrstack = { 0 },
+ .hwintrstack = NULL,
.hwstackbuf = 0,
.hwstacksize = 0,
.pte_rpn_shift = PTE_RPN_SHIFT_L4_BOOK3E_64K,
@@ -676,6 +676,9 @@ ppc64_init(int when)
*/
offset = MEMBER_OFFSET("paca_struct", "xHrdIntStack");
paca_sym = symbol_value("paca");
+ if (!(machdep->machspec->hwintrstack =
+ (ulong *)calloc(NR_CPUS, sizeof(ulong))))
+ error(FATAL, "cannot malloc hwintrstack space.");
for (cpu = 0; cpu < kt->cpus; cpu++) {
readmem(paca_sym + (paca_size * cpu) + offset,
KVADDR,
@@ -686,14 +689,9 @@ ppc64_init(int when)
machdep->machspec->hwstacksize = 8 * machdep->pagesize;
if ((machdep->machspec->hwstackbuf = (char *)
malloc(machdep->machspec->hwstacksize)) == NULL)
- error(FATAL, "cannot malloc hwirqstack space.");
- } else
- /*
- * 'xHrdIntStack' member in "paca_struct" is not
- * available for 2.6 kernel.
- */
- BZERO(&machdep->machspec->hwintrstack,
- NR_CPUS*sizeof(ulong));
+ error(FATAL, "cannot malloc hwirqstack buffer space.");
+ }
+
if (!machdep->hz) {
machdep->hz = HZ;
if (THIS_KERNEL_VERSION >= LINUX(2,6,0))
@@ -846,23 +844,15 @@ ppc64_dump_machdep_table(ulong arg)
fprintf(fp, " is_vmaddr: %s\n",
machdep->machspec->is_vmaddr == book3e_is_vmaddr ?
"book3e_is_vmaddr()" : "ppc64_is_vmaddr()");
- fprintf(fp, " hwintrstack[%d]: ", NR_CPUS);
- for (c = 0; c < NR_CPUS; c++) {
- for (others = 0, i = c; i < NR_CPUS; i++) {
- if (machdep->machspec->hwintrstack[i])
- others++;
+ if (machdep->machspec->hwintrstack) {
+ fprintf(fp, " hwintrstack[%d]: ", NR_CPUS);
+ for (c = 0; c < NR_CPUS; c++) {
+ fprintf(fp, "%s%016lx ",
+ ((c % 4) == 0) ? "\n " : "",
+ machdep->machspec->hwintrstack[c]);
}
- if (!others) {
- fprintf(fp, "%s%s",
- c && ((c % 4) == 0) ? "\n " : "",
- c ? "(remainder unused)" : "(unused)");
- break;
- }
-
- fprintf(fp, "%s%016lx ",
- ((c % 4) == 0) ? "\n " : "",
- machdep->machspec->hwintrstack[c]);
- }
+ } else
+ fprintf(fp, " hwintrstack: (unused)");
fprintf(fp, "\n");
fprintf(fp, " hwstackbuf: %lx\n", (ulong)machdep->machspec->hwstackbuf);
fprintf(fp, " hwstacksize: %d\n", machdep->machspec->hwstacksize);
@@ -1683,9 +1673,10 @@ ppc64_check_sp_in_HWintrstack(ulong sp, struct bt_info *bt)
*
* Note: HW Interrupt stack is used only in 2.4 kernel.
*/
- if (is_task_active(bt->task) && (tt->panic_task != bt->task) &&
- machdep->machspec->hwintrstack[bt->tc->processor]) {
+ if (machdep->machspec->hwintrstack && is_task_active(bt->task) &&
+ (bt->task != tt->panic_task)) {
ulong newsp;
+
readmem(machdep->machspec->hwintrstack[bt->tc->processor],
KVADDR, &newsp, sizeof(ulong),
"stack pointer", FAULT_ON_ERROR);
@@ -1958,7 +1949,7 @@ ppc64_back_trace(struct gnu_request *req, struct bt_info *bt)
bt->stackbase = irqstack;
bt->stacktop = bt->stackbase + STACKSIZE();
alter_stackbuf(bt);
- } else if (ms->hwintrstack[bt->tc->processor]) {
+ } else if (ms->hwintrstack) {
bt->stacktop = ms->hwintrstack[bt->tc->processor] +
sizeof(ulong);
bt->stackbase = ms->hwintrstack[bt->tc->processor] -
@@ -2555,7 +2546,7 @@ retry:
goto retry;
}
- if (check_intrstack && ms->hwintrstack[bt->tc->processor]) {
+ if (check_intrstack && ms->hwintrstack) {
bt->stacktop = ms->hwintrstack[bt->tc->processor] +
sizeof(ulong);
bt->stackbase = ms->hwintrstack[bt->tc->processor] -
--
2.37.1

View File

@ -1,103 +0,0 @@
From 530fe6ad7e4d7ff6254596c1219d25ed929e3867 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Mon, 23 May 2022 18:04:15 +0800
Subject: [PATCH 04/18] sbitmapq: fix invalid offset for
"sbitmap_queue_round_robin" on Linux v5.13-rc1
Kernel commit efe1f3a1d583 ("scsi: sbitmap: Maintain allocation
round_robin in sbitmap") moved the round_robin member from struct
sbitmap_queue to struct sbitmap. Without the patch, the sbitmapq
will fail:
crash> sbitmapq 0xffff8e99d0dc8010
sbitmapq: invalid structure member offset: sbitmap_queue_round_robin
FILE: sbitmap.c LINE: 378 FUNCTION: sbitmap_queue_context_load()
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 2 ++
sbitmap.c | 12 ++++++++++--
symbols.c | 2 ++
3 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/defs.h b/defs.h
index 0aeb98c4f654..ecbced24d2e3 100644
--- a/defs.h
+++ b/defs.h
@@ -2169,6 +2169,7 @@ struct offset_table { /* stash of commonly-used offsets */
long sbq_wait_state_wait_cnt;
long sbq_wait_state_wait;
long sbitmap_alloc_hint;
+ long sbitmap_round_robin;
};
struct size_table { /* stash of commonly-used sizes */
@@ -5909,6 +5910,7 @@ struct sbitmap_context {
unsigned map_nr;
ulong map_addr;
ulong alloc_hint;
+ bool round_robin;
};
typedef bool (*sbitmap_for_each_fn)(unsigned int idx, void *p);
diff --git a/sbitmap.c b/sbitmap.c
index 2921d5447c65..7b318b533702 100644
--- a/sbitmap.c
+++ b/sbitmap.c
@@ -352,7 +352,11 @@ static void sbitmap_queue_show(const struct sbitmap_queue_context *sqc,
FREEBUF(sbq_wait_state_buf);
- fprintf(fp, "round_robin = %d\n", sqc->round_robin);
+ if (VALID_MEMBER(sbitmap_queue_round_robin))
+ fprintf(fp, "round_robin = %d\n", sqc->round_robin);
+ else if (VALID_MEMBER(sbitmap_round_robin)) /* 5.13 and later */
+ fprintf(fp, "round_robin = %d\n", sc->round_robin);
+
fprintf(fp, "min_shallow_depth = %u\n", sqc->min_shallow_depth);
}
@@ -374,7 +378,8 @@ static void sbitmap_queue_context_load(ulong addr, struct sbitmap_queue_context
sqc->wake_index = INT(sbitmap_queue_buf + OFFSET(sbitmap_queue_wake_index));
sqc->ws_addr = ULONG(sbitmap_queue_buf + OFFSET(sbitmap_queue_ws));
sqc->ws_active = INT(sbitmap_queue_buf + OFFSET(sbitmap_queue_ws_active));
- sqc->round_robin = BOOL(sbitmap_queue_buf + OFFSET(sbitmap_queue_round_robin));
+ if (VALID_MEMBER(sbitmap_queue_round_robin))
+ sqc->round_robin = BOOL(sbitmap_queue_buf + OFFSET(sbitmap_queue_round_robin));
sqc->min_shallow_depth = UINT(sbitmap_queue_buf + OFFSET(sbitmap_queue_min_shallow_depth));
FREEBUF(sbitmap_queue_buf);
@@ -396,6 +401,8 @@ void sbitmap_context_load(ulong addr, struct sbitmap_context *sc)
sc->map_addr = ULONG(sbitmap_buf + OFFSET(sbitmap_map));
if (VALID_MEMBER(sbitmap_alloc_hint))
sc->alloc_hint = ULONG(sbitmap_buf + OFFSET(sbitmap_alloc_hint));
+ if (VALID_MEMBER(sbitmap_round_robin))
+ sc->round_robin = BOOL(sbitmap_buf + OFFSET(sbitmap_round_robin));
FREEBUF(sbitmap_buf);
}
@@ -522,6 +529,7 @@ void sbitmapq_init(void)
MEMBER_OFFSET_INIT(sbitmap_map_nr, "sbitmap", "map_nr");
MEMBER_OFFSET_INIT(sbitmap_map, "sbitmap", "map");
MEMBER_OFFSET_INIT(sbitmap_alloc_hint, "sbitmap", "alloc_hint");
+ MEMBER_OFFSET_INIT(sbitmap_round_robin, "sbitmap", "round_robin");
MEMBER_OFFSET_INIT(sbitmap_queue_sb, "sbitmap_queue", "sb");
MEMBER_OFFSET_INIT(sbitmap_queue_alloc_hint, "sbitmap_queue", "alloc_hint");
diff --git a/symbols.c b/symbols.c
index fd0eb06899f0..5d12a021c769 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10710,6 +10710,8 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(sbitmap_map));
fprintf(fp, " sbitmap_alloc_hint: %ld\n",
OFFSET(sbitmap_alloc_hint));
+ fprintf(fp, " sbitmap_round_robin: %ld\n",
+ OFFSET(sbitmap_round_robin));
fprintf(fp, " sbitmap_queue_sb: %ld\n",
OFFSET(sbitmap_queue_sb));
fprintf(fp, " sbitmap_queue_alloc_hint: %ld\n",
--
2.30.2

View File

@ -0,0 +1,171 @@
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,56 +0,0 @@
From 4dbf7e296f6fde05894a55e23fbaf0d50e3b38b9 Mon Sep 17 00:00:00 2001
From: Hari Bathini <hbathini@linux.ibm.com>
Date: Mon, 4 Jul 2022 10:55:43 +0530
Subject: [PATCH 05/28] ppc64: rename ppc64_paca_init to
ppc64_paca_percpu_offset_init
ppc64_paca_init() function is specifically used to initialize percpu
data_offset for kernels older than v2.6.36. So, the name is slightly
misleading. Rename it to ppc64_paca_percpu_offset_init to reflect its
purpose.
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
ppc64.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/ppc64.c b/ppc64.c
index 272eb207074a..0a3aa5f7af91 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -52,7 +52,7 @@ static char * ppc64_check_eframe(struct ppc64_pt_regs *);
static void ppc64_print_eframe(char *, struct ppc64_pt_regs *,
struct bt_info *);
static void parse_cmdline_args(void);
-static int ppc64_paca_init(int);
+static int ppc64_paca_percpu_offset_init(int);
static void ppc64_init_cpu_info(void);
static int ppc64_get_cpu_map(void);
static void ppc64_clear_machdep_cache(void);
@@ -3285,7 +3285,7 @@ parse_cmdline_args(void)
* Initialize the per cpu data_offset values from paca structure.
*/
static int
-ppc64_paca_init(int map)
+ppc64_paca_percpu_offset_init(int map)
{
int i, cpus, nr_paca;
char *cpu_paca_buf;
@@ -3387,10 +3387,11 @@ ppc64_init_cpu_info(void)
* which was removed post v2.6.15 ppc64 and now we get the per cpu
* data_offset from __per_cpu_offset symbol during kernel_init()
* call. Hence for backward (pre-2.6.36) compatibility, call
- * ppc64_paca_init() only if symbol __per_cpu_offset does not exist.
+ * ppc64_paca_percpu_offset_init() only if symbol __per_cpu_offset
+ * does not exist.
*/
if (!symbol_exists("__per_cpu_offset"))
- cpus = ppc64_paca_init(map);
+ cpus = ppc64_paca_percpu_offset_init(map);
else {
if (!(nr_cpus = get_array_length("__per_cpu_offset", NULL, 0)))
nr_cpus = (kt->kernel_NR_CPUS ? kt->kernel_NR_CPUS :
--
2.37.1

View File

@ -1,101 +0,0 @@
From 3750803f6ae5f5ad071f86ca916dbbb17b7a83a5 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Mon, 23 May 2022 18:04:16 +0800
Subject: [PATCH 05/18] sbitmapq: fix invalid offset for "sbitmap_word_depth"
on Linux v5.18-rc1
Kernel commit 3301bc53358a ("lib/sbitmap: kill 'depth' from sbitmap_word")
removed the depth member from struct sbitmap_word. Without the patch, the
sbitmapq will fail:
crash> sbitmapq 0xffff8e99d0dc8010
sbitmapq: invalid structure member offset: sbitmap_word_depth
FILE: sbitmap.c LINE: 84 FUNCTION: __sbitmap_weight()
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
sbitmap.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/sbitmap.c b/sbitmap.c
index 7b318b533702..e8ebd62fe01c 100644
--- a/sbitmap.c
+++ b/sbitmap.c
@@ -78,10 +78,16 @@ static unsigned long bitmap_weight(unsigned long bitmap, unsigned int bits)
return w;
}
+static inline unsigned int __map_depth(const struct sbitmap_context *sc, int index)
+{
+ if (index == sc->map_nr - 1)
+ return sc->depth - (index << sc->shift);
+ return 1U << sc->shift;
+}
+
static unsigned int __sbitmap_weight(const struct sbitmap_context *sc, bool set)
{
const ulong sbitmap_word_size = SIZE(sbitmap_word);
- const ulong w_depth_off = OFFSET(sbitmap_word_depth);
const ulong w_word_off = OFFSET(sbitmap_word_word);
const ulong w_cleared_off = OFFSET(sbitmap_word_cleared);
@@ -99,7 +105,7 @@ static unsigned int __sbitmap_weight(const struct sbitmap_context *sc, bool set)
error(FATAL, "cannot read sbitmap_word\n");
}
- depth = ULONG(sbitmap_word_buf + w_depth_off);
+ depth = __map_depth(sc, i);
if (set) {
word = ULONG(sbitmap_word_buf + w_word_off);
@@ -142,7 +148,6 @@ static void sbitmap_emit_byte(unsigned int offset, uint8_t byte)
static void sbitmap_bitmap_show(const struct sbitmap_context *sc)
{
const ulong sbitmap_word_size = SIZE(sbitmap_word);
- const ulong w_depth_off = OFFSET(sbitmap_word_depth);
const ulong w_word_off = OFFSET(sbitmap_word_word);
const ulong w_cleared_off = OFFSET(sbitmap_word_cleared);
@@ -165,7 +170,7 @@ static void sbitmap_bitmap_show(const struct sbitmap_context *sc)
word = ULONG(sbitmap_word_buf + w_word_off);
cleared = ULONG(sbitmap_word_buf + w_cleared_off);
- word_bits = ULONG(sbitmap_word_buf + w_depth_off);
+ word_bits = __map_depth(sc, i);
word &= ~cleared;
@@ -213,7 +218,6 @@ static void __sbitmap_for_each_set(const struct sbitmap_context *sc,
unsigned int start, sbitmap_for_each_fn fn, void *data)
{
const ulong sbitmap_word_size = SIZE(sbitmap_word);
- const ulong w_depth_off = OFFSET(sbitmap_word_depth);
const ulong w_word_off = OFFSET(sbitmap_word_word);
const ulong w_cleared_off = OFFSET(sbitmap_word_cleared);
@@ -232,7 +236,7 @@ static void __sbitmap_for_each_set(const struct sbitmap_context *sc,
while (scanned < sc->depth) {
unsigned long w_addr = sc->map_addr + (sbitmap_word_size * index);
- unsigned long w_depth, w_word, w_cleared;
+ unsigned long w_word, w_cleared;
unsigned long word, depth;
if (!readmem(w_addr, KVADDR, sbitmap_word_buf, sbitmap_word_size, "sbitmap_word", RETURN_ON_ERROR)) {
@@ -240,11 +244,10 @@ static void __sbitmap_for_each_set(const struct sbitmap_context *sc,
error(FATAL, "cannot read sbitmap_word\n");
}
- w_depth = ULONG(sbitmap_word_buf + w_depth_off);
w_word = ULONG(sbitmap_word_buf + w_word_off);
w_cleared = ULONG(sbitmap_word_buf + w_cleared_off);
- depth = min(w_depth - nr, sc->depth - scanned);
+ depth = min(__map_depth(sc, index) - nr, sc->depth - scanned);
scanned += depth;
word = w_word & ~w_cleared;
--
2.30.2

View File

@ -0,0 +1,67 @@
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,352 +0,0 @@
From f256095c61355d8db11502709ab3a084343f2bec Mon Sep 17 00:00:00 2001
From: Hari Bathini <hbathini@linux.ibm.com>
Date: Mon, 4 Jul 2022 10:55:44 +0530
Subject: [PATCH 06/28] ppc64: handle backtrace when CPU is in an emergency
stack
A CPU could be in an emergency stack when it is running in real mode
or any special scenario like TM bad thing. Also, there are dedicated
emergency stacks for machine check and system reset interrupt. Right
now, no backtrace is provided if a CPU is in any of these stacks.
This change ensures backtrace is processed appropriately even when
a CPU is in any one of these emergency stacks. Also, if stack info
cannot be found, print that message always instead of only when
verbose logs are enabled.
Related kernel commits:
729b0f715371 ("powerpc/book3s: Introduce exclusive emergency stack for machine check exception.")
b1ee8a3de579 ("powerpc/64s: Dedicated system reset interrupt stack")
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 12 ++++
ppc64.c | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 203 insertions(+), 12 deletions(-)
diff --git a/defs.h b/defs.h
index d8fbeb89e335..6a1b6f8a16a8 100644
--- a/defs.h
+++ b/defs.h
@@ -6296,6 +6296,13 @@ struct ppc64_elf_prstatus {
#ifdef PPC64
+enum emergency_stack_type {
+ NONE_STACK = 0,
+ EMERGENCY_STACK,
+ NMI_EMERGENCY_STACK,
+ MC_EMERGENCY_STACK
+};
+
struct ppc64_opal {
uint64_t base;
uint64_t entry;
@@ -6315,6 +6322,11 @@ struct machine_specific {
char *hwstackbuf;
uint hwstacksize;
+ /* Emergency stacks */
+ ulong *emergency_sp;
+ ulong *nmi_emergency_sp;
+ ulong *mc_emergency_sp;
+
uint l4_index_size;
uint l3_index_size;
uint l2_index_size;
diff --git a/ppc64.c b/ppc64.c
index 0a3aa5f7af91..03047a85955d 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -48,6 +48,10 @@ static ulong ppc64_get_stackbase(ulong);
static ulong ppc64_get_stacktop(ulong);
void ppc64_compiler_warning_stub(void);
static ulong ppc64_in_irqstack(ulong);
+static enum emergency_stack_type ppc64_in_emergency_stack(int cpu, ulong addr,
+ bool verbose);
+static void ppc64_set_bt_emergency_stack(enum emergency_stack_type type,
+ struct bt_info *bt);
static char * ppc64_check_eframe(struct ppc64_pt_regs *);
static void ppc64_print_eframe(char *, struct ppc64_pt_regs *,
struct bt_info *);
@@ -56,6 +60,7 @@ static int ppc64_paca_percpu_offset_init(int);
static void ppc64_init_cpu_info(void);
static int ppc64_get_cpu_map(void);
static void ppc64_clear_machdep_cache(void);
+static void ppc64_init_paca_info(void);
static void ppc64_vmemmap_init(void);
static int ppc64_get_kvaddr_ranges(struct vaddr_range *);
static uint get_ptetype(ulong pte);
@@ -692,6 +697,8 @@ ppc64_init(int when)
error(FATAL, "cannot malloc hwirqstack buffer space.");
}
+ ppc64_init_paca_info();
+
if (!machdep->hz) {
machdep->hz = HZ;
if (THIS_KERNEL_VERSION >= LINUX(2,6,0))
@@ -1204,6 +1211,70 @@ ppc64_kvtop(struct task_context *tc, ulong kvaddr,
return ppc64_vtop(kvaddr, (ulong *)vt->kernel_pgd[0], paddr, verbose);
}
+static void
+ppc64_init_paca_info(void)
+{
+ struct machine_specific *ms = machdep->machspec;
+ ulong *paca_ptr;
+ int i;
+
+ if (!(paca_ptr = (ulong *)calloc(kt->cpus, sizeof(ulong))))
+ error(FATAL, "cannot malloc paca pointers space.\n");
+
+ /* Get paca pointers for all CPUs. */
+ if (symbol_exists("paca_ptrs")) {
+ ulong paca_loc;
+
+ readmem(symbol_value("paca_ptrs"), KVADDR, &paca_loc, sizeof(void *),
+ "paca double pointer", FAULT_ON_ERROR);
+ readmem(paca_loc, KVADDR, paca_ptr, sizeof(void *) * kt->cpus,
+ "paca pointers", FAULT_ON_ERROR);
+ } else if (symbol_exists("paca") &&
+ (get_symbol_type("paca", NULL, NULL) == TYPE_CODE_PTR)) {
+ readmem(symbol_value("paca"), KVADDR, paca_ptr, sizeof(void *) * kt->cpus,
+ "paca pointers", FAULT_ON_ERROR);
+ } else {
+ free(paca_ptr);
+ return;
+ }
+
+ /* Initialize emergency stacks info. */
+ if (MEMBER_EXISTS("paca_struct", "emergency_sp")) {
+ ulong offset = MEMBER_OFFSET("paca_struct", "emergency_sp");
+
+ if (!(ms->emergency_sp = (ulong *)calloc(kt->cpus, sizeof(ulong))))
+ error(FATAL, "cannot malloc emergency stack space.\n");
+ for (i = 0; i < kt->cpus; i++)
+ readmem(paca_ptr[i] + offset, KVADDR, &ms->emergency_sp[i],
+ sizeof(void *), "paca->emergency_sp",
+ FAULT_ON_ERROR);
+ }
+
+ if (MEMBER_EXISTS("paca_struct", "nmi_emergency_sp")) {
+ ulong offset = MEMBER_OFFSET("paca_struct", "nmi_emergency_sp");
+
+ if (!(ms->nmi_emergency_sp = (ulong *)calloc(kt->cpus, sizeof(ulong))))
+ error(FATAL, "cannot malloc NMI emergency stack space.\n");
+ for (i = 0; i < kt->cpus; i++)
+ readmem(paca_ptr[i] + offset, KVADDR, &ms->nmi_emergency_sp[i],
+ sizeof(void *), "paca->nmi_emergency_sp",
+ FAULT_ON_ERROR);
+ }
+
+ if (MEMBER_EXISTS("paca_struct", "mc_emergency_sp")) {
+ ulong offset = MEMBER_OFFSET("paca_struct", "mc_emergency_sp");
+
+ if (!(ms->mc_emergency_sp = (ulong *)calloc(kt->cpus, sizeof(ulong))))
+ error(FATAL, "cannot malloc machine check emergency stack space.\n");
+ for (i = 0; i < kt->cpus; i++)
+ readmem(paca_ptr[i] + offset, KVADDR, &ms->mc_emergency_sp[i],
+ sizeof(void *), "paca->mc_emergency_sp",
+ FAULT_ON_ERROR);
+ }
+
+ free(paca_ptr);
+}
+
/*
* Verify that the kernel has made the vmemmap list available,
* and if so, stash the relevant data required to make vtop
@@ -1755,6 +1826,11 @@ ppc64_eframe_search(struct bt_info *bt_in)
addr = bt->stackbase +
roundup(SIZE(thread_info), sizeof(ulong));
} else if (!INSTACK(addr, bt)) {
+ enum emergency_stack_type estype;
+
+ if ((estype = ppc64_in_emergency_stack(bt->tc->processor, addr, false)))
+ ppc64_set_bt_emergency_stack(estype, bt);
+
/*
* If the user specified SP is in HW interrupt stack
* (only for tasks running on other CPUs and in 2.4
@@ -1856,6 +1932,84 @@ ppc64_in_irqstack(ulong addr)
return 0;
}
+/*
+ * Check if the CPU is running in any of its emergency stacks.
+ * Returns
+ * NONE_STACK : if input is invalid or addr is not within any emergency stack.
+ * EMERGENCY_STACK : if the addr is within emergency stack.
+ * NMI_EMERGENCY_STACK : if the addr is within NMI emergency stack.
+ * MC_EMERGENCY_STACK : if the addr is within machine check emergency stack.
+ */
+static enum emergency_stack_type
+ppc64_in_emergency_stack(int cpu, ulong addr, bool verbose)
+{
+ struct machine_specific *ms = machdep->machspec;
+ ulong base, top;
+
+ if (cpu < 0 || cpu >= kt->cpus)
+ return NONE_STACK;
+
+ if (ms->emergency_sp) {
+ top = ms->emergency_sp[cpu];
+ base = top - STACKSIZE();
+ if (addr >= base && addr < top) {
+ if (verbose)
+ fprintf(fp, "---<Emergency Stack>---\n");
+ return EMERGENCY_STACK;
+ }
+ }
+
+ if (ms->nmi_emergency_sp) {
+ top = ms->nmi_emergency_sp[cpu];
+ base = top - STACKSIZE();
+ if (addr >= base && addr < top) {
+ if (verbose)
+ fprintf(fp, "---<NMI Emergency Stack>---\n");
+ return NMI_EMERGENCY_STACK;
+ }
+ }
+
+ if (ms->mc_emergency_sp) {
+ top = ms->mc_emergency_sp[cpu];
+ base = top - STACKSIZE();
+ if (addr >= base && addr < top) {
+ if (verbose)
+ fprintf(fp, "---<Machine Check Emergency Stack>---\n");
+ return MC_EMERGENCY_STACK;
+ }
+ }
+
+ return NONE_STACK;
+}
+
+static void
+ppc64_set_bt_emergency_stack(enum emergency_stack_type type, struct bt_info *bt)
+{
+ struct machine_specific *ms = machdep->machspec;
+ ulong top;
+
+ switch (type) {
+ case EMERGENCY_STACK:
+ top = ms->emergency_sp[bt->tc->processor];
+ break;
+ case NMI_EMERGENCY_STACK:
+ top = ms->nmi_emergency_sp[bt->tc->processor];
+ break;
+ case MC_EMERGENCY_STACK:
+ top = ms->mc_emergency_sp[bt->tc->processor];
+ break;
+ default:
+ top = 0;
+ break;
+ }
+
+ if (top) {
+ bt->stackbase = top - STACKSIZE();
+ bt->stacktop = top;
+ alter_stackbuf(bt);
+ }
+}
+
/*
* Unroll a kernel stack.
*/
@@ -1936,10 +2090,13 @@ ppc64_back_trace_cmd(struct bt_info *bt)
static void
ppc64_back_trace(struct gnu_request *req, struct bt_info *bt)
{
- int frame = 0;
- ulong lr = 0; /* hack...need to pass in initial lr reg */
+ enum emergency_stack_type estype;
ulong newpc = 0, newsp, marker;
+ int c = bt->tc->processor;
+ ulong nmi_sp = 0;
int eframe_found;
+ int frame = 0;
+ ulong lr = 0; /* hack...need to pass in initial lr reg */
if (!INSTACK(req->sp, bt)) {
ulong irqstack;
@@ -1949,6 +2106,10 @@ ppc64_back_trace(struct gnu_request *req, struct bt_info *bt)
bt->stackbase = irqstack;
bt->stacktop = bt->stackbase + STACKSIZE();
alter_stackbuf(bt);
+ } else if ((estype = ppc64_in_emergency_stack(c, req->sp, true))) {
+ if (estype == NMI_EMERGENCY_STACK)
+ nmi_sp = req->sp;
+ ppc64_set_bt_emergency_stack(estype, bt);
} else if (ms->hwintrstack) {
bt->stacktop = ms->hwintrstack[bt->tc->processor] +
sizeof(ulong);
@@ -1957,9 +2118,7 @@ ppc64_back_trace(struct gnu_request *req, struct bt_info *bt)
bt->stackbuf = ms->hwstackbuf;
alter_stackbuf(bt);
} else {
- if (CRASHDEBUG(1)) {
- fprintf(fp, "cannot find the stack info.\n");
- }
+ fprintf(fp, "cannot find the stack info.\n");
return;
}
}
@@ -1989,13 +2148,20 @@ ppc64_back_trace(struct gnu_request *req, struct bt_info *bt)
newsp =
*(ulong *)&bt->stackbuf[newsp - bt->stackbase];
if (!INSTACK(newsp, bt)) {
- /*
- * Switch HW interrupt stack to process's stack.
- */
- bt->stackbase = GET_STACKBASE(bt->task);
- bt->stacktop = GET_STACKTOP(bt->task);
- alter_stackbuf(bt);
- }
+ if ((estype = ppc64_in_emergency_stack(c, newsp, true))) {
+ if (!nmi_sp && estype == NMI_EMERGENCY_STACK)
+ nmi_sp = newsp;
+ ppc64_set_bt_emergency_stack(estype, bt);
+ } else {
+ /*
+ * Switch HW interrupt stack or emergency stack
+ * to process's stack.
+ */
+ bt->stackbase = GET_STACKBASE(bt->task);
+ bt->stacktop = GET_STACKTOP(bt->task);
+ alter_stackbuf(bt);
+ }
+ }
if (IS_KVADDR(newsp) && INSTACK(newsp, bt))
newpc = *(ulong *)&bt->stackbuf[newsp + 16 -
bt->stackbase];
@@ -2039,6 +2205,16 @@ ppc64_back_trace(struct gnu_request *req, struct bt_info *bt)
}
}
+ /*
+ * NMI stack may not be re-entrant. In so, an SP in the NMI stack
+ * is likely to point back to an SP within the NMI stack, in case
+ * of a nested NMI.
+ */
+ if (nmi_sp && nmi_sp == newsp) {
+ fprintf(fp, "---<Nested NMI>---\n");
+ break;
+ }
+
/*
* Some Linux 3.7 kernel threads have been seen to have
* their end-of-trace stack linkage pointer pointing
@@ -2416,6 +2592,9 @@ ppc64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
pt_regs = (struct ppc64_pt_regs *)bt->machdep;
ur_nip = pt_regs->nip;
ur_ksp = pt_regs->gpr[1];
+ /* Print the collected regs for panic task. */
+ ppc64_print_regs(pt_regs);
+ ppc64_print_nip_lr(pt_regs, 1);
} else if ((pc->flags & KDUMP) ||
((pc->flags & DISKDUMP) &&
(*diskdump_flags & KDUMP_CMPRS_LOCAL))) {
--
2.37.1

View File

@ -0,0 +1,47 @@
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

@ -0,0 +1,43 @@
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,205 +0,0 @@
From 6833262bf87177d8affe4f91b2e7d2c76ecdf636 Mon Sep 17 00:00:00 2001
From: Qi Zheng <zhengqi.arch@bytedance.com>
Date: Tue, 24 May 2022 20:25:53 +0800
Subject: [PATCH 07/18] bt: x86_64: filter out idle task stack
When we use crash to troubleshoot softlockup and other problems,
we often use the 'bt -a' command to print the stacks of running
processes on all CPUs. But now some servers have hundreds of CPUs
(such as AMD machines), which causes the 'bt -a' command to output
a lot of process stacks. And many of these stacks are the stacks
of the idle process, which are not needed by us.
Therefore, in order to reduce this part of the interference information,
this patch adds the -n option to the bt command. When we specify
'-n idle' (meaning no idle), the stack of the idle process will be
filtered out, thus speeding up our troubleshooting.
And the option works only for crash dumps captured by kdump.
The command output is as follows:
crash> bt -a -n idle
[...]
PID: 0 TASK: ffff889ff8c34380 CPU: 8 COMMAND: "swapper/8"
PID: 0 TASK: ffff889ff8c32d00 CPU: 9 COMMAND: "swapper/9"
PID: 0 TASK: ffff889ff8c31680 CPU: 10 COMMAND: "swapper/10"
PID: 0 TASK: ffff889ff8c35a00 CPU: 11 COMMAND: "swapper/11"
PID: 0 TASK: ffff889ff8c3c380 CPU: 12 COMMAND: "swapper/12"
PID: 150773 TASK: ffff889fe85a1680 CPU: 13 COMMAND: "bash"
#0 [ffffc9000d35bcd0] machine_kexec at ffffffff8105a407
#1 [ffffc9000d35bd28] __crash_kexec at ffffffff8113033d
#2 [ffffc9000d35bdf0] panic at ffffffff81081930
#3 [ffffc9000d35be70] sysrq_handle_crash at ffffffff814e38d1
#4 [ffffc9000d35be78] __handle_sysrq.cold.12 at ffffffff814e4175
#5 [ffffc9000d35bea8] write_sysrq_trigger at ffffffff814e404b
#6 [ffffc9000d35beb8] proc_reg_write at ffffffff81330d86
#7 [ffffc9000d35bed0] vfs_write at ffffffff812a72d5
#8 [ffffc9000d35bf00] ksys_write at ffffffff812a7579
#9 [ffffc9000d35bf38] do_syscall_64 at ffffffff81004259
RIP: 00007fa7abcdc274 RSP: 00007fffa731f678 RFLAGS: 00000246
RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007fa7abcdc274
RDX: 0000000000000002 RSI: 0000563ca51ee6d0 RDI: 0000000000000001
RBP: 0000563ca51ee6d0 R8: 000000000000000a R9: 00007fa7abd6be80
R10: 000000000000000a R11: 0000000000000246 R12: 00007fa7abdad760
R13: 0000000000000002 R14: 00007fa7abda8760 R15: 0000000000000002
ORIG_RAX: 0000000000000001 CS: 0033 SS: 002b
[...]
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Acked-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Acked-by: Lianbo Jiang <lijiang@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 1 +
help.c | 33 ++++++++++++++++++++++++++++++++-
kernel.c | 13 ++++++++++++-
x86_64.c | 8 ++++++++
4 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/defs.h b/defs.h
index ecbced24d2e3..c8444b4e54eb 100644
--- a/defs.h
+++ b/defs.h
@@ -5832,6 +5832,7 @@ ulong cpu_map_addr(const char *type);
#define BT_SHOW_ALL_REGS (0x2000000000000ULL)
#define BT_REGS_NOT_FOUND (0x4000000000000ULL)
#define BT_OVERFLOW_STACK (0x8000000000000ULL)
+#define BT_SKIP_IDLE (0x10000000000000ULL)
#define BT_SYMBOL_OFFSET (BT_SYMBOLIC_ARGS)
#define BT_REF_HEXVAL (0x1)
diff --git a/help.c b/help.c
index 51a0fe3d687c..e1bbc5abe029 100644
--- a/help.c
+++ b/help.c
@@ -1909,12 +1909,14 @@ char *help_bt[] = {
"bt",
"backtrace",
"[-a|-c cpu(s)|-g|-r|-t|-T|-l|-e|-E|-f|-F|-o|-O|-v|-p] [-R ref] [-s [-x|d]]"
-"\n [-I ip] [-S sp] [pid | task]",
+"\n [-I ip] [-S sp] [-n idle] [pid | task]",
" Display a kernel stack backtrace. If no arguments are given, the stack",
" trace of the current context will be displayed.\n",
" -a displays the stack traces of the active task on each CPU.",
" (only applicable to crash dumps)",
" -A same as -a, but also displays vector registers (S390X only).",
+" -n idle filter the stack of idle tasks (x86_64).",
+" (only applicable to crash dumps)",
" -p display the stack trace of the panic task only.",
" (only applicable to crash dumps)",
" -c cpu display the stack trace of the active task on one or more CPUs,",
@@ -2004,6 +2006,35 @@ char *help_bt[] = {
" DS: 002b ESI: bfffc8a0 ES: 002b EDI: 00000000 ",
" SS: 002b ESP: bfffc82c EBP: bfffd224 ",
" CS: 0023 EIP: 400d032e ERR: 0000008e EFLAGS: 00000246 ",
+" ",
+" Display the stack trace of the active task(s) when the kernel panicked,",
+" and filter out the stack of the idle tasks:",
+" ",
+" %s> bt -a -n idle",
+" ...",
+" PID: 0 TASK: ffff889ff8c35a00 CPU: 11 COMMAND: \"swapper/11\"",
+" ",
+" PID: 0 TASK: ffff889ff8c3c380 CPU: 12 COMMAND: \"swapper/12\"",
+" ",
+" PID: 150773 TASK: ffff889fe85a1680 CPU: 13 COMMAND: \"bash\"",
+" #0 [ffffc9000d35bcd0] machine_kexec at ffffffff8105a407",
+" #1 [ffffc9000d35bd28] __crash_kexec at ffffffff8113033d",
+" #2 [ffffc9000d35bdf0] panic at ffffffff81081930",
+" #3 [ffffc9000d35be70] sysrq_handle_crash at ffffffff814e38d1",
+" #4 [ffffc9000d35be78] __handle_sysrq.cold.12 at ffffffff814e4175",
+" #5 [ffffc9000d35bea8] write_sysrq_trigger at ffffffff814e404b",
+" #6 [ffffc9000d35beb8] proc_reg_write at ffffffff81330d86",
+" #7 [ffffc9000d35bed0] vfs_write at ffffffff812a72d5",
+" #8 [ffffc9000d35bf00] ksys_write at ffffffff812a7579",
+" #9 [ffffc9000d35bf38] do_syscall_64 at ffffffff81004259",
+" RIP: 00007fa7abcdc274 RSP: 00007fffa731f678 RFLAGS: 00000246",
+" RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007fa7abcdc274",
+" RDX: 0000000000000002 RSI: 0000563ca51ee6d0 RDI: 0000000000000001",
+" RBP: 0000563ca51ee6d0 R8: 000000000000000a R9: 00007fa7abd6be80",
+" R10: 000000000000000a R11: 0000000000000246 R12: 00007fa7abdad760",
+" R13: 0000000000000002 R14: 00007fa7abda8760 R15: 0000000000000002",
+" ORIG_RAX: 0000000000000001 CS: 0033 SS: 002b",
+" ...",
"\n Display the stack trace of the active task on CPU 0 and 1:\n",
" %s> bt -c 0,1",
" PID: 0 TASK: ffffffff81a8d020 CPU: 0 COMMAND: \"swapper\"",
diff --git a/kernel.c b/kernel.c
index d0921cf567d9..411e9da1e54f 100644
--- a/kernel.c
+++ b/kernel.c
@@ -2503,7 +2503,7 @@ cmd_bt(void)
if (kt->flags & USE_OPT_BT)
bt->flags |= BT_OPT_BACK_TRACE;
- while ((c = getopt(argcnt, args, "D:fFI:S:c:aAloreEgstTdxR:Ovp")) != EOF) {
+ while ((c = getopt(argcnt, args, "D:fFI:S:c:n:aAloreEgstTdxR:Ovp")) != EOF) {
switch (c)
{
case 'f':
@@ -2672,6 +2672,13 @@ cmd_bt(void)
active++;
break;
+ case 'n':
+ if (machine_type("X86_64") && STREQ(optarg, "idle"))
+ bt->flags |= BT_SKIP_IDLE;
+ else
+ option_not_supported(c);
+ break;
+
case 'r':
bt->flags |= BT_RAW;
break;
@@ -3092,6 +3099,10 @@ back_trace(struct bt_info *bt)
} else
machdep->get_stack_frame(bt, &eip, &esp);
+ /* skip idle task stack */
+ if (bt->flags & BT_SKIP_IDLE)
+ return;
+
if (bt->flags & BT_KSTACKP) {
bt->stkptr = esp;
return;
diff --git a/x86_64.c b/x86_64.c
index ecaefd2f46a8..cfafbcc4dabe 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -4918,6 +4918,9 @@ x86_64_get_stack_frame(struct bt_info *bt, ulong *pcp, ulong *spp)
if (bt->flags & BT_DUMPFILE_SEARCH)
return x86_64_get_dumpfile_stack_frame(bt, pcp, spp);
+ if (bt->flags & BT_SKIP_IDLE)
+ bt->flags &= ~BT_SKIP_IDLE;
+
if (pcp)
*pcp = x86_64_get_pc(bt);
if (spp)
@@ -4960,6 +4963,9 @@ x86_64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *rip, ulong *rsp)
estack = -1;
panic = FALSE;
+ if (bt_in->flags & BT_SKIP_IDLE)
+ bt_in->flags &= ~BT_SKIP_IDLE;
+
panic_task = tt->panic_task == bt->task ? TRUE : FALSE;
if (panic_task && bt->machdep) {
@@ -5098,6 +5104,8 @@ next_sysrq:
if (!panic_task && STREQ(sym, "crash_nmi_callback")) {
*rip = *up;
*rsp = bt->stackbase + ((char *)(up) - bt->stackbuf);
+ if ((bt->flags & BT_SKIP_IDLE) && is_idle_thread(bt->task))
+ bt_in->flags |= BT_SKIP_IDLE;
return;
}
--
2.30.2

View File

@ -1,74 +0,0 @@
From 9429b15851f184fbff187d9a751451c9ed8ae5c9 Mon Sep 17 00:00:00 2001
From: Hari Bathini <hbathini@linux.ibm.com>
Date: Mon, 4 Jul 2022 10:55:45 +0530
Subject: [PATCH 07/28] ppc64: print emergency stacks info with 'mach' command
Print top address of emergency stacks with 'mach' command.
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
ppc64.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/ppc64.c b/ppc64.c
index 03047a85955d..ad1d6e121e81 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -3161,6 +3161,44 @@ opalmsg(void)
fprintf(fp, "\n");
}
+static void ppc64_print_emergency_stack_info(void)
+{
+ struct machine_specific *ms = machdep->machspec;
+ char buf[32];
+ int i;
+
+ fprintf(fp, " EMERGENCY STACK: ");
+ if (ms->emergency_sp) {
+ fprintf(fp, "\n");
+ for (i = 0; i < kt->cpus; i++) {
+ sprintf(buf, "CPU %d", i);
+ fprintf(fp, "%19s: %lx\n", buf, ms->emergency_sp[i]);
+ }
+ } else
+ fprintf(fp, "(unused)\n");
+
+ fprintf(fp, "NMI EMERGENCY STACK: ");
+ if (ms->nmi_emergency_sp) {
+ fprintf(fp, "\n");
+ for (i = 0; i < kt->cpus; i++) {
+ sprintf(buf, "CPU %d", i);
+ fprintf(fp, "%19s: %lx\n", buf, ms->nmi_emergency_sp[i]);
+ }
+ } else
+ fprintf(fp, "(unused)\n");
+
+ fprintf(fp, " MC EMERGENCY STACK: ");
+ if (ms->mc_emergency_sp) {
+ fprintf(fp, "\n");
+ for (i = 0; i < kt->cpus; i++) {
+ sprintf(buf, "CPU %d", i);
+ fprintf(fp, "%19s: %lx\n", buf, ms->mc_emergency_sp[i]);
+ }
+ } else
+ fprintf(fp, "(unused)\n");
+ fprintf(fp, "\n");
+}
+
/*
* Machine dependent command.
*/
@@ -3241,6 +3279,8 @@ ppc64_display_machine_stats(void)
fprintf(fp, "%19s: %lx\n", buf, tt->softirq_ctx[c]);
}
}
+
+ ppc64_print_emergency_stack_info();
}
static const char *hook_files[] = {
--
2.37.1

View File

@ -1,96 +0,0 @@
From 0f162febebc4d11a165dd40cee00f3b0ba691a52 Mon Sep 17 00:00:00 2001
From: Qi Zheng <zhengqi.arch@bytedance.com>
Date: Tue, 24 May 2022 20:25:54 +0800
Subject: [PATCH 08/18] bt: arm64: add support for 'bt -n idle'
The '-n idle' option of bt command can help us filter the
stack of the idle process when debugging the dumpfiles
captured by kdump.
This patch supports this feature on ARM64.
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
arm64.c | 19 ++++++++++++++++---
help.c | 2 +-
kernel.c | 3 ++-
3 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/arm64.c b/arm64.c
index 65f6cdf69fa6..0f615cf52bef 100644
--- a/arm64.c
+++ b/arm64.c
@@ -3681,6 +3681,12 @@ arm64_get_dumpfile_stackframe(struct bt_info *bt, struct arm64_stackframe *frame
{
struct machine_specific *ms = machdep->machspec;
struct arm64_pt_regs *ptregs;
+ bool skip = false;
+
+ if (bt->flags & BT_SKIP_IDLE) {
+ skip = true;
+ bt->flags &= ~BT_SKIP_IDLE;
+ }
if (!ms->panic_task_regs ||
(!ms->panic_task_regs[bt->tc->processor].sp &&
@@ -3713,8 +3719,11 @@ try_kernel:
}
if (arm64_in_kdump_text(bt, frame) ||
- arm64_in_kdump_text_on_irq_stack(bt))
+ arm64_in_kdump_text_on_irq_stack(bt)) {
bt->flags |= BT_KDUMP_ADJUST;
+ if (skip && is_idle_thread(bt->task))
+ bt->flags |= BT_SKIP_IDLE;
+ }
return TRUE;
}
@@ -3738,10 +3747,14 @@ arm64_get_stack_frame(struct bt_info *bt, ulong *pcp, ulong *spp)
int ret;
struct arm64_stackframe stackframe = { 0 };
- if (DUMPFILE() && is_task_active(bt->task))
+ if (DUMPFILE() && is_task_active(bt->task)) {
ret = arm64_get_dumpfile_stackframe(bt, &stackframe);
- else
+ } else {
+ if (bt->flags & BT_SKIP_IDLE)
+ bt->flags &= ~BT_SKIP_IDLE;
+
ret = arm64_get_stackframe(bt, &stackframe);
+ }
if (!ret)
error(WARNING,
diff --git a/help.c b/help.c
index e1bbc5abe029..99214c1590fa 100644
--- a/help.c
+++ b/help.c
@@ -1915,7 +1915,7 @@ char *help_bt[] = {
" -a displays the stack traces of the active task on each CPU.",
" (only applicable to crash dumps)",
" -A same as -a, but also displays vector registers (S390X only).",
-" -n idle filter the stack of idle tasks (x86_64).",
+" -n idle filter the stack of idle tasks (x86_64, arm64).",
" (only applicable to crash dumps)",
" -p display the stack trace of the panic task only.",
" (only applicable to crash dumps)",
diff --git a/kernel.c b/kernel.c
index 411e9da1e54f..a521ef30cdb0 100644
--- a/kernel.c
+++ b/kernel.c
@@ -2673,7 +2673,8 @@ cmd_bt(void)
break;
case 'n':
- if (machine_type("X86_64") && STREQ(optarg, "idle"))
+ if ((machine_type("X86_64") || machine_type("ARM64")) &&
+ STREQ(optarg, "idle"))
bt->flags |= BT_SKIP_IDLE;
else
option_not_supported(c);
--
2.30.2

View File

@ -1,389 +0,0 @@
From 656f0b50866247a2fdb2d0c917f0a7a3f34c2e7d Mon Sep 17 00:00:00 2001
From: Hari Bathini <hbathini@linux.ibm.com>
Date: Mon, 4 Jul 2022 10:55:46 +0530
Subject: [PATCH 08/28] ppc64: use a variable for machdep->machspec
machdpep->machspec is referred to multiple times. The compiler would
likely optimize this but nonetheless, use a variable to optimize in
coding and also improve readability. No functional change.
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
ppc64.c | 224 ++++++++++++++++++++++++++++----------------------------
1 file changed, 111 insertions(+), 113 deletions(-)
diff --git a/ppc64.c b/ppc64.c
index ad1d6e121e81..4ea1f7c0c6f8 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -307,6 +307,8 @@ struct machine_specific book3e_machine_specific = {
void
ppc64_init(int when)
{
+ struct machine_specific *ms;
+
#if defined(__x86_64__)
if (ACTIVE())
error(FATAL, "compiled for the PPC64 architecture\n");
@@ -416,16 +418,16 @@ ppc64_init(int when)
break;
case POST_GDB:
- if (!(machdep->flags & BOOK3E)) {
- struct machine_specific *m = machdep->machspec;
+ ms = machdep->machspec;
+ if (!(machdep->flags & BOOK3E)) {
/*
* To determine if the kernel was running on OPAL based platform,
* use struct opal, which is populated with relevant values.
*/
if (symbol_exists("opal")) {
- get_symbol_data("opal", sizeof(struct ppc64_opal), &(m->opal));
- if (m->opal.base == SKIBOOT_BASE)
+ get_symbol_data("opal", sizeof(struct ppc64_opal), &(ms->opal));
+ if (ms->opal.base == SKIBOOT_BASE)
machdep->flags |= OPAL_FW;
}
@@ -453,18 +455,18 @@ ppc64_init(int when)
* _PAGE_WRITETHRU can be used to infer it.
*/
if (THIS_KERNEL_VERSION >= LINUX(3,14,0))
- m->_page_coherent = 0x0UL;
+ ms->_page_coherent = 0x0UL;
/*
* In kernel v4.5, _PAGE_PTE bit is introduced to
* distinguish PTEs from pointers.
*/
if (THIS_KERNEL_VERSION >= LINUX(4,5,0)) {
- m->_page_pte = 0x1UL;
- m->_page_present = 0x2UL;
- m->_page_user = 0x4UL;
- m->_page_rw = 0x8UL;
- m->_page_guarded = 0x10UL;
+ ms->_page_pte = 0x1UL;
+ ms->_page_present = 0x2UL;
+ ms->_page_user = 0x4UL;
+ ms->_page_rw = 0x8UL;
+ ms->_page_guarded = 0x10UL;
}
/*
@@ -474,8 +476,8 @@ ppc64_init(int when)
* Also, page table entries store physical addresses.
*/
if (THIS_KERNEL_VERSION >= LINUX(4,6,0)) {
- m->_page_pte = 0x1UL << 62;
- m->_page_present = 0x1UL << 63;
+ ms->_page_pte = 0x1UL << 62;
+ ms->_page_present = 0x1UL << 63;
machdep->flags |= PHYS_ENTRY_L4;
}
@@ -504,118 +506,117 @@ ppc64_init(int when)
machdep->ptrs_per_pgd = PTRS_PER_PGD;
} else {
/* 2.6.14 layout */
- struct machine_specific *m = machdep->machspec;
if (machdep->pagesize == 65536) {
/* 64K pagesize */
if (machdep->flags & RADIX_MMU) {
- m->l1_index_size = PTE_INDEX_SIZE_RADIX_64K;
- m->l2_index_size = PMD_INDEX_SIZE_RADIX_64K;
- m->l3_index_size = PUD_INDEX_SIZE_RADIX_64K;
- m->l4_index_size = PGD_INDEX_SIZE_RADIX_64K;
+ ms->l1_index_size = PTE_INDEX_SIZE_RADIX_64K;
+ ms->l2_index_size = PMD_INDEX_SIZE_RADIX_64K;
+ ms->l3_index_size = PUD_INDEX_SIZE_RADIX_64K;
+ ms->l4_index_size = PGD_INDEX_SIZE_RADIX_64K;
} else if (!(machdep->flags & BOOK3E) &&
(THIS_KERNEL_VERSION >= LINUX(4,6,0))) {
- m->l1_index_size = PTE_INDEX_SIZE_L4_64K_3_10;
+ ms->l1_index_size = PTE_INDEX_SIZE_L4_64K_3_10;
if (THIS_KERNEL_VERSION >= LINUX(4,12,0)) {
- m->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_12;
+ ms->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_12;
if (THIS_KERNEL_VERSION >= LINUX(4,17,0))
- m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_17;
+ ms->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_17;
else
- m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_12;
- m->l4_index_size = PGD_INDEX_SIZE_L4_64K_4_12;
+ ms->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_12;
+ ms->l4_index_size = PGD_INDEX_SIZE_L4_64K_4_12;
} else {
- m->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_6;
- m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_6;
- m->l4_index_size = PGD_INDEX_SIZE_L4_64K_3_10;
+ ms->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_6;
+ ms->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_6;
+ ms->l4_index_size = PGD_INDEX_SIZE_L4_64K_3_10;
}
} else if (THIS_KERNEL_VERSION >= LINUX(3,10,0)) {
- m->l1_index_size = PTE_INDEX_SIZE_L4_64K_3_10;
- m->l2_index_size = PMD_INDEX_SIZE_L4_64K_3_10;
- m->l3_index_size = PUD_INDEX_SIZE_L4_64K;
- m->l4_index_size = PGD_INDEX_SIZE_L4_64K_3_10;
+ ms->l1_index_size = PTE_INDEX_SIZE_L4_64K_3_10;
+ ms->l2_index_size = PMD_INDEX_SIZE_L4_64K_3_10;
+ ms->l3_index_size = PUD_INDEX_SIZE_L4_64K;
+ ms->l4_index_size = PGD_INDEX_SIZE_L4_64K_3_10;
} else {
- m->l1_index_size = PTE_INDEX_SIZE_L4_64K;
- m->l2_index_size = PMD_INDEX_SIZE_L4_64K;
- m->l3_index_size = PUD_INDEX_SIZE_L4_64K;
- m->l4_index_size = PGD_INDEX_SIZE_L4_64K;
+ ms->l1_index_size = PTE_INDEX_SIZE_L4_64K;
+ ms->l2_index_size = PMD_INDEX_SIZE_L4_64K;
+ ms->l3_index_size = PUD_INDEX_SIZE_L4_64K;
+ ms->l4_index_size = PGD_INDEX_SIZE_L4_64K;
}
if (!(machdep->flags & BOOK3E))
- m->pte_rpn_shift = symbol_exists("demote_segment_4k") ?
+ ms->pte_rpn_shift = symbol_exists("demote_segment_4k") ?
PTE_RPN_SHIFT_L4_64K_V2 : PTE_RPN_SHIFT_L4_64K_V1;
if (!(machdep->flags & BOOK3E) &&
(THIS_KERNEL_VERSION >= LINUX(4,6,0))) {
- m->pgd_masked_bits = PGD_MASKED_BITS_64K_4_6;
- m->pud_masked_bits = PUD_MASKED_BITS_64K_4_6;
- m->pmd_masked_bits = PMD_MASKED_BITS_64K_4_6;
+ ms->pgd_masked_bits = PGD_MASKED_BITS_64K_4_6;
+ ms->pud_masked_bits = PUD_MASKED_BITS_64K_4_6;
+ ms->pmd_masked_bits = PMD_MASKED_BITS_64K_4_6;
} else {
- m->pgd_masked_bits = PGD_MASKED_BITS_64K;
- m->pud_masked_bits = PUD_MASKED_BITS_64K;
+ ms->pgd_masked_bits = PGD_MASKED_BITS_64K;
+ ms->pud_masked_bits = PUD_MASKED_BITS_64K;
if ((machdep->flags & BOOK3E) &&
(THIS_KERNEL_VERSION >= LINUX(4,5,0)))
- m->pmd_masked_bits = PMD_MASKED_BITS_BOOK3E_64K_4_5;
+ ms->pmd_masked_bits = PMD_MASKED_BITS_BOOK3E_64K_4_5;
else if (THIS_KERNEL_VERSION >= LINUX(3,11,0))
- m->pmd_masked_bits = PMD_MASKED_BITS_64K_3_11;
+ ms->pmd_masked_bits = PMD_MASKED_BITS_64K_3_11;
else
- m->pmd_masked_bits = PMD_MASKED_BITS_64K;
+ ms->pmd_masked_bits = PMD_MASKED_BITS_64K;
}
} else {
/* 4K pagesize */
if (machdep->flags & RADIX_MMU) {
- m->l1_index_size = PTE_INDEX_SIZE_RADIX_4K;
- m->l2_index_size = PMD_INDEX_SIZE_RADIX_4K;
- m->l3_index_size = PUD_INDEX_SIZE_RADIX_4K;
- m->l4_index_size = PGD_INDEX_SIZE_RADIX_4K;
+ ms->l1_index_size = PTE_INDEX_SIZE_RADIX_4K;
+ ms->l2_index_size = PMD_INDEX_SIZE_RADIX_4K;
+ ms->l3_index_size = PUD_INDEX_SIZE_RADIX_4K;
+ ms->l4_index_size = PGD_INDEX_SIZE_RADIX_4K;
} else {
- m->l1_index_size = PTE_INDEX_SIZE_L4_4K;
- m->l2_index_size = PMD_INDEX_SIZE_L4_4K;
+ ms->l1_index_size = PTE_INDEX_SIZE_L4_4K;
+ ms->l2_index_size = PMD_INDEX_SIZE_L4_4K;
if (THIS_KERNEL_VERSION >= LINUX(3,7,0))
- m->l3_index_size = PUD_INDEX_SIZE_L4_4K_3_7;
+ ms->l3_index_size = PUD_INDEX_SIZE_L4_4K_3_7;
else
- m->l3_index_size = PUD_INDEX_SIZE_L4_4K;
- m->l4_index_size = PGD_INDEX_SIZE_L4_4K;
+ ms->l3_index_size = PUD_INDEX_SIZE_L4_4K;
+ ms->l4_index_size = PGD_INDEX_SIZE_L4_4K;
if (machdep->flags & BOOK3E)
- m->pte_rpn_shift = PTE_RPN_SHIFT_L4_BOOK3E_4K;
+ ms->pte_rpn_shift = PTE_RPN_SHIFT_L4_BOOK3E_4K;
else
- m->pte_rpn_shift = THIS_KERNEL_VERSION >= LINUX(4,5,0) ?
+ ms->pte_rpn_shift = THIS_KERNEL_VERSION >= LINUX(4,5,0) ?
PTE_RPN_SHIFT_L4_4K_4_5 : PTE_RPN_SHIFT_L4_4K;
}
- m->pgd_masked_bits = PGD_MASKED_BITS_4K;
- m->pud_masked_bits = PUD_MASKED_BITS_4K;
- m->pmd_masked_bits = PMD_MASKED_BITS_4K;
+ ms->pgd_masked_bits = PGD_MASKED_BITS_4K;
+ ms->pud_masked_bits = PUD_MASKED_BITS_4K;
+ ms->pmd_masked_bits = PMD_MASKED_BITS_4K;
}
- m->pte_rpn_mask = PTE_RPN_MASK_DEFAULT;
+ ms->pte_rpn_mask = PTE_RPN_MASK_DEFAULT;
if (!(machdep->flags & BOOK3E)) {
if (THIS_KERNEL_VERSION >= LINUX(4,6,0)) {
- m->pte_rpn_mask = PTE_RPN_MASK_L4_4_6;
- m->pte_rpn_shift = PTE_RPN_SHIFT_L4_4_6;
+ ms->pte_rpn_mask = PTE_RPN_MASK_L4_4_6;
+ ms->pte_rpn_shift = PTE_RPN_SHIFT_L4_4_6;
}
if (THIS_KERNEL_VERSION >= LINUX(4,7,0)) {
- m->pgd_masked_bits = PGD_MASKED_BITS_4_7;
- m->pud_masked_bits = PUD_MASKED_BITS_4_7;
- m->pmd_masked_bits = PMD_MASKED_BITS_4_7;
+ ms->pgd_masked_bits = PGD_MASKED_BITS_4_7;
+ ms->pud_masked_bits = PUD_MASKED_BITS_4_7;
+ ms->pmd_masked_bits = PMD_MASKED_BITS_4_7;
}
}
/* Compute ptrs per each level */
- m->l1_shift = machdep->pageshift;
- m->ptrs_per_l1 = (1 << m->l1_index_size);
- m->ptrs_per_l2 = (1 << m->l2_index_size);
- m->ptrs_per_l3 = (1 << m->l3_index_size);
- m->ptrs_per_l4 = (1 << m->l4_index_size);
- machdep->ptrs_per_pgd = m->ptrs_per_l4;
+ ms->l1_shift = machdep->pageshift;
+ ms->ptrs_per_l1 = (1 << ms->l1_index_size);
+ ms->ptrs_per_l2 = (1 << ms->l2_index_size);
+ ms->ptrs_per_l3 = (1 << ms->l3_index_size);
+ ms->ptrs_per_l4 = (1 << ms->l4_index_size);
+ machdep->ptrs_per_pgd = ms->ptrs_per_l4;
/* Compute shifts */
- m->l2_shift = m->l1_shift + m->l1_index_size;
- m->l3_shift = m->l2_shift + m->l2_index_size;
- m->l4_shift = m->l3_shift + m->l3_index_size;
+ ms->l2_shift = ms->l1_shift + ms->l1_index_size;
+ ms->l3_shift = ms->l2_shift + ms->l2_index_size;
+ ms->l4_shift = ms->l3_shift + ms->l3_index_size;
}
if (machdep->flags & VMEMMAP)
@@ -681,19 +682,15 @@ ppc64_init(int when)
*/
offset = MEMBER_OFFSET("paca_struct", "xHrdIntStack");
paca_sym = symbol_value("paca");
- if (!(machdep->machspec->hwintrstack =
- (ulong *)calloc(NR_CPUS, sizeof(ulong))))
+ if (!(ms->hwintrstack = (ulong *)calloc(NR_CPUS, sizeof(ulong))))
error(FATAL, "cannot malloc hwintrstack space.");
for (cpu = 0; cpu < kt->cpus; cpu++) {
- readmem(paca_sym + (paca_size * cpu) + offset,
- KVADDR,
- &machdep->machspec->hwintrstack[cpu],
- sizeof(ulong), "PPC64 HW_intr_stack",
- FAULT_ON_ERROR);
+ readmem(paca_sym + (paca_size * cpu) + offset, KVADDR,
+ &ms->hwintrstack[cpu], sizeof(ulong),
+ "PPC64 HW_intr_stack", FAULT_ON_ERROR);
}
- machdep->machspec->hwstacksize = 8 * machdep->pagesize;
- if ((machdep->machspec->hwstackbuf = (char *)
- malloc(machdep->machspec->hwstacksize)) == NULL)
+ ms->hwstacksize = 8 * machdep->pagesize;
+ if ((ms->hwstackbuf = (char *)malloc(ms->hwstacksize)) == NULL)
error(FATAL, "cannot malloc hwirqstack buffer space.");
}
@@ -756,6 +753,7 @@ ppc64_get_stacktop(ulong task)
void
ppc64_dump_machdep_table(ulong arg)
{
+ struct machine_specific *ms = machdep->machspec;
int i, c, others;
others = 0;
@@ -844,57 +842,57 @@ ppc64_dump_machdep_table(ulong arg)
i, machdep->cmdline_args[i] ?
machdep->cmdline_args[i] : "(unused)");
}
- fprintf(fp, " machspec: %lx\n", (ulong)machdep->machspec);
+ fprintf(fp, " machspec: %lx\n", (ulong)ms);
fprintf(fp, " is_kvaddr: %s\n",
- machdep->machspec->is_kvaddr == book3e_is_kvaddr ?
+ ms->is_kvaddr == book3e_is_kvaddr ?
"book3e_is_kvaddr()" : "generic_is_kvaddr()");
fprintf(fp, " is_vmaddr: %s\n",
- machdep->machspec->is_vmaddr == book3e_is_vmaddr ?
+ ms->is_vmaddr == book3e_is_vmaddr ?
"book3e_is_vmaddr()" : "ppc64_is_vmaddr()");
- if (machdep->machspec->hwintrstack) {
+ if (ms->hwintrstack) {
fprintf(fp, " hwintrstack[%d]: ", NR_CPUS);
for (c = 0; c < NR_CPUS; c++) {
fprintf(fp, "%s%016lx ",
((c % 4) == 0) ? "\n " : "",
- machdep->machspec->hwintrstack[c]);
+ ms->hwintrstack[c]);
}
} else
fprintf(fp, " hwintrstack: (unused)");
fprintf(fp, "\n");
- fprintf(fp, " hwstackbuf: %lx\n", (ulong)machdep->machspec->hwstackbuf);
- fprintf(fp, " hwstacksize: %d\n", machdep->machspec->hwstacksize);
- fprintf(fp, " l4_index_size: %d\n", machdep->machspec->l4_index_size);
- fprintf(fp, " l3_index_size: %d\n", machdep->machspec->l3_index_size);
- fprintf(fp, " l2_index_size: %d\n", machdep->machspec->l2_index_size);
- fprintf(fp, " l1_index_size: %d\n", machdep->machspec->l1_index_size);
- fprintf(fp, " ptrs_per_l4: %d\n", machdep->machspec->ptrs_per_l4);
- fprintf(fp, " ptrs_per_l3: %d\n", machdep->machspec->ptrs_per_l3);
- fprintf(fp, " ptrs_per_l2: %d\n", machdep->machspec->ptrs_per_l2);
- fprintf(fp, " ptrs_per_l1: %d\n", machdep->machspec->ptrs_per_l1);
- fprintf(fp, " l4_shift: %d\n", machdep->machspec->l4_shift);
- fprintf(fp, " l3_shift: %d\n", machdep->machspec->l3_shift);
- fprintf(fp, " l2_shift: %d\n", machdep->machspec->l2_shift);
- fprintf(fp, " l1_shift: %d\n", machdep->machspec->l1_shift);
- fprintf(fp, " pte_rpn_mask: %lx\n", machdep->machspec->pte_rpn_mask);
- fprintf(fp, " pte_rpn_shift: %d\n", machdep->machspec->pte_rpn_shift);
- fprintf(fp, " pgd_masked_bits: %lx\n", machdep->machspec->pgd_masked_bits);
- fprintf(fp, " pud_masked_bits: %lx\n", machdep->machspec->pud_masked_bits);
- fprintf(fp, " pmd_masked_bits: %lx\n", machdep->machspec->pmd_masked_bits);
+ fprintf(fp, " hwstackbuf: %lx\n", (ulong)ms->hwstackbuf);
+ fprintf(fp, " hwstacksize: %d\n", ms->hwstacksize);
+ fprintf(fp, " l4_index_size: %d\n", ms->l4_index_size);
+ fprintf(fp, " l3_index_size: %d\n", ms->l3_index_size);
+ fprintf(fp, " l2_index_size: %d\n", ms->l2_index_size);
+ fprintf(fp, " l1_index_size: %d\n", ms->l1_index_size);
+ fprintf(fp, " ptrs_per_l4: %d\n", ms->ptrs_per_l4);
+ fprintf(fp, " ptrs_per_l3: %d\n", ms->ptrs_per_l3);
+ fprintf(fp, " ptrs_per_l2: %d\n", ms->ptrs_per_l2);
+ fprintf(fp, " ptrs_per_l1: %d\n", ms->ptrs_per_l1);
+ fprintf(fp, " l4_shift: %d\n", ms->l4_shift);
+ fprintf(fp, " l3_shift: %d\n", ms->l3_shift);
+ fprintf(fp, " l2_shift: %d\n", ms->l2_shift);
+ fprintf(fp, " l1_shift: %d\n", ms->l1_shift);
+ fprintf(fp, " pte_rpn_mask: %lx\n", ms->pte_rpn_mask);
+ fprintf(fp, " pte_rpn_shift: %d\n", ms->pte_rpn_shift);
+ fprintf(fp, " pgd_masked_bits: %lx\n", ms->pgd_masked_bits);
+ fprintf(fp, " pud_masked_bits: %lx\n", ms->pud_masked_bits);
+ fprintf(fp, " pmd_masked_bits: %lx\n", ms->pmd_masked_bits);
fprintf(fp, " vmemmap_base: ");
- if (machdep->machspec->vmemmap_base)
- fprintf(fp, "%lx\n", machdep->machspec->vmemmap_base);
+ if (ms->vmemmap_base)
+ fprintf(fp, "%lx\n", ms->vmemmap_base);
else
fprintf(fp, "(unused)\n");
- if (machdep->machspec->vmemmap_cnt) {
+ if (ms->vmemmap_cnt) {
fprintf(fp, " vmemmap_cnt: %d\n",
- machdep->machspec->vmemmap_cnt);
+ ms->vmemmap_cnt);
fprintf(fp, " vmemmap_psize: %d\n",
- machdep->machspec->vmemmap_psize);
- for (i = 0; i < machdep->machspec->vmemmap_cnt; i++) {
+ ms->vmemmap_psize);
+ for (i = 0; i < ms->vmemmap_cnt; i++) {
fprintf(fp,
" vmemmap_list[%d]: virt: %lx phys: %lx\n", i,
- machdep->machspec->vmemmap_list[i].virt,
- machdep->machspec->vmemmap_list[i].phys);
+ ms->vmemmap_list[i].virt,
+ ms->vmemmap_list[i].phys);
}
} else {
fprintf(fp, " vmemmap_cnt: (unused)\n");
--
2.37.1

View File

@ -0,0 +1,70 @@
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,39 +0,0 @@
From b077c3569788f5eb5ddf85bf41026b452d253a90 Mon Sep 17 00:00:00 2001
From: Qianli Zhao <qianli.zhao@horizon.ai>
Date: Mon, 4 Jul 2022 16:40:01 +0800
Subject: [PATCH 09/28] arm64: Fix for st->_stext_vmlinux not initialized when
set VA_BITS_ACTUAL
Setting st->_stext_vmlinux to UNINITIALIZED to search for "_stext"
from the vmlinux. In the scenario where kaslr is disabled and
without vmcoreinfo, crash will get the wrong MODULES/VMALLOC ranges
and cause a failure in parsing a raw RAM dumpfile.
Signed-off-by: Qianli Zhao <qianli.zhao@horizon.ai>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
arm64.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arm64.c b/arm64.c
index 0f615cf52bef..b6b7aa11f4fe 100644
--- a/arm64.c
+++ b/arm64.c
@@ -149,6 +149,14 @@ arm64_init(int when)
ms = machdep->machspec;
+ /*
+ * The st->_stext_vmlinux is needed in arm64_init(PRE_GDB) when a
+ * dumpfile does not have vmcoreinfo and we use -m vabits_actual
+ * option, e.g. a raw RAM dumpfile.
+ */
+ if (ms->VA_BITS_ACTUAL)
+ st->_stext_vmlinux = UNINITIALIZED;
+
if (!ms->kimage_voffset && STREQ(pc->live_memsrc, "/dev/crash"))
ioctl(pc->mfd, DEV_CRASH_ARCH_DATA, &ms->kimage_voffset);
--
2.37.1

View File

@ -0,0 +1,323 @@
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,392 +0,0 @@
From 7095c8fd029e3a33117e3b67de73f504686ebfe2 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Thu, 2 Jun 2022 20:12:55 +0800
Subject: [PATCH 10/18] Enhance "dev -d|-D" options to support blk-mq sbitmap
Since Linux 5.16-rc1, which kernel commit 9a14d6ce4135 ("block: remove
debugfs blk_mq_ctx dispatched/merged/completed attributes") removed the
members from struct blk_mq_ctx, crash has not displayed disk I/O statistics
for multiqueue (blk-mq) devices.
Let's parse the sbitmap in blk-mq layer to support it.
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
defs.h | 11 +++
dev.c | 244 +++++++++++++++++++++++++++++++++++++++++++++---------
symbols.c | 22 +++++
3 files changed, 238 insertions(+), 39 deletions(-)
diff --git a/defs.h b/defs.h
index c8444b4e54eb..2681586a33dc 100644
--- a/defs.h
+++ b/defs.h
@@ -2170,6 +2170,16 @@ struct offset_table { /* stash of commonly-used offsets */
long sbq_wait_state_wait;
long sbitmap_alloc_hint;
long sbitmap_round_robin;
+ long request_cmd_flags;
+ long request_q;
+ long request_state;
+ long request_queue_queue_hw_ctx;
+ long request_queue_nr_hw_queues;
+ long blk_mq_hw_ctx_tags;
+ long blk_mq_tags_bitmap_tags;
+ long blk_mq_tags_breserved_tags;
+ long blk_mq_tags_nr_reserved_tags;
+ long blk_mq_tags_rqs;
};
struct size_table { /* stash of commonly-used sizes */
@@ -2339,6 +2349,7 @@ struct size_table { /* stash of commonly-used sizes */
long sbitmap;
long sbitmap_queue;
long sbq_wait_state;
+ long blk_mq_tags;
};
struct array_table {
diff --git a/dev.c b/dev.c
index a493e51ac95c..4be4c96df8b0 100644
--- a/dev.c
+++ b/dev.c
@@ -4238,19 +4238,176 @@ get_one_mctx_diskio(unsigned long mctx, struct diskio *io)
io->write = (dispatch[1] - comp[1]);
}
+typedef bool (busy_tag_iter_fn)(ulong rq, void *data);
+
+struct mq_inflight {
+ ulong q;
+ struct diskio *dio;
+};
+
+struct bt_iter_data {
+ ulong tags;
+ uint reserved;
+ uint nr_reserved_tags;
+ busy_tag_iter_fn *fn;
+ void *data;
+};
+
+/*
+ * See the include/linux/blk_types.h and include/linux/blk-mq.h
+ */
+#define MQ_RQ_IN_FLIGHT 1
+#define REQ_OP_BITS 8
+#define REQ_OP_MASK ((1 << REQ_OP_BITS) - 1)
+
+static uint op_is_write(uint op)
+{
+ return (op & REQ_OP_MASK) & 1;
+}
+
+static bool mq_check_inflight(ulong rq, void *data)
+{
+ uint cmd_flags = 0, state = 0;
+ ulong addr = 0, queue = 0;
+ struct mq_inflight *mi = data;
+
+ if (!IS_KVADDR(rq))
+ return TRUE;
+
+ addr = rq + OFFSET(request_q);
+ if (!readmem(addr, KVADDR, &queue, sizeof(ulong), "request.q", RETURN_ON_ERROR))
+ return FALSE;
+
+ addr = rq + OFFSET(request_cmd_flags);
+ if (!readmem(addr, KVADDR, &cmd_flags, sizeof(uint), "request.cmd_flags", RETURN_ON_ERROR))
+ return FALSE;
+
+ addr = rq + OFFSET(request_state);
+ if (!readmem(addr, KVADDR, &state, sizeof(uint), "request.state", RETURN_ON_ERROR))
+ return FALSE;
+
+ if (queue == mi->q && state == MQ_RQ_IN_FLIGHT) {
+ if (op_is_write(cmd_flags))
+ mi->dio->write++;
+ else
+ mi->dio->read++;
+ }
+
+ return TRUE;
+}
+
+static bool bt_iter(uint bitnr, void *data)
+{
+ ulong addr = 0, rqs_addr = 0, rq = 0;
+ struct bt_iter_data *iter_data = data;
+ ulong tag = iter_data->tags;
+
+ if (!iter_data->reserved)
+ bitnr += iter_data->nr_reserved_tags;
+
+ /* rqs */
+ addr = tag + OFFSET(blk_mq_tags_rqs);
+ if (!readmem(addr, KVADDR, &rqs_addr, sizeof(void *), "blk_mq_tags.rqs", RETURN_ON_ERROR))
+ return FALSE;
+
+ addr = rqs_addr + bitnr * sizeof(ulong); /* rqs[bitnr] */
+ if (!readmem(addr, KVADDR, &rq, sizeof(ulong), "blk_mq_tags.rqs[]", RETURN_ON_ERROR))
+ return FALSE;
+
+ return iter_data->fn(rq, iter_data->data);
+}
+
+static void bt_for_each(ulong q, ulong tags, ulong sbq, uint reserved, uint nr_resvd_tags, struct diskio *dio)
+{
+ struct sbitmap_context sc = {0};
+ struct mq_inflight mi = {
+ .q = q,
+ .dio = dio,
+ };
+ struct bt_iter_data iter_data = {
+ .tags = tags,
+ .reserved = reserved,
+ .nr_reserved_tags = nr_resvd_tags,
+ .fn = mq_check_inflight,
+ .data = &mi,
+ };
+
+ sbitmap_context_load(sbq + OFFSET(sbitmap_queue_sb), &sc);
+ sbitmap_for_each_set(&sc, bt_iter, &iter_data);
+}
+
+static void queue_for_each_hw_ctx(ulong q, ulong *hctx, uint cnt, struct diskio *dio)
+{
+ uint i;
+
+ for (i = 0; i < cnt; i++) {
+ ulong addr = 0, tags = 0;
+ uint nr_reserved_tags = 0;
+
+ /* Tags owned by the block driver */
+ addr = hctx[i] + OFFSET(blk_mq_hw_ctx_tags);
+ if (!readmem(addr, KVADDR, &tags, sizeof(ulong),
+ "blk_mq_hw_ctx.tags", RETURN_ON_ERROR))
+ break;
+
+ addr = tags + OFFSET(blk_mq_tags_nr_reserved_tags);
+ if (!readmem(addr, KVADDR, &nr_reserved_tags, sizeof(uint),
+ "blk_mq_tags_nr_reserved_tags", RETURN_ON_ERROR))
+ break;
+
+ if (nr_reserved_tags) {
+ addr = tags + OFFSET(blk_mq_tags_breserved_tags);
+ bt_for_each(q, tags, addr, 1, nr_reserved_tags, dio);
+ }
+ addr = tags + OFFSET(blk_mq_tags_bitmap_tags);
+ bt_for_each(q, tags, addr, 0, nr_reserved_tags, dio);
+ }
+}
+
+static void get_mq_diskio_from_hw_queues(ulong q, struct diskio *dio)
+{
+ uint cnt = 0;
+ ulong addr = 0, hctx_addr = 0;
+ ulong *hctx_array = NULL;
+
+ addr = q + OFFSET(request_queue_nr_hw_queues);
+ readmem(addr, KVADDR, &cnt, sizeof(uint),
+ "request_queue.nr_hw_queues", FAULT_ON_ERROR);
+
+ addr = q + OFFSET(request_queue_queue_hw_ctx);
+ readmem(addr, KVADDR, &hctx_addr, sizeof(void *),
+ "request_queue.queue_hw_ctx", FAULT_ON_ERROR);
+
+ hctx_array = (ulong *)GETBUF(sizeof(void *) * cnt);
+ if (!hctx_array)
+ error(FATAL, "fail to get memory for the hctx_array\n");
+
+ if (!readmem(hctx_addr, KVADDR, hctx_array, sizeof(void *) * cnt,
+ "request_queue.queue_hw_ctx[]", RETURN_ON_ERROR)) {
+ FREEBUF(hctx_array);
+ return;
+ }
+
+ queue_for_each_hw_ctx(q, hctx_array, cnt, dio);
+
+ FREEBUF(hctx_array);
+}
+
static void
get_mq_diskio(unsigned long q, unsigned long *mq_count)
{
int cpu;
unsigned long queue_ctx;
unsigned long mctx_addr;
- struct diskio tmp;
+ struct diskio tmp = {0};
if (INVALID_MEMBER(blk_mq_ctx_rq_dispatched) ||
- INVALID_MEMBER(blk_mq_ctx_rq_completed))
+ INVALID_MEMBER(blk_mq_ctx_rq_completed)) {
+ get_mq_diskio_from_hw_queues(q, &tmp);
+ mq_count[0] = tmp.read;
+ mq_count[1] = tmp.write;
return;
-
- memset(&tmp, 0x00, sizeof(struct diskio));
+ }
readmem(q + OFFSET(request_queue_queue_ctx), KVADDR, &queue_ctx,
sizeof(ulong), "request_queue.queue_ctx",
@@ -4479,41 +4636,24 @@ display_one_diskio(struct iter *i, unsigned long gendisk, ulong flags)
&& (io.read + io.write == 0))
return;
- if (use_mq_interface(queue_addr) &&
- (INVALID_MEMBER(blk_mq_ctx_rq_dispatched) ||
- INVALID_MEMBER(blk_mq_ctx_rq_completed)))
- fprintf(fp, "%s%s%s %s%s%s%s %s%s%s",
- mkstring(buf0, 5, RJUST|INT_DEC, (char *)(unsigned long)major),
- space(MINSPACE),
- mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX, (char *)gendisk),
- space(MINSPACE),
- mkstring(buf2, 10, LJUST, disk_name),
- space(MINSPACE),
- mkstring(buf3, VADDR_PRLEN <= 11 ? 11 : VADDR_PRLEN,
- LJUST|LONG_HEX, (char *)queue_addr),
- space(MINSPACE),
- mkstring(buf4, 17, RJUST, "(not supported)"),
- space(MINSPACE));
-
- else
- fprintf(fp, "%s%s%s %s%s%s%s %s%5d%s%s%s%s%s",
- mkstring(buf0, 5, RJUST|INT_DEC, (char *)(unsigned long)major),
- space(MINSPACE),
- mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX, (char *)gendisk),
- space(MINSPACE),
- mkstring(buf2, 10, LJUST, disk_name),
- space(MINSPACE),
- mkstring(buf3, VADDR_PRLEN <= 11 ? 11 : VADDR_PRLEN,
- LJUST|LONG_HEX, (char *)queue_addr),
- space(MINSPACE),
- io.read + io.write,
- space(MINSPACE),
- mkstring(buf4, 5, RJUST|INT_DEC,
- (char *)(unsigned long)io.read),
- space(MINSPACE),
- mkstring(buf5, 5, RJUST|INT_DEC,
- (char *)(unsigned long)io.write),
- space(MINSPACE));
+ fprintf(fp, "%s%s%s %s%s%s%s %s%5d%s%s%s%s%s",
+ mkstring(buf0, 5, RJUST|INT_DEC, (char *)(unsigned long)major),
+ space(MINSPACE),
+ mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX, (char *)gendisk),
+ space(MINSPACE),
+ mkstring(buf2, 10, LJUST, disk_name),
+ space(MINSPACE),
+ mkstring(buf3, VADDR_PRLEN <= 11 ? 11 : VADDR_PRLEN,
+ LJUST|LONG_HEX, (char *)queue_addr),
+ space(MINSPACE),
+ io.read + io.write,
+ space(MINSPACE),
+ mkstring(buf4, 5, RJUST|INT_DEC,
+ (char *)(unsigned long)io.read),
+ space(MINSPACE),
+ mkstring(buf5, 5, RJUST|INT_DEC,
+ (char *)(unsigned long)io.write),
+ space(MINSPACE));
if (VALID_MEMBER(request_queue_in_flight)) {
if (!use_mq_interface(queue_addr)) {
@@ -4597,6 +4737,9 @@ void diskio_init(void)
MEMBER_OFFSET_INIT(kobject_entry, "kobject", "entry");
MEMBER_OFFSET_INIT(kset_list, "kset", "list");
MEMBER_OFFSET_INIT(request_list_count, "request_list", "count");
+ MEMBER_OFFSET_INIT(request_cmd_flags, "request", "cmd_flags");
+ MEMBER_OFFSET_INIT(request_q, "request", "q");
+ MEMBER_OFFSET_INIT(request_state, "request", "state");
MEMBER_OFFSET_INIT(request_queue_in_flight, "request_queue",
"in_flight");
if (MEMBER_EXISTS("request_queue", "rq"))
@@ -4608,10 +4751,33 @@ void diskio_init(void)
"mq_ops");
ANON_MEMBER_OFFSET_INIT(request_queue_queue_ctx,
"request_queue", "queue_ctx");
+ MEMBER_OFFSET_INIT(request_queue_queue_hw_ctx,
+ "request_queue", "queue_hw_ctx");
+ MEMBER_OFFSET_INIT(request_queue_nr_hw_queues,
+ "request_queue", "nr_hw_queues");
MEMBER_OFFSET_INIT(blk_mq_ctx_rq_dispatched, "blk_mq_ctx",
"rq_dispatched");
MEMBER_OFFSET_INIT(blk_mq_ctx_rq_completed, "blk_mq_ctx",
"rq_completed");
+ MEMBER_OFFSET_INIT(blk_mq_hw_ctx_tags, "blk_mq_hw_ctx", "tags");
+ MEMBER_OFFSET_INIT(blk_mq_tags_bitmap_tags, "blk_mq_tags",
+ "bitmap_tags");
+ MEMBER_OFFSET_INIT(blk_mq_tags_breserved_tags, "blk_mq_tags",
+ "breserved_tags");
+ MEMBER_OFFSET_INIT(blk_mq_tags_nr_reserved_tags, "blk_mq_tags",
+ "nr_reserved_tags");
+ MEMBER_OFFSET_INIT(blk_mq_tags_rqs, "blk_mq_tags", "rqs");
+ STRUCT_SIZE_INIT(blk_mq_tags, "blk_mq_tags");
+ STRUCT_SIZE_INIT(sbitmap, "sbitmap");
+ STRUCT_SIZE_INIT(sbitmap_word, "sbitmap_word");
+ MEMBER_OFFSET_INIT(sbitmap_word_word, "sbitmap_word", "word");
+ MEMBER_OFFSET_INIT(sbitmap_word_cleared, "sbitmap_word", "cleared");
+ MEMBER_OFFSET_INIT(sbitmap_depth, "sbitmap", "depth");
+ MEMBER_OFFSET_INIT(sbitmap_shift, "sbitmap", "shift");
+ MEMBER_OFFSET_INIT(sbitmap_map_nr, "sbitmap", "map_nr");
+ MEMBER_OFFSET_INIT(sbitmap_map, "sbitmap", "map");
+ MEMBER_OFFSET_INIT(sbitmap_queue_sb, "sbitmap_queue", "sb");
+
}
MEMBER_OFFSET_INIT(subsys_private_klist_devices, "subsys_private",
"klist_devices");
diff --git a/symbols.c b/symbols.c
index 5d12a021c769..c1f09556d710 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10385,6 +10385,12 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(kset_list));
fprintf(fp, " request_list_count: %ld\n",
OFFSET(request_list_count));
+ fprintf(fp, " request_cmd_flags: %ld\n",
+ OFFSET(request_cmd_flags));
+ fprintf(fp, " request_q: %ld\n",
+ OFFSET(request_q));
+ fprintf(fp, " request_state: %ld\n",
+ OFFSET(request_state));
fprintf(fp, " request_queue_in_flight: %ld\n",
OFFSET(request_queue_in_flight));
fprintf(fp, " request_queue_rq: %ld\n",
@@ -10393,10 +10399,25 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(request_queue_mq_ops));
fprintf(fp, " request_queue_queue_ctx: %ld\n",
OFFSET(request_queue_queue_ctx));
+ fprintf(fp, " request_queue_queue_hw_ctx: %ld\n",
+ OFFSET(request_queue_queue_hw_ctx));
+ fprintf(fp, " request_queue_nr_hw_queues: %ld\n",
+ OFFSET(request_queue_nr_hw_queues));
fprintf(fp, " blk_mq_ctx_rq_dispatched: %ld\n",
OFFSET(blk_mq_ctx_rq_dispatched));
fprintf(fp, " blk_mq_ctx_rq_completed: %ld\n",
OFFSET(blk_mq_ctx_rq_completed));
+ fprintf(fp, " blk_mq_hw_ctx_tags: %ld\n",
+ OFFSET(blk_mq_hw_ctx_tags));
+ fprintf(fp, " blk_mq_tags_bitmap_tags: %ld\n",
+ OFFSET(blk_mq_tags_bitmap_tags));
+ fprintf(fp, " blk_mq_tags_breserved_tags: %ld\n",
+ OFFSET(blk_mq_tags_breserved_tags));
+ fprintf(fp, " blk_mq_tags_nr_reserved_tags: %ld\n",
+ OFFSET(blk_mq_tags_nr_reserved_tags));
+ fprintf(fp, " blk_mq_tags_rqs: %ld\n",
+ OFFSET(blk_mq_tags_rqs));
+
fprintf(fp, " subsys_private_klist_devices: %ld\n",
OFFSET(subsys_private_klist_devices));
fprintf(fp, " subsystem_kset: %ld\n",
@@ -11003,6 +11024,7 @@ dump_offset_table(char *spec, ulong makestruct)
fprintf(fp, " sbitmap: %ld\n", SIZE(sbitmap));
fprintf(fp, " sbitmap_queue: %ld\n", SIZE(sbitmap_queue));
fprintf(fp, " sbq_wait_state: %ld\n", SIZE(sbq_wait_state));
+ fprintf(fp, " blk_mq_tags: %ld\n", SIZE(blk_mq_tags));
fprintf(fp, "\n array_table:\n");
/*
--
2.30.2

View File

@ -1,53 +0,0 @@
From 6132fe21e0d5f2951c860f8850aeaacf1588dfb0 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Fri, 22 Jul 2022 13:44:50 +0900
Subject: [PATCH 10/28] Fix gcc-11 compiler warnings on filesys.c
Without the patch, the following gcc-11 compiler warnings are emitted
for filesys.c:
filesys.c: In function 'mount_point':
filesys.c:718:17: warning: 'pclose' called on pointer returned from a mismatched allocation function [-Wmismatched-dealloc]
718 | pclose(mp);
| ^~~~~~~~~~
filesys.c:709:27: note: returned from 'fopen'
709 | if ((mp = fopen(mntfile, "r")) == NULL)
| ^~~~~~~~~~~~~~~~~~~
filesys.c:738:17: warning: 'pclose' called on pointer returned from a mismatched allocation function [-Wmismatched-dealloc]
738 | pclose(mp);
| ^~~~~~~~~~
filesys.c:723:27: note: returned from 'fopen'
723 | if ((mp = fopen(mntfile, "r")) == NULL)
| ^~~~~~~~~~~~~~~~~~~
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
filesys.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/filesys.c b/filesys.c
index 43cbe826fc79..a863f04eb250 100644
--- a/filesys.c
+++ b/filesys.c
@@ -715,7 +715,7 @@ mount_point(char *name)
continue;
found++;
}
- pclose(mp);
+ fclose(mp);
if (!(mount_points = (char **)malloc(sizeof(char *) * found)))
return FALSE;
@@ -735,7 +735,7 @@ mount_point(char *name)
mount_points_gathered++, i++;
}
}
- pclose(mp);
+ fclose(mp);
if (CRASHDEBUG(2))
for (i = 0; i < mount_points_gathered; i++)
--
2.37.1

View File

@ -0,0 +1,160 @@
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,121 +0,0 @@
From 68ce0b9a35d77d767872dd1a729c50e4695a30a8 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Thu, 2 Jun 2022 20:12:56 +0800
Subject: [PATCH 11/18] Fix for "dev -d|-D" options to support blk-mq change on
Linux v5.18-rc1
Kernel commit 4e5cc99e1e48 ("blk-mq: manage hctx map via xarray") removed
the "queue_hw_ctx" member from struct request_queue at Linux v5.18-rc1,
and replaced it with a struct xarray "hctx_table". Without the patch, the
"dev -d|-D" options will print an error:
crash> dev -d
MAJOR GENDISK NAME REQUEST_QUEUE TOTAL READ WRITE
dev: invalid structure member offset: request_queue_queue_hw_ctx
With the patch:
crash> dev -d
MAJOR GENDISK NAME REQUEST_QUEUE TOTAL READ WRITE
8 ffff8e99d0a1ae00 sda ffff8e9c14c59980 10 6 4
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 1 +
dev.c | 42 +++++++++++++++++++++++++++++++++---------
symbols.c | 2 ++
3 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/defs.h b/defs.h
index 2681586a33dc..7d3b73422f48 100644
--- a/defs.h
+++ b/defs.h
@@ -2180,6 +2180,7 @@ struct offset_table { /* stash of commonly-used offsets */
long blk_mq_tags_breserved_tags;
long blk_mq_tags_nr_reserved_tags;
long blk_mq_tags_rqs;
+ long request_queue_hctx_table;
};
struct size_table { /* stash of commonly-used sizes */
diff --git a/dev.c b/dev.c
index 4be4c96df8b0..0172c83ffaea 100644
--- a/dev.c
+++ b/dev.c
@@ -4369,20 +4369,42 @@ static void get_mq_diskio_from_hw_queues(ulong q, struct diskio *dio)
uint cnt = 0;
ulong addr = 0, hctx_addr = 0;
ulong *hctx_array = NULL;
+ struct list_pair *lp = NULL;
+
+ if (VALID_MEMBER(request_queue_hctx_table)) {
+ addr = q + OFFSET(request_queue_hctx_table);
+ cnt = do_xarray(addr, XARRAY_COUNT, NULL);
+ lp = (struct list_pair *)GETBUF(sizeof(struct list_pair) * (cnt + 1));
+ if (!lp)
+ error(FATAL, "fail to get memory for list_pair.\n");
+ lp[0].index = cnt;
+ cnt = do_xarray(addr, XARRAY_GATHER, lp);
+ } else {
+ addr = q + OFFSET(request_queue_nr_hw_queues);
+ readmem(addr, KVADDR, &cnt, sizeof(uint),
+ "request_queue.nr_hw_queues", FAULT_ON_ERROR);
- addr = q + OFFSET(request_queue_nr_hw_queues);
- readmem(addr, KVADDR, &cnt, sizeof(uint),
- "request_queue.nr_hw_queues", FAULT_ON_ERROR);
-
- addr = q + OFFSET(request_queue_queue_hw_ctx);
- readmem(addr, KVADDR, &hctx_addr, sizeof(void *),
- "request_queue.queue_hw_ctx", FAULT_ON_ERROR);
+ addr = q + OFFSET(request_queue_queue_hw_ctx);
+ readmem(addr, KVADDR, &hctx_addr, sizeof(void *),
+ "request_queue.queue_hw_ctx", FAULT_ON_ERROR);
+ }
hctx_array = (ulong *)GETBUF(sizeof(void *) * cnt);
- if (!hctx_array)
+ if (!hctx_array) {
+ if (lp)
+ FREEBUF(lp);
error(FATAL, "fail to get memory for the hctx_array\n");
+ }
+
+ if (lp && hctx_array) {
+ uint i;
+
+ /* copy it from list_pair to hctx_array */
+ for (i = 0; i < cnt; i++)
+ hctx_array[i] = (ulong)lp[i].value;
- if (!readmem(hctx_addr, KVADDR, hctx_array, sizeof(void *) * cnt,
+ FREEBUF(lp);
+ } else if (!readmem(hctx_addr, KVADDR, hctx_array, sizeof(void *) * cnt,
"request_queue.queue_hw_ctx[]", RETURN_ON_ERROR)) {
FREEBUF(hctx_array);
return;
@@ -4755,6 +4777,8 @@ void diskio_init(void)
"request_queue", "queue_hw_ctx");
MEMBER_OFFSET_INIT(request_queue_nr_hw_queues,
"request_queue", "nr_hw_queues");
+ MEMBER_OFFSET_INIT(request_queue_hctx_table,
+ "request_queue", "hctx_table");
MEMBER_OFFSET_INIT(blk_mq_ctx_rq_dispatched, "blk_mq_ctx",
"rq_dispatched");
MEMBER_OFFSET_INIT(blk_mq_ctx_rq_completed, "blk_mq_ctx",
diff --git a/symbols.c b/symbols.c
index c1f09556d710..bee1faf92c83 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10403,6 +10403,8 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(request_queue_queue_hw_ctx));
fprintf(fp, " request_queue_nr_hw_queues: %ld\n",
OFFSET(request_queue_nr_hw_queues));
+ fprintf(fp, " request_queue_hctx_table: %ld\n",
+ OFFSET(request_queue_hctx_table));
fprintf(fp, " blk_mq_ctx_rq_dispatched: %ld\n",
OFFSET(blk_mq_ctx_rq_dispatched));
fprintf(fp, " blk_mq_ctx_rq_completed: %ld\n",
--
2.30.2

View File

@ -1,53 +0,0 @@
From 98484914b7f4ba34da0625baa0ed6d449c1fa3ad Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Fri, 22 Jul 2022 13:44:50 +0900
Subject: [PATCH 11/28] Fix gcc-11 compiler warning on symbols.c
Without the patch, the following gcc-11 compiler warning is emitted for
symbols.c:
symbols.c: In function 'cmd_p':
symbols.c:7412:38: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
7412 | *(cpuspec-1) = ':';
| ~~~~~~~~~~~~~^~~~~
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
symbols.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/symbols.c b/symbols.c
index 69004a2e66e3..a94660538492 100644
--- a/symbols.c
+++ b/symbols.c
@@ -7363,7 +7363,7 @@ cmd_p(void)
unsigned radix;
int do_load_module_filter;
char buf1[BUFSIZE];
- char *cpuspec;
+ char *cpuspec, *p;
do_load_module_filter = radix = 0;
@@ -7398,7 +7398,7 @@ cmd_p(void)
if (argerrs || !args[optind])
cmd_usage(pc->curcmd, SYNOPSIS);
- cpuspec = strrchr(args[optind], ':');
+ p = cpuspec = strrchr(args[optind], ':');
if (cpuspec)
*cpuspec++ = NULLCHAR;
@@ -7421,7 +7421,7 @@ cmd_p(void)
sp->name);
else
/* maybe a valid C expression (e.g. ':') */
- *(cpuspec-1) = ':';
+ *p = ':';
}
process_gdb_output(concat_args(buf1, 0, TRUE), radix,
--
2.37.1

View File

@ -0,0 +1,87 @@
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,43 +0,0 @@
From c672d7a4c290712b32c54329cbdc1e74d122e813 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Mon, 6 Jun 2022 19:09:16 +0800
Subject: [PATCH 12/18] Doc: update man page for the "bpf" and "sbitmapq"
commands
The information of the "bpf" and "sbitmapq" commands is missing in the man
page of the crash utility. Let's add it to the man page.
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
crash.8 | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/crash.8 b/crash.8
index 1f3657b11e4c..e553a0b4adb3 100644
--- a/crash.8
+++ b/crash.8
@@ -584,6 +584,9 @@ creates a single-word alias for a command.
.I ascii
displays an ascii chart or translates a numeric value into its ascii components.
.TP
+.I bpf
+provides information on currently-loaded eBPF programs and maps.
+.TP
.I bt
displays a task's kernel-stack backtrace. If it is given the
.I \-a
@@ -706,6 +709,11 @@ number of seconds between each command execution.
.I runq
displays the tasks on the run queue.
.TP
+.I sbitmapq
+dumps the contents of the sbitmap_queue structure and the used
+bits in the bitmap. Also, it shows the dump of a structure array
+associated with the sbitmap_queue.
+.TP
.I search
searches a range of user or kernel memory space for given value.
.TP
--
2.30.2

View File

@ -1,38 +0,0 @@
From 9bb8a48d9424fc00ccd073125cdee9613b389cc6 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Fri, 22 Jul 2022 13:44:50 +0900
Subject: [PATCH 12/28] Fix gcc-11 compiler warning on makedumpfile.c
Without the patch, the following gcc-11 compiler warning is emitted for
makedumpfile.c:
In function 'flattened_format_get_osrelease',
inlined from 'check_flattened_format' at makedumpfile.c:236:3:
makedumpfile.c:392:9: warning: 'fclose' called on pointer returned from a mismatched allocation function [-Wmismatched-dealloc]
392 | fclose(pipe);
| ^~~~~~~~~~~~
makedumpfile.c: In function 'check_flattened_format':
makedumpfile.c:380:21: note: returned from 'popen'
380 | if ((pipe = popen(buf, "r")) == NULL)
| ^~~~~~~~~~~~~~~
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
makedumpfile.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/makedumpfile.c b/makedumpfile.c
index ebf24f56da2c..26d12b638ecd 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -389,5 +389,5 @@ flattened_format_get_osrelease(char *file)
}
}
- fclose(pipe);
+ pclose(pipe);
}
--
2.37.1

View File

@ -0,0 +1,265 @@
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,61 +0,0 @@
From 75739a08e952b6bd7434f4625a8fbe921361cbe8 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Fri, 22 Jul 2022 13:44:50 +0900
Subject: [PATCH 13/28] Fix gcc-11 compiler warning on kvmdump.c
Without the patch, the following gcc-11 compiler warning is emitted for
kvmdump.c:
In function 'write_mapfile_registers',
inlined from 'write_mapfile_trailer' at kvmdump.c:947:3,
inlined from 'kvmdump_init' at kvmdump.c:145:4:
kvmdump.c:972:13: warning: 'write' reading 8 bytes from a region of size 4 [-Wstringop-overread]
972 | if (write(kvm->mapfd, &kvm->cpu_devices, sizeof(uint64_t)) != sizeof(uint64_t))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from kvmdump.c:19:
kvmdump.c: In function 'kvmdump_init':
kvmdump.h:67:18: note: source object 'cpu_devices' of size 4
67 | uint32_t cpu_devices;
| ^~~~~~~~~~~
In file included from defs.h:26,
from kvmdump.c:18:
/usr/include/unistd.h:378:16: note: in a call to function 'write' declared with attribute 'access (read_only, 2, 3)'
378 | extern ssize_t write (int __fd, const void *__buf, size_t __n) __wur
| ^~~~~
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
kvmdump.c | 2 +-
kvmdump.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/kvmdump.c b/kvmdump.c
index 4db96bd844e9..e515bf0ce9a1 100644
--- a/kvmdump.c
+++ b/kvmdump.c
@@ -297,7 +297,7 @@ kvmdump_memory_dump(FILE *ofp)
(ulonglong)kvm->page_cache[i].paddr);
}
- fprintf(ofp, " cpu_devices: %d\n", kvm->cpu_devices);
+ fprintf(ofp, " cpu_devices: %ld\n", kvm->cpu_devices);
fprintf(ofp, " iohole: %llx (%llx - %llx)\n",
(ulonglong)kvm->iohole, 0x100000000ULL - kvm->iohole,
0x100000000ULL);
diff --git a/kvmdump.h b/kvmdump.h
index 07e047bb171c..2e408aebef0b 100644
--- a/kvmdump.h
+++ b/kvmdump.h
@@ -64,7 +64,7 @@ struct kvmdump_data {
ulong compresses;
uint64_t kvbase;
ulong *debug;
- uint32_t cpu_devices;
+ uint64_t cpu_devices;
struct register_set *registers;
uint64_t iohole;
};
--
2.37.1

View File

@ -0,0 +1,36 @@
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,48 +0,0 @@
From 9ce31a14d1083cbb2beb4a8e6eb7b88234b79a99 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Fri, 10 Jun 2022 11:49:47 +0900
Subject: [PATCH 13/18] sbitmapq: Fix for sbitmap_queue without ws_active
member
The sbitmap_queue.ws_active member was added by kernel commit 5d2ee7122c73
("sbitmap: optimize wakeup check") at Linux 5.0. Without the patch, on
earlier kernels the "sbitmapq" command fails with the following error:
crash> sbitmapq ffff8f1a3611cf10
sbitmapq: invalid structure member offset: sbitmap_queue_ws_active
FILE: sbitmap.c LINE: 393 FUNCTION: sbitmap_queue_context_load()
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
sbitmap.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/sbitmap.c b/sbitmap.c
index e8ebd62fe01c..152c28e6875f 100644
--- a/sbitmap.c
+++ b/sbitmap.c
@@ -325,7 +325,8 @@ static void sbitmap_queue_show(const struct sbitmap_queue_context *sqc,
fprintf(fp, "wake_batch = %u\n", sqc->wake_batch);
fprintf(fp, "wake_index = %d\n", sqc->wake_index);
- fprintf(fp, "ws_active = %d\n", sqc->ws_active);
+ if (VALID_MEMBER(sbitmap_queue_ws_active)) /* 5.0 and later */
+ fprintf(fp, "ws_active = %d\n", sqc->ws_active);
sbq_wait_state_size = SIZE(sbq_wait_state);
wait_cnt_off = OFFSET(sbq_wait_state_wait_cnt);
@@ -380,7 +381,8 @@ static void sbitmap_queue_context_load(ulong addr, struct sbitmap_queue_context
sqc->wake_batch = UINT(sbitmap_queue_buf + OFFSET(sbitmap_queue_wake_batch));
sqc->wake_index = INT(sbitmap_queue_buf + OFFSET(sbitmap_queue_wake_index));
sqc->ws_addr = ULONG(sbitmap_queue_buf + OFFSET(sbitmap_queue_ws));
- sqc->ws_active = INT(sbitmap_queue_buf + OFFSET(sbitmap_queue_ws_active));
+ if (VALID_MEMBER(sbitmap_queue_ws_active))
+ sqc->ws_active = INT(sbitmap_queue_buf + OFFSET(sbitmap_queue_ws_active));
if (VALID_MEMBER(sbitmap_queue_round_robin))
sqc->round_robin = BOOL(sbitmap_queue_buf + OFFSET(sbitmap_queue_round_robin));
sqc->min_shallow_depth = UINT(sbitmap_queue_buf + OFFSET(sbitmap_queue_min_shallow_depth));
--
2.30.2

View File

@ -1,110 +0,0 @@
From 0d3e86fee5eead93b521a0e20a0e099ede4ab72b Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Fri, 10 Jun 2022 11:49:47 +0900
Subject: [PATCH 14/18] sbitmapq: Fix for sbitmap_word without cleared member
The sbitmap_word.cleared member was added by kernel commit ea86ea2cdced
("sbitmap: ammortize cost of clearing bits") at Linux 5.0. Without the
patch, on earlier kernels the "sbitmapq" command fails with the
following error:
crash> sbitmapq ffff8f1a3611cf10
sbitmapq: invalid structure member offset: sbitmap_word_cleared
FILE: sbitmap.c LINE: 92 FUNCTION: __sbitmap_weight()
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
sbitmap.c | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/sbitmap.c b/sbitmap.c
index 152c28e6875f..c9f7209f9e3e 100644
--- a/sbitmap.c
+++ b/sbitmap.c
@@ -89,7 +89,6 @@ static unsigned int __sbitmap_weight(const struct sbitmap_context *sc, bool set)
{
const ulong sbitmap_word_size = SIZE(sbitmap_word);
const ulong w_word_off = OFFSET(sbitmap_word_word);
- const ulong w_cleared_off = OFFSET(sbitmap_word_cleared);
unsigned int weight = 0;
ulong addr = sc->map_addr;
@@ -111,7 +110,10 @@ static unsigned int __sbitmap_weight(const struct sbitmap_context *sc, bool set)
word = ULONG(sbitmap_word_buf + w_word_off);
weight += bitmap_weight(word, depth);
} else {
- cleared = ULONG(sbitmap_word_buf + w_cleared_off);
+ if (VALID_MEMBER(sbitmap_word_cleared))
+ cleared = ULONG(sbitmap_word_buf + OFFSET(sbitmap_word_cleared));
+ else
+ cleared = 0;
weight += bitmap_weight(cleared, depth);
}
@@ -130,7 +132,10 @@ static unsigned int sbitmap_weight(const struct sbitmap_context *sc)
static unsigned int sbitmap_cleared(const struct sbitmap_context *sc)
{
- return __sbitmap_weight(sc, false);
+ if (VALID_MEMBER(sbitmap_word_cleared)) /* 5.0 and later */
+ return __sbitmap_weight(sc, false);
+
+ return 0;
}
static void sbitmap_emit_byte(unsigned int offset, uint8_t byte)
@@ -149,7 +154,6 @@ static void sbitmap_bitmap_show(const struct sbitmap_context *sc)
{
const ulong sbitmap_word_size = SIZE(sbitmap_word);
const ulong w_word_off = OFFSET(sbitmap_word_word);
- const ulong w_cleared_off = OFFSET(sbitmap_word_cleared);
uint8_t byte = 0;
unsigned int byte_bits = 0;
@@ -169,7 +173,10 @@ static void sbitmap_bitmap_show(const struct sbitmap_context *sc)
}
word = ULONG(sbitmap_word_buf + w_word_off);
- cleared = ULONG(sbitmap_word_buf + w_cleared_off);
+ if (VALID_MEMBER(sbitmap_word_cleared))
+ cleared = ULONG(sbitmap_word_buf + OFFSET(sbitmap_word_cleared));
+ else
+ cleared = 0;
word_bits = __map_depth(sc, i);
word &= ~cleared;
@@ -219,7 +226,6 @@ static void __sbitmap_for_each_set(const struct sbitmap_context *sc,
{
const ulong sbitmap_word_size = SIZE(sbitmap_word);
const ulong w_word_off = OFFSET(sbitmap_word_word);
- const ulong w_cleared_off = OFFSET(sbitmap_word_cleared);
unsigned int index;
unsigned int nr;
@@ -245,7 +251,10 @@ static void __sbitmap_for_each_set(const struct sbitmap_context *sc,
}
w_word = ULONG(sbitmap_word_buf + w_word_off);
- w_cleared = ULONG(sbitmap_word_buf + w_cleared_off);
+ if (VALID_MEMBER(sbitmap_word_cleared))
+ w_cleared = ULONG(sbitmap_word_buf + OFFSET(sbitmap_word_cleared));
+ else
+ w_cleared = 0;
depth = min(__map_depth(sc, index) - nr, sc->depth - scanned);
@@ -297,7 +306,8 @@ static void sbitmap_queue_show(const struct sbitmap_queue_context *sqc,
fprintf(fp, "depth = %u\n", sc->depth);
fprintf(fp, "busy = %u\n", sbitmap_weight(sc) - sbitmap_cleared(sc));
- fprintf(fp, "cleared = %u\n", sbitmap_cleared(sc));
+ if (VALID_MEMBER(sbitmap_word_cleared)) /* 5.0 and later */
+ fprintf(fp, "cleared = %u\n", sbitmap_cleared(sc));
fprintf(fp, "bits_per_word = %u\n", 1U << sc->shift);
fprintf(fp, "map_nr = %u\n", sc->map_nr);
--
2.30.2

View File

@ -1,156 +0,0 @@
From b584eb81ff27e42547d01c521b488aaeaa35b460 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Thu, 28 Jul 2022 15:11:20 +0800
Subject: [PATCH 14/28] x86_64: Fix for AMD SME issue
Kernel commit changes(see [1]/[2]) may cause the failure of crash-utility
with the following error:
#./crash /home/vmlinux /home/vmcore
...
For help, type "help".
Type "apropos word" to search for commands related to "word"...
crash: seek error: physical address: 8000760a14000 type: "p4d page"
Let's get the "NUMBER(sme_mask)" from vmcoreinfo, and try to remove
the C-bit from the page table entries, the intention is to get the
true physical address.
Related kernel commits:
[1] aad983913d77 ("x86/mm/encrypt: Simplify sme_populate_pgd() and sme_populate_pgd_large()")
[2] e7d445ab26db ("x86/sme: Use #define USE_EARLY_PGTABLE_L5 in mem_encrypt_identity.c")
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 1 +
x86_64.c | 21 ++++++++++++++++++---
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/defs.h b/defs.h
index 6a1b6f8a16a8..f8fbfdfd1152 100644
--- a/defs.h
+++ b/defs.h
@@ -6206,6 +6206,7 @@ struct machine_specific {
ulong cpu_entry_area_end;
ulong page_offset_force;
char **exception_functions;
+ ulong sme_mask;
};
#define KSYMS_START (0x1)
diff --git a/x86_64.c b/x86_64.c
index f4e5d9e77cef..b2a536e4b19c 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -206,6 +206,10 @@ x86_64_init(int when)
machdep->machspec->kernel_image_size = dtol(string, QUIET, NULL);
free(string);
}
+ if ((string = pc->read_vmcoreinfo("NUMBER(sme_mask)"))) {
+ machdep->machspec->sme_mask = dtol(string, QUIET, NULL);
+ free(string);
+ }
if (SADUMP_DUMPFILE() || QEMU_MEM_DUMP_NO_VMCOREINFO() ||
VMSS_DUMPFILE())
/* Need for calculation of kaslr_offset and phys_base */
@@ -937,6 +941,7 @@ x86_64_dump_machdep_table(ulong arg)
ms->kernel_image_size/MEGABYTES(1));
else
fprintf(fp, "(uninitialized)\n");
+ fprintf(fp, " sme_mask: %lx\n", ms->sme_mask);
fprintf(fp, " physical_mask_shift: %ld\n", ms->physical_mask_shift);
fprintf(fp, " pgdir_shift: %ld\n", ms->pgdir_shift);
fprintf(fp, " GART_start: %lx\n", ms->GART_start);
@@ -1814,7 +1819,7 @@ x86_64_kpgd_offset(ulong kvaddr, int verbose, int IS_XEN)
if (IS_XEN)
fprintf(fp, "PAGE DIRECTORY: %lx [machine]\n", *pgd);
else
- fprintf(fp, "PAGE DIRECTORY: %lx\n", *pgd);
+ fprintf(fp, "PAGE DIRECTORY: %lx\n", *pgd & ~machdep->machspec->sme_mask);
}
return pgd;
@@ -1851,7 +1856,8 @@ x86_64_upgd_offset_legacy(struct task_context *tc, ulong uvaddr, int verbose, in
if (IS_XEN)
fprintf(fp, " PGD: %lx => %lx [machine]\n", (ulong)pud, pud_pte);
else
- fprintf(fp, " PGD: %lx => %lx\n", (ulong)pud, pud_pte);
+ fprintf(fp, " PGD: %lx => %lx\n",
+ (ulong)pud, pud_pte & ~machdep->machspec->sme_mask);
}
return pud_pte;
@@ -1882,7 +1888,8 @@ x86_64_upgd_offset(struct task_context *tc, ulong uvaddr, int verbose, int IS_XE
if (IS_XEN)
fprintf(fp, " PGD: %lx => %lx [machine]\n", (ulong)pgd, pgd_pte);
else
- fprintf(fp, " PGD: %lx => %lx\n", (ulong)pgd, pgd_pte);
+ fprintf(fp, " PGD: %lx => %lx\n",
+ (ulong)pgd, pgd_pte & ~machdep->machspec->sme_mask);
}
return pgd_pte;
@@ -1900,9 +1907,11 @@ x86_64_p4d_offset(ulong pgd_pte, ulong vaddr, int verbose, int IS_XEN)
ulong p4d_pte;
p4d_paddr = pgd_pte & PHYSICAL_PAGE_MASK;
+ p4d_paddr &= ~machdep->machspec->sme_mask;
FILL_P4D(p4d_paddr, PHYSADDR, PAGESIZE());
p4d = ((ulong *)p4d_paddr) + p4d_index(vaddr);
p4d_pte = ULONG(machdep->machspec->p4d + PAGEOFFSET(p4d));
+ p4d_pte &= ~machdep->machspec->sme_mask;
if (verbose) {
if (IS_XEN)
fprintf(fp, " P4D: %lx => %lx [machine]\n", (ulong)p4d, p4d_pte);
@@ -1925,6 +1934,7 @@ x86_64_pud_offset(ulong pgd_pte, ulong vaddr, int verbose, int IS_XEN)
ulong pud_pte;
pud_paddr = pgd_pte & PHYSICAL_PAGE_MASK;
+ pud_paddr &= ~machdep->machspec->sme_mask;
if (IS_XEN) {
pud_paddr = xen_m2p(pud_paddr);
@@ -1935,6 +1945,7 @@ x86_64_pud_offset(ulong pgd_pte, ulong vaddr, int verbose, int IS_XEN)
FILL_PUD(pud_paddr, PHYSADDR, PAGESIZE());
pud = ((ulong *)pud_paddr) + pud_index(vaddr);
pud_pte = ULONG(machdep->pud + PAGEOFFSET(pud));
+ pud_pte &= ~machdep->machspec->sme_mask;
if (verbose) {
if (IS_XEN)
fprintf(fp, " PUD: %lx => %lx [machine]\n", (ulong)pud, pud_pte);
@@ -1957,6 +1968,7 @@ x86_64_pmd_offset(ulong pud_pte, ulong vaddr, int verbose, int IS_XEN)
ulong pmd_pte;
pmd_paddr = pud_pte & PHYSICAL_PAGE_MASK;
+ pmd_paddr &= ~machdep->machspec->sme_mask;
if (IS_XEN) {
pmd_paddr = xen_m2p(pmd_paddr);
@@ -1967,6 +1979,7 @@ x86_64_pmd_offset(ulong pud_pte, ulong vaddr, int verbose, int IS_XEN)
FILL_PMD(pmd_paddr, PHYSADDR, PAGESIZE());
pmd = ((ulong *)pmd_paddr) + pmd_index(vaddr);
pmd_pte = ULONG(machdep->pmd + PAGEOFFSET(pmd));
+ pmd_pte &= ~machdep->machspec->sme_mask;
if (verbose) {
if (IS_XEN)
fprintf(fp, " PMD: %lx => %lx [machine]\n", (ulong)pmd, pmd_pte);
@@ -1988,6 +2001,7 @@ x86_64_pte_offset(ulong pmd_pte, ulong vaddr, int verbose, int IS_XEN)
ulong pte;
pte_paddr = pmd_pte & PHYSICAL_PAGE_MASK;
+ pte_paddr &= ~machdep->machspec->sme_mask;
if (IS_XEN) {
pte_paddr = xen_m2p(pte_paddr);
@@ -1998,6 +2012,7 @@ x86_64_pte_offset(ulong pmd_pte, ulong vaddr, int verbose, int IS_XEN)
FILL_PTBL(pte_paddr, PHYSADDR, PAGESIZE());
ptep = ((ulong *)pte_paddr) + pte_index(vaddr);
pte = ULONG(machdep->ptbl + PAGEOFFSET(ptep));
+ pte &= ~machdep->machspec->sme_mask;
if (verbose) {
if (IS_XEN)
fprintf(fp, " PTE: %lx => %lx [machine]\n", (ulong)ptep, pte);
--
2.37.1

View File

@ -0,0 +1,65 @@
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,34 +0,0 @@
From 619e36c18791333ee3a7fea759ce20396e711a46 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Mon, 22 Aug 2022 11:59:46 +0900
Subject: [PATCH 15/28] Makefile: Fix unnecessary re-patching with
coreutils-9.0
"sum" command in coreutils-9.0 (e.g. Fedora 36) started to output a file
name. As a result, "make" always detects a change of gdb-10.2.patch
wrongly and re-applies it unnecessarily.
Use standard input to fix it and "md5sum" to improve detection.
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index 059759b3e4ab..dd81df6c198c 100644
--- a/Makefile
+++ b/Makefile
@@ -269,7 +269,7 @@ rebuild:
@if [ ! -f ${GDB}/${GDB}.patch ]; then \
touch ${GDB}/${GDB}.patch; fi
@if [ -f ${GDB}.patch ] && [ -s ${GDB}.patch ] && \
- [ "`sum ${GDB}.patch`" != "`sum ${GDB}/${GDB}.patch`" ]; then \
+ [ "`md5sum < ${GDB}.patch`" != "`md5sum < ${GDB}/${GDB}.patch`" ]; then \
(sh -x ${GDB}.patch ${TARGET}; patch -N -p0 -r- --fuzz=0 < ${GDB}.patch; cp ${GDB}.patch ${GDB}; cd ${GDB}; \
$(MAKE) CRASH_TARGET=${TARGET}) \
else (cd ${GDB}/gdb; $(MAKE) CRASH_TARGET=${TARGET}); fi
--
2.37.1

View File

@ -1,49 +0,0 @@
From 12fe6c7cdd768f87ce6e903a2bbfb0c0591585c5 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Fri, 10 Jun 2022 11:49:47 +0900
Subject: [PATCH 15/18] sbitmapq: Fix for sbitmap_queue without
min_shallow_depth member
The sbitmap_queue.min_shallow_depth member was added by kernel commit
a327553965de ("sbitmap: fix missed wakeups caused by sbitmap_queue_get_shallow()")
at Linux 4.18. Without the patch, on earlier kernels the "sbitmapq"
command fails with the following error:
crash> sbitmapq ffff89bb7638ee50
sbitmapq: invalid structure member offset: sbitmap_queue_min_shallow_depth
FILE: sbitmap.c LINE: 398 FUNCTION: sbitmap_queue_context_load()
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
sbitmap.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/sbitmap.c b/sbitmap.c
index c9f7209f9e3e..bb2f19e6207b 100644
--- a/sbitmap.c
+++ b/sbitmap.c
@@ -371,7 +371,8 @@ static void sbitmap_queue_show(const struct sbitmap_queue_context *sqc,
else if (VALID_MEMBER(sbitmap_round_robin)) /* 5.13 and later */
fprintf(fp, "round_robin = %d\n", sc->round_robin);
- fprintf(fp, "min_shallow_depth = %u\n", sqc->min_shallow_depth);
+ if (VALID_MEMBER(sbitmap_queue_min_shallow_depth)) /* 4.18 and later */
+ fprintf(fp, "min_shallow_depth = %u\n", sqc->min_shallow_depth);
}
static void sbitmap_queue_context_load(ulong addr, struct sbitmap_queue_context *sqc)
@@ -395,7 +396,8 @@ static void sbitmap_queue_context_load(ulong addr, struct sbitmap_queue_context
sqc->ws_active = INT(sbitmap_queue_buf + OFFSET(sbitmap_queue_ws_active));
if (VALID_MEMBER(sbitmap_queue_round_robin))
sqc->round_robin = BOOL(sbitmap_queue_buf + OFFSET(sbitmap_queue_round_robin));
- sqc->min_shallow_depth = UINT(sbitmap_queue_buf + OFFSET(sbitmap_queue_min_shallow_depth));
+ if (VALID_MEMBER(sbitmap_queue_min_shallow_depth))
+ sqc->min_shallow_depth = UINT(sbitmap_queue_buf + OFFSET(sbitmap_queue_min_shallow_depth));
FREEBUF(sbitmap_queue_buf);
}
--
2.30.2

View File

@ -1,84 +0,0 @@
From c07068266b41450ca6821ee0a1a3adf34206015f Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Fri, 10 Jun 2022 15:21:53 +0900
Subject: [PATCH 16/18] Make "dev -d|-D" options parse sbitmap on Linux 4.18
and later
There have been a few reports that the "dev -d|-D" options displayed
incorrect I/O stats due to racy blk_mq_ctx.rq_* counters. To fix it,
make the options parse sbitmap to count I/O stats on Linux 4.18 and
later kernels, which include RHEL8 ones.
To do this, adjust to the blk_mq_tags structure of Linux 5.10 through
5.15 kernels, which contain kernel commit 222a5ae03cdd ("blk-mq: Use
pointers for blk_mq_tags bitmap tags") and do not contain ae0f1a732f4a
("blk-mq: Stop using pointers for blk_mq_tags bitmap tags").
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
dev.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/dev.c b/dev.c
index 0172c83ffaea..db97f8aebdc2 100644
--- a/dev.c
+++ b/dev.c
@@ -4339,6 +4339,10 @@ static void bt_for_each(ulong q, ulong tags, ulong sbq, uint reserved, uint nr_r
static void queue_for_each_hw_ctx(ulong q, ulong *hctx, uint cnt, struct diskio *dio)
{
uint i;
+ int bitmap_tags_is_ptr = 0;
+
+ if (MEMBER_TYPE("blk_mq_tags", "bitmap_tags") == TYPE_CODE_PTR)
+ bitmap_tags_is_ptr = 1;
for (i = 0; i < cnt; i++) {
ulong addr = 0, tags = 0;
@@ -4357,9 +4361,17 @@ static void queue_for_each_hw_ctx(ulong q, ulong *hctx, uint cnt, struct diskio
if (nr_reserved_tags) {
addr = tags + OFFSET(blk_mq_tags_breserved_tags);
+ if (bitmap_tags_is_ptr &&
+ !readmem(addr, KVADDR, &addr, sizeof(ulong),
+ "blk_mq_tags.bitmap_tags", RETURN_ON_ERROR))
+ break;
bt_for_each(q, tags, addr, 1, nr_reserved_tags, dio);
}
addr = tags + OFFSET(blk_mq_tags_bitmap_tags);
+ if (bitmap_tags_is_ptr &&
+ !readmem(addr, KVADDR, &addr, sizeof(ulong),
+ "blk_mq_tags.bitmap_tags", RETURN_ON_ERROR))
+ break;
bt_for_each(q, tags, addr, 0, nr_reserved_tags, dio);
}
}
@@ -4423,14 +4435,23 @@ get_mq_diskio(unsigned long q, unsigned long *mq_count)
unsigned long mctx_addr;
struct diskio tmp = {0};
- if (INVALID_MEMBER(blk_mq_ctx_rq_dispatched) ||
- INVALID_MEMBER(blk_mq_ctx_rq_completed)) {
+ /*
+ * Currently this function does not support old blk-mq implementation
+ * before 12f5b9314545 ("blk-mq: Remove generation seqeunce"), so
+ * filter them out.
+ */
+ if (VALID_MEMBER(request_state)) {
+ if (CRASHDEBUG(1))
+ fprintf(fp, "mq: using sbitmap\n");
get_mq_diskio_from_hw_queues(q, &tmp);
mq_count[0] = tmp.read;
mq_count[1] = tmp.write;
return;
}
+ if (CRASHDEBUG(1))
+ fprintf(fp, "mq: using blk_mq_ctx.rq_{completed,dispatched} counters\n");
+
readmem(q + OFFSET(request_queue_queue_ctx), KVADDR, &queue_ctx,
sizeof(ulong), "request_queue.queue_ctx",
FAULT_ON_ERROR);
--
2.30.2

View File

@ -1,111 +0,0 @@
From 28a41ec7a471474094d8ab39f3a69b44d0f9ebcf Mon Sep 17 00:00:00 2001
From: Huang Shijie <shijie@os.amperecomputing.com>
Date: Mon, 22 Aug 2022 09:29:32 +0000
Subject: [PATCH 16/28] arm64: use TCR_EL1_T1SZ to get the correct info if
vabits_actual is missing
After kernel commit 0d9b1ffefabe ("arm64: mm: make vabits_actual a build
time constant if possible"), the vabits_actual is not compiled to kernel
symbols when "VA_BITS > 48" is false.
So the crash will not find the vabits_actual symbol, and it will fail
in the end like this:
# ./crash
...
WARNING: VA_BITS: calculated: 46 vmcoreinfo: 48
crash: invalid kernel virtual address: ffff88177ffff000 type: "pud page"
This patch introduces the arm64_set_va_bits_by_tcr(), and if crash cannot
find vabits_actual symbol, it will use the TCR_EL1_T1SZ register to get
the correct VA_BITS_ACTUAL/VA_BITS/VA_START.
Tested this patch with:
1.) the live mode with /proc/kcore
2.) the kdump file with /proc/vmcore.
Signed-off-by: Huang Shijie <shijie@os.amperecomputing.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
arm64.c | 51 ++++++++++++++++++++++++++++++++++-----------------
1 file changed, 34 insertions(+), 17 deletions(-)
diff --git a/arm64.c b/arm64.c
index b6b7aa11f4fe..c3e26a371a61 100644
--- a/arm64.c
+++ b/arm64.c
@@ -4586,6 +4586,36 @@ arm64_IS_VMALLOC_ADDR(ulong vaddr)
(vaddr >= ms->modules_vaddr && vaddr <= ms->modules_end));
}
+/* Return TRUE if we succeed, return FALSE on failure. */
+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)"))) {
+ /* See ARMv8 ARM for the description of
+ * TCR_EL1.T1SZ and how it can be used
+ * to calculate the vabits_actual
+ * supported by underlying kernel.
+ *
+ * Basically:
+ * vabits_actual = 64 - T1SZ;
+ */
+ value = 64 - strtoll(string, NULL, 0);
+ 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);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static void
arm64_calc_VA_BITS(void)
{
@@ -4616,23 +4646,8 @@ arm64_calc_VA_BITS(void)
} else if (ACTIVE())
error(FATAL, "cannot determine VA_BITS_ACTUAL: please use /proc/kcore\n");
else {
- if ((string = pc->read_vmcoreinfo("NUMBER(TCR_EL1_T1SZ)")) ||
- (string = pc->read_vmcoreinfo("NUMBER(tcr_el1_t1sz)"))) {
- /* See ARMv8 ARM for the description of
- * TCR_EL1.T1SZ and how it can be used
- * to calculate the vabits_actual
- * supported by underlying kernel.
- *
- * Basically:
- * vabits_actual = 64 - T1SZ;
- */
- value = 64 - strtoll(string, NULL, 0);
- 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);
+ if (arm64_set_va_bits_by_tcr()) {
+ /* nothing */
} else if (machdep->machspec->VA_BITS_ACTUAL) {
machdep->machspec->VA_BITS = machdep->machspec->VA_BITS_ACTUAL;
machdep->machspec->VA_START = _VA_START(machdep->machspec->VA_BITS_ACTUAL);
@@ -4654,6 +4669,8 @@ arm64_calc_VA_BITS(void)
*/
machdep->flags |= FLIPPED_VM;
return;
+ } else if (arm64_set_va_bits_by_tcr()) {
+ return;
}
if (!(sp = symbol_search("swapper_pg_dir")) &&
--
2.37.1

View File

@ -1,66 +0,0 @@
From c32abfea658ef33c20a942700277cb52baf95bfa Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Thu, 25 Aug 2022 14:39:44 +0800
Subject: [PATCH 17/28] Fix "task -R" by adding end identifier for union in
task_struct
Previously, the start and end identifiers for union are " {\n" and
" }, \n". However the end identifier is not always as expected.
" },\n" can also be the end identifier with gdb-10.2. As a result,
variable "randomized" is in incorrect state after union, and fails to
identify the later struct members. For example, we can reproduce the
issue as follows:
crash> task
PID: 847 TASK: ffff94f8038f4000 CPU: 72 COMMAND: "khungtaskd"
struct task_struct {
thread_info = {
flags = 2148024320,
status = 0,
preempt_lazy_count = 0
},
{
<the union>
},
...
wake_entry = {
next = 0x0
},
...
Before patch:
crash> task -R wake_entry
PID: 847 TASK: ffff94f8038f4000 CPU: 72 COMMAND: "khungtaskd"
After patch:
crash> task -R wake_entry
PID: 847 TASK: ffff94f8038f4000 CPU: 72 COMMAND: "khungtaskd"
wake_entry = {
next = 0x0
},
Signed-off-by: Tao Liu <ltao@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
task.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/task.c b/task.c
index 071c787fbfa5..db2abc8106a2 100644
--- a/task.c
+++ b/task.c
@@ -3436,7 +3436,8 @@ parse_task_thread(int argcnt, char *arglist[], struct task_context *tc) {
while (fgets(buf, BUFSIZE, pc->tmpfile)) {
if (STREQ(buf, " {\n"))
randomized = TRUE;
- else if (randomized && STREQ(buf, " }, \n"))
+ else if (randomized &&
+ (STREQ(buf, " }, \n") || STREQ(buf, " },\n")))
randomized = FALSE;
if (strlen(lookfor2)) {
--
2.37.1

View File

@ -1,44 +0,0 @@
From 6bc3b74c6e2b0aaebe1bc164594e53b010efef56 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Fri, 10 Jun 2022 15:52:34 +0900
Subject: [PATCH 17/18] sbitmapq: Fix for kernels without struct
wait_queue_head
The current struct wait_queue_head was renamed by kernel commit
9d9d676f595b ("sched/wait: Standardize internal naming of wait-queue heads")
at Linux 4.13. Without the patch, on earlier kernels the "sbitmapq"
command fails with the following error:
crash> sbitmapq ffff8801790b3b50
depth = 128
busy = 0
bits_per_word = 32
...
sbitmapq: invalid structure member offset: wait_queue_head_head
FILE: sbitmap.c LINE: 344 FUNCTION: sbitmap_queue_show()
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
sbitmap.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/sbitmap.c b/sbitmap.c
index bb2f19e6207b..be5d30a8ea88 100644
--- a/sbitmap.c
+++ b/sbitmap.c
@@ -341,7 +341,10 @@ static void sbitmap_queue_show(const struct sbitmap_queue_context *sqc,
sbq_wait_state_size = SIZE(sbq_wait_state);
wait_cnt_off = OFFSET(sbq_wait_state_wait_cnt);
wait_off = OFFSET(sbq_wait_state_wait);
- list_head_off = OFFSET(wait_queue_head_head);
+ if (VALID_MEMBER(wait_queue_head_head)) /* 4.13 and later */
+ list_head_off = OFFSET(wait_queue_head_head);
+ else
+ list_head_off = OFFSET(__wait_queue_head_task_list);
sbq_wait_state_buf = GETBUF(sbq_wait_state_size);
--
2.30.2

View File

@ -1,133 +0,0 @@
From 5948cb9b3e622e3c87216c7c6479f509c8aeb7c1 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Wed, 16 Nov 2022 17:36:03 +0800
Subject: [PATCH 18/28] Let gdb get kernel module symbols info from crash
Gdb will try to resolve an address to its corresponding symbol name such as
when printing a structure. It works fine for kernel symbols, because gdb can
find them through vmlinux. However as for kernel modules symbols, crash
resolves them by dig into "struct module", which gdb don't know. As a result,
gdb fails to translate a kernel module address to its symbol name without
"mod -s|-S" options. For example we can reproduce the issue as follows.
crash> timer
....
4331308176 336 ffff94ea24240860 ffffffffc03762c0 <estimation_timer>
....
crash> sym 0xffffffffc03762c0
ffffffffc03762c0 (t) estimation_timer [ip_vs]
Before patch:
crash> timer_list ffff94ea24240860
struct timer_list {
....
function = 0xffffffffc03762c0,
....
}
After patch:
crash> timer_list ffff94ea24240860
struct timer_list {
....
function = 0xffffffffc03762c0 <estimation_timer>,
....
}
In this patch, we add an interface for gdb, when gdb trying to build kernel
module's address symbolic, the info can be get from crash.
Signed-off-by: Tao Liu <ltao@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 2 ++
gdb-7.6.patch | 33 +++++++++++++++++++++++++++++++++
gdb_interface.c | 12 ++++++++++++
3 files changed, 47 insertions(+)
diff --git a/defs.h b/defs.h
index f8fbfdfd1152..b7d76330141a 100644
--- a/defs.h
+++ b/defs.h
@@ -4877,6 +4877,7 @@ int patch_kernel_symbol(struct gnu_request *);
struct syment *symbol_search(char *);
int gdb_line_number_callback(ulong, ulong, ulong);
int gdb_print_callback(ulong);
+char *gdb_lookup_module_symbol(ulong, ulong *);
#endif
#ifndef GDB_COMMON
@@ -7291,6 +7292,7 @@ int gdb_pass_through(char *, FILE *, ulong);
int gdb_readmem_callback(ulong, void *, int, int);
int gdb_line_number_callback(ulong, ulong, ulong);
int gdb_print_callback(ulong);
+char *gdb_lookup_module_symbol(ulong, ulong *);
void gdb_error_hook(void);
void restore_gdb_sanity(void);
int is_gdb_command(int, ulong);
diff --git a/gdb-7.6.patch b/gdb-7.6.patch
index c63ad7d81cb0..f1c3aa734241 100644
--- a/gdb-7.6.patch
+++ b/gdb-7.6.patch
@@ -2568,3 +2568,36 @@ diff -up gdb-7.6/opcodes/configure.orig gdb-7.6/opcodes/configure
$(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \
-o $(shell /bin/cat mergeobj) $(LIBGDB_OBS) \
$(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES) $(shell /bin/cat mergelibs)
+--- gdb-7.6/gdb/printcmd.c.orig
++++ gdb-7.6/gdb/printcmd.c
+@@ -622,6 +622,10 @@ print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr,
+ return 1;
+ }
+
++#ifdef CRASH_MERGE
++extern char *gdb_lookup_module_symbol(unsigned long, unsigned long *);
++#endif
++
+ /* Given an address ADDR return all the elements needed to print the
+ address in a symbolic form. NAME can be mangled or not depending
+ on DO_DEMANGLE (and also on the asm_demangle global variable,
+@@ -710,7 +714,19 @@ build_address_symbolic (struct gdbarch *gdbarch,
+ }
+ }
+ if (symbol == NULL && msymbol == NULL)
++#ifdef CRASH_MERGE
++ {
++ char *name_ptr = gdb_lookup_module_symbol(addr, (unsigned long *)offset);
++ if (name_ptr) {
++ *name = xstrdup (name_ptr);
++ return 0;
++ } else {
++ return 1;
++ }
++ }
++#else
+ return 1;
++#endif
+
+ /* If the nearest symbol is too far away, don't print anything symbolic. */
+
diff --git a/gdb_interface.c b/gdb_interface.c
index 1f10006a2d63..f9d0018998df 100644
--- a/gdb_interface.c
+++ b/gdb_interface.c
@@ -945,6 +945,18 @@ gdb_print_callback(ulong addr)
return IS_KVADDR(addr);
}
+char *
+gdb_lookup_module_symbol(ulong addr, ulong *offset)
+{
+ struct syment *sp;
+
+ if ((sp = value_search(addr, offset))) {
+ return sp->name;
+ } else {
+ return NULL;
+ }
+}
+
/*
* Used by gdb_interface() to catch gdb-related errors, if desired.
*/
--
2.37.1

View File

@ -1,43 +0,0 @@
From b8f2ae6b494d706b1e4855b439c4930a6a6a2f5c Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Fri, 10 Jun 2022 16:00:14 +0900
Subject: [PATCH 18/18] sbitmapq: Limit kernels without sbitmap again
commit 364b2e413c69 ("sbitmapq: remove struct and member validation
in sbitmapq_init()") allowed the use of the "sbitmapq" command
unconditionally. Without the patch, the command fails with the
following error on kernels without sbitmap:
crash> sbitmapq ffff88015796e550
sbitmapq: invalid structure member offset: sbitmap_queue_sb
FILE: sbitmap.c LINE: 385 FUNCTION: sbitmap_queue_context_load()
Now the command supports Linux 4.9 and later kernels since it was
abstracted out, so it can be limited by the non-existence of the
sbitmap structure.
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
sbitmap.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/sbitmap.c b/sbitmap.c
index be5d30a8ea88..12d6512a1e4d 100644
--- a/sbitmap.c
+++ b/sbitmap.c
@@ -540,6 +540,10 @@ void sbitmapq_init(void)
STRUCT_SIZE_INIT(sbitmap_queue, "sbitmap_queue");
STRUCT_SIZE_INIT(sbq_wait_state, "sbq_wait_state");
+ /* sbitmap was abstracted out by commit 88459642cba4 on Linux 4.9. */
+ if (INVALID_SIZE(sbitmap))
+ command_not_supported();
+
MEMBER_OFFSET_INIT(sbitmap_word_depth, "sbitmap_word", "depth");
MEMBER_OFFSET_INIT(sbitmap_word_word, "sbitmap_word", "word");
MEMBER_OFFSET_INIT(sbitmap_word_cleared, "sbitmap_word", "cleared");
--
2.30.2

View File

@ -1,65 +0,0 @@
From 93cd670426aaf4951bceb8f24f0ce63c24e16f5d Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Wed, 16 Nov 2022 20:09:22 +0800
Subject: [PATCH 19/28] x86_64: Correct the identifier when locating the call
instruction
The previous implementation to locate the call instruction is
to strstr "call", then check whether the previous char is ' '
or '\t'. The implementation is problematic. For example it
cannot resolve the following disassembly string:
"0xffffffffc0995378 <nfs41_callback_svc+344>:\tcall 0xffffffff8ecfa4c0 <schedule>\n"
strstr will locate the "_call" and char check fails,
as a result, extract_hex fails to get the calling address.
NOTE: the issue is more likely to be reproduced when patch[1] applied.
Because without patch[1], the disassembly string will be as follows,
so the issue is no longer reproducible.
"0xffffffffc0995378:\tcall 0xffffffff8ecfa4c0 <schedule>\n"
Before the patch:
crash> bt 1472
PID: 1472 TASK: ffff8c121fa72f70 CPU: 18 COMMAND: "nfsv4.1-svc"
#0 [ffff8c16231a3db8] __schedule at ffffffff8ecf9ef3
#1 [ffff8c16231a3e40] schedule at ffffffff8ecfa4e9
After the patch:
crash> bt 1472
PID: 1472 TASK: ffff8c121fa72f70 CPU: 18 COMMAND: "nfsv4.1-svc"
#0 [ffff8c16231a3db8] __schedule at ffffffff8ecf9ef3
#1 [ffff8c16231a3e40] schedule at ffffffff8ecfa4e9
#2 [ffff8c16231a3e50] nfs41_callback_svc at ffffffffc099537d [nfsv4]
#3 [ffff8c16231a3ec8] kthread at ffffffff8e6b966f
#4 [ffff8c16231a3f50] ret_from_fork at ffffffff8ed07898
This patch fix the issue by strstr "\tcall" and " call", to
locate the correct call instruction.
[1]: https://listman.redhat.com/archives/crash-utility/2022-August/010085.html
Signed-off-by: Tao Liu <ltao@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
x86_64.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/x86_64.c b/x86_64.c
index b2a536e4b19c..292c240e887e 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -4429,8 +4429,7 @@ x86_64_function_called_by(ulong rip)
if (gdb_pass_through(buf, pc->tmpfile2, GNU_RETURN_ON_ERROR)) {
rewind(pc->tmpfile2);
while (fgets(buf, BUFSIZE, pc->tmpfile2)) {
- if ((p1 = strstr(buf, "callq")) &&
- whitespace(*(p1-1))) {
+ if ((p1 = strstr(buf, " callq")) || (p1 = strstr(buf, "\tcallq"))) {
if (extract_hex(p1, &value, NULLCHAR, TRUE))
break;
}
--
2.37.1

View File

@ -1,40 +0,0 @@
From 931ea86070e9b56bf698ae3a4f20647d42325d6d Mon Sep 17 00:00:00 2001
From: "Chunguang.Xu" <chunguang.xu@shopee.com>
Date: Thu, 25 Aug 2022 12:07:20 +0800
Subject: [PATCH 20/28] Add debian/ubuntu vmlinux location to default search
dirs
Now crash cannot find debian/ubuntu kernel vmlinux, we need to
explicitly specify the path to vmlinux. Try to add the debian
vmlinux location to default search directories.
Signed-off-by: Chunguang Xu <chunguang.xu@shopee.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
filesys.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/filesys.c b/filesys.c
index a863f04eb250..c2ea78de821d 100644
--- a/filesys.c
+++ b/filesys.c
@@ -319,7 +319,7 @@ match_proc_version(void)
#define CREATE 1
#define DESTROY 0
-#define DEFAULT_SEARCHDIRS 5
+#define DEFAULT_SEARCHDIRS 6
#define EXTRA_SEARCHDIRS 5
static char **
@@ -336,6 +336,7 @@ build_searchdirs(int create, int *preferred)
"/boot/",
"/boot/efi/redhat",
"/boot/efi/EFI/redhat",
+ "/usr/lib/debug/boot/",
"/",
NULL
};
--
2.37.1

View File

@ -1,102 +0,0 @@
From a4f8fe965e1ed0d27aff0cdf30e2c571da2e5356 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Thu, 1 Sep 2022 14:03:09 +0900
Subject: [PATCH 21/28] Fix gcc-12 compiler warnings on lkcd_*.c
Without the patch, the following gcc-12 compiler warnings are emitted
for lkcd_*.c:
lkcd_v1.c: In function 'dump_lkcd_environment_v1':
lkcd_v1.c:252:20: warning: the comparison will always evaluate as 'true' for the address of 'dh_panic_string' will never be NULL [-Waddress]
252 | dh && dh->dh_panic_string &&
| ^~
In file included from lkcd_v1.c:21:
lkcd_vmdump_v1.h:108:30: note: 'dh_panic_string' declared here
108 | char dh_panic_string[DUMP_PANIC_LEN];
| ^~~~~~~~~~~~~~~
...
Reported-by: Lianbo Jiang <lijiang@redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
lkcd_v1.c | 3 +--
lkcd_v2_v3.c | 3 +--
lkcd_v5.c | 3 +--
lkcd_v7.c | 3 +--
lkcd_v8.c | 3 +--
5 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/lkcd_v1.c b/lkcd_v1.c
index 5f891aeb1ce3..31bdc04c5fdd 100644
--- a/lkcd_v1.c
+++ b/lkcd_v1.c
@@ -249,8 +249,7 @@ dump_header_only:
lkcd_print(" dh_eip: %lx\n", dh->dh_eip);
lkcd_print(" dh_num_pages: %d\n", dh->dh_num_pages);
lkcd_print(" dh_panic_string: %s%s", dh->dh_panic_string,
- dh && dh->dh_panic_string &&
- strstr(dh->dh_panic_string, "\n") ? "" : "\n");
+ dh && strstr(dh->dh_panic_string, "\n") ? "" : "\n");
lkcd_print(" dh_time: %s\n",
strip_linefeeds(ctime(&(dh->dh_time.tv_sec))));
diff --git a/lkcd_v2_v3.c b/lkcd_v2_v3.c
index 8635a7b07c77..edcb6637a55e 100644
--- a/lkcd_v2_v3.c
+++ b/lkcd_v2_v3.c
@@ -307,8 +307,7 @@ dump_header_only:
lkcd_print(" dh_num_pages: ");
lkcd_print(BITS32() ? "%ld\n" : "%d\n", dh->dh_num_pages);
lkcd_print(" dh_panic_string: %s%s", dh->dh_panic_string,
- dh && dh->dh_panic_string &&
- strstr(dh->dh_panic_string, "\n") ? "" : "\n");
+ dh && strstr(dh->dh_panic_string, "\n") ? "" : "\n");
lkcd_print(" dh_time: %s\n",
strip_linefeeds(ctime(&(dh->dh_time.tv_sec))));
diff --git a/lkcd_v5.c b/lkcd_v5.c
index cb7634d094ec..e3bfa6f4b272 100644
--- a/lkcd_v5.c
+++ b/lkcd_v5.c
@@ -270,8 +270,7 @@ dump_header_only:
lkcd_print(" dh_num_pages: ");
lkcd_print(BITS32() ? "%ld\n" : "%d\n", dh->dh_num_pages);
lkcd_print(" dh_panic_string: %s%s", dh->dh_panic_string,
- dh && dh->dh_panic_string &&
- strstr(dh->dh_panic_string, "\n") ? "" : "\n");
+ dh && strstr(dh->dh_panic_string, "\n") ? "" : "\n");
lkcd_print(" dh_time: %s\n",
strip_linefeeds(ctime(&(dh->dh_time.tv_sec))));
diff --git a/lkcd_v7.c b/lkcd_v7.c
index 608e1481f01d..97d99008635a 100644
--- a/lkcd_v7.c
+++ b/lkcd_v7.c
@@ -347,8 +347,7 @@ dump_header_only:
lkcd_print(" dh_num_pages: ");
lkcd_print(BITS32() ? "%ld\n" : "%d\n", dh->dh_num_pages);
lkcd_print(" dh_panic_string: %s%s", dh->dh_panic_string,
- dh && dh->dh_panic_string &&
- strstr(dh->dh_panic_string, "\n") ? "" : "\n");
+ dh && strstr(dh->dh_panic_string, "\n") ? "" : "\n");
lkcd_print(" dh_time: %s\n",
strip_linefeeds(ctime(&(dh->dh_time.tv_sec))));
diff --git a/lkcd_v8.c b/lkcd_v8.c
index 3b355e056123..4167fa5e4292 100644
--- a/lkcd_v8.c
+++ b/lkcd_v8.c
@@ -543,8 +543,7 @@ dump_header_only:
lkcd_print(" dh_num_pages: ");
lkcd_print(BITS32() ? "%ld\n" : "%d\n", dh->dh_num_pages);
lkcd_print(" dh_panic_string: %s%s", dh->dh_panic_string,
- dh && dh->dh_panic_string &&
- strstr(dh->dh_panic_string, "\n") ? "" : "\n");
+ dh && strstr(dh->dh_panic_string, "\n") ? "" : "\n");
tv.tv_sec = dh->dh_time.tv_sec;
lkcd_print(" dh_time: %s\n",
strip_linefeeds(ctime(&(tv.tv_sec))));
--
2.37.1

View File

@ -1,41 +0,0 @@
From 598377606649ee3cdcc1694d975bed27005612ee Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Wed, 16 Nov 2022 20:46:48 +0800
Subject: [PATCH 22/28] Fix for the invalid linux_banner pointer issue
Currently, crash may fail with the following error:
# ./crash -s vmlinux vmcore
WARNING: invalid linux_banner pointer: 65762078756e694c
crash: vmlinux and vmcore do not match!
The reason is that the type of the symbol in the data segment may be
defined as 'D' or 'd'. The crash only handled the type 'D', but it
didn't deal with the type 'd'. For example:
# nm vmlinux | grep linux_banner
ffffffff827cfa80 d linux_banner
It has been observed that a vmlinux compiled by clang has this type.
Let's add the type 'd' recognition to solve such issue.
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
kernel.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/kernel.c b/kernel.c
index bd0bf8c6cf03..2a1c1c391414 100644
--- a/kernel.c
+++ b/kernel.c
@@ -1060,6 +1060,7 @@ verify_version(void)
if (!(sp = symbol_search("linux_banner")))
error(FATAL, "linux_banner symbol does not exist?\n");
else if ((sp->type == 'R') || (sp->type == 'r') ||
+ (THIS_KERNEL_VERSION >= LINUX(2,6,11) && (sp->type == 'D' || sp->type == 'd')) ||
(machine_type("ARM") && sp->type == 'T') ||
(machine_type("ARM64")))
linux_banner = symbol_value("linux_banner");
--
2.37.1

View File

@ -1,57 +0,0 @@
From 488896b1ab0ca8bc4cc6aa608b6ee1744ae480e7 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Mon, 19 Sep 2022 17:49:21 +0800
Subject: [PATCH 23/28] Fix "kmem" failing to print task context when address
is vmalloced stack
When kernel enabled CONFIG_VMAP_STACK, stack can be allocated to
vmalloced area. Currently crash didn't handle the case, as a result,
"kmem" will not print the task context as expected. This patch fix the
bug by checking if the address is a vmalloced stack first.
Before:
crash> kmem ffffb7efce9bbe28
VMAP_AREA VM_STRUCT ADDRESS RANGE SIZE
ffff94eb9102c640 ffff94eb9102b140 ffffb7efce9b8000 - ffffb7efce9bd000 20480
PAGE PHYSICAL MAPPING INDEX CNT FLAGS
ffffdd28220dc000 1883700000 0 0 1 50000000000000
After:
crash> kmem ffffb7efce9bbe28
PID: 847
COMMAND: "khungtaskd"
TASK: ffff94f8038f4000 [THREAD_INFO: ffff94f8038f4000]
CPU: 72
STATE: TASK_RUNNING (PANIC)
VMAP_AREA VM_STRUCT ADDRESS RANGE SIZE
ffff94eb9102c640 ffff94eb9102b140 ffffb7efce9b8000 - ffffb7efce9bd000 20480
PAGE PHYSICAL MAPPING INDEX CNT FLAGS
ffffdd28220dc000 1883700000 0 0 1 50000000000000
Signed-off-by: Tao Liu <ltao@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
memory.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/memory.c b/memory.c
index a31a430e2823..e44b59d2e805 100644
--- a/memory.c
+++ b/memory.c
@@ -13477,6 +13477,10 @@ kmem_search(struct meminfo *mi)
* Check for a valid mapped address.
*/
if ((mi->memtype == KVADDR) && IS_VMALLOC_ADDR(mi->spec_addr)) {
+ if ((task = stkptr_to_task(vaddr)) && (tc = task_to_context(task))) {
+ show_context(tc);
+ fprintf(fp, "\n");
+ }
if (kvtop(NULL, mi->spec_addr, &paddr, 0)) {
mi->flags = orig_flags | VMLIST_VERIFY;
dump_vmlist(mi);
--
2.37.1

View File

@ -1,49 +0,0 @@
From d0726d96b92e5dacd1df56756e168a50a4e62589 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Mon, 19 Sep 2022 17:49:22 +0800
Subject: [PATCH 24/28] Fix page offset issue when converting physical to
virtual address
When trying to convert a physical address to its virtual
address in dump_vmap_area() and dump_vmlist(), the vi->retval
is added by 2 values: the page aligned address "pcheck"
and page offset address "PAGEOFFSET(paddr)".
However "paddr" is given by "pcheck", is also page aligned,
so "PAGEOFFSET(paddr)" is always 0.
In this patch, we will use PAGEOFFSET(vi->spec_addr) to give the
page offset, vi->spec_addr is the physical address we'd like
to convert, which contains the correct page offset.
Signed-off-by: Tao Liu <ltao@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
memory.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/memory.c b/memory.c
index e44b59d2e805..a60c3f9493f6 100644
--- a/memory.c
+++ b/memory.c
@@ -8861,7 +8861,7 @@ dump_vmlist(struct meminfo *vi)
(vi->spec_addr < (paddr+PAGESIZE()))) {
if (vi->flags & GET_PHYS_TO_VMALLOC) {
vi->retval = pcheck +
- PAGEOFFSET(paddr);
+ PAGEOFFSET(vi->spec_addr);
return;
} else
fprintf(fp,
@@ -9010,7 +9010,7 @@ dump_vmap_area(struct meminfo *vi)
(vi->spec_addr < (paddr+PAGESIZE()))) {
if (vi->flags & GET_PHYS_TO_VMALLOC) {
vi->retval = pcheck +
- PAGEOFFSET(paddr);
+ PAGEOFFSET(vi->spec_addr);
FREEBUF(ld->list_ptr);
return;
} else
--
2.37.1

View File

@ -1,76 +0,0 @@
From 74759e0e9736e86c7d2439bfe74ca5eb51b0a52b Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Mon, 19 Sep 2022 17:49:23 +0800
Subject: [PATCH 25/28] Let "kmem" print task context with physical address
Patch [1] enables "kmem" to print task context if the given virtual
address is a vmalloced stack.
This patch lets "kmem" print task context also when the given address
is a physical address.
Before:
crash> kmem 1883700e28
VMAP_AREA VM_STRUCT ADDRESS RANGE SIZE
ffff94eb9102c640 ffff94eb9102b140 ffffb7efce9b8000 - ffffb7efce9bd000 20480
PAGE PHYSICAL MAPPING INDEX CNT FLAGS
ffffdd28220dc000 1883700000 0 0 1 50000000000000
After:
crash> kmem 1883700e28
PID: 847
COMMAND: "khungtaskd"
TASK: ffff94f8038f4000 [THREAD_INFO: ffff94f8038f4000]
CPU: 72
STATE: TASK_RUNNING (PANIC)
VMAP_AREA VM_STRUCT ADDRESS RANGE SIZE
ffff94eb9102c640 ffff94eb9102b140 ffffb7efce9b8000 - ffffb7efce9bd000 20480
PAGE PHYSICAL MAPPING INDEX CNT FLAGS
ffffdd28220dc000 1883700000 0 0 1 50000000000000
[1]: https://listman.redhat.com/archives/crash-utility/2022-September/010115.html
[ kh: squashed the 4/4 patch into 3/4 ]
Signed-off-by: Tao Liu <ltao@redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
memory.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/memory.c b/memory.c
index a60c3f9493f6..ff6b571361eb 100644
--- a/memory.c
+++ b/memory.c
@@ -13506,6 +13506,10 @@ kmem_search(struct meminfo *mi)
mi->flags &= ~GET_PHYS_TO_VMALLOC;
if (mi->retval) {
+ if ((task = stkptr_to_task(mi->retval)) && (tc = task_to_context(task))) {
+ show_context(tc);
+ fprintf(fp, "\n");
+ }
if ((sp = value_search(mi->retval, &offset))) {
show_symbol(sp, offset,
SHOW_LINENUM | SHOW_RADIX());
@@ -13562,11 +13566,11 @@ kmem_search(struct meminfo *mi)
/*
* Check whether it's a current task or stack address.
*/
- if ((mi->memtype == KVADDR) && (task = vaddr_in_task_struct(vaddr)) &&
+ if ((mi->memtype & (KVADDR|PHYSADDR)) && (task = vaddr_in_task_struct(vaddr)) &&
(tc = task_to_context(task))) {
show_context(tc);
fprintf(fp, "\n");
- } else if ((mi->memtype == KVADDR) && (task = stkptr_to_task(vaddr)) &&
+ } else if ((mi->memtype & (KVADDR|PHYSADDR)) && (task = stkptr_to_task(vaddr)) &&
(tc = task_to_context(task))) {
show_context(tc);
fprintf(fp, "\n");
--
2.37.1

View File

@ -1,103 +0,0 @@
From edbd19bb260f7a98bc9e0b49fe2f0b8214885797 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Tue, 4 Oct 2022 18:57:11 +0800
Subject: [PATCH 26/28] ppc64: still allow to move on if the emergency stacks
info fails to initialize
Currently crash will fail and then exit, if the initialization of
the emergency stacks information fails. In real customer environments,
sometimes, a vmcore may be partially damaged, although such vmcores
are rare. For example:
# ./crash ../3.10.0-1127.18.2.el7.ppc64le/vmcore ../3.10.0-1127.18.2.el7.ppc64le/vmlinux -s
crash: invalid kernel virtual address: 38 type: "paca->emergency_sp"
#
Lets try to keep loading vmcore if such issues happen, so call
the readmem() with the RETURN_ON_ERROR instead of FAULT_ON_ERROR,
which allows the crash move on.
Reported-by: Dave Wysochanski <dwysocha@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
ppc64.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/ppc64.c b/ppc64.c
index 4ea1f7c0c6f8..b95a621d8fe4 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -1224,13 +1224,13 @@ ppc64_init_paca_info(void)
ulong paca_loc;
readmem(symbol_value("paca_ptrs"), KVADDR, &paca_loc, sizeof(void *),
- "paca double pointer", FAULT_ON_ERROR);
+ "paca double pointer", RETURN_ON_ERROR);
readmem(paca_loc, KVADDR, paca_ptr, sizeof(void *) * kt->cpus,
- "paca pointers", FAULT_ON_ERROR);
+ "paca pointers", RETURN_ON_ERROR);
} else if (symbol_exists("paca") &&
(get_symbol_type("paca", NULL, NULL) == TYPE_CODE_PTR)) {
readmem(symbol_value("paca"), KVADDR, paca_ptr, sizeof(void *) * kt->cpus,
- "paca pointers", FAULT_ON_ERROR);
+ "paca pointers", RETURN_ON_ERROR);
} else {
free(paca_ptr);
return;
@@ -1245,7 +1245,7 @@ ppc64_init_paca_info(void)
for (i = 0; i < kt->cpus; i++)
readmem(paca_ptr[i] + offset, KVADDR, &ms->emergency_sp[i],
sizeof(void *), "paca->emergency_sp",
- FAULT_ON_ERROR);
+ RETURN_ON_ERROR);
}
if (MEMBER_EXISTS("paca_struct", "nmi_emergency_sp")) {
@@ -1256,7 +1256,7 @@ ppc64_init_paca_info(void)
for (i = 0; i < kt->cpus; i++)
readmem(paca_ptr[i] + offset, KVADDR, &ms->nmi_emergency_sp[i],
sizeof(void *), "paca->nmi_emergency_sp",
- FAULT_ON_ERROR);
+ RETURN_ON_ERROR);
}
if (MEMBER_EXISTS("paca_struct", "mc_emergency_sp")) {
@@ -1267,7 +1267,7 @@ ppc64_init_paca_info(void)
for (i = 0; i < kt->cpus; i++)
readmem(paca_ptr[i] + offset, KVADDR, &ms->mc_emergency_sp[i],
sizeof(void *), "paca->mc_emergency_sp",
- FAULT_ON_ERROR);
+ RETURN_ON_ERROR);
}
free(paca_ptr);
@@ -1947,7 +1947,7 @@ ppc64_in_emergency_stack(int cpu, ulong addr, bool verbose)
if (cpu < 0 || cpu >= kt->cpus)
return NONE_STACK;
- if (ms->emergency_sp) {
+ if (ms->emergency_sp && IS_KVADDR(ms->emergency_sp[cpu])) {
top = ms->emergency_sp[cpu];
base = top - STACKSIZE();
if (addr >= base && addr < top) {
@@ -1957,7 +1957,7 @@ ppc64_in_emergency_stack(int cpu, ulong addr, bool verbose)
}
}
- if (ms->nmi_emergency_sp) {
+ if (ms->nmi_emergency_sp && IS_KVADDR(ms->nmi_emergency_sp[cpu])) {
top = ms->nmi_emergency_sp[cpu];
base = top - STACKSIZE();
if (addr >= base && addr < top) {
@@ -1967,7 +1967,7 @@ ppc64_in_emergency_stack(int cpu, ulong addr, bool verbose)
}
}
- if (ms->mc_emergency_sp) {
+ if (ms->mc_emergency_sp && IS_KVADDR(ms->mc_emergency_sp[cpu])) {
top = ms->mc_emergency_sp[cpu];
base = top - STACKSIZE();
if (addr >= base && addr < top) {
--
2.37.1

View File

@ -1,39 +0,0 @@
From cdcf2d3f4c69ffa8a29b70120ee4fca6e390123b Mon Sep 17 00:00:00 2001
From: Matias Ezequiel Vara Larsen <matiasevara@gmail.com>
Date: Mon, 24 Oct 2022 11:35:29 +0200
Subject: [PATCH 27/28] Fix segmentation fault in
page_flags_init_from_pageflag_names()
When read_string() fails in page_flags_init_from_pageflag_names(),
error() dereferences the name variable to print the string that the
variable points to. However, name points to a string that is not in
crash's memory-space thus triggering a segmentation fault.
This patch replaces "%s" in the error message with "%lx" so the address
is printed instead. Also replaces "%ld" for mask with "%lx".
[ kh: changed the conversion specifiers and commit message ]
Signed-off-by: Matias Ezequiel Vara Larsen <matias.vara@vates.fr>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
memory.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/memory.c b/memory.c
index ff6b571361eb..ddbf458277f0 100644
--- a/memory.c
+++ b/memory.c
@@ -6599,7 +6599,7 @@ page_flags_init_from_pageflag_names(void)
}
if (!read_string((ulong)name, namebuf, BUFSIZE-1)) {
- error(INFO, "failed to read pageflag_names entry (i: %d name: \"%s\" mask: %ld)\n",
+ error(INFO, "failed to read pageflag_names entry (i: %d name: %lx mask: %lx)\n",
i, name, mask);
goto pageflags_fail;
}
--
2.37.1

View File

@ -1,86 +0,0 @@
From 74fe453f2b5ddf1e1571d006d486cb214817a0ed Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Wed, 9 Nov 2022 14:21:57 +0800
Subject: [PATCH 28/28] Fix for "ps/vm" commands to display correct %MEM and
RSS values
The ps/vm commands may print the bogus value of the %MEM and RSS, the
reason is that the counter of rss stat is updated in asynchronous manner
and may become negative, when the SPLIT_RSS_COUNTING is enabled in kernel.
As a result, crash will read it from memory and convert from negative to
unsigned long integer, eventually it overflows and gets a big integer. For
example:
crash> ps 1393
PID PPID CPU TASK ST %MEM VSZ RSS COMM
1393 1 24 ffff9584bb542100 RU 541298032135.9 4132 18014398509481908 enlinuxpc64
^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
This is unexpected, crash needs to correct its value for this case.
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
memory.c | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/memory.c b/memory.c
index ddbf458277f0..2167281b6039 100644
--- a/memory.c
+++ b/memory.c
@@ -4714,18 +4714,29 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
* Latest kernels have mm_struct.mm_rss_stat[].
*/
if (VALID_MEMBER(mm_struct_rss_stat)) {
- long anonpages, filepages;
+ long anonpages, filepages, count;
anonpages = tt->anonpages;
filepages = tt->filepages;
- rss += LONG(tt->mm_struct +
+ count = LONG(tt->mm_struct +
OFFSET(mm_struct_rss_stat) +
OFFSET(mm_rss_stat_count) +
(filepages * sizeof(long)));
- rss += LONG(tt->mm_struct +
+
+ /*
+ * The counter is updated in asynchronous manner
+ * and may become negative, see:
+ * include/linux/mm.h: get_mm_counter()
+ */
+ if (count > 0)
+ rss += count;
+
+ count = LONG(tt->mm_struct +
OFFSET(mm_struct_rss_stat) +
OFFSET(mm_rss_stat_count) +
(anonpages * sizeof(long)));
+ if (count > 0)
+ rss += count;
}
/* Check whether SPLIT_RSS_COUNTING is enabled */
@@ -4769,7 +4780,8 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
RETURN_ON_ERROR))
continue;
- rss_cache += sync_rss;
+ if (sync_rss > 0)
+ rss_cache += sync_rss;
/* count 1 -> anonpages */
if (!readmem(first->task +
@@ -4782,7 +4794,8 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
RETURN_ON_ERROR))
continue;
- rss_cache += sync_rss;
+ if (sync_rss > 0)
+ rss_cache += sync_rss;
if (first == last)
break;
--
2.37.1

View File

@ -1,6 +1,6 @@
--- crash-7.3.2/Makefile.orig
+++ crash-7.3.2/Makefile
@@ -201,7 +201,7 @@ GDB_FLAGS=
--- crash-8.0.4/Makefile.orig
+++ crash-8.0.4/Makefile
@@ -204,7 +204,7 @@ GDB_FLAGS=
# TARGET_CFLAGS will be configured automatically by configure
TARGET_CFLAGS=
@ -9,18 +9,18 @@
GPL_FILES=
TAR_FILES=${SOURCE_FILES} Makefile ${GPL_FILES} README .rh_rpm_package crash.8 \
@@ -253,7 +253,7 @@ all: make_configure
@@ -256,7 +256,7 @@ all: make_configure
gdb_merge: force
@if [ ! -f ${GDB}/README ]; then \
$(MAKE) gdb_unzip; fi
- @echo "${LDFLAGS} -lz -llzo2 -lsnappy -lzstd -ldl -rdynamic" > ${GDB}/gdb/mergelibs
+ @echo "${LDFLAGS} -lz -llzo2 -lsnappy -lzstd -ldl -rdynamic -Wl,-z,now -fpie" > ${GDB}/gdb/mergelibs
+ @echo "${LDFLAGS} -lz -llzo2 -lsnappy -lzstd -ldl -rdynamic -Wl,-z,now -fPIE" > ${GDB}/gdb/mergelibs
@echo "../../${PROGRAM} ../../${PROGRAM}lib.a" > ${GDB}/gdb/mergeobj
@rm -f ${PROGRAM}
@if [ ! -f ${GDB}/config.status ]; then \
--- crash-7.3.2/configure.c.orig
+++ crash-7.3.2/configure.c
@@ -800,7 +800,8 @@ build_configure(struct supported_gdb_version *sp)
--- crash-8.0.4/configure.c.orig
+++ crash-8.0.4/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]);
} else if (strncmp(buf, "LDFLAGS=", strlen("LDFLAGS=")) == 0) {
@ -30,4 +30,4 @@
} else
fprintf(fp2, "%s", buf);
--

View File

@ -1,6 +1,6 @@
--- crash-7.3.2/Makefile.orig
+++ crash-7.3.2/Makefile
@@ -253,7 +253,7 @@ all: make_configure
--- crash-8.0.4/Makefile.orig
+++ crash-8.0.4/Makefile
@@ -256,7 +256,7 @@ all: make_configure
gdb_merge: force
@if [ ! -f ${GDB}/README ]; then \
$(MAKE) gdb_unzip; fi
@ -9,8 +9,8 @@
@echo "../../${PROGRAM} ../../${PROGRAM}lib.a" > ${GDB}/gdb/mergeobj
@rm -f ${PROGRAM}
@if [ ! -f ${GDB}/config.status ]; then \
--- crash-7.3.2/diskdump.c.orig
+++ crash-7.3.2/diskdump.c
--- crash-8.0.4/diskdump.c.orig
+++ crash-8.0.4/diskdump.c
@@ -23,6 +23,9 @@
* GNU General Public License for more details.
*/
@ -21,4 +21,3 @@
#include "defs.h"
#include "diskdump.h"
#include "xen_dom0.h"
--

View File

@ -1,16 +0,0 @@
--- crash-7.3.2/memory.c.orig
+++ crash-7.3.2/memory.c
@@ -19412,9 +19412,8 @@ freelist_ptr(struct meminfo *si, ulong ptr, ulong ptr_addr)
if (VALID_MEMBER(kmem_cache_random)) {
/* CONFIG_SLAB_FREELIST_HARDENED */
- if (THIS_KERNEL_VERSION >= LINUX(5,7,0))
- ptr_addr = (sizeof(long) == 8) ? bswap_64(ptr_addr)
- : bswap_32(ptr_addr);
+ ptr_addr = (sizeof(long) == 8) ? bswap_64(ptr_addr)
+ : bswap_32(ptr_addr);
return (ptr ^ si->random ^ ptr_addr);
} else
return ptr;
--
fix freepointer issue

View File

@ -3,71 +3,41 @@
#
Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles
Name: crash
Version: 7.3.2
Release: 4%{?dist}
Version: 8.0.4
Release: 2%{?dist}.alma
License: GPLv3
Group: Development/Debuggers
Source0: https://github.com/crash-utility/crash/archive/crash-%{version}.tar.gz
Source1: http://ftp.gnu.org/gnu/gdb/gdb-7.6.tar.gz
Source1: http://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.gz
URL: https://crash-utility.github.io
ExclusiveOS: Linux
ExclusiveArch: %{ix86} ia64 x86_64 ppc ppc64 s390 s390x %{arm} aarch64 ppc64le
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot-%(%{__id_u} -n)
BuildRequires: ncurses-devel zlib-devel lzo-devel bison snappy-devel wget patch libzstd-devel
BuildRequires: ncurses-devel zlib-devel lzo-devel bison snappy-devel wget patch texinfo libzstd-devel
BuildRequires: gcc gcc-c++ make
Requires: binutils
Provides: bundled(gdb) = 7.6
Provides: bundled(libiberty)
Provides: bundled(gdb) = 10.2
Patch0: lzo_snappy_zstd.patch
Patch1: rhel8_build.patch
Patch2: rhel8_freepointer.patch
Patch3: 0001-ppc64-update-the-NR_CPUS-to-8192.patch
Patch4: 0002-sbitmapq-remove-struct-and-member-validation-in-sbit.patch
Patch5: 0003-sbitmapq-fix-invalid-offset-for-sbitmap_queue_alloc_.patch
Patch6: 0004-sbitmapq-fix-invalid-offset-for-sbitmap_queue_round_.patch
Patch7: 0005-sbitmapq-fix-invalid-offset-for-sbitmap_word_depth-o.patch
Patch8: 0007-bt-x86_64-filter-out-idle-task-stack.patch
Patch9: 0008-bt-arm64-add-support-for-bt-n-idle.patch
Patch10: 0010-Enhance-dev-d-D-options-to-support-blk-mq-sbitmap.patch
Patch11: 0011-Fix-for-dev-d-D-options-to-support-blk-mq-change-on-.patch
Patch12: 0012-Doc-update-man-page-for-the-bpf-and-sbitmapq-command.patch
Patch13: 0013-sbitmapq-Fix-for-sbitmap_queue-without-ws_active-mem.patch
Patch14: 0014-sbitmapq-Fix-for-sbitmap_word-without-cleared-member.patch
Patch15: 0015-sbitmapq-Fix-for-sbitmap_queue-without-min_shallow_d.patch
Patch16: 0016-Make-dev-d-D-options-parse-sbitmap-on-Linux-4.18-and.patch
Patch17: 0017-sbitmapq-Fix-for-kernels-without-struct-wait_queue_h.patch
Patch18: 0018-sbitmapq-Limit-kernels-without-sbitmap-again.patch
Patch19: 0001-Fix-for-dev-command-on-Linux-5.11-and-later.patch
Patch20: 0002-Extend-field-length-of-task-attributes.patch
Patch21: 0003-ppc64-fix-bt-for-S-case.patch
Patch22: 0004-ppc64-dynamically-allocate-h-w-interrupt-stack.patch
Patch23: 0005-ppc64-rename-ppc64_paca_init-to-ppc64_paca_percpu_of.patch
Patch24: 0006-ppc64-handle-backtrace-when-CPU-is-in-an-emergency-s.patch
Patch25: 0007-ppc64-print-emergency-stacks-info-with-mach-command.patch
Patch26: 0008-ppc64-use-a-variable-for-machdep-machspec.patch
Patch27: 0009-arm64-Fix-for-st-_stext_vmlinux-not-initialized-when.patch
Patch28: 0010-Fix-gcc-11-compiler-warnings-on-filesys.c.patch
Patch29: 0011-Fix-gcc-11-compiler-warning-on-symbols.c.patch
Patch30: 0012-Fix-gcc-11-compiler-warning-on-makedumpfile.c.patch
Patch31: 0013-Fix-gcc-11-compiler-warning-on-kvmdump.c.patch
Patch32: 0014-x86_64-Fix-for-AMD-SME-issue.patch
Patch33: 0015-Makefile-Fix-unnecessary-re-patching-with-coreutils-.patch
Patch34: 0016-arm64-use-TCR_EL1_T1SZ-to-get-the-correct-info-if-va.patch
Patch35: 0017-Fix-task-R-by-adding-end-identifier-for-union-in-tas.patch
Patch36: 0018-Let-gdb-get-kernel-module-symbols-info-from-crash.patch
Patch37: 0019-x86_64-Correct-the-identifier-when-locating-the-call.patch
Patch38: 0020-Add-debian-ubuntu-vmlinux-location-to-default-search.patch
Patch39: 0021-Fix-gcc-12-compiler-warnings-on-lkcd_-.c.patch
Patch40: 0022-Fix-for-the-invalid-linux_banner-pointer-issue.patch
Patch41: 0023-Fix-kmem-failing-to-print-task-context-when-address-.patch
Patch42: 0024-Fix-page-offset-issue-when-converting-physical-to-vi.patch
Patch43: 0025-Let-kmem-print-task-context-with-physical-address.patch
Patch44: 0026-ppc64-still-allow-to-move-on-if-the-emergency-stacks.patch
Patch45: 0027-Fix-segmentation-fault-in-page_flags_init_from_pagef.patch
Patch46: 0028-Fix-for-ps-vm-commands-to-display-correct-MEM-and-RS.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
%description
The core analysis suite is a self-contained tool that can be used to
investigate either live systems, kernel core dumps created from the
netdump, diskdump and kdump packages from Red Hat Linux, the mcore kernel patch
netdump, diskdump and kdump packages from AlmaLinux, the mcore kernel patch
offered by Mission Critical Linux, or the LKCD kernel patch.
%package devel
@ -78,68 +48,36 @@ Group: Development/Debuggers
%description devel
The core analysis suite is a self-contained tool that can be used to
investigate either live systems, kernel core dumps created from the
netdump, diskdump and kdump packages from Red Hat Linux, the mcore kernel patch
netdump, diskdump and kdump packages from AlmaLinux, the mcore kernel patch
offered by Mission Critical Linux, or the LKCD kernel patch.
%prep
%setup -n %{name}-%{version} -q
%patch0 -p1 -b lzo_snappy_zstd.patch
%patch1 -p1 -b rhel8_build.patch
%patch2 -p1 -b rhel8_freepointer.patch
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1
%patch31 -p1
%patch32 -p1
%patch33 -p1
%patch34 -p1
%patch35 -p1
%patch36 -p1
%patch37 -p1
%patch38 -p1
%patch39 -p1
%patch40 -p1
%patch41 -p1
%patch42 -p1
%patch43 -p1
%patch44 -p1
%patch45 -p1
%patch46 -p1
%patch -P 0 -p1 -b lzo_snappy_zstd.patch
%patch -P 1 -p1 -b crash-8.0.4_build.patch
%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
%build
cp %{SOURCE1} .
#make RPMPKG="%{version}-%{release}" CFLAGS="%{optflags}"
make -j`nproc` RPMPKG="%{version}-%{release}" CFLAGS="%{optflags}" LDFLAGS="%{build_ldflags}"
make -j`nproc` RPMPKG="%{version}-%{release}" CFLAGS="%{optflags}" CXXFLAGS="%{optflags}" LDFLAGS="%{build_ldflags}"
%install
rm -rf %{buildroot}
mkdir -p %{buildroot}%{_bindir}
make DESTDIR=%{buildroot} install
%make_install
mkdir -p %{buildroot}%{_mandir}/man8
cp -p crash.8 %{buildroot}%{_mandir}/man8/crash.8
mkdir -p %{buildroot}%{_includedir}/crash
@ -150,25 +88,48 @@ cp -p defs.h %{buildroot}%{_includedir}/crash
rm -rf %{buildroot}
%files
%defattr(-,root,root,-)
%{_bindir}/crash
%{_mandir}/man8/crash.8*
%doc README COPYING3
%files devel
%defattr(-,root,root,-)
%{_includedir}/*
%changelog
* Wed Mar 27 2024 Eduard Abdullin <eabdullin@almalinux.org> - 8.0.4-2.alma
- AlmaLinux changes
* Tue Jan 02 2024 Lianbo Jiang <lijiang@redhat.com> - 8.0.4-2
- Fix the "dis -lr" not displaying the source file names
and line numbers
- Fix incorrect symbol translation by the 'struct blk_mq_ops'
* Fri Nov 17 2023 Lianbo Jiang <lijiang@redhat.com> - 8.0.4-1
- Rebase to upstream crash 8.0.4
* Thu Sep 07 2023 Lianbo Jiang <lijiang@redhat.com> - 8.0.3-1
- Rebase to upstream crash-utility 8.0.3
- Backport the latest patches from upstream crash-utility
* Thu Jun 15 2023 Lianbo Jiang <lijiang@redhat.com> - 7.3.2-8
- arm64: Fix again segfault in arm64_is_kernel_exception_frame()
- Fix invalid structure size error during crash startup on ppc64
* Wed Jun 07 2023 Lianbo Jiang <lijiang@redhat.com> - 7.3.2-7
- Fix segfault caused by failure of stopping CPUs
* Mon May 08 2023 Lianbo Jiang <lijiang@redhat.com> - 7.3.2-6
- Fix for freelist pointer on PPC64le, ARM64 and S390x
* Mon May 08 2023 Lianbo Jiang <lijiang@redhat.com> - 7.3.2-5
- Update to the latest upstream commit 47216437e79a
- ("Fix "net" command on kernel configured with CONFIG_IPV6=m")
* Mon Nov 21 2022 Lianbo Jiang <lijiang@redhat.com> - 7.3.2-4
- Fix for commit 2145b2bb79c5, there are different behaviors between gdb-7.6 and gdb-10.2
* Thu Nov 17 2022 Lianbo Jiang <lijiang@redhat.com> - 7.3.2-3
- Update to the latest commit a158590f475c from master branch
* Thu Jun 16 2022 Lianbo Jiang <lijiang@redhat.com> - 7.3.2-2
- Enhance "dev -d|-D" options to support blk-mq sbitmap
* Mon May 16 2022 Lianbo Jiang <lijiang@redhat.com> - 7.3.2-1
- Rebase to upstream crash 7.3.2