Compare commits

...

9 Commits

Author SHA1 Message Date
eabdullin 2a3aec2e2a Import from AlmaLinux stable repository 2024-05-31 17:33:05 +00:00
CentOS Sources 02c0380c05 import crash-7.3.2-4.el8 2023-05-16 06:08:25 +00:00
CentOS Sources 4a1f8b44fb import crash-7.3.2-2.el8 2022-11-08 12:07:29 +00:00
CentOS Sources 1365ff98ac import crash-7.3.1-5.el8 2022-05-10 07:38:34 +00:00
CentOS Sources b3156befab import crash-7.3.0-2.el8 2021-11-09 09:52:56 +00:00
CentOS Sources f2865a0179 import crash-7.2.9-2.el8 2021-05-18 02:45:16 -04:00
CentOS Sources 17cf870a7d import crash-7.2.8-7.el8 2020-11-03 07:07:52 -05:00
CentOS Sources 145e277e6d import crash-7.2.7-3.el8 2020-04-28 04:50:30 -04:00
CentOS Sources bc6356dc5c import crash-7.2.6-2.el8 2019-11-05 14:04:53 -05:00
41 changed files with 1938 additions and 5257 deletions

View File

@ -1 +0,0 @@
1a9fa8cd6869da42314ec47df6a750e053f4bece SOURCES/crash-7.2.3.tar.gz

