Update to latest upstream release(crash-8.0.0)
Release: crash-8.0.0-1 Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
This commit is contained in:
parent
e1f6e2b6fb
commit
99e49885eb
1
.gitignore
vendored
1
.gitignore
vendored
@ -44,5 +44,6 @@ crash-5.0.6.tar.gz
|
||||
/crash-7.2.8.tar.gz
|
||||
/crash-7.2.9.tar.gz
|
||||
/crash-7.3.0.tar.gz
|
||||
/crash-8.0.0.tar.gz
|
||||
/gdb-7.6.tar.gz
|
||||
/gdb-10.2.tar.gz
|
||||
|
@ -1,50 +0,0 @@
|
||||
From a7ecf2467f953b632713f38ab8104596755bca8c Mon Sep 17 00:00:00 2001
|
||||
From: John Donnelly <john.p.donnelly@oracle.com>
|
||||
Date: Wed, 12 May 2021 14:48:03 -0700
|
||||
Subject: [PATCH 01/16] arm64: Add lowercase tcr_el1_t1sz
|
||||
|
||||
Commit 1c45cea "arm64: Change tcr_el1_t1sz variable name to
|
||||
TCR_EL1_T1SZ", renamed the variable to upper case, but there are
|
||||
kernels in existence that still have the lower case name, which
|
||||
breaks crash backwards compatibility.
|
||||
|
||||
Resolves: https://github.com/crash-utility/crash/pull/82
|
||||
Signed-off-by: John Donnelly <john.p.donnelly@oracle.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
---
|
||||
arm64.c | 3 ++-
|
||||
netdump.c | 3 ++-
|
||||
2 files changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arm64.c b/arm64.c
|
||||
index 4787fa61e3e5..8934961b109d 100644
|
||||
--- a/arm64.c
|
||||
+++ b/arm64.c
|
||||
@@ -3936,7 +3936,8 @@ arm64_calc_VA_BITS(void)
|
||||
} else if (ACTIVE())
|
||||
error(FATAL, "cannot determine VA_BITS_ACTUAL: please use /proc/kcore\n");
|
||||
else {
|
||||
- if ((string = pc->read_vmcoreinfo("NUMBER(TCR_EL1_T1SZ)"))) {
|
||||
+ if ((string = pc->read_vmcoreinfo("NUMBER(TCR_EL1_T1SZ)")) ||
|
||||
+ (string = pc->read_vmcoreinfo("NUMBER(tcr_el1_t1sz)"))) {
|
||||
/* See ARMv8 ARM for the description of
|
||||
* TCR_EL1.T1SZ and how it can be used
|
||||
* to calculate the vabits_actual
|
||||
diff --git a/netdump.c b/netdump.c
|
||||
index c1c9cbfaed94..aaea945aaca7 100644
|
||||
--- a/netdump.c
|
||||
+++ b/netdump.c
|
||||
@@ -1921,7 +1921,8 @@ vmcoreinfo_read_string(const char *key)
|
||||
sprintf(value, "%ld", nd->arch_data2 & 0xffffffff);
|
||||
return value;
|
||||
}
|
||||
- if (STREQ(key, "NUMBER(TCR_EL1_T1SZ)") && nd->arch_data2) {
|
||||
+ if ((STREQ(key, "NUMBER(TCR_EL1_T1SZ)") ||
|
||||
+ STREQ(key, "NUMBER(tcr_el1_t1sz)")) && nd->arch_data2) {
|
||||
value = calloc(VADDR_PRLEN+1, sizeof(char));
|
||||
sprintf(value, "%lld", ((ulonglong)nd->arch_data2 >> 32) & 0xffffffff);
|
||||
pc->read_vmcoreinfo = no_vmcoreinfo;
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,156 +0,0 @@
|
||||
From 80334ed25820cc08d147de5da361f427885cdd9e Mon Sep 17 00:00:00 2001
|
||||
From: Aaron Tomlin <atomlin@redhat.com>
|
||||
Date: Tue, 13 Jul 2021 14:24:49 +0100
|
||||
Subject: [PATCH 01/27] kmem: Add support to -S option to specify a range of
|
||||
CPU-specific slab data
|
||||
|
||||
With this patch, it is now possible for one to explicitly specify a range
|
||||
of CPU-specific slab data to list. For example:
|
||||
|
||||
Note: This is only applicable to a Linux kernel with Kconfig
|
||||
CONFIG_SLUB enabled. The optional argument GNU extension
|
||||
for getopt(3) is utilized; and, the CPU range must be
|
||||
specified as expected
|
||||
|
||||
crash> kmem -S=1,4 kmalloc-512
|
||||
CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
|
||||
ffff8d3f07c06c00 512 1916 3680 115 16k kmalloc-512
|
||||
CPU 1 KMEM_CACHE_CPU:
|
||||
ffff8d461fa6f140
|
||||
CPU 1 SLAB:
|
||||
SLAB MEMORY NODE TOTAL ALLOCATED FREE
|
||||
fffff540df7c4000 ffff8d45df100000 0 32 8 24
|
||||
FREE / [ALLOCATED]
|
||||
ffff8d45df100000 (cpu 1 cache)
|
||||
[ffff8d45df100200]
|
||||
ffff8d45df101000 (cpu 1 cache)
|
||||
...skipped ...
|
||||
CPU 4 KMEM_CACHE_CPU:
|
||||
ffff8d461fb2f140
|
||||
CPU 4 SLAB:
|
||||
SLAB MEMORY NODE TOTAL ALLOCATED FREE
|
||||
fffff540dfde3800 ffff8d45f78e0000 0 32 8 24
|
||||
FREE / [ALLOCATED]
|
||||
[ffff8d45f78e0000]
|
||||
ffff8d45f78e0200 (cpu 4 cache)
|
||||
ffff8d45f78e0400 (cpu 4 cache)
|
||||
...skipped ...
|
||||
|
||||
Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
help.c | 5 ++++-
|
||||
memory.c | 37 ++++++++++++++++++++++++++++++++++---
|
||||
2 files changed, 38 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/help.c b/help.c
|
||||
index 99be7cb4e17c..6c262a3ffcbb 100644
|
||||
--- a/help.c
|
||||
+++ b/help.c
|
||||
@@ -6601,7 +6601,7 @@ char *help_kmem[] = {
|
||||
"kmem",
|
||||
"kernel memory",
|
||||
"[-f|-F|-c|-C|-i|-v|-V|-n|-z|-o|-h] [-p | -m member[,member]]\n"
|
||||
-" [[-s|-S|-r] [slab] [-I slab[,slab]]] [-g [flags]] [[-P] address]]",
|
||||
+" [[-s|-S|-S=cpu[s]|-r] [slab] [-I slab[,slab]]] [-g [flags]] [[-P] address]]",
|
||||
" This command displays information about the use of kernel memory.\n",
|
||||
" -f displays the contents of the system free memory headers.",
|
||||
" also verifies that the page count equals nr_free_pages.",
|
||||
@@ -6649,6 +6649,9 @@ char *help_kmem[] = {
|
||||
" slab data for each per-cpu slab is displayed, along with the",
|
||||
" address of each kmem_cache_node, its count of full and partial",
|
||||
" slabs, and a list of all tracked slabs.",
|
||||
+" Note: one can specify the per-cpu slab data to be displayed;",
|
||||
+" the cpu[s] can be given as \"1,3,5\", \"1-3\", \"1,3,5-7,10\",",
|
||||
+" \"all\", or \"a\" (shortcut for \"all\").",
|
||||
" -r displays the accumulated basic kmalloc() slab data of each",
|
||||
" root slab cache and its children. The kernel must contain the",
|
||||
" \"slab_root_caches\" list_head. (currently only available if",
|
||||
diff --git a/memory.c b/memory.c
|
||||
index cbe90eebe748..ca4c633e5074 100644
|
||||
--- a/memory.c
|
||||
+++ b/memory.c
|
||||
@@ -48,6 +48,7 @@ struct meminfo { /* general purpose memory information structure */
|
||||
int slab_offset;
|
||||
char *reqname;
|
||||
char *curname;
|
||||
+ ulong *spec_cpumask;
|
||||
ulong *addrlist;
|
||||
int *kmem_bufctl;
|
||||
ulong *cpudata[NR_CPUS];
|
||||
@@ -4851,10 +4852,13 @@ cmd_kmem(void)
|
||||
struct meminfo meminfo;
|
||||
ulonglong value[MAXARGS];
|
||||
char buf[BUFSIZE];
|
||||
+ char arg_buf[BUFSIZE];
|
||||
char *p1;
|
||||
- int spec_addr, escape;
|
||||
+ ulong *cpus;
|
||||
+ int spec_addr, escape, choose_cpu;
|
||||
|
||||
- spec_addr = 0;
|
||||
+ cpus = NULL;
|
||||
+ spec_addr = choose_cpu = 0;
|
||||
sflag = Sflag = pflag = fflag = Fflag = Pflag = zflag = oflag = 0;
|
||||
vflag = Cflag = cflag = iflag = nflag = lflag = Lflag = Vflag = 0;
|
||||
gflag = hflag = rflag = 0;
|
||||
@@ -4863,7 +4867,7 @@ cmd_kmem(void)
|
||||
BZERO(&value[0], sizeof(ulonglong)*MAXARGS);
|
||||
pc->curcmd_flags &= ~HEADER_PRINTED;
|
||||
|
||||
- while ((c = getopt(argcnt, args, "gI:sSrFfm:pvczCinl:L:PVoh")) != EOF) {
|
||||
+ while ((c = getopt(argcnt, args, "gI:sS::rFfm:pvczCinl:L:PVoh")) != EOF) {
|
||||
switch(c)
|
||||
{
|
||||
case 'V':
|
||||
@@ -4903,6 +4907,29 @@ cmd_kmem(void)
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
+ if (choose_cpu)
|
||||
+ error(FATAL, "only one -S option allowed\n");
|
||||
+ /* Use the GNU extension with getopt(3) ... */
|
||||
+ if (optarg) {
|
||||
+ if (!(vt->flags & KMALLOC_SLUB))
|
||||
+ error(FATAL,
|
||||
+ "can only use -S=cpu(s) with a kernel \n"
|
||||
+ "that is built with CONFIG_SLUB support.\n");
|
||||
+ if (optarg[0] != '=')
|
||||
+ error(FATAL,
|
||||
+ "CPU-specific slab data to be displayed "
|
||||
+ "must be written as expected only e.g. -S=1,45.\n");
|
||||
+ /* Skip = ... */
|
||||
+ optarg++;
|
||||
+
|
||||
+ choose_cpu = 1;
|
||||
+ BZERO(arg_buf, BUFSIZE);
|
||||
+ strcpy(arg_buf, optarg);
|
||||
+
|
||||
+ cpus = get_cpumask_buf();
|
||||
+ make_cpumask(arg_buf, cpus, FAULT_ON_ERROR, NULL);
|
||||
+ meminfo.spec_cpumask = cpus;
|
||||
+ }
|
||||
Sflag = 1; sflag = rflag = 0;
|
||||
break;
|
||||
|
||||
@@ -5185,6 +5212,8 @@ cmd_kmem(void)
|
||||
meminfo.flags = VERBOSE;
|
||||
vt->dump_kmem_cache(&meminfo);
|
||||
}
|
||||
+ if (choose_cpu)
|
||||
+ FREEBUF(cpus);
|
||||
}
|
||||
|
||||
if (vflag == 1)
|
||||
@@ -19083,6 +19112,8 @@ do_kmem_cache_slub(struct meminfo *si)
|
||||
per_cpu = (ulong *)GETBUF(sizeof(ulong) * vt->numnodes);
|
||||
|
||||
for (i = 0; i < kt->cpus; i++) {
|
||||
+ if (si->spec_cpumask && !NUM_IN_BITMAP(si->spec_cpumask, i))
|
||||
+ continue;
|
||||
if (hide_offline_cpu(i)) {
|
||||
fprintf(fp, "CPU %d [OFFLINE]\n", i);
|
||||
continue;
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,151 +0,0 @@
|
||||
From 2fab8fbc0c4f1c4cbe889de4cead5f7457a19f77 Mon Sep 17 00:00:00 2001
|
||||
From: Tao Liu <ltao@redhat.com>
|
||||
Date: Sat, 16 Oct 2021 13:21:11 +0800
|
||||
Subject: [PATCH 1/9] symbols: Implement install and remove operations for
|
||||
mod_symname_hash
|
||||
|
||||
Currently the sequence for symbol_search to search a symbol is: 1) kernel
|
||||
symname hash table, 2) iterate all kernel symbols, 3) iterate all kernel
|
||||
modules and their symbols. In the worst case, if a non-exist symbol been
|
||||
searched, all 3 stages will be went through. The time consuming status for
|
||||
each stage is like:
|
||||
|
||||
stage 1 stage 2 stage 3
|
||||
0.007000(ms) 0.593000(ms) 2.421000(ms)
|
||||
|
||||
stage 3 takes too much time when comparing to stage 1. This patch series
|
||||
introduces a symname hash table for kernel modules, to improve the
|
||||
performance of symbol searching.
|
||||
|
||||
Functions symbol_search() and symbol_exists() are fundamental and widely
|
||||
used by other crash functions, thus the benefit of performance improvement
|
||||
can get accumulated. For example, "ps -m" and "irq" commands, which call
|
||||
the functions many times, will become faster with the patch series.
|
||||
|
||||
This patch indroduces mod_symname_hash, and its install/remove operations.
|
||||
Since symbol_search() has to return the lowest address symbol and
|
||||
symbol_search_next() returns the next lowest symbol, thus the installation
|
||||
should be sorted ascendingly.
|
||||
|
||||
In mod_symname_hash_install_range() scenario, spn are already arranged
|
||||
ascendingly, so for mod_symname_hash_install():
|
||||
|
||||
Install spn previous to sp:
|
||||
|
||||
If sp is the start of bucket, or
|
||||
1) spn->value is smaller than sp->value.
|
||||
|
||||
Install spn next to sp:
|
||||
|
||||
1) sp->name_hash_next is NULL, or
|
||||
2) sp->name_hash_next->value is larger than spn->value
|
||||
|
||||
spn->value is the kernel address of the symbol and will not change.
|
||||
So we use it mainly to determine the sequence. When spn->value equals
|
||||
sp->value, they must be symbols within a kernel module.
|
||||
|
||||
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||
---
|
||||
defs.h | 1 +
|
||||
symbols.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 74 insertions(+)
|
||||
|
||||
diff --git a/defs.h b/defs.h
|
||||
index cbd45e52f9da..bbdca799f72d 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -2755,6 +2755,7 @@ struct symbol_table_data {
|
||||
double val_hash_searches;
|
||||
double val_hash_iterations;
|
||||
struct syment *symname_hash[SYMNAME_HASH];
|
||||
+ struct syment *mod_symname_hash[SYMNAME_HASH];
|
||||
struct symbol_namespace kernel_namespace;
|
||||
struct syment *ext_module_symtable;
|
||||
struct syment *ext_module_symend;
|
||||
diff --git a/symbols.c b/symbols.c
|
||||
index 69dccdb09d5f..ad12d1c22225 100644
|
||||
--- a/symbols.c
|
||||
+++ b/symbols.c
|
||||
@@ -1157,6 +1157,79 @@ symname_hash_install(struct syment *spn)
|
||||
}
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Install a single kernel module symbol into the mod_symname_hash.
|
||||
+ */
|
||||
+static void
|
||||
+mod_symname_hash_install(struct syment *spn)
|
||||
+{
|
||||
+ struct syment *sp;
|
||||
+ int index;
|
||||
+
|
||||
+ if (!spn)
|
||||
+ return;
|
||||
+
|
||||
+ index = SYMNAME_HASH_INDEX(spn->name);
|
||||
+
|
||||
+ sp = st->mod_symname_hash[index];
|
||||
+
|
||||
+ if (!sp || (spn->value < sp->value)) {
|
||||
+ st->mod_symname_hash[index] = spn;
|
||||
+ spn->name_hash_next = sp;
|
||||
+ return;
|
||||
+ }
|
||||
+ for (; sp; sp = sp->name_hash_next) {
|
||||
+ if (!sp->name_hash_next ||
|
||||
+ spn->value < sp->name_hash_next->value) {
|
||||
+ spn->name_hash_next = sp->name_hash_next;
|
||||
+ sp->name_hash_next = spn;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mod_symname_hash_remove(struct syment *spn)
|
||||
+{
|
||||
+ struct syment *sp;
|
||||
+ int index;
|
||||
+
|
||||
+ if (!spn)
|
||||
+ return;
|
||||
+
|
||||
+ index = SYMNAME_HASH_INDEX(spn->name);
|
||||
+
|
||||
+ if (st->mod_symname_hash[index] == spn) {
|
||||
+ st->mod_symname_hash[index] = spn->name_hash_next;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ for (sp = st->mod_symname_hash[index]; sp; sp = sp->name_hash_next) {
|
||||
+ if (sp->name_hash_next == spn) {
|
||||
+ sp->name_hash_next = spn->name_hash_next;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mod_symtable_hash_install_range(struct syment *from, struct syment *to)
|
||||
+{
|
||||
+ struct syment *sp;
|
||||
+
|
||||
+ for (sp = from; sp <= to; sp++)
|
||||
+ mod_symname_hash_install(sp);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mod_symtable_hash_remove_range(struct syment *from, struct syment *to)
|
||||
+{
|
||||
+ struct syment *sp;
|
||||
+
|
||||
+ for (sp = from; sp <= to; sp++)
|
||||
+ mod_symname_hash_remove(sp);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Static kernel symbol value search
|
||||
*/
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,59 +0,0 @@
|
||||
From 647a5c33e1c94054d7b63168cd6c12901591cb77 Mon Sep 17 00:00:00 2001
|
||||
From: Lianbo Jiang <lijiang@redhat.com>
|
||||
Date: Thu, 27 May 2021 18:02:11 +0800
|
||||
Subject: [PATCH 02/16] Fix for "kmem -s|-S" option on Linux 5.7 and later
|
||||
kernels
|
||||
|
||||
Linux 5.7 and later kernels that contain kernel commit 1ad53d9fa3f6
|
||||
("slub: improve bit diffusion for freelist ptr obfuscation") changed
|
||||
the calculation formula in the freelist_ptr(), which added a swab()
|
||||
call to mix bits a little more. When kernel is configured with the
|
||||
"CONFIG_SLAB_FREELIST_HARDENED=y", without the patch, the "kmem -s|-S"
|
||||
options display wrong statistics and state whether slab objects are
|
||||
in use or free and can print the following errors:
|
||||
|
||||
crash> kmem -s
|
||||
CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
|
||||
87201e00 528 0 0 0 8k xfs_dqtrx
|
||||
87201f00 496 0 0 0 8k xfs_dquot
|
||||
kmem: xfs_buf: slab: 37202e6e900 invalid freepointer: b844bab900001d70
|
||||
kmem: xfs_buf: slab: 3720250fd80 invalid freepointer: b8603f9400001370
|
||||
...
|
||||
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
---
|
||||
memory.c | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/memory.c b/memory.c
|
||||
index 8c6bbe409922..a3cf8a86728d 100644
|
||||
--- a/memory.c
|
||||
+++ b/memory.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <sys/mman.h>
|
||||
#include <ctype.h>
|
||||
#include <netinet/in.h>
|
||||
+#include <byteswap.h>
|
||||
|
||||
struct meminfo { /* general purpose memory information structure */
|
||||
ulong cache; /* used by the various memory searching/dumping */
|
||||
@@ -19336,10 +19337,14 @@ count_free_objects(struct meminfo *si, ulong freelist)
|
||||
static ulong
|
||||
freelist_ptr(struct meminfo *si, ulong ptr, ulong ptr_addr)
|
||||
{
|
||||
- if (VALID_MEMBER(kmem_cache_random))
|
||||
+ if (VALID_MEMBER(kmem_cache_random)) {
|
||||
/* CONFIG_SLAB_FREELIST_HARDENED */
|
||||
+
|
||||
+ if (THIS_KERNEL_VERSION >= LINUX(5,7,0))
|
||||
+ ptr_addr = (sizeof(long) == 8) ? bswap_64(ptr_addr)
|
||||
+ : bswap_32(ptr_addr);
|
||||
return (ptr ^ si->random ^ ptr_addr);
|
||||
- else
|
||||
+ } else
|
||||
return ptr;
|
||||
}
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,125 +0,0 @@
|
||||
From 4631320e96f8a63c897fbbce4e87e3c47af40bc9 Mon Sep 17 00:00:00 2001
|
||||
From: Roman Bolshakov <r.bolshakov@yadro.com>
|
||||
Date: Thu, 17 Jun 2021 02:27:32 +0300
|
||||
Subject: [PATCH 02/27] diskdump: Fail readmem() early if dump is incomplete
|
||||
|
||||
kdump format description [1] says:
|
||||
|
||||
[...] zero page has its own offset not equal 0. So when reading page
|
||||
from incomplete core, only the page lost by ENOSPACE errors has 0 in its
|
||||
corresponding page descriptor's member offset.
|
||||
|
||||
crash has special treatment for page descriptors with zero offset only if
|
||||
DUMP_DH_COMPRESSED_INCOMPLETE is set in dump header. However,
|
||||
makedumpfile places the flag after ENOSPC is hit and only if dump header
|
||||
modification went without errors.
|
||||
|
||||
In case if crashkernel environment was terminated early (e.g. by BMC) or
|
||||
some other reason, DUMP_DH_COMPRESSED_INCOMPLETE won't be set on the
|
||||
dump header. Then cache_page() would be performed on pages with
|
||||
pd.offset == 0 and due to pd.size == 0 it'll skip read into
|
||||
compressed_page and then non related pre-existing contents of
|
||||
compressed_page will copied into page cache for the non-present page.
|
||||
|
||||
Ultimately, it'll lead to a cryptic failure, like:
|
||||
|
||||
crash: invalid kernel virtual address: 72288cacacf427f8 [...]
|
||||
|
||||
The failure would be a bit cleaner if crash explicitly fails on the page
|
||||
that is an outcome of incomplete dump:
|
||||
|
||||
crash: page incomplete: kernel virtual address: c000003fff9d17e8 [...]
|
||||
|
||||
Debugging level 8 would also produce exact offset from data_offset to
|
||||
print descriptor value with ease:
|
||||
|
||||
read_diskdump/cache_page: descriptor with zero offset found at paddr/pfn/pos: 3fff9d0000/3fff9d/743dd
|
||||
|
||||
That helps in inspecting broken descriptor with hexdump or similar tools:
|
||||
|
||||
hexdump -s (data_offset + pos * 0x18) -n 0x18
|
||||
|
||||
[1] https://github.com/makedumpfile/makedumpfile/blob/master/IMPLEMENTATION
|
||||
|
||||
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
|
||||
---
|
||||
defs.h | 1 +
|
||||
diskdump.c | 16 +++++++++++-----
|
||||
memory.c | 7 +++++++
|
||||
3 files changed, 19 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/defs.h b/defs.h
|
||||
index c91177a245fd..eb1c71b5333a 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -361,6 +361,7 @@ struct number_option {
|
||||
#define READ_ERROR (-2)
|
||||
#define WRITE_ERROR (-3)
|
||||
#define PAGE_EXCLUDED (-4)
|
||||
+#define PAGE_INCOMPLETE (-5)
|
||||
|
||||
#define RESTART() (longjmp(pc->main_loop_env, 1))
|
||||
#define RESUME_FOREACH() (longjmp(pc->foreach_loop_env, 1))
|
||||
diff --git a/diskdump.c b/diskdump.c
|
||||
index 668069585080..59b79e1bce95 100644
|
||||
--- a/diskdump.c
|
||||
+++ b/diskdump.c
|
||||
@@ -1146,10 +1146,9 @@ cache_page(physaddr_t paddr)
|
||||
if (FLAT_FORMAT()) {
|
||||
if (!read_flattened_format(dd->dfd, pd.offset, dd->compressed_page, pd.size))
|
||||
return READ_ERROR;
|
||||
- } else if (is_incomplete_dump() && (0 == pd.offset)) {
|
||||
+ } else if (0 == pd.offset) {
|
||||
/*
|
||||
- * If the incomplete flag has been set in the header,
|
||||
- * first check whether zero_excluded has been set.
|
||||
+ * First check whether zero_excluded has been set.
|
||||
*/
|
||||
if (*diskdump_flags & ZERO_EXCLUDED) {
|
||||
if (CRASHDEBUG(8))
|
||||
@@ -1158,8 +1157,15 @@ cache_page(physaddr_t paddr)
|
||||
"paddr/pfn: %llx/%lx\n",
|
||||
(ulonglong)paddr, pfn);
|
||||
memset(dd->compressed_page, 0, dd->block_size);
|
||||
- } else
|
||||
- return READ_ERROR;
|
||||
+ } else {
|
||||
+ if (CRASHDEBUG(8))
|
||||
+ fprintf(fp,
|
||||
+ "read_diskdump/cache_page: "
|
||||
+ "descriptor with zero offset found at "
|
||||
+ "paddr/pfn/pos: %llx/%lx/%lx\n",
|
||||
+ (ulonglong)paddr, pfn, desc_pos);
|
||||
+ return PAGE_INCOMPLETE;
|
||||
+ }
|
||||
} else {
|
||||
if (lseek(dd->dfd, pd.offset, SEEK_SET) == failed)
|
||||
return SEEK_ERROR;
|
||||
diff --git a/memory.c b/memory.c
|
||||
index ca4c633e5074..86c02c132890 100644
|
||||
--- a/memory.c
|
||||
+++ b/memory.c
|
||||
@@ -2213,6 +2213,7 @@ accessible(ulong kva)
|
||||
#define READ_ERRMSG "read error: %s address: %llx type: \"%s\"\n"
|
||||
#define WRITE_ERRMSG "write error: %s address: %llx type: \"%s\"\n"
|
||||
#define PAGE_EXCLUDED_ERRMSG "page excluded: %s address: %llx type: \"%s\"\n"
|
||||
+#define PAGE_INCOMPLETE_ERRMSG "page incomplete: %s address: %llx type: \"%s\"\n"
|
||||
|
||||
#define RETURN_ON_PARTIAL_READ() \
|
||||
if ((error_handle & RETURN_PARTIAL) && (size < orig_size)) { \
|
||||
@@ -2378,6 +2379,12 @@ readmem(ulonglong addr, int memtype, void *buffer, long size,
|
||||
error(INFO, PAGE_EXCLUDED_ERRMSG, memtype_string(memtype, 0), addr, type);
|
||||
goto readmem_error;
|
||||
|
||||
+ case PAGE_INCOMPLETE:
|
||||
+ RETURN_ON_PARTIAL_READ();
|
||||
+ if (PRINT_ERROR_MESSAGE)
|
||||
+ error(INFO, PAGE_INCOMPLETE_ERRMSG, memtype_string(memtype, 0), addr, type);
|
||||
+ goto readmem_error;
|
||||
+
|
||||
default:
|
||||
break;
|
||||
}
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,103 +0,0 @@
|
||||
From 214f9bf3727c3350401b3f4b4389258c24486e06 Mon Sep 17 00:00:00 2001
|
||||
From: Tao Liu <ltao@redhat.com>
|
||||
Date: Sat, 16 Oct 2021 13:21:12 +0800
|
||||
Subject: [PATCH 2/9] symbols: Integrate symbol_search() with mod_symname_hash
|
||||
search
|
||||
|
||||
This patch introduces mod_symname_hash search to symbol_search(),
|
||||
to get a better searching performance.
|
||||
|
||||
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||
Reviewed-by: Philipp Rudo <prudo@redhat.com>
|
||||
---
|
||||
symbols.c | 58 ++++++++++++++++++-------------------------------------
|
||||
1 file changed, 19 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/symbols.c b/symbols.c
|
||||
index ad12d1c22225..c4ad31fe926f 100644
|
||||
--- a/symbols.c
|
||||
+++ b/symbols.c
|
||||
@@ -4551,6 +4551,17 @@ symbol_query(char *s, char *print_pad, struct syment **spp)
|
||||
return(cnt);
|
||||
}
|
||||
|
||||
+static int
|
||||
+skip_symbols(struct syment *sp, char *s)
|
||||
+{
|
||||
+ int pseudos, skip = FALSE;
|
||||
+
|
||||
+ pseudos = (strstr(s, "_MODULE_START_") || strstr(s, "_MODULE_END_") ||
|
||||
+ strstr(s, "_MODULE_INIT_START_") || strstr(s, "_MODULE_INIT_END_"));
|
||||
+ if (!pseudos && MODULE_PSEUDO_SYMBOL(sp))
|
||||
+ skip = TRUE;
|
||||
+ return skip;
|
||||
+}
|
||||
|
||||
/*
|
||||
* Return the syment of a symbol.
|
||||
@@ -4558,10 +4569,7 @@ symbol_query(char *s, char *print_pad, struct syment **spp)
|
||||
struct syment *
|
||||
symbol_search(char *s)
|
||||
{
|
||||
- int i;
|
||||
- struct syment *sp_hashed, *sp, *sp_end;
|
||||
- struct load_module *lm;
|
||||
- int pseudos, search_init;
|
||||
+ struct syment *sp_hashed, *sp;
|
||||
|
||||
sp_hashed = symname_hash_search(s);
|
||||
|
||||
@@ -4570,43 +4578,15 @@ symbol_search(char *s)
|
||||
return(sp);
|
||||
}
|
||||
|
||||
- pseudos = (strstr(s, "_MODULE_START_") || strstr(s, "_MODULE_END_"));
|
||||
- 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 = lm->mod_symtable;
|
||||
- sp_end = lm->mod_symend;
|
||||
-
|
||||
- for ( ; sp <= sp_end; sp++) {
|
||||
- if (!pseudos && MODULE_PSEUDO_SYMBOL(sp))
|
||||
- continue;
|
||||
- if (STREQ(s, sp->name))
|
||||
- return(sp);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (!search_init)
|
||||
- return((struct syment *)NULL);
|
||||
-
|
||||
- pseudos = (strstr(s, "_MODULE_INIT_START_") || strstr(s, "_MODULE_INIT_END_"));
|
||||
-
|
||||
- for (i = 0; i < st->mods_installed; i++) {
|
||||
- lm = &st->load_modules[i];
|
||||
- if (!lm->mod_init_symtable)
|
||||
+ sp = st->mod_symname_hash[SYMNAME_HASH_INDEX(s)];
|
||||
+ while (sp) {
|
||||
+ if (skip_symbols(sp, s)) {
|
||||
+ sp = sp->name_hash_next;
|
||||
continue;
|
||||
- sp = lm->mod_init_symtable;
|
||||
- sp_end = lm->mod_init_symend;
|
||||
-
|
||||
- for ( ; sp < sp_end; sp++) {
|
||||
- if (!pseudos && MODULE_PSEUDO_SYMBOL(sp))
|
||||
- continue;
|
||||
-
|
||||
- if (STREQ(s, sp->name))
|
||||
- return(sp);
|
||||
}
|
||||
+ if (STREQ(sp->name, s))
|
||||
+ return sp;
|
||||
+ sp = sp->name_hash_next;
|
||||
}
|
||||
|
||||
return((struct syment *)NULL);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,102 +0,0 @@
|
||||
From 0b5435e10161345cf713ed447a155a611a1b408b Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Wed, 26 May 2021 17:33:13 +0900
|
||||
Subject: [PATCH 03/16] memory: Add support for SECTION_TAINT_ZONE_DEVICE flag
|
||||
|
||||
Fix for "kmem -n|-p" options on Linux 5.12-rc1 and later kernels
|
||||
that contain commit 1f90a3477df3f ("mm: teach pfn_to_online_page()
|
||||
about ZONE_DEVICE section collisions"). Without the patch, the
|
||||
"kmem -n" option incorrectly shows mem_map addresses containing the
|
||||
flag in bit 5 as part of the virtual address, and also the "kmem -p"
|
||||
option shows page structures at wrong position. With the patch,
|
||||
the "kmem -n" option displays the new "D" state flag.
|
||||
|
||||
Without the patch:
|
||||
crash> kmem -n
|
||||
...
|
||||
NR SECTION CODED_MEM_MAP MEM_MAP STATE PFN
|
||||
1040 ffff9edf3ffd4100 ffffe2bcc0000010 ffffe2bd42000010 PMOE 34078720
|
||||
^ ^
|
||||
crash> kmem -p
|
||||
PAGE PHYSICAL MAPPING INDEX CNT FLAGS
|
||||
ffffe2bd42000010 2080000000 400040 1ffffffff 9961471 dead000000000122 referenced,active,error
|
||||
ffffe2bd42000050 2080001000 800080 1ffffffff 9961471 dead000000000122 referenced,active,error
|
||||
ffffe2bd42000090 2080002000 0 1ffffffff 9961471 dead000000000122 referenced,active,error
|
||||
^^
|
||||
With the patch:
|
||||
crash> kmem -n
|
||||
...
|
||||
NR SECTION CODED_MEM_MAP MEM_MAP STATE PFN
|
||||
1040 ffff9edf3ffd4100 ffffe2bcc0000000 ffffe2bd42000000 PMOED 34078720
|
||||
|
||||
crash> kmem -p
|
||||
PAGE PHYSICAL MAPPING INDEX CNT FLAGS
|
||||
ffffe2bd42000000 2080000000 ffff9ebfc0044100 0 1 97ffffc0000200 slab
|
||||
ffffe2bd42000040 2080001000 ffff9ebfc0044400 0 1 97ffffc0000200 slab
|
||||
ffffe2bd42000080 2080002000 0 0 1 97ffffc0000000
|
||||
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
---
|
||||
help.c | 11 +++++++----
|
||||
memory.c | 15 +++++++++------
|
||||
2 files changed, 16 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/help.c b/help.c
|
||||
index e0c84087add3..9649cc81fa36 100644
|
||||
--- a/help.c
|
||||
+++ b/help.c
|
||||
@@ -6584,10 +6584,13 @@ char *help_kmem[] = {
|
||||
" kernels, the vm_zone_stat, vm_node_stat and vm_numa_stat tables,",
|
||||
" the cumulative page_states counter values if they exist, and/or ",
|
||||
" the cumulative, vm_event_states counter values if they exist.",
|
||||
-" -n display memory node, memory section, and memory block data",
|
||||
-" and state; the state of each memory section state is encoded",
|
||||
-" as \"P\", \"M\", \"O\" and/or \"E\", meaning SECTION_MARKED_PRESENT,",
|
||||
-" SECTION_HAS_MEM_MAP, SECTION_IS_ONLINE and SECTION_IS_EARLY.",
|
||||
+" -n display memory node, memory section, memory block data and state;",
|
||||
+" the state of each memory section is shown as the following flags:",
|
||||
+" \"P\": SECTION_MARKED_PRESENT",
|
||||
+" \"M\": SECTION_HAS_MEM_MAP",
|
||||
+" \"O\": SECTION_IS_ONLINE",
|
||||
+" \"E\": SECTION_IS_EARLY",
|
||||
+" \"D\": SECTION_TAINT_ZONE_DEVICE",
|
||||
" -z displays per-zone memory statistics.",
|
||||
" -o displays each cpu's offset value that is added to per-cpu symbol",
|
||||
" values to translate them into kernel virtual addresses.",
|
||||
diff --git a/memory.c b/memory.c
|
||||
index a3cf8a86728d..2c4f9790f498 100644
|
||||
--- a/memory.c
|
||||
+++ b/memory.c
|
||||
@@ -17270,12 +17270,13 @@ nr_to_section(ulong nr)
|
||||
* which results in PFN_SECTION_SHIFT equal 6.
|
||||
* To sum it up, at least 6 bits are available.
|
||||
*/
|
||||
-#define SECTION_MARKED_PRESENT (1UL<<0)
|
||||
-#define SECTION_HAS_MEM_MAP (1UL<<1)
|
||||
-#define SECTION_IS_ONLINE (1UL<<2)
|
||||
-#define SECTION_IS_EARLY (1UL<<3)
|
||||
-#define SECTION_MAP_LAST_BIT (1UL<<4)
|
||||
-#define SECTION_MAP_MASK (~(SECTION_MAP_LAST_BIT-1))
|
||||
+#define SECTION_MARKED_PRESENT (1UL<<0)
|
||||
+#define SECTION_HAS_MEM_MAP (1UL<<1)
|
||||
+#define SECTION_IS_ONLINE (1UL<<2)
|
||||
+#define SECTION_IS_EARLY (1UL<<3)
|
||||
+#define SECTION_TAINT_ZONE_DEVICE (1UL<<4)
|
||||
+#define SECTION_MAP_LAST_BIT (1UL<<5)
|
||||
+#define SECTION_MAP_MASK (~(SECTION_MAP_LAST_BIT-1))
|
||||
|
||||
|
||||
int
|
||||
@@ -17373,6 +17374,8 @@ fill_mem_section_state(ulong state, char *buf)
|
||||
bufidx += sprintf(buf + bufidx, "%s", "O");
|
||||
if (state & SECTION_IS_EARLY)
|
||||
bufidx += sprintf(buf + bufidx, "%s", "E");
|
||||
+ if (state & SECTION_TAINT_ZONE_DEVICE)
|
||||
+ bufidx += sprintf(buf + bufidx, "%s", "D");
|
||||
}
|
||||
|
||||
void
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,36 +0,0 @@
|
||||
From 41cda195c6421fbde72ed67b32b8c1ab3eb0c56f Mon Sep 17 00:00:00 2001
|
||||
From: Roman Bolshakov <r.bolshakov@yadro.com>
|
||||
Date: Thu, 17 Jun 2021 02:27:33 +0300
|
||||
Subject: [PATCH 03/27] netdump: Permit --zero_excluded for incomplete ELF
|
||||
dumps
|
||||
|
||||
DUMP_ELF_INCOMPLETE is set very late after ENOSPC error is hit by
|
||||
makedumpfile. Any following error that prevents modification of ELF
|
||||
header would result in effectively incomplete core that doesn't have the
|
||||
flag. zero_excluded flag doesn't work for such kind of incomplete core.
|
||||
|
||||
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
|
||||
---
|
||||
netdump.c | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/netdump.c b/netdump.c
|
||||
index aaea945aaca7..e8721d89f1a3 100644
|
||||
--- a/netdump.c
|
||||
+++ b/netdump.c
|
||||
@@ -819,10 +819,9 @@ read_netdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
|
||||
read_ret = read(nd->ndfd, bufptr, cnt);
|
||||
if (read_ret != cnt) {
|
||||
/*
|
||||
- * If the incomplete flag has been set in the header,
|
||||
- * first check whether zero_excluded has been set.
|
||||
+ * First check whether zero_excluded has been set.
|
||||
*/
|
||||
- if (is_incomplete_dump() && (read_ret >= 0) &&
|
||||
+ if ((read_ret >= 0) &&
|
||||
(*diskdump_flags & ZERO_EXCLUDED)) {
|
||||
if (CRASHDEBUG(8))
|
||||
fprintf(fp, "read_netdump: zero-fill: "
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,82 +0,0 @@
|
||||
From 340c6ad1a0a7ce76eb5d9397833bfc6a049e2b3b Mon Sep 17 00:00:00 2001
|
||||
From: Tao Liu <ltao@redhat.com>
|
||||
Date: Sat, 16 Oct 2021 13:21:13 +0800
|
||||
Subject: [PATCH 3/9] symbols: Extend symname_hash_search() with hash table
|
||||
select
|
||||
|
||||
Previously symname_hash_search() can only search symbols from kernel's
|
||||
symname_hash. This patch add hash table pointer as parameter for
|
||||
symname_hash_search(). Thus symname_hash_search() can be used both for
|
||||
symname_hash and mod_symname_hash searching.
|
||||
|
||||
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||
---
|
||||
symbols.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/symbols.c b/symbols.c
|
||||
index c4ad31fe926f..83393f09270d 100644
|
||||
--- a/symbols.c
|
||||
+++ b/symbols.c
|
||||
@@ -65,7 +65,7 @@ static void symval_hash_init(void);
|
||||
static struct syment *symval_hash_search(ulong);
|
||||
static void symname_hash_init(void);
|
||||
static void symname_hash_install(struct syment *);
|
||||
-static struct syment *symname_hash_search(char *);
|
||||
+static struct syment *symname_hash_search(struct syment *[], char *);
|
||||
static void gnu_qsort(bfd *, void *, long, unsigned int, asymbol *, asymbol *);
|
||||
static int check_gnu_debuglink(bfd *);
|
||||
static int separate_debug_file_exists(const char *, unsigned long, int *);
|
||||
@@ -1234,11 +1234,11 @@ mod_symtable_hash_remove_range(struct syment *from, struct syment *to)
|
||||
* Static kernel symbol value search
|
||||
*/
|
||||
static struct syment *
|
||||
-symname_hash_search(char *name)
|
||||
+symname_hash_search(struct syment *table[], char *name)
|
||||
{
|
||||
struct syment *sp;
|
||||
|
||||
- sp = st->symname_hash[SYMNAME_HASH_INDEX(name)];
|
||||
+ sp = table[SYMNAME_HASH_INDEX(name)];
|
||||
|
||||
while (sp) {
|
||||
if (STREQ(sp->name, name))
|
||||
@@ -4571,7 +4571,7 @@ symbol_search(char *s)
|
||||
{
|
||||
struct syment *sp_hashed, *sp;
|
||||
|
||||
- sp_hashed = symname_hash_search(s);
|
||||
+ sp_hashed = symname_hash_search(st->symname_hash, s);
|
||||
|
||||
for (sp = sp_hashed ? sp_hashed : st->symtable; sp < st->symend; sp++) {
|
||||
if (STREQ(s, sp->name))
|
||||
@@ -5485,7 +5485,7 @@ symbol_exists(char *symbol)
|
||||
struct syment *sp, *sp_end;
|
||||
struct load_module *lm;
|
||||
|
||||
- if ((sp = symname_hash_search(symbol)))
|
||||
+ if ((sp = symname_hash_search(st->symname_hash, symbol)))
|
||||
return TRUE;
|
||||
|
||||
for (i = 0; i < st->mods_installed; i++) {
|
||||
@@ -5564,7 +5564,7 @@ kernel_symbol_exists(char *symbol)
|
||||
{
|
||||
struct syment *sp;
|
||||
|
||||
- if ((sp = symname_hash_search(symbol)))
|
||||
+ if ((sp = symname_hash_search(st->symname_hash, symbol)))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
@@ -5576,7 +5576,7 @@ kernel_symbol_exists(char *symbol)
|
||||
struct syment *
|
||||
kernel_symbol_search(char *symbol)
|
||||
{
|
||||
- return symname_hash_search(symbol);
|
||||
+ return symname_hash_search(st->symname_hash, symbol);
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,52 +0,0 @@
|
||||
From 1425b0504b1e79d88a2d188d7e4c0e7fceba4501 Mon Sep 17 00:00:00 2001
|
||||
From: Roman Bolshakov <r.bolshakov@yadro.com>
|
||||
Date: Thu, 17 Jun 2021 02:27:34 +0300
|
||||
Subject: [PATCH 04/27] diskdump: Print total number of dumpable pages
|
||||
|
||||
It's not clear how broken an incomplete dump from the existing debugging
|
||||
prints. Aggregate number of valid pages helps to figure out approximate
|
||||
size of the dump. Size of a complete dump is roughly:
|
||||
|
||||
EXPECTED_CORE_SIZE = a few pages (kdump headers + bitmaps + descriptors) +
|
||||
(total_valid_pages * block_size) * compression rate
|
||||
|
||||
An incomplete core would be significantly smaller than:
|
||||
|
||||
total_valid_pages * block_size
|
||||
|
||||
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
|
||||
---
|
||||
diskdump.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/diskdump.c b/diskdump.c
|
||||
index 59b79e1bce95..0f9402248d51 100644
|
||||
--- a/diskdump.c
|
||||
+++ b/diskdump.c
|
||||
@@ -74,6 +74,7 @@ struct diskdump_data {
|
||||
ulong evictions; /* total evictions done */
|
||||
ulong cached_reads;
|
||||
ulong *valid_pages;
|
||||
+ int max_sect_len; /* highest bucket of valid_pages */
|
||||
ulong accesses;
|
||||
ulong snapshot_task;
|
||||
};
|
||||
@@ -877,6 +878,7 @@ restart:
|
||||
}
|
||||
|
||||
dd->valid_pages = calloc(sizeof(ulong), max_sect_len + 1);
|
||||
+ dd->max_sect_len = max_sect_len;
|
||||
for (i = 1; i < max_sect_len + 1; i++) {
|
||||
dd->valid_pages[i] = dd->valid_pages[i - 1];
|
||||
for (j = 0; j < BITMAP_SECT_LEN; j++, pfn++)
|
||||
@@ -2089,6 +2091,7 @@ __diskdump_memory_dump(FILE *fp)
|
||||
else
|
||||
fprintf(fp, "\n");
|
||||
fprintf(fp, " valid_pages: %lx\n", (ulong)dd->valid_pages);
|
||||
+ fprintf(fp, " total_valid_pages: %ld\n", dd->valid_pages[dd->max_sect_len]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,50 +0,0 @@
|
||||
From ec44b902d3467e7b86ee39e2d7d472b9cb202148 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Mon, 31 May 2021 14:08:28 +0900
|
||||
Subject: [PATCH 04/16] memory: Fix for "kmem -n" option to display NID
|
||||
correctly
|
||||
|
||||
The nid member of struct memory_block is a 4-byte integer, but read
|
||||
and printed as a 8-byte integer on 64-bit machines. Without the
|
||||
patch, the option displays wrong NIDs.
|
||||
|
||||
crash> kmem -n
|
||||
...
|
||||
MEM_BLOCK NAME PHYSICAL RANGE NODE STATE START_SECTION_NO
|
||||
ffff9edeff2b9400 memory0 0 - 7fffffff 14195095130662240256 ONLINE 0
|
||||
ffff9edeff2bb400 memory2 100000000 - 17fffffff 14195094718345379840 ONLINE 32
|
||||
|
||||
The issue seems to appear on Linux 5.12 and later kernels that contain
|
||||
commit e9a2e48e8704c ("drivers/base/memory: don't store phys_device
|
||||
in memory blocks"), which changed the arrangement of the members of
|
||||
struct memory_block.
|
||||
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
---
|
||||
memory.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/memory.c b/memory.c
|
||||
index 2c4f9790f498..cbe90eebe748 100644
|
||||
--- a/memory.c
|
||||
+++ b/memory.c
|
||||
@@ -17568,13 +17568,13 @@ print_memory_block(ulong memory_block)
|
||||
|
||||
if (MEMBER_EXISTS("memory_block", "nid")) {
|
||||
readmem(memory_block + OFFSET(memory_block_nid), KVADDR, &nid,
|
||||
- sizeof(void *), "memory_block nid", FAULT_ON_ERROR);
|
||||
+ sizeof(int), "memory_block nid", FAULT_ON_ERROR);
|
||||
fprintf(fp, " %s %s %s %s %s %s\n",
|
||||
mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
|
||||
MKSTR(memory_block)),
|
||||
mkstring(buf2, 12, CENTER, name),
|
||||
parangebuf,
|
||||
- mkstring(buf5, strlen("NODE"), CENTER|LONG_DEC,
|
||||
+ mkstring(buf5, strlen("NODE"), CENTER|INT_DEC,
|
||||
MKSTR(nid)),
|
||||
mkstring(buf6, strlen("OFFLINE"), LJUST,
|
||||
statebuf),
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,74 +0,0 @@
|
||||
From f3bee9375ed32b85e7f81a5e46a0040620553ae0 Mon Sep 17 00:00:00 2001
|
||||
From: Tao Liu <ltao@redhat.com>
|
||||
Date: Sat, 16 Oct 2021 13:21:14 +0800
|
||||
Subject: [PATCH 4/9] symbols: Intergrate symbol_exists() with mod_symname_hash
|
||||
search
|
||||
|
||||
This patch introduces mod_symname_hash search to symbol_exists()
|
||||
to improve its performance. And code refactoring for
|
||||
kernel_symbol_exists().
|
||||
|
||||
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||
Reviewed-by: Philipp Rudo <prudo@redhat.com>
|
||||
---
|
||||
symbols.c | 35 ++++-------------------------------
|
||||
1 file changed, 4 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/symbols.c b/symbols.c
|
||||
index 83393f09270d..8d3dd95f737b 100644
|
||||
--- a/symbols.c
|
||||
+++ b/symbols.c
|
||||
@@ -5481,33 +5481,11 @@ value_symbol(ulong value)
|
||||
int
|
||||
symbol_exists(char *symbol)
|
||||
{
|
||||
- int i;
|
||||
- struct syment *sp, *sp_end;
|
||||
- struct load_module *lm;
|
||||
-
|
||||
- if ((sp = symname_hash_search(st->symname_hash, symbol)))
|
||||
+ if (symname_hash_search(st->symname_hash, symbol))
|
||||
return TRUE;
|
||||
|
||||
- for (i = 0; i < st->mods_installed; i++) {
|
||||
- lm = &st->load_modules[i];
|
||||
- sp = lm->mod_symtable;
|
||||
- sp_end = lm->mod_symend;
|
||||
-
|
||||
- for ( ; sp < sp_end; sp++) {
|
||||
- if (STREQ(symbol, sp->name))
|
||||
- return(TRUE);
|
||||
- }
|
||||
-
|
||||
- if (lm->mod_init_symtable) {
|
||||
- sp = lm->mod_init_symtable;
|
||||
- sp_end = lm->mod_init_symend;
|
||||
-
|
||||
- for ( ; sp < sp_end; sp++) {
|
||||
- if (STREQ(symbol, sp->name))
|
||||
- return(TRUE);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ if (symname_hash_search(st->mod_symname_hash, symbol))
|
||||
+ return TRUE;
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
@@ -5562,12 +5540,7 @@ per_cpu_symbol_search(char *symbol)
|
||||
int
|
||||
kernel_symbol_exists(char *symbol)
|
||||
{
|
||||
- struct syment *sp;
|
||||
-
|
||||
- if ((sp = symname_hash_search(st->symname_hash, symbol)))
|
||||
- return TRUE;
|
||||
- else
|
||||
- return FALSE;
|
||||
+ return !!symname_hash_search(st->symname_hash, symbol);
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,103 +0,0 @@
|
||||
From 704623dfde43da98ffb354b3d7f450cd012a8215 Mon Sep 17 00:00:00 2001
|
||||
From: Youling Tang <tangyouling@loongson.cn>
|
||||
Date: Thu, 3 Jun 2021 16:07:41 +0800
|
||||
Subject: [PATCH 05/16] defs.h: Fix the value of TIF_SIGPENDING macro
|
||||
|
||||
Correct the change of the value of TIF_SIGPENDING macro between
|
||||
different kernel versions.
|
||||
|
||||
TIF_SIGPENDING changes with the kernel version as follows:
|
||||
ARM 2 -> 0 at v2.6.23
|
||||
MIPS 2 -> 1 at v2.6.23
|
||||
MIPS64 2 -> 1 at v2.6.23
|
||||
PPC 2 -> 1 at v2.6.23
|
||||
IA64 1 -> 0 at v2.6.23
|
||||
PPC64 2 -> 1 at v2.6.23
|
||||
S390 2 -> 1 at v3.16
|
||||
S390X 2 -> 1 at v3.16
|
||||
|
||||
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
---
|
||||
defs.h | 16 ++++++++--------
|
||||
1 file changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/defs.h b/defs.h
|
||||
index 396d61aaf532..3502c6d6e90c 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -2997,7 +2997,7 @@ typedef struct QEMUCPUState QEMUCPUState;
|
||||
#define __swp_type(entry) SWP_TYPE(entry)
|
||||
#define __swp_offset(entry) SWP_OFFSET(entry)
|
||||
|
||||
-#define TIF_SIGPENDING (2)
|
||||
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 0 : 2)
|
||||
|
||||
#define _SECTION_SIZE_BITS 28
|
||||
#define _MAX_PHYSMEM_BITS 32
|
||||
@@ -3377,7 +3377,7 @@ struct arm64_stackframe {
|
||||
#define __swp_type(entry) SWP_TYPE(entry)
|
||||
#define __swp_offset(entry) SWP_OFFSET(entry)
|
||||
|
||||
-#define TIF_SIGPENDING (2)
|
||||
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 1 : 2)
|
||||
|
||||
#define _SECTION_SIZE_BITS 26
|
||||
#define _MAX_PHYSMEM_BITS 32
|
||||
@@ -3416,7 +3416,7 @@ struct arm64_stackframe {
|
||||
#define __swp_type(entry) SWP_TYPE(entry)
|
||||
#define __swp_offset(entry) SWP_OFFSET(entry)
|
||||
|
||||
-#define TIF_SIGPENDING (2)
|
||||
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 1 : 2)
|
||||
|
||||
#define _SECTION_SIZE_BITS 28
|
||||
#define _MAX_PHYSMEM_BITS 48
|
||||
@@ -3884,7 +3884,7 @@ struct machine_specific {
|
||||
#define __swp_type(entry) SWP_TYPE(entry)
|
||||
#define __swp_offset(entry) SWP_OFFSET(entry)
|
||||
|
||||
-#define TIF_SIGPENDING (2)
|
||||
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 1 : 2)
|
||||
|
||||
#define _SECTION_SIZE_BITS 24
|
||||
#define _MAX_PHYSMEM_BITS 44
|
||||
@@ -4079,7 +4079,7 @@ struct efi_memory_desc_t {
|
||||
#define __swp_type(entry) ((entry >> 2) & 0x7f)
|
||||
#define __swp_offset(entry) ((entry << 1) >> 10)
|
||||
|
||||
-#define TIF_SIGPENDING (1)
|
||||
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 0 : 1)
|
||||
|
||||
#define KERNEL_TR_PAGE_SIZE (1 << _PAGE_SIZE_64M)
|
||||
#define KERNEL_TR_PAGE_MASK (~(KERNEL_TR_PAGE_SIZE - 1))
|
||||
@@ -4219,7 +4219,7 @@ struct efi_memory_desc_t {
|
||||
#define PTE_RPN_MASK (machdep->machspec->pte_rpn_mask)
|
||||
#define PTE_RPN_SHIFT (machdep->machspec->pte_rpn_shift)
|
||||
|
||||
-#define TIF_SIGPENDING (2)
|
||||
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 1 : 2)
|
||||
|
||||
#define SWP_TYPE(entry) (((entry) >> 1) & 0x7f)
|
||||
#define SWP_OFFSET(entry) ((entry) >> 8)
|
||||
@@ -4259,7 +4259,7 @@ struct efi_memory_desc_t {
|
||||
#define __swp_type(entry) SWP_TYPE(entry)
|
||||
#define __swp_offset(entry) SWP_OFFSET(entry)
|
||||
|
||||
-#define TIF_SIGPENDING (2)
|
||||
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(3,16,0) ? 1 : 2)
|
||||
|
||||
#define _SECTION_SIZE_BITS 25
|
||||
#define _MAX_PHYSMEM_BITS 31
|
||||
@@ -4284,7 +4284,7 @@ struct efi_memory_desc_t {
|
||||
#define __swp_type(entry) SWP_TYPE(entry)
|
||||
#define __swp_offset(entry) SWP_OFFSET(entry)
|
||||
|
||||
-#define TIF_SIGPENDING (2)
|
||||
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(3,16,0) ? 1 : 2)
|
||||
|
||||
#define _SECTION_SIZE_BITS 28
|
||||
#define _MAX_PHYSMEM_BITS_OLD 42
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,67 +0,0 @@
|
||||
From 881f33d97cee9895796829d0cc969b51dd34d831 Mon Sep 17 00:00:00 2001
|
||||
From: Roman Bolshakov <r.bolshakov@yadro.com>
|
||||
Date: Thu, 17 Jun 2021 02:27:35 +0300
|
||||
Subject: [PATCH 05/27] diskdump: Introduce read_pd()
|
||||
|
||||
Standalone function for reading of page descriptors is needed later for
|
||||
of expected core size and detection of incomplete dumps.
|
||||
|
||||
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
|
||||
---
|
||||
diskdump.c | 33 ++++++++++++++++++++++++---------
|
||||
1 file changed, 24 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/diskdump.c b/diskdump.c
|
||||
index 0f9402248d51..de3eeb2c720c 100644
|
||||
--- a/diskdump.c
|
||||
+++ b/diskdump.c
|
||||
@@ -510,6 +510,27 @@ arm_kdump_header_adjust(int header_version)
|
||||
}
|
||||
#endif /* __i386__ && (ARM || MIPS) */
|
||||
|
||||
+/*
|
||||
+ * Read page descriptor.
|
||||
+ */
|
||||
+static int
|
||||
+read_pd(int fd, off_t offset, page_desc_t *pd)
|
||||
+{
|
||||
+ const off_t failed = (off_t)-1;
|
||||
+
|
||||
+ if (FLAT_FORMAT()) {
|
||||
+ if (!read_flattened_format(fd, offset, pd, sizeof(*pd)))
|
||||
+ return READ_ERROR;
|
||||
+ } else {
|
||||
+ if (lseek(fd, offset, SEEK_SET) == failed)
|
||||
+ return SEEK_ERROR;
|
||||
+ if (read(fd, pd, sizeof(*pd)) != sizeof(*pd))
|
||||
+ return READ_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
read_dump_header(char *file)
|
||||
{
|
||||
@@ -1130,15 +1151,9 @@ cache_page(physaddr_t paddr)
|
||||
+ (off_t)(desc_pos - 1)*sizeof(page_desc_t);
|
||||
|
||||
/* read page descriptor */
|
||||
- if (FLAT_FORMAT()) {
|
||||
- if (!read_flattened_format(dd->dfd, seek_offset, &pd, sizeof(pd)))
|
||||
- return READ_ERROR;
|
||||
- } else {
|
||||
- if (lseek(dd->dfd, seek_offset, SEEK_SET) == failed)
|
||||
- return SEEK_ERROR;
|
||||
- if (read(dd->dfd, &pd, sizeof(pd)) != sizeof(pd))
|
||||
- return READ_ERROR;
|
||||
- }
|
||||
+ ret = read_pd(dd->dfd, seek_offset, &pd);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
|
||||
/* sanity check */
|
||||
if (pd.size > block_size)
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,92 +0,0 @@
|
||||
From 1e23335dab6bf9f6219a23bf0be4ad9f433f4f43 Mon Sep 17 00:00:00 2001
|
||||
From: Tao Liu <ltao@redhat.com>
|
||||
Date: Sat, 16 Oct 2021 13:21:15 +0800
|
||||
Subject: [PATCH 5/9] symbols: Sync module symbols into mod_symtable whenever
|
||||
module symbols change
|
||||
|
||||
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||
Reviewed-by: Philipp Rudo <prudo@redhat.com>
|
||||
---
|
||||
kernel.c | 1 +
|
||||
symbols.c | 9 +++++++++
|
||||
2 files changed, 10 insertions(+)
|
||||
|
||||
diff --git a/kernel.c b/kernel.c
|
||||
index 3ead4bbb172e..f10b8b216571 100644
|
||||
--- a/kernel.c
|
||||
+++ b/kernel.c
|
||||
@@ -4661,6 +4661,7 @@ reinit_modules(void)
|
||||
st->ext_module_symtable = NULL;
|
||||
st->load_modules = NULL;
|
||||
kt->mods_installed = 0;
|
||||
+ memset(st->mod_symname_hash, 0, sizeof(st->mod_symname_hash));
|
||||
|
||||
module_init();
|
||||
}
|
||||
diff --git a/symbols.c b/symbols.c
|
||||
index 8d3dd95f737b..5603a2efd61f 100644
|
||||
--- a/symbols.c
|
||||
+++ b/symbols.c
|
||||
@@ -1668,6 +1668,7 @@ store_module_symbols_v1(ulong total, int mods_installed)
|
||||
lm->mod_symend = sp;
|
||||
}
|
||||
}
|
||||
+ mod_symtable_hash_install_range(lm->mod_symtable, lm->mod_symend);
|
||||
}
|
||||
|
||||
st->flags |= MODULE_SYMS;
|
||||
@@ -2148,6 +2149,8 @@ store_module_symbols_v2(ulong total, int mods_installed)
|
||||
lm->mod_init_symend = sp;
|
||||
}
|
||||
}
|
||||
+ mod_symtable_hash_install_range(lm->mod_symtable, lm->mod_symend);
|
||||
+ mod_symtable_hash_install_range(lm->mod_init_symtable, lm->mod_init_symend);
|
||||
}
|
||||
|
||||
st->flags |= MODULE_SYMS;
|
||||
@@ -12478,8 +12481,10 @@ store_load_module_symbols(bfd *bfd, int dynamic, void *minisyms,
|
||||
error(INFO, "%s: last symbol: %s is not _MODULE_END_%s?\n",
|
||||
lm->mod_name, lm->mod_load_symend->name, lm->mod_name);
|
||||
|
||||
+ mod_symtable_hash_remove_range(lm->mod_symtable, lm->mod_symend);
|
||||
lm->mod_symtable = lm->mod_load_symtable;
|
||||
lm->mod_symend = lm->mod_load_symend;
|
||||
+ mod_symtable_hash_install_range(lm->mod_symtable, lm->mod_symend);
|
||||
|
||||
lm->mod_flags &= ~MOD_EXT_SYMS;
|
||||
lm->mod_flags |= MOD_LOAD_SYMS;
|
||||
@@ -12509,6 +12514,7 @@ delete_load_module(ulong base_addr)
|
||||
req->name = lm->mod_namelist;
|
||||
gdb_interface(req);
|
||||
}
|
||||
+ mod_symtable_hash_remove_range(lm->mod_symtable, lm->mod_symend);
|
||||
if (lm->mod_load_symtable) {
|
||||
free(lm->mod_load_symtable);
|
||||
namespace_ctl(NAMESPACE_FREE,
|
||||
@@ -12518,6 +12524,7 @@ delete_load_module(ulong base_addr)
|
||||
unlink_module(lm);
|
||||
lm->mod_symtable = lm->mod_ext_symtable;
|
||||
lm->mod_symend = lm->mod_ext_symend;
|
||||
+ mod_symtable_hash_install_range(lm->mod_symtable, lm->mod_symend);
|
||||
lm->mod_flags &= ~(MOD_LOAD_SYMS|MOD_REMOTE|MOD_NOPATCH);
|
||||
lm->mod_flags |= MOD_EXT_SYMS;
|
||||
lm->mod_load_symtable = NULL;
|
||||
@@ -12546,6 +12553,7 @@ delete_load_module(ulong base_addr)
|
||||
req->name = lm->mod_namelist;
|
||||
gdb_interface(req);
|
||||
}
|
||||
+ mod_symtable_hash_remove_range(lm->mod_symtable, lm->mod_symend);
|
||||
if (lm->mod_load_symtable) {
|
||||
free(lm->mod_load_symtable);
|
||||
namespace_ctl(NAMESPACE_FREE,
|
||||
@@ -12555,6 +12563,7 @@ delete_load_module(ulong base_addr)
|
||||
unlink_module(lm);
|
||||
lm->mod_symtable = lm->mod_ext_symtable;
|
||||
lm->mod_symend = lm->mod_ext_symend;
|
||||
+ mod_symtable_hash_install_range(lm->mod_symtable, lm->mod_symend);
|
||||
lm->mod_flags &= ~(MOD_LOAD_SYMS|MOD_REMOTE|MOD_NOPATCH);
|
||||
lm->mod_flags |= MOD_EXT_SYMS;
|
||||
lm->mod_load_symtable = NULL;
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,81 +0,0 @@
|
||||
From 859d1c0e8a6618634cbc1fe7ee2b082a6a3c99a1 Mon Sep 17 00:00:00 2001
|
||||
From: Youling Tang <tangyouling@loongson.cn>
|
||||
Date: Fri, 23 Apr 2021 15:40:41 +0800
|
||||
Subject: [PATCH 06/16] MIPS32/64: Add 'irq' command support
|
||||
|
||||
Add support for the 'irq' series of commands in the MIPS32/64
|
||||
architecture, except for the 'irq -d' command, others can be
|
||||
used. Without the patch, the 'irq' command fails as follows:
|
||||
|
||||
irq: cannot determine number of IRQs
|
||||
|
||||
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
---
|
||||
mips.c | 10 ++++++++--
|
||||
mips64.c | 14 ++++++++++++++
|
||||
2 files changed, 22 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/mips.c b/mips.c
|
||||
index f73dfaddf34e..d6602e3c2b0e 100644
|
||||
--- a/mips.c
|
||||
+++ b/mips.c
|
||||
@@ -1126,8 +1126,14 @@ mips_init(int when)
|
||||
machdep->get_irq_affinity = generic_get_irq_affinity;
|
||||
machdep->section_size_bits = _SECTION_SIZE_BITS;
|
||||
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
|
||||
- ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc,
|
||||
- "irq_desc", NULL, 0);
|
||||
+
|
||||
+ if (symbol_exists("irq_desc"))
|
||||
+ ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc,
|
||||
+ "irq_desc", NULL, 0);
|
||||
+ else if (kernel_symbol_exists("nr_irqs"))
|
||||
+ get_symbol_data("nr_irqs", sizeof(unsigned int),
|
||||
+ &machdep->nr_irqs);
|
||||
+
|
||||
mips_stackframe_init();
|
||||
|
||||
if (!machdep->hz)
|
||||
diff --git a/mips64.c b/mips64.c
|
||||
index 62ed799f479a..b1d6acfbd609 100644
|
||||
--- a/mips64.c
|
||||
+++ b/mips64.c
|
||||
@@ -1160,6 +1160,9 @@ mips64_dump_machdep_table(ulong arg)
|
||||
fprintf(fp, " is_task_addr: mips64_is_task_addr()\n");
|
||||
fprintf(fp, " verify_symbol: mips64_verify_symbol()\n");
|
||||
fprintf(fp, " dis_filter: generic_dis_filter()\n");
|
||||
+ fprintf(fp, " dump_irq: generic_dump_irq()\n");
|
||||
+ fprintf(fp, " show_interrupts: generic_show_interrupts()\n");
|
||||
+ fprintf(fp, " get_irq_affinity: generic_get_irq_affinity()\n");
|
||||
fprintf(fp, " cmd_mach: mips64_cmd_mach()\n");
|
||||
fprintf(fp, " get_smp_cpus: mips64_get_smp_cpus()\n");
|
||||
fprintf(fp, " is_kvaddr: generic_is_kvaddr()\n");
|
||||
@@ -1246,6 +1249,9 @@ mips64_init(int when)
|
||||
machdep->is_task_addr = mips64_is_task_addr;
|
||||
machdep->get_smp_cpus = mips64_get_smp_cpus;
|
||||
machdep->dis_filter = generic_dis_filter;
|
||||
+ machdep->dump_irq = generic_dump_irq;
|
||||
+ machdep->show_interrupts = generic_show_interrupts;
|
||||
+ machdep->get_irq_affinity = generic_get_irq_affinity;
|
||||
machdep->value_to_symbol = generic_machdep_value_to_symbol;
|
||||
machdep->init_kernel_pgd = NULL;
|
||||
break;
|
||||
@@ -1257,6 +1263,14 @@ mips64_init(int when)
|
||||
mips64_stackframe_init();
|
||||
if (!machdep->hz)
|
||||
machdep->hz = 250;
|
||||
+
|
||||
+ if (symbol_exists("irq_desc"))
|
||||
+ ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc,
|
||||
+ "irq_desc", NULL, 0);
|
||||
+ else if (kernel_symbol_exists("nr_irqs"))
|
||||
+ get_symbol_data("nr_irqs", sizeof(unsigned int),
|
||||
+ &machdep->nr_irqs);
|
||||
+
|
||||
MEMBER_OFFSET_INIT(elf_prstatus_pr_reg, "elf_prstatus",
|
||||
"pr_reg");
|
||||
STRUCT_SIZE_INIT(note_buf, "note_buf_t");
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,121 +0,0 @@
|
||||
From df0049d12b2ced1b6ff7350ee3c0ca28c3f7cd52 Mon Sep 17 00:00:00 2001
|
||||
From: Tao Liu <ltao@redhat.com>
|
||||
Date: Sat, 16 Oct 2021 13:21:16 +0800
|
||||
Subject: [PATCH 6/9] symbols: Refactor SYMNAME_HASH_INDEX macro to be a
|
||||
function
|
||||
|
||||
SYMNAME_HASH_INDEX is used as the index of symname hash table. It will
|
||||
be out of range if SYMNAME_HASH_INDEX is negative. This patch avoids
|
||||
the risk by changing the marco into a function, and casting and calculating
|
||||
the numbers as unsigned.
|
||||
|
||||
Suggested-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
Suggested-by: Philipp Rudo <prudo@redhat.com>
|
||||
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||
---
|
||||
defs.h | 2 --
|
||||
symbols.c | 31 +++++++++++++++++++++++--------
|
||||
2 files changed, 23 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/defs.h b/defs.h
|
||||
index bbdca799f72d..8b356d5e8959 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -2728,8 +2728,6 @@ struct downsized {
|
||||
(((vaddr) >> machdep->pageshift) % SYMVAL_HASH)
|
||||
|
||||
#define SYMNAME_HASH (512)
|
||||
-#define SYMNAME_HASH_INDEX(name) \
|
||||
- ((name[0] ^ (name[strlen(name)-1] * name[strlen(name)/2])) % SYMNAME_HASH)
|
||||
|
||||
#define PATCH_KERNEL_SYMBOLS_START ((char *)(1))
|
||||
#define PATCH_KERNEL_SYMBOLS_STOP ((char *)(2))
|
||||
diff --git a/symbols.c b/symbols.c
|
||||
index 5603a2efd61f..67b701454563 100644
|
||||
--- a/symbols.c
|
||||
+++ b/symbols.c
|
||||
@@ -1127,6 +1127,21 @@ symname_hash_init(void)
|
||||
st->__per_cpu_end = sp->value;
|
||||
}
|
||||
|
||||
+static unsigned int
|
||||
+symname_hash_index(char *name)
|
||||
+{
|
||||
+ unsigned int len, value;
|
||||
+ unsigned char *array = (unsigned char *)name;
|
||||
+
|
||||
+ len = strlen(name);
|
||||
+ if (!len)
|
||||
+ error(FATAL, "The length of the symbol name is zero!\n");
|
||||
+
|
||||
+ value = array[len - 1] * array[len / 2];
|
||||
+
|
||||
+ return (array[0] ^ value) % SYMNAME_HASH;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Install a single static kernel symbol into the symname_hash.
|
||||
*/
|
||||
@@ -1134,9 +1149,9 @@ static void
|
||||
symname_hash_install(struct syment *spn)
|
||||
{
|
||||
struct syment *sp;
|
||||
- int index;
|
||||
+ unsigned int index;
|
||||
|
||||
- index = SYMNAME_HASH_INDEX(spn->name);
|
||||
+ index = symname_hash_index(spn->name);
|
||||
spn->cnt = 1;
|
||||
|
||||
if ((sp = st->symname_hash[index]) == NULL)
|
||||
@@ -1164,12 +1179,12 @@ static void
|
||||
mod_symname_hash_install(struct syment *spn)
|
||||
{
|
||||
struct syment *sp;
|
||||
- int index;
|
||||
+ unsigned int index;
|
||||
|
||||
if (!spn)
|
||||
return;
|
||||
|
||||
- index = SYMNAME_HASH_INDEX(spn->name);
|
||||
+ index = symname_hash_index(spn->name);
|
||||
|
||||
sp = st->mod_symname_hash[index];
|
||||
|
||||
@@ -1192,12 +1207,12 @@ static void
|
||||
mod_symname_hash_remove(struct syment *spn)
|
||||
{
|
||||
struct syment *sp;
|
||||
- int index;
|
||||
+ unsigned int index;
|
||||
|
||||
if (!spn)
|
||||
return;
|
||||
|
||||
- index = SYMNAME_HASH_INDEX(spn->name);
|
||||
+ index = symname_hash_index(spn->name);
|
||||
|
||||
if (st->mod_symname_hash[index] == spn) {
|
||||
st->mod_symname_hash[index] = spn->name_hash_next;
|
||||
@@ -1238,7 +1253,7 @@ symname_hash_search(struct syment *table[], char *name)
|
||||
{
|
||||
struct syment *sp;
|
||||
|
||||
- sp = table[SYMNAME_HASH_INDEX(name)];
|
||||
+ sp = table[symname_hash_index(name)];
|
||||
|
||||
while (sp) {
|
||||
if (STREQ(sp->name, name))
|
||||
@@ -4581,7 +4596,7 @@ symbol_search(char *s)
|
||||
return(sp);
|
||||
}
|
||||
|
||||
- sp = st->mod_symname_hash[SYMNAME_HASH_INDEX(s)];
|
||||
+ sp = st->mod_symname_hash[symname_hash_index(s)];
|
||||
while (sp) {
|
||||
if (skip_symbols(sp, s)) {
|
||||
sp = sp->name_hash_next;
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,66 +0,0 @@
|
||||
From 44e5801d9016987b6b4ebd571bfde8ae3e75da7b Mon Sep 17 00:00:00 2001
|
||||
From: Philipp Rudo <prudo@redhat.com>
|
||||
Date: Thu, 5 Aug 2021 15:19:37 +0200
|
||||
Subject: [PATCH 06/27] x86_64: Fix check for __per_cpu_offset initialization
|
||||
|
||||
Since at least kernel v2.6.30 the __per_cpu_offset gets initialized to
|
||||
__per_cpu_load. So first check if the __per_cpu_offset was set to a
|
||||
proper value before reading any per cpu variable to prevent potential
|
||||
bugs.
|
||||
|
||||
[ kh: added check for the existence of __per_cpu_load ]
|
||||
|
||||
Signed-off-by: Philipp Rudo <prudo@redhat.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
x86_64.c | 12 +++++++++++-
|
||||
1 file changed, 11 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/x86_64.c b/x86_64.c
|
||||
index 6eb7d6708db0..87cbeaeb4f06 100644
|
||||
--- a/x86_64.c
|
||||
+++ b/x86_64.c
|
||||
@@ -1285,6 +1285,7 @@ x86_64_per_cpu_init(void)
|
||||
struct machine_specific *ms;
|
||||
struct syment *irq_sp, *curr_sp, *cpu_sp, *hardirq_stack_ptr_sp;
|
||||
ulong hardirq_stack_ptr;
|
||||
+ ulong __per_cpu_load = 0;
|
||||
|
||||
ms = machdep->machspec;
|
||||
|
||||
@@ -1326,7 +1327,12 @@ x86_64_per_cpu_init(void)
|
||||
else if (!ms->stkinfo.isize)
|
||||
ms->stkinfo.isize = 16384;
|
||||
|
||||
+ if (kernel_symbol_exists("__per_cpu_load"))
|
||||
+ __per_cpu_load = symbol_value("__per_cpu_load");
|
||||
+
|
||||
for (i = cpus = 0; i < NR_CPUS; i++) {
|
||||
+ if (__per_cpu_load && kt->__per_cpu_offset[i] == __per_cpu_load)
|
||||
+ break;
|
||||
if (!readmem(cpu_sp->value + kt->__per_cpu_offset[i],
|
||||
KVADDR, &cpunumber, sizeof(int),
|
||||
"cpu number (per_cpu)", QUIET|RETURN_ON_ERROR))
|
||||
@@ -5595,14 +5601,18 @@ x86_64_get_smp_cpus(void)
|
||||
char *cpu_pda_buf;
|
||||
ulong level4_pgt, cpu_pda_addr;
|
||||
struct syment *sp;
|
||||
+ ulong __per_cpu_load = 0;
|
||||
|
||||
if (!VALID_STRUCT(x8664_pda)) {
|
||||
if (!(sp = per_cpu_symbol_search("per_cpu__cpu_number")) ||
|
||||
!(kt->flags & PER_CPU_OFF))
|
||||
return 1;
|
||||
|
||||
+ if (kernel_symbol_exists("__per_cpu_load"))
|
||||
+ __per_cpu_load = symbol_value("__per_cpu_load");
|
||||
+
|
||||
for (i = cpus = 0; i < NR_CPUS; i++) {
|
||||
- if (kt->__per_cpu_offset[i] == 0)
|
||||
+ if (__per_cpu_load && kt->__per_cpu_offset[i] == __per_cpu_load)
|
||||
break;
|
||||
if (!readmem(sp->value + kt->__per_cpu_offset[i],
|
||||
KVADDR, &cpunumber, sizeof(int),
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,67 +0,0 @@
|
||||
From c15a1e025e62134094ba0ac600263d75673d5a22 Mon Sep 17 00:00:00 2001
|
||||
From: Youling Tang <tangyouling@loongson.cn>
|
||||
Date: Fri, 23 Apr 2021 15:42:11 +0800
|
||||
Subject: [PATCH 07/16] MIPS64: three fixes for MIPS64 kernels
|
||||
|
||||
Three fixes for MIPS64 kernels:
|
||||
(1) To support ramdumps, add the machine_type() check for MIPS64 in
|
||||
ramdump_to_elf().
|
||||
(2) To fix a stuck issue when invoking crash with "-d1" or larger
|
||||
debug value, add the machine_type() check to get the correct
|
||||
dump NOTE offsets.
|
||||
(3) Fix the reference file path to the definition of the pt_regs
|
||||
structure, to which mips64_regster refers.
|
||||
|
||||
[ kh: merged three patches into one ]
|
||||
|
||||
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
---
|
||||
defs.h | 2 +-
|
||||
diskdump.c | 2 +-
|
||||
ramdump.c | 2 +-
|
||||
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/defs.h b/defs.h
|
||||
index 3502c6d6e90c..148b03e14455 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -6488,7 +6488,7 @@ void mips64_dump_machdep_table(ulong);
|
||||
#define display_idt_table() \
|
||||
error(FATAL, "-d option is not applicable to MIPS64 architecture\n")
|
||||
|
||||
-/* from arch/mips/include/uapi/asm/ptrace.h */
|
||||
+/* from arch/mips/include/asm/ptrace.h */
|
||||
struct mips64_register {
|
||||
ulong regs[45];
|
||||
};
|
||||
diff --git a/diskdump.c b/diskdump.c
|
||||
index 3effb52771c6..668069585080 100644
|
||||
--- a/diskdump.c
|
||||
+++ b/diskdump.c
|
||||
@@ -1700,7 +1700,7 @@ dump_note_offsets(FILE *fp)
|
||||
qemu = FALSE;
|
||||
if (machine_type("X86_64") || machine_type("S390X") ||
|
||||
machine_type("ARM64") || machine_type("PPC64") ||
|
||||
- machine_type("SPARC64")) {
|
||||
+ machine_type("SPARC64") || machine_type("MIPS64")) {
|
||||
note64 = (void *)dd->notes_buf + tot;
|
||||
len = sizeof(Elf64_Nhdr);
|
||||
if (STRNEQ((char *)note64 + len, "QEMU"))
|
||||
diff --git a/ramdump.c b/ramdump.c
|
||||
index 4c4a920a8281..a206fcbbab3c 100644
|
||||
--- a/ramdump.c
|
||||
+++ b/ramdump.c
|
||||
@@ -184,7 +184,7 @@ char *ramdump_to_elf(void)
|
||||
e_machine = EM_ARM;
|
||||
else if (machine_type("ARM64"))
|
||||
e_machine = EM_AARCH64;
|
||||
- else if (machine_type("MIPS"))
|
||||
+ else if (machine_type("MIPS") || machine_type("MIPS64"))
|
||||
e_machine = EM_MIPS;
|
||||
else if (machine_type("X86_64"))
|
||||
e_machine = EM_X86_64;
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,77 +0,0 @@
|
||||
From 4b34197508578bb43639e6d169fb91fb0489fa2b Mon Sep 17 00:00:00 2001
|
||||
From: James Hsu <james.hsu@mediatek.com>
|
||||
Date: Wed, 18 Aug 2021 15:45:47 +0800
|
||||
Subject: [PATCH 07/27] arm64: Get CPU registers from ELF notes even without
|
||||
crash_notes symbol
|
||||
|
||||
Currently arm64 crash retrieves the CPU registers from crash_notes symbol
|
||||
or ELF notes only when the symbol exists, but there are dumpfiles which
|
||||
have the registers in ELF notes without the symbol.
|
||||
|
||||
With the patch, crash can retrieve the registers from ELF notes without
|
||||
the crash_notes symbol.
|
||||
|
||||
Signed-off-by: James Hsu <james.hsu@mediatek.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
arm64.c | 38 ++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 36 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arm64.c b/arm64.c
|
||||
index d73d5c5a4fed..7069312671cf 100644
|
||||
--- a/arm64.c
|
||||
+++ b/arm64.c
|
||||
@@ -3698,14 +3698,48 @@ arm64_get_crash_notes(void)
|
||||
{
|
||||
struct machine_specific *ms = machdep->machspec;
|
||||
ulong crash_notes;
|
||||
- Elf64_Nhdr *note;
|
||||
+ Elf64_Nhdr *note = NULL;
|
||||
ulong offset;
|
||||
char *buf, *p;
|
||||
ulong *notes_ptrs;
|
||||
ulong i, found;
|
||||
|
||||
- if (!symbol_exists("crash_notes"))
|
||||
+ if (!symbol_exists("crash_notes")) {
|
||||
+ if (DISKDUMP_DUMPFILE() || KDUMP_DUMPFILE()) {
|
||||
+ if (!(ms->panic_task_regs = calloc((size_t)kt->cpus, sizeof(struct arm64_pt_regs))))
|
||||
+ error(FATAL, "cannot calloc panic_task_regs space\n");
|
||||
+
|
||||
+ for (i = found = 0; i < kt->cpus; i++) {
|
||||
+ if (DISKDUMP_DUMPFILE())
|
||||
+ note = diskdump_get_prstatus_percpu(i);
|
||||
+ else if (KDUMP_DUMPFILE())
|
||||
+ note = netdump_get_prstatus_percpu(i);
|
||||
+
|
||||
+ if (!note) {
|
||||
+ error(WARNING, "cpu %d: cannot find NT_PRSTATUS note\n", i);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Find correct location of note data. This contains elf_prstatus
|
||||
+ * structure which has registers etc. for the crashed task.
|
||||
+ */
|
||||
+ offset = sizeof(Elf64_Nhdr);
|
||||
+ offset = roundup(offset + note->n_namesz, 4);
|
||||
+ p = (char *)note + offset; /* start of elf_prstatus */
|
||||
+
|
||||
+ BCOPY(p + OFFSET(elf_prstatus_pr_reg), &ms->panic_task_regs[i],
|
||||
+ sizeof(struct arm64_pt_regs));
|
||||
+
|
||||
+ found++;
|
||||
+ }
|
||||
+ if (!found) {
|
||||
+ free(ms->panic_task_regs);
|
||||
+ ms->panic_task_regs = NULL;
|
||||
+ }
|
||||
+ }
|
||||
return;
|
||||
+ }
|
||||
|
||||
crash_notes = symbol_value("crash_notes");
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,99 +0,0 @@
|
||||
From 5c04a6f3f923af7c50f0d853477044802b3fa6ec Mon Sep 17 00:00:00 2001
|
||||
From: Tao Liu <ltao@redhat.com>
|
||||
Date: Sat, 16 Oct 2021 13:21:17 +0800
|
||||
Subject: [PATCH 7/9] symbols: Add mod_symname_hash table dump to help -s
|
||||
|
||||
Previously, help -s only print out the dump status of symname_hash
|
||||
table. Since we have mod_symname_hash table introduced, let's print
|
||||
out mod_symname_hash in help -s as well.
|
||||
|
||||
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||
---
|
||||
symbols.c | 57 ++++++++++++++++++++++++++++++++++---------------------
|
||||
1 file changed, 35 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/symbols.c b/symbols.c
|
||||
index 67b701454563..73baa953217a 100644
|
||||
--- a/symbols.c
|
||||
+++ b/symbols.c
|
||||
@@ -3219,13 +3219,40 @@ kallsyms_module_function_size(struct syment *sp, struct load_module *lm, ulong *
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+static void
|
||||
+dump_symname_hash_table(struct syment *table[])
|
||||
+{
|
||||
+ int i, cnt, tot;
|
||||
+ struct syment *sp;
|
||||
+
|
||||
+ fprintf(fp, " ");
|
||||
+ for (i = tot = 0; i < SYMNAME_HASH; i++) {
|
||||
+ fprintf(fp, "[%3d]: ", i);
|
||||
+ if ((sp = table[i]) == NULL)
|
||||
+ fprintf(fp, "%3d ", 0);
|
||||
+ else {
|
||||
+ cnt = 1;
|
||||
+ while (sp->name_hash_next) {
|
||||
+ cnt++;
|
||||
+ sp = sp->name_hash_next;
|
||||
+ }
|
||||
+ fprintf(fp, "%3d ", cnt);
|
||||
+ tot += cnt;
|
||||
+ }
|
||||
+ if (i && (((i+1) % 6) == 0))
|
||||
+ fprintf(fp, "\n ");
|
||||
+ }
|
||||
+ if (SYMNAME_HASH % 6)
|
||||
+ fprintf(fp, "\n");
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* "help -s" output
|
||||
*/
|
||||
void
|
||||
dump_symbol_table(void)
|
||||
{
|
||||
- int i, s, cnt, tot;
|
||||
+ int i, s, cnt;
|
||||
struct load_module *lm;
|
||||
struct syment *sp;
|
||||
struct downsized *ds;
|
||||
@@ -3355,28 +3382,14 @@ dump_symbol_table(void)
|
||||
|
||||
fprintf(fp, " symname_hash[%d]: %lx\n", SYMNAME_HASH,
|
||||
(ulong)&st->symname_hash[0]);
|
||||
+ if (CRASHDEBUG(1))
|
||||
+ dump_symname_hash_table(st->symname_hash);
|
||||
+
|
||||
+ fprintf(fp, "mod_symname_hash[%d]: %lx\n", SYMNAME_HASH,
|
||||
+ (ulong)&st->mod_symname_hash[0]);
|
||||
+ if (CRASHDEBUG(1))
|
||||
+ dump_symname_hash_table(st->mod_symname_hash);
|
||||
|
||||
- if (CRASHDEBUG(1)) {
|
||||
- fprintf(fp, " ");
|
||||
- for (i = tot = 0; i < SYMNAME_HASH; i++) {
|
||||
- fprintf(fp, "[%3d]: ", i);
|
||||
- if ((sp = st->symname_hash[i]) == NULL)
|
||||
- fprintf(fp, "%3d ", 0);
|
||||
- else {
|
||||
- cnt = 1;
|
||||
- while (sp->name_hash_next) {
|
||||
- cnt++;
|
||||
- sp = sp->name_hash_next;
|
||||
- }
|
||||
- fprintf(fp, "%3d ", cnt);
|
||||
- tot += cnt;
|
||||
- }
|
||||
- if (i && (((i+1) % 6) == 0))
|
||||
- fprintf(fp, "\n ");
|
||||
- }
|
||||
- if (SYMNAME_HASH % 6)
|
||||
- fprintf(fp, "\n");
|
||||
- }
|
||||
fprintf(fp, " symbol_namespace: ");
|
||||
fprintf(fp, "address: %lx ", (ulong)st->kernel_namespace.address);
|
||||
fprintf(fp, "index: %ld ", st->kernel_namespace.index);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,34 +0,0 @@
|
||||
From 3db5fff2e9d7b8762d1bd46d8d2c47ba4c7e374f Mon Sep 17 00:00:00 2001
|
||||
From: Ritesh Harjani <riteshh@linux.ibm.com>
|
||||
Date: Thu, 26 Aug 2021 02:31:08 +0530
|
||||
Subject: [PATCH 08/27] .gitignore: Add cscope, ctags & compile_commands.json
|
||||
|
||||
Add cscope, ctags & compile_commands.json in .gitignore file.
|
||||
|
||||
Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com>
|
||||
---
|
||||
.gitignore | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index 5b2ba1d34012..b39832fa71df 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -14,3 +14,14 @@ gdb-7.6/
|
||||
extensions/defs.h
|
||||
extensions/*.so
|
||||
extensions/eppic
|
||||
+
|
||||
+# cscope files
|
||||
+cscope.*
|
||||
+ncscope.*
|
||||
+
|
||||
+# ctags files
|
||||
+tags
|
||||
+TAGS
|
||||
+
|
||||
+# Clang's compilation database file
|
||||
+/compile_commands.json
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,66 +0,0 @@
|
||||
From c180a63f2cb370da6097ad97eb07333c07aa988b Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Mon, 25 Oct 2021 16:53:26 +0900
|
||||
Subject: [PATCH 8/9] arm64: Use VA_BITS for page_offset calculation
|
||||
|
||||
Commit 167d37e347fe ("arm64: assign page_offset with VA_BITS kernel
|
||||
configuration value") changed the page_offset calculation from
|
||||
using VA_BITS_ACTUAL to CONFIG_ARM64_VA_BITS. This caused an error
|
||||
for ramdumps without vmcoreinfo like this:
|
||||
|
||||
crash: vmlinux and /var/tmp/ramdump_elf_XUtCMT do not match!
|
||||
|
||||
Set the vmcoreinfo value to VA_BITS if available, and use VA_BITS
|
||||
for page_offset calculation instead.
|
||||
|
||||
Also remove ARM64_FLIP_PAGE_OFFSET_ACTUAL because it's not used
|
||||
actually.
|
||||
|
||||
Reported-by: Ankur Bansal <er.ankurbansal@gmail.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
arm64.c | 5 ++++-
|
||||
defs.h | 4 +---
|
||||
2 files changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/arm64.c b/arm64.c
|
||||
index 7069312671cf..3dcbcc642fda 100644
|
||||
--- a/arm64.c
|
||||
+++ b/arm64.c
|
||||
@@ -404,7 +404,7 @@ arm64_init(int when)
|
||||
fprintf(fp, "CONFIG_ARM64_VA_BITS: %ld\n", ms->CONFIG_ARM64_VA_BITS);
|
||||
fprintf(fp, " VA_BITS_ACTUAL: %ld\n", ms->VA_BITS_ACTUAL);
|
||||
fprintf(fp, "(calculated) VA_BITS: %ld\n", ms->VA_BITS);
|
||||
- fprintf(fp, " PAGE_OFFSET: %lx\n", ARM64_FLIP_PAGE_OFFSET_ACTUAL);
|
||||
+ fprintf(fp, " PAGE_OFFSET: %lx\n", ARM64_FLIP_PAGE_OFFSET);
|
||||
fprintf(fp, " VA_START: %lx\n", ms->VA_START);
|
||||
fprintf(fp, " modules: %lx - %lx\n", ms->modules_vaddr, ms->modules_end);
|
||||
fprintf(fp, " vmalloc: %lx - %lx\n", ms->vmalloc_start_addr, ms->vmalloc_end);
|
||||
@@ -4031,6 +4031,9 @@ arm64_calc_VA_BITS(void)
|
||||
error(FATAL, "cannot determine VA_BITS_ACTUAL\n");
|
||||
}
|
||||
|
||||
+ if (machdep->machspec->CONFIG_ARM64_VA_BITS)
|
||||
+ machdep->machspec->VA_BITS = machdep->machspec->CONFIG_ARM64_VA_BITS;
|
||||
+
|
||||
/*
|
||||
* The mm flip commit is introduced before 52-bits VA, which is before the
|
||||
* commit to export NUMBER(TCR_EL1_T1SZ)
|
||||
diff --git a/defs.h b/defs.h
|
||||
index 8b356d5e8959..971005596506 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -3238,9 +3238,7 @@ typedef signed int s32;
|
||||
#define ARM64_PAGE_OFFSET ((0xffffffffffffffffUL) \
|
||||
<< (machdep->machspec->VA_BITS - 1))
|
||||
/* kernels >= v5.4 the kernel VA space is flipped */
|
||||
-#define ARM64_FLIP_PAGE_OFFSET (-(1UL) << machdep->machspec->CONFIG_ARM64_VA_BITS)
|
||||
-#define ARM64_FLIP_PAGE_OFFSET_ACTUAL ((0xffffffffffffffffUL) \
|
||||
- - ((1UL) << machdep->machspec->VA_BITS_ACTUAL) + 1)
|
||||
+#define ARM64_FLIP_PAGE_OFFSET (-(1UL) << machdep->machspec->VA_BITS)
|
||||
|
||||
#define ARM64_USERSPACE_TOP ((1UL) << machdep->machspec->VA_BITS)
|
||||
#define ARM64_USERSPACE_TOP_ACTUAL ((1UL) << machdep->machspec->VA_BITS_ACTUAL)
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,36 +0,0 @@
|
||||
From e61841a8b86ac551c314f74f4b82daae84f99700 Mon Sep 17 00:00:00 2001
|
||||
From: Luc Chouinard <lucchouina@gmail.com>
|
||||
Date: Wed, 9 Jun 2021 07:59:40 -0400
|
||||
Subject: [PATCH 08/16] extensions/eppic.mk: Enable use of alternate eppic
|
||||
branch
|
||||
|
||||
Made significant changes and fixes to eppic.
|
||||
Using options in the clone command break due to args parsing.
|
||||
Use separate variable for clone options.
|
||||
|
||||
Closes: https://github.com/crash-utility/crash/pull/86
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
---
|
||||
extensions/eppic.mk | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/extensions/eppic.mk b/extensions/eppic.mk
|
||||
index bda69da6706f..b9c046b710ad 100644
|
||||
--- a/extensions/eppic.mk
|
||||
+++ b/extensions/eppic.mk
|
||||
@@ -35,10 +35,10 @@ all:
|
||||
if [ -f "$(GIT)" ]; \
|
||||
then \
|
||||
if [ -n "$(EPPIC_GIT_URL)" ]; then \
|
||||
- git clone "$(EPPIC_GIT_URL)" eppic; \
|
||||
+ git clone $(EPPIC_GIT_OPTIONS) $(EPPIC_GIT_URL) eppic; \
|
||||
else \
|
||||
if ping -c 1 -W 5 github.com >/dev/null ; then \
|
||||
- git clone https://github.com/lucchouina/eppic.git eppic; \
|
||||
+ git clone $(EPPIC_GIT_OPTIONS) https://github.com/lucchouina/eppic.git eppic; \
|
||||
fi; \
|
||||
fi; \
|
||||
else \
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,57 +0,0 @@
|
||||
From 68870c83d299603c07785e3530e33c13045c87ef Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Egorenkov <egorenar@linux.ibm.com>
|
||||
Date: Wed, 13 Oct 2021 10:56:39 +0200
|
||||
Subject: [PATCH 9/9] Handle task_struct cpu member changes for kernels >=
|
||||
5.16-rc1
|
||||
|
||||
Kernel commit bcf9033e5449bdcaa9bed46467a7141a8049dadb
|
||||
("sched: move CPU field back into thread_info if THREAD_INFO_IN_TASK=y")
|
||||
moved the member cpu of task_struct back into thread_info.
|
||||
Without the patch, crash fails with the following error message
|
||||
during session initialization:
|
||||
|
||||
crash: invalid structure member offset: task_struct_cpu
|
||||
FILE: task.c LINE: 2904 FUNCTION: add_context()
|
||||
|
||||
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
task.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/task.c b/task.c
|
||||
index 672b41697e75..bb6a5da8ad33 100644
|
||||
--- a/task.c
|
||||
+++ b/task.c
|
||||
@@ -278,8 +278,10 @@ task_init(void)
|
||||
} else if (VALID_MEMBER(task_struct_stack))
|
||||
MEMBER_OFFSET_INIT(task_struct_thread_info, "task_struct", "stack");
|
||||
|
||||
+ MEMBER_OFFSET_INIT(task_struct_cpu, "task_struct", "cpu");
|
||||
+
|
||||
if (VALID_MEMBER(task_struct_thread_info)) {
|
||||
- if (tt->flags & THREAD_INFO_IN_TASK) {
|
||||
+ if (tt->flags & THREAD_INFO_IN_TASK && VALID_MEMBER(task_struct_cpu)) {
|
||||
MEMBER_OFFSET_INIT(thread_info_flags, "thread_info", "flags");
|
||||
/* (unnecessary) reminders */
|
||||
ASSIGN_OFFSET(thread_info_task) = INVALID_OFFSET;
|
||||
@@ -315,7 +317,6 @@ task_init(void)
|
||||
MEMBER_OFFSET_INIT(task_struct_has_cpu, "task_struct", "has_cpu");
|
||||
MEMBER_OFFSET_INIT(task_struct_cpus_runnable,
|
||||
"task_struct", "cpus_runnable");
|
||||
- MEMBER_OFFSET_INIT(task_struct_cpu, "task_struct", "cpu");
|
||||
MEMBER_OFFSET_INIT(task_struct_active_mm, "task_struct", "active_mm");
|
||||
MEMBER_OFFSET_INIT(task_struct_next_run, "task_struct", "next_run");
|
||||
MEMBER_OFFSET_INIT(task_struct_flags, "task_struct", "flags");
|
||||
@@ -2900,7 +2901,7 @@ add_context(ulong task, char *tp)
|
||||
else
|
||||
tc->thread_info = ULONG(tp + OFFSET(task_struct_thread_info));
|
||||
fill_thread_info(tc->thread_info);
|
||||
- if (tt->flags & THREAD_INFO_IN_TASK)
|
||||
+ if (tt->flags & THREAD_INFO_IN_TASK && VALID_MEMBER(task_struct_cpu))
|
||||
processor_addr = (int *) (tp + OFFSET(task_struct_cpu));
|
||||
else
|
||||
processor_addr = (int *) (tt->thread_info +
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,156 +0,0 @@
|
||||
From f091b5e76d2d6e81b12cd40df7b5863c9e2efed1 Mon Sep 17 00:00:00 2001
|
||||
From: Firo Yang <firo.yang@suse.com>
|
||||
Date: Tue, 25 May 2021 18:17:37 +0800
|
||||
Subject: [PATCH 09/16] list: add -O option for specifying head node offset
|
||||
|
||||
The -O option is very useful to specify the embedded head node's
|
||||
offset which is different to the offset of other nodes embedded,
|
||||
e.g. dentry.d_subdirs (the head node) and dentry.d_child.
|
||||
|
||||
[ kh: did some cosmetic adjustments ]
|
||||
|
||||
Signed-off-by: Firo Yang <firo.yang@suse.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
---
|
||||
defs.h | 1 +
|
||||
help.c | 32 +++++++++++++++++++++++++++++++-
|
||||
tools.c | 32 +++++++++++++++++++++++++++++---
|
||||
3 files changed, 61 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/defs.h b/defs.h
|
||||
index 148b03e14455..42c8074e6ac6 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -2613,6 +2613,7 @@ struct list_data { /* generic structure used by do_list() to walk */
|
||||
#define LIST_PARSE_MEMBER (VERBOSE << 13)
|
||||
#define LIST_READ_MEMBER (VERBOSE << 14)
|
||||
#define LIST_BRENT_ALGO (VERBOSE << 15)
|
||||
+#define LIST_HEAD_OFFSET_ENTERED (VERBOSE << 16)
|
||||
|
||||
struct tree_data {
|
||||
ulong flags;
|
||||
diff --git a/help.c b/help.c
|
||||
index 9649cc81fa36..99be7cb4e17c 100644
|
||||
--- a/help.c
|
||||
+++ b/help.c
|
||||
@@ -5716,7 +5716,7 @@ char *help__list[] = {
|
||||
"list",
|
||||
"linked list",
|
||||
"[[-o] offset][-e end][-[s|S] struct[.member[,member] [-l offset]] -[x|d]]"
|
||||
-"\n [-r|-B] [-h|-H] start",
|
||||
+"\n [-r|-B] [-h [-O head_offset]|-H] start",
|
||||
" ",
|
||||
" This command dumps the contents of a linked list. The entries in a linked",
|
||||
" list are typically data structures that are tied together in one of two",
|
||||
@@ -5800,6 +5800,15 @@ char *help__list[] = {
|
||||
" -S struct Similar to -s, but instead of parsing gdb output, member values",
|
||||
" are read directly from memory, so the command works much faster",
|
||||
" for 1-, 2-, 4-, and 8-byte members.",
|
||||
+" -O offset Only used in conjunction with -h; it specifies the offset of",
|
||||
+" head node list_head embedded within a data structure which is",
|
||||
+" different than the offset of list_head of other nodes embedded",
|
||||
+" within a data structure.",
|
||||
+" The offset may be entered in either of the following manners:",
|
||||
+"",
|
||||
+" 1. in \"structure.member\" format.",
|
||||
+" 2. a number of bytes.",
|
||||
+"",
|
||||
" -l offset Only used in conjunction with -s, if the start address argument",
|
||||
" is a pointer to an embedded list head (or any other similar list",
|
||||
" linkage structure whose first member points to the next linkage",
|
||||
@@ -6116,6 +6125,27 @@ char *help__list[] = {
|
||||
" comm = \"sudo\"",
|
||||
" ffff88005ac10180",
|
||||
" comm = \"crash\"",
|
||||
+"",
|
||||
+" To display a liked list whose head node and other nodes are embedded within",
|
||||
+" either same or different data structures resulting in different offsets for",
|
||||
+" head node and other nodes, e.g. dentry.d_subdirs and dentry.d_child, the",
|
||||
+" -O option can be used:",
|
||||
+"",
|
||||
+" %s> list -o dentry.d_child -s dentry.d_name.name -O dentry.d_subdirs -h ffff9c585b81a180",
|
||||
+" ffff9c585b9cb140",
|
||||
+" d_name.name = 0xffff9c585b9cb178 ccc.txt",
|
||||
+" ffff9c585b9cb980",
|
||||
+" d_name.name = 0xffff9c585b9cb9b8 bbb.txt",
|
||||
+" ffff9c585b9cb740",
|
||||
+" d_name.name = 0xffff9c585b9cb778 aaa.txt",
|
||||
+"",
|
||||
+" The dentry.d_subdirs example above is equal to the following sequence:",
|
||||
+"",
|
||||
+" %s> struct -o dentry.d_subdirs ffff9c585b81a180",
|
||||
+" struct dentry {",
|
||||
+" [ffff9c585b81a220] struct list_head d_subdirs;",
|
||||
+" }",
|
||||
+" %s> list -o dentry.d_child -s dentry.d_name.name -H ffff9c585b81a220",
|
||||
NULL
|
||||
};
|
||||
|
||||
diff --git a/tools.c b/tools.c
|
||||
index a26b101f6481..6fa3c70bac2b 100644
|
||||
--- a/tools.c
|
||||
+++ b/tools.c
|
||||
@@ -3343,6 +3343,7 @@ void
|
||||
cmd_list(void)
|
||||
{
|
||||
int c;
|
||||
+ long head_member_offset = 0; /* offset for head like denty.d_subdirs */
|
||||
struct list_data list_data, *ld;
|
||||
struct datatype_member struct_member, *sm;
|
||||
struct syment *sp;
|
||||
@@ -3353,7 +3354,7 @@ cmd_list(void)
|
||||
BZERO(ld, sizeof(struct list_data));
|
||||
struct_list_offset = 0;
|
||||
|
||||
- while ((c = getopt(argcnt, args, "BHhrs:S:e:o:xdl:")) != EOF) {
|
||||
+ while ((c = getopt(argcnt, args, "BHhrs:S:e:o:O:xdl:")) != EOF) {
|
||||
switch(c)
|
||||
{
|
||||
case 'B':
|
||||
@@ -3394,6 +3395,20 @@ cmd_list(void)
|
||||
optarg);
|
||||
break;
|
||||
|
||||
+ case 'O':
|
||||
+ if (ld->flags & LIST_HEAD_OFFSET_ENTERED)
|
||||
+ error(FATAL, "offset value %d (0x%lx) already entered\n",
|
||||
+ head_member_offset, head_member_offset);
|
||||
+ else if (IS_A_NUMBER(optarg))
|
||||
+ head_member_offset = stol(optarg, FAULT_ON_ERROR, NULL);
|
||||
+ else if (arg_to_datatype(optarg, sm, RETURN_ON_ERROR) > 1)
|
||||
+ head_member_offset = sm->member_offset;
|
||||
+ else
|
||||
+ error(FATAL, "invalid -O argument: %s\n", optarg);
|
||||
+
|
||||
+ ld->flags |= LIST_HEAD_OFFSET_ENTERED;
|
||||
+ break;
|
||||
+
|
||||
case 'o':
|
||||
if (ld->flags & LIST_OFFSET_ENTERED)
|
||||
error(FATAL,
|
||||
@@ -3599,8 +3614,19 @@ next_arg:
|
||||
fprintf(fp, "(empty)\n");
|
||||
return;
|
||||
}
|
||||
- } else
|
||||
- ld->start += ld->list_head_offset;
|
||||
+ } else {
|
||||
+ if (ld->flags & LIST_HEAD_OFFSET_ENTERED) {
|
||||
+ if (!ld->end)
|
||||
+ ld->end = ld->start + head_member_offset;
|
||||
+ readmem(ld->start + head_member_offset, KVADDR, &ld->start,
|
||||
+ sizeof(void *), "LIST_HEAD contents", FAULT_ON_ERROR);
|
||||
+ if (ld->start == ld->end) {
|
||||
+ fprintf(fp, "(empty)\n");
|
||||
+ return;
|
||||
+ }
|
||||
+ } else
|
||||
+ ld->start += ld->list_head_offset;
|
||||
+ }
|
||||
}
|
||||
|
||||
ld->flags &= ~(LIST_OFFSET_ENTERED|LIST_START_ENTERED);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,28 +0,0 @@
|
||||
From 15765867c0f1d937db5ec06f51adb6bfd13354ea Mon Sep 17 00:00:00 2001
|
||||
From: Ritesh Harjani <riteshh@linux.ibm.com>
|
||||
Date: Thu, 26 Aug 2021 02:31:10 +0530
|
||||
Subject: [PATCH 09/27] ppc64: Add MMU type info in machdep command
|
||||
|
||||
This adds MMU type info in "machdep" command.
|
||||
|
||||
Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com>
|
||||
---
|
||||
ppc64.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/ppc64.c b/ppc64.c
|
||||
index f368bf8e1a08..975caa53b812 100644
|
||||
--- a/ppc64.c
|
||||
+++ b/ppc64.c
|
||||
@@ -3027,6 +3027,8 @@ ppc64_display_machine_stats(void)
|
||||
else
|
||||
fprintf(fp, "(unknown)\n");
|
||||
fprintf(fp, " HZ: %d\n", machdep->hz);
|
||||
+ fprintf(fp, " MMU: %s\n", machdep->flags & RADIX_MMU
|
||||
+ ? "RADIX" : "HASH");
|
||||
fprintf(fp, " PAGE SIZE: %d\n", PAGESIZE());
|
||||
// fprintf(fp, " L1 CACHE SIZE: %d\n", l1_cache_size());
|
||||
fprintf(fp, "KERNEL VIRTUAL BASE: %lx\n", machdep->kvbase);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,132 +0,0 @@
|
||||
From eaf14f852ae79f7745934e213661f1c6abac711e Mon Sep 17 00:00:00 2001
|
||||
From: Greg Edwards <gedwards@ddn.com>
|
||||
Date: Wed, 23 Jun 2021 13:50:47 -0600
|
||||
Subject: [PATCH 10/16] Fix 'waitq' command for Linux 4.13 and later kernels
|
||||
|
||||
The wait queue structs and members were renamed in 4.13 in commits:
|
||||
|
||||
ac6424b981bc ("sched/wait: Rename wait_queue_t => wait_queue_entry_t")
|
||||
9d9d676f595b ("sched/wait: Standardize internal naming of wait-queue heads")
|
||||
2055da97389a ("sched/wait: Disambiguate wq_entry->task_list and wq_head->task_list naming")
|
||||
|
||||
Add support to the 'waitq' command for these more recent kernels.
|
||||
|
||||
[ kh: suppressed compilation warnings ]
|
||||
|
||||
Signed-off-by: Greg Edwards <gedwards@ddn.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
---
|
||||
defs.h | 4 ++++
|
||||
kernel.c | 27 +++++++++++++++++++++++----
|
||||
symbols.c | 10 +++++++++-
|
||||
3 files changed, 36 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/defs.h b/defs.h
|
||||
index 42c8074e6ac6..6bb00e29d811 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -2138,6 +2138,9 @@ struct offset_table { /* stash of commonly-used offsets */
|
||||
long atomic_long_t_counter;
|
||||
long block_device_bd_device;
|
||||
long block_device_bd_stats;
|
||||
+ long wait_queue_entry_private;
|
||||
+ long wait_queue_head_head;
|
||||
+ long wait_queue_entry_entry;
|
||||
};
|
||||
|
||||
struct size_table { /* stash of commonly-used sizes */
|
||||
@@ -2300,6 +2303,7 @@ struct size_table { /* stash of commonly-used sizes */
|
||||
long printk_info;
|
||||
long printk_ringbuffer;
|
||||
long prb_desc;
|
||||
+ long wait_queue_entry;
|
||||
};
|
||||
|
||||
struct array_table {
|
||||
diff --git a/kernel.c b/kernel.c
|
||||
index 528f6ee524f6..e123f760e036 100644
|
||||
--- a/kernel.c
|
||||
+++ b/kernel.c
|
||||
@@ -615,7 +615,15 @@ kernel_init()
|
||||
kt->flags |= TVEC_BASES_V1;
|
||||
|
||||
STRUCT_SIZE_INIT(__wait_queue, "__wait_queue");
|
||||
- if (VALID_STRUCT(__wait_queue)) {
|
||||
+ STRUCT_SIZE_INIT(wait_queue_entry, "wait_queue_entry");
|
||||
+ if (VALID_STRUCT(wait_queue_entry)) {
|
||||
+ MEMBER_OFFSET_INIT(wait_queue_entry_private,
|
||||
+ "wait_queue_entry", "private");
|
||||
+ MEMBER_OFFSET_INIT(wait_queue_head_head,
|
||||
+ "wait_queue_head", "head");
|
||||
+ MEMBER_OFFSET_INIT(wait_queue_entry_entry,
|
||||
+ "wait_queue_entry", "entry");
|
||||
+ } else if (VALID_STRUCT(__wait_queue)) {
|
||||
if (MEMBER_EXISTS("__wait_queue", "task"))
|
||||
MEMBER_OFFSET_INIT(__wait_queue_task,
|
||||
"__wait_queue", "task");
|
||||
@@ -9367,9 +9375,9 @@ dump_waitq(ulong wq, char *wq_name)
|
||||
struct list_data list_data, *ld;
|
||||
ulong *wq_list; /* addr of wait queue element */
|
||||
ulong next_offset; /* next pointer of wq element */
|
||||
- ulong task_offset; /* offset of task in wq element */
|
||||
+ ulong task_offset = 0; /* offset of task in wq element */
|
||||
int cnt; /* # elems on Queue */
|
||||
- int start_index; /* where to start in wq array */
|
||||
+ int start_index = -1; /* where to start in wq array */
|
||||
int i;
|
||||
|
||||
ld = &list_data;
|
||||
@@ -9397,9 +9405,20 @@ dump_waitq(ulong wq, char *wq_name)
|
||||
ld->list_head_offset = OFFSET(__wait_queue_task_list);
|
||||
ld->member_offset = next_offset;
|
||||
|
||||
+ start_index = 1;
|
||||
+ } else if (VALID_STRUCT(wait_queue_entry)) {
|
||||
+ ulong head_offset;
|
||||
+
|
||||
+ next_offset = OFFSET(list_head_next);
|
||||
+ task_offset = OFFSET(wait_queue_entry_private);
|
||||
+ head_offset = OFFSET(wait_queue_head_head);
|
||||
+ ld->end = ld->start = wq + head_offset + next_offset;
|
||||
+ ld->list_head_offset = OFFSET(wait_queue_entry_entry);
|
||||
+ ld->member_offset = next_offset;
|
||||
+
|
||||
start_index = 1;
|
||||
} else {
|
||||
- return;
|
||||
+ error(FATAL, "cannot determine wait queue structures\n");
|
||||
}
|
||||
|
||||
hq_open();
|
||||
diff --git a/symbols.c b/symbols.c
|
||||
index 370d4c3e8ac0..67c135f12984 100644
|
||||
--- a/symbols.c
|
||||
+++ b/symbols.c
|
||||
@@ -9817,7 +9817,13 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||
OFFSET(__wait_queue_head_task_list));
|
||||
fprintf(fp, " __wait_queue_task_list: %ld\n",
|
||||
OFFSET(__wait_queue_task_list));
|
||||
-
|
||||
+ fprintf(fp, " wait_queue_entry_private: %ld\n",
|
||||
+ OFFSET(wait_queue_entry_private));
|
||||
+ fprintf(fp, " wait_queue_head_head: %ld\n",
|
||||
+ OFFSET(wait_queue_head_head));
|
||||
+ fprintf(fp, " wait_queue_entry_entry: %ld\n",
|
||||
+ OFFSET(wait_queue_entry_entry));
|
||||
+
|
||||
fprintf(fp, " pglist_data_node_zones: %ld\n",
|
||||
OFFSET(pglist_data_node_zones));
|
||||
fprintf(fp, " pglist_data_node_mem_map: %ld\n",
|
||||
@@ -10717,6 +10723,8 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||
fprintf(fp, " wait_queue: %ld\n", SIZE(wait_queue));
|
||||
fprintf(fp, " __wait_queue: %ld\n",
|
||||
SIZE(__wait_queue));
|
||||
+ fprintf(fp, " wait_queue_entry: %ld\n",
|
||||
+ SIZE(wait_queue_entry));
|
||||
fprintf(fp, " device: %ld\n", SIZE(device));
|
||||
fprintf(fp, " net_device: %ld\n", SIZE(net_device));
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,48 +0,0 @@
|
||||
From cf0c8d10e1870d89b39f40382634db51aa8fcf2c Mon Sep 17 00:00:00 2001
|
||||
From: Hari Bathini <hbathini@linux.ibm.com>
|
||||
Date: Fri, 3 Sep 2021 17:33:42 +0530
|
||||
Subject: [PATCH 10/27] mod: fix module object file lookup
|
||||
|
||||
On systems where vmlinux file is not under /usr/lib/debug/lib/modules
|
||||
directory, 'mod -s|-S' command may fail to find the module's object
|
||||
file with the below error:
|
||||
|
||||
mod: cannot find or load object file for sd_mod module
|
||||
|
||||
Fix it by trying all possible module object file extentions while
|
||||
searching for the object file under /usr/lib/debug/lib/modules
|
||||
directory.
|
||||
|
||||
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.ibm.com>
|
||||
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
|
||||
---
|
||||
kernel.c | 13 ++++++++++++-
|
||||
1 file changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/kernel.c b/kernel.c
|
||||
index 36fdea29b1cb..b2c8a0ccb7ab 100644
|
||||
--- a/kernel.c
|
||||
+++ b/kernel.c
|
||||
@@ -4796,7 +4796,18 @@ module_objfile_search(char *modref, char *filename, char *tree)
|
||||
|
||||
sprintf(dir, "%s/%s", DEFAULT_REDHAT_DEBUG_LOCATION,
|
||||
kt->utsname.release);
|
||||
- retbuf = search_directory_tree(dir, file, 0);
|
||||
+ if (!(retbuf = search_directory_tree(dir, file, 0))) {
|
||||
+ switch (kt->flags & (KMOD_V1|KMOD_V2))
|
||||
+ {
|
||||
+ case KMOD_V2:
|
||||
+ sprintf(file, "%s.ko", modref);
|
||||
+ retbuf = search_directory_tree(dir, file, 0);
|
||||
+ if (!retbuf) {
|
||||
+ sprintf(file, "%s.ko.debug", modref);
|
||||
+ retbuf = search_directory_tree(dir, file, 0);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
|
||||
if (!retbuf && (env = getenv("CRASH_MODULE_PATH"))) {
|
||||
sprintf(dir, "%s", env);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,90 +0,0 @@
|
||||
From 4badc6229c69f5cd9da7eb7bdf400a53ec6db01a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Petr=20Tesa=C5=99=C3=ADk?= <ptesarik@suse.cz>
|
||||
Date: Fri, 25 Jun 2021 17:21:18 +0200
|
||||
Subject: [PATCH 11/16] Fix pvops Xen detection for kernels >= v4.20
|
||||
|
||||
Kernel commit 5c83511bdb9832c86be20fb86b783356e2f58062 removed
|
||||
pv_init_ops, and later commit 054ac8ad5ebe4a69e1f0e842483821ddbe560121
|
||||
removed the Xen-specific paravirt patch function. As a result, pvops Xen
|
||||
dumps are no longer recognized as Xen dumps, and virtual-to-physical
|
||||
translation fails.
|
||||
|
||||
Use the value of xen_start_info to determine whether the kernel is
|
||||
running in Xen PV mode. This pointer is set during the initialization of
|
||||
a PV domain. Kudos to Juergen Gross, who suggested this check.
|
||||
|
||||
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
---
|
||||
kernel.c | 34 ++++++++++++++++++++++++++++------
|
||||
1 file changed, 28 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/kernel.c b/kernel.c
|
||||
index e123f760e036..36fdea29b1cb 100644
|
||||
--- a/kernel.c
|
||||
+++ b/kernel.c
|
||||
@@ -95,6 +95,7 @@ static ulong __dump_audit(char *);
|
||||
static void dump_audit(void);
|
||||
static char *vmcoreinfo_read_string(const char *);
|
||||
static void check_vmcoreinfo(void);
|
||||
+static int is_pvops_xen(void);
|
||||
|
||||
|
||||
/*
|
||||
@@ -109,7 +110,6 @@ kernel_init()
|
||||
char *rqstruct;
|
||||
char *rq_timestamp_name = NULL;
|
||||
char *irq_desc_type_name;
|
||||
- ulong pv_init_ops;
|
||||
struct gnu_request req;
|
||||
|
||||
if (pc->flags & KERNEL_DEBUG_QUERY)
|
||||
@@ -169,11 +169,7 @@ kernel_init()
|
||||
error(FATAL, "cannot malloc m2p page.");
|
||||
}
|
||||
|
||||
- if (PVOPS() && symbol_exists("pv_init_ops") &&
|
||||
- readmem(symbol_value("pv_init_ops"), KVADDR, &pv_init_ops,
|
||||
- sizeof(void *), "pv_init_ops", RETURN_ON_ERROR) &&
|
||||
- ((p1 = value_symbol(pv_init_ops)) &&
|
||||
- (STREQ(p1, "xen_patch") || STREQ(p1, "paravirt_patch_default")))) {
|
||||
+ if (is_pvops_xen()) {
|
||||
kt->flags |= ARCH_XEN | ARCH_PVOPS_XEN;
|
||||
kt->xen_flags |= WRITABLE_PAGE_TABLES;
|
||||
if (machine_type("X86"))
|
||||
@@ -10709,6 +10705,32 @@ paravirt_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
+static int
|
||||
+is_pvops_xen(void)
|
||||
+{
|
||||
+ ulong addr;
|
||||
+ char *sym;
|
||||
+
|
||||
+ if (!PVOPS())
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (symbol_exists("pv_init_ops") &&
|
||||
+ readmem(symbol_value("pv_init_ops"), KVADDR, &addr,
|
||||
+ sizeof(void *), "pv_init_ops", RETURN_ON_ERROR) &&
|
||||
+ (sym = value_symbol(addr)) &&
|
||||
+ (STREQ(sym, "xen_patch") ||
|
||||
+ STREQ(sym, "paravirt_patch_default")))
|
||||
+ return TRUE;
|
||||
+
|
||||
+ if (symbol_exists("xen_start_info") &&
|
||||
+ readmem(symbol_value("xen_start_info"), KVADDR, &addr,
|
||||
+ sizeof(void *), "xen_start_info", RETURN_ON_ERROR) &&
|
||||
+ addr != 0)
|
||||
+ return TRUE;
|
||||
+
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Get the kernel's xtime timespec from its relevant location.
|
||||
*/
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,265 +0,0 @@
|
||||
From 7f38d1baf794823355ee100b3a1914155d4190f2 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Mon, 27 Sep 2021 09:45:42 +0900
|
||||
Subject: [PATCH 11/27] diskdump: Add support for reading dumpfiles compressed
|
||||
by Zstandard
|
||||
|
||||
Add support for reading dumpfiles compressed by Zstandard (zstd)
|
||||
using makedumpfile.
|
||||
|
||||
To build crash with zstd support, type "make zstd".
|
||||
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
Makefile | 4 ++++
|
||||
README | 4 ++--
|
||||
configure.c | 24 +++++++++++++++++++++---
|
||||
defs.h | 4 ++++
|
||||
diskdump.c | 37 +++++++++++++++++++++++++++++++++++++
|
||||
diskdump.h | 1 +
|
||||
help.c | 4 ++--
|
||||
7 files changed, 71 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index ece13069a029..eae023c54bdd 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -333,6 +333,10 @@ snappy: make_configure
|
||||
@./configure -x snappy ${CONF_TARGET_FLAG} -w -b
|
||||
@make --no-print-directory gdb_merge
|
||||
|
||||
+zstd: make_configure
|
||||
+ @./configure -x zstd ${CONF_TARGET_FLAG} -w -b
|
||||
+ @make --no-print-directory gdb_merge
|
||||
+
|
||||
valgrind: make_configure
|
||||
@./configure -x valgrind ${CONF_TARGET_FLAG} -w -b
|
||||
@make --no-print-directory gdb_merge
|
||||
diff --git a/README b/README
|
||||
index 50179742e620..4962f272074b 100644
|
||||
--- a/README
|
||||
+++ b/README
|
||||
@@ -102,8 +102,8 @@
|
||||
Traditionally when vmcores are compressed via the makedumpfile(8) facility
|
||||
the libz compression library is used, and by default the crash utility
|
||||
only supports libz. Recently makedumpfile has been enhanced to optionally
|
||||
- use either the LZO or snappy compression libraries. To build crash with
|
||||
- either or both of those libraries, type "make lzo" or "make snappy".
|
||||
+ use the LZO, snappy or zstd compression libraries. To build crash with any
|
||||
+ or all of those libraries, type "make lzo", "make snappy" or "make zstd".
|
||||
|
||||
crash supports valgrind Memcheck tool on the crash's custom memory allocator.
|
||||
To build crash with this feature enabled, type "make valgrind" and then run
|
||||
diff --git a/configure.c b/configure.c
|
||||
index e8f619a3c061..b691a139b960 100644
|
||||
--- a/configure.c
|
||||
+++ b/configure.c
|
||||
@@ -1738,6 +1738,10 @@ get_extra_flags(char *filename, char *initial)
|
||||
* - enter -DSNAPPY in the CFLAGS.extra file
|
||||
* - enter -lsnappy in the LDFLAGS.extra file
|
||||
*
|
||||
+ * For zstd:
|
||||
+ * - enter -DZSTD in the CFLAGS.extra file
|
||||
+ * - enter -lzstd in the LDFLAGS.extra file
|
||||
+ *
|
||||
* For valgrind:
|
||||
* - enter -DVALGRIND in the CFLAGS.extra file
|
||||
*/
|
||||
@@ -1746,6 +1750,7 @@ add_extra_lib(char *option)
|
||||
{
|
||||
int lzo, add_DLZO, add_llzo2;
|
||||
int snappy, add_DSNAPPY, add_lsnappy;
|
||||
+ int zstd, add_DZSTD, add_lzstd;
|
||||
int valgrind, add_DVALGRIND;
|
||||
char *cflags, *ldflags;
|
||||
FILE *fp_cflags, *fp_ldflags;
|
||||
@@ -1754,6 +1759,7 @@ add_extra_lib(char *option)
|
||||
|
||||
lzo = add_DLZO = add_llzo2 = 0;
|
||||
snappy = add_DSNAPPY = add_lsnappy = 0;
|
||||
+ zstd = add_DZSTD = add_lzstd = 0;
|
||||
valgrind = add_DVALGRIND = 0;
|
||||
|
||||
ldflags = get_extra_flags("LDFLAGS.extra", NULL);
|
||||
@@ -1775,13 +1781,21 @@ add_extra_lib(char *option)
|
||||
add_lsnappy++;
|
||||
}
|
||||
|
||||
+ if (strcmp(option, "zstd") == 0) {
|
||||
+ zstd++;
|
||||
+ if (!cflags || !strstr(cflags, "-DZSTD"))
|
||||
+ add_DZSTD++;
|
||||
+ if (!ldflags || !strstr(ldflags, "-lzstd"))
|
||||
+ add_lzstd++;
|
||||
+ }
|
||||
+
|
||||
if (strcmp(option, "valgrind") == 0) {
|
||||
valgrind++;
|
||||
if (!cflags || !strstr(cflags, "-DVALGRIND"))
|
||||
add_DVALGRIND++;
|
||||
}
|
||||
|
||||
- if ((lzo || snappy) &&
|
||||
+ if ((lzo || snappy || zstd) &&
|
||||
file_exists("diskdump.o") && (unlink("diskdump.o") < 0)) {
|
||||
perror("diskdump.o");
|
||||
return;
|
||||
@@ -1806,24 +1820,28 @@ add_extra_lib(char *option)
|
||||
return;
|
||||
}
|
||||
|
||||
- if (add_DLZO || add_DSNAPPY || add_DVALGRIND) {
|
||||
+ if (add_DLZO || add_DSNAPPY || add_DZSTD || add_DVALGRIND) {
|
||||
while (fgets(inbuf, 512, fp_cflags))
|
||||
;
|
||||
if (add_DLZO)
|
||||
fputs("-DLZO\n", fp_cflags);
|
||||
if (add_DSNAPPY)
|
||||
fputs("-DSNAPPY\n", fp_cflags);
|
||||
+ if (add_DZSTD)
|
||||
+ fputs("-DZSTD\n", fp_cflags);
|
||||
if (add_DVALGRIND)
|
||||
fputs("-DVALGRIND\n", fp_cflags);
|
||||
}
|
||||
|
||||
- if (add_llzo2 || add_lsnappy) {
|
||||
+ if (add_llzo2 || add_lsnappy || add_lzstd) {
|
||||
while (fgets(inbuf, 512, fp_ldflags))
|
||||
;
|
||||
if (add_llzo2)
|
||||
fputs("-llzo2\n", fp_ldflags);
|
||||
if (add_lsnappy)
|
||||
fputs("-lsnappy\n", fp_ldflags);
|
||||
+ if (add_lzstd)
|
||||
+ fputs("-lzstd\n", fp_ldflags);
|
||||
}
|
||||
|
||||
fclose(fp_cflags);
|
||||
diff --git a/defs.h b/defs.h
|
||||
index eb1c71b5333a..b2e94722c92b 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -54,6 +54,9 @@
|
||||
#ifdef SNAPPY
|
||||
#include <snappy-c.h>
|
||||
#endif
|
||||
+#ifdef ZSTD
|
||||
+#include <zstd.h>
|
||||
+#endif
|
||||
|
||||
#ifndef ATTRIBUTE_UNUSED
|
||||
#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
|
||||
@@ -327,6 +330,7 @@ struct number_option {
|
||||
#define NO_ELF_NOTES (0x20)
|
||||
#define LZO_SUPPORTED (0x40)
|
||||
#define SNAPPY_SUPPORTED (0x80)
|
||||
+#define ZSTD_SUPPORTED (0x100)
|
||||
#define DISKDUMP_VALID() (dd->flags & DISKDUMP_LOCAL)
|
||||
#define KDUMP_CMPRS_VALID() (dd->flags & KDUMP_CMPRS_LOCAL)
|
||||
#define KDUMP_SPLIT() (dd->flags & DUMPFILE_SPLIT)
|
||||
diff --git a/diskdump.c b/diskdump.c
|
||||
index de3eeb2c720c..112f769f8949 100644
|
||||
--- a/diskdump.c
|
||||
+++ b/diskdump.c
|
||||
@@ -1001,6 +1001,9 @@ is_diskdump(char *file)
|
||||
#ifdef SNAPPY
|
||||
dd->flags |= SNAPPY_SUPPORTED;
|
||||
#endif
|
||||
+#ifdef ZSTD
|
||||
+ dd->flags |= ZSTD_SUPPORTED;
|
||||
+#endif
|
||||
|
||||
pc->read_vmcoreinfo = vmcoreinfo_read_string;
|
||||
|
||||
@@ -1124,6 +1127,9 @@ cache_page(physaddr_t paddr)
|
||||
const int block_size = dd->block_size;
|
||||
const off_t failed = (off_t)-1;
|
||||
ulong retlen;
|
||||
+#ifdef ZSTD
|
||||
+ static ZSTD_DCtx *dctx = NULL;
|
||||
+#endif
|
||||
|
||||
for (i = found = 0; i < DISKDUMP_CACHED_PAGES; i++) {
|
||||
if (DISKDUMP_VALID_PAGE(dd->page_cache_hdr[i].pg_flags))
|
||||
@@ -1251,6 +1257,33 @@ cache_page(physaddr_t paddr)
|
||||
ret);
|
||||
return READ_ERROR;
|
||||
}
|
||||
+#endif
|
||||
+ } else if (pd.flags & DUMP_DH_COMPRESSED_ZSTD) {
|
||||
+
|
||||
+ if (!(dd->flags & ZSTD_SUPPORTED)) {
|
||||
+ error(INFO, "%s: uncompess failed: no zstd compression support\n",
|
||||
+ DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
|
||||
+ return READ_ERROR;
|
||||
+ }
|
||||
+#ifdef ZSTD
|
||||
+ if (!dctx) {
|
||||
+ dctx = ZSTD_createDCtx();
|
||||
+ if (!dctx) {
|
||||
+ error(INFO, "%s: uncompess failed: cannot create ZSTD_DCtx\n",
|
||||
+ DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
|
||||
+ return READ_ERROR;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ retlen = ZSTD_decompressDCtx(dctx,
|
||||
+ dd->page_cache_hdr[i].pg_bufptr, block_size,
|
||||
+ dd->compressed_page, pd.size);
|
||||
+ if (ZSTD_isError(retlen) || (retlen != block_size)) {
|
||||
+ error(INFO, "%s: uncompress failed: %d (%s)\n",
|
||||
+ DISKDUMP_VALID() ? "diskdump" : "compressed kdump",
|
||||
+ retlen, ZSTD_getErrorName(retlen));
|
||||
+ return READ_ERROR;
|
||||
+ }
|
||||
#endif
|
||||
} else
|
||||
memcpy(dd->page_cache_hdr[i].pg_bufptr,
|
||||
@@ -1806,6 +1839,8 @@ __diskdump_memory_dump(FILE *fp)
|
||||
fprintf(fp, "%sLZO_SUPPORTED", others++ ? "|" : "");
|
||||
if (dd->flags & SNAPPY_SUPPORTED)
|
||||
fprintf(fp, "%sSNAPPY_SUPPORTED", others++ ? "|" : "");
|
||||
+ if (dd->flags & ZSTD_SUPPORTED)
|
||||
+ fprintf(fp, "%sZSTD_SUPPORTED", others++ ? "|" : "");
|
||||
fprintf(fp, ") %s\n", FLAT_FORMAT() ? "[FLAT]" : "");
|
||||
fprintf(fp, " dfd: %d\n", dd->dfd);
|
||||
fprintf(fp, " ofp: %lx\n", (ulong)dd->ofp);
|
||||
@@ -1872,6 +1907,8 @@ __diskdump_memory_dump(FILE *fp)
|
||||
fprintf(fp, "DUMP_DH_COMPRESSED_LZO");
|
||||
if (dh->status & DUMP_DH_COMPRESSED_SNAPPY)
|
||||
fprintf(fp, "DUMP_DH_COMPRESSED_SNAPPY");
|
||||
+ if (dh->status & DUMP_DH_COMPRESSED_ZSTD)
|
||||
+ fprintf(fp, "DUMP_DH_COMPRESSED_ZSTD");
|
||||
if (dh->status & DUMP_DH_COMPRESSED_INCOMPLETE)
|
||||
fprintf(fp, "DUMP_DH_COMPRESSED_INCOMPLETE");
|
||||
if (dh->status & DUMP_DH_EXCLUDED_VMEMMAP)
|
||||
diff --git a/diskdump.h b/diskdump.h
|
||||
index 28713407b841..c152c7b86616 100644
|
||||
--- a/diskdump.h
|
||||
+++ b/diskdump.h
|
||||
@@ -86,6 +86,7 @@ struct kdump_sub_header {
|
||||
#define DUMP_DH_COMPRESSED_SNAPPY 0x4 /* page is compressed with snappy */
|
||||
#define DUMP_DH_COMPRESSED_INCOMPLETE 0x8 /* dumpfile is incomplete */
|
||||
#define DUMP_DH_EXCLUDED_VMEMMAP 0x10 /* unused vmemmap pages are excluded */
|
||||
+#define DUMP_DH_COMPRESSED_ZSTD 0x20 /* page is compressed with zstd */
|
||||
|
||||
/* descriptor of each page for vmcore */
|
||||
typedef struct page_desc {
|
||||
diff --git a/help.c b/help.c
|
||||
index 6c262a3ffcbb..f34838d59908 100644
|
||||
--- a/help.c
|
||||
+++ b/help.c
|
||||
@@ -9420,8 +9420,8 @@ README_ENTER_DIRECTORY,
|
||||
" Traditionally when vmcores are compressed via the makedumpfile(8) facility",
|
||||
" the libz compression library is used, and by default the crash utility",
|
||||
" only supports libz. Recently makedumpfile has been enhanced to optionally",
|
||||
-" use either the LZO or snappy compression libraries. To build crash with",
|
||||
-" either or both of those libraries, type \"make lzo\" or \"make snappy\".",
|
||||
+" use the LZO, snappy or zstd compression libraries. To build crash with any",
|
||||
+" or all of those libraries, type \"make lzo\", \"make snappy\" or \"make zstd\".",
|
||||
"",
|
||||
" crash supports valgrind Memcheck tool on the crash's custom memory allocator.",
|
||||
" To build crash with this feature enabled, type \"make valgrind\" and then run",
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,77 +0,0 @@
|
||||
From d6b4f36d6b22b70fb14e692f36d20910ef5563c1 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Egorenkov <egorenar@linux.ibm.com>
|
||||
Date: Tue, 29 Jun 2021 08:39:00 +0200
|
||||
Subject: [PATCH 12/16] Handle task_struct state member changes for kernels >=
|
||||
5.14-rc1
|
||||
|
||||
Kernel commit 2f064a59a11ff9bc22e52e9678bc601404c7cb34 ("sched: Change
|
||||
task_struct::state") renamed the member state of task_struct to __state
|
||||
and its type changed from long to unsigned int. Without the patch,
|
||||
crash fails to start up with the following error:
|
||||
|
||||
crash: invalid structure member offset: task_struct_state
|
||||
FILE: task.c LINE: 5929 FUNCTION: task_state()
|
||||
|
||||
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
---
|
||||
defs.h | 1 +
|
||||
symbols.c | 1 +
|
||||
task.c | 10 +++++++++-
|
||||
3 files changed, 11 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/defs.h b/defs.h
|
||||
index 6bb00e29d811..5d32954905c2 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -2304,6 +2304,7 @@ struct size_table { /* stash of commonly-used sizes */
|
||||
long printk_ringbuffer;
|
||||
long prb_desc;
|
||||
long wait_queue_entry;
|
||||
+ long task_struct_state;
|
||||
};
|
||||
|
||||
struct array_table {
|
||||
diff --git a/symbols.c b/symbols.c
|
||||
index 67c135f12984..bf6d94db84af 100644
|
||||
--- a/symbols.c
|
||||
+++ b/symbols.c
|
||||
@@ -10678,6 +10678,7 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||
SIZE(page_cache_bucket));
|
||||
fprintf(fp, " pt_regs: %ld\n", SIZE(pt_regs));
|
||||
fprintf(fp, " task_struct: %ld\n", SIZE(task_struct));
|
||||
+ fprintf(fp, " task_struct_state: %ld\n", SIZE(task_struct_state));
|
||||
fprintf(fp, " task_struct_flags: %ld\n", SIZE(task_struct_flags));
|
||||
fprintf(fp, " task_struct_policy: %ld\n", SIZE(task_struct_policy));
|
||||
fprintf(fp, " thread_info: %ld\n", SIZE(thread_info));
|
||||
diff --git a/task.c b/task.c
|
||||
index 36cf259e5d7b..672b41697e75 100644
|
||||
--- a/task.c
|
||||
+++ b/task.c
|
||||
@@ -297,6 +297,11 @@ task_init(void)
|
||||
}
|
||||
|
||||
MEMBER_OFFSET_INIT(task_struct_state, "task_struct", "state");
|
||||
+ MEMBER_SIZE_INIT(task_struct_state, "task_struct", "state");
|
||||
+ if (INVALID_MEMBER(task_struct_state)) {
|
||||
+ MEMBER_OFFSET_INIT(task_struct_state, "task_struct", "__state");
|
||||
+ MEMBER_SIZE_INIT(task_struct_state, "task_struct", "__state");
|
||||
+ }
|
||||
MEMBER_OFFSET_INIT(task_struct_exit_state, "task_struct", "exit_state");
|
||||
MEMBER_OFFSET_INIT(task_struct_pid, "task_struct", "pid");
|
||||
MEMBER_OFFSET_INIT(task_struct_comm, "task_struct", "comm");
|
||||
@@ -5926,7 +5931,10 @@ task_state(ulong task)
|
||||
if (!tt->last_task_read)
|
||||
return 0;
|
||||
|
||||
- state = ULONG(tt->task_struct + OFFSET(task_struct_state));
|
||||
+ if (SIZE(task_struct_state) == sizeof(ulong))
|
||||
+ state = ULONG(tt->task_struct + OFFSET(task_struct_state));
|
||||
+ else
|
||||
+ state = UINT(tt->task_struct + OFFSET(task_struct_state));
|
||||
exit_state = VALID_MEMBER(task_struct_exit_state) ?
|
||||
ULONG(tt->task_struct + OFFSET(task_struct_exit_state)) : 0;
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,62 +0,0 @@
|
||||
From 5719afc7a40868418405a87a2711088556e68a3b Mon Sep 17 00:00:00 2001
|
||||
From: Pingfan Liu <piliu@redhat.com>
|
||||
Date: Fri, 2 Jul 2021 10:14:21 +0800
|
||||
Subject: [PATCH 13/16] arm64: rename ARM64_PAGE_OFFSET_ACTUAL to
|
||||
ARM64_FLIP_PAGE_OFFSET_ACTUAL
|
||||
|
||||
Reflect the flipped layout of kernel VA, which is introduced by
|
||||
kernel commit 14c127c957c1 ("arm64: mm: Flip kernel VA space").
|
||||
|
||||
Signed-off-by: Pingfan Liu <piliu@redhat.com>
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
---
|
||||
arm64.c | 10 ++++++----
|
||||
defs.h | 3 ++-
|
||||
2 files changed, 8 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/arm64.c b/arm64.c
|
||||
index 8934961b109d..9fe1a4a3bddb 100644
|
||||
--- a/arm64.c
|
||||
+++ b/arm64.c
|
||||
@@ -217,10 +217,12 @@ arm64_init(int when)
|
||||
arm64_calc_VA_BITS();
|
||||
arm64_calc_KERNELPACMASK();
|
||||
ms = machdep->machspec;
|
||||
+
|
||||
+ /* vabits_actual introduced after mm flip, so it should be flipped layout */
|
||||
if (ms->VA_BITS_ACTUAL) {
|
||||
- ms->page_offset = ARM64_PAGE_OFFSET_ACTUAL;
|
||||
- machdep->identity_map_base = ARM64_PAGE_OFFSET_ACTUAL;
|
||||
- machdep->kvbase = ARM64_PAGE_OFFSET_ACTUAL;
|
||||
+ ms->page_offset = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
|
||||
+ machdep->identity_map_base = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
|
||||
+ machdep->kvbase = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
|
||||
ms->userspace_top = ARM64_USERSPACE_TOP_ACTUAL;
|
||||
} else {
|
||||
ms->page_offset = ARM64_PAGE_OFFSET;
|
||||
@@ -401,7 +403,7 @@ arm64_init(int when)
|
||||
fprintf(fp, "CONFIG_ARM64_VA_BITS: %ld\n", ms->CONFIG_ARM64_VA_BITS);
|
||||
fprintf(fp, " VA_BITS_ACTUAL: %ld\n", ms->VA_BITS_ACTUAL);
|
||||
fprintf(fp, "(calculated) VA_BITS: %ld\n", ms->VA_BITS);
|
||||
- fprintf(fp, " PAGE_OFFSET: %lx\n", ARM64_PAGE_OFFSET_ACTUAL);
|
||||
+ fprintf(fp, " PAGE_OFFSET: %lx\n", ARM64_FLIP_PAGE_OFFSET_ACTUAL);
|
||||
fprintf(fp, " VA_START: %lx\n", ms->VA_START);
|
||||
fprintf(fp, " modules: %lx - %lx\n", ms->modules_vaddr, ms->modules_end);
|
||||
fprintf(fp, " vmalloc: %lx - %lx\n", ms->vmalloc_start_addr, ms->vmalloc_end);
|
||||
diff --git a/defs.h b/defs.h
|
||||
index 5d32954905c2..eb7ce6aea331 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -3233,7 +3233,8 @@ typedef signed int s32;
|
||||
|
||||
#define ARM64_PAGE_OFFSET ((0xffffffffffffffffUL) \
|
||||
<< (machdep->machspec->VA_BITS - 1))
|
||||
-#define ARM64_PAGE_OFFSET_ACTUAL ((0xffffffffffffffffUL) \
|
||||
+/* kernels >= v5.4 the kernel VA space is flipped */
|
||||
+#define ARM64_FLIP_PAGE_OFFSET_ACTUAL ((0xffffffffffffffffUL) \
|
||||
- ((1UL) << machdep->machspec->VA_BITS_ACTUAL) + 1)
|
||||
|
||||
#define ARM64_USERSPACE_TOP ((1UL) << machdep->machspec->VA_BITS)
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,120 +0,0 @@
|
||||
From 163abcbbabdf8207c11ee93b1c909d85ecbcbf1f Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Date: Fri, 19 Mar 2021 21:07:26 -0700
|
||||
Subject: [PATCH 13/27] crash_get_nr_cpus: get nr_cpus from the dumps
|
||||
|
||||
Most of the dumps have information about real number of CPUS.
|
||||
Use that to instantiate GDB's target inferior threads.
|
||||
|
||||
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
|
||||
---
|
||||
diskdump.c | 13 +++++++++++--
|
||||
gdb_interface.c | 9 +++++++++
|
||||
netdump.c | 11 ++++++++---
|
||||
sadump.c | 2 +-
|
||||
4 files changed, 29 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/diskdump.c b/diskdump.c
|
||||
index 112f769f8949..3e1cfd548c96 100644
|
||||
--- a/diskdump.c
|
||||
+++ b/diskdump.c
|
||||
@@ -2593,13 +2593,22 @@ diskdump_kaslr_check()
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
-#ifdef X86_64
|
||||
int
|
||||
diskdump_get_nr_cpus(void)
|
||||
{
|
||||
- return dd->num_qemu_notes;
|
||||
+ if (dd->num_prstatus_notes)
|
||||
+ return dd->num_prstatus_notes;
|
||||
+ else if (dd->num_qemu_notes)
|
||||
+ return dd->num_qemu_notes;
|
||||
+ else if (dd->num_vmcoredd_notes)
|
||||
+ return dd->num_vmcoredd_notes;
|
||||
+ else if (dd->header->nr_cpus)
|
||||
+ return dd->header->nr_cpus;
|
||||
+
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
+#ifdef X86_64
|
||||
QEMUCPUState *
|
||||
diskdump_get_qemucpustate(int cpu)
|
||||
{
|
||||
diff --git a/gdb_interface.c b/gdb_interface.c
|
||||
index 93fc8baef2c6..bcca080eb8b4 100644
|
||||
--- a/gdb_interface.c
|
||||
+++ b/gdb_interface.c
|
||||
@@ -1070,6 +1070,15 @@ int crash_get_nr_cpus(void);
|
||||
|
||||
int crash_get_nr_cpus(void)
|
||||
{
|
||||
+ if (SADUMP_DUMPFILE())
|
||||
+ return sadump_get_nr_cpus();
|
||||
+ else if (DISKDUMP_DUMPFILE())
|
||||
+ return diskdump_get_nr_cpus();
|
||||
+ else if (KDUMP_DUMPFILE())
|
||||
+ return kdump_get_nr_cpus();
|
||||
+ else if (VMSS_DUMPFILE())
|
||||
+ return vmware_vmss_get_nr_cpus();
|
||||
+
|
||||
/* Just CPU #0 */
|
||||
return 1;
|
||||
}
|
||||
diff --git a/netdump.c b/netdump.c
|
||||
index e8721d89f1a3..ff273b4fdfab 100644
|
||||
--- a/netdump.c
|
||||
+++ b/netdump.c
|
||||
@@ -5206,11 +5206,17 @@ kdump_kaslr_check(void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
-#ifdef X86_64
|
||||
int
|
||||
kdump_get_nr_cpus(void)
|
||||
{
|
||||
- return nd->num_qemu_notes;
|
||||
+ if (nd->num_prstatus_notes)
|
||||
+ return nd->num_prstatus_notes;
|
||||
+ else if (nd->num_qemu_notes)
|
||||
+ return nd->num_qemu_notes;
|
||||
+ else if (nd->num_vmcoredd_notes)
|
||||
+ return nd->num_vmcoredd_notes;
|
||||
+
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
QEMUCPUState *
|
||||
@@ -5232,7 +5238,6 @@ kdump_get_qemucpustate(int cpu)
|
||||
|
||||
return (QEMUCPUState *)nd->nt_qemu_percpu[cpu];
|
||||
}
|
||||
-#endif
|
||||
|
||||
static void *
|
||||
get_kdump_device_dump_offset(void)
|
||||
diff --git a/sadump.c b/sadump.c
|
||||
index d75c66b74be9..cb43fdb8ecab 100644
|
||||
--- a/sadump.c
|
||||
+++ b/sadump.c
|
||||
@@ -1670,7 +1670,6 @@ get_sadump_data(void)
|
||||
return sd;
|
||||
}
|
||||
|
||||
-#ifdef X86_64
|
||||
int
|
||||
sadump_get_nr_cpus(void)
|
||||
{
|
||||
@@ -1678,6 +1677,7 @@ sadump_get_nr_cpus(void)
|
||||
return sd->dump_header->nr_cpus;
|
||||
}
|
||||
|
||||
+#ifdef X86_64
|
||||
int
|
||||
sadump_get_cr3_cr4_idtr(int cpu, ulong *cr3, ulong *cr4, ulong *idtr)
|
||||
{
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,57 +0,0 @@
|
||||
From 167d37e347fe35c6f7db826e8539e192c4375564 Mon Sep 17 00:00:00 2001
|
||||
From: Pingfan Liu <piliu@redhat.com>
|
||||
Date: Fri, 2 Jul 2021 10:14:22 +0800
|
||||
Subject: [PATCH 14/16] arm64: assign page_offset with VA_BITS kernel
|
||||
configuration value
|
||||
|
||||
On RHEL9, crash hits a bug when executing "crash /proc/kcore":
|
||||
seek error: kernel virtual address: ffff6a0f3fff0000 type: "pmd page"
|
||||
|
||||
The kernel virtual address does not vary with vabits_actual, instead,
|
||||
is determined by configuration value. But crash does not observe this
|
||||
fact.
|
||||
|
||||
Since vabits_actual related kernel commit is introduced after arm64
|
||||
mm layout flip commit, so changes are safe under the condition if
|
||||
(ms->VA_BITS_ACTUAL), and keep the else branch untouched.
|
||||
|
||||
Signed-off-by: Pingfan Liu <piliu@redhat.com>
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
---
|
||||
arm64.c | 7 ++++---
|
||||
defs.h | 1 +
|
||||
2 files changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/arm64.c b/arm64.c
|
||||
index 9fe1a4a3bddb..149db36cd119 100644
|
||||
--- a/arm64.c
|
||||
+++ b/arm64.c
|
||||
@@ -220,9 +220,10 @@ arm64_init(int when)
|
||||
|
||||
/* vabits_actual introduced after mm flip, so it should be flipped layout */
|
||||
if (ms->VA_BITS_ACTUAL) {
|
||||
- ms->page_offset = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
|
||||
- machdep->identity_map_base = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
|
||||
- machdep->kvbase = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
|
||||
+ ms->page_offset = ARM64_FLIP_PAGE_OFFSET;
|
||||
+ /* useless on arm64 */
|
||||
+ machdep->identity_map_base = ARM64_FLIP_PAGE_OFFSET;
|
||||
+ machdep->kvbase = ARM64_FLIP_PAGE_OFFSET;
|
||||
ms->userspace_top = ARM64_USERSPACE_TOP_ACTUAL;
|
||||
} else {
|
||||
ms->page_offset = ARM64_PAGE_OFFSET;
|
||||
diff --git a/defs.h b/defs.h
|
||||
index eb7ce6aea331..b7b20af4bcf9 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -3234,6 +3234,7 @@ typedef signed int s32;
|
||||
#define ARM64_PAGE_OFFSET ((0xffffffffffffffffUL) \
|
||||
<< (machdep->machspec->VA_BITS - 1))
|
||||
/* kernels >= v5.4 the kernel VA space is flipped */
|
||||
+#define ARM64_FLIP_PAGE_OFFSET (-(1UL) << machdep->machspec->CONFIG_ARM64_VA_BITS)
|
||||
#define ARM64_FLIP_PAGE_OFFSET_ACTUAL ((0xffffffffffffffffUL) \
|
||||
- ((1UL) << machdep->machspec->VA_BITS_ACTUAL) + 1)
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,45 +0,0 @@
|
||||
From 36e9d8673e9205f4ea4daad61c199597920c93df Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Date: Fri, 19 Mar 2021 21:07:27 -0700
|
||||
Subject: [PATCH 14/27] "whatis -m": fix duplications in the output
|
||||
|
||||
"whatis -m" output started to generate duplicated results after GDB update:
|
||||
|
||||
crash> whatis -m mm_struct
|
||||
SIZE TYPE
|
||||
16 tlb_state
|
||||
...
|
||||
256 linux_binprm
|
||||
2752 rq
|
||||
2752 rq <<-- duplicated
|
||||
2752 rq
|
||||
2752 rq
|
||||
2752 rq
|
||||
4048 task_struct
|
||||
|
||||
It was caused by incorrect string comparisons.
|
||||
Use strcmp for full string comparison instead of just string pointers
|
||||
comparison.
|
||||
|
||||
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Reported-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
symbols.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/symbols.c b/symbols.c
|
||||
index 7ffac2ee8b49..338af2ce5038 100644
|
||||
--- a/symbols.c
|
||||
+++ b/symbols.c
|
||||
@@ -7000,7 +7000,7 @@ append_struct_symbol (struct gnu_request *req, void *data)
|
||||
struct type_request *treq = (struct type_request *)data;
|
||||
|
||||
for (i = 0; i < treq->idx; i++)
|
||||
- if (treq->types[i].name == req->name)
|
||||
+ if (!strcmp(treq->types[i].name, req->name))
|
||||
break;
|
||||
|
||||
if (i < treq->idx) // We've already collected this type
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,80 +0,0 @@
|
||||
From 0b85218983ffcf939a638f1133871079c5615a46 Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Date: Fri, 19 Mar 2021 21:07:30 -0700
|
||||
Subject: [PATCH 15/27] Fix reduced output of `bt` command
|
||||
|
||||
gdb-10 produces reduced output of `bt` command.
|
||||
|
||||
Changed disassembler output is the reason of missing frames
|
||||
in backtrace. Call instruction mnemonic for x86_64 was changed
|
||||
from "callq" to "call" in gdb-10.
|
||||
|
||||
Fixing the issue by adding a search for "call" word in disassembler
|
||||
parser.
|
||||
|
||||
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Reported-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
x86_64.c | 14 ++++++++++----
|
||||
1 file changed, 10 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/x86_64.c b/x86_64.c
|
||||
index 21756f6cf7ab..4f34afac06f9 100644
|
||||
--- a/x86_64.c
|
||||
+++ b/x86_64.c
|
||||
@@ -4415,7 +4415,7 @@ x86_64_function_called_by(ulong rip)
|
||||
if (gdb_pass_through(buf, pc->tmpfile2, GNU_RETURN_ON_ERROR)) {
|
||||
rewind(pc->tmpfile2);
|
||||
while (fgets(buf, BUFSIZE, pc->tmpfile2)) {
|
||||
- if ((p1 = strstr(buf, "callq")) &&
|
||||
+ if ((p1 = strstr(buf, "call")) &&
|
||||
whitespace(*(p1-1))) {
|
||||
if (extract_hex(p1, &value, NULLCHAR, TRUE))
|
||||
break;
|
||||
@@ -6381,11 +6381,13 @@ search_for_switch_to(ulong start, ulong end)
|
||||
char search_string1[BUFSIZE];
|
||||
char search_string2[BUFSIZE];
|
||||
char search_string3[BUFSIZE];
|
||||
+ char search_string4[BUFSIZE];
|
||||
int found;
|
||||
|
||||
max_instructions = end - start;
|
||||
found = FALSE;
|
||||
- search_string1[0] = search_string2[0] = search_string3[0] = NULLCHAR;
|
||||
+ search_string1[0] = search_string2[0] = NULLCHAR;
|
||||
+ search_string3[0] = search_string4[0] = NULLCHAR;
|
||||
sprintf(buf1, "x/%ldi 0x%lx", max_instructions, start);
|
||||
|
||||
if (symbol_exists("__switch_to")) {
|
||||
@@ -6396,7 +6398,9 @@ search_for_switch_to(ulong start, ulong end)
|
||||
}
|
||||
if (symbol_exists("__switch_to_asm")) {
|
||||
sprintf(search_string3,
|
||||
- "callq 0x%lx", symbol_value("__switch_to_asm"));
|
||||
+ "callq 0x%lx", symbol_value("__switch_to_asm"));
|
||||
+ sprintf(search_string4,
|
||||
+ "call 0x%lx", symbol_value("__switch_to_asm"));
|
||||
}
|
||||
|
||||
open_tmpfile();
|
||||
@@ -6416,6 +6420,8 @@ search_for_switch_to(ulong start, ulong end)
|
||||
found = TRUE;
|
||||
if (strlen(search_string3) && strstr(buf1, search_string3))
|
||||
found = TRUE;
|
||||
+ if (strlen(search_string4) && strstr(buf1, search_string4))
|
||||
+ found = TRUE;
|
||||
}
|
||||
close_tmpfile();
|
||||
|
||||
@@ -8230,7 +8236,7 @@ x86_64_do_not_cache_framesize(struct syment *sp, ulong textaddr)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
- if (STREQ(arglist[instr], "callq"))
|
||||
+ if (STREQ(arglist[instr], "callq") || STREQ(arglist[instr], "call"))
|
||||
break;
|
||||
}
|
||||
close_tmpfile2();
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,84 +0,0 @@
|
||||
From bf1379a8b6ff8d6a8fa12978f7194f15f85c4380 Mon Sep 17 00:00:00 2001
|
||||
From: Pingfan Liu <piliu@redhat.com>
|
||||
Date: Fri, 2 Jul 2021 10:14:23 +0800
|
||||
Subject: [PATCH 15/16] arm64: use dedicated bits to record the VA space layout
|
||||
changes
|
||||
|
||||
arm64 memory layout experiences big changes due to the following kernel
|
||||
commits in date descending order:
|
||||
5. 7bc1a0f9e176 arm64: mm: use single quantity to represent the PA to VA translation
|
||||
4. b6d00d47e81a arm64: mm: Introduce 52-bit Kernel VAs
|
||||
3. 5383cc6efed1 arm64: mm: Introduce vabits_actual
|
||||
2. 14c127c957c1 arm64: mm: Flip kernel VA space
|
||||
1. f80fb3a3d508 arm64: add support for kernel ASLR
|
||||
|
||||
For 1, crash has already used NEW_VMEMMAP to trace it.
|
||||
For 2, crash lacks a flag to tag it and handle it differently.
|
||||
For 3, two important kernel variables vabits_actual and physvirt_offset
|
||||
are introduced.
|
||||
For 4, since it comes immediately after 3, crash-utility does not need
|
||||
to distinguish it.
|
||||
For 5, kernel variable phyvirt_offset is removed
|
||||
|
||||
These changes have effects on PTOV()/VTOP() formula. So introducing
|
||||
two bits HAS_PHYSVIRT_OFFSET and FLIPPED_VM as hint to apply different
|
||||
formula.
|
||||
|
||||
Signed-off-by: Pingfan Liu <piliu@redhat.com>
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
---
|
||||
arm64.c | 10 ++++++++++
|
||||
defs.h | 2 ++
|
||||
2 files changed, 12 insertions(+)
|
||||
|
||||
diff --git a/arm64.c b/arm64.c
|
||||
index 149db36cd119..b04369f6d4d8 100644
|
||||
--- a/arm64.c
|
||||
+++ b/arm64.c
|
||||
@@ -563,6 +563,10 @@ arm64_dump_machdep_table(ulong arg)
|
||||
fprintf(fp, "%sMACHDEP_BT_TEXT", others++ ? "|" : "");
|
||||
if (machdep->flags & NEW_VMEMMAP)
|
||||
fprintf(fp, "%sNEW_VMEMMAP", others++ ? "|" : "");
|
||||
+ if (machdep->flags & FLIPPED_VM)
|
||||
+ fprintf(fp, "%sFLIPPED_VM", others++ ? "|" : "");
|
||||
+ if (machdep->flags & HAS_PHYSVIRT_OFFSET)
|
||||
+ fprintf(fp, "%sHAS_PHYSVIRT_OFFSET", others++ ? "|" : "");
|
||||
fprintf(fp, ")\n");
|
||||
|
||||
fprintf(fp, " kvbase: %lx\n", machdep->kvbase);
|
||||
@@ -997,6 +1001,7 @@ arm64_calc_physvirt_offset(void)
|
||||
if (READMEM(pc->mfd, &physvirt_offset, sizeof(physvirt_offset),
|
||||
sp->value, sp->value -
|
||||
machdep->machspec->kimage_voffset) > 0) {
|
||||
+ machdep->flags |= HAS_PHYSVIRT_OFFSET;
|
||||
ms->physvirt_offset = physvirt_offset;
|
||||
}
|
||||
}
|
||||
@@ -3963,6 +3968,11 @@ arm64_calc_VA_BITS(void)
|
||||
error(FATAL, "cannot determine VA_BITS_ACTUAL\n");
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * The mm flip commit is introduced before 52-bits VA, which is before the
|
||||
+ * commit to export NUMBER(TCR_EL1_T1SZ)
|
||||
+ */
|
||||
+ machdep->flags |= FLIPPED_VM;
|
||||
return;
|
||||
}
|
||||
|
||||
diff --git a/defs.h b/defs.h
|
||||
index b7b20af4bcf9..eca145cb881c 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -3214,6 +3214,8 @@ typedef signed int s32;
|
||||
#define NEW_VMEMMAP (0x80)
|
||||
#define VM_L4_4K (0x100)
|
||||
#define UNW_4_14 (0x200)
|
||||
+#define FLIPPED_VM (0x400)
|
||||
+#define HAS_PHYSVIRT_OFFSET (0x800)
|
||||
|
||||
/*
|
||||
* Get kimage_voffset from /dev/crash
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,166 +0,0 @@
|
||||
From f53b73e8380bca054cebd2b61ff118c46609429b Mon Sep 17 00:00:00 2001
|
||||
From: Pingfan Liu <piliu@redhat.com>
|
||||
Date: Fri, 2 Jul 2021 10:14:24 +0800
|
||||
Subject: [PATCH 16/16] arm64: implement switchable PTOV()/VTOP() for kernels
|
||||
>= 5.10
|
||||
|
||||
Crash encounters a bug like the following:
|
||||
...
|
||||
SECTION_SIZE_BITS: 30
|
||||
CONFIG_ARM64_VA_BITS: 52
|
||||
VA_BITS_ACTUAL: 48
|
||||
(calculated) VA_BITS: 48
|
||||
PAGE_OFFSET: ffff000000000000
|
||||
VA_START: ffff800000000000
|
||||
modules: ffff800008000000 - ffff80000fffffff
|
||||
vmalloc: ffff800010000000 - ffffffdfdffeffff
|
||||
kernel image: ffff800010000000 - ffff800012750000
|
||||
vmemmap: ffffffdfffe00000 - ffffffffffffffff
|
||||
|
||||
<readmem: ffff800011c53bc8, KVADDR, "nr_irqs", 4, (FOE), b47bdc>
|
||||
<read_kdump: addr: ffff800011c53bc8 paddr: eb453bc8 cnt: 4>
|
||||
read_netdump: addr: ffff800011c53bc8 paddr: eb453bc8 cnt: 4 offset: 1c73bc8
|
||||
irq_stack_ptr:
|
||||
type: 1, TYPE_CODE_PTR
|
||||
target_typecode: 8, TYPE_CODE_INT
|
||||
target_length: 8
|
||||
length: 8
|
||||
GNU_GET_DATATYPE[thread_union]: returned via gdb_error_hook
|
||||
<readmem: ffff000b779c0050, KVADDR, "IRQ stack pointer", 8, (ROE), 3a37bea0>
|
||||
<read_kdump: addr: ffff000b779c0050 paddr: fff1000bf79c0050 cnt: 8>
|
||||
read_netdump: READ_ERROR: offset not found for paddr: fff1000bf79c0050
|
||||
crash: read error: kernel virtual address: ffff000b779c0050 type: "IRQ stack pointer"
|
||||
...
|
||||
|
||||
Apparently, for a normal system, the 'paddr: fff1000bf79c0050' is
|
||||
unreasonable.
|
||||
|
||||
This bug connects with kernel commit 7bc1a0f9e176 ("arm64: mm: use
|
||||
single quantity to represent the PA to VA translation"), which removed
|
||||
physvirt_offset kernel variable and changed the PTOV()/VTOP() formulas.
|
||||
|
||||
Implement switchable PTOV()/VTOP() to cope with different kernel
|
||||
version.
|
||||
|
||||
Signed-off-by: Pingfan Liu <piliu@redhat.com>
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
---
|
||||
arm64.c | 37 +++++++++++++++++++++++++++++++++----
|
||||
defs.h | 9 ++++-----
|
||||
2 files changed, 37 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/arm64.c b/arm64.c
|
||||
index b04369f6d4d8..d73d5c5a4fed 100644
|
||||
--- a/arm64.c
|
||||
+++ b/arm64.c
|
||||
@@ -994,8 +994,6 @@ arm64_calc_physvirt_offset(void)
|
||||
ulong physvirt_offset;
|
||||
struct syment *sp;
|
||||
|
||||
- ms->physvirt_offset = ms->phys_offset - ms->page_offset;
|
||||
-
|
||||
if ((sp = kernel_symbol_search("physvirt_offset")) &&
|
||||
machdep->machspec->kimage_voffset) {
|
||||
if (READMEM(pc->mfd, &physvirt_offset, sizeof(physvirt_offset),
|
||||
@@ -1003,8 +1001,13 @@ arm64_calc_physvirt_offset(void)
|
||||
machdep->machspec->kimage_voffset) > 0) {
|
||||
machdep->flags |= HAS_PHYSVIRT_OFFSET;
|
||||
ms->physvirt_offset = physvirt_offset;
|
||||
+ return;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ /* Useless if no symbol 'physvirt_offset', just keep semantics */
|
||||
+ ms->physvirt_offset = ms->phys_offset - ms->page_offset;
|
||||
+
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1051,6 +1054,7 @@ arm64_calc_phys_offset(void)
|
||||
if (READMEM(pc->mfd, &phys_offset, sizeof(phys_offset),
|
||||
vaddr, paddr) > 0) {
|
||||
ms->phys_offset = phys_offset;
|
||||
+
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1178,6 +1182,21 @@ arm64_init_kernel_pgd(void)
|
||||
vt->kernel_pgd[i] = value;
|
||||
}
|
||||
|
||||
+ulong arm64_PTOV(ulong paddr)
|
||||
+{
|
||||
+ struct machine_specific *ms = machdep->machspec;
|
||||
+
|
||||
+ /*
|
||||
+ * Either older kernel before kernel has 'physvirt_offset' or newer
|
||||
+ * kernel which removes 'physvirt_offset' has the same formula:
|
||||
+ * #define __phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET) | PAGE_OFFSET)
|
||||
+ */
|
||||
+ if (!(machdep->flags & HAS_PHYSVIRT_OFFSET))
|
||||
+ return (paddr - ms->phys_offset) | PAGE_OFFSET;
|
||||
+ else
|
||||
+ return paddr - ms->physvirt_offset;
|
||||
+}
|
||||
+
|
||||
ulong
|
||||
arm64_VTOP(ulong addr)
|
||||
{
|
||||
@@ -1188,8 +1207,18 @@ arm64_VTOP(ulong addr)
|
||||
return addr - machdep->machspec->kimage_voffset;
|
||||
}
|
||||
|
||||
- if (addr >= machdep->machspec->page_offset)
|
||||
- return addr + machdep->machspec->physvirt_offset;
|
||||
+ if (addr >= machdep->machspec->page_offset) {
|
||||
+ if (machdep->flags & HAS_PHYSVIRT_OFFSET) {
|
||||
+ return addr + machdep->machspec->physvirt_offset;
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * Either older kernel before kernel has 'physvirt_offset' or newer
|
||||
+ * kernel which removes 'physvirt_offset' has the same formula:
|
||||
+ * #define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)
|
||||
+ */
|
||||
+ return (addr & ~PAGE_OFFSET) + machdep->machspec->phys_offset;
|
||||
+ }
|
||||
+ }
|
||||
else if (machdep->machspec->kimage_voffset)
|
||||
return addr - machdep->machspec->kimage_voffset;
|
||||
else /* no randomness */
|
||||
diff --git a/defs.h b/defs.h
|
||||
index eca145cb881c..c91177a245fd 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -3092,11 +3092,6 @@ typedef u64 pte_t;
|
||||
#define _64BIT_
|
||||
#define MACHINE_TYPE "ARM64"
|
||||
|
||||
-#define PTOV(X) \
|
||||
- ((unsigned long)(X) - (machdep->machspec->physvirt_offset))
|
||||
-
|
||||
-#define VTOP(X) arm64_VTOP((ulong)(X))
|
||||
-
|
||||
#define USERSPACE_TOP (machdep->machspec->userspace_top)
|
||||
#define PAGE_OFFSET (machdep->machspec->page_offset)
|
||||
#define VMALLOC_START (machdep->machspec->vmalloc_start_addr)
|
||||
@@ -3106,6 +3101,9 @@ typedef u64 pte_t;
|
||||
#define MODULES_VADDR (machdep->machspec->modules_vaddr)
|
||||
#define MODULES_END (machdep->machspec->modules_end)
|
||||
|
||||
+#define PTOV(X) arm64_PTOV((ulong)(X))
|
||||
+#define VTOP(X) arm64_VTOP((ulong)(X))
|
||||
+
|
||||
#define IS_VMALLOC_ADDR(X) arm64_IS_VMALLOC_ADDR((ulong)(X))
|
||||
|
||||
#define PAGEBASE(X) (((ulong)(X)) & (ulong)machdep->pagemask)
|
||||
@@ -5910,6 +5908,7 @@ void unwind_backtrace(struct bt_info *);
|
||||
void arm64_init(int);
|
||||
void arm64_dump_machdep_table(ulong);
|
||||
ulong arm64_VTOP(ulong);
|
||||
+ulong arm64_PTOV(ulong);
|
||||
int arm64_IS_VMALLOC_ADDR(ulong);
|
||||
ulong arm64_swp_type(ulong);
|
||||
ulong arm64_swp_offset(ulong);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,335 +0,0 @@
|
||||
From 2f967fb5ebd737ce5eadba462df35935122e8865 Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Date: Fri, 19 Mar 2021 21:07:33 -0700
|
||||
Subject: [PATCH 16/27] crash_taget: fetch_registers support
|
||||
|
||||
Provides API for crash_target to fetch registers of given
|
||||
CPU. It will allow gdb to perform such commands as "bt",
|
||||
"frame", "info locals".
|
||||
|
||||
Highlevel API is crash_get_cpu_reg (). It calls machine
|
||||
(architecture) specific function: machdep->get_cpu_reg().
|
||||
Input arguments such as register number and register size
|
||||
come from gdb arch information. So, get_cpu_regs()
|
||||
implementations in crash must understand it.
|
||||
|
||||
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
|
||||
---
|
||||
crash_target.c | 33 +++++++++++++++++++++++++++++++-
|
||||
defs.h | 51 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
gdb_interface.c | 19 +++++++++++++-----
|
||||
vmware_vmss.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
x86_64.c | 16 ++++++++++++++++
|
||||
5 files changed, 163 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/crash_target.c b/crash_target.c
|
||||
index a123329019f5..455480679741 100644
|
||||
--- a/crash_target.c
|
||||
+++ b/crash_target.c
|
||||
@@ -27,6 +27,8 @@ void crash_target_init (void);
|
||||
|
||||
extern "C" int gdb_readmem_callback(unsigned long, void *, int, int);
|
||||
extern "C" int crash_get_nr_cpus(void);
|
||||
+extern "C" int crash_get_cpu_reg (int cpu, int regno, const char *regname,
|
||||
+ int regsize, void *val);
|
||||
|
||||
|
||||
/* The crash target. */
|
||||
@@ -44,6 +46,7 @@ public:
|
||||
const target_info &info () const override
|
||||
{ return crash_target_info; }
|
||||
|
||||
+ void fetch_registers (struct regcache *, int) override;
|
||||
enum target_xfer_status xfer_partial (enum target_object object,
|
||||
const char *annex,
|
||||
gdb_byte *readbuf,
|
||||
@@ -54,13 +57,35 @@ public:
|
||||
bool has_all_memory () override { return true; }
|
||||
bool has_memory () override { return true; }
|
||||
bool has_stack () override { return true; }
|
||||
- bool has_registers () override { return false; }
|
||||
+ bool has_registers () override { return true; }
|
||||
bool thread_alive (ptid_t ptid) override { return true; }
|
||||
std::string pid_to_str (ptid_t ptid) override
|
||||
{ return string_printf ("CPU %ld", ptid.tid ()); }
|
||||
|
||||
};
|
||||
|
||||
+/* We just get all the registers, so we don't use regno. */
|
||||
+void
|
||||
+crash_target::fetch_registers (struct regcache *regcache, int regno)
|
||||
+{
|
||||
+ gdb_byte regval[16];
|
||||
+ int cpu = inferior_ptid.tid();
|
||||
+ struct gdbarch *arch = regcache->arch ();
|
||||
+
|
||||
+ for (int r = 0; r < gdbarch_num_regs (arch); r++)
|
||||
+ {
|
||||
+ const char *regname = gdbarch_register_name(arch, r);
|
||||
+ int regsize = register_size (arch, r);
|
||||
+ if (regsize > sizeof (regval))
|
||||
+ error (_("fatal error: buffer size is not enough to fit register value"));
|
||||
+
|
||||
+ if (crash_get_cpu_reg (cpu, r, regname, regsize, (void *)®val))
|
||||
+ regcache->raw_supply (r, regval);
|
||||
+ else
|
||||
+ regcache->raw_supply (r, NULL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
|
||||
enum target_xfer_status
|
||||
crash_target::xfer_partial (enum target_object object, const char *annex,
|
||||
@@ -101,4 +126,10 @@ crash_target_init (void)
|
||||
if (!i)
|
||||
switch_to_thread (thread);
|
||||
}
|
||||
+
|
||||
+ /* Fetch all registers from core file. */
|
||||
+ target_fetch_registers (get_current_regcache (), -1);
|
||||
+
|
||||
+ /* Now, set up the frame cache. */
|
||||
+ reinit_frame_cache ();
|
||||
}
|
||||
diff --git a/defs.h b/defs.h
|
||||
index db0bd9ca9fe8..b34c60e9a795 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -1013,6 +1013,7 @@ struct machdep_table {
|
||||
ulong (*processor_speed)(void);
|
||||
int (*uvtop)(struct task_context *, ulong, physaddr_t *, int);
|
||||
int (*kvtop)(struct task_context *, ulong, physaddr_t *, int);
|
||||
+ int (*get_cpu_reg)(int, int, const char *, int, void *);
|
||||
ulong (*get_task_pgd)(ulong);
|
||||
void (*dump_irq)(int);
|
||||
void (*get_stack_frame)(struct bt_info *, ulong *, ulong *);
|
||||
@@ -6858,6 +6859,7 @@ int vmware_vmss_get_nr_cpus(void);
|
||||
int vmware_vmss_get_cr3_cr4_idtr(int, ulong *, ulong *, ulong *);
|
||||
int vmware_vmss_phys_base(ulong *phys_base);
|
||||
int vmware_vmss_set_phys_base(ulong);
|
||||
+int vmware_vmss_get_cpu_reg(int, int, const char *, int, void *);
|
||||
|
||||
/*
|
||||
* vmware_guestdump.c
|
||||
@@ -7282,4 +7284,53 @@ extern int have_full_symbols(void);
|
||||
#define XEN_HYPERVISOR_ARCH
|
||||
#endif
|
||||
|
||||
+/*
|
||||
+ * Register numbers must be in sync with gdb/features/i386/64bit-core.c
|
||||
+ * to make crash_target->fetch_registers() ---> machdep->get_cpu_reg()
|
||||
+ * working properly.
|
||||
+ */
|
||||
+enum x86_64_regnum {
|
||||
+ RAX_REGNUM,
|
||||
+ RBX_REGNUM,
|
||||
+ RCX_REGNUM,
|
||||
+ RDX_REGNUM,
|
||||
+ RSI_REGNUM,
|
||||
+ RDI_REGNUM,
|
||||
+ RBP_REGNUM,
|
||||
+ RSP_REGNUM,
|
||||
+ R8_REGNUM,
|
||||
+ R9_REGNUM,
|
||||
+ R10_REGNUM,
|
||||
+ R11_REGNUM,
|
||||
+ R12_REGNUM,
|
||||
+ R13_REGNUM,
|
||||
+ R14_REGNUM,
|
||||
+ R15_REGNUM,
|
||||
+ RIP_REGNUM,
|
||||
+ EFLAGS_REGNUM,
|
||||
+ CS_REGNUM,
|
||||
+ SS_REGNUM,
|
||||
+ DS_REGNUM,
|
||||
+ ES_REGNUM,
|
||||
+ FS_REGNUM,
|
||||
+ GS_REGNUM,
|
||||
+ ST0_REGNUM,
|
||||
+ ST1_REGNUM,
|
||||
+ ST2_REGNUM,
|
||||
+ ST3_REGNUM,
|
||||
+ ST4_REGNUM,
|
||||
+ ST5_REGNUM,
|
||||
+ ST6_REGNUM,
|
||||
+ ST7_REGNUM,
|
||||
+ FCTRL_REGNUM,
|
||||
+ FSTAT_REGNUM,
|
||||
+ FTAG_REGNUM,
|
||||
+ FISEG_REGNUM,
|
||||
+ FIOFF_REGNUM,
|
||||
+ FOSEG_REGNUM,
|
||||
+ FOOFF_REGNUM,
|
||||
+ FOP_REGNUM,
|
||||
+ LAST_REGNUM
|
||||
+};
|
||||
+
|
||||
#endif /* !GDB_COMMON */
|
||||
diff --git a/gdb_interface.c b/gdb_interface.c
|
||||
index bcca080eb8b4..ce88d5a7c338 100644
|
||||
--- a/gdb_interface.c
|
||||
+++ b/gdb_interface.c
|
||||
@@ -698,11 +698,10 @@ static char *prohibited_list[] = {
|
||||
"run", "r", "break", "b", "tbreak", "hbreak", "thbreak", "rbreak",
|
||||
"watch", "rwatch", "awatch", "attach", "continue", "c", "fg", "detach",
|
||||
"finish", "handle", "interrupt", "jump", "kill", "next", "nexti",
|
||||
- "signal", "step", "s", "stepi", "target", "thread", "until", "delete",
|
||||
- "clear", "disable", "enable", "condition", "ignore", "frame",
|
||||
- "select-frame", "f", "up", "down", "catch", "tcatch", "return",
|
||||
- "file", "exec-file", "core-file", "symbol-file", "load", "si", "ni",
|
||||
- "shell", "sy",
|
||||
+ "signal", "step", "s", "stepi", "target", "until", "delete",
|
||||
+ "clear", "disable", "enable", "condition", "ignore", "frame", "catch",
|
||||
+ "tcatch", "return", "file", "exec-file", "core-file", "symbol-file",
|
||||
+ "load", "si", "ni", "shell", "sy",
|
||||
NULL /* must be last */
|
||||
};
|
||||
|
||||
@@ -1067,6 +1066,8 @@ unsigned long crash_get_kaslr_offset(void)
|
||||
|
||||
/* Callbacks for crash_target */
|
||||
int crash_get_nr_cpus(void);
|
||||
+int crash_get_cpu_reg (int cpu, int regno, const char *regname,
|
||||
+ int regsize, void *val);
|
||||
|
||||
int crash_get_nr_cpus(void)
|
||||
{
|
||||
@@ -1083,3 +1084,11 @@ int crash_get_nr_cpus(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+int crash_get_cpu_reg (int cpu, int regno, const char *regname,
|
||||
+ int regsize, void *value)
|
||||
+{
|
||||
+ if (!machdep->get_cpu_reg)
|
||||
+ return FALSE;
|
||||
+ return machdep->get_cpu_reg(cpu, regno, regname, regsize, value);
|
||||
+}
|
||||
+
|
||||
diff --git a/vmware_vmss.c b/vmware_vmss.c
|
||||
index 52d58e87d1c5..948a83817847 100644
|
||||
--- a/vmware_vmss.c
|
||||
+++ b/vmware_vmss.c
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* vmware_vmss.c
|
||||
*
|
||||
- * Copyright (c) 2015 VMware, Inc.
|
||||
+ * Copyright (c) 2015, 2020 VMware, Inc.
|
||||
* Copyright (c) 2018 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -16,6 +16,7 @@
|
||||
*
|
||||
* Authors: Dyno Hongjun Fu <hfu@vmware.com>
|
||||
* Sergio Lopez <slp@redhat.com>
|
||||
+ * Alexey Makhalov <amakhalov@vmware.com>
|
||||
*/
|
||||
|
||||
#include "defs.h"
|
||||
@@ -891,6 +892,54 @@ vmware_vmss_get_cr3_cr4_idtr(int cpu, ulong *cr3, ulong *cr4, ulong *idtr)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+int
|
||||
+vmware_vmss_get_cpu_reg(int cpu, int regno, const char *name, int size,
|
||||
+ void *value)
|
||||
+{
|
||||
+ if (cpu >= vmss.num_vcpus)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ /* All supported registers are 8 bytes long. */
|
||||
+ if (size != 8)
|
||||
+ return FALSE;
|
||||
+
|
||||
+#define CASE(R,r) \
|
||||
+ case R##_REGNUM: \
|
||||
+ if (!(vmss.vcpu_regs[cpu] & REGS_PRESENT_##R)) \
|
||||
+ return FALSE; \
|
||||
+ memcpy(value, &vmss.regs64[cpu]->r, size); \
|
||||
+ break
|
||||
+
|
||||
+
|
||||
+ switch (regno) {
|
||||
+ CASE (RAX, rax);
|
||||
+ CASE (RBX, rbx);
|
||||
+ CASE (RCX, rcx);
|
||||
+ CASE (RDX, rdx);
|
||||
+ CASE (RSI, rsi);
|
||||
+ CASE (RDI, rdi);
|
||||
+ CASE (RBP, rbp);
|
||||
+ CASE (RSP, rsp);
|
||||
+ CASE (R8, r8);
|
||||
+ CASE (R9, r9);
|
||||
+ CASE (R10, r10);
|
||||
+ CASE (R11, r11);
|
||||
+ CASE (R12, r12);
|
||||
+ CASE (R13, r13);
|
||||
+ CASE (R14, r14);
|
||||
+ CASE (R15, r15);
|
||||
+ CASE (RIP, rip);
|
||||
+ case EFLAGS_REGNUM:
|
||||
+ if (!(vmss.vcpu_regs[cpu] & REGS_PRESENT_RFLAGS))
|
||||
+ return FALSE;
|
||||
+ memcpy(value, &vmss.regs64[cpu]->rflags, size);
|
||||
+ break;
|
||||
+ default:
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
int
|
||||
vmware_vmss_phys_base(ulong *phys_base)
|
||||
{
|
||||
diff --git a/x86_64.c b/x86_64.c
|
||||
index 4f34afac06f9..d0565ba26a0c 100644
|
||||
--- a/x86_64.c
|
||||
+++ b/x86_64.c
|
||||
@@ -126,6 +126,7 @@ static int x86_64_get_framesize(struct bt_info *, ulong, ulong);
|
||||
static void x86_64_framesize_debug(struct bt_info *);
|
||||
static void x86_64_get_active_set(void);
|
||||
static int x86_64_get_kvaddr_ranges(struct vaddr_range *);
|
||||
+static int x86_64_get_cpu_reg(int, int, const char *, int, void *);
|
||||
static int x86_64_verify_paddr(uint64_t);
|
||||
static void GART_init(void);
|
||||
static void x86_64_exception_stacks_init(void);
|
||||
@@ -194,6 +195,7 @@ x86_64_init(int when)
|
||||
machdep->machspec->irq_eframe_link = UNINITIALIZED;
|
||||
machdep->machspec->irq_stack_gap = UNINITIALIZED;
|
||||
machdep->get_kvaddr_ranges = x86_64_get_kvaddr_ranges;
|
||||
+ machdep->get_cpu_reg = x86_64_get_cpu_reg;
|
||||
if (machdep->cmdline_args[0])
|
||||
parse_cmdline_args();
|
||||
if ((string = pc->read_vmcoreinfo("relocate"))) {
|
||||
@@ -884,6 +886,7 @@ x86_64_dump_machdep_table(ulong arg)
|
||||
fprintf(fp, " is_page_ptr: x86_64_is_page_ptr()\n");
|
||||
fprintf(fp, " verify_paddr: x86_64_verify_paddr()\n");
|
||||
fprintf(fp, " get_kvaddr_ranges: x86_64_get_kvaddr_ranges()\n");
|
||||
+ fprintf(fp, " get_cpu_reg: x86_64_get_cpu_reg()\n");
|
||||
fprintf(fp, " init_kernel_pgd: x86_64_init_kernel_pgd()\n");
|
||||
fprintf(fp, "clear_machdep_cache: x86_64_clear_machdep_cache()\n");
|
||||
fprintf(fp, " xendump_p2m_create: %s\n", PVOPS_XEN() ?
|
||||
@@ -8934,6 +8937,19 @@ x86_64_get_kvaddr_ranges(struct vaddr_range *vrp)
|
||||
return cnt;
|
||||
}
|
||||
|
||||
+static int
|
||||
+x86_64_get_cpu_reg(int cpu, int regno, const char *name,
|
||||
+ int size, void *value)
|
||||
+{
|
||||
+ if (regno >= LAST_REGNUM)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (VMSS_DUMPFILE())
|
||||
+ return vmware_vmss_get_cpu_reg(cpu, regno, name, size, value);
|
||||
+
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Determine the physical memory range reserved for GART.
|
||||
*/
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,33 +0,0 @@
|
||||
From e832e0eb5bd8d97dfa9f4bd0e22fbfad849c11df Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Date: Fri, 19 Mar 2021 21:07:34 -0700
|
||||
Subject: [PATCH 17/27] Allow 'gdb disassemble' command for relocated kernel
|
||||
|
||||
As new gdb is able to handle it properly.
|
||||
|
||||
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
|
||||
---
|
||||
gdb_interface.c | 7 -------
|
||||
1 file changed, 7 deletions(-)
|
||||
|
||||
diff --git a/gdb_interface.c b/gdb_interface.c
|
||||
index ce88d5a7c338..d3e1484f8dd9 100644
|
||||
--- a/gdb_interface.c
|
||||
+++ b/gdb_interface.c
|
||||
@@ -741,13 +741,6 @@ is_restricted_command(char *cmd, ulong flags)
|
||||
}
|
||||
}
|
||||
|
||||
- if (kt->relocate &&
|
||||
- STRNEQ("disassemble", cmd) && STRNEQ(cmd, "disas"))
|
||||
- error(FATAL,
|
||||
- "the gdb \"disassemble\" command is prohibited because the kernel text\n"
|
||||
- "%swas relocated%s; use the crash \"dis\" command instead.\n",
|
||||
- space(strlen(pc->curcmd)+2), kt->flags2 & KASLR ? " by KASLR" : "");
|
||||
-
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,45 +0,0 @@
|
||||
From 96716862765f73676bfdb2d19fc5872364d21b73 Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Date: Fri, 19 Mar 2021 21:07:35 -0700
|
||||
Subject: [PATCH 18/27] vmware backend: honor silence flag
|
||||
|
||||
Do not print any boot messages in silence (-s) mode.
|
||||
|
||||
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
|
||||
---
|
||||
vmware_vmss.c | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/vmware_vmss.c b/vmware_vmss.c
|
||||
index 948a83817847..f6c5f32ea4c0 100644
|
||||
--- a/vmware_vmss.c
|
||||
+++ b/vmware_vmss.c
|
||||
@@ -444,11 +444,13 @@ vmware_vmss_init(char *filename, FILE *ofp)
|
||||
if (vmss.memsize == 0) {
|
||||
char *vmem_filename, *p;
|
||||
|
||||
- fprintf(ofp, LOGPRX"Memory dump is not part of this vmss file.\n");
|
||||
+ if (!(pc->flags & SILENT))
|
||||
+ fprintf(ofp, LOGPRX"Memory dump is not part of this vmss file.\n");
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
|
||||
- fprintf(ofp, LOGPRX"Try to locate the companion vmem file ...\n");
|
||||
+ if (!(pc->flags & SILENT))
|
||||
+ fprintf(ofp, LOGPRX"Try to locate the companion vmem file ...\n");
|
||||
/* check the companion vmem file */
|
||||
vmem_filename = strdup(filename);
|
||||
p = vmem_filename + strlen(vmem_filename) - 4;
|
||||
@@ -471,7 +473,8 @@ vmware_vmss_init(char *filename, FILE *ofp)
|
||||
vmss.separate_vmem = TRUE;
|
||||
vmss.filename = filename;
|
||||
|
||||
- fprintf(ofp, LOGPRX"vmem file: %s\n\n", vmem_filename);
|
||||
+ if (!(pc->flags & SILENT))
|
||||
+ fprintf(ofp, LOGPRX"vmem file: %s\n\n", vmem_filename);
|
||||
free(vmem_filename);
|
||||
}
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,31 +0,0 @@
|
||||
From 6c5f0c6ff5d158f2ef4fa997a052b0643d0c25ee Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Date: Fri, 19 Mar 2021 21:07:36 -0700
|
||||
Subject: [PATCH 19/27] vmware_guestdump: add debugging of the init function
|
||||
|
||||
Dump memory and registers state after parsing.
|
||||
|
||||
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
|
||||
---
|
||||
vmware_guestdump.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/vmware_guestdump.c b/vmware_guestdump.c
|
||||
index 62da0a77a227..cf818e588a60 100644
|
||||
--- a/vmware_guestdump.c
|
||||
+++ b/vmware_guestdump.c
|
||||
@@ -267,6 +267,11 @@ vmware_guestdump_init(char *filename, FILE *ofp)
|
||||
fseek(vmss.dfp, 0L, SEEK_SET);
|
||||
fprintf(ofp, LOGPRX"vmem file: %s\n\n", vmem_filename);
|
||||
|
||||
+ if (CRASHDEBUG(1)) {
|
||||
+ vmware_guestdump_memory_dump(ofp);
|
||||
+ dump_registers_for_vmss_dump();
|
||||
+ }
|
||||
+
|
||||
exit:
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,65 +0,0 @@
|
||||
From 8d6f677e54a2474b3da19402e29278b62603d71d Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Date: Thu, 8 Jul 2021 16:14:02 -0700
|
||||
Subject: [PATCH 20/27] Do not adjust addr by relocate offset(KASLR)
|
||||
|
||||
GBD symbol resolution already considers relocation (KASLR) offset.
|
||||
So, there is no needs to adjust the function address before calling
|
||||
GDB.
|
||||
|
||||
It fixes file name and line number output for 'dis -l' and 'sys -c'
|
||||
commands.
|
||||
|
||||
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||
---
|
||||
gdb_interface.c | 3 +--
|
||||
kernel.c | 3 +--
|
||||
symbols.c | 3 +--
|
||||
3 files changed, 3 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/gdb_interface.c b/gdb_interface.c
|
||||
index d3e1484f8dd9..b098ed823d55 100644
|
||||
--- a/gdb_interface.c
|
||||
+++ b/gdb_interface.c
|
||||
@@ -1013,8 +1013,7 @@ gdb_set_crash_scope(ulong vaddr, char *arg)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
- } else if (kt->flags2 & KASLR)
|
||||
- vaddr -= (kt->relocate * -1);
|
||||
+ }
|
||||
}
|
||||
|
||||
req->command = GNU_SET_CRASH_BLOCK;
|
||||
diff --git a/kernel.c b/kernel.c
|
||||
index 6b586dbb05c1..6a812ac7b1bc 100644
|
||||
--- a/kernel.c
|
||||
+++ b/kernel.c
|
||||
@@ -1484,8 +1484,7 @@ list_source_code(struct gnu_request *req, int count_entered)
|
||||
if (!(lm->mod_flags & MOD_LOAD_SYMS))
|
||||
error(FATAL, "%s: module source code is not available\n", lm->mod_name);
|
||||
get_line_number(req->addr, buf1, FALSE);
|
||||
- } else if (kt->flags2 & KASLR)
|
||||
- req->addr -= (kt->relocate * -1);
|
||||
+ }
|
||||
|
||||
sprintf(buf1, "list *0x%lx", req->addr);
|
||||
open_tmpfile();
|
||||
diff --git a/symbols.c b/symbols.c
|
||||
index 338af2ce5038..5d3c53a30abc 100644
|
||||
--- a/symbols.c
|
||||
+++ b/symbols.c
|
||||
@@ -4296,8 +4296,7 @@ get_line_number(ulong addr, char *buf, int reserved)
|
||||
if (module_symbol(addr, NULL, &lm, NULL, 0)) {
|
||||
if (!(lm->mod_flags & MOD_LOAD_SYMS))
|
||||
return(buf);
|
||||
- } else if (kt->flags2 & KASLR)
|
||||
- addr -= (kt->relocate * -1);
|
||||
+ }
|
||||
|
||||
if ((lnh = machdep->line_number_hooks)) {
|
||||
name = closest_symbol(addr);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,44 +0,0 @@
|
||||
From fce91bec5bef534e52f3261cc289a21a2cdb5fe3 Mon Sep 17 00:00:00 2001
|
||||
From: Tao Liu <ltao@redhat.com>
|
||||
Date: Sun, 11 Jul 2021 22:30:22 +0800
|
||||
Subject: [PATCH 21/27] Fix the failure of reporting vmcore and vmlinux do not
|
||||
match for kernels(<2.6.11)
|
||||
|
||||
There is a regression issue for kernels(<2.6.11) as below:
|
||||
|
||||
$ crash 2.6.9-68.9/vmcore 2.6.9-68.9/vmlinux.gz
|
||||
...
|
||||
GNU gdb (GDB) 10.2
|
||||
...
|
||||
crash: /var/tmp/vmlinux.gz_GLsAvX and 2.6.9-68.9/vmcore do not match!
|
||||
|
||||
The reason is that it needs to read out the address of linux banner with
|
||||
readmem() first, and then the read_string() will be able to read the data
|
||||
from linux banner. So, for the kernels(<2.6.11) case, lets still invoke
|
||||
get_symbol_data() to accomplish this. See the changes:
|
||||
[1] https://elixir.bootlin.com/linux/v2.6.10/source/init/version.c#L38
|
||||
[2] https://elixir.bootlin.com/linux/v2.6.11/source/init/version.c#L38
|
||||
|
||||
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
---
|
||||
kernel.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/kernel.c b/kernel.c
|
||||
index 6a812ac7b1bc..a559f937980e 100644
|
||||
--- a/kernel.c
|
||||
+++ b/kernel.c
|
||||
@@ -1052,7 +1052,8 @@ verify_version(void)
|
||||
|
||||
if (!(sp = symbol_search("linux_banner")))
|
||||
error(FATAL, "linux_banner symbol does not exist?\n");
|
||||
- else if ((sp->type == 'R') || (sp->type == 'r') || (sp->type == 'D') ||
|
||||
+ else if ((sp->type == 'R') || (sp->type == 'r') ||
|
||||
+ (THIS_KERNEL_VERSION >= LINUX(2,6,11) && sp->type == 'D') ||
|
||||
(machine_type("ARM") && sp->type == 'T') ||
|
||||
(machine_type("ARM64")))
|
||||
linux_banner = symbol_value("linux_banner");
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,90 +0,0 @@
|
||||
From 51f21b0d1c91a4ae02ebf0d8c81460ec8b6c1283 Mon Sep 17 00:00:00 2001
|
||||
From: Tao Liu <ltao@redhat.com>
|
||||
Date: Thu, 15 Jul 2021 17:34:29 +0800
|
||||
Subject: [PATCH 22/27] x86_64_irq_eframe_link_init: Fix wrong instruction
|
||||
searching range calculation
|
||||
|
||||
In function x86_64_irq_eframe_link_init, instruction "push xxx" is searched in
|
||||
addresses range from "common_interrupt" to the next nearby symbol, in order to
|
||||
calculate the value of irq_eframe_link. The searching distance is given by
|
||||
max_instructions, which is calculated by end ranging address minus start ranging
|
||||
address. Then crash asks gdb to disassemble max_instructions quantity of instructions.
|
||||
|
||||
Taking max_instructions as the quantity of disassemble instructions is inappropriate,
|
||||
because most x86_64 instructions have a length longer than 1, as a consequence, much
|
||||
more than the actual needed instructions get disassembled.
|
||||
|
||||
In gdb-7.6 crash, the extra instructions are skipped by "if (!strstr(buf, sp->name))",
|
||||
which breaks if one instruction doesn't belongs to a symbol:
|
||||
|
||||
0xffffffff8005d5b4 <common_interrupt+0>: cld
|
||||
0xffffffff8005d5b5 <common_interrupt+1>: sub $0x48,%rsp
|
||||
...
|
||||
0xffffffff8005d61e <common_interrupt+106>: leaveq
|
||||
0xffffffff8005d61f <exit_intr>: mov %gs:0x10,%rcx <--- searching stops here
|
||||
...
|
||||
|
||||
In gdb-10.2 crash, "exit_intr" doesn't show, however it really exist. As a result,
|
||||
searching for "push xxx" will go to a wrong place.
|
||||
|
||||
0xffffffff8005d5b4 <common_interrupt+0>: cld
|
||||
0xffffffff8005d5b5 <common_interrupt+1>: sub $0x48,%rsp
|
||||
...
|
||||
0xffffffff8005d61e <common_interrupt+106>: leave
|
||||
0xffffffff8005d61f <common_interrupt+107>: mov %gs:0x10,%rcx <--- searching continues
|
||||
...
|
||||
|
||||
(gdb) p exit_intr
|
||||
$1 = {<text variable, no debug info>} 0xffffffff8005d61f <common_interrupt+107>
|
||||
(gdb) info symbol exit_intr
|
||||
common_interrupt + 107 in section .text
|
||||
|
||||
The previous way to determine start and end searching range is not stable, otherwise we may
|
||||
encounter regression that cmd "bt" prints wrong IRQ stack. This patch fix the bug by removing
|
||||
max_instructions calculation, and directly ask gdb to disassemble addresses range from
|
||||
"common_interrupt" to the next nearby symbol.
|
||||
|
||||
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||
---
|
||||
x86_64.c | 9 ++++-----
|
||||
1 file changed, 4 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/x86_64.c b/x86_64.c
|
||||
index d0565ba26a0c..552d6194930b 100644
|
||||
--- a/x86_64.c
|
||||
+++ b/x86_64.c
|
||||
@@ -6472,7 +6472,6 @@ x86_64_irq_eframe_link_init(void)
|
||||
char buf[BUFSIZE];
|
||||
char link_register[BUFSIZE];
|
||||
char *arglist[MAXARGS];
|
||||
- ulong max_instructions;
|
||||
|
||||
if (machdep->machspec->irq_eframe_link == UNINITIALIZED)
|
||||
machdep->machspec->irq_eframe_link = 0;
|
||||
@@ -6487,12 +6486,10 @@ x86_64_irq_eframe_link_init(void)
|
||||
return;
|
||||
}
|
||||
|
||||
- max_instructions = spn->value - sp->value;
|
||||
-
|
||||
open_tmpfile();
|
||||
|
||||
- sprintf(buf, "x/%ldi 0x%lx",
|
||||
- max_instructions, sp->value);
|
||||
+ sprintf(buf, "disassemble 0x%lx, 0x%lx",
|
||||
+ sp->value, spn->value);
|
||||
|
||||
if (!gdb_pass_through(buf, pc->tmpfile, GNU_RETURN_ON_ERROR))
|
||||
return;
|
||||
@@ -6501,6 +6498,8 @@ x86_64_irq_eframe_link_init(void)
|
||||
|
||||
rewind(pc->tmpfile);
|
||||
while (fgets(buf, BUFSIZE, pc->tmpfile)) {
|
||||
+ if (STRNEQ(buf, "Dump of assembler code"))
|
||||
+ continue;
|
||||
if (!strstr(buf, sp->name))
|
||||
break;
|
||||
if ((c = parse_line(buf, arglist)) < 4)
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,49 +0,0 @@
|
||||
From b8e1f2735b8dd1303aeb2affa309a2a409a82d38 Mon Sep 17 00:00:00 2001
|
||||
From: Tao Liu <ltao@redhat.com>
|
||||
Date: Mon, 26 Jul 2021 09:58:54 +0800
|
||||
Subject: [PATCH 23/27] Add kernel version dependent check for getting length
|
||||
of log_end
|
||||
|
||||
For kernels(>=2.4.9.11 [1] && <3.5 [2]), log_end was involved in the kernel sources.
|
||||
For kernels(>=2.6.25 [3]), log_end was defined as:
|
||||
static unsigned log_end;
|
||||
For kernels(<2.6.25), log_end was defined as:
|
||||
static unsigned long log_end;
|
||||
|
||||
Previously, the length of log_end is determined by get_symbol_length, but it can
|
||||
be a regression when the returned length is 0 for some cases and value unchecked:
|
||||
|
||||
crash> help -t
|
||||
...
|
||||
help: invalid size request: 0 type: "log_end"
|
||||
|
||||
To solve the above issue, let's add a kernel version dependent check to get its
|
||||
value appropriately when the length of the 'log_end' returns a value of zero.
|
||||
|
||||
[1]: https://elixir.bootlin.com/linux/2.4.9.11/source/kernel/printk.c#L74
|
||||
[2]: https://elixir.bootlin.com/linux/v3.5/source/kernel/printk.c
|
||||
[3]: https://elixir.bootlin.com/linux/v2.6.25/source/kernel/printk.c#L104
|
||||
|
||||
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||
---
|
||||
kernel.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/kernel.c b/kernel.c
|
||||
index a559f937980e..a8be7bb1947f 100644
|
||||
--- a/kernel.c
|
||||
+++ b/kernel.c
|
||||
@@ -5106,6 +5106,10 @@ dump_log(int msg_flags)
|
||||
if ((len = get_symbol_length("log_end")) == sizeof(int)) {
|
||||
get_symbol_data("log_end", len, &tmp);
|
||||
log_end = (ulong)tmp;
|
||||
+ } else if (len == 0) {
|
||||
+ THIS_KERNEL_VERSION >= LINUX(2,6,25) ?
|
||||
+ get_symbol_data("log_end", sizeof(unsigned), &log_end) :
|
||||
+ get_symbol_data("log_end", sizeof(unsigned long), &log_end);
|
||||
} else
|
||||
get_symbol_data("log_end", len, &log_end);
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,39 +0,0 @@
|
||||
From 5c2d8d2d9da6423eec076fd51049d7b4677b61c6 Mon Sep 17 00:00:00 2001
|
||||
From: Tao Liu <ltao@redhat.com>
|
||||
Date: Tue, 17 Aug 2021 16:21:43 +0800
|
||||
Subject: [PATCH 24/27] Set gdb max-value-size to be unlimited
|
||||
|
||||
gdb-10.2 uses max-value-size as the maximum size in bytes that the contents
|
||||
of a object may allocate. The default value of max-value-size is 64K. However,
|
||||
it could be not enough for allocating an object which requires larger space, and
|
||||
failed at the startup of crash.
|
||||
|
||||
In gdb-7.6, there is no max-value-size check and works fine. So in this patch,
|
||||
let's just set max-value-size to be unlimited.
|
||||
|
||||
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||
---
|
||||
gdb_interface.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/gdb_interface.c b/gdb_interface.c
|
||||
index b098ed823d55..2fe9ccde83a1 100644
|
||||
--- a/gdb_interface.c
|
||||
+++ b/gdb_interface.c
|
||||
@@ -300,6 +300,13 @@ retry:
|
||||
sprintf(req->buf, "set width 0");
|
||||
gdb_interface(req);
|
||||
|
||||
+#ifdef GDB_10_2
|
||||
+ req->command = GNU_PASS_THROUGH;
|
||||
+ req->name = NULL, req->flags = 0;
|
||||
+ sprintf(req->buf, "set max-value-size unlimited");
|
||||
+ gdb_interface(req);
|
||||
+#endif
|
||||
+
|
||||
#if 0
|
||||
/*
|
||||
* Patch gdb's symbol values with the correct values from either
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,55 +0,0 @@
|
||||
From c1e256249426dd59ceea99038451a39e98a26790 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Thu, 19 Aug 2021 10:52:58 +0900
|
||||
Subject: [PATCH 25/27] Fix tab completion issues
|
||||
|
||||
1. The maximum number of tab completion candidates is limited to 200
|
||||
by default. Set it unlimited.
|
||||
|
||||
2. The output of tab completion is not wrapped with the screen width.
|
||||
Get and use it when tab completion is invoked.
|
||||
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
gdb-10.2.patch | 11 +++++++++++
|
||||
gdb_interface.c | 5 +++++
|
||||
2 files changed, 16 insertions(+)
|
||||
|
||||
diff --git a/gdb-10.2.patch b/gdb-10.2.patch
|
||||
index 4f8d418b17ed..1332b6638028 100644
|
||||
--- a/gdb-10.2.patch
|
||||
+++ b/gdb-10.2.patch
|
||||
@@ -1580,3 +1580,14 @@
|
||||
_rl_tracefp = 0;
|
||||
return r;
|
||||
}
|
||||
+--- gdb-10.2/gdb/completer.c.orig
|
||||
++++ gdb-10.2/gdb/completer.c
|
||||
+@@ -2949,6 +2949,8 @@
|
||||
+
|
||||
+ /* How many items of MAX length can we fit in the screen window? */
|
||||
+ cols = gdb_complete_get_screenwidth (displayer);
|
||||
++ rl_reset_screen_size();
|
||||
++ rl_get_screen_size(NULL, &cols);
|
||||
+ max += 2;
|
||||
+ limit = cols / max;
|
||||
+ if (limit != 1 && (limit * max == cols))
|
||||
diff --git a/gdb_interface.c b/gdb_interface.c
|
||||
index 2fe9ccde83a1..ff45cdcd39ae 100644
|
||||
--- a/gdb_interface.c
|
||||
+++ b/gdb_interface.c
|
||||
@@ -305,6 +305,11 @@ retry:
|
||||
req->name = NULL, req->flags = 0;
|
||||
sprintf(req->buf, "set max-value-size unlimited");
|
||||
gdb_interface(req);
|
||||
+
|
||||
+ req->command = GNU_PASS_THROUGH;
|
||||
+ req->name = NULL, req->flags = 0;
|
||||
+ sprintf(req->buf, "set max-completions unlimited");
|
||||
+ gdb_interface(req);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,402 +0,0 @@
|
||||
From 05a3a328fcd8920e49926b6d1c9c81ce0b6acbca Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Thu, 9 Sep 2021 15:23:27 +0900
|
||||
Subject: [PATCH 26/27] Remove text value cache code
|
||||
|
||||
The text value cache was implemented for analysis of remote dumpfiles
|
||||
using the deprecated "crash daemon" running on the remote host. On
|
||||
updating GDB to 10.2, a regression occurred when we tried to fix a
|
||||
"help -x" command problem, and there was no performance degradation
|
||||
even without the text cache, so let's drop this functionality.
|
||||
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
alpha.c | 8 +-
|
||||
cmdline.c | 1 -
|
||||
defs.h | 4 -
|
||||
gdb_interface.c | 14 ----
|
||||
help.c | 8 +-
|
||||
kernel.c | 1 -
|
||||
symbols.c | 196 ------------------------------------------------
|
||||
x86.c | 7 --
|
||||
8 files changed, 3 insertions(+), 236 deletions(-)
|
||||
|
||||
diff --git a/alpha.c b/alpha.c
|
||||
index fa2d5f5935c9..73497120b4bf 100644
|
||||
--- a/alpha.c
|
||||
+++ b/alpha.c
|
||||
@@ -776,12 +776,8 @@ alpha_frame_offset(struct gnu_request *req, ulong alt_pc)
|
||||
* Don't go any farther than "stq ra,0(sp)" (0xb75e0000)
|
||||
*/
|
||||
while (ival != 0xb75e0000) {
|
||||
- if (!text_value_cache((ulong)ip, 0, &ival)) {
|
||||
- readmem((ulong)ip, KVADDR, &ival,
|
||||
- sizeof(uint), "uncached text value",
|
||||
- FAULT_ON_ERROR);
|
||||
- text_value_cache((ulong)ip, ival, NULL);
|
||||
- }
|
||||
+ readmem((ulong)ip, KVADDR, &ival, sizeof(uint),
|
||||
+ "text value", FAULT_ON_ERROR);
|
||||
|
||||
if ((ival & 0xffe01fff) == 0x43c0153e) {
|
||||
value = (ival & 0x1fe000) >> 13;
|
||||
diff --git a/cmdline.c b/cmdline.c
|
||||
index 796f7c58f243..ded6551c2597 100644
|
||||
--- a/cmdline.c
|
||||
+++ b/cmdline.c
|
||||
@@ -1235,7 +1235,6 @@ restore_sanity(void)
|
||||
if (CRASHDEBUG(5)) {
|
||||
dump_filesys_table(0);
|
||||
dump_vma_cache(0);
|
||||
- dump_text_value_cache(0);
|
||||
}
|
||||
|
||||
if (REMOTE())
|
||||
diff --git a/defs.h b/defs.h
|
||||
index b34c60e9a795..cbd45e52f9da 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -5327,10 +5327,6 @@ char *load_module_filter(char *, int);
|
||||
long datatype_info(char *, char *, struct datatype_member *);
|
||||
int get_symbol_type(char *, char *, struct gnu_request *);
|
||||
int get_symbol_length(char *);
|
||||
-int text_value_cache(ulong, uint32_t, uint32_t *);
|
||||
-int text_value_cache_byte(ulong, unsigned char *);
|
||||
-void dump_text_value_cache(int);
|
||||
-void clear_text_value_cache(void);
|
||||
void dump_numargs_cache(void);
|
||||
int patch_kernel_symbol(struct gnu_request *);
|
||||
struct syment *generic_machdep_value_to_symbol(ulong, ulong *);
|
||||
diff --git a/gdb_interface.c b/gdb_interface.c
|
||||
index ff45cdcd39ae..3a7fcc9e3ade 100644
|
||||
--- a/gdb_interface.c
|
||||
+++ b/gdb_interface.c
|
||||
@@ -828,7 +828,6 @@ int
|
||||
gdb_readmem_callback(ulong addr, void *buf, int len, int write)
|
||||
{
|
||||
char locbuf[SIZEOF_32BIT], *p1;
|
||||
- uint32_t *p2;
|
||||
int memtype;
|
||||
ulong readflags;
|
||||
|
||||
@@ -885,19 +884,12 @@ gdb_readmem_callback(ulong addr, void *buf, int len, int write)
|
||||
}
|
||||
|
||||
p1 = (char *)buf;
|
||||
- if ((memtype == KVADDR) &&
|
||||
- text_value_cache_byte(addr, (unsigned char *)p1))
|
||||
- return TRUE;
|
||||
|
||||
if (!readmem(addr, memtype, locbuf, SIZEOF_32BIT,
|
||||
"gdb_readmem_callback", readflags))
|
||||
return FALSE;
|
||||
|
||||
*p1 = locbuf[0];
|
||||
- if (memtype == KVADDR) {
|
||||
- p2 = (uint32_t *)locbuf;
|
||||
- text_value_cache(addr, *p2, 0);
|
||||
- }
|
||||
return TRUE;
|
||||
|
||||
case SIZEOF_32BIT:
|
||||
@@ -907,16 +899,10 @@ gdb_readmem_callback(ulong addr, void *buf, int len, int write)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
- if ((memtype == KVADDR) && text_value_cache(addr, 0, buf))
|
||||
- return TRUE;
|
||||
-
|
||||
if (!readmem(addr, memtype, buf, SIZEOF_32BIT,
|
||||
"gdb_readmem callback", readflags))
|
||||
return FALSE;
|
||||
|
||||
- if (memtype == KVADDR)
|
||||
- text_value_cache(addr,
|
||||
- (uint32_t)*((uint32_t *)buf), NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
diff --git a/help.c b/help.c
|
||||
index e67fde0018ab..c19b69b8b20c 100644
|
||||
--- a/help.c
|
||||
+++ b/help.c
|
||||
@@ -535,7 +535,7 @@ cmd_help(void)
|
||||
oflag = 0;
|
||||
|
||||
while ((c = getopt(argcnt, args,
|
||||
- "efNDdmM:ngcaBbHhkKsvVoptTzLxOr")) != EOF) {
|
||||
+ "efNDdmM:ngcaBbHhkKsvVoptTzLOr")) != EOF) {
|
||||
switch(c)
|
||||
{
|
||||
case 'e':
|
||||
@@ -551,10 +551,6 @@ cmd_help(void)
|
||||
dumpfile_memory(DUMPFILE_MEM_DUMP);
|
||||
return;
|
||||
|
||||
- case 'x':
|
||||
- dump_text_value_cache(VERBOSE);
|
||||
- return;
|
||||
-
|
||||
case 'd':
|
||||
dump_dev_table();
|
||||
return;
|
||||
@@ -666,7 +662,6 @@ cmd_help(void)
|
||||
fprintf(fp, " -T - task_table plus context_array\n");
|
||||
fprintf(fp, " -v - vm_table\n");
|
||||
fprintf(fp, " -V - vm_table (verbose)\n");
|
||||
- fprintf(fp, " -x - text cache\n");
|
||||
fprintf(fp, " -z - help options\n");
|
||||
return;
|
||||
|
||||
@@ -1026,7 +1021,6 @@ char *help_help[] = {
|
||||
" -T - task_table plus context_array",
|
||||
" -v - vm_table",
|
||||
" -V - vm_table (verbose)",
|
||||
-" -x - text cache",
|
||||
" -z - help options",
|
||||
NULL
|
||||
};
|
||||
diff --git a/kernel.c b/kernel.c
|
||||
index a8be7bb1947f..3ead4bbb172e 100644
|
||||
--- a/kernel.c
|
||||
+++ b/kernel.c
|
||||
@@ -4661,7 +4661,6 @@ reinit_modules(void)
|
||||
st->ext_module_symtable = NULL;
|
||||
st->load_modules = NULL;
|
||||
kt->mods_installed = 0;
|
||||
- clear_text_value_cache();
|
||||
|
||||
module_init();
|
||||
}
|
||||
diff --git a/symbols.c b/symbols.c
|
||||
index 5d3c53a30abc..69dccdb09d5f 100644
|
||||
--- a/symbols.c
|
||||
+++ b/symbols.c
|
||||
@@ -12824,202 +12824,6 @@ gnu_qsort(bfd *bfd,
|
||||
qsort(minisyms, symcount, size, numeric_forward);
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Keep a stash of commonly-accessed text locations checked by the
|
||||
- * back_trace code. The saved values unsigned 32-bit values.
|
||||
- * The same routine is used to store and query, based upon whether
|
||||
- * the passed-in value and valptr args are non-zero.
|
||||
- */
|
||||
-#define TEXT_CACHE (50)
|
||||
-#define MAX_TEXT_CACHE (TEXT_CACHE*4)
|
||||
-
|
||||
-struct text_cache_entry {
|
||||
- ulong vaddr;
|
||||
- uint32_t value;
|
||||
-};
|
||||
-
|
||||
-static struct text_cache {
|
||||
- int index;
|
||||
- int entries;
|
||||
- ulong hits;
|
||||
- ulong refs;
|
||||
- struct text_cache_entry *cache;
|
||||
-} text_cache = { 0 };
|
||||
-
|
||||
-/*
|
||||
- * Cache the contents of 32-bit text addresses. If "value" is set, the purpose
|
||||
- * is to cache it. If "valptr" is set, a query is being made for the text
|
||||
- * address.
|
||||
- */
|
||||
-int
|
||||
-text_value_cache(ulong vaddr, uint32_t value, uint32_t *valptr)
|
||||
-{
|
||||
- int i;
|
||||
- struct text_cache *tc;
|
||||
-
|
||||
- if (!is_kernel_text(vaddr))
|
||||
- return FALSE;
|
||||
-
|
||||
- tc = &text_cache;
|
||||
-
|
||||
- if (!tc->cache) {
|
||||
- if (!(tc->cache = (struct text_cache_entry *)
|
||||
- malloc(sizeof(struct text_cache_entry) * TEXT_CACHE)))
|
||||
- return FALSE;
|
||||
- BZERO(tc->cache, sizeof(struct text_cache_entry) * TEXT_CACHE);
|
||||
- tc->index = 0;
|
||||
- tc->entries = TEXT_CACHE;
|
||||
- }
|
||||
-
|
||||
- if (value) {
|
||||
- for (i = 0; i < tc->entries; i++) {
|
||||
- if (tc->cache[i].vaddr == vaddr)
|
||||
- return TRUE;
|
||||
- }
|
||||
-
|
||||
- i = tc->index;
|
||||
- tc->cache[i].vaddr = vaddr;
|
||||
- tc->cache[i].value = value;
|
||||
- tc->index++;
|
||||
- if (tc->index == MAX_TEXT_CACHE) {
|
||||
- tc->index = 0;
|
||||
- } else if (tc->index == tc->entries) {
|
||||
- struct text_cache_entry *old_cache;
|
||||
-
|
||||
- old_cache = tc->cache;
|
||||
- if ((tc->cache = (struct text_cache_entry *)
|
||||
- realloc(old_cache, sizeof(struct text_cache_entry) *
|
||||
- (TEXT_CACHE+tc->entries)))) {
|
||||
- BZERO(&tc->cache[tc->index],
|
||||
- sizeof(struct text_cache_entry) *
|
||||
- TEXT_CACHE);
|
||||
- tc->entries += TEXT_CACHE;
|
||||
- } else {
|
||||
- tc->cache = old_cache;
|
||||
- tc->index = 0;
|
||||
- }
|
||||
- }
|
||||
- return TRUE;
|
||||
- }
|
||||
-
|
||||
- if (valptr) {
|
||||
- tc->refs++;
|
||||
-
|
||||
- for (i = 0; i < tc->entries; i++) {
|
||||
- if (!tc->cache[i].vaddr)
|
||||
- return FALSE;
|
||||
-
|
||||
- if (tc->cache[i].vaddr == vaddr) {
|
||||
- *valptr = tc->cache[i].value;
|
||||
- tc->hits++;
|
||||
- return TRUE;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return FALSE;
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * The gdb disassembler reads text memory byte-by-byte, so this routine
|
||||
- * acts as a front-end to the 32-bit (4-byte) text storage.
|
||||
- */
|
||||
-
|
||||
-int
|
||||
-text_value_cache_byte(ulong vaddr, unsigned char *valptr)
|
||||
-{
|
||||
- int i;
|
||||
- int shift;
|
||||
- struct text_cache *tc;
|
||||
- ulong valtmp;
|
||||
-
|
||||
- if (!is_kernel_text(vaddr))
|
||||
- return FALSE;
|
||||
-
|
||||
- tc = &text_cache;
|
||||
-
|
||||
- tc->refs++;
|
||||
-
|
||||
- for (i = 0; i < tc->entries; i++) {
|
||||
- if (!tc->cache[i].vaddr)
|
||||
- return FALSE;
|
||||
-
|
||||
- if ((vaddr >= tc->cache[i].vaddr) &&
|
||||
- (vaddr < (tc->cache[i].vaddr+SIZEOF_32BIT))) {
|
||||
- valtmp = tc->cache[i].value;
|
||||
- shift = (vaddr - tc->cache[i].vaddr) * 8;
|
||||
- valtmp >>= shift;
|
||||
- *valptr = valtmp & 0xff;
|
||||
- tc->hits++;
|
||||
- return TRUE;
|
||||
- }
|
||||
- }
|
||||
- return FALSE;
|
||||
-}
|
||||
-
|
||||
-void
|
||||
-dump_text_value_cache(int verbose)
|
||||
-{
|
||||
- int i;
|
||||
- struct syment *sp;
|
||||
- ulong offset;
|
||||
- struct text_cache *tc;
|
||||
-
|
||||
- tc = &text_cache;
|
||||
-
|
||||
- if (!verbose) {
|
||||
- if (!tc->refs || !tc->cache)
|
||||
- return;
|
||||
-
|
||||
- fprintf(stderr, " text hit rate: %2ld%% (%ld of %ld)\n",
|
||||
- (tc->hits * 100)/tc->refs,
|
||||
- (ulong)tc->hits, (ulong)tc->refs);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- for (i = 0; tc->cache && (i < tc->entries); i++) {
|
||||
- if (!tc->cache[i].vaddr)
|
||||
- break;
|
||||
- fprintf(fp, "[%2d]: %lx %08x ", i, tc->cache[i].vaddr,
|
||||
- tc->cache[i].value);
|
||||
- if ((sp = value_search(tc->cache[i].vaddr, &offset))) {
|
||||
- fprintf(fp, "(%s+", sp->name);
|
||||
- switch (pc->output_radix)
|
||||
- {
|
||||
- case 10:
|
||||
- fprintf(fp, "%ld)", offset);
|
||||
- break;
|
||||
- case 16:
|
||||
- fprintf(fp, "%lx)", offset);
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- fprintf(fp, "\n");
|
||||
- }
|
||||
-
|
||||
- fprintf(fp,
|
||||
- "text_cache entries: %d index: %d hit rate: %ld%% (%ld of %ld)\n",
|
||||
- tc->entries, tc->index,
|
||||
- (tc->hits * 100)/(tc->refs ? tc->refs : 1),
|
||||
- tc->hits, tc->refs);
|
||||
-
|
||||
-}
|
||||
-
|
||||
-void
|
||||
-clear_text_value_cache(void)
|
||||
-{
|
||||
- int i;
|
||||
- struct text_cache *tc;
|
||||
-
|
||||
- tc = &text_cache;
|
||||
- tc->index = 0;
|
||||
-
|
||||
- for (i = 0; tc->cache && (i < tc->entries); i++) {
|
||||
- tc->cache[i].vaddr = 0;
|
||||
- tc->cache[i].value = 0;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* If a System.map file or a debug kernel was specified, the name hash
|
||||
* has been filled -- so sync up gdb's notion of symbol values with
|
||||
diff --git a/x86.c b/x86.c
|
||||
index a174bbc7737c..b36f44c54819 100644
|
||||
--- a/x86.c
|
||||
+++ b/x86.c
|
||||
@@ -474,17 +474,10 @@ db_get_value(addr, size, is_signed, bt)
|
||||
else
|
||||
GET_STACK_DATA(addr, data, size);
|
||||
} else {
|
||||
- if ((size == sizeof(int)) &&
|
||||
- text_value_cache(addr, 0, (uint32_t *)&value))
|
||||
- return value;
|
||||
-
|
||||
if (!readmem(addr, KVADDR, &value, size, "db_get_value",
|
||||
RETURN_ON_ERROR))
|
||||
error(FATAL, "db_get_value: read error: address: %lx\n",
|
||||
addr);
|
||||
-
|
||||
- if (size == sizeof(int))
|
||||
- text_value_cache(addr, value, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,25 +0,0 @@
|
||||
From f7e3b2d9b753793e230a5242974a111cdf139e49 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Thu, 30 Sep 2021 11:04:31 +0900
|
||||
Subject: [PATCH 27/27] .gitignore: add gdb-10.2 directory
|
||||
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
.gitignore | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index b39832fa71df..f391c5d340f9 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -11,6 +11,7 @@ crash.spec
|
||||
*.rpm
|
||||
gdb.files
|
||||
gdb-7.6/
|
||||
+gdb-10.2/
|
||||
extensions/defs.h
|
||||
extensions/*.so
|
||||
extensions/eppic
|
||||
--
|
||||
2.30.2
|
||||
|
111
crash.spec
111
crash.spec
@ -3,8 +3,8 @@
|
||||
#
|
||||
Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles
|
||||
Name: crash
|
||||
Version: 7.3.0
|
||||
Release: 5%{?dist}
|
||||
Version: 8.0.0
|
||||
Release: 1%{?dist}
|
||||
License: GPLv3
|
||||
Source0: https://github.com/crash-utility/crash/archive/crash-%{version}.tar.gz
|
||||
Source1: http://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.gz
|
||||
@ -18,58 +18,6 @@ Requires: binutils
|
||||
Provides: bundled(libiberty)
|
||||
Provides: bundled(gdb) = 10.2
|
||||
Patch0: lzo_snappy.patch
|
||||
Patch1: 0001-arm64-Add-lowercase-tcr_el1_t1sz.patch
|
||||
Patch2: 0002-Fix-for-kmem-s-S-option-on-Linux-5.7-and-later-kerne.patch
|
||||
Patch3: 0003-memory-Add-support-for-SECTION_TAINT_ZONE_DEVICE-fla.patch
|
||||
Patch4: 0004-memory-Fix-for-kmem-n-option-to-display-NID-correctl.patch
|
||||
Patch5: 0005-defs.h-Fix-the-value-of-TIF_SIGPENDING-macro.patch
|
||||
Patch6: 0006-MIPS32-64-Add-irq-command-support.patch
|
||||
Patch7: 0007-MIPS64-three-fixes-for-MIPS64-kernels.patch
|
||||
Patch8: 0008-extensions-eppic.mk-Enable-use-of-alternate-eppic-br.patch
|
||||
Patch9: 0009-list-add-O-option-for-specifying-head-node-offset.patch
|
||||
Patch10: 0010-Fix-waitq-command-for-Linux-4.13-and-later-kernels.patch
|
||||
Patch11: 0011-Fix-pvops-Xen-detection-for-kernels-v4.20.patch
|
||||
Patch12: 0012-Handle-task_struct-state-member-changes-for-kernels-.patch
|
||||
Patch13: 0013-arm64-rename-ARM64_PAGE_OFFSET_ACTUAL-to-ARM64_FLIP_.patch
|
||||
Patch14: 0014-arm64-assign-page_offset-with-VA_BITS-kernel-configu.patch
|
||||
Patch15: 0015-arm64-use-dedicated-bits-to-record-the-VA-space-layo.patch
|
||||
Patch16: 0016-arm64-implement-switchable-PTOV-VTOP-for-kernels-5.1.patch
|
||||
Patch17: 0001-kmem-Add-support-to-S-option-to-specify-a-range-of-C.patch
|
||||
Patch18: 0002-diskdump-Fail-readmem-early-if-dump-is-incomplete.patch
|
||||
Patch19: 0003-netdump-Permit-zero_excluded-for-incomplete-ELF-dump.patch
|
||||
Patch20: 0004-diskdump-Print-total-number-of-dumpable-pages.patch
|
||||
Patch21: 0005-diskdump-Introduce-read_pd.patch
|
||||
Patch22: 0006-x86_64-Fix-check-for-__per_cpu_offset-initialization.patch
|
||||
Patch23: 0007-arm64-Get-CPU-registers-from-ELF-notes-even-without-.patch
|
||||
Patch24: 0008-.gitignore-Add-cscope-ctags-compile_commands.json.patch
|
||||
Patch25: 0009-ppc64-Add-MMU-type-info-in-machdep-command.patch
|
||||
Patch26: 0010-mod-fix-module-object-file-lookup.patch
|
||||
Patch27: 0011-diskdump-Add-support-for-reading-dumpfiles-compresse.patch
|
||||
Patch28: 0012-Update-to-gdb-10.2.patch
|
||||
Patch29: 0013-crash_get_nr_cpus-get-nr_cpus-from-the-dumps.patch
|
||||
Patch30: 0014-whatis-m-fix-duplications-in-the-output.patch
|
||||
Patch31: 0015-Fix-reduced-output-of-bt-command.patch
|
||||
Patch32: 0016-crash_taget-fetch_registers-support.patch
|
||||
Patch33: 0017-Allow-gdb-disassemble-command-for-relocated-kernel.patch
|
||||
Patch34: 0018-vmware-backend-honor-silence-flag.patch
|
||||
Patch35: 0019-vmware_guestdump-add-debugging-of-the-init-function.patch
|
||||
Patch36: 0020-Do-not-adjust-addr-by-relocate-offset-KASLR.patch
|
||||
Patch37: 0021-Fix-the-failure-of-reporting-vmcore-and-vmlinux-do-n.patch
|
||||
Patch38: 0022-x86_64_irq_eframe_link_init-Fix-wrong-instruction-se.patch
|
||||
Patch39: 0023-Add-kernel-version-dependent-check-for-getting-lengt.patch
|
||||
Patch40: 0024-Set-gdb-max-value-size-to-be-unlimited.patch
|
||||
Patch41: 0025-Fix-tab-completion-issues.patch
|
||||
Patch42: 0026-Remove-text-value-cache-code.patch
|
||||
Patch43: 0027-.gitignore-add-gdb-10.2-directory.patch
|
||||
Patch44: 0001-symbols-Implement-install-and-remove-operations-for-.patch
|
||||
Patch45: 0002-symbols-Integrate-symbol_search-with-mod_symname_has.patch
|
||||
Patch46: 0003-symbols-Extend-symname_hash_search-with-hash-table-s.patch
|
||||
Patch47: 0004-symbols-Intergrate-symbol_exists-with-mod_symname_ha.patch
|
||||
Patch48: 0005-symbols-Sync-module-symbols-into-mod_symtable-whenev.patch
|
||||
Patch49: 0006-symbols-Refactor-SYMNAME_HASH_INDEX-macro-to-be-a-fu.patch
|
||||
Patch50: 0007-symbols-Add-mod_symname_hash-table-dump-to-help-s.patch
|
||||
Patch51: 0008-arm64-Use-VA_BITS-for-page_offset-calculation.patch
|
||||
Patch52: 0009-Handle-task_struct-cpu-member-changes-for-kernels-5..patch
|
||||
|
||||
%description
|
||||
The core analysis suite is a self-contained tool that can be used to
|
||||
@ -90,58 +38,6 @@ offered by Mission Critical Linux, or the LKCD kernel patch.
|
||||
%prep
|
||||
%setup -n %{name}-%{version} -q
|
||||
%patch0 -p1 -b lzo_snappy.patch
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
%patch11 -p1
|
||||
%patch12 -p1
|
||||
%patch13 -p1
|
||||
%patch14 -p1
|
||||
%patch15 -p1
|
||||
%patch16 -p1
|
||||
%patch17 -p1
|
||||
%patch18 -p1
|
||||
%patch19 -p1
|
||||
%patch20 -p1
|
||||
%patch21 -p1
|
||||
%patch22 -p1
|
||||
%patch23 -p1
|
||||
%patch24 -p1
|
||||
%patch25 -p1
|
||||
%patch26 -p1
|
||||
%patch27 -p1
|
||||
%patch28 -p1
|
||||
%patch29 -p1
|
||||
%patch30 -p1
|
||||
%patch31 -p1
|
||||
%patch32 -p1
|
||||
%patch33 -p1
|
||||
%patch34 -p1
|
||||
%patch35 -p1
|
||||
%patch36 -p1
|
||||
%patch37 -p1
|
||||
%patch38 -p1
|
||||
%patch39 -p1
|
||||
%patch40 -p1
|
||||
%patch41 -p1
|
||||
%patch42 -p1
|
||||
%patch43 -p1
|
||||
%patch44 -p1
|
||||
%patch45 -p1
|
||||
%patch46 -p1
|
||||
%patch47 -p1
|
||||
%patch48 -p1
|
||||
%patch49 -p1
|
||||
%patch50 -p1
|
||||
%patch51 -p1
|
||||
%patch52 -p1
|
||||
|
||||
%build
|
||||
# This package has an internal copy of GDB which has broken configure code for
|
||||
@ -175,6 +71,9 @@ cp -p defs.h %{buildroot}%{_includedir}/crash
|
||||
%{_includedir}/*
|
||||
|
||||
%changelog
|
||||
* Wed Nov 24 2021 Lianbo Jiang <lijiang@redhat.com> - 8.0.0-1
|
||||
- Rebase to upstream 8.0.0
|
||||
|
||||
* Sat Nov 06 2021 Lianbo Jiang <lijiang@redhat.com> - 7.3.0-5
|
||||
- Update to the latest upstream: commit <68870c83d299>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
--- crash-7.3.0/diskdump.c.orig
|
||||
+++ crash-7.3.0/diskdump.c
|
||||
--- crash-8.0.0/diskdump.c.orig
|
||||
+++ crash-8.0.0/diskdump.c
|
||||
@@ -23,6 +23,8 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
@ -9,8 +9,8 @@
|
||||
#include "defs.h"
|
||||
#include "diskdump.h"
|
||||
#include "xen_dom0.h"
|
||||
--- crash-7.3.0/Makefile.orig
|
||||
+++ crash-7.3.0/Makefile
|
||||
--- crash-8.0.0/Makefile.orig
|
||||
+++ crash-8.0.0/Makefile
|
||||
@@ -228,7 +228,7 @@ all: make_configure
|
||||
gdb_merge: force
|
||||
@if [ ! -f ${GDB}/README ]; then \
|
||||
|
@ -1,442 +0,0 @@
|
||||
From a5531b24750e7949c35640d996ea14c0587938bc Mon Sep 17 00:00:00 2001
|
||||
From: John Ogness <john.ogness@linutronix.de>
|
||||
Date: Fri, 20 Nov 2020 05:56:59 +0000
|
||||
Subject: [PATCH 1/2] printk: add support for lockless ringbuffer
|
||||
|
||||
Linux 5.10 introduces a new lockless ringbuffer. The new ringbuffer
|
||||
is structured completely different to the previous iterations.
|
||||
Add support for dumping the ringbuffer with the "log" command.
|
||||
The new ringbuffer is detected based on the availability of
|
||||
the "prb" symbol.
|
||||
|
||||
Signed-off-by: John Ogness <john.ogness@linutronix.de>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
Makefile | 5 ++
|
||||
defs.h | 30 +++++++
|
||||
kernel.c | 7 +-
|
||||
printk.c | 256 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
symbols.c | 27 ++++++
|
||||
5 files changed, 324 insertions(+), 1 deletion(-)
|
||||
create mode 100644 printk.c
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index d1857190c2fb..f66eba7418d1 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -61,6 +61,7 @@ VMWARE_HFILES=vmware_vmss.h
|
||||
|
||||
CFILES=main.c tools.c global_data.c memory.c filesys.c help.c task.c \
|
||||
kernel.c test.c gdb_interface.c configure.c net.c dev.c bpf.c \
|
||||
+ printk.c \
|
||||
alpha.c x86.c ppc.c ia64.c s390.c s390x.c s390dbf.c ppc64.c x86_64.c \
|
||||
arm.c arm64.c mips.c sparc64.c \
|
||||
extensions.c remote.c va_server.c va_server_v1.c symbols.c cmdline.c \
|
||||
@@ -80,6 +81,7 @@ SOURCE_FILES=${CFILES} ${GENERIC_HFILES} ${MCORE_HFILES} \
|
||||
|
||||
OBJECT_FILES=main.o tools.o global_data.o memory.o filesys.o help.o task.o \
|
||||
build_data.o kernel.o test.o gdb_interface.o net.o dev.o bpf.o \
|
||||
+ printk.o \
|
||||
alpha.o x86.o ppc.o ia64.o s390.o s390x.o s390dbf.o ppc64.o x86_64.o \
|
||||
arm.o arm64.o mips.o sparc64.o \
|
||||
extensions.o remote.o va_server.o va_server_v1.o symbols.o cmdline.o \
|
||||
@@ -363,6 +365,9 @@ task.o: ${GENERIC_HFILES} task.c
|
||||
kernel.o: ${GENERIC_HFILES} kernel.c
|
||||
${CC} -c ${CRASH_CFLAGS} kernel.c ${WARNING_OPTIONS} ${WARNING_ERROR}
|
||||
|
||||
+printk.o: ${GENERIC_HFILES} printk.c
|
||||
+ ${CC} -c ${CRASH_CFLAGS} printk.c ${WARNING_OPTIONS} ${WARNING_ERROR}
|
||||
+
|
||||
gdb_interface.o: ${GENERIC_HFILES} gdb_interface.c
|
||||
${CC} -c ${CRASH_CFLAGS} gdb_interface.c ${WARNING_OPTIONS} ${WARNING_ERROR}
|
||||
|
||||
diff --git a/defs.h b/defs.h
|
||||
index 95949507cae4..e1a18e9d0b4d 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -2106,6 +2106,28 @@ struct offset_table { /* stash of commonly-used offsets */
|
||||
long irq_common_data_affinity;
|
||||
long irq_desc_irq_common_data;
|
||||
long uts_namespace_name;
|
||||
+ long printk_info_seq;
|
||||
+ long printk_info_ts_nsec;
|
||||
+ long printk_info_text_len;
|
||||
+ long printk_info_level;
|
||||
+ long printk_info_caller_id;
|
||||
+ long printk_info_dev_info;
|
||||
+ long dev_printk_info_subsystem;
|
||||
+ long dev_printk_info_device;
|
||||
+ long prb_desc_ring;
|
||||
+ long prb_text_data_ring;
|
||||
+ long prb_desc_ring_count_bits;
|
||||
+ long prb_desc_ring_descs;
|
||||
+ long prb_desc_ring_infos;
|
||||
+ long prb_desc_ring_head_id;
|
||||
+ long prb_desc_ring_tail_id;
|
||||
+ long prb_desc_state_var;
|
||||
+ long prb_desc_text_blk_lpos;
|
||||
+ long prb_data_blk_lpos_begin;
|
||||
+ long prb_data_blk_lpos_next;
|
||||
+ long prb_data_ring_size_bits;
|
||||
+ long prb_data_ring_data;
|
||||
+ long atomic_long_t_counter;
|
||||
};
|
||||
|
||||
struct size_table { /* stash of commonly-used sizes */
|
||||
@@ -2265,6 +2287,9 @@ struct size_table { /* stash of commonly-used sizes */
|
||||
long xa_node;
|
||||
long zram_table_entry;
|
||||
long irq_common_data;
|
||||
+ long printk_info;
|
||||
+ long printk_ringbuffer;
|
||||
+ long prb_desc;
|
||||
};
|
||||
|
||||
struct array_table {
|
||||
@@ -6696,6 +6721,11 @@ int vmware_guestdump_memory_dump(FILE *);
|
||||
*/
|
||||
int calc_kaslr_offset(ulong *, ulong *);
|
||||
|
||||
+/*
|
||||
+ * printk.c
|
||||
+ */
|
||||
+void dump_lockless_record_log(int);
|
||||
+
|
||||
/*
|
||||
* gnu_binutils.c
|
||||
*/
|
||||
diff --git a/kernel.c b/kernel.c
|
||||
index 98716372c8be..e722ff941527 100644
|
||||
--- a/kernel.c
|
||||
+++ b/kernel.c
|
||||
@@ -5042,6 +5042,11 @@ dump_log(int msg_flags)
|
||||
struct syment *nsp;
|
||||
int log_wrap, loglevel, log_buf_len;
|
||||
|
||||
+ if (kernel_symbol_exists("prb")) {
|
||||
+ dump_lockless_record_log(msg_flags);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (kernel_symbol_exists("log_first_idx") &&
|
||||
kernel_symbol_exists("log_next_idx")) {
|
||||
dump_variable_length_record_log(msg_flags);
|
||||
@@ -5289,7 +5294,7 @@ dump_log_entry(char *logptr, int msg_flags)
|
||||
}
|
||||
|
||||
/*
|
||||
- * Handle the new variable-length-record log_buf.
|
||||
+ * Handle the variable-length-record log_buf.
|
||||
*/
|
||||
static void
|
||||
dump_variable_length_record_log(int msg_flags)
|
||||
diff --git a/printk.c b/printk.c
|
||||
new file mode 100644
|
||||
index 000000000000..f6d54ce9d0d8
|
||||
--- /dev/null
|
||||
+++ b/printk.c
|
||||
@@ -0,0 +1,256 @@
|
||||
+#include "defs.h"
|
||||
+#include <ctype.h>
|
||||
+
|
||||
+#define DESC_SV_BITS (sizeof(unsigned long) * 8)
|
||||
+#define DESC_COMMITTED_MASK (1UL << (DESC_SV_BITS - 1))
|
||||
+#define DESC_REUSE_MASK (1UL << (DESC_SV_BITS - 2))
|
||||
+#define DESC_FLAGS_MASK (DESC_COMMITTED_MASK | DESC_REUSE_MASK)
|
||||
+#define DESC_ID_MASK (~DESC_FLAGS_MASK)
|
||||
+
|
||||
+/* convenience struct for passing many values to helper functions */
|
||||
+struct prb_map {
|
||||
+ char *prb;
|
||||
+
|
||||
+ char *desc_ring;
|
||||
+ unsigned long desc_ring_count;
|
||||
+ char *descs;
|
||||
+ char *infos;
|
||||
+
|
||||
+ char *text_data_ring;
|
||||
+ unsigned long text_data_ring_size;
|
||||
+ char *text_data;
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+init_offsets(void)
|
||||
+{
|
||||
+ char *n;
|
||||
+
|
||||
+ n = "printk_info";
|
||||
+ STRUCT_SIZE_INIT(printk_info, n);
|
||||
+ MEMBER_OFFSET_INIT(printk_info_seq, n, "seq");
|
||||
+ MEMBER_OFFSET_INIT(printk_info_ts_nsec, n, "ts_nsec");
|
||||
+ MEMBER_OFFSET_INIT(printk_info_text_len, n, "text_len");
|
||||
+ MEMBER_OFFSET_INIT(printk_info_level, n, "level");
|
||||
+ MEMBER_OFFSET_INIT(printk_info_caller_id, n, "caller_id");
|
||||
+ MEMBER_OFFSET_INIT(printk_info_dev_info, n, "dev_info");
|
||||
+
|
||||
+ n = "dev_printk_info";
|
||||
+ MEMBER_OFFSET_INIT(dev_printk_info_subsystem, n, "subsystem");
|
||||
+ MEMBER_OFFSET_INIT(dev_printk_info_device, n, "device");
|
||||
+
|
||||
+ n = "printk_ringbuffer";
|
||||
+ STRUCT_SIZE_INIT(printk_ringbuffer, n);
|
||||
+ MEMBER_OFFSET_INIT(prb_desc_ring, n, "desc_ring");
|
||||
+ MEMBER_OFFSET_INIT(prb_text_data_ring, n, "text_data_ring");
|
||||
+
|
||||
+ n = "prb_desc_ring";
|
||||
+ MEMBER_OFFSET_INIT(prb_desc_ring_count_bits, n, "count_bits");
|
||||
+ MEMBER_OFFSET_INIT(prb_desc_ring_descs, n, "descs");
|
||||
+ MEMBER_OFFSET_INIT(prb_desc_ring_infos, n, "infos");
|
||||
+ MEMBER_OFFSET_INIT(prb_desc_ring_head_id, n, "head_id");
|
||||
+ MEMBER_OFFSET_INIT(prb_desc_ring_tail_id, n, "tail_id");
|
||||
+
|
||||
+ n = "prb_desc";
|
||||
+ STRUCT_SIZE_INIT(prb_desc, n);
|
||||
+ MEMBER_OFFSET_INIT(prb_desc_state_var, n, "state_var");
|
||||
+ MEMBER_OFFSET_INIT(prb_desc_text_blk_lpos, n, "text_blk_lpos");
|
||||
+
|
||||
+ n = "prb_data_blk_lpos";
|
||||
+ MEMBER_OFFSET_INIT(prb_data_blk_lpos_begin, n, "begin");
|
||||
+ MEMBER_OFFSET_INIT(prb_data_blk_lpos_next, n, "next");
|
||||
+
|
||||
+ n = "prb_data_ring";
|
||||
+ MEMBER_OFFSET_INIT(prb_data_ring_size_bits, n, "size_bits");
|
||||
+ MEMBER_OFFSET_INIT(prb_data_ring_data, n, "data");
|
||||
+
|
||||
+ n = "atomic_long_t";
|
||||
+ MEMBER_OFFSET_INIT(atomic_long_t_counter, n, "counter");
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+dump_record(struct prb_map *m, unsigned long id, int msg_flags)
|
||||
+{
|
||||
+ unsigned short text_len;
|
||||
+ unsigned long state_var;
|
||||
+ unsigned int caller_id;
|
||||
+ unsigned char level;
|
||||
+ unsigned long begin;
|
||||
+ unsigned long next;
|
||||
+ char buf[BUFSIZE];
|
||||
+ uint64_t ts_nsec;
|
||||
+ ulonglong nanos;
|
||||
+ ulonglong seq;
|
||||
+ int ilen = 0, i;
|
||||
+ char *desc, *info, *text, *p;
|
||||
+ ulong rem;
|
||||
+
|
||||
+ desc = m->descs + ((id % m->desc_ring_count) * SIZE(prb_desc));
|
||||
+
|
||||
+ /* skip non-committed record */
|
||||
+ state_var = ULONG(desc + OFFSET(prb_desc_state_var) +
|
||||
+ OFFSET(atomic_long_t_counter));
|
||||
+ if ((state_var & DESC_FLAGS_MASK) != DESC_COMMITTED_MASK)
|
||||
+ return;
|
||||
+
|
||||
+ info = m->infos + ((id % m->desc_ring_count) * SIZE(printk_info));
|
||||
+
|
||||
+ seq = ULONGLONG(info + OFFSET(printk_info_seq));
|
||||
+ caller_id = UINT(info + OFFSET(printk_info_caller_id));
|
||||
+ if (CRASHDEBUG(1))
|
||||
+ fprintf(fp, "seq: %llu caller_id: %x (%s: %u)\n", seq, caller_id,
|
||||
+ caller_id & 0x80000000 ? "cpu" : "pid", caller_id & ~0x80000000);
|
||||
+
|
||||
+ text_len = USHORT(info + OFFSET(printk_info_text_len));
|
||||
+
|
||||
+ begin = ULONG(desc + OFFSET(prb_desc_text_blk_lpos) +
|
||||
+ OFFSET(prb_data_blk_lpos_begin)) %
|
||||
+ m->text_data_ring_size;
|
||||
+ next = ULONG(desc + OFFSET(prb_desc_text_blk_lpos) +
|
||||
+ OFFSET(prb_data_blk_lpos_next)) %
|
||||
+ m->text_data_ring_size;
|
||||
+
|
||||
+ /* skip data-less text blocks */
|
||||
+ if (begin == next)
|
||||
+ goto out;
|
||||
+
|
||||
+ if ((msg_flags & SHOW_LOG_TEXT) == 0) {
|
||||
+ ts_nsec = ULONGLONG(info + OFFSET(printk_info_ts_nsec));
|
||||
+ nanos = (ulonglong)ts_nsec / (ulonglong)1000000000;
|
||||
+ rem = (ulonglong)ts_nsec % (ulonglong)1000000000;
|
||||
+ if (msg_flags & SHOW_LOG_CTIME) {
|
||||
+ time_t t = kt->boot_date.tv_sec + nanos;
|
||||
+ sprintf(buf, "[%s] ", ctime_tz(&t));
|
||||
+ } else
|
||||
+ sprintf(buf, "[%5lld.%06ld] ", nanos, rem/1000);
|
||||
+
|
||||
+ ilen += strlen(buf);
|
||||
+ fprintf(fp, "%s", buf);
|
||||
+ }
|
||||
+
|
||||
+ if (msg_flags & SHOW_LOG_LEVEL) {
|
||||
+ level = UCHAR(info + OFFSET(printk_info_level)) >> 5;
|
||||
+ sprintf(buf, "<%x>", level);
|
||||
+ ilen += strlen(buf);
|
||||
+ fprintf(fp, "%s", buf);
|
||||
+ }
|
||||
+
|
||||
+ /* handle wrapping data block */
|
||||
+ if (begin > next)
|
||||
+ begin = 0;
|
||||
+
|
||||
+ /* skip over descriptor ID */
|
||||
+ begin += sizeof(unsigned long);
|
||||
+
|
||||
+ /* handle truncated messages */
|
||||
+ if (next - begin < text_len)
|
||||
+ text_len = next - begin;
|
||||
+
|
||||
+ text = m->text_data + begin;
|
||||
+
|
||||
+ for (i = 0, p = text; i < text_len; i++, p++) {
|
||||
+ if (*p == '\n')
|
||||
+ fprintf(fp, "\n%s", space(ilen));
|
||||
+ else if (isprint(*p) || isspace(*p))
|
||||
+ fputc(*p, fp);
|
||||
+ else
|
||||
+ fputc('.', fp);
|
||||
+ }
|
||||
+
|
||||
+ if (msg_flags & SHOW_LOG_DICT) {
|
||||
+ text = info + OFFSET(printk_info_dev_info) +
|
||||
+ OFFSET(dev_printk_info_subsystem);
|
||||
+ if (strlen(text))
|
||||
+ fprintf(fp, "\n%sSUBSYSTEM=%s", space(ilen), text);
|
||||
+
|
||||
+ text = info + OFFSET(printk_info_dev_info) +
|
||||
+ OFFSET(dev_printk_info_device);
|
||||
+ if (strlen(text))
|
||||
+ fprintf(fp, "\n%sDEVICE=%s", space(ilen), text);
|
||||
+ }
|
||||
+out:
|
||||
+ fprintf(fp, "\n");
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Handle the lockless printk_ringbuffer.
|
||||
+ */
|
||||
+void
|
||||
+dump_lockless_record_log(int msg_flags)
|
||||
+{
|
||||
+ unsigned long head_id;
|
||||
+ unsigned long tail_id;
|
||||
+ unsigned long kaddr;
|
||||
+ unsigned long id;
|
||||
+ struct prb_map m;
|
||||
+
|
||||
+ if (INVALID_SIZE(printk_info))
|
||||
+ init_offsets();
|
||||
+
|
||||
+ /* setup printk_ringbuffer */
|
||||
+ get_symbol_data("prb", sizeof(char *), &kaddr);
|
||||
+ m.prb = GETBUF(SIZE(printk_ringbuffer));
|
||||
+ if (!readmem(kaddr, KVADDR, m.prb, SIZE(printk_ringbuffer),
|
||||
+ "printk_ringbuffer contents", RETURN_ON_ERROR|QUIET)) {
|
||||
+ error(WARNING, "\ncannot read printk_ringbuffer contents\n");
|
||||
+ goto out_prb;
|
||||
+ }
|
||||
+
|
||||
+ /* setup descriptor ring */
|
||||
+ m.desc_ring = m.prb + OFFSET(prb_desc_ring);
|
||||
+ m.desc_ring_count = 1 << UINT(m.desc_ring + OFFSET(prb_desc_ring_count_bits));
|
||||
+
|
||||
+ kaddr = ULONG(m.desc_ring + OFFSET(prb_desc_ring_descs));
|
||||
+ m.descs = GETBUF(SIZE(prb_desc) * m.desc_ring_count);
|
||||
+ if (!readmem(kaddr, KVADDR, m.descs, SIZE(prb_desc) * m.desc_ring_count,
|
||||
+ "prb_desc_ring contents", RETURN_ON_ERROR|QUIET)) {
|
||||
+ error(WARNING, "\ncannot read prb_desc_ring contents\n");
|
||||
+ goto out_descs;
|
||||
+ }
|
||||
+
|
||||
+ kaddr = ULONG(m.desc_ring + OFFSET(prb_desc_ring_infos));
|
||||
+ m.infos = GETBUF(SIZE(printk_info) * m.desc_ring_count);
|
||||
+ if (!readmem(kaddr, KVADDR, m.infos, SIZE(printk_info) * m.desc_ring_count,
|
||||
+ "prb_info_ring contents", RETURN_ON_ERROR|QUIET)) {
|
||||
+ error(WARNING, "\ncannot read prb_info_ring contents\n");
|
||||
+ goto out_infos;
|
||||
+ }
|
||||
+
|
||||
+ /* setup text data ring */
|
||||
+ m.text_data_ring = m.prb + OFFSET(prb_text_data_ring);
|
||||
+ m.text_data_ring_size = 1 << UINT(m.text_data_ring + OFFSET(prb_data_ring_size_bits));
|
||||
+
|
||||
+ kaddr = ULONG(m.text_data_ring + OFFSET(prb_data_ring_data));
|
||||
+ m.text_data = GETBUF(m.text_data_ring_size);
|
||||
+ if (!readmem(kaddr, KVADDR, m.text_data, m.text_data_ring_size,
|
||||
+ "prb_text_data_ring contents", RETURN_ON_ERROR|QUIET)) {
|
||||
+ error(WARNING, "\ncannot read prb_text_data_ring contents\n");
|
||||
+ goto out_text_data;
|
||||
+ }
|
||||
+
|
||||
+ /* ready to go */
|
||||
+
|
||||
+ tail_id = ULONG(m.desc_ring + OFFSET(prb_desc_ring_tail_id) +
|
||||
+ OFFSET(atomic_long_t_counter));
|
||||
+ head_id = ULONG(m.desc_ring + OFFSET(prb_desc_ring_head_id) +
|
||||
+ OFFSET(atomic_long_t_counter));
|
||||
+
|
||||
+ hq_open();
|
||||
+
|
||||
+ for (id = tail_id; id != head_id; id = (id + 1) & DESC_ID_MASK)
|
||||
+ dump_record(&m, id, msg_flags);
|
||||
+
|
||||
+ /* dump head record */
|
||||
+ dump_record(&m, id, msg_flags);
|
||||
+
|
||||
+ hq_close();
|
||||
+
|
||||
+out_text_data:
|
||||
+ FREEBUF(m.text_data);
|
||||
+out_infos:
|
||||
+ FREEBUF(m.infos);
|
||||
+out_descs:
|
||||
+ FREEBUF(m.descs);
|
||||
+out_prb:
|
||||
+ FREEBUF(m.prb);
|
||||
+}
|
||||
diff --git a/symbols.c b/symbols.c
|
||||
index b2f4eb5402d1..a51078d58e6b 100644
|
||||
--- a/symbols.c
|
||||
+++ b/symbols.c
|
||||
@@ -10426,6 +10426,30 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||
OFFSET(log_level));
|
||||
fprintf(fp, " log_flags_level: %ld\n",
|
||||
OFFSET(log_flags_level));
|
||||
+
|
||||
+ fprintf(fp, " printk_info_seq: %ld\n", OFFSET(printk_info_seq));
|
||||
+ fprintf(fp, " printk_info_ts_nseq: %ld\n", OFFSET(printk_info_ts_nsec));
|
||||
+ fprintf(fp, " printk_info_text_len: %ld\n", OFFSET(printk_info_text_len));
|
||||
+ fprintf(fp, " printk_info_level: %ld\n", OFFSET(printk_info_level));
|
||||
+ fprintf(fp, " printk_info_caller_id: %ld\n", OFFSET(printk_info_caller_id));
|
||||
+ fprintf(fp, " printk_info_dev_info: %ld\n", OFFSET(printk_info_dev_info));
|
||||
+ fprintf(fp, " dev_printk_info_subsystem: %ld\n", OFFSET(dev_printk_info_subsystem));
|
||||
+ fprintf(fp, " dev_printk_info_device: %ld\n", OFFSET(dev_printk_info_device));
|
||||
+ fprintf(fp, " prb_desc_ring: %ld\n", OFFSET(prb_desc_ring));
|
||||
+ fprintf(fp, " prb_text_data_ring: %ld\n", OFFSET(prb_text_data_ring));
|
||||
+ fprintf(fp, " prb_desc_ring_count_bits: %ld\n", OFFSET(prb_desc_ring_count_bits));
|
||||
+ fprintf(fp, " prb_desc_ring_descs: %ld\n", OFFSET(prb_desc_ring_descs));
|
||||
+ fprintf(fp, " prb_desc_ring_infos: %ld\n", OFFSET(prb_desc_ring_infos));
|
||||
+ fprintf(fp, " prb_desc_ring_head_id: %ld\n", OFFSET(prb_desc_ring_head_id));
|
||||
+ fprintf(fp, " prb_desc_ring_tail_id: %ld\n", OFFSET(prb_desc_ring_tail_id));
|
||||
+ fprintf(fp, " prb_desc_state_var: %ld\n", OFFSET(prb_desc_state_var));
|
||||
+ fprintf(fp, " prb_desc_text_blk_lpos: %ld\n", OFFSET(prb_desc_text_blk_lpos));
|
||||
+ fprintf(fp, " prb_data_blk_lpos_begin: %ld\n", OFFSET(prb_data_blk_lpos_begin));
|
||||
+ fprintf(fp, " prb_data_blk_lpos_next: %ld\n", OFFSET(prb_data_blk_lpos_next));
|
||||
+ fprintf(fp, " prb_data_ring_size_bits: %ld\n", OFFSET(prb_data_ring_size_bits));
|
||||
+ fprintf(fp, " prb_data_ring_data: %ld\n", OFFSET(prb_data_ring_data));
|
||||
+ fprintf(fp, " atomit_long_t_counter: %ld\n", OFFSET(atomic_long_t_counter));
|
||||
+
|
||||
fprintf(fp, " sched_rt_entity_my_q: %ld\n",
|
||||
OFFSET(sched_rt_entity_my_q));
|
||||
fprintf(fp, " task_group_parent: %ld\n",
|
||||
@@ -10850,6 +10874,9 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||
SIZE(xarray));
|
||||
fprintf(fp, " xa_node: %ld\n",
|
||||
SIZE(xa_node));
|
||||
+ fprintf(fp, " printk_info: %ld\n", SIZE(printk_info));
|
||||
+ fprintf(fp, " printk_ringbuffer: %ld\n", SIZE(printk_ringbuffer));
|
||||
+ fprintf(fp, " prb_desc: %ld\n", SIZE(prb_desc));
|
||||
|
||||
|
||||
fprintf(fp, "\n array_table:\n");
|
||||
--
|
||||
2.17.1
|
||||
|
@ -1,100 +0,0 @@
|
||||
From 71e159c64000467e94e08aefc144f5e1cdaa4aa0 Mon Sep 17 00:00:00 2001
|
||||
From: John Ogness <john.ogness@linutronix.de>
|
||||
Date: Wed, 25 Nov 2020 05:27:53 +0106
|
||||
Subject: [PATCH 2/2] printk: use committed/finalized state values
|
||||
|
||||
An addendum to the previous crash commit a5531b24750e.
|
||||
The ringbuffer entries use 2 state values (committed and finalized)
|
||||
rather than a single flag to represent being available for reading.
|
||||
Copy the definitions and state lookup function directly from the
|
||||
kernel source and use the new states.
|
||||
|
||||
Signed-off-by: John Ogness <john.ogness@linutronix.de>
|
||||
Signed-off-by: Nikolay Borisov <nborisov@suse.com>
|
||||
---
|
||||
printk.c | 48 +++++++++++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 41 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/printk.c b/printk.c
|
||||
index f6d54ce9d0d8..8658016e65bf 100644
|
||||
--- a/printk.c
|
||||
+++ b/printk.c
|
||||
@@ -1,12 +1,6 @@
|
||||
#include "defs.h"
|
||||
#include <ctype.h>
|
||||
|
||||
-#define DESC_SV_BITS (sizeof(unsigned long) * 8)
|
||||
-#define DESC_COMMITTED_MASK (1UL << (DESC_SV_BITS - 1))
|
||||
-#define DESC_REUSE_MASK (1UL << (DESC_SV_BITS - 2))
|
||||
-#define DESC_FLAGS_MASK (DESC_COMMITTED_MASK | DESC_REUSE_MASK)
|
||||
-#define DESC_ID_MASK (~DESC_FLAGS_MASK)
|
||||
-
|
||||
/* convenience struct for passing many values to helper functions */
|
||||
struct prb_map {
|
||||
char *prb;
|
||||
@@ -21,6 +15,44 @@ struct prb_map {
|
||||
char *text_data;
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * desc_state and DESC_* definitions taken from kernel source:
|
||||
+ *
|
||||
+ * kernel/printk/printk_ringbuffer.h
|
||||
+ */
|
||||
+
|
||||
+/* The possible responses of a descriptor state-query. */
|
||||
+enum desc_state {
|
||||
+ desc_miss = -1, /* ID mismatch (pseudo state) */
|
||||
+ desc_reserved = 0x0, /* reserved, in use by writer */
|
||||
+ desc_committed = 0x1, /* committed by writer, could get reopened */
|
||||
+ desc_finalized = 0x2, /* committed, no further modification allowed */
|
||||
+ desc_reusable = 0x3, /* free, not yet used by any writer */
|
||||
+};
|
||||
+
|
||||
+#define DESC_SV_BITS (sizeof(unsigned long) * 8)
|
||||
+#define DESC_FLAGS_SHIFT (DESC_SV_BITS - 2)
|
||||
+#define DESC_FLAGS_MASK (3UL << DESC_FLAGS_SHIFT)
|
||||
+#define DESC_STATE(sv) (3UL & (sv >> DESC_FLAGS_SHIFT))
|
||||
+#define DESC_ID_MASK (~DESC_FLAGS_MASK)
|
||||
+#define DESC_ID(sv) ((sv) & DESC_ID_MASK)
|
||||
+
|
||||
+/*
|
||||
+ * get_desc_state() taken from kernel source:
|
||||
+ *
|
||||
+ * kernel/printk/printk_ringbuffer.c
|
||||
+ */
|
||||
+
|
||||
+/* Query the state of a descriptor. */
|
||||
+static enum desc_state get_desc_state(unsigned long id,
|
||||
+ unsigned long state_val)
|
||||
+{
|
||||
+ if (id != DESC_ID(state_val))
|
||||
+ return desc_miss;
|
||||
+
|
||||
+ return DESC_STATE(state_val);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
init_offsets(void)
|
||||
{
|
||||
@@ -74,6 +106,7 @@ dump_record(struct prb_map *m, unsigned long id, int msg_flags)
|
||||
unsigned short text_len;
|
||||
unsigned long state_var;
|
||||
unsigned int caller_id;
|
||||
+ enum desc_state state;
|
||||
unsigned char level;
|
||||
unsigned long begin;
|
||||
unsigned long next;
|
||||
@@ -90,7 +123,8 @@ dump_record(struct prb_map *m, unsigned long id, int msg_flags)
|
||||
/* skip non-committed record */
|
||||
state_var = ULONG(desc + OFFSET(prb_desc_state_var) +
|
||||
OFFSET(atomic_long_t_counter));
|
||||
- if ((state_var & DESC_FLAGS_MASK) != DESC_COMMITTED_MASK)
|
||||
+ state = get_desc_state(id, state_var);
|
||||
+ if (state != desc_committed && state != desc_finalized)
|
||||
return;
|
||||
|
||||
info = m->infos + ((id % m->desc_ring_count) * SIZE(printk_info));
|
||||
--
|
||||
2.17.1
|
||||
|
2
sources
2
sources
@ -1,2 +1,2 @@
|
||||
SHA512 (crash-7.3.0.tar.gz) = bc288821892c3d7ecbf192d9fe6ea9e73216f8074a24d12a00fbcaf967a1faa38ee69c4a5a97aa93bf75426293f5b275f5ab496c154b4e7be265ba0e263b2bc8
|
||||
SHA512 (crash-8.0.0.tar.gz) = c52afab6c8187dc0c44a13b2a5b33bd7df33d9ee12bcecc6b7e94e8bc98d9470c134cb0fbe941b750f36a66028aad718bfd6f1a00524ad38ce43d1f278048a3b
|
||||
SHA512 (gdb-10.2.tar.gz) = aa89caf47c1c84366020377d47e7c51ddbc48e5b7686f244e38797c8eb88411cf57fcdc37eb669961efb41ceeac4181747f429625fd1acce7712cb9a1fea9c41
|
||||
|
Loading…
Reference in New Issue
Block a user