3
.gitignore vendored
View File

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

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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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,32 +1,33 @@
--- crash-7.2.3/Makefile.orig
+++ crash-7.2.3/Makefile
@@ -198,7 +198,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=
-CRASH_CFLAGS=-g -D${TARGET} ${TARGET_CFLAGS} ${GDB_FLAGS} ${CFLAGS}
+CRASH_CFLAGS=-g -D${TARGET} ${TARGET_CFLAGS} ${GDB_FLAGS} ${CFLAGS} ${CPPFLAGS} -fPIE
GPL_FILES=COPYING3
GPL_FILES=
TAR_FILES=${SOURCE_FILES} Makefile ${GPL_FILES} README .rh_rpm_package crash.8 \
@@ -228,7 +228,7 @@ all: make_configure
@@ -256,7 +256,7 @@ all: make_configure
gdb_merge: force
@if [ ! -f ${GDB}/README ]; then \
make --no-print-directory gdb_unzip; fi
- @echo "${LDFLAGS} -lz -llzo2 -lsnappy -ldl -rdynamic" > ${GDB}/gdb/mergelibs
+ @echo "${LDFLAGS} -lz -llzo2 -lsnappy -ldl -rdynamic -Wl,-z,now -fpie" > ${GDB}/gdb/mergelibs
$(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 "../../${PROGRAM} ../../${PROGRAM}lib.a" > ${GDB}/gdb/mergeobj
@rm -f ${PROGRAM}
@if [ ! -f ${GDB}/config.status ]; then \
--- crash-7.2.3/configure.c.orig
+++ crash-7.2.3/configure.c
@@ -780,7 +780,8 @@ build_configure(struct supported_gdb_ver
--- 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) {
- fprintf(fp2, "LDFLAGS=%s\n", ldflags ? ldflags : "");
+ if (ldflags)
+ fprintf(fp2, "LDFLAGS=%s\n", ldflags ? ldflags : "");
+ fprintf(fp2, "LDFLAGS=%s\n", ldflags ? ldflags : "");
} else
fprintf(fp2, "%s", buf);

View File

@ -1,154 +0,0 @@
commit 0f65ae0c36bf04e22219f28c32c3ae0cdee5acfe
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Dec 7 15:17:37 2018 -0500
Implemented a new plugin function for the readline library's tab
completion feature. Without the patch, the use of the default plugin
from the embedded gdb module has been seen to cause segmentation
violations or other fatal malloc/free/corruption assertions. The new
plugin takes gdb out of the picture entirely, and also restricts the
matching options to just symbol names, so as not to clutter the
results with irrelevant filenames.
(anderson@redhat.com)
diff --git a/cmdline.c b/cmdline.c
index cf3e150..665f48c 100644
--- a/cmdline.c
+++ b/cmdline.c
@@ -40,6 +40,8 @@ int shell_command(char *);
static void modify_orig_line(char *, struct args_input_file *);
static void modify_expression_arg(char *, char **, struct args_input_file *);
static int verify_args_input_file(char *);
+static char *crash_readline_completion_generator(const char *, int);
+static char **crash_readline_completer(const char *, int, int);
#define READLINE_LIBRARY
@@ -2073,6 +2075,9 @@ readline_init(void)
if (STREQ(pc->editing_mode, "emacs")) {
rl_editing_mode = emacs_mode;
}
+
+ rl_attempted_completion_function = crash_readline_completer;
+ rl_attempted_completion_over = 1;
}
/*
@@ -2610,3 +2615,27 @@ exec_args_input_file(struct command_table_entry *ct, struct args_input_file *aif
fclose(pc->args_ifile);
pc->args_ifile = NULL;
}
+
+static char *
+crash_readline_completion_generator(const char *match, int state)
+{
+ static struct syment *sp_match;
+
+ if (state == 0)
+ sp_match = NULL;
+
+ sp_match = symbol_complete_match(match, sp_match);
+
+ if (sp_match)
+ return(strdup(sp_match->name));
+ else
+ return NULL;
+}
+
+static char **
+crash_readline_completer(const char *match, int start, int end)
+{
+ rl_attempted_completion_over = 1;
+ return rl_completion_matches(match, crash_readline_completion_generator);
+}
+
diff --git a/defs.h b/defs.h
index 9ce32c1..a3cb5a4 100644
--- a/defs.h
+++ b/defs.h
@@ -5153,6 +5153,7 @@ void parse_for_member_extended(struct datatype_member *, ulong);
void add_to_downsized(char *);
int is_downsized(char *);
int is_string(char *, char *);
+struct syment *symbol_complete_match(const char *, struct syment *);
/*
* memory.c
diff --git a/symbols.c b/symbols.c
index 05628ff..0769294 100644
--- a/symbols.c
+++ b/symbols.c
@@ -13108,3 +13108,73 @@ is_downsized(char *name)
return FALSE;
}
+
+struct syment *
+symbol_complete_match(const char *match, struct syment *sp_last)
+{
+ int i;
+ struct syment *sp, *sp_end, *sp_start;
+ struct load_module *lm;
+ int search_init;
+
+ if (sp_last) {
+ sp_start = next_symbol(NULL, sp_last);
+ if (!sp_start)
+ return NULL;
+ } else
+ sp_start = st->symtable;
+
+ if ((sp_start >= st->symtable) && (sp_start < st->symend)) {
+ for (sp = sp_start; sp < st->symend; sp++) {
+ if (STRNEQ(sp->name, match))
+ return sp;
+ }
+ sp_start = NULL;
+ }
+
+ search_init = FALSE;
+
+ for (i = 0; i < st->mods_installed; i++) {
+ lm = &st->load_modules[i];
+ if (lm->mod_flags & MOD_INIT)
+ search_init = TRUE;
+ sp_end = lm->mod_symend;
+ if (!sp_start)
+ sp_start = lm->mod_symtable;
+
+ if ((sp_start >= lm->mod_symtable) && (sp_start < sp_end)) {
+ for (sp = sp_start; sp < sp_end; sp++) {
+ if (MODULE_START(sp))
+ continue;
+
+ if (STRNEQ(sp->name, match))
+ return sp;
+ }
+ sp_start = NULL;
+ }
+ }
+
+ if (!search_init)
+ return NULL;
+
+ for (i = 0; i < st->mods_installed; i++) {
+ lm = &st->load_modules[i];
+ if (!lm->mod_init_symtable)
+ continue;
+ sp_end = lm->mod_init_symend;
+ if (!sp_start)
+ sp_start = lm->mod_init_symtable;
+
+ if ((sp_start >= lm->mod_init_symtable) && (sp_start < sp_end)) {
+ for (sp = sp_start; sp < sp_end; sp++) {
+ if (MODULE_START(sp))
+ continue;
+
+ if (STRNEQ(sp->name, match))
+ return sp;
+ }
+ }
+ }
+
+ return NULL;
+}

View File

@ -1,27 +0,0 @@
commit 1926150ee350e17fee2aeabb8ef781222d94366e
Author: Dave Anderson <anderson@redhat.com>
Date: Mon Jun 11 13:46:41 2018 -0400
Fix for the ppc64/ppc64le "bt" command on Linux 4.7 and later kernels
that contain commit d8bff643d81a58181356c0aa3ab771ac10da6894,
titled "[x86] asm: Make sure verify_cpu() has a good stack", which
inadvertently breaks the ppc64/ppc64le kernel stack size calculation
when running with crash-7.2.2 or later. Without the patch, "bt" may
fail with a filtered kdump dumpfile with the two error messages
"bt: page excluded: kernel virtual address: <address> type: stack
contents" and "bt: read of stack at <address> failed".
(anderson@redhat.com)
diff --git a/task.c b/task.c
index f6956d5..1b32629 100644
--- a/task.c
+++ b/task.c
@@ -440,7 +440,7 @@ task_init(void)
} else if (VALID_SIZE(thread_union) &&
((len = SIZE(thread_union)) != STACKSIZE())) {
machdep->stacksize = len;
- } else {
+ } else if (!VALID_SIZE(thread_union) && !VALID_SIZE(task_union)) {
if (kernel_symbol_exists("__start_init_task") &&
kernel_symbol_exists("__end_init_task")) {
len = symbol_value("__end_init_task");

View File

@ -1,412 +0,0 @@
commit 27a6ebd0cda386b1dfb7b0fffb4d8b489b391ccf
Author: Dave Anderson <anderson@redhat.com>
Date: Mon Sep 24 16:33:57 2018 -0400
Resurrection of the the "dev -p" option for displaying PCI device
data on Linux 2.6.26 and later kernels. The option was deprecated
as of Linux 2.6.26, and without the patch, the option would indicate
"dev: -p option not supported or applicable on this architecture
or kernel" when running against the newer kernel versions. PCI Bus
information will also be displayed with this patch.
(m.mizuma@jp.fujitsu.com)
diff --git a/defs.h b/defs.h
index d6492c5..80c61ef 100644
--- a/defs.h
+++ b/defs.h
@@ -2032,6 +2032,17 @@ struct offset_table {
long bpf_prog_aux_user;
long user_struct_uid;
long idr_cur;
+ long pci_dev_dev;
+ long pci_dev_hdr_type;
+ long pci_dev_pcie_flags_reg;
+ long pci_bus_node;
+ long pci_bus_devices;
+ long pci_bus_dev;
+ long pci_bus_children;
+ long pci_bus_parent;
+ long pci_bus_self;
+ long device_kobj;
+ long kobject_name;
};
struct size_table { /* stash of commonly-used sizes */
diff --git a/dev.c b/dev.c
index 3db898a..7ce2422 100644
--- a/dev.c
+++ b/dev.c
@@ -24,6 +24,7 @@ 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 void do_pci(void);
+static void do_pci2(void);
static void do_io(void);
static void do_resource_list(ulong, char *, int);
@@ -51,11 +52,23 @@ dev_init(void)
MEMBER_OFFSET_INIT(pci_dev_global_list, "pci_dev", "global_list");
MEMBER_OFFSET_INIT(pci_dev_next, "pci_dev", "next");
MEMBER_OFFSET_INIT(pci_dev_bus, "pci_dev", "bus");
+ MEMBER_OFFSET_INIT(pci_dev_dev, "pci_dev", "dev");
MEMBER_OFFSET_INIT(pci_dev_devfn, "pci_dev", "devfn");
MEMBER_OFFSET_INIT(pci_dev_class, "pci_dev", "class");
MEMBER_OFFSET_INIT(pci_dev_device, "pci_dev", "device");
+ MEMBER_OFFSET_INIT(pci_dev_hdr_type, "pci_dev", "hdr_type");
+ MEMBER_OFFSET_INIT(pci_dev_pcie_flags_reg, "pci_dev", "pcie_flags_reg");
MEMBER_OFFSET_INIT(pci_dev_vendor, "pci_dev", "vendor");
MEMBER_OFFSET_INIT(pci_bus_number, "pci_bus", "number");
+ MEMBER_OFFSET_INIT(pci_bus_node, "pci_bus", "node");
+ MEMBER_OFFSET_INIT(pci_bus_devices, "pci_bus", "devices");
+ MEMBER_OFFSET_INIT(pci_bus_dev, "pci_bus", "dev");
+ MEMBER_OFFSET_INIT(pci_bus_children, "pci_bus", "children");
+ MEMBER_OFFSET_INIT(pci_bus_parent, "pci_bus", "parent");
+ MEMBER_OFFSET_INIT(pci_bus_self, "pci_bus", "self");
+
+ MEMBER_OFFSET_INIT(device_kobj, "device", "kobj");
+ MEMBER_OFFSET_INIT(kobject_name, "kobject", "name");
STRUCT_SIZE_INIT(resource, "resource");
if ((VALID_STRUCT(resource) && symbol_exists("do_resource_list")) ||
@@ -114,10 +127,14 @@ cmd_dev(void)
return;
case 'p':
- if (machine_type("S390X") ||
- (THIS_KERNEL_VERSION >= LINUX(2,6,26)))
+ if (machine_type("S390X"))
+ option_not_supported(c);
+ if (symbol_exists("pci_devices"))
+ do_pci();
+ else if (symbol_exists("pci_root_buses"))
+ do_pci2();
+ else
option_not_supported(c);
- do_pci();
return;
default:
@@ -2217,6 +2234,313 @@ do_resource_list(ulong first_entry, char *resource_buf, int size)
#endif /* USE_2_2_17_PCI_H */
+#define PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */
+#define PCI_EXP_TYPE_ENDPOINT 0x0 /* Express Endpoint */
+#define PCI_EXP_TYPE_LEG_END 0x1 /* Legacy Endpoint */
+#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */
+#define PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */
+#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */
+#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCIe to PCI/PCI-X Bridge */
+#define PCI_EXP_TYPE_PCIE_BRIDGE 0x8 /* PCI/PCI-X to PCIe Bridge */
+#define PCI_EXP_TYPE_RC_END 0x9 /* Root Complex Integrated Endpoint */
+#define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */
+
+static void
+fill_dev_name(ulong pci_dev, char *name)
+{
+ ulong kobj, value;
+
+ memset(name, 0, sizeof(*name) * BUFSIZE);
+
+ kobj = pci_dev + OFFSET(pci_dev_dev) + OFFSET(device_kobj);
+
+ readmem(kobj + OFFSET(kobject_name),
+ KVADDR, &value, sizeof(void *), "kobject name",
+ FAULT_ON_ERROR);
+
+ read_string(value, name, BUFSIZE-1);
+}
+
+static void
+fill_bus_name(ulong pci_bus, char *name)
+{
+ ulong kobj, value;
+
+ memset(name, 0, sizeof(*name) * BUFSIZE);
+
+ kobj = pci_bus + OFFSET(pci_bus_dev) + OFFSET(device_kobj);
+
+ readmem(kobj + OFFSET(kobject_name),
+ KVADDR, &value, sizeof(void *), "kobject name",
+ FAULT_ON_ERROR);
+
+ read_string(value, name, BUFSIZE-1);
+}
+
+static void
+fill_dev_id(ulong pci_dev, char *id)
+{
+ unsigned short device, vendor;
+
+ memset(id, 0, sizeof(*id) * BUFSIZE);
+
+ readmem(pci_dev + OFFSET(pci_dev_device),
+ KVADDR, &device, sizeof(short), "pci dev device",
+ FAULT_ON_ERROR);
+ readmem(pci_dev + OFFSET(pci_dev_vendor), KVADDR,
+ &vendor, sizeof(short), "pci dev vendor", FAULT_ON_ERROR);
+
+ sprintf(id, "%x:%x", vendor, device);
+}
+
+static void
+fill_dev_class(ulong pci_dev, char *c)
+{
+ unsigned int class;
+
+ memset(c, 0, sizeof(*c) * BUFSIZE);
+ readmem(pci_dev + OFFSET(pci_dev_class), KVADDR,
+ &class, sizeof(int), "pci class", FAULT_ON_ERROR);
+
+ class >>= 8;
+
+ sprintf(c, "%04x", class);
+}
+
+static int
+pci_pcie_type(ulong cap)
+{
+ return (cap & PCI_EXP_FLAGS_TYPE) >> 4;
+}
+
+static int
+pci_is_bridge(unsigned char hdr_type)
+{
+ return hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+ hdr_type == PCI_HEADER_TYPE_CARDBUS;
+}
+
+static void
+fill_pcie_type(ulong pcidev, char *t)
+{
+ int type, bufidx = 0;
+ unsigned short pciecap;
+ unsigned char hdr_type;
+
+ memset(t, 0, sizeof(*t) * BUFSIZE);
+
+ readmem(pcidev + OFFSET(pci_dev_hdr_type), KVADDR, &hdr_type,
+ sizeof(char), "pci dev hdr_type", FAULT_ON_ERROR);
+
+ if (!VALID_MEMBER(pci_dev_pcie_flags_reg))
+ goto bridge_chk;
+
+ readmem(pcidev + OFFSET(pci_dev_pcie_flags_reg), KVADDR, &pciecap,
+ sizeof(unsigned short), "pci dev pcie_flags_reg", FAULT_ON_ERROR);
+
+ type = pci_pcie_type(pciecap);
+
+ if (type == PCI_EXP_TYPE_ENDPOINT)
+ bufidx = sprintf(t, "ENDPOINT");
+ else if (type == PCI_EXP_TYPE_LEG_END)
+ bufidx = sprintf(t, "LEG_END");
+ else if (type == PCI_EXP_TYPE_ROOT_PORT)
+ bufidx = sprintf(t, "ROOT_PORT");
+ else if (type == PCI_EXP_TYPE_UPSTREAM)
+ bufidx = sprintf(t, "UPSTREAM");
+ else if (type == PCI_EXP_TYPE_DOWNSTREAM)
+ bufidx = sprintf(t, "DOWNSTREAM");
+ else if (type == PCI_EXP_TYPE_PCI_BRIDGE)
+ bufidx = sprintf(t, "PCI_BRIDGE");
+ else if (type == PCI_EXP_TYPE_PCIE_BRIDGE)
+ bufidx = sprintf(t, "PCIE_BRIDGE");
+ else if (type == PCI_EXP_TYPE_RC_END)
+ bufidx = sprintf(t, "RC_END");
+ else if (type == PCI_EXP_TYPE_RC_EC)
+ bufidx = sprintf(t, "RC_EC");
+
+bridge_chk:
+ if (pci_is_bridge(hdr_type))
+ sprintf(t + bufidx, " [BRIDGE]");
+}
+
+static void
+walk_devices(ulong pci_bus)
+{
+ struct list_data list_data, *ld;
+ int devcnt, i;
+ ulong *devlist, self;
+ char name[BUFSIZE], class[BUFSIZE], id[BUFSIZE], type[BUFSIZE];
+ char pcidev_hdr[BUFSIZE];
+ char buf1[BUFSIZE];
+ char buf2[BUFSIZE];
+ char buf3[BUFSIZE];
+ char buf4[BUFSIZE];
+ char buf5[BUFSIZE];
+
+ ld = &list_data;
+
+ BZERO(ld, sizeof(struct list_data));
+
+ readmem(pci_bus + OFFSET(pci_bus_devices), KVADDR,
+ &ld->start, sizeof(void *), "pci bus devices",
+ FAULT_ON_ERROR);
+
+ if (VALID_MEMBER(pci_dev_pcie_flags_reg))
+ snprintf(pcidev_hdr, sizeof(pcidev_hdr), "%s %s %s %s %s\n",
+ mkstring(buf1, VADDR_PRLEN, CENTER, "PCI DEV"),
+ mkstring(buf2, strlen("0000:00:00.0"), CENTER, "DO:BU:SL.FN"),
+ mkstring(buf3, strlen("0000") + 2, CENTER, "CLASS"),
+ mkstring(buf4, strlen("0000:0000"), CENTER, "PCI_ID"),
+ mkstring(buf5, 10, CENTER, "TYPE"));
+ else
+ snprintf(pcidev_hdr, sizeof(pcidev_hdr), "%s %s %s %s\n",
+ mkstring(buf1, VADDR_PRLEN, CENTER, "PCI DEV"),
+ mkstring(buf2, strlen("0000:00:00.0"), CENTER, "DO:BU:SL.FN"),
+ mkstring(buf3, strlen("0000") + 2, CENTER, "CLASS"),
+ mkstring(buf4, strlen("0000:0000"), CENTER, "PCI_ID"));
+
+ fprintf(fp, " %s", pcidev_hdr);
+
+ readmem(pci_bus + OFFSET(pci_bus_self), KVADDR, &self,
+ sizeof(void *), "pci bus self", FAULT_ON_ERROR);
+ if (self) {
+ fill_dev_name(self, name);
+ fill_dev_class(self, class);
+ fill_dev_id(self, id);
+ fill_pcie_type(self, type);
+ fprintf(fp, " %s %s %s %s %s\n",
+ mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
+ MKSTR(self)),
+ mkstring(buf2, strlen("0000:00:00.0"), CENTER, name),
+ mkstring(buf3, strlen("0000") + 2, CENTER, class),
+ mkstring(buf4, strlen("0000:0000"), CENTER, id),
+ mkstring(buf5, 10, CENTER, type));
+ }
+
+ if (ld->start == (pci_bus + OFFSET(pci_bus_devices)))
+ return;
+
+ ld->end = pci_bus + OFFSET(pci_bus_devices);
+ hq_open();
+ devcnt = do_list(ld);
+ devlist = (ulong *)GETBUF(devcnt * sizeof(ulong));
+ devcnt = retrieve_list(devlist, devcnt);
+ hq_close();
+
+ for (i = 0; i < devcnt; i++) {
+ fill_dev_name(devlist[i], name);
+ fill_dev_class(devlist[i], class);
+ fill_dev_id(devlist[i], id);
+ fill_pcie_type(devlist[i], type);
+ fprintf(fp, " %s %s %s %s %s\n",
+ mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
+ MKSTR(devlist[i])),
+ mkstring(buf2, strlen("0000:00:00.0"), CENTER, name),
+ mkstring(buf3, strlen("0000") + 2, CENTER, class),
+ mkstring(buf4, strlen("0000:0000"), CENTER, id),
+ mkstring(buf5, 10, CENTER, type));
+ }
+ FREEBUF(devlist);
+}
+
+static void
+walk_buses(ulong pci_bus)
+{
+ struct list_data list_data, *ld;
+ int buscnt, i;
+ ulong *buslist, parent;
+ char pcibus_hdr[BUFSIZE];
+ char buf1[BUFSIZE];
+ char buf2[BUFSIZE];
+
+ ld = &list_data;
+
+ BZERO(ld, sizeof(struct list_data));
+
+ readmem(pci_bus + OFFSET(pci_bus_children), KVADDR,
+ &ld->start, sizeof(void *), "pci bus children",
+ FAULT_ON_ERROR);
+
+ if (ld->start == (pci_bus + OFFSET(pci_bus_children)))
+ return;
+
+ ld->end = pci_bus + OFFSET(pci_bus_children);
+ hq_open();
+ buscnt = do_list(ld);
+ buslist = (ulong *)GETBUF(buscnt * sizeof(ulong));
+ buscnt = retrieve_list(buslist, buscnt);
+ hq_close();
+
+ snprintf(pcibus_hdr, sizeof(pcibus_hdr), "%s %s\n",
+ mkstring(buf1, VADDR_PRLEN, CENTER, "PCI BUS"),
+ mkstring(buf2, VADDR_PRLEN, CENTER, "PARENT BUS"));
+
+ for (i = 0; i < buscnt; i++) {
+ readmem(buslist[i] + OFFSET(pci_bus_parent), KVADDR, &parent,
+ sizeof(void *), "pci bus parent", FAULT_ON_ERROR);
+
+ fprintf(fp, " %s", pcibus_hdr);
+
+ fprintf(fp, " %s %s\n",
+ mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
+ MKSTR(buslist[i])),
+ mkstring(buf2, VADDR_PRLEN, LJUST|LONG_HEX,
+ MKSTR(parent)));
+ walk_devices(buslist[i]);
+ fprintf(fp, "\n");
+ walk_buses(buslist[i]);
+ }
+ FREEBUF(buslist);
+}
+
+static void
+do_pci2(void)
+{
+ struct list_data list_data, *ld;
+ int rootbuscnt, i;
+ ulong *rootbuslist;
+ unsigned long pci_root_bus_addr = symbol_value("pci_root_buses");
+ char name[BUFSIZE];
+ char pcirootbus_hdr[BUFSIZE];
+ char buf1[BUFSIZE];
+ char buf2[BUFSIZE];
+
+ ld = &list_data;
+ BZERO(ld, sizeof(struct list_data));
+
+ get_symbol_data("pci_root_buses", sizeof(void *), &ld->start);
+
+ if (ld->start == pci_root_bus_addr)
+ error(FATAL, "no PCI devices found on this system.\n");
+
+ ld->end = pci_root_bus_addr;
+
+ hq_open();
+ rootbuscnt = do_list(ld);
+ rootbuslist = (ulong *)GETBUF(rootbuscnt * sizeof(ulong));
+ rootbuscnt = retrieve_list(rootbuslist, rootbuscnt);
+ hq_close();
+
+ snprintf(pcirootbus_hdr, sizeof(pcirootbus_hdr), "%s %s\n",
+ mkstring(buf1, VADDR_PRLEN, CENTER, "ROOT BUS"),
+ mkstring(buf2, strlen("0000:00"), CENTER, "BUSNAME"));
+
+ for (i = 0; i < rootbuscnt; i++) {
+ fprintf(fp, "%s", pcirootbus_hdr);
+ fill_bus_name(rootbuslist[i], name);
+ fprintf(fp, "%s %s\n",
+ mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
+ MKSTR(rootbuslist[i])),
+ mkstring(buf2, strlen("0000:00"), CENTER, name));
+ walk_devices(rootbuslist[i]);
+ walk_buses(rootbuslist[i]);
+
+ fprintf(fp, "\n");
+ }
+ FREEBUF(rootbuslist);
+}
+
static void
do_pci(void)
{
@@ -2230,9 +2554,6 @@ do_pci(void)
char buf2[BUFSIZE];
char buf3[BUFSIZE];
- if (!symbol_exists("pci_devices"))
- error(FATAL, "no PCI devices found on this system.\n");
-
BZERO(&pcilist_data, sizeof(struct list_data));
if (VALID_MEMBER(pci_dev_global_list)) {

View File

@ -1,174 +0,0 @@
commit 28fa7bd09013455b5ddc020dea4706278cda0d65
Author: Dave Anderson <anderson@redhat.com>
Date: Tue Jun 19 16:31:54 2018 -0400
Fix for PPC64 kernel virtual address translation in Linux 4.17 and
later kernels with commit c2b4d8b7417a59b7f9a52d0d8402f5257cbbd398,
titled "powerpc/mm/hash64: Increase the VA range", in which the
maximum virtual address value has been increased to 4PB. Without
the patch, the translation/access of high vmalloc space addresses
fails; for example, the "kmem -[sS]" option fails the translation
of per-cpu kmem_cache_cpu addresses located in vmalloc space, with
the error messages "kmem: invalid kernel virtual address: <address>
type: kmem_cache_cpu.freelist" and "kmem: invalid kernel virtual
address: <address> type: kmem_cache_cpu.page", and the "vtop"
command shows the addresses as "(not mapped)".
(hbathini@linux.ibm.com)
diff --git a/defs.h b/defs.h
index 6e6f6be..e6e3850 100644
--- a/defs.h
+++ b/defs.h
@@ -3977,6 +3977,7 @@ struct efi_memory_desc_t {
#define PMD_INDEX_SIZE_L4_64K_4_12 10
#define PUD_INDEX_SIZE_L4_64K_4_12 7
#define PGD_INDEX_SIZE_L4_64K_4_12 8
+#define PUD_INDEX_SIZE_L4_64K_4_17 10
#define PTE_INDEX_SIZE_RADIX_64K 5
#define PMD_INDEX_SIZE_RADIX_64K 9
#define PUD_INDEX_SIZE_RADIX_64K 9
diff --git a/ppc64.c b/ppc64.c
index 0dd8a2a..f5d0dac 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -451,7 +451,10 @@ ppc64_init(int when)
if (THIS_KERNEL_VERSION >= LINUX(4,12,0)) {
m->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_12;
- m->l3_index_size = PUD_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;
+ else
+ m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_12;
m->l4_index_size = PGD_INDEX_SIZE_L4_64K_4_12;
} else {
m->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_6;
commit e5df29d54bbdb8b84cb1661233ed186b153be746
Author: Dave Anderson <anderson@redhat.com>
Date: Wed Jun 20 11:15:38 2018 -0400
Fix for the x86_64 "bt" command in which a legitimate exception
frame is appended with the message "bt: WARNING: possibly bogus
exception frame". This only happens in KASLR-enabled kernels when
the text address that was executing when the exception occurred
is marked as a "weak" symbol (type "W") instead of a text symbol
(type "T" or "t"). As a result, the exception frame's RIP is not
recognized as a text symbol, and the warning message is displayed.
(anderson@redhat.com)
diff --git a/symbols.c b/symbols.c
index bb4ae3a..bf55319 100644
--- a/symbols.c
+++ b/symbols.c
@@ -2755,9 +2755,14 @@ is_kernel_text(ulong value)
section);
end = start + (ulong)bfd_section_size(st->bfd,
section);
+
+ if (kt->flags2 & KASLR) {
+ start += (kt->relocate * -1);
+ end += (kt->relocate * -1);
+ }
- if ((value >= start) && (value < end))
- return TRUE;
+ if ((value >= start) && (value < end))
+ return TRUE;
}
}
}
@@ -2833,7 +2838,16 @@ is_kernel_text_offset(ulong value)
int
is_symbol_text(struct syment *sp)
{
- return ((sp->type == 'T') || (sp->type == 't'));
+ if ((sp->type == 'T') || (sp->type == 't'))
+ return TRUE;
+
+ if ((sp->type == 'W') || (sp->type == 'w')) {
+ if ((sp->value >= kt->stext) &&
+ (sp->value < kt->etext))
+ return TRUE;
+ }
+
+ return FALSE;
}
/*
commit a7e5b90757bb41ad5e148177c5b3aaf5d892243d
Author: Dave Anderson <anderson@redhat.com>
Date: Wed Jun 20 16:33:43 2018 -0400
Fix for the x86_64 "bt" command in Linux 4.16 and later kernels
containing commit 3aa99fc3e708b9cd9b4cfe2df0b7a66cf293e3cf, titled
"x86/entry/64: Remove 'interrupt' macro". Without the patch, the
exception frame display generated by an interrupt exception will
show incorrect contents, and be followed by the message "bt: WARNING:
possibly bogus exception frame".
(anderson@redhat.com)
diff --git a/x86_64.c b/x86_64.c
index e01082b..6d1ae2f 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -4285,6 +4285,12 @@ x86_64_exception_frame(ulong flags, ulong kvaddr, char *local,
long err;
char buf[BUFSIZE];
+ if (flags == EFRAME_VERIFY) {
+ if (!accessible(kvaddr) ||
+ !accessible(kvaddr + SIZE(pt_regs) - sizeof(long)))
+ return FALSE;
+ }
+
ms = machdep->machspec;
sp = NULL;
@@ -6283,6 +6289,9 @@ x86_64_irq_eframe_link(ulong stkref, struct bt_info *bt, FILE *ofp)
{
ulong irq_eframe;
+ if (x86_64_exception_frame(EFRAME_VERIFY, stkref, 0, bt, ofp))
+ return stkref;
+
irq_eframe = stkref - machdep->machspec->irq_eframe_link;
if (x86_64_exception_frame(EFRAME_VERIFY, irq_eframe, 0, bt, ofp))
commit 02efd0838f05ef8a7fe21b0b8ba6cad729270645
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Jun 22 11:00:01 2018 -0400
Fix for the failure of several "kmem" command options, most notably
seen if the command is piped directly into a crash session, or if
the command is contained in an input file. For examples:
$ echo "kmem -i" | crash ...
$ crash -i <input-file> ...
Without the patch, the kmem command may fail with the error message
"<segmentation violation in gdb>". While the bug is due to a buffer
overflow that has always existed, it only is triggered by certain
kernel configurations.
(anderson@redhat.com)
diff --git a/memory.c b/memory.c
index 2f568d5..5c0a853 100644
--- a/memory.c
+++ b/memory.c
@@ -17498,13 +17498,12 @@ vm_stat_init(void)
STREQ(arglist[0], "NR_VM_ZONE_STAT_ITEMS")) {
continue;
} else {
- stringlen += strlen(arglist[0]);
+ stringlen += strlen(arglist[0]) + 1;
count++;
}
}
- total = stringlen + vt->nr_vm_stat_items +
- (sizeof(void *) * vt->nr_vm_stat_items);
+ total = stringlen + (sizeof(void *) * vt->nr_vm_stat_items);
if (!(vt->vm_stat_items = (char **)malloc(total))) {
close_tmpfile();
error(FATAL, "cannot malloc vm_stat_items cache\n");

View File

@ -1,58 +0,0 @@
commit 2f57a96ce27d8b121c2822de2a66c71b83bdad21
Author: Dave Anderson <anderson@redhat.com>
Date: Tue Sep 4 14:29:45 2018 -0400
Fix for the "files" command in Linux 4.17 and later kernels that
contain commit b93b016313b3ba8003c3b8bb71f569af91f19fc7, titled
"page cache: use xa_lock". Without the patch, the "files -c" option
fails with the message "files: -c option not supported or applicable
on this architecture or kernel", and the "files -p &lt;inode>" option
fails in a similar manner.
(k-hagio@ab.jp.nec.com)
diff --git a/filesys.c b/filesys.c
index 47f5a24..32daa5a 100644
--- a/filesys.c
+++ b/filesys.c
@@ -2207,6 +2207,11 @@ dump_inode_page_cache_info(ulong inode)
RJUST|LONG_DEC,
MKSTR(nrpages)));
+ FREEBUF(inode_buf);
+
+ if (!nrpages)
+ return;
+
root_rnode = i_mapping + OFFSET(address_space_page_tree);
rtp.index = 0;
rtp.value = (void *)&dump_inode_page;
@@ -2217,7 +2222,6 @@ dump_inode_page_cache_info(ulong inode)
error(INFO, "page_tree count: %ld nrpages: %ld\n",
count, nrpages);
- FREEBUF(inode_buf);
return;
}
@@ -2275,7 +2279,7 @@ cmd_files(void)
return;
case 'c':
- if (VALID_MEMBER(address_space_page_tree) &&
+ if (VALID_MEMBER(address_space_nrpages) &&
VALID_MEMBER(inode_i_mapping))
open_flags |= PRINT_NRPAGES;
else
diff --git a/memory.c b/memory.c
index 24fce5e..ea25047 100644
--- a/memory.c
+++ b/memory.c
@@ -485,6 +485,8 @@ vm_init(void)
MEMBER_OFFSET_INIT(block_device_bd_disk, "block_device", "bd_disk");
MEMBER_OFFSET_INIT(inode_i_mapping, "inode", "i_mapping");
MEMBER_OFFSET_INIT(address_space_page_tree, "address_space", "page_tree");
+ if (INVALID_MEMBER(address_space_page_tree))
+ MEMBER_OFFSET_INIT(address_space_page_tree, "address_space", "i_pages");
MEMBER_OFFSET_INIT(address_space_nrpages, "address_space", "nrpages");
if (INVALID_MEMBER(address_space_nrpages))
MEMBER_OFFSET_INIT(address_space_nrpages, "address_space", "__nrpages");

View File

@ -1,45 +0,0 @@
commit 3141bba98af302e2a7c5e2a19203bb8a40b6aa63
Author: Dave Anderson <anderson@redhat.com>
Date: Wed Oct 10 09:15:42 2018 -0400
Fix the calculation of the vmalloc memory region size to account for
Linux 4.17 commit a7412546d8cb5ad578805060b4006f2a021b5868, titled
"x86/mm: Adjust vmalloc base and size at boot-time", which increases
the region's size from 32TB to 1280TB when 5-level pagetables are
enabled. Also presume that virtual addresses above the end of the
vmalloc space up to the beginning of vmemmap space are translatable
via 5-level page tables. Without the patch, mapped virtual addresses
may fail translation in whatever command accesses them, with errors
indicating "seek error: kernel virtual address: <mapped-address>
type: <type-string>"
(anderson@redhat.com)
diff --git a/x86_64.c b/x86_64.c
index 6f547e8..345122c 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -393,8 +393,12 @@ x86_64_init(int when)
readmem(symbol_value("vmalloc_base"), KVADDR,
&machdep->machspec->vmalloc_start_addr,
sizeof(ulong), "vmalloc_base", FAULT_ON_ERROR);
- machdep->machspec->vmalloc_end =
- machdep->machspec->vmalloc_start_addr + TERABYTES(32) - 1;
+ if (machdep->flags & VM_5LEVEL)
+ machdep->machspec->vmalloc_end =
+ machdep->machspec->vmalloc_start_addr + TERABYTES(1280) - 1;
+ else
+ machdep->machspec->vmalloc_end =
+ machdep->machspec->vmalloc_start_addr + TERABYTES(32) - 1;
if (kernel_symbol_exists("vmemmap_base")) {
readmem(symbol_value("vmemmap_base"), KVADDR,
&machdep->machspec->vmemmap_vaddr, sizeof(ulong),
@@ -1626,7 +1630,8 @@ x86_64_IS_VMALLOC_ADDR(ulong vaddr)
(vaddr >= VSYSCALL_START && vaddr < VSYSCALL_END) ||
(machdep->machspec->cpu_entry_area_start &&
vaddr >= machdep->machspec->cpu_entry_area_start &&
- vaddr <= machdep->machspec->cpu_entry_area_end));
+ vaddr <= machdep->machspec->cpu_entry_area_end) ||
+ ((machdep->flags & VM_5LEVEL) && vaddr > VMALLOC_END && vaddr < VMEMMAP_VADDR));
}
static int

View File

@ -1,196 +0,0 @@
commit 361f050e3148c6188afb45942e06d4a509852b86
Author: Dave Anderson <anderson@redhat.com>
Date: Mon Jan 7 13:56:15 2019 -0500
Fix for the "dev -[dD]" options in kernels containing Linux 5.0-rc1
commit 7ff4f8035695984c513598e2d49c8277d5d234ca, titled "block:
remove dead queue members", in which the number of I/Os issued to
a disk driver are no longer stored in the request_queue structure.
Without the patch, the options indicate "dev: -d option not supported
or applicable on this architecture or kernel". With the patch, the
"DRV" column is not shown.
(m.mizuma@jp.fujitsu.com)
diff --git a/defs.h b/defs.h
index a3cb5a4..9ebdde6 100644
--- a/defs.h
+++ b/defs.h
@@ -2043,6 +2043,8 @@ struct offset_table {
long pci_bus_self;
long device_kobj;
long kobject_name;
+ long hd_struct_dkstats;
+ long disk_stats_in_flight;
};
struct size_table { /* stash of commonly-used sizes */
diff --git a/dev.c b/dev.c
index 7ce2422..24efea2 100644
--- a/dev.c
+++ b/dev.c
@@ -3974,7 +3974,7 @@ struct iter {
* this function reads request_list.count[2], and the first argument
* is the address of request_queue.
*/
- void (*get_diskio)(unsigned long , struct diskio *);
+ void (*get_diskio)(unsigned long , unsigned long, struct diskio *);
/*
* check if device.type == &disk_type
@@ -4187,24 +4187,55 @@ get_mq_diskio(unsigned long q, unsigned long *mq_count)
}
}
+static void
+get_one_diskio_from_dkstats(unsigned long dkstats, unsigned long *count)
+{
+ int cpu;
+ unsigned long dkstats_addr;
+ unsigned long in_flight[2];
+
+ for (cpu = 0; cpu < kt->cpus; cpu++) {
+ if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF)) {
+ dkstats_addr = dkstats + kt->__per_cpu_offset[cpu];
+ readmem(dkstats_addr + OFFSET(disk_stats_in_flight),
+ KVADDR, in_flight, sizeof(long) * 2,
+ "disk_stats.in_flight", FAULT_ON_ERROR);
+ count[0] += in_flight[0];
+ count[1] += in_flight[1];
+ }
+ }
+}
+
+
/* read request_queue.rq.count[2] */
static void
-get_diskio_1(unsigned long rq, struct diskio *io)
+get_diskio_1(unsigned long rq, unsigned long gendisk, struct diskio *io)
{
int count[2];
- unsigned long mq_count[2] = { 0 };
+ unsigned long io_counts[2] = { 0 };
+ unsigned long dkstats;
if (!use_mq_interface(rq)) {
- readmem(rq + OFFSET(request_queue_rq) +
- OFFSET(request_list_count), KVADDR, count,
- sizeof(int) * 2, "request_list.count", FAULT_ON_ERROR);
+ if (VALID_MEMBER(request_queue_rq)) {
+ readmem(rq + OFFSET(request_queue_rq) +
+ OFFSET(request_list_count), KVADDR, count,
+ sizeof(int) * 2, "request_list.count", FAULT_ON_ERROR);
+
+ io->read = count[0];
+ io->write = count[1];
+ } else {
+ readmem(gendisk + OFFSET(gendisk_part0) +
+ OFFSET(hd_struct_dkstats), KVADDR, &dkstats,
+ sizeof(ulong), "gendisk.part0.dkstats", FAULT_ON_ERROR);
+ get_one_diskio_from_dkstats(dkstats, io_counts);
- io->read = count[0];
- io->write = count[1];
+ io->read = io_counts[0];
+ io->write = io_counts[1];
+ }
} else {
- get_mq_diskio(rq, mq_count);
- io->read = mq_count[0];
- io->write = mq_count[1];
+ get_mq_diskio(rq, io_counts);
+ io->read = io_counts[0];
+ io->write = io_counts[1];
}
}
@@ -4250,9 +4281,6 @@ init_iter(struct iter *i)
i->get_in_flight = get_in_flight_1;
} else if (SIZE(rq_in_flight) == sizeof(int) * 2) {
i->get_in_flight = get_in_flight_2;
- } else {
- option_not_supported('d');
- return;
}
i->get_diskio = get_diskio_1;
@@ -4354,7 +4382,7 @@ display_one_diskio(struct iter *i, unsigned long gendisk, ulong flags)
sizeof(ulong), "gen_disk.queue", FAULT_ON_ERROR);
readmem(gendisk + OFFSET(gendisk_major), KVADDR, &major, sizeof(int),
"gen_disk.major", FAULT_ON_ERROR);
- i->get_diskio(queue_addr, &io);
+ i->get_diskio(queue_addr, gendisk, &io);
if ((flags & DIOF_NONZERO)
&& (io.read + io.write == 0))
@@ -4379,11 +4407,14 @@ display_one_diskio(struct iter *i, unsigned long gendisk, ulong flags)
(char *)(unsigned long)io.write),
space(MINSPACE));
- if (!use_mq_interface(queue_addr)) {
- in_flight = i->get_in_flight(queue_addr);
- fprintf(fp, "%5u\n", in_flight);
+ if (VALID_MEMBER(request_queue_in_flight)) {
+ if (!use_mq_interface(queue_addr)) {
+ in_flight = i->get_in_flight(queue_addr);
+ fprintf(fp, "%5u\n", in_flight);
+ } else
+ fprintf(fp, "%s\n", "N/A(MQ)");
} else
- fprintf(fp, "%s\n", "N/A(MQ)");
+ fprintf(fp, "\n");
}
static void
@@ -4418,7 +4449,7 @@ display_all_diskio(ulong flags)
i.sync_count ? mkstring(buf4, 5, RJUST, "SYNC") :
mkstring(buf4, 5, RJUST, "WRITE"),
space(MINSPACE),
- mkstring(buf5, 5, RJUST, "DRV"));
+ VALID_MEMBER(request_queue_in_flight) ? mkstring(buf5, 5, RJUST, "DRV") : "");
while ((gendisk = i.next_disk(&i)) != 0)
display_one_diskio(&i, gendisk, flags);
@@ -4446,6 +4477,7 @@ void diskio_init(void)
MEMBER_OFFSET_INIT(gendisk_part0, "gendisk", "part0");
MEMBER_OFFSET_INIT(gendisk_queue, "gendisk", "queue");
MEMBER_OFFSET_INIT(hd_struct_dev, "hd_struct", "__dev");
+ MEMBER_OFFSET_INIT(hd_struct_dkstats, "hd_struct", "dkstats");
MEMBER_OFFSET_INIT(klist_k_list, "klist", "k_list");
MEMBER_OFFSET_INIT(klist_node_n_klist, "klist_node", "n_klist");
MEMBER_OFFSET_INIT(klist_node_n_node, "klist_node", "n_node");
@@ -4476,6 +4508,7 @@ void diskio_init(void)
MEMBER_SIZE_INIT(rq_in_flight, "request_queue", "in_flight");
MEMBER_SIZE_INIT(class_private_devices, "class_private",
"class_devices");
+ MEMBER_OFFSET_INIT(disk_stats_in_flight, "disk_stats", "in_flight");
dt->flags |= DISKIO_INIT;
}
diff --git a/help.c b/help.c
index aadd2ed..1593e82 100644
--- a/help.c
+++ b/help.c
@@ -3218,7 +3218,7 @@ char *help_dev[] = {
" WRITE: I/O requests that are writes (older kernels)",
" DRV: I/O requests that are in-flight in the device driver.",
" If the device driver uses blk-mq interface, this field",
-" shows N/A(MQ).",
+" shows N/A(MQ). If not available, this column is not shown.",
" -D same as -d, but filter out disks with no in-progress I/O requests.",
"\nEXAMPLES",
" Display character and block device data:\n",
diff --git a/symbols.c b/symbols.c
index ef6f934..5f77e27 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10021,6 +10021,10 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(gendisk_queue));
fprintf(fp, " hd_struct_dev: %ld\n",
OFFSET(hd_struct_dev));
+ fprintf(fp, " hd_struct_dkstats: %ld\n",
+ OFFSET(hd_struct_dkstats));
+ fprintf(fp, " disk_stats_in_flight: %ld\n",
+ OFFSET(disk_stats_in_flight));
fprintf(fp, " klist_k_list: %ld\n",
OFFSET(klist_k_list));
fprintf(fp, " klist_node_n_klist: %ld\n",

View File

@ -1,414 +0,0 @@
commit 46d2121960d81354facf4e2558c81f82257b740e
Author: Dave Anderson <anderson@redhat.com>
Date: Tue May 29 14:04:03 2018 -0400
Fix for the "timer -r" command on Linux 4.10 and later kernels that
contain commit 2456e855354415bfaeb7badaa14e11b3e02c8466, titled
"ktime: Get rid of the union". Without the patch, the command fails
with the error message "timer: invalid structure member offset:
ktime_t_sec".
(k-hagio@ab.jp.nec.com)
diff --git a/kernel.c b/kernel.c
index b1886ce..138a47f 100644
--- a/kernel.c
+++ b/kernel.c
@@ -7740,7 +7740,7 @@ ktime_to_ns(const void *ktime)
if (VALID_MEMBER(ktime_t_tv64)) {
readmem((ulong)ktime + OFFSET(ktime_t_tv64), KVADDR, &ns,
sizeof(ns), "ktime_t tv64", QUIET|RETURN_ON_ERROR);
- } else {
+ } else if (VALID_MEMBER(ktime_t_sec) && VALID_MEMBER(ktime_t_nsec)) {
uint32_t sec, nsec;
sec = 0;
@@ -7753,6 +7753,9 @@ ktime_to_ns(const void *ktime)
sizeof(nsec), "ktime_t nsec", QUIET|RETURN_ON_ERROR);
ns = sec * 1000000000L + nsec;
+ } else {
+ readmem((ulong)ktime, KVADDR, &ns,
+ sizeof(ns), "ktime_t", QUIET|RETURN_ON_ERROR);
}
return ns;
commit a6cd8408d1d214a67ed0c4b09343fec77a8e2ae7
Author: Dave Anderson <anderson@redhat.com>
Date: Thu May 31 11:43:14 2018 -0400
Fix for the x86 and x86_64 "mach -m" option on Linux 4.12 and later
kernels to account for the structure name changes "e820map" to
"e820_table", and "e820entry" to "e820_entry", and for the symbol
name change from "e820" to "e820_table". Also updated the display
output to properly translate E820_PRAM and E820_RESERVED_KERN entries.
Without the patch on all kernels, E820_PRAM and E820_RESERVED_KERN
entries show "type 12" and "type 128" respectively. Without the
patch on Linux 4.12 and later kernels, the command fails with the
error message "mach: cannot resolve e820".
(anderson@redhat.com)
diff --git a/x86.c b/x86.c
index 47767b6..88562b6 100644
--- a/x86.c
+++ b/x86.c
@@ -1,8 +1,8 @@
/* x86.c - core analysis suite
*
* Portions Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
- * Copyright (C) 2002-2014,2017 David Anderson
- * Copyright (C) 2002-2014,2017 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2002-2014,2017-2018 David Anderson
+ * Copyright (C) 2002-2014,2017-2018 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1967,15 +1967,27 @@ x86_init(int when)
}
MEMBER_OFFSET_INIT(thread_struct_cr3, "thread_struct", "cr3");
STRUCT_SIZE_INIT(cpuinfo_x86, "cpuinfo_x86");
- STRUCT_SIZE_INIT(e820map, "e820map");
- STRUCT_SIZE_INIT(e820entry, "e820entry");
STRUCT_SIZE_INIT(irq_ctx, "irq_ctx");
+ if (STRUCT_EXISTS("e820map")) {
+ STRUCT_SIZE_INIT(e820map, "e820map");
+ MEMBER_OFFSET_INIT(e820map_nr_map, "e820map", "nr_map");
+ } else {
+ STRUCT_SIZE_INIT(e820map, "e820_table");
+ MEMBER_OFFSET_INIT(e820map_nr_map, "e820_table", "nr_entries");
+ }
+ if (STRUCT_EXISTS("e820entry")) {
+ STRUCT_SIZE_INIT(e820entry, "e820entry");
+ MEMBER_OFFSET_INIT(e820entry_addr, "e820entry", "addr");
+ MEMBER_OFFSET_INIT(e820entry_size, "e820entry", "size");
+ MEMBER_OFFSET_INIT(e820entry_type, "e820entry", "type");
+ } else {
+ STRUCT_SIZE_INIT(e820entry, "e820_entry");
+ MEMBER_OFFSET_INIT(e820entry_addr, "e820_entry", "addr");
+ MEMBER_OFFSET_INIT(e820entry_size, "e820_entry", "size");
+ MEMBER_OFFSET_INIT(e820entry_type, "e820_entry", "type");
+ }
if (!VALID_STRUCT(irq_ctx))
STRUCT_SIZE_INIT(irq_ctx, "irq_stack");
- MEMBER_OFFSET_INIT(e820map_nr_map, "e820map", "nr_map");
- MEMBER_OFFSET_INIT(e820entry_addr, "e820entry", "addr");
- MEMBER_OFFSET_INIT(e820entry_size, "e820entry", "size");
- MEMBER_OFFSET_INIT(e820entry_type, "e820entry", "type");
if (KVMDUMP_DUMPFILE())
set_kvm_iohole(NULL);
if (symbol_exists("irq_desc"))
@@ -4415,33 +4427,54 @@ static char *e820type[] = {
static void
x86_display_memmap(void)
{
- ulong e820;
- int nr_map, i;
- char *buf, *e820entry_ptr;
- ulonglong addr, size;
- ulong type;
+ ulong e820;
+ int nr_map, i;
+ char *buf, *e820entry_ptr;
+ ulonglong addr, size;
+ uint type;
+
+ if (kernel_symbol_exists("e820")) {
+ if (get_symbol_type("e820", NULL, NULL) == TYPE_CODE_PTR)
+ get_symbol_data("e820", sizeof(void *), &e820);
+ else
+ e820 = symbol_value("e820");
+
+ } else if (kernel_symbol_exists("e820_table"))
+ get_symbol_data("e820_table", sizeof(void *), &e820);
+ else
+ error(FATAL, "neither e820 or e820_table symbols exist\n");
- e820 = symbol_value("e820");
- buf = (char *)GETBUF(SIZE(e820map));
+ if (CRASHDEBUG(1)) {
+ if (STRUCT_EXISTS("e820map"))
+ dump_struct("e820map", e820, RADIX(16));
+ else if (STRUCT_EXISTS("e820_table"))
+ dump_struct("e820_table", e820, RADIX(16));
+ }
+ buf = (char *)GETBUF(SIZE(e820map));
- readmem(e820, KVADDR, &buf[0], SIZE(e820map),
- "e820map", FAULT_ON_ERROR);
+ readmem(e820, KVADDR, &buf[0], SIZE(e820map),
+ "e820map", FAULT_ON_ERROR);
- nr_map = INT(buf + OFFSET(e820map_nr_map));
+ nr_map = INT(buf + OFFSET(e820map_nr_map));
- fprintf(fp, " PHYSICAL ADDRESS RANGE TYPE\n");
+ fprintf(fp, " PHYSICAL ADDRESS RANGE TYPE\n");
- for (i = 0; i < nr_map; i++) {
- e820entry_ptr = buf + sizeof(int) + (SIZE(e820entry) * i);
- addr = ULONGLONG(e820entry_ptr + OFFSET(e820entry_addr));
- size = ULONGLONG(e820entry_ptr + OFFSET(e820entry_size));
- type = ULONG(e820entry_ptr + OFFSET(e820entry_type));
+ for (i = 0; i < nr_map; i++) {
+ e820entry_ptr = buf + sizeof(int) + (SIZE(e820entry) * i);
+ addr = ULONGLONG(e820entry_ptr + OFFSET(e820entry_addr));
+ size = ULONGLONG(e820entry_ptr + OFFSET(e820entry_size));
+ type = UINT(e820entry_ptr + OFFSET(e820entry_type));
fprintf(fp, "%016llx - %016llx ", addr, addr+size);
- if (type >= (sizeof(e820type)/sizeof(char *)))
- fprintf(fp, "type %ld\n", type);
- else
+ if (type >= (sizeof(e820type)/sizeof(char *))) {
+ if (type == 12)
+ fprintf(fp, "E820_PRAM\n");
+ else if (type == 128)
+ fprintf(fp, "E820_RESERVED_KERN\n");
+ else
+ fprintf(fp, "type %d\n", type);
+ } else
fprintf(fp, "%s\n", e820type[type]);
- }
+ }
}
/*
diff --git a/x86_64.c b/x86_64.c
index 921552b..1d5e155 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -415,12 +415,26 @@ x86_64_init(int when)
STRUCT_SIZE_INIT(gate_struct, "gate_desc");
else
STRUCT_SIZE_INIT(gate_struct, "gate_struct");
- STRUCT_SIZE_INIT(e820map, "e820map");
- STRUCT_SIZE_INIT(e820entry, "e820entry");
- MEMBER_OFFSET_INIT(e820map_nr_map, "e820map", "nr_map");
- MEMBER_OFFSET_INIT(e820entry_addr, "e820entry", "addr");
- MEMBER_OFFSET_INIT(e820entry_size, "e820entry", "size");
- MEMBER_OFFSET_INIT(e820entry_type, "e820entry", "type");
+
+ if (STRUCT_EXISTS("e820map")) {
+ STRUCT_SIZE_INIT(e820map, "e820map");
+ MEMBER_OFFSET_INIT(e820map_nr_map, "e820map", "nr_map");
+ } else {
+ STRUCT_SIZE_INIT(e820map, "e820_table");
+ MEMBER_OFFSET_INIT(e820map_nr_map, "e820_table", "nr_entries");
+ }
+ if (STRUCT_EXISTS("e820entry")) {
+ STRUCT_SIZE_INIT(e820entry, "e820entry");
+ MEMBER_OFFSET_INIT(e820entry_addr, "e820entry", "addr");
+ MEMBER_OFFSET_INIT(e820entry_size, "e820entry", "size");
+ MEMBER_OFFSET_INIT(e820entry_type, "e820entry", "type");
+ } else {
+ STRUCT_SIZE_INIT(e820entry, "e820_entry");
+ MEMBER_OFFSET_INIT(e820entry_addr, "e820_entry", "addr");
+ MEMBER_OFFSET_INIT(e820entry_size, "e820_entry", "size");
+ MEMBER_OFFSET_INIT(e820entry_type, "e820_entry", "type");
+ }
+
if (KVMDUMP_DUMPFILE())
set_kvm_iohole(NULL);
MEMBER_OFFSET_INIT(thread_struct_rip, "thread_struct", "rip");
@@ -5643,12 +5657,23 @@ x86_64_display_memmap(void)
ulonglong addr, size;
uint type;
- if (get_symbol_type("e820", NULL, NULL) == TYPE_CODE_PTR)
- get_symbol_data("e820", sizeof(void *), &e820);
+ if (kernel_symbol_exists("e820")) {
+ if (get_symbol_type("e820", NULL, NULL) == TYPE_CODE_PTR)
+ get_symbol_data("e820", sizeof(void *), &e820);
+ else
+ e820 = symbol_value("e820");
+
+ } else if (kernel_symbol_exists("e820_table"))
+ get_symbol_data("e820_table", sizeof(void *), &e820);
else
- e820 = symbol_value("e820");
- if (CRASHDEBUG(1))
- dump_struct("e820map", e820, RADIX(16));
+ error(FATAL, "neither e820 or e820_table symbols exist\n");
+
+ if (CRASHDEBUG(1)) {
+ if (STRUCT_EXISTS("e820map"))
+ dump_struct("e820map", e820, RADIX(16));
+ else if (STRUCT_EXISTS("e820_table"))
+ dump_struct("e820_table", e820, RADIX(16));
+ }
buf = (char *)GETBUF(SIZE(e820map));
readmem(e820, KVADDR, &buf[0], SIZE(e820map),
@@ -5664,9 +5689,14 @@ x86_64_display_memmap(void)
size = ULONGLONG(e820entry_ptr + OFFSET(e820entry_size));
type = UINT(e820entry_ptr + OFFSET(e820entry_type));
fprintf(fp, "%016llx - %016llx ", addr, addr+size);
- if (type >= (sizeof(e820type)/sizeof(char *)))
- fprintf(fp, "type %d\n", type);
- else
+ if (type >= (sizeof(e820type)/sizeof(char *))) {
+ if (type == 12)
+ fprintf(fp, "E820_PRAM\n");
+ else if (type == 128)
+ fprintf(fp, "E820_RESERVED_KERN\n");
+ else
+ fprintf(fp, "type %d\n", type);
+ } else
fprintf(fp, "%s\n", e820type[type]);
}
}
commit da49e2010b3cb88b4755d69d38fe90af6ba218b2
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Jun 1 10:58:00 2018 -0400
Update for the recognition of the new x86_64 CPU_ENTRY_AREA virtual
address range introduced in Linux 4.15. The memory range exists
above the vmemmap range and below the mapped kernel static text/data
region, and where all of the x86_64 exception stacks have been moved.
Without the patch, reads from the new memory region fail because the
address range is not recognized as a legitimate virtual address.
Most notable is the failure of "bt" on tasks whose backtraces
originate from any of the exception stacks, which fail with the two
error messages "bt: seek error: kernel virtual address: <address>
type: stack contents" followed by "bt: read of stack at <address>
failed".
(anderson@redhat.com)
diff --git a/defs.h b/defs.h
index 931be07..6e6f6be 100644
--- a/defs.h
+++ b/defs.h
@@ -3391,6 +3391,9 @@ struct arm64_stackframe {
#define VSYSCALL_START 0xffffffffff600000
#define VSYSCALL_END 0xffffffffff601000
+#define CPU_ENTRY_AREA_START 0xfffffe0000000000
+#define CPU_ENTRY_AREA_END 0xfffffe7fffffffff
+
#define PTOV(X) ((unsigned long)(X)+(machdep->kvbase))
#define VTOP(X) x86_64_VTOP((ulong)(X))
#define IS_VMALLOC_ADDR(X) x86_64_IS_VMALLOC_ADDR((ulong)(X))
@@ -5829,6 +5832,8 @@ struct machine_specific {
ulong kpti_entry_stack;
ulong kpti_entry_stack_size;
ulong ptrs_per_pgd;
+ ulong cpu_entry_area_start;
+ ulong cpu_entry_area_end;
};
#define KSYMS_START (0x1)
diff --git a/x86_64.c b/x86_64.c
index 1d5e155..54b6539 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -407,6 +407,11 @@ x86_64_init(int when)
machdep->machspec->modules_end = MODULES_END_2_6_31;
}
}
+ if (STRUCT_EXISTS("cpu_entry_area")) {
+ machdep->machspec->cpu_entry_area_start = CPU_ENTRY_AREA_START;
+ machdep->machspec->cpu_entry_area_end = CPU_ENTRY_AREA_END;
+ }
+
STRUCT_SIZE_INIT(cpuinfo_x86, "cpuinfo_x86");
/*
* Before 2.6.25 the structure was called gate_struct
@@ -879,20 +884,21 @@ x86_64_dump_machdep_table(ulong arg)
/* pml4 and upml is legacy for extension modules */
if (ms->pml4) {
- fprintf(fp, " pml4: %lx\n", (ulong)ms->pml4);
- fprintf(fp, " last_pml4_read: %lx\n", (ulong)ms->last_pml4_read);
+ fprintf(fp, " pml4: %lx\n", (ulong)ms->pml4);
+ fprintf(fp, " last_pml4_read: %lx\n", (ulong)ms->last_pml4_read);
} else {
- fprintf(fp, " pml4: (unused)\n");
- fprintf(fp, " last_pml4_read: (unused)\n");
+ fprintf(fp, " pml4: (unused)\n");
+ fprintf(fp, " last_pml4_read: (unused)\n");
}
if (ms->upml) {
- fprintf(fp, " upml: %lx\n", (ulong)ms->upml);
- fprintf(fp, " last_upml_read: %lx\n", (ulong)ms->last_upml_read);
+ fprintf(fp, " upml: %lx\n", (ulong)ms->upml);
+ fprintf(fp, " last_upml_read: %lx\n", (ulong)ms->last_upml_read);
} else {
- fprintf(fp, " upml: (unused)\n");
- fprintf(fp, " last_upml_read: (unused)\n");
+ fprintf(fp, " GART_end: %lx\n", ms->GART_end);
+ fprintf(fp, " upml: (unused)\n");
+ fprintf(fp, " last_upml_read: (unused)\n");
}
if (ms->p4d) {
@@ -1016,10 +1022,14 @@ x86_64_dump_machdep_table(ulong arg)
fprintf(fp, "\n ");
fprintf(fp, "%016lx ", ms->stkinfo.ibase[c]);
}
- fprintf(fp, "\n kpti_entry_stack_size: %ld", ms->kpti_entry_stack_size);
- fprintf(fp, "\n kpti_entry_stack: ");
+ fprintf(fp, "\n kpti_entry_stack_size: ");
+ if (ms->kpti_entry_stack_size)
+ fprintf(fp, "%ld", ms->kpti_entry_stack_size);
+ else
+ fprintf(fp, "(unused)");
+ fprintf(fp, "\n kpti_entry_stack: ");
if (machdep->flags & KPTI) {
- fprintf(fp, "%lx\n ", ms->kpti_entry_stack);
+ fprintf(fp, "(percpu: %lx):\n ", ms->kpti_entry_stack);
for (c = 0; c < cpus; c++) {
if (c && !(c%4))
fprintf(fp, "\n ");
@@ -1028,6 +1038,16 @@ x86_64_dump_machdep_table(ulong arg)
fprintf(fp, "\n");
} else
fprintf(fp, "(unused)\n");
+ fprintf(fp, " cpu_entry_area_start: ");
+ if (ms->cpu_entry_area_start)
+ fprintf(fp, "%016lx\n", (ulong)ms->cpu_entry_area_start);
+ else
+ fprintf(fp, "(unused)\n");
+ fprintf(fp, " cpu_entry_area_end: ");
+ if (ms->cpu_entry_area_end)
+ fprintf(fp, "%016lx\n", (ulong)ms->cpu_entry_area_end);
+ else
+ fprintf(fp, "(unused)\n");
}
/*
@@ -1586,7 +1606,10 @@ x86_64_IS_VMALLOC_ADDR(ulong vaddr)
((machdep->flags & VMEMMAP) &&
(vaddr >= VMEMMAP_VADDR && vaddr <= VMEMMAP_END)) ||
(vaddr >= MODULES_VADDR && vaddr <= MODULES_END) ||
- (vaddr >= VSYSCALL_START && vaddr < VSYSCALL_END));
+ (vaddr >= VSYSCALL_START && vaddr < VSYSCALL_END) ||
+ (machdep->machspec->cpu_entry_area_start &&
+ vaddr >= machdep->machspec->cpu_entry_area_start &&
+ vaddr <= machdep->machspec->cpu_entry_area_end));
}
static int
commit 9446958fe211825ed5524317b05d5ea020bb00d6
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Jun 1 14:01:01 2018 -0400
Fix to address a "__builtin___snprintf_chk" compiler warning if bpf.c
is compiled with -D_FORTIFY_SOURCE=2.
(anderson@redhat.com)
diff --git a/bpf.c b/bpf.c
index 305d49f..ee1986f 100644
--- a/bpf.c
+++ b/bpf.c
@@ -362,7 +362,7 @@ do_bpf(ulong flags, ulong prog_id, ulong map_id, int radix)
fprintf(fp, " LOAD_TIME: ");
if (VALID_MEMBER(bpf_prog_aux_load_time)) {
load_time = ULONGLONG(bpf->bpf_prog_aux_buf + OFFSET(bpf_prog_aux_load_time));
- print_boot_time(load_time, buf5, BUFSIZE);
+ print_boot_time(load_time, buf5, BUFSIZE/2);
fprintf(fp, "%s\n", buf5);
} else
fprintf(fp, "(unknown)\n");

View File

@ -1,34 +0,0 @@
commit 64dad6d0d60514498252e6071738fa1b4c12db8c
Author: Dave Anderson <anderson@redhat.com>
Date: Thu Nov 29 14:21:19 2018 -0500
Fix for the "ps -s" option on ARM64 if the number of tasks exceeds
2000. Without the patch, the command ultimately fails with a
dump of the internal buffer allocation stats, followed by the
message "ps: cannot allocate any more memory!".
(anderson@redhat.com)
diff -up crash-7.2.3/task.c.orig crash-7.2.3/task.c
--- crash-7.2.3/task.c.orig 2018-11-29 13:54:39.108320730 -0500
+++ crash-7.2.3/task.c 2018-11-29 13:54:48.598279086 -0500
@@ -4133,6 +4133,10 @@ task_pointer_string(struct task_context
readmem(tc->task + OFFSET(task_struct_thread_ksp),
KVADDR, &bt->stkptr, sizeof(void *),
"thread_struct ksp", FAULT_ON_ERROR);
+ } else if (VALID_MEMBER(task_struct_thread_context_sp)) {
+ readmem(tc->task + OFFSET(task_struct_thread_context_sp),
+ KVADDR, &bt->stkptr, sizeof(void *),
+ "cpu_context sp", FAULT_ON_ERROR);
} else {
if ((bt->stackbase = GET_STACKBASE(tc->task))) {
bt->stacktop = GET_STACKTOP(tc->task);
@@ -4140,6 +4144,8 @@ task_pointer_string(struct task_context
bt->tc = tc;
bt->flags |= BT_KSTACKP;
back_trace(bt);
+ if (bt->stackbuf)
+ FREEBUF(bt->stackbuf);
} else
bt->stkptr = 0;
}

View File

@ -1,39 +0,0 @@
commit 6b93714b83d59ae4147b8ec3887261aca7fd6f65
Author: Dave Anderson <anderson@redhat.com>
Date: Mon Jan 7 10:44:29 2019 -0500
Prevent a SIGSEGV if a user attempts to input a command line that
exceeds the maximum length of 1500 bytes. The patch displays an
error message and ignores the command line.
(anderson@redhat.com)
diff --git a/cmdline.c b/cmdline.c
index 665f48c..796f7c5 100644
--- a/cmdline.c
+++ b/cmdline.c
@@ -1,8 +1,8 @@
/* cmdline.c - core analysis suite
*
* Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
- * Copyright (C) 2002-2015,2018 David Anderson
- * Copyright (C) 2002-2015,2018 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2002-2015,2019 David Anderson
+ * Copyright (C) 2002-2015,2019 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -121,9 +121,11 @@ process_command_line(void)
args[0] = NULL;
fprintf(fp, "\n");
return;
- }
-
- strcpy(pc->command_line, pc->readline);
+ }
+ if (strlen(pc->readline) >= BUFSIZE)
+ error(FATAL, "input line exceeds maximum of 1500 bytes\n");
+ else
+ strcpy(pc->command_line, pc->readline);
free(pc->readline);
clean_line(pc->command_line);

View File

@ -1,212 +0,0 @@
commit 8618ddd817621c40c1f44f0ab6df7c7805234416
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Feb 1 15:01:29 2019 -0500
First phase of support for ARM64 kernels that are configured with
CONFIG_ARM64_USER_VA_BITS_52, which causes the PTRS_PER_PGD count
to increase from 64 to 1024. Without the patch, "WARNING: cannot
access vmalloc'd module memory" will be displayed during session
initialization, and the translation of any mapped kernel virtual
address that requires a page table walk will fail, leading to a
myriad of other errors.
(anderson@redhat.com)
diff --git a/arm64.c b/arm64.c
index 45c7313..2308612 100644
--- a/arm64.c
+++ b/arm64.c
@@ -1,8 +1,8 @@
/*
* arm64.c - core analysis suite
*
- * Copyright (C) 2012-2018 David Anderson
- * Copyright (C) 2012-2018 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2012-2019 David Anderson
+ * Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -209,6 +209,8 @@ arm64_init(int when)
ms->page_offset = ARM64_PAGE_OFFSET;
machdep->identity_map_base = ARM64_PAGE_OFFSET;
machdep->kvbase = ARM64_VA_START;
+ machdep->is_kvaddr = generic_is_kvaddr;
+ machdep->kvtop = arm64_kvtop;
ms->userspace_top = ARM64_USERSPACE_TOP;
if (machdep->flags & NEW_VMEMMAP) {
struct syment *sp;
@@ -262,11 +264,17 @@ arm64_init(int when)
break;
case 65536:
+ if (kernel_symbol_exists("idmap_ptrs_per_pgd") &&
+ readmem(symbol_value("idmap_ptrs_per_pgd"), KVADDR,
+ &value, sizeof(ulong), "idmap_ptrs_per_pgd", RETURN_ON_ERROR))
+ machdep->ptrs_per_pgd = value;
+
if (machdep->machspec->VA_BITS > PGDIR_SHIFT_L3_64K) {
machdep->flags |= VM_L3_64K;
- machdep->ptrs_per_pgd = PTRS_PER_PGD_L3_64K;
+ if (!machdep->ptrs_per_pgd)
+ machdep->ptrs_per_pgd = PTRS_PER_PGD_L3_64K;
if ((machdep->pgd =
- (char *)malloc(PTRS_PER_PGD_L3_64K * 8)) == NULL)
+ (char *)malloc(machdep->ptrs_per_pgd * 8)) == NULL)
error(FATAL, "cannot malloc pgd space.");
if ((machdep->pmd =
(char *)malloc(PTRS_PER_PMD_L3_64K * 8)) == NULL)
@@ -276,9 +284,10 @@ arm64_init(int when)
error(FATAL, "cannot malloc ptbl space.");
} else {
machdep->flags |= VM_L2_64K;
- machdep->ptrs_per_pgd = PTRS_PER_PGD_L2_64K;
+ if (!machdep->ptrs_per_pgd)
+ machdep->ptrs_per_pgd = PTRS_PER_PGD_L2_64K;
if ((machdep->pgd =
- (char *)malloc(PTRS_PER_PGD_L2_64K * 8)) == NULL)
+ (char *)malloc(machdep->ptrs_per_pgd * 8)) == NULL)
error(FATAL, "cannot malloc pgd space.");
if ((machdep->ptbl =
(char *)malloc(PTRS_PER_PTE_L2_64K * 8)) == NULL)
@@ -306,9 +315,11 @@ arm64_init(int when)
machdep->flags |= VMEMMAP;
machdep->uvtop = arm64_uvtop;
- machdep->kvtop = arm64_kvtop;
- machdep->is_kvaddr = generic_is_kvaddr;
machdep->is_uvaddr = arm64_is_uvaddr;
+ if (kernel_symbol_exists("vabits_user") &&
+ readmem(symbol_value("vabits_user"), KVADDR,
+ &value, sizeof(ulong), "vabits_user", RETURN_ON_ERROR))
+ machdep->machspec->vabits_user = value;
machdep->eframe_search = arm64_eframe_search;
machdep->back_trace = arm64_back_trace_cmd;
machdep->in_alternate_stack = arm64_in_alternate_stack;
@@ -350,10 +361,14 @@ arm64_init(int when)
case POST_GDB:
arm64_calc_virtual_memory_ranges();
machdep->section_size_bits = _SECTION_SIZE_BITS;
- if (THIS_KERNEL_VERSION >= LINUX(3,17,0))
- machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_3_17;
- else
- machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
+ if (!machdep->max_physmem_bits) {
+ if (machdep->machspec->VA_BITS == 52) /* guess */
+ machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_52;
+ else if (THIS_KERNEL_VERSION >= LINUX(3,17,0))
+ machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_3_17;
+ else
+ machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
+ }
ms = machdep->machspec;
if (THIS_KERNEL_VERSION >= LINUX(4,0,0)) {
@@ -601,6 +616,11 @@ arm64_dump_machdep_table(ulong arg)
fprintf(fp, " machspec: %lx\n", (ulong)ms);
fprintf(fp, " VA_BITS: %ld\n", ms->VA_BITS);
+ fprintf(fp, " vabits_user: ");
+ if (ms->vabits_user)
+ fprintf(fp, "%ld\n", ms->vabits_user);
+ else
+ fprintf(fp, "(unused)\n");
fprintf(fp, " userspace_top: %016lx\n", ms->userspace_top);
fprintf(fp, " page_offset: %016lx\n", ms->page_offset);
fprintf(fp, " vmalloc_start_addr: %016lx\n", ms->vmalloc_start_addr);
@@ -691,6 +711,8 @@ arm64_parse_machdep_arg_l(char *argstring, char *param, ulong *value)
*value = dtol(p, flags, &err);
if (!err)
*value = MEGABYTES(*value);
+ } else if (STRNEQ(argstring, "max_physmem_bits")) {
+ *value = dtol(p, flags, &err);
} else {
*value = htol(p, flags, &err);
}
@@ -750,6 +772,12 @@ arm64_parse_cmdline_args(void)
"setting kimage_voffset to: 0x%lx\n\n",
machdep->machspec->kimage_voffset);
continue;
+ } else if (arm64_parse_machdep_arg_l(arglist[i], "max_physmem_bits",
+ &machdep->max_physmem_bits)) {
+ error(NOTE,
+ "setting max_physmem_bits to: %ld\n\n",
+ machdep->max_physmem_bits);
+ continue;
}
error(WARNING, "ignoring --machdep option: %s\n",
@@ -1065,8 +1093,8 @@ arm64_vtop_2level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
fprintf(fp, "PAGE DIRECTORY: %lx\n", pgd);
pgd_base = (ulong *)pgd;
- FILL_PGD(pgd_base, KVADDR, PTRS_PER_PGD_L2_64K * sizeof(ulong));
- pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L2_64K) & (PTRS_PER_PGD_L2_64K - 1));
+ FILL_PGD(pgd_base, KVADDR, machdep->ptrs_per_pgd * sizeof(ulong));
+ pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L2_64K) & (machdep->ptrs_per_pgd - 1));
pgd_val = ULONG(machdep->pgd + PAGEOFFSET(pgd_ptr));
if (verbose)
fprintf(fp, " PGD: %lx => %lx\n", (ulong)pgd_ptr, pgd_val);
@@ -1129,8 +1157,8 @@ arm64_vtop_3level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
fprintf(fp, "PAGE DIRECTORY: %lx\n", pgd);
pgd_base = (ulong *)pgd;
- FILL_PGD(pgd_base, KVADDR, PTRS_PER_PGD_L3_64K * sizeof(ulong));
- pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L3_64K) & (PTRS_PER_PGD_L3_64K - 1));
+ FILL_PGD(pgd_base, KVADDR, machdep->ptrs_per_pgd * sizeof(ulong));
+ pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L3_64K) & (machdep->ptrs_per_pgd - 1));
pgd_val = ULONG(machdep->pgd + PGDIR_OFFSET_L3_64K(pgd_ptr));
if (verbose)
fprintf(fp, " PGD: %lx => %lx\n", (ulong)pgd_ptr, pgd_val);
diff --git a/crash.8 b/crash.8
index 8c11615..f9de36d 100644
--- a/crash.8
+++ b/crash.8
@@ -278,6 +278,7 @@ ARM:
ARM64:
phys_offset=<physical-address>
kimage_voffset=<kimage_voffset-value>
+ max_physmem_bits=<value>
X86:
page_offset=<CONFIG_PAGE_OFFSET-value>
.fi
diff --git a/defs.h b/defs.h
index b473972..05f2d17 100644
--- a/defs.h
+++ b/defs.h
@@ -3049,7 +3049,7 @@ typedef signed int s32;
#define PMD_SHIFT_L3_64K (29)
#define PMD_SIZE_L3_64K (1UL << PMD_SHIFT_L3_64K)
#define PMD_MASK_L3_64K (~(PMD_SIZE_L3_64K-1))
-#define PGDIR_OFFSET_L3_64K(X) (((ulong)(X)) & ((PTRS_PER_PGD_L3_64K * 8) - 1))
+#define PGDIR_OFFSET_L3_64K(X) (((ulong)(X)) & ((machdep->ptrs_per_pgd * 8) - 1))
/*
* 2-levels / 64K pages
@@ -3136,6 +3136,7 @@ typedef signed int s32;
#define _SECTION_SIZE_BITS 30
#define _MAX_PHYSMEM_BITS 40
#define _MAX_PHYSMEM_BITS_3_17 48
+#define _MAX_PHYSMEM_BITS_52 52
typedef unsigned long long __u64;
typedef unsigned long long u64;
@@ -3215,6 +3216,7 @@ struct machine_specific {
ulong kern_eframe_offset;
ulong machine_kexec_start;
ulong machine_kexec_end;
+ ulong vabits_user;
};
struct arm64_stackframe {
diff --git a/help.c b/help.c
index ff0c80b..ba15dec 100644
--- a/help.c
+++ b/help.c
@@ -179,6 +179,7 @@ char *program_usage_info[] = {
" ARM64:",
" phys_offset=<physical-address>",
" kimage_voffset=<kimage_voffset-value>",
+ " max_physmem_bits=<value>",
" X86:",
" page_offset=<CONFIG_PAGE_OFFSET-value>",
"",

View File

@ -1,23 +0,0 @@
commit 95daa11b82dfa6aa3e68ffc92e1282abc1b2b62a
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Jun 1 15:28:55 2018 -0400
Fix for the "bpf -t" option. Although highly unlikely, without the
patch, the target function name of a BPF bytecode call instruction
may fail to be resolved correctly.
(anderson@redhat.com)
diff --git a/bpf.c b/bpf.c
index ee1986f..427263d 100644
--- a/bpf.c
+++ b/bpf.c
@@ -1060,8 +1060,7 @@ static char *__func_get_name(const struct bpf_insn *insn,
return buff;
if (insn->src_reg != BPF_PSEUDO_CALL &&
- insn->imm >= 0 && insn->imm < __BPF_FUNC_MAX_ID &&
- func_id_str[insn->imm]) {
+ insn->imm >= 0 && insn->imm < __BPF_FUNC_MAX_ID) {
// return func_id_str[insn->imm];
if (!readmem(symbol_value("func_id_str") + (insn->imm * sizeof(void *)),
KVADDR, &func_id_ptr, sizeof(void *), "func_id_str pointer",

File diff suppressed because it is too large Load Diff

View File

@ -1,894 +0,0 @@
commit a10917ba3203aa8b20e2aa1b84dc12c1e17445e1
Author: Dave Anderson <anderson@redhat.com>
Date: Thu Jul 19 13:43:07 2018 -0400
Update for "ps" and "foreach" commands to display and recognize two
new process states, "ID" for the TASK_IDLE macro introduced in
Linux 4.2, and "NE" for the TASK_NEW bit introduced in Linux 4.8.
(k-hagio@ab.jp.nec.com)
diff --git a/help.c b/help.c
index 54bf9b4..83cda7c 100644
--- a/help.c
+++ b/help.c
@@ -837,7 +837,7 @@ char *help_foreach[] = {
" kernel perform the command(s) on all kernel threads.",
" active perform the command(s) on the active thread on each CPU.",
" state perform the command(s) on all tasks in the specified state, which",
-" may be one of: RU, IN, UN, ST, ZO, TR, SW, DE, WA or PA.\n",
+" may be one of: RU, IN, UN, ST, ZO, TR, SW, DE, WA, PA, ID or NE.\n",
" If none of the task-identifying arguments above are entered, the command",
" will be performed on all tasks.\n",
" command select one or more of the following commands to be run on the tasks",
@@ -1292,7 +1292,7 @@ char *help_ps[] = {
" 3. the CPU number that the task ran on last.",
" 4. the task_struct address or the kernel stack pointer of the process.",
" (see -s option below)",
-" 5. the task state (RU, IN, UN, ZO, ST, TR, DE, SW, WA, PA).",
+" 5. the task state (RU, IN, UN, ZO, ST, TR, DE, SW, WA, PA, ID, NE).",
" 6. the percentage of physical memory being used by this task.",
" 7. the virtual address size of this task in kilobytes.",
" 8. the resident set size of this task in kilobytes.",
diff --git a/task.c b/task.c
index 1b32629..39fb0de 100644
--- a/task.c
+++ b/task.c
@@ -5172,6 +5172,7 @@ static long _WAKING_ = TASK_STATE_UNINITIALIZED;
static long _NONINTERACTIVE_ = TASK_STATE_UNINITIALIZED;
static long _PARKED_ = TASK_STATE_UNINITIALIZED;
static long _NOLOAD_ = TASK_STATE_UNINITIALIZED;
+static long _NEW_ = TASK_STATE_UNINITIALIZED;
#define valid_task_state(X) ((X) != TASK_STATE_UNINITIALIZED)
@@ -5249,6 +5250,10 @@ dump_task_states(void)
if (valid_task_state(_NOLOAD_))
fprintf(fp, " NOLOAD: %3ld (0x%lx)\n",
_NOLOAD_, _NOLOAD_);
+
+ if (valid_task_state(_NEW_))
+ fprintf(fp, " NEW: %3ld (0x%lx)\n",
+ _NEW_, _NEW_);
}
@@ -5282,6 +5287,7 @@ old_defaults:
/*
* If the later version of stat_nam[] array exists that contains
* WAKING, WAKEKILL and PARKED, use it instead of task_state_array[].
+ * Available since kernel version 2.6.33 to 4.13.
*/
if (((len = get_array_length("stat_nam", NULL, 0)) > 0) &&
read_string(symbol_value("stat_nam"), buf, BUFSIZE-1) &&
@@ -5331,6 +5337,9 @@ old_defaults:
case 'N':
_NOLOAD_ = (1 << (i-1));
break;
+ case 'n':
+ _NEW_ = (1 << (i-1));
+ break;
}
}
@@ -5393,7 +5402,16 @@ old_defaults:
_NONINTERACTIVE_ = 64;
}
- if (THIS_KERNEL_VERSION >= LINUX(2,6,32)) {
+ if (THIS_KERNEL_VERSION >= LINUX(4,14,0)) {
+ if (valid_task_state(_PARKED_)) {
+ bitpos = _PARKED_;
+ _DEAD_ |= (bitpos << 1); /* TASK_DEAD */
+ _WAKEKILL_ = (bitpos << 2); /* TASK_WAKEKILL */
+ _WAKING_ = (bitpos << 3); /* TASK_WAKING */
+ _NOLOAD_ = (bitpos << 4); /* TASK_NOLOAD */
+ _NEW_ = (bitpos << 5); /* TASK_NEW */
+ }
+ } else if (THIS_KERNEL_VERSION >= LINUX(2,6,32)) {
/*
* Account for states not listed in task_state_array[]
*/
@@ -5481,6 +5499,10 @@ task_state_string_verbose(ulong task, char *buf)
sprintf(&buf[strlen(buf)], "%sTASK_NOLOAD",
count++ ? "|" : "");
+ if (valid_task_state(_NEW_) && (state & _NEW_))
+ sprintf(&buf[strlen(buf)], "%sTASK_NEW",
+ count++ ? "|" : "");
+
if (valid_task_state(_NONINTERACTIVE_) &&
(state & _NONINTERACTIVE_))
sprintf(&buf[strlen(buf)], "%sTASK_NONINTERACTIVE",
@@ -5530,7 +5552,11 @@ task_state_string(ulong task, char *buf, int verbose)
}
if (state & _UNINTERRUPTIBLE_) {
- sprintf(buf, "UN");
+ if (valid_task_state(_NOLOAD_) &&
+ (state & _NOLOAD_))
+ sprintf(buf, "ID");
+ else
+ sprintf(buf, "UN");
valid++;
set++;
}
@@ -5576,6 +5602,11 @@ task_state_string(ulong task, char *buf, int verbose)
valid++;
}
+ if (state == _NEW_) {
+ sprintf(buf, "NE");
+ valid++;
+ }
+
if (valid && exclusive)
strcat(buf, "EX");
@@ -6273,6 +6304,8 @@ cmd_foreach(void)
STREQ(args[optind], "DE") ||
STREQ(args[optind], "PA") ||
STREQ(args[optind], "WA") ||
+ STREQ(args[optind], "ID") ||
+ STREQ(args[optind], "NE") ||
STREQ(args[optind], "SW")) {
if (fd->flags & FOREACH_STATE)
@@ -6298,6 +6331,10 @@ cmd_foreach(void)
fd->state = _PARKED_;
else if (STREQ(args[optind], "WA"))
fd->state = _WAKING_;
+ else if (STREQ(args[optind], "ID"))
+ fd->state = _UNINTERRUPTIBLE_|_NOLOAD_;
+ else if (STREQ(args[optind], "NE"))
+ fd->state = _NEW_;
if (fd->state == TASK_STATE_UNINITIALIZED)
error(FATAL,
@@ -6678,6 +6715,19 @@ foreach(struct foreach_data *fd)
if (fd->state == _RUNNING_) {
if (task_state(tc->task) != _RUNNING_)
continue;
+ } else if (fd->state & _UNINTERRUPTIBLE_) {
+ if (!(task_state(tc->task) & _UNINTERRUPTIBLE_))
+ continue;
+
+ if (valid_task_state(_NOLOAD_)) {
+ if (fd->state & _NOLOAD_) {
+ if (!(task_state(tc->task) & _NOLOAD_))
+ continue;
+ } else {
+ if ((task_state(tc->task) & _NOLOAD_))
+ continue;
+ }
+ }
} else if (!(task_state(tc->task) & fd->state))
continue;
}
commit 6c39a3d39b799e1f3f26e8017bcfa458d38d3820
Author: Dave Anderson <anderson@redhat.com>
Date: Wed Aug 8 11:31:17 2018 -0400
Fix for running live on ARM64 kernels against /proc/kcore on kernels
configured with CONFIG_RANDOMIZE_BASE. Without the patch, depending
upon the hardware platform, the session may fail with the error message
"crash: vmlinux and /proc/kcore do not match!".
(anderson@redhat.com)
diff --git a/arm64.c b/arm64.c
index 150e7d7..4ee53ce 100644
--- a/arm64.c
+++ b/arm64.c
@@ -125,7 +125,8 @@ arm64_init(int when)
free(string);
}
- if (ms->kimage_voffset) {
+ if (ms->kimage_voffset ||
+ (ACTIVE() && (symbol_value_from_proc_kallsyms("kimage_voffset") != BADVAL))) {
machdep->flags |= NEW_VMEMMAP;
/*
@@ -771,6 +772,17 @@ arm64_calc_kimage_voffset(void)
char *p1;
int errflag;
FILE *iomem;
+ ulong kimage_voffset, vaddr;
+
+ if (pc->flags & PROC_KCORE) {
+ kimage_voffset = symbol_value_from_proc_kallsyms("kimage_voffset");
+ if ((kimage_voffset != BADVAL) &&
+ (READMEM(pc->mfd, &vaddr, sizeof(ulong),
+ kimage_voffset, KCORE_USE_VADDR) > 0)) {
+ ms->kimage_voffset = vaddr;
+ return;
+ }
+ }
if ((iomem = fopen("/proc/iomem", "r")) == NULL)
return;
@@ -838,16 +850,22 @@ arm64_calc_phys_offset(void)
int errflag;
FILE *iomem;
physaddr_t paddr;
+ ulong vaddr;
struct syment *sp;
if ((machdep->flags & NEW_VMEMMAP) &&
ms->kimage_voffset && (sp = kernel_symbol_search("memstart_addr"))) {
- if (pc->flags & PROC_KCORE)
+ if (pc->flags & PROC_KCORE) {
+ vaddr = symbol_value_from_proc_kallsyms("memstart_addr");
+ if (vaddr == BADVAL)
+ vaddr = sp->value;
paddr = KCORE_USE_VADDR;
- else
+ } else {
+ vaddr = sp->value;
paddr = sp->value - machdep->machspec->kimage_voffset;
+ }
if (READMEM(pc->mfd, &phys_offset, sizeof(phys_offset),
- sp->value, paddr) > 0) {
+ vaddr, paddr) > 0) {
ms->phys_offset = phys_offset;
return;
}
diff --git a/defs.h b/defs.h
index 5af82be..da2ae04 100644
--- a/defs.h
+++ b/defs.h
@@ -5067,6 +5067,7 @@ struct syment *per_cpu_symbol_search(char *);
int symbol_exists(char *s);
int kernel_symbol_exists(char *s);
struct syment *kernel_symbol_search(char *);
+ulong symbol_value_from_proc_kallsyms(char *);
int get_syment_array(char *, struct syment **, int);
void set_temporary_radix(unsigned int, unsigned int *);
void restore_current_radix(unsigned int);
diff --git a/symbols.c b/symbols.c
index 8ff1430..df84ee2 100644
--- a/symbols.c
+++ b/symbols.c
@@ -28,7 +28,6 @@ static void store_sysmap_symbols(void);
static ulong relocate(ulong, char *, int);
static int relocate_force(ulong, char *);
static void kaslr_init(void);
-static ulong symbol_value_from_proc_kallsyms(char *);
static void strip_module_symbol_end(char *s);
static int compare_syms(const void *, const void *);
static int compare_mods(const void *, const void *);
@@ -997,7 +996,7 @@ relocate_force(ulong symval, char *symname)
/*
* Get a symbol value from /proc/kallsyms.
*/
-static ulong
+ulong
symbol_value_from_proc_kallsyms(char *symname)
{
FILE *kp;
commit 455da1ae5c7f22ba870aa57e071dad340749bdcd
Author: Dave Anderson <anderson@redhat.com>
Date: Wed Aug 8 14:20:21 2018 -0400
Modify the output of the "kmem -[sS]" header and contents such that
the slab cache name string is moved from the second column to the
the last column. Since the slab cache name strings have become
increasingly longer over time, without the patch, the numerical
column contents may be skewed so far to the right that the output
becomes difficult to read.
(k-hagio@ab.jp.nec.com)
diff --git a/help.c b/help.c
index 83cda7c..a189038 100644
--- a/help.c
+++ b/help.c
@@ -6692,8 +6692,8 @@ char *help_kmem[] = {
" Find all of the combined slab/page structures that are used by",
" the kmalloc-8192 slab cache:\n",
" %s> kmem -s kmalloc-8192",
-" CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE",
-" ffff880215802e00 kmalloc-8192 8192 65 80 20 32k",
+" CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME",
+" ffff880215802e00 8192 65 80 20 32k kmalloc-8192",
" %s> kmem -m slab_cache | grep ffff880215802e00",
" ffffea0004117800 ffff880215802e00 ",
" ffffea00041ca600 ffff880215802e00 ",
@@ -6889,72 +6889,72 @@ char *help_kmem[] = {
" ",
" Display kmalloc() slab data:\n",
" %s> kmem -s",
-" CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE",
-" c02eadc0 kmem_cache 232 58 68 4 4k",
-" f79c2888 ip_vs_conn 128 0 0 0 4k",
-" f79c2970 tcp_tw_bucket 96 0 0 0 4k",
-" f79c2a58 tcp_bind_bucket 32 12 565 5 4k",
-" f79c2b40 tcp_open_request 64 0 59 1 4k",
-" f79c2c28 inet_peer_cache 64 1 59 1 4k",
-" f79c2d10 ip_fib_hash 32 11 339 3 4k",
-" f79c2df8 ip_dst_cache 160 8 120 5 4k",
-" f79c2ee0 arp_cache 128 1 30 1 4k",
-" c8402970 blkdev_requests 96 30208 37800 945 4k",
-" c8402a58 nfs_read_data 384 0 0 0 4k",
-" c8402b40 nfs_write_data 384 0 0 0 4k",
-" c8402c28 nfs_page 96 0 0 0 4k",
-" c8402d10 dnotify cache 20 0 0 0 4k",
-" c8402df8 file lock cache 92 3 336 8 4k",
-" c8402ee0 fasync cache 16 0 0 0 4k",
-" c84027a0 uid_cache 32 3 339 3 4k",
-" c84026b8 skbuff_head_cache 160 320 624 26 4k",
-" c84025d0 sock 832 32 180 20 8k",
-" c84024e8 sigqueue 132 0 203 7 4k",
-" c8402400 cdev_cache 64 19 472 8 4k",
-" c8402318 bdev_cache 64 8 236 4 4k",
-" c8402230 mnt_cache 96 11 120 3 4k",
-" c8402148 inode_cache 480 817 848 106 4k",
-" c8402060 dentry_cache 128 1352 1470 49 4k",
-" c8403ee0 filp 96 244 440 11 4k",
-" c8403df8 names_cache 4096 0 12 12 4k",
-" c8403d10 buffer_head 96 14936 16000 400 4k",
-" c8403c28 mm_struct 128 25 240 8 4k",
-" c8403b40 vm_area_struct 64 393 1298 22 4k",
-" c8403a58 fs_cache 64 30 472 8 4k",
-" c8403970 files_cache 416 30 135 15 4k",
-" c8403888 signal_act 1312 32 99 33 4k",
-" c84037a0 size-131072(DMA) 131072 0 0 0 128k",
-" c84036b8 size-131072 131072 1 1 1 128k",
-" c84035d0 size-65536(DMA) 65536 0 0 0 64k",
-" c84034e8 size-65536 65536 0 0 0 64k",
-" c8403400 size-32768(DMA) 32768 0 0 0 32k",
-" c8403318 size-32768 32768 0 1 1 32k",
-" c8403230 size-16384(DMA) 16384 0 0 0 16k",
-" c8403148 size-16384 16384 0 0 0 16k",
-" c8403060 size-8192(DMA) 8192 0 0 0 8k",
-" c8401ee0 size-8192 8192 1 2 2 8k",
-" c8401df8 size-4096(DMA) 4096 0 0 0 4k",
-" c8401d10 size-4096 4096 30 30 30 4k",
-" c8401c28 size-2048(DMA) 2048 0 0 0 4k",
-" c8401b40 size-2048 2048 37 132 66 4k",
-" c8401a58 size-1024(DMA) 1024 0 0 0 4k",
-" c8401970 size-1024 1024 301 328 82 4k",
-" c8401888 size-512(DMA) 512 0 0 0 4k",
-" c84017a0 size-512 512 141 168 21 4k",
-" c84016b8 size-256(DMA) 256 0 0 0 4k",
-" c84015d0 size-256 256 80 435 29 4k",
-" c84014e8 size-128(DMA) 128 0 0 0 4k",
-" c8401400 size-128 128 508 840 28 4k",
-" c8401318 size-64(DMA) 64 0 0 0 4k",
-" c8401230 size-64 64 978 1357 23 4k",
-" c8401148 size-32(DMA) 32 0 0 0 4k",
-" c8401060 size-32 32 1244 1808 16 4k",
+" CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME",
+" c02eadc0 232 58 68 4 4k kmem_cache",
+" f79c2888 128 0 0 0 4k ip_vs_conn",
+" f79c2970 96 0 0 0 4k tcp_tw_bucket",
+" f79c2a58 32 12 565 5 4k tcp_bind_bucket",
+" f79c2b40 64 0 59 1 4k tcp_open_request",
+" f79c2c28 64 1 59 1 4k inet_peer_cache",
+" f79c2d10 32 11 339 3 4k ip_fib_hash",
+" f79c2df8 160 8 120 5 4k ip_dst_cache",
+" f79c2ee0 128 1 30 1 4k arp_cache",
+" c8402970 96 30208 37800 945 4k blkdev_requests",
+" c8402a58 384 0 0 0 4k nfs_read_data",
+" c8402b40 384 0 0 0 4k nfs_write_data",
+" c8402c28 96 0 0 0 4k nfs_page",
+" c8402d10 20 0 0 0 4k dnotify cache",
+" c8402df8 92 3 336 8 4k file lock cache",
+" c8402ee0 16 0 0 0 4k fasync cache",
+" c84027a0 32 3 339 3 4k uid_cache",
+" c84026b8 160 320 624 26 4k skbuff_head_cache",
+" c84025d0 832 32 180 20 8k sock",
+" c84024e8 132 0 203 7 4k sigqueue",
+" c8402400 64 19 472 8 4k cdev_cache",
+" c8402318 64 8 236 4 4k bdev_cache",
+" c8402230 96 11 120 3 4k mnt_cache",
+" c8402148 480 817 848 106 4k inode_cache",
+" c8402060 128 1352 1470 49 4k dentry_cache",
+" c8403ee0 96 244 440 11 4k filp",
+" c8403df8 4096 0 12 12 4k names_cache",
+" c8403d10 96 14936 16000 400 4k buffer_head",
+" c8403c28 128 25 240 8 4k mm_struct",
+" c8403b40 64 393 1298 22 4k vm_area_struct",
+" c8403a58 64 30 472 8 4k fs_cache",
+" c8403970 416 30 135 15 4k files_cache",
+" c8403888 1312 32 99 33 4k signal_act",
+" c84037a0 131072 0 0 0 128k size-131072(DMA)",
+" c84036b8 131072 1 1 1 128k size-131072",
+" c84035d0 65536 0 0 0 64k size-65536(DMA)",
+" c84034e8 65536 0 0 0 64k size-65536",
+" c8403400 32768 0 0 0 32k size-32768(DMA)",
+" c8403318 32768 0 1 1 32k size-32768",
+" c8403230 16384 0 0 0 16k size-16384(DMA)",
+" c8403148 16384 0 0 0 16k size-16384",
+" c8403060 8192 0 0 0 8k size-8192(DMA)",
+" c8401ee0 8192 1 2 2 8k size-8192",
+" c8401df8 4096 0 0 0 4k size-4096(DMA)",
+" c8401d10 4096 30 30 30 4k size-4096",
+" c8401c28 2048 0 0 0 4k size-2048(DMA)",
+" c8401b40 2048 37 132 66 4k size-2048",
+" c8401a58 1024 0 0 0 4k size-1024(DMA)",
+" c8401970 1024 301 328 82 4k size-1024",
+" c8401888 512 0 0 0 4k size-512(DMA)",
+" c84017a0 512 141 168 21 4k size-512",
+" c84016b8 256 0 0 0 4k size-256(DMA)",
+" c84015d0 256 80 435 29 4k size-256",
+" c84014e8 128 0 0 0 4k size-128(DMA)",
+" c8401400 128 508 840 28 4k size-128",
+" c8401318 64 0 0 0 4k size-64(DMA)",
+" c8401230 64 978 1357 23 4k size-64",
+" c8401148 32 0 0 0 4k size-32(DMA)",
+" c8401060 32 1244 1808 16 4k size-32",
" ",
" Display all slab data in the \"arp_cache\" cache:\n",
" %s> kmem -S arp_cache",
-" CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE",
-" f79c2ee0 arp_cache 128 1 30 1 4k",
+" CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME",
+" f79c2ee0 128 1 30 1 4k arp_cache",
" SLAB MEMORY TOTAL ALLOCATED FREE",
" f729d000 f729d0a0 30 1 29",
" FREE / [ALLOCATED]",
@@ -6991,8 +6991,8 @@ char *help_kmem[] = {
" ",
" Search the kmalloc() slab subsystem for address c3fbdb60:\n",
" %s> kmem -s c3fbdb60",
-" CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE",
-" c8402970 blkdev_requests 96 30208 37800 945 4k",
+" CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME",
+" c8402970 96 30208 37800 945 4k blkdev_requests",
" SLAB MEMORY TOTAL ALLOCATED FREE",
" c3fbd020 c3fbd0e0 40 40 0",
" FREE / [ALLOCATED]",
@@ -7000,8 +7000,8 @@ char *help_kmem[] = {
" ",
" Make a generic search (no flags) for the same address c3fbdb60:\n",
" %s> kmem c3fbdb60 ",
-" CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE",
-" c8402970 blkdev_requests 96 30208 37800 945 4k",
+" CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME",
+" c8402970 96 30208 37800 945 4k blkdev_requests",
" SLAB MEMORY TOTAL ALLOCATED FREE",
" c3fbd020 c3fbd0e0 40 40 0 ",
" FREE / [ALLOCATED]",
diff --git a/memory.c b/memory.c
index 81ed689..5bcf09e 100644
--- a/memory.c
+++ b/memory.c
@@ -172,7 +172,6 @@ static void dump_kmem_cache(struct meminfo *);
static void dump_kmem_cache_percpu_v1(struct meminfo *);
static void dump_kmem_cache_percpu_v2(struct meminfo *);
static void dump_kmem_cache_slub(struct meminfo *);
-static void dump_kmem_cache_info_v2(struct meminfo *);
static void kmem_cache_list_common(void);
static ulong get_cpu_slab_ptr(struct meminfo *, int, ulong *);
static unsigned int oo_order(ulong);
@@ -9379,7 +9378,7 @@ kmem_cache_init(void)
if (!strlen(kmem_cache_hdr))
sprintf(kmem_cache_hdr,
- "CACHE%sNAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE\n",
+ "CACHE%s OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME\n",
space(VADDR_PRLEN > 8 ? 12 : 4));
if (!strlen(free_inuse_hdr))
@@ -9964,55 +9963,36 @@ ignore_cache(struct meminfo *si, char *name)
#define KMEM_SLAB_OVERLOAD_PAGE (8)
#define KMEM_SLAB_FREELIST (9)
-#define DUMP_KMEM_CACHE_INFO_V1() \
- { \
- char b1[BUFSIZE]; \
- fprintf(fp, "%s %-18s %8ld ", \
- mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->cache)), \
- buf, si->size); \
- fprintf(fp, "%9ld %8ld %5ld %3ldk\n", \
- vt->flags & PERCPU_KMALLOC_V1 ? \
- si->inuse - si->cpucached_cache : \
- si->inuse, si->num_slabs * si->c_num, \
- si->num_slabs, si->slabsize/1024); \
- }
-
-#define DUMP_KMEM_CACHE_INFO_V2() dump_kmem_cache_info_v2(si)
+#define DUMP_KMEM_CACHE_INFO() dump_kmem_cache_info(si)
static void
-dump_kmem_cache_info_v2(struct meminfo *si)
+dump_kmem_cache_info(struct meminfo *si)
{
char b1[BUFSIZE];
- char b2[BUFSIZE];
- int namelen, sizelen, spacelen;
-
- fprintf(fp, "%s ",
- mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->cache)));
-
- namelen = strlen(si->curname);
- sprintf(b2, "%ld", si->size);
- sizelen = strlen(b2);
- spacelen = 0;
-
- if (namelen++ > 18) {
- spacelen = 29 - namelen - sizelen;
- fprintf(fp, "%s%s%ld ", si->curname,
- space(spacelen <= 0 ? 1 : spacelen), si->size);
- if (spacelen > 0)
- spacelen = 1;
- sprintf(b1, "%c%dld ", '%', 9 + spacelen - 1);
+ ulong objsize, allocated, total;
+
+ if (si->flags & SLAB_GATHER_FAILURE)
+ error(INFO, "%s: cannot gather relevant slab data\n", si->curname);
+
+ objsize = (vt->flags & KMALLOC_SLUB) ? si->objsize : si->size;
+
+ fprintf(fp, "%s %8ld ",
+ mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->cache)),
+ objsize);
+
+ if (si->flags & SLAB_GATHER_FAILURE) {
+ fprintf(fp, "%9s %8s %5s ", "?", "?", "?");
} else {
- fprintf(fp, "%-18s %8ld ", si->curname, si->size);
- sprintf(b1, "%c%dld ", '%', 9);
- }
+ allocated = (vt->flags & (PERCPU_KMALLOC_V1|PERCPU_KMALLOC_V2)) ?
+ si->inuse - si->cpucached_cache : si->inuse;
+ total = (vt->flags & KMALLOC_SLUB) ?
+ si->inuse + si->free : si->num_slabs * si->c_num;
- fprintf(fp, b1, vt->flags & (PERCPU_KMALLOC_V2) ?
- si->inuse - si->cpucached_cache : si->inuse);
+ fprintf(fp, "%9ld %8ld %5ld ",
+ allocated, total, si->num_slabs);
+ }
- fprintf(fp, "%8ld %s%5ld %s%3ldk\n",
- si->num_slabs * si->c_num,
- si->num_slabs < 100000 ? " " : "", si->num_slabs,
- (si->slabsize/1024) < 1000 ? " " : "", si->slabsize/1024);
+ fprintf(fp, "%4ldk %s\n", si->slabsize/1024, si->curname);
}
#define DUMP_SLAB_INFO() \
@@ -10152,7 +10132,7 @@ dump_kmem_cache(struct meminfo *si)
do_slab_chain(SLAB_GET_COUNTS, si);
if (!(si->flags & (ADDRESS_SPECIFIED|GET_SLAB_PAGES)))
- DUMP_KMEM_CACHE_INFO_V1();
+ DUMP_KMEM_CACHE_INFO();
if (si->flags == GET_SLAB_PAGES)
si->retval += (si->num_slabs *
@@ -10166,7 +10146,7 @@ dump_kmem_cache(struct meminfo *si)
if (si->found) {
fprintf(fp, "%s", kmem_cache_hdr);
- DUMP_KMEM_CACHE_INFO_V1();
+ DUMP_KMEM_CACHE_INFO();
fprintf(fp, "%s", slab_hdr);
DUMP_SLAB_INFO();
@@ -10362,7 +10342,7 @@ dump_kmem_cache_percpu_v1(struct meminfo *si)
do_slab_chain_percpu_v1(SLAB_GET_COUNTS, si);
if (!(si->flags & (ADDRESS_SPECIFIED|GET_SLAB_PAGES))) {
- DUMP_KMEM_CACHE_INFO_V1();
+ DUMP_KMEM_CACHE_INFO();
if (CRASHDEBUG(3))
dump_struct("kmem_cache_s", si->cache, 0);
}
@@ -10382,7 +10362,7 @@ dump_kmem_cache_percpu_v1(struct meminfo *si)
if (si->found) {
fprintf(fp, "%s", kmem_cache_hdr);
- DUMP_KMEM_CACHE_INFO_V1();
+ DUMP_KMEM_CACHE_INFO();
fprintf(fp, "%s", slab_hdr);
gather_slab_cached_count(si);
DUMP_SLAB_INFO();
@@ -10617,7 +10597,7 @@ dump_kmem_cache_percpu_v2(struct meminfo *si)
do_slab_chain_percpu_v2(SLAB_GET_COUNTS, si);
if (!(si->flags & (ADDRESS_SPECIFIED|GET_SLAB_PAGES))) {
- DUMP_KMEM_CACHE_INFO_V2();
+ DUMP_KMEM_CACHE_INFO();
if (CRASHDEBUG(3))
dump_struct("kmem_cache_s", si->cache, 0);
}
@@ -10644,7 +10624,7 @@ dump_kmem_cache_percpu_v2(struct meminfo *si)
if (si->found) {
fprintf(fp, "%s", kmem_cache_hdr);
- DUMP_KMEM_CACHE_INFO_V2();
+ DUMP_KMEM_CACHE_INFO();
fprintf(fp, "%s", slab_hdr);
gather_slab_cached_count(si);
DUMP_SLAB_INFO();
@@ -18064,56 +18044,6 @@ kmem_cache_list_common(void)
FREEBUF(cache_list);
}
-#define DUMP_KMEM_CACHE_INFO_SLUB() dump_kmem_cache_info_slub(si)
-
-static void
-dump_kmem_cache_info_slub(struct meminfo *si)
-{
- char b1[BUFSIZE];
- char b2[BUFSIZE];
- int namelen, sizelen, spacelen;
-
- if (si->flags & SLAB_GATHER_FAILURE)
- error(INFO, "%s: cannot gather relevant slab data\n", si->curname);
-
- fprintf(fp, "%s ",
- mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->cache)));
-
- namelen = strlen(si->curname);
- sprintf(b2, "%ld", si->objsize);
- sizelen = strlen(b2);
- spacelen = 0;
-
- if (namelen++ > 18) {
- spacelen = 29 - namelen - sizelen;
- fprintf(fp, "%s%s%ld ", si->curname,
- space(spacelen <= 0 ? 1 : spacelen), si->objsize);
- if (spacelen > 0)
- spacelen = 1;
- if (si->flags & SLAB_GATHER_FAILURE)
- sprintf(b1, "%c%ds ", '%', 9 + spacelen - 1);
- else
- sprintf(b1, "%c%dld ", '%', 9 + spacelen - 1);
- } else {
- fprintf(fp, "%-18s %8ld ", si->curname, si->objsize);
- if (si->flags & SLAB_GATHER_FAILURE)
- sprintf(b1, "%c%ds ", '%', 9);
- else
- sprintf(b1, "%c%dld ", '%', 9);
- }
-
- if (si->flags & SLAB_GATHER_FAILURE) {
- fprintf(fp, b1, "?");
- fprintf(fp, "%8s %5s %4ldk\n",
- "?", "?", si->slabsize/1024);
- } else {
- fprintf(fp, b1, si->inuse);
- fprintf(fp, "%8ld %5ld %4ldk\n",
- si->inuse + si->free,
- si->num_slabs, si->slabsize/1024);
- }
-}
-
static void
dump_kmem_cache_slub(struct meminfo *si)
{
@@ -18214,7 +18144,7 @@ dump_kmem_cache_slub(struct meminfo *si)
!get_kmem_cache_slub_data(GET_SLUB_OBJECTS, si))
si->flags |= SLAB_GATHER_FAILURE;
- DUMP_KMEM_CACHE_INFO_SLUB();
+ DUMP_KMEM_CACHE_INFO();
if (si->flags & SLAB_GATHER_FAILURE) {
si->flags &= ~SLAB_GATHER_FAILURE;
commit ba03b66cec24fc0033d4378be08f5f9a96cd4a91
Author: Dave Anderson <anderson@redhat.com>
Date: Thu Aug 9 10:54:46 2018 -0400
Fix for the "files" and "net -s" commands when a task has an open
files count that exceeds 1024 (FD_SETSIZE) file descriptors. Without
the patch, the commands may omit the display of open file descriptors.
(tan.hu@zte.com.cn)
diff --git a/filesys.c b/filesys.c
index 0ace8f4..47f5a24 100644
--- a/filesys.c
+++ b/filesys.c
@@ -2380,7 +2380,8 @@ open_files_dump(ulong task, int flags, struct reference *ref)
int max_fdset = 0;
int max_fds = 0;
ulong open_fds_addr;
- fd_set open_fds;
+ int open_fds_size;
+ ulong *open_fds;
ulong fd;
ulong file;
ulong value;
@@ -2583,16 +2584,25 @@ open_files_dump(ulong task, int flags, struct reference *ref)
open_fds_addr = ULONG(files_struct_buf +
OFFSET(files_struct_open_fds));
+ open_fds_size = MAX(max_fdset, max_fds) / BITS_PER_BYTE;
+ open_fds = (ulong *)GETBUF(open_fds_size);
+ if (!open_fds) {
+ if (fdtable_buf)
+ FREEBUF(fdtable_buf);
+ FREEBUF(files_struct_buf);
+ return;
+ }
+
if (open_fds_addr) {
if (VALID_MEMBER(files_struct_open_fds_init) &&
(open_fds_addr == (files_struct_addr +
OFFSET(files_struct_open_fds_init))))
BCOPY(files_struct_buf +
OFFSET(files_struct_open_fds_init),
- &open_fds, sizeof(fd_set));
+ open_fds, open_fds_size);
else
- readmem(open_fds_addr, KVADDR, &open_fds,
- sizeof(fd_set), "fdtable open_fds",
+ readmem(open_fds_addr, KVADDR, open_fds,
+ open_fds_size, "fdtable open_fds",
FAULT_ON_ERROR);
}
@@ -2607,6 +2617,7 @@ open_files_dump(ulong task, int flags, struct reference *ref)
if (fdtable_buf)
FREEBUF(fdtable_buf);
FREEBUF(files_struct_buf);
+ FREEBUF(open_fds);
return;
}
@@ -2617,11 +2628,11 @@ open_files_dump(ulong task, int flags, struct reference *ref)
j = 0;
for (;;) {
unsigned long set;
- i = j * __NFDBITS;
+ i = j * BITS_PER_LONG;
if (((max_fdset >= 0) && (i >= max_fdset)) ||
(i >= max_fds))
break;
- set = open_fds.__fds_bits[j++];
+ set = open_fds[j++];
while (set) {
if (set & 1) {
readmem(fd + i*sizeof(struct file *), KVADDR,
@@ -2665,6 +2676,7 @@ open_files_dump(ulong task, int flags, struct reference *ref)
if (fdtable_buf)
FREEBUF(fdtable_buf);
FREEBUF(files_struct_buf);
+ FREEBUF(open_fds);
}
/*
diff --git a/net.c b/net.c
index 4199091..f08f22a 100644
--- a/net.c
+++ b/net.c
@@ -1373,7 +1373,8 @@ dump_sockets_workhorse(ulong task, ulong flag, struct reference *ref)
int max_fdset = 0;
int max_fds = 0;
ulong open_fds_addr = 0;
- fd_set open_fds;
+ ulong *open_fds;
+ int open_fds_size;
ulong fd;
ulong file;
int i, j;
@@ -1446,12 +1447,18 @@ dump_sockets_workhorse(ulong task, ulong flag, struct reference *ref)
sizeof(void *), "files_struct fd addr", FAULT_ON_ERROR);
}
+ open_fds_size = MAX(max_fdset, max_fds) / BITS_PER_BYTE;
+ open_fds = (ulong *)GETBUF(open_fds_size);
+ if (!open_fds)
+ return;
+
if (open_fds_addr)
- readmem(open_fds_addr, KVADDR, &open_fds, sizeof(fd_set),
+ readmem(open_fds_addr, KVADDR, open_fds, open_fds_size,
"files_struct open_fds", FAULT_ON_ERROR);
if (!open_fds_addr || !fd) {
if (!NET_REFERENCE_CHECK(ref))
fprintf(fp, "No open sockets.\n");
+ FREEBUF(open_fds);
return;
}
@@ -1479,10 +1486,10 @@ dump_sockets_workhorse(ulong task, ulong flag, struct reference *ref)
j = 0;
for (;;) {
unsigned long set;
- i = j * __NFDBITS;
+ i = j * BITS_PER_LONG;
if (((max_fdset >= 0) && (i >= max_fdset)) || (i >= max_fds))
break;
- set = open_fds.__fds_bits[j++];
+ set = open_fds[j++];
while (set) {
if (set & 1) {
readmem(fd + i*sizeof(struct file *), KVADDR,
@@ -1505,6 +1512,8 @@ dump_sockets_workhorse(ulong task, ulong flag, struct reference *ref)
if (NET_REFERENCE_FOUND(ref))
fprintf(fp, "\n");
+
+ FREEBUF(open_fds);
}
commit e9532aea6818b347bc0740f39efd4ec844cfb9b0
Author: Dave Anderson <anderson@redhat.com>
Date: Thu Aug 9 11:20:26 2018 -0400
As an addendum to the new "kmem -[sS]" output format, align the slab
cache name string so that it is beneath the "NAME" header column when
the "kmem -I &lt;slab-cache>" option is used to ignore a slab cache,
or if the scan of the metadata of a slab cache enounters corruption.
Also remove a superfluous line from the "help kmem" description of
the "kmem -I" option.
(k-hagio@ab.jp.nec.com, anderson@redhat.com)
diff --git a/help.c b/help.c
index a189038..aeeb056 100644
--- a/help.c
+++ b/help.c
@@ -6495,7 +6495,6 @@ char *help_kmem[] = {
" all slab cache names and addresses are listed.",
" -I slab when used with -s or -S, one or more slab cache names in a",
" comma-separated list may be specified as slab caches to ignore.",
-" their hugepage size, total and free counts, and name.",
" -g displays the enumerator value of all bits in the page structure's",
" \"flags\" field.",
" flags when used with -g, translates all bits in this hexadecimal page",
diff --git a/memory.c b/memory.c
index 5bcf09e..4790cf6 100644
--- a/memory.c
+++ b/memory.c
@@ -9963,6 +9963,9 @@ ignore_cache(struct meminfo *si, char *name)
#define KMEM_SLAB_OVERLOAD_PAGE (8)
#define KMEM_SLAB_FREELIST (9)
+#define DUMP_KMEM_CACHE_TAG(addr, name, tag) \
+ fprintf(fp, "%lx %-43s %s\n", addr, tag, name)
+
#define DUMP_KMEM_CACHE_INFO() dump_kmem_cache_info(si)
static void
@@ -10094,7 +10097,7 @@ dump_kmem_cache(struct meminfo *si)
goto next_cache;
if (ignore_cache(si, buf)) {
- fprintf(fp, "%lx %-18s [IGNORED]\n", si->cache, buf);
+ DUMP_KMEM_CACHE_TAG(si->cache, buf, "[IGNORED]");
goto next_cache;
}
@@ -10303,7 +10306,7 @@ dump_kmem_cache_percpu_v1(struct meminfo *si)
goto next_cache;
if (ignore_cache(si, buf)) {
- fprintf(fp, "%lx %-18s [IGNORED]\n", si->cache, buf);
+ DUMP_KMEM_CACHE_TAG(si->cache, buf, "[IGNORED]");
goto next_cache;
}
@@ -10547,12 +10550,12 @@ dump_kmem_cache_percpu_v2(struct meminfo *si)
goto next_cache;
if (ignore_cache(si, buf)) {
- fprintf(fp, "%lx %-18s [IGNORED]\n", si->cache, buf);
+ DUMP_KMEM_CACHE_TAG(si->cache, buf, "[IGNORED]");
goto next_cache;
}
if (bad_slab_cache(si->cache)) {
- fprintf(fp, "%lx %-18s [INVALID/CORRUPTED]\n", si->cache, buf);
+ DUMP_KMEM_CACHE_TAG(si->cache, buf, "[INVALID/CORRUPTED]");
goto next_cache;
}
@@ -18109,8 +18112,7 @@ dump_kmem_cache_slub(struct meminfo *si)
fprintf(fp, "%s", kmem_cache_hdr);
}
if (ignore_cache(si, buf)) {
- fprintf(fp, "%lx %-18s [IGNORED]\n",
- si->cache_list[i], buf);
+ DUMP_KMEM_CACHE_TAG(si->cache_list[i], buf, "[IGNORED]");
goto next_cache;
}

View File

@ -1,193 +0,0 @@
commit a89ec821cb5dbb106cb58e8740f84c7e382c0140
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Feb 8 11:12:23 2019 -0500
For live system analysis where there is no vmcoreinfo ELF note
attached to /proc/kcore, or for dumpfile analysis where there is no
vmcoreinfo ELF note attached to the dumpfile, this patch sets the
internal pc->read_vmcoreinfo() function to a new plugin function
that reads the data directly from the live kernel or dumpfile.
Because the function is set much later during initialization than
if the ELF note is attached to /proc/kcore or the dumpfile, it may
not be available during very early session initialization.
(anderson@redhat.com)
diff --git a/defs.h b/defs.h
index 05f2d17..5841b1f 100644
--- a/defs.h
+++ b/defs.h
@@ -4872,6 +4872,7 @@ int clean_exit(int);
int untrusted_file(FILE *, char *);
char *readmem_function_name(void);
char *writemem_function_name(void);
+char *no_vmcoreinfo(const char *);
/*
* cmdline.c
diff --git a/kernel.c b/kernel.c
index e512da5..9f5ba89 100644
--- a/kernel.c
+++ b/kernel.c
@@ -93,6 +93,8 @@ static void source_tree_init(void);
static ulong dump_audit_skb_queue(ulong);
static ulong __dump_audit(char *);
static void dump_audit(void);
+static char *vmcoreinfo_read_string(const char *);
+static void check_vmcoreinfo(void);
/*
@@ -127,6 +129,8 @@ kernel_init()
kt->end = highest_bss_symbol();
if ((sp1 = kernel_symbol_search("_end")) && (sp1->value > kt->end))
kt->end = sp1->value;
+
+ check_vmcoreinfo();
/*
* For the traditional (non-pv_ops) Xen architecture, default to writable
@@ -11117,3 +11121,84 @@ dump_audit(void)
if (!qlen)
error(INFO, "kernel audit log is empty\n");
}
+
+/*
+ * Reads a string value from the VMCOREINFO data stored in (live) memory.
+ *
+ * Returns a string (that has to be freed by the caller) that contains the
+ * value for key or NULL if the key has not been found.
+ */
+static char *
+vmcoreinfo_read_string(const char *key)
+{
+ char *buf, *value_string, *p1, *p2;
+ size_t value_length;
+ size_t vmcoreinfo_size;
+ ulong vmcoreinfo_data;
+ char keybuf[BUFSIZE];
+
+ buf = value_string = NULL;
+
+ switch (get_symbol_type("vmcoreinfo_data", NULL, NULL))
+ {
+ case TYPE_CODE_PTR:
+ get_symbol_data("vmcoreinfo_data", sizeof(vmcoreinfo_data), &vmcoreinfo_data);
+ break;
+ case TYPE_CODE_ARRAY:
+ vmcoreinfo_data = symbol_value("vmcoreinfo_data");
+ break;
+ default:
+ return NULL;
+ }
+
+ get_symbol_data("vmcoreinfo_size", sizeof(vmcoreinfo_size), &vmcoreinfo_size);
+
+ sprintf(keybuf, "%s=", key);
+
+ if ((buf = malloc(vmcoreinfo_size+1)) == NULL) {
+ error(INFO, "cannot malloc vmcoreinfo buffer\n");
+ goto err;
+ }
+
+ if (!readmem(vmcoreinfo_data, KVADDR, buf, vmcoreinfo_size,
+ "vmcoreinfo_data", RETURN_ON_ERROR|QUIET)) {
+ error(INFO, "cannot read vmcoreinfo_data\n");
+ goto err;
+ }
+
+ buf[vmcoreinfo_size] = '\n';
+
+ if ((p1 = strstr(buf, keybuf))) {
+ p2 = p1 + strlen(keybuf);
+ p1 = strstr(p2, "\n");
+ value_length = p1-p2;
+ value_string = calloc(value_length+1, sizeof(char));
+ strncpy(value_string, p2, value_length);
+ value_string[value_length] = NULLCHAR;
+ }
+err:
+ if (buf)
+ free(buf);
+
+ return value_string;
+}
+
+static void
+check_vmcoreinfo(void)
+{
+ if (!kernel_symbol_exists("vmcoreinfo_data") ||
+ !kernel_symbol_exists("vmcoreinfo_size"))
+ return;
+
+ if (pc->read_vmcoreinfo == no_vmcoreinfo) {
+ switch (get_symbol_type("vmcoreinfo_data", NULL, NULL))
+ {
+ case TYPE_CODE_PTR:
+ pc->read_vmcoreinfo = vmcoreinfo_read_string;
+ break;
+ case TYPE_CODE_ARRAY:
+ pc->read_vmcoreinfo = vmcoreinfo_read_string;
+ break;
+ }
+ }
+}
diff --git a/main.c b/main.c
index 7248810..cd282cd 100644
--- a/main.c
+++ b/main.c
@@ -1,8 +1,8 @@
/* main.c - core analysis suite
*
* Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
- * Copyright (C) 2002-2018 David Anderson
- * Copyright (C) 2002-2018 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2002-2019 David Anderson
+ * Copyright (C) 2002-2019 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,7 +29,6 @@ static void check_xen_hyper(void);
static void show_untrusted_files(void);
static void get_osrelease(char *);
static void get_log(char *);
-static char *no_vmcoreinfo(const char *);
static struct option long_options[] = {
{"memory_module", required_argument, 0, 0},
@@ -1950,7 +1949,7 @@ get_log(char *dumpfile)
}
-static char *
+char *
no_vmcoreinfo(const char *unused)
{
return NULL;
diff --git a/netdump.c b/netdump.c
index d0179e0..5aeea6f 100644
--- a/netdump.c
+++ b/netdump.c
@@ -1,7 +1,7 @@
/* netdump.c
*
- * Copyright (C) 2002-2018 David Anderson
- * Copyright (C) 2002-2018 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2002-2019 David Anderson
+ * Copyright (C) 2002-2019 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1786,11 +1786,13 @@ vmcoreinfo_read_string(const char *key)
if (STREQ(key, "NUMBER(kimage_voffset)") && nd->arch_data) {
value = calloc(VADDR_PRLEN+1, sizeof(char));
sprintf(value, "%lx", nd->arch_data);
+ pc->read_vmcoreinfo = no_vmcoreinfo;
return value;
}
if (STREQ(key, "relocate") && nd->arch_data) {
value = calloc(VADDR_PRLEN+1, sizeof(char));
sprintf(value, "%lx", nd->arch_data);
+ pc->read_vmcoreinfo = no_vmcoreinfo;
return value;
}
}

View File

@ -1,29 +0,0 @@
commit ac5a7889d31bb37aa0687110ecea08837f8a66a8
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Feb 8 10:48:30 2019 -0500
Support for configurable CONFIG_ARM64_PA_BITS values introduced
in kernel commit 982aa7c5f0861bf56b2412ca341a13f44c238ba4, titled
"arm64: add kconfig symbol to configure physical address size".
Without the patch, it is impossible to determine the value of
CONFIG_ARM64_PA_BITS, and will require a new MAX_PHYSMEM_BITS
vmcoreinfo entry to be exported. This patch reads that entry
during intitialization.
(anderson@redhat.com)
diff --git a/arm64.c b/arm64.c
index 2308612..b4d9b13 100644
--- a/arm64.c
+++ b/arm64.c
@@ -362,7 +362,10 @@ arm64_init(int when)
arm64_calc_virtual_memory_ranges();
machdep->section_size_bits = _SECTION_SIZE_BITS;
if (!machdep->max_physmem_bits) {
- if (machdep->machspec->VA_BITS == 52) /* guess */
+ if ((string = pc->read_vmcoreinfo("NUMBER(MAX_PHYSMEM_BITS)"))) {
+ machdep->max_physmem_bits = atol(string);
+ free(string);
+ } 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))
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_3_17;

View File

@ -1,149 +0,0 @@
commit b9d76838372d1b4087bb506ce6da425afad68876
Author: Dave Anderson <anderson@redhat.com>
Date: Thu Jun 7 13:20:16 2018 -0400
If /proc/kcore gets selected for the live memory source because
/dev/mem was configured with CONFIG_STRICT_DEVMEM, its ELF header
contents are not displayed by "help -[dD]", and are not displayed
when the crash session is invoked with -d<number>". Without the
patch, the ELF contents are only displayed in those two situations
if "/proc/kcore" is explicitly entered on the crash command line.
(anderson@redhat.com)
diff --git a/netdump.c b/netdump.c
index 25683eb..1f3e26c 100644
--- a/netdump.c
+++ b/netdump.c
@@ -4334,11 +4334,8 @@ kcore_memory_dump(FILE *ofp)
Elf32_Phdr *lp32;
Elf64_Phdr *lp64;
- if (!(pkd->flags & KCORE_LOCAL))
- return FALSE;
-
fprintf(ofp, "proc_kcore_data:\n");
- fprintf(ofp, " flags: %lx (", nd->flags);
+ fprintf(ofp, " flags: %x (", pkd->flags);
others = 0;
if (pkd->flags & KCORE_LOCAL)
fprintf(ofp, "%sKCORE_LOCAL", others++ ? "|" : "");
commit c79a11fa10da94b71ddf341ec996c522fbd75237
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Jun 8 14:31:08 2018 -0400
If the default live memory source /dev/mem is determined to be
unusable because the kernel was configured with CONFIG_STRICT_DEVMEM,
the first memory read during session initialization will fail. The
current behavior results in a readmem() error message, followed by two
notification messages that indicate that /dev/mem is restricted and
a switch to using /proc/kcore will be attempted; the readmem is
reattempted from /proc/kcore, and if successful, the session will
continue initialization. With this patch, the behavior will change
such that if the switch to /proc/kcore and the reattempted readmem()
are successful, no messages will be displayed unless the crash
session is invoked with "crash -d&lt;number>".
(anderson@redhat.com)
diff --git a/kernel.c b/kernel.c
index 138a47f..3cd5bf1 100644
--- a/kernel.c
+++ b/kernel.c
@@ -882,7 +882,7 @@ cpu_maps_init(void)
{
int i, c, m, cpu, len;
char *buf;
- ulong *maskptr, addr;
+ ulong *maskptr, addr, error_handle;
struct mapinfo {
ulong cpu_flag;
char *name;
@@ -902,8 +902,9 @@ cpu_maps_init(void)
if (!(addr = cpu_map_addr(mapinfo[m].name)))
continue;
+ error_handle = pc->flags & DEVMEM ? RETURN_ON_ERROR|QUIET : RETURN_ON_ERROR;
if (!readmem(addr, KVADDR, buf, len,
- mapinfo[m].name, RETURN_ON_ERROR)) {
+ mapinfo[m].name, error_handle)) {
error(WARNING, "cannot read cpu_%s_map\n",
mapinfo[m].name);
continue;
diff --git a/memory.c b/memory.c
index 82f9cbf..2f568d5 100644
--- a/memory.c
+++ b/memory.c
@@ -2243,9 +2243,11 @@ readmem(ulonglong addr, int memtype, void *buffer, long size,
error(INFO, READ_ERRMSG, memtype_string(memtype, 0), addr, type);
if ((pc->flags & DEVMEM) && (kt->flags & PRE_KERNEL_INIT) &&
!(error_handle & NO_DEVMEM_SWITCH) && devmem_is_restricted() &&
- switch_to_proc_kcore())
+ switch_to_proc_kcore()) {
+ error_handle &= ~QUIET;
return(readmem(addr, memtype, bufptr, size,
type, error_handle));
+ }
goto readmem_error;
case PAGE_EXCLUDED:
@@ -2457,7 +2459,7 @@ devmem_is_restricted(void)
QUIET|RETURN_ON_ERROR|NO_DEVMEM_SWITCH))
restricted = TRUE;
- if (restricted)
+ if (restricted && CRASHDEBUG(1))
error(INFO,
"this kernel may be configured with CONFIG_STRICT_DEVMEM,"
" which\n renders /dev/mem unusable as a live memory "
@@ -2472,9 +2474,10 @@ switch_to_proc_kcore(void)
{
close(pc->mfd);
- if (file_exists("/proc/kcore", NULL))
- error(INFO, "trying /proc/kcore as an alternative to /dev/mem\n\n");
- else
+ if (file_exists("/proc/kcore", NULL)) {
+ if (CRASHDEBUG(1))
+ error(INFO, "trying /proc/kcore as an alternative to /dev/mem\n\n");
+ } else
return FALSE;
if ((pc->mfd = open("/proc/kcore", O_RDONLY)) < 0) {
diff --git a/ppc64.c b/ppc64.c
index 0b04187..0dd8a2a 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -1,7 +1,7 @@
/* ppc64.c -- core analysis suite
*
- * Copyright (C) 2004-2015,2017 David Anderson
- * Copyright (C) 2004-2015,2017 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2015,2018 David Anderson
+ * Copyright (C) 2004-2015,2018 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004, 2006 Haren Myneni, IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -343,8 +343,9 @@ ppc64_init(int when)
if (symbol_exists("vmemmap_populate")) {
if (symbol_exists("vmemmap")) {
- get_symbol_data("vmemmap", sizeof(void *),
- &machdep->machspec->vmemmap_base);
+ readmem(symbol_value("vmemmap"), KVADDR,
+ &machdep->machspec->vmemmap_base,
+ sizeof(void *), "vmemmap", QUIET|FAULT_ON_ERROR);
} else
machdep->machspec->vmemmap_base =
VMEMMAP_REGION_ID << REGION_SHIFT;
diff --git a/x86_64.c b/x86_64.c
index 54b6539..e01082b 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -356,7 +356,7 @@ x86_64_init(int when)
machdep->flags |= RANDOMIZED;
readmem(symbol_value("page_offset_base"), KVADDR,
&machdep->machspec->page_offset, sizeof(ulong),
- "page_offset_base", FAULT_ON_ERROR);
+ "page_offset_base", QUIET|FAULT_ON_ERROR);
machdep->kvbase = machdep->machspec->page_offset;
machdep->identity_map_base = machdep->machspec->page_offset;
}

View File

@ -1,239 +0,0 @@
commit c5f45d6cdbe7f01314857a75b2feef25b22adaaa
Author: Dave Anderson <anderson@redhat.com>
Date: Thu Oct 11 13:28:39 2018 -0400
Address several Coverity Scan "RESOURCE_LEAK" issues in the following
top-level source files: cmdline.c, kvmdump.c, lkcd_v8.c, xendump.c,
symbols.c, unwind_x86_32_64.c, va_server.c and va_server_v1.c.
(anderson@redhat.com)
diff --git a/cmdline.c b/cmdline.c
index c0a9f4f..cf3e150 100644
--- a/cmdline.c
+++ b/cmdline.c
@@ -1318,8 +1318,10 @@ is_shell_script(char *s)
if ((fd = open(s, O_RDONLY)) < 0)
return FALSE;
- if (isatty(fd))
+ if (isatty(fd)) {
+ close(fd);
return FALSE;
+ }
if (read(fd, interp, 2) != 2) {
close(fd);
diff --git a/kvmdump.c b/kvmdump.c
index 622619c..4db96bd 100644
--- a/kvmdump.c
+++ b/kvmdump.c
@@ -846,8 +846,10 @@ kvmdump_mapfile_exists(void)
sprintf(filename, "%s.map", pc->dumpfile);
- if (!file_exists(filename, &stat) || !S_ISREG(stat.st_mode))
+ if (!file_exists(filename, &stat) || !S_ISREG(stat.st_mode)) {
+ free(filename);
return FALSE;
+ }
if (is_kvmdump_mapfile(filename)) {
pc->kvmdump_mapfile = filename;
diff --git a/lkcd_v8.c b/lkcd_v8.c
index 1322250..3b355e0 100644
--- a/lkcd_v8.c
+++ b/lkcd_v8.c
@@ -184,6 +184,7 @@ lkcd_dump_init_v8_arch(dump_header_t *dh)
memcpy(&dump_header_asm_v8, &arch_hdr, sizeof(dump_header_asm_t));
+ free(hdr_buf);
return 0;
err:
diff --git a/symbols.c b/symbols.c
index b54b8c0..fb9cd1b 100644
--- a/symbols.c
+++ b/symbols.c
@@ -3862,12 +3862,10 @@ is_bfd_format(char *filename)
#else
struct bfd *bfd;
#endif
- char **matching;
-
if ((bfd = bfd_openr(filename, NULL)) == NULL)
return FALSE;
- if (!bfd_check_format_matches(bfd, bfd_object, &matching)) {
+ if (!bfd_check_format_matches(bfd, bfd_object, NULL)) {
bfd_close(bfd);
return FALSE;
}
diff --git a/unwind_x86_32_64.c b/unwind_x86_32_64.c
index c62f92f..c7c30d6 100644
--- a/unwind_x86_32_64.c
+++ b/unwind_x86_32_64.c
@@ -819,6 +819,7 @@ try_eh_frame:
error(WARNING, "cannot read %s data from %s\n",
is_ehframe ? ".eh_frame" : ".debug_frame", pc->namelist);
free(unwind_table);
+ close(fd);
return;
}
diff --git a/va_server.c b/va_server.c
index d96287a..96c2b5c 100644
--- a/va_server.c
+++ b/va_server.c
@@ -313,20 +313,27 @@ int read_map(char *crash_file)
ret = fseek(vas_file_p, (long)0, SEEK_SET);
if(ret == -1) {
printf("va_server: unable to fseek, err = %d\n", ferror(vas_file_p));
+ free(hdr);
free(disk_hdr);
return -1;
}
items = fread((void *)disk_hdr, 1, Page_Size, vas_file_p);
if(items != Page_Size) {
+ free(hdr);
+ free(disk_hdr);
return -1;
}
if(disk_hdr->magic[0] != CRASH_MAGIC) {
+ free(hdr);
+ free(disk_hdr);
return -1;
}
ret = fseek(vas_file_p, (long)((disk_hdr->map_block) * disk_hdr->blk_size), SEEK_SET);
if(ret == -1) {
printf("va_server: unable to fseek, err = %d\n", ferror(vas_file_p));
+ free(hdr);
+ free(disk_hdr);
return -1;
}
@@ -338,10 +345,13 @@ int read_map(char *crash_file)
vas_file_p);
if(items != disk_hdr->map_blocks) {
printf("unable to read map entries, err = %d\n", errno);
+ free(hdr);
+ free(disk_hdr);
return -1;
}
vas_map_base = hdr;
+ free(disk_hdr);
return 0;
}
diff --git a/va_server_v1.c b/va_server_v1.c
index 1924946..88a2a5a 100644
--- a/va_server_v1.c
+++ b/va_server_v1.c
@@ -253,7 +253,7 @@ u_long vas_find_end_v1(void)
}
int read_maps_v1(char *crash_file)
{
- int *cur_entry_p;
+ int *cur_entry_p, *cp;
int ret, items, blk_pos;
cur_entry_p = (int *)malloc(Page_Size);
@@ -266,25 +266,32 @@ int read_maps_v1(char *crash_file)
vas_file_p = fopen(crash_file, "r");
if(vas_file_p == (FILE *)0) {
printf("read_maps: bad ret from fopen for %s: %s\n", crash_file, strerror(errno));
+ free(cur_entry_p);
return -1;
}
ret = fseek(vas_file_p, (long)0, SEEK_SET);
if(ret == -1) {
printf("read_maps: unable to fseek in %s, errno = %d\n", crash_file, ferror(vas_file_p));
+ free(cur_entry_p);
return -1;
}
items = fread((void *)cur_entry_p, 1, Page_Size, vas_file_p);
if(items != Page_Size) {
printf("read_maps: unable to read header from %s, errno = %d\n", crash_file, ferror(vas_file_p));
+ free(cur_entry_p);
return -1;
}
ret = -1;
- while ((blk_pos = *cur_entry_p++)) {
- if (read_map_v1(blk_pos))
+ cp = cur_entry_p;
+ while ((blk_pos = *cp++)) {
+ if (read_map_v1(blk_pos)) {
+ free(cur_entry_p);
return -1;
+ }
ret = 0;
}
+ free(cur_entry_p);
return ret;
}
@@ -308,21 +315,28 @@ int read_map_v1(int blk_pos)
ret = fseek(vas_file_p, (long)(blk_pos*Page_Size), SEEK_SET);
if(ret == -1) {
console("va_server: unable to fseek, err = %d\n", ferror(vas_file_p));
+ free(hdr);
free(disk_hdr);
return -1;
}
items = fread((void *)disk_hdr, 1, Page_Size, vas_file_p);
if(items != Page_Size) {
+ free(hdr);
+ free(disk_hdr);
return -1;
}
if(disk_hdr->magic[0] != CRASH_MAGIC) {
console("va_server: bad magic 0x%lx\n", disk_hdr->magic[0]);
+ free(hdr);
+ free(disk_hdr);
return -1;
}
ret = fseek(vas_file_p, (long)((blk_pos + disk_hdr->map_block) * disk_hdr->blk_size), SEEK_SET);
if(ret == -1) {
printf("va_server: unable to fseek, err = %d\n", ferror(vas_file_p));
+ free(hdr);
+ free(disk_hdr);
return -1;
}
@@ -338,6 +352,8 @@ int read_map_v1(int blk_pos)
vas_file_p);
if(items != hdr->map_entries) {
printf("unable to read map entries, err = %d\n", errno);
+ free(hdr);
+ free(disk_hdr);
return -1;
}
diff --git a/xendump.c b/xendump.c
index 4bd59b5..70cf261 100644
--- a/xendump.c
+++ b/xendump.c
@@ -2775,8 +2775,10 @@ xc_core_dump_elfnote(off_t sh_offset, size_t sh_size, int store)
index += sizeof(struct elfnote) + elfnote->descsz;
}
- if (!store)
+ if (!store) {
+ free(notes_buffer);
return;
+ }
if (elfnote_header) {
xd->xc_core.header.xch_magic = elfnote_header->xch_magic;
@@ -2798,6 +2800,7 @@ xc_core_dump_elfnote(off_t sh_offset, size_t sh_size, int store)
xd->xc_core.format_version = format_version->version;
}
+ free(notes_buffer);
}
/*

View File

@ -1,41 +0,0 @@
commit ced5255233447cc0810965b683657409f798c4a2
Author: Dave Anderson <anderson@redhat.com>
Date: Tue Oct 2 11:18:09 2018 -0400
As an addendum to the "dev -p" patch above, add the new structure
member offsets for display by the "help -o" option.
(anderson@redhat.com)
diff --git a/symbols.c b/symbols.c
index cb2174b..bb8a8f4 100644
--- a/symbols.c
+++ b/symbols.c
@@ -9692,6 +9692,28 @@ dump_offset_table(char *spec, ulong makestruct)
fprintf(fp, " pci_bus_number: %ld\n",
OFFSET(pci_bus_number));
+ fprintf(fp, " pci_dev_dev: %ld\n",
+ OFFSET(pci_dev_dev));
+ fprintf(fp, " pci_dev_hdr_type: %ld\n",
+ OFFSET(pci_dev_hdr_type));
+ fprintf(fp, " pci_dev_pcie_flags_reg: %ld\n",
+ OFFSET(pci_dev_pcie_flags_reg));
+ fprintf(fp, " pci_bus_node: %ld\n",
+ OFFSET(pci_bus_node));
+ fprintf(fp, " pci_bus_devices: %ld\n",
+ OFFSET(pci_bus_devices));
+ fprintf(fp, " pci_bus_dev: %ld\n",
+ OFFSET(pci_bus_dev));
+ fprintf(fp, " pci_bus_children: %ld\n",
+ OFFSET(pci_bus_children));
+ fprintf(fp, " pci_bus_parent: %ld\n",
+ OFFSET(pci_bus_parent));
+ fprintf(fp, " pci_bus_self: %ld\n",
+ OFFSET(pci_bus_self));
+ fprintf(fp, " device_kobj: %ld\n",
+ OFFSET(device_kobj));
+ fprintf(fp, " kobject_name: %ld\n",
+ OFFSET(kobject_name));
fprintf(fp, " resource_entry_t_from: %ld\n",
OFFSET(resource_entry_t_from));

View File

@ -1,89 +0,0 @@
commit f3a5305947077a65aea8091b05cdb542cea0d61a
Author: Dave Anderson <anderson@redhat.com>
Date: Wed Oct 24 16:25:43 2018 -0400
Modify the x86_64 "bt" behavior when a legitimate exception RIP value
cannot be referenced symbolically, such as when the exception occurs
while running in seccomp BPF filter code. Without the patch, the
exception frame register dump is preceded by "[exception RIP: unknown
or invalid address]", and then followed by "bt: WARNING: possibly
bogus exception frame". With the patch applied, the translation of
the exception RIP will show "[exception RIP: no symbolic reference]",
and there will be no warning message.
(anderson@redhat.com)
diff --git a/x86_64.c b/x86_64.c
index 345122c..d145f96 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -3259,6 +3259,18 @@ x86_64_in_alternate_stack(int cpu, ulong
return FALSE;
}
+static char *
+x86_64_exception_RIP_message(struct bt_info *bt, ulong rip)
+{
+ physaddr_t phys;
+
+ if (IS_VMALLOC_ADDR(rip) &&
+ machdep->kvtop(bt->tc, rip, &phys, 0))
+ return ("no symbolic reference");
+
+ return ("unknown or invalid address");
+}
+
#define STACK_TRANSITION_ERRMSG_E_I_P \
"cannot transition from exception stack to IRQ stack to current process stack:\n exception stack pointer: %lx\n IRQ stack pointer: %lx\n process stack pointer: %lx\n current stack base: %lx\n"
#define STACK_TRANSITION_ERRMSG_E_P \
@@ -3370,7 +3382,7 @@ x86_64_low_budget_back_trace_cmd(struct
fprintf(ofp, (*gdb_output_radix == 16) ?
"+0x%lx" : "+%ld", offset);
} else
- fprintf(ofp, "unknown or invalid address");
+ fprintf(ofp, "%s", x86_64_exception_RIP_message(bt, bt->instptr));
fprintf(ofp, "]\n");
if (KVMDUMP_DUMPFILE())
kvmdump_display_regs(bt->tc->processor, ofp);
@@ -4458,9 +4470,9 @@ x86_64_exception_frame(ulong flags, ulon
(*gdb_output_radix == 16) ?
"+0x%lx" : "+%ld",
offset);
- } else
- fprintf(ofp,
- "unknown or invalid address");
+ } else
+ fprintf(ofp, "%s",
+ x86_64_exception_RIP_message(bt, rip));
fprintf(ofp, "]\n");
}
} else if (!(cs & 3)) {
@@ -4472,7 +4484,7 @@ x86_64_exception_frame(ulong flags, ulon
"+0x%lx" : "+%ld", offset);
bt->eframe_ip = rip;
} else
- fprintf(ofp, "unknown or invalid address");
+ fprintf(ofp, "%s", x86_64_exception_RIP_message(bt, rip));
fprintf(ofp, "]\n");
}
fprintf(ofp, " RIP: %016lx RSP: %016lx RFLAGS: %08lx\n",
@@ -4616,6 +4628,7 @@ x86_64_eframe_verify(struct bt_info *bt,
int estack;
struct syment *sp;
ulong offset, exception;
+ physaddr_t phys;
if ((rflags & RAZ_MASK) || !(rflags & 0x2))
return FALSE;
@@ -4682,6 +4695,12 @@ x86_64_eframe_verify(struct bt_info *bt,
return TRUE;
}
+ if ((cs == 0x10) && kvaddr) {
+ if (IS_KVADDR(rsp) && IS_VMALLOC_ADDR(rip) &&
+ machdep->kvtop(bt->tc, rip, &phys, 0))
+ return TRUE;
+ }
+
if ((cs == 0x33) && (ss == 0x2b)) {
if (IS_UVADDR(rip, bt->tc) && IS_UVADDR(rsp, bt->tc))
return TRUE;

View File

@ -1,499 +0,0 @@
commit 5fe78861ea1589084f6a2956a6ff63677c9269e1
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Sep 7 16:05:52 2018 -0400
Commit 3db3d3992d781c1e42587d2d2bf81e785408e0c2 in crash-7.1.8 was
aimed at making the PPC64 "bt" command work for dumpfiles saved
with the FADUMP facility, but it introduced a bit of unwarranted
complexity in "bt" command processing. Reworked the "bt" command
processing for PPC64 arch to make it a little less compilated and
also to print symbols for NIP and LR registers in exception frames.
Without the patch, "bt" on non-panic active tasks may fail with
the message "bt: invalid kernel virtual address: <address>
type: Regs NIP value".
(hbathini@linux.ibm.com)
diff --git a/ppc64.c b/ppc64.c
index f5d0dac..03fecd3 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -2093,15 +2093,10 @@ ppc64_print_stack_entry(int frame,
lr);
return;
}
- if (req->pc != lr) {
- fprintf(fp, "\n%s[Link Register] ",
- frame < 10 ? " " : "");
- fprintf(fp, "[%lx] %s at %lx",
- req->sp, lrname, lr);
- }
req->ra = lr;
}
- if (!req->name || STREQ(req->name,lrname))
+ if (!req->name || STREQ(req->name, lrname) ||
+ !is_kernel_text(req->pc))
fprintf(fp, " (unreliable)");
fprintf(fp, "\n");
@@ -2219,6 +2214,22 @@ ppc64_print_regs(struct ppc64_pt_regs *regs)
fprintf(fp, " Syscall Result: %016lx\n", regs->result);
}
+static void ppc64_print_nip_lr(struct ppc64_pt_regs *regs, int print_lr)
+{
+ char buf[BUFSIZE];
+ char *sym_buf;
+
+ sym_buf = value_to_symstr(regs->nip, buf, 0);
+ if (sym_buf[0] != NULLCHAR)
+ fprintf(fp, " [NIP : %s]\n", sym_buf);
+
+ if (print_lr) {
+ sym_buf = value_to_symstr(regs->link, buf, 0);
+ if (sym_buf[0] != NULLCHAR)
+ fprintf(fp, " [LR : %s]\n", sym_buf);
+ }
+}
+
/*
* Print the exception frame information
*/
@@ -2231,6 +2242,59 @@ ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs *regs,
fprintf(fp, " %s [%lx] exception frame:\n", efrm_str, regs->trap);
ppc64_print_regs(regs);
+ ppc64_print_nip_lr(regs, 1);
+}
+
+/*
+ * For vmcore typically saved with KDump or FADump, get SP and IP values
+ * from the saved ptregs.
+ */
+static int
+ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
+{
+ struct ppc64_pt_regs *pt_regs;
+ unsigned long unip;
+
+ pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
+ if (!pt_regs || !pt_regs->gpr[1]) {
+ /*
+ * Not collected regs. May be the corresponding CPU not
+ * responded to an IPI in case of KDump OR f/w has not
+ * not provided the register info in case of FADump.
+ */
+ fprintf(fp, "%0lx: GPR1 register value (SP) was not saved\n",
+ bt_in->task);
+ return FALSE;
+ }
+ *ksp = pt_regs->gpr[1];
+ if (IS_KVADDR(*ksp)) {
+ readmem(*ksp+16, KVADDR, &unip, sizeof(ulong), "Regs NIP value",
+ FAULT_ON_ERROR);
+ *nip = unip;
+ } else {
+ if (IN_TASK_VMA(bt_in->task, *ksp))
+ fprintf(fp, "%0lx: Task is running in user space\n",
+ bt_in->task);
+ else
+ fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n",
+ bt_in->task, *ksp);
+ *nip = pt_regs->nip;
+ }
+
+ if (bt_in->flags &&
+ ((BT_TEXT_SYMBOLS|BT_TEXT_SYMBOLS_PRINT|BT_TEXT_SYMBOLS_NOPRINT)))
+ return TRUE;
+
+ /*
+ * Print the collected regs for the active task
+ */
+ ppc64_print_regs(pt_regs);
+ if (!IS_KVADDR(*ksp))
+ return FALSE;
+
+ ppc64_print_nip_lr(pt_regs, (unip != pt_regs->link) ? 1 : 0);
+
+ return TRUE;
}
/*
@@ -2239,7 +2303,7 @@ ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs *regs,
static int
ppc64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
{
- int i;
+ int i, ret, panic_task;
char *sym;
ulong *up;
struct bt_info bt_local, *bt;
@@ -2251,11 +2315,29 @@ ppc64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
struct ppc64_pt_regs *pt_regs;
struct syment *sp;
- bt = &bt_local;
- BCOPY(bt_in, bt, sizeof(struct bt_info));
- ms = machdep->machspec;
+ bt = &bt_local;
+ BCOPY(bt_in, bt, sizeof(struct bt_info));
+ ms = machdep->machspec;
+ ur_nip = ur_ksp = 0;
+
+ panic_task = tt->panic_task == bt->task ? TRUE : FALSE;
check_hardirq = check_softirq = tt->flags & IRQSTACKS ? TRUE : FALSE;
+ if (panic_task && bt->machdep) {
+ pt_regs = (struct ppc64_pt_regs *)bt->machdep;
+ ur_nip = pt_regs->nip;
+ ur_ksp = pt_regs->gpr[1];
+ } else if ((pc->flags & KDUMP) ||
+ ((pc->flags & DISKDUMP) &&
+ (*diskdump_flags & KDUMP_CMPRS_LOCAL))) {
+ /*
+ * For the KDump or FADump vmcore, use SP and IP values
+ * that are saved in ptregs.
+ */
+ ret = ppc64_vmcore_stack_frame(bt_in, nip, ksp);
+ if (ret)
+ return TRUE;
+ }
if (bt->task != tt->panic_task) {
char cpu_frozen = FALSE;
@@ -2385,38 +2467,14 @@ retry:
check_intrstack = FALSE;
goto retry;
}
-
/*
- * We didn't find what we were looking for, so try to use
- * the SP and IP values saved in ptregs.
+ * We didn't find what we were looking for, so just use what was
+ * passed in the ELF header.
*/
- pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
- if (!pt_regs || !pt_regs->gpr[1]) {
- /*
- * Not collected regs. May be the corresponding CPU did not
- * respond to an IPI.
- */
- if (CRASHDEBUG(1))
- fprintf(fp, "%0lx: GPR1(SP) register value not saved\n",
- bt_in->task);
- } else {
- *ksp = pt_regs->gpr[1];
- if (IS_KVADDR(*ksp)) {
- readmem(*ksp+16, KVADDR, nip, sizeof(ulong),
- "Regs NIP value", FAULT_ON_ERROR);
- ppc64_print_regs(pt_regs);
- return TRUE;
- } else {
- if (IN_TASK_VMA(bt_in->task, *ksp))
- fprintf(fp, "%0lx: Task is running in user space\n",
- bt_in->task);
- else
- fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n",
- bt_in->task, *ksp);
- *nip = pt_regs->nip;
- ppc64_print_regs(pt_regs);
- return FALSE;
- }
+ if (ur_nip && ur_ksp) {
+ *nip = ur_nip;
+ *ksp = ur_ksp;
+ return TRUE;
}
console("ppc64_get_dumpfile_stack_frame: cannot find SP for panic task\n");
commit 7e3936895386ea6e85a6dc01bc5027f8133d12bb
Author: Dave Anderson <anderson@redhat.com>
Date: Mon Sep 17 14:33:08 2018 -0400
An addendum to crash commit 5fe78861ea1589084f6a2956a6ff63677c9269e1,
this patch for the PPC64 "bt" command prevents an invalid error
message from being displayed when an active non-panic task is
interrupted while running in user space. Without the patch, the
command correctly indicates "Task is running in user space", dumps
the user-space exception frame, but then prints the invalid error
message "bt: invalid kernel virtual address: ffffffffffffff90 type:
Regs NIP value".
(anderson@redhat.com)
diff --git a/ppc64.c b/ppc64.c
index 03fecd3..8badcde 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -2254,6 +2254,7 @@ ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
{
struct ppc64_pt_regs *pt_regs;
unsigned long unip;
+ int in_user_space = FALSE;
pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
if (!pt_regs || !pt_regs->gpr[1]) {
@@ -2272,10 +2273,11 @@ ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
FAULT_ON_ERROR);
*nip = unip;
} else {
- if (IN_TASK_VMA(bt_in->task, *ksp))
+ if (IN_TASK_VMA(bt_in->task, *ksp)) {
fprintf(fp, "%0lx: Task is running in user space\n",
bt_in->task);
- else
+ in_user_space = TRUE;
+ } else
fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n",
bt_in->task, *ksp);
*nip = pt_regs->nip;
@@ -2289,6 +2291,8 @@ ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
* Print the collected regs for the active task
*/
ppc64_print_regs(pt_regs);
+ if (in_user_space)
+ return TRUE;
if (!IS_KVADDR(*ksp))
return FALSE;
commit 599a6579aa916df7800f8e889d68e4287e4520dd
Author: Dave Anderson <anderson@redhat.com>
Date: Thu Sep 27 14:14:31 2018 -0400
With Linux 4.19-rc1 commit 7d4340bb92a9df78e6e28152f3dd89d9bd82146b,
titled "powerpc/mm: Increase MAX_PHYSMEM_BITS to 128TB with
SPARSEMEM_VMEMMAP config", the PPC64 MAX_PHYSMEM_BITS value has
been bumped up to 47. The appropriate update has been made in
this patch.
(hbathini@linux.ibm.com)
diff --git a/defs.h b/defs.h
index 80c61ef..5b64bb7 100644
--- a/defs.h
+++ b/defs.h
@@ -4054,6 +4054,7 @@ struct efi_memory_desc_t {
#define _SECTION_SIZE_BITS 24
#define _MAX_PHYSMEM_BITS 44
#define _MAX_PHYSMEM_BITS_3_7 46
+#define _MAX_PHYSMEM_BITS_4_19 47
#endif /* PPC64 */
diff --git a/ppc64.c b/ppc64.c
index 8badcde..ee2f76f 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -554,7 +554,10 @@ ppc64_init(int when)
ppc64_vmemmap_init();
machdep->section_size_bits = _SECTION_SIZE_BITS;
- if (THIS_KERNEL_VERSION >= LINUX(3,7,0))
+ if ((machdep->flags & VMEMMAP) &&
+ (THIS_KERNEL_VERSION >= LINUX(4,19,0)))
+ machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_4_19;
+ else if (THIS_KERNEL_VERSION >= LINUX(3,7,0))
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_3_7;
else
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
commit 72cc0cba8a6cab14ca0961dff062d0384d307ce5
Author: Dave Anderson <anderson@redhat.com>
Date: Tue Oct 2 10:56:28 2018 -0400
Fix for the PPC64 "bt" command to recognize when a thread is running
in OPAL firmware. Without the patch, the "bt" command indicates
<task-address>: Invalid Stack Pointer <OPAL-firmware-address>"
(hbathini@linux.ibm.com)
--- a/defs.h
+++ b/defs.h
@@ -5934,6 +5934,12 @@ struct ppc64_elf_prstatus {
#ifdef PPC64
+struct ppc64_opal {
+ uint64_t base;
+ uint64_t entry;
+ uint64_t size;
+};
+
struct ppc64_vmemmap {
unsigned long phys;
unsigned long virt;
@@ -5984,6 +5990,7 @@ struct machine_specific {
ulong _page_accessed;
int (*is_kvaddr)(ulong);
int (*is_vmaddr)(ulong);
+ struct ppc64_opal opal;
};
void ppc64_init(int);
@@ -6001,6 +6008,7 @@ void ppc64_dump_machdep_table(ulong);
* in the kernel is also 0x40.
*/
#define RADIX_MMU (0x40)
+#define OPAL_FW (0x80)
#define REGION_SHIFT (60UL)
#define REGION_ID(addr) (((unsigned long)(addr)) >> REGION_SHIFT)
--- a/ppc64.c
+++ b/ppc64.c
@@ -65,8 +65,26 @@ static ulong hugepage_dir(ulong pte);
static ulong pgd_page_vaddr_l4(ulong pgd);
static ulong pud_page_vaddr_l4(ulong pud);
static ulong pmd_page_vaddr_l4(ulong pmd);
+static int is_opal_context(ulong sp, ulong nip);
void opalmsg(void);
+static int is_opal_context(ulong sp, ulong nip)
+{
+ uint64_t opal_start, opal_end;
+
+ if (!(machdep->flags & OPAL_FW))
+ return FALSE;
+
+ opal_start = machdep->machspec->opal.base;
+ opal_end = opal_start + machdep->machspec->opal.size;
+
+ if (((sp >= opal_start) && (sp < opal_end)) ||
+ ((nip >= opal_start) && (nip < opal_end)))
+ return TRUE;
+
+ return FALSE;
+}
+
static inline int is_hugepage(ulong pte)
{
if ((machdep->flags & BOOK3E) ||
@@ -241,6 +259,7 @@ struct machine_specific book3e_machine_s
.is_vmaddr = book3e_is_vmaddr,
};
+#define SKIBOOT_BASE 0x30000000
/*
* Do all necessary machine-specific setup here. This is called several
@@ -362,6 +381,16 @@ ppc64_init(int when)
struct machine_specific *m = machdep->machspec;
/*
+ * 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)
+ machdep->flags |= OPAL_FW;
+ }
+
+ /*
* On Power ISA 3.0 based server processors, a kernel can
* run with radix MMU or standard MMU. Set the flag,
* if it is radix MMU.
@@ -712,6 +741,8 @@ ppc64_dump_machdep_table(ulong arg)
fprintf(fp, "%sSWAP_ENTRY_L4", others++ ? "|" : "");
if (machdep->flags & RADIX_MMU)
fprintf(fp, "%sRADIX_MMU", others++ ? "|" : "");
+ if (machdep->flags & OPAL_FW)
+ fprintf(fp, "%sOPAL_FW", others++ ? "|" : "");
fprintf(fp, ")\n");
fprintf(fp, " kvbase: %lx\n", machdep->kvbase);
@@ -2257,7 +2288,11 @@ ppc64_vmcore_stack_frame(struct bt_info
{
struct ppc64_pt_regs *pt_regs;
unsigned long unip;
- int in_user_space = FALSE;
+ /*
+ * TRUE: task is running in a different context (userspace, OPAL..)
+ * FALSE: task is probably running in kernel space.
+ */
+ int out_of_context = FALSE;
pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
if (!pt_regs || !pt_regs->gpr[1]) {
@@ -2270,20 +2305,25 @@ ppc64_vmcore_stack_frame(struct bt_info
bt_in->task);
return FALSE;
}
+
*ksp = pt_regs->gpr[1];
if (IS_KVADDR(*ksp)) {
readmem(*ksp+16, KVADDR, &unip, sizeof(ulong), "Regs NIP value",
FAULT_ON_ERROR);
*nip = unip;
} else {
+ *nip = pt_regs->nip;
if (IN_TASK_VMA(bt_in->task, *ksp)) {
fprintf(fp, "%0lx: Task is running in user space\n",
bt_in->task);
- in_user_space = TRUE;
+ out_of_context = TRUE;
+ } else if (is_opal_context(*ksp, *nip)) {
+ fprintf(fp, "%0lx: Task is running in OPAL (firmware) context\n",
+ bt_in->task);
+ out_of_context = TRUE;
} else
fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n",
bt_in->task, *ksp);
- *nip = pt_regs->nip;
}
if (bt_in->flags &&
@@ -2294,7 +2334,8 @@ ppc64_vmcore_stack_frame(struct bt_info
* Print the collected regs for the active task
*/
ppc64_print_regs(pt_regs);
- if (in_user_space)
+
+ if (out_of_context)
return TRUE;
if (!IS_KVADDR(*ksp))
return FALSE;
@@ -2828,7 +2869,6 @@ ppc64_get_smp_cpus(void)
*/
#define SKIBOOT_CONSOLE_DUMP_START 0x31000000
#define SKIBOOT_CONSOLE_DUMP_SIZE 0x100000
-#define SKIBOOT_BASE 0x30000000
#define ASCII_UNLIMITED ((ulong)(-1) >> 1)
void
@@ -2841,10 +2881,6 @@ opalmsg(void)
uint64_t u64;
uint64_t limit64;
};
- struct opal {
- unsigned long long base;
- unsigned long long entry;
- } opal;
int i, a;
size_t typesz;
void *location;
@@ -2856,25 +2892,13 @@ opalmsg(void)
long count = SKIBOOT_CONSOLE_DUMP_SIZE;
ulonglong addr = SKIBOOT_CONSOLE_DUMP_START;
+ if (!(machdep->flags & OPAL_FW))
+ error(FATAL, "dump was not captured on OPAL based system");
+
if (CRASHDEBUG(4))
fprintf(fp, "<addr: %llx count: %ld (%s)>\n",
addr, count, "PHYSADDR");
- /*
- * OPAL based platform check
- * struct opal of BSS section and hence default value will be ZERO(0)
- * opal_init() in the kernel initializes this structure based on
- * the platform. Use it as a key to determine whether the dump
- * was taken on an OPAL based system or not.
- */
- if (symbol_exists("opal")) {
- get_symbol_data("opal", sizeof(struct opal), &opal);
- if (opal.base != SKIBOOT_BASE)
- error(FATAL, "dump was captured on non-PowerNV machine");
- } else {
- error(FATAL, "dump was captured on non-PowerNV machine");
- }
-
BZERO(&mem, sizeof(struct memloc));
lost = typesz = per_line = 0;
location = NULL;

View File

@ -1,22 +1,23 @@
--- crash-7.1.5/diskdump.c.orig
+++ crash-7.1.5/diskdump.c
@@ -23,6 +23,8 @@
--- 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
- @echo "${LDFLAGS} -lz -ldl -rdynamic" > ${GDB}/gdb/mergelibs
+ @echo "${LDFLAGS} -lz -llzo2 -lsnappy -lzstd -ldl -rdynamic" > ${GDB}/gdb/mergelibs
@echo "../../${PROGRAM} ../../${PROGRAM}lib.a" > ${GDB}/gdb/mergeobj
@rm -f ${PROGRAM}
@if [ ! -f ${GDB}/config.status ]; then \
--- crash-8.0.4/diskdump.c.orig
+++ crash-8.0.4/diskdump.c
@@ -23,6 +23,9 @@
* GNU General Public License for more details.
*/
+#define LZO
+#define SNAPPY
+#define ZSTD
#include "defs.h"
#include "diskdump.h"
#include "xen_dom0.h"
--- crash-7.1.5/Makefile.orig
+++ crash-7.1.5/Makefile
@@ -228,7 +228,7 @@ all: make_configure
gdb_merge: force
@if [ ! -f ${GDB}/README ]; then \
make --no-print-directory gdb_unzip; fi
- @echo "${LDFLAGS} -lz -ldl -rdynamic" > ${GDB}/gdb/mergelibs
+ @echo "${LDFLAGS} -lz -llzo2 -lsnappy -ldl -rdynamic" > ${GDB}/gdb/mergelibs
@echo "../../${PROGRAM} ../../${PROGRAM}lib.a" > ${GDB}/gdb/mergeobj
@rm -f ${PROGRAM}
@if [ ! -f ${GDB}/config.status ]; then \

View File

@ -1,15 +0,0 @@
--- crash-7.2.3/ppc64.c.orig
+++ crash-7.2.3/ppc64.c
@@ -583,8 +583,11 @@ ppc64_init(int when)
ppc64_vmemmap_init();
machdep->section_size_bits = _SECTION_SIZE_BITS;
+
+#define is_RHEL8() (strstr(kt->proc_version, ".el8."))
+
if ((machdep->flags & VMEMMAP) &&
- (THIS_KERNEL_VERSION >= LINUX(4,19,0)))
+ ((THIS_KERNEL_VERSION >= LINUX(4,19,0)) || is_RHEL8()))
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_4_19;
else if (THIS_KERNEL_VERSION >= LINUX(3,7,0))
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_3_7;

View File

@ -3,46 +3,41 @@
#
Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles
Name: crash
Version: 7.2.3
Release: 18%{?dist}
Version: 8.0.4
Release: 2%{?dist}.alma
License: GPLv3
Group: Development/Debuggers
Source: http://people.redhat.com/anderson/crash-%{version}.tar.gz
URL: http://people.redhat.com/anderson
Source0: https://github.com/crash-utility/crash/archive/crash-%{version}.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
BuildRequires: ncurses-devel zlib-devel lzo-devel bison snappy-devel wget patch texinfo libzstd-devel
BuildRequires: gcc gcc-c++ make
Requires: binutils
Patch0: lzo_snappy.patch
Patch1: github_46d21219_to_9446958f.patch
Patch2: github_95daa11b.patch
Patch3: github_b9d76838_c79a11fa_proc_kcore.patch
Patch4: github_1926150e_ppc64_stacksize.patch
Patch5: github_28fa7bd0_to_02efd083.patch
Patch6: github_9b494b70_to_eb823b79.patch
Patch7: github_a10917ba_to_e9532aea.patch
Patch8: rhel8_build.patch
Patch9: github_ppc64_5fe78861_7e393689_599a6579_72cc0cba.patch
Patch10: github_3141bba9.patch
Patch11: github_c5f45d6c.patch
Patch12: github_f3a53059.patch
Patch13: github_64dad6d0.patch
Patch14: rhel8_ppc64_max_physmem_bits.patch
Patch15: github_27a6ebd0_dev-p.patch
Patch16: github_ced52552_dev-p_offsets.patch
Patch17: github_361f050e_dev-d.patch
Patch18: github_0f65ae0c_readline.patch
Patch19: github_6b93714b_cmdline.patch
Patch20: github_8618ddd8_CONFIG_ARM64_USER_VA_BITS_52
Patch21: github_ac5a7889_CONFIG_ARM64_PA_BITS.patch
Patch22: github_a89ec821_vmcoreinfo_plugin.patch
Patch23: github_2f57a96c_files-c-p.patch
Provides: bundled(libiberty)
Provides: bundled(gdb) = 10.2
Patch0: lzo_snappy_zstd.patch
Patch1: crash-8.0.4_build.patch
Patch2: 0001-Fix-rd-command-for-zram-data-display-in-Linux-6.2-an.patch
Patch3: 0002-Fix-typos-in-offset_table-and-missing-help-o-items.patch
Patch4: 0003-zram-Fixes-for-lookup_swap_cache.patch
Patch5: 0004-symbols-expand-all-kernel-module-symtable-if-not-all.patch
Patch6: 0005-symbols-skip-load-.init.-sections-if-module-was-succ.patch
Patch7: 0006-use-NR_SWAPCACHE-when-nr_swapper_spaces-isn-t-availa.patch
Patch8: 0007-Fix-identity_map_base-value-dump-on-S390.patch
Patch9: 0008-s390x-fix-virtual-vs-physical-address-confusion.patch
Patch10: 0009-s390x-uncouple-physical-and-virtual-memory-spaces.patch
Patch11: 0010-RISCV64-Dump-NT_PRSTATUS-in-help-n.patch
Patch12: 0011-RISCV64-Fix-bt-output-when-no-ra-on-the-stack-top.patch
Patch13: 0012-arm64-rewrite-the-arm64_get_vmcoreinfo_ul-to-arm64_g.patch
Patch14: 0013-help.c-Remove-kmem-l-help-messages.patch
Patch15: 0014-x86_64-check-bt-bptr-before-calculate-framesize.patch
%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
@ -53,43 +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.patch
%patch1 -p1 -b github_46d21219_to_9446958f.patch
%patch2 -p1 -b github_95daa11b.patch
%patch3 -p1 -b github_b9d76838_c79a11fa_proc_kcore.patch
%patch4 -p1 -b github_1926150e_ppc64_stacksize.patch
%patch5 -p1 -b github_28fa7bd0_to_02efd083.patch
%patch6 -p1 -b github_9b494b70_to_eb823b79.patch
%patch7 -p1 -b github_a10917ba_to_e9532aea.patch
%patch8 -p1 -b rhel8_build.patch
%patch9 -p1 -b github_ppc64_5fe78861_7e393689_599a6579_72cc0cba.patch
%patch10 -p1 -b github_3141bba9.patch
%patch11 -p1 -b github_c5f45d6c.patch
%patch12 -p1 -b github_f3a53059.patch
%patch13 -p1 -b github_64dad6d0.patch
%patch14 -p1 -b rhel8_ppc64_max_physmem_bits.patch
%patch15 -p1 -b github_27a6ebd0_dev-p.patch
%patch16 -p1 -b github_ced52552_dev-p_offsets.patch
%patch17 -p1 -b github_361f050e_dev-d.patch
%patch18 -p1 -b github_0f65ae0c_readline.patch
%patch19 -p1 -b github_6b93714b_cmdline.patch
%patch20 -p1 -b github_8618ddd8_CONFIG_ARM64_USER_VA_BITS_52
%patch21 -p1 -b github_ac5a7889_CONFIG_ARM64_PA_BITS.patch
%patch22 -p1 -b github_a89ec821_vmcoreinfo_plugin.patch
%patch23 -p1 -b github_2f57a96c_files-c-p.patch
%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
make RPMPKG="%{version}-%{release}" CFLAGS="%{optflags}"
cp %{SOURCE1} .
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
@ -100,16 +88,154 @@ 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
* Tue Feb 08 2022 Lianbo Jiang <lijiang@redhat.com> - 7.3.1-5
- Rebuild for osci badfuncs issue
* Mon Feb 07 2022 Lianbo Jiang <lijiang@redhat.com> - 7.3.1-4
- Fix segfault on aarch64 for "bt -a|-c" command
- Fix HZ calculation on Linux 5.14 and later
- Fix for "timer -r" option to display all the per-CPU clocks
* Mon Dec 13 2021 Lianbo Jiang <lijiang@redhat.com> - 7.3.1-3
- Fix segmentation fault caused by crash extension modules
- Support the overflow stack exception handling on aarch64
* Tue Dec 07 2021 Lianbo Jiang <lijiang@redhat.com> - 7.3.1-2
- Enable ZSTD feature support
* Fri Nov 26 2021 Lianbo Jiang <lijiang@redhat.com> - 7.3.1-1
- Rebase to the latest crash-7.3.1
* Thu Nov 18 2021 Lianbo Jiang <lijiang@redhat.com> - 7.3.0-3
- Fix for "sched: Change task_struct::state"
- Fix for "sched: move CPU field back into thread_info if THREAD_INFO_IN_TASK=y"
- Fix live debugging with lockdown=integrity
- Fix 'waitq' command for Linux 4.13 and later kernels
- Fix for "kmem -s|-S" option on Linux 5.7 and later kernels
* Fri May 14 2021 Lianbo Jiang <lijiang@redhat.com> - 7.3.0-2
- Update the sha512 hash in the sources file to solve the
compilation issues
* Thu May 13 2021 Lianbo Jiang <lijiang@redhat.com> - 7.3.0-1
- Rebase to upstream 7.3.0
* Tue Dec 1 2020 Bhupesh Sharma <bhsharma@redhat.com> - 7.2.9-2
- Fix the sources file to add gdb-7.6 tarball
[The line was somehow removed when using rhpkg new-sources to
update the crash tarball location]
Resolves: rhbz#1881854
* Tue Dec 1 2020 Bhupesh Sharma <bhsharma@redhat.com> - 7.2.9-1
- Rebase to upstream crash version 7.2.9
- Also minimize the rhel-only patches to the bare minimum.
Resolves: rhbz#1881854
* Thu Nov 5 2020 Bhupesh Sharma <bhsharma@redhat.com> - 7.2.8-8
- crash/arm64: Fix arm64 read error with 'idmap_ptrs_per_pgd' symbol with debug kernel
Resolves: rhbz#1876039
* Mon Aug 17 2020 Bhupesh Sharma <bhsharma@redhat.com> - 7.2.8-7
- crash/sadump, kaslr: fix failure of calculating kaslr_offset due to an sadump format restriction
Resolves: rhbz#1855527
* Fri Aug 7 2020 Bhupesh Sharma <bhsharma@redhat.com> - 7.2.8-6
- aarch64: Revert to reading CONFIG_ARM64_USER_VA_BITS_52 and CONFIG_ARM64_PA_BITS=52 for 52-bit VA/PA space.
Resolves: rhbz#1861086
* Mon Jul 27 2020 Bhupesh Sharma <bhsharma@redhat.com> - 7.2.8-5
- aarch64: Support reading extended 52-bit address space via crash-utility
Resolves: rhbz#1861086
* Fri Jul 10 2020 Bhupesh Sharma <bhsharma@redhat.com> - 7.2.8-4
- Replace people.redhat.com references with github equivalents.
Resolves: rhbz#1851745
* Mon Jun 22 2020 Bhupesh Sharma <bhsharma@redhat.com> - 7.2.8-3
- Fix for reading compressed kdump dumpfiles from systems with physical memory
Resolves: rhbz#1819606
* Mon Jun 8 2020 Bhupesh Sharma <bhsharma@redhat.com> - 7.2.8-2
- Remove wget from BuildRequires section
Resolves: rhbz#1838322
* Fri Jun 5 2020 Bhupesh Sharma <bhsharma@redhat.com> - 7.2.8-1
- Rebase to latest upstream release 7.2.8
Resolves: rhbz#1838322
* Mon Feb 3 2020 Dave Anderson <anderson@redhat.com> - 7.2.7-3
- Rebase to github commit 6c1c8ac6
Resolves: rhbz#1738619
- Fix "log -a" option
Resolves: rhbz#1785537
- Fix for ELF kdump vmcores form s390x KASLR kernels
Resolves: rhbz#1786996
* Mon Nov 11 2019 Dave Anderson <anderson@redhat.com> - 7.2.7-2
- Rebase to latest upstream sources
Resolves: rhbz#1738619
- Support for KASLR on s390x
Resolves: rhbz# 1753172
* Mon Jun 10 2019 Dave Anderson <anderson@redhat.com> - 7.2.6-2
- Fix "p" command regression
Resolves: rhbz#1718417
- Fix arm64 debug kernel read error message during initialization
Resolves: rhbz#1718736
* Mon May 6 2019 Dave Anderson <anderson@redhat.com> - 7.2.6-1
- Rebase to latest upstream sources
Resolves: rhbz#1686560
- Utilize the VMCOREINFO PT_NOTE in /proc/kcore header
Resolves: rhbz#1627528
- Support extraction of CONFIG_PROC_VMCORE_DEVICE_DUMP data from dumpfile header
Resolves: rhbz#1702535
* Thu Feb 14 2019 Dave Anderson <anderson@redhat.com> - 7.2.3-18
- Fix "files -c" and "files -p" options
Resolves: rhbz#1673285