import CS crash-7.3.2-8.el8
This commit is contained in:
parent
35805d71a2
commit
e30355f227
@ -0,0 +1,52 @@
|
|||||||
|
From 040a56e9f9d0df15a2f8161ed3a0a907d70dda03 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Date: Wed, 10 May 2023 16:09:03 +0900
|
||||||
|
Subject: [PATCH 1/6] Fix kernel version macros for revision numbers over 255
|
||||||
|
|
||||||
|
The current comparison macros for kernel version shift minor number only
|
||||||
|
8 bits. This can cause an unexpected result on kernels with revision
|
||||||
|
number over 255, e.g. Linux 4.14.314.
|
||||||
|
|
||||||
|
In fact, on Linux 4.14.314 for x86_64 without CONFIG_RANDOMIZE_BASE=y
|
||||||
|
(KASLR), the following condition became false in x86_64_init().
|
||||||
|
|
||||||
|
((THIS_KERNEL_VERSION >= LINUX(4,14,84)) &&
|
||||||
|
(THIS_KERNEL_VERSION < LINUX(4,15,0)))
|
||||||
|
|
||||||
|
As a result, crash used a wrong hard-coded value for PAGE_OFFSET and
|
||||||
|
failed to start a session with the following seek error.
|
||||||
|
|
||||||
|
crash: seek error: physical address: 200e000 type: "pud page"
|
||||||
|
|
||||||
|
Shift the major and minor number by 24 and 16 bits respectively to fix
|
||||||
|
this issue.
|
||||||
|
|
||||||
|
Reported-by: Luiz Capitulino <luizcap@amazon.com>
|
||||||
|
Tested-by: Luiz Capitulino <luizcap@amazon.com>
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
defs.h | 6 +++---
|
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index 12ad6aaa0998..211fc9d55d33 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -807,10 +807,10 @@ struct kernel_table { /* kernel data */
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define THIS_KERNEL_VERSION ((kt->kernel_version[0] << 16) + \
|
||||||
|
- (kt->kernel_version[1] << 8) + \
|
||||||
|
+#define THIS_KERNEL_VERSION ((kt->kernel_version[0] << 24) + \
|
||||||
|
+ (kt->kernel_version[1] << 16) + \
|
||||||
|
(kt->kernel_version[2]))
|
||||||
|
-#define LINUX(x,y,z) (((uint)(x) << 16) + ((uint)(y) << 8) + (uint)(z))
|
||||||
|
+#define LINUX(x,y,z) (((uint)(x) << 24) + ((uint)(y) << 16) + (uint)(z))
|
||||||
|
|
||||||
|
#define THIS_GCC_VERSION ((kt->gcc_version[0] << 16) + \
|
||||||
|
(kt->gcc_version[1] << 8) + \
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
71
SOURCES/0001-Output-prompt-when-stdin-is-not-a-TTY.patch
Normal file
71
SOURCES/0001-Output-prompt-when-stdin-is-not-a-TTY.patch
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
From 8527bbff71cbdfd90a67d5cec4a1d94156e6bf13 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hsin-Yi Wang <hsinyi@chromium.org>
|
||||||
|
Date: Wed, 31 May 2023 14:01:36 +0800
|
||||||
|
Subject: [PATCH 1/5] Output prompt when stdin is not a TTY
|
||||||
|
|
||||||
|
When stdin is not a TTY, prompt ("crash> ") won't be displayed. If
|
||||||
|
another process interact with crash with piped stdin/stdout, it will not
|
||||||
|
get the prompt as a delimiter.
|
||||||
|
|
||||||
|
Compared to other debugger like gdb, crash seems intended to give a
|
||||||
|
prompt in this case in the beginning of process_command_line(). It
|
||||||
|
checks if pc->flags does NOT have any of
|
||||||
|
READLINE|SILENT|CMDLINE_IFILE|RCHOME_IFILE|RCLOCAL_IFILE, a
|
||||||
|
prompt should be printed. The check will never be true since READLINE is
|
||||||
|
set in setup_environment() unconditionally.
|
||||||
|
|
||||||
|
It makes more sense to change the READLINE flag in the check to TTY
|
||||||
|
instead. Besides this change, the prompt in process_command_line() should
|
||||||
|
only be print when it's not in the middle of processing the input file
|
||||||
|
recovering from a previous FATAL command, because the prompt will be
|
||||||
|
displayed by the exec_input_file().
|
||||||
|
|
||||||
|
Additionally, when stdin is not TTY, repeat the command line from user
|
||||||
|
after prompt, which can give more context.
|
||||||
|
|
||||||
|
The prompt and command line can be opt out by using the silent (-s) flag.
|
||||||
|
|
||||||
|
Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
cmdline.c | 14 +++++++++-----
|
||||||
|
1 file changed, 9 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cmdline.c b/cmdline.c
|
||||||
|
index ded6551c2597..b7f919ae2279 100644
|
||||||
|
--- a/cmdline.c
|
||||||
|
+++ b/cmdline.c
|
||||||
|
@@ -64,8 +64,8 @@ process_command_line(void)
|
||||||
|
fp = stdout;
|
||||||
|
BZERO(pc->command_line, BUFSIZE);
|
||||||
|
|
||||||
|
- if (!(pc->flags &
|
||||||
|
- (READLINE|SILENT|CMDLINE_IFILE|RCHOME_IFILE|RCLOCAL_IFILE)))
|
||||||
|
+ if (!pc->ifile_in_progress && !(pc->flags &
|
||||||
|
+ (TTY|SILENT|CMDLINE_IFILE|RCHOME_IFILE|RCLOCAL_IFILE)))
|
||||||
|
fprintf(fp, "%s", pc->prompt);
|
||||||
|
fflush(fp);
|
||||||
|
|
||||||
|
@@ -136,12 +136,16 @@ process_command_line(void)
|
||||||
|
add_history(pc->command_line);
|
||||||
|
|
||||||
|
check_special_handling(pc->command_line);
|
||||||
|
- } else {
|
||||||
|
- if (fgets(pc->command_line, BUFSIZE-1, stdin) == NULL)
|
||||||
|
+ } else {
|
||||||
|
+ if (fgets(pc->command_line, BUFSIZE-1, stdin) == NULL)
|
||||||
|
clean_exit(1);
|
||||||
|
+ if (!(pc->flags & SILENT)) {
|
||||||
|
+ fprintf(fp, "%s", pc->command_line);
|
||||||
|
+ fflush(fp);
|
||||||
|
+ }
|
||||||
|
clean_line(pc->command_line);
|
||||||
|
strcpy(pc->orig_line, pc->command_line);
|
||||||
|
- }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First clean out all linefeeds and leading/trailing spaces.
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From ae52398a13fa9a238279114ed671c7c514c154ee Mon Sep 17 00:00:00 2001
|
From a48cebaa9691efe4e2c47bbd56d40ebc8acfa89e Mon Sep 17 00:00:00 2001
|
||||||
From: Sourabh Jain <sourabhjain@linux.ibm.com>
|
From: Sourabh Jain <sourabhjain@linux.ibm.com>
|
||||||
Date: Mon, 9 May 2022 12:49:56 +0530
|
Date: Mon, 9 May 2022 12:49:56 +0530
|
||||||
Subject: [PATCH 01/18] ppc64: update the NR_CPUS to 8192
|
Subject: [PATCH 01/89] ppc64: update the NR_CPUS to 8192
|
||||||
|
|
||||||
Since the kernel commit 2d8ae638bb86 ("powerpc: Make the NR_CPUS max 8192")
|
Since the kernel commit 2d8ae638bb86 ("powerpc: Make the NR_CPUS max 8192")
|
||||||
the NR_CPUS on Linux kernel ranges from 1-8192. So let's match NR_CPUS with
|
the NR_CPUS on Linux kernel ranges from 1-8192. So let's match NR_CPUS with
|
||||||
@ -14,7 +14,7 @@ Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
|||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
diff --git a/defs.h b/defs.h
|
diff --git a/defs.h b/defs.h
|
||||||
index 1e8360d65a3b..a6735d07b32f 100644
|
index 89f57873f1a1..984348062bcb 100644
|
||||||
--- a/defs.h
|
--- a/defs.h
|
||||||
+++ b/defs.h
|
+++ b/defs.h
|
||||||
@@ -136,7 +136,7 @@
|
@@ -136,7 +136,7 @@
|
||||||
@ -27,5 +27,5 @@ index 1e8360d65a3b..a6735d07b32f 100644
|
|||||||
#ifdef S390
|
#ifdef S390
|
||||||
#define NR_CPUS (512)
|
#define NR_CPUS (512)
|
||||||
--
|
--
|
||||||
2.30.2
|
2.37.1
|
||||||
|
|
||||||
|
@ -0,0 +1,179 @@
|
|||||||
|
From 58c1816521c2e6bece3d69256b1866c9df8d93aa Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Date: Tue, 16 May 2023 08:59:50 +0900
|
||||||
|
Subject: [PATCH 2/6] Fix failure of "dev -d|-D" options on Linux 6.4 and later
|
||||||
|
kernels
|
||||||
|
|
||||||
|
Kernel commit 2df418cf4b72 ("driver core: class: remove subsystem
|
||||||
|
private pointer from struct class"), which is contained in Linux 6.4 and
|
||||||
|
later kernels, removed the class.p member for struct subsys_private. As
|
||||||
|
a result, the "dev -d|-D" options fail with the following error.
|
||||||
|
|
||||||
|
dev: invalid structure member offset: class_p
|
||||||
|
FILE: dev.c LINE: 4689 FUNCTION: init_iter()
|
||||||
|
|
||||||
|
Search the class_kset list for the subsys_private of block class to fix
|
||||||
|
this.
|
||||||
|
|
||||||
|
As a preparation, introduce get_subsys_private() function, which is
|
||||||
|
abstracted from the same search procedure in init_memory_block().
|
||||||
|
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
defs.h | 1 +
|
||||||
|
dev.c | 20 +++++++++++++++++---
|
||||||
|
memory.c | 35 +++--------------------------------
|
||||||
|
tools.c | 43 +++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
4 files changed, 64 insertions(+), 35 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index 211fc9d55d33..21cc760444d1 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -5521,6 +5521,7 @@ struct rb_node *rb_left(struct rb_node *, struct rb_node *);
|
||||||
|
struct rb_node *rb_next(struct rb_node *);
|
||||||
|
struct rb_node *rb_last(struct rb_root *);
|
||||||
|
long percpu_counter_sum_positive(ulong fbc);
|
||||||
|
+ulong get_subsys_private(char *, char *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* symbols.c
|
||||||
|
diff --git a/dev.c b/dev.c
|
||||||
|
index 75d30bd022a1..9d38aef9b3db 100644
|
||||||
|
--- a/dev.c
|
||||||
|
+++ b/dev.c
|
||||||
|
@@ -4686,9 +4686,16 @@ init_iter(struct iter *i)
|
||||||
|
} else {
|
||||||
|
/* kernel version > 2.6.27, klist */
|
||||||
|
unsigned long class_private_addr;
|
||||||
|
- readmem(block_class_addr + OFFSET(class_p), KVADDR,
|
||||||
|
- &class_private_addr, sizeof(class_private_addr),
|
||||||
|
- "class.p", FAULT_ON_ERROR);
|
||||||
|
+
|
||||||
|
+ if (INVALID_MEMBER(class_p)) /* kernel version >= 6.4 */
|
||||||
|
+ class_private_addr = get_subsys_private("class_kset", "block");
|
||||||
|
+ else
|
||||||
|
+ readmem(block_class_addr + OFFSET(class_p), KVADDR,
|
||||||
|
+ &class_private_addr, sizeof(class_private_addr),
|
||||||
|
+ "class.p", FAULT_ON_ERROR);
|
||||||
|
+
|
||||||
|
+ if (!class_private_addr)
|
||||||
|
+ error(FATAL, "cannot determine subsys_private for block.\n");
|
||||||
|
|
||||||
|
if (VALID_STRUCT(class_private)) {
|
||||||
|
/* 2.6.27 < kernel version <= 2.6.37-rc2 */
|
||||||
|
@@ -4823,6 +4830,13 @@ void diskio_init(void)
|
||||||
|
if (INVALID_MEMBER(class_devices))
|
||||||
|
MEMBER_OFFSET_INIT(class_devices, "class", "devices");
|
||||||
|
MEMBER_OFFSET_INIT(class_p, "class", "p");
|
||||||
|
+ if (INVALID_MEMBER(class_p)) {
|
||||||
|
+ MEMBER_OFFSET_INIT(kset_list, "kset", "list");
|
||||||
|
+ MEMBER_OFFSET_INIT(kset_kobj, "kset", "kobj");
|
||||||
|
+ MEMBER_OFFSET_INIT(kobject_name, "kobject", "name");
|
||||||
|
+ MEMBER_OFFSET_INIT(kobject_entry, "kobject", "entry");
|
||||||
|
+ MEMBER_OFFSET_INIT(subsys_private_subsys, "subsys_private", "subsys");
|
||||||
|
+ }
|
||||||
|
MEMBER_OFFSET_INIT(class_private_devices, "class_private",
|
||||||
|
"class_devices");
|
||||||
|
MEMBER_OFFSET_INIT(device_knode_class, "device", "knode_class");
|
||||||
|
diff --git a/memory.c b/memory.c
|
||||||
|
index 0568f18eb9b7..953fc380c03c 100644
|
||||||
|
--- a/memory.c
|
||||||
|
+++ b/memory.c
|
||||||
|
@@ -17865,38 +17865,9 @@ init_memory_block(int *klistcnt, ulong **klistbuf)
|
||||||
|
* v6.3-rc1
|
||||||
|
* d2bf38c088e0 driver core: remove private pointer from struct bus_type
|
||||||
|
*/
|
||||||
|
- if (INVALID_MEMBER(bus_type_p)) {
|
||||||
|
- int i, cnt;
|
||||||
|
- char buf[32];
|
||||||
|
- ulong bus_kset, list, name;
|
||||||
|
-
|
||||||
|
- BZERO(ld, sizeof(struct list_data));
|
||||||
|
-
|
||||||
|
- get_symbol_data("bus_kset", sizeof(ulong), &bus_kset);
|
||||||
|
- readmem(bus_kset + OFFSET(kset_list), KVADDR, &list,
|
||||||
|
- sizeof(ulong), "bus_kset.list", FAULT_ON_ERROR);
|
||||||
|
-
|
||||||
|
- ld->flags |= LIST_ALLOCATE;
|
||||||
|
- ld->start = list;
|
||||||
|
- ld->end = bus_kset + OFFSET(kset_list);
|
||||||
|
- ld->list_head_offset = OFFSET(kobject_entry);
|
||||||
|
-
|
||||||
|
- cnt = do_list(ld);
|
||||||
|
- for (i = 0; i < cnt; i++) {
|
||||||
|
- readmem(ld->list_ptr[i] + OFFSET(kobject_name), KVADDR, &name,
|
||||||
|
- sizeof(ulong), "kobject.name", FAULT_ON_ERROR);
|
||||||
|
- read_string(name, buf, sizeof(buf)-1);
|
||||||
|
- if (CRASHDEBUG(1))
|
||||||
|
- fprintf(fp, "kobject: %lx name: %s\n", ld->list_ptr[i], buf);
|
||||||
|
- if (STREQ(buf, "memory")) {
|
||||||
|
- /* entry is subsys_private.subsys.kobj. See bus_to_subsys(). */
|
||||||
|
- private = ld->list_ptr[i] - OFFSET(kset_kobj)
|
||||||
|
- - OFFSET(subsys_private_subsys);
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- FREEBUF(ld->list_ptr);
|
||||||
|
- } else {
|
||||||
|
+ if (INVALID_MEMBER(bus_type_p))
|
||||||
|
+ private = get_subsys_private("bus_kset", "memory");
|
||||||
|
+ else {
|
||||||
|
ulong memory_subsys = symbol_value("memory_subsys");
|
||||||
|
readmem(memory_subsys + OFFSET(bus_type_p), KVADDR, &private,
|
||||||
|
sizeof(void *), "memory_subsys.private", FAULT_ON_ERROR);
|
||||||
|
diff --git a/tools.c b/tools.c
|
||||||
|
index c2cfa7e280bc..392a79707e61 100644
|
||||||
|
--- a/tools.c
|
||||||
|
+++ b/tools.c
|
||||||
|
@@ -6963,3 +6963,46 @@ percpu_counter_sum_positive(ulong fbc)
|
||||||
|
|
||||||
|
return (ret < 0) ? 0 : ret;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ulong
|
||||||
|
+get_subsys_private(char *kset_name, char *target_name)
|
||||||
|
+{
|
||||||
|
+ ulong kset_addr, kset_list, name_addr, private = 0;
|
||||||
|
+ struct list_data list_data, *ld;
|
||||||
|
+ char buf[32];
|
||||||
|
+ int i, cnt;
|
||||||
|
+
|
||||||
|
+ if (!symbol_exists(kset_name))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ ld = &list_data;
|
||||||
|
+ BZERO(ld, sizeof(struct list_data));
|
||||||
|
+
|
||||||
|
+ get_symbol_data(kset_name, sizeof(ulong), &kset_addr);
|
||||||
|
+ readmem(kset_addr + OFFSET(kset_list), KVADDR, &kset_list,
|
||||||
|
+ sizeof(ulong), "kset.list", FAULT_ON_ERROR);
|
||||||
|
+
|
||||||
|
+ ld->flags |= LIST_ALLOCATE;
|
||||||
|
+ ld->start = kset_list;
|
||||||
|
+ ld->end = kset_addr + OFFSET(kset_list);
|
||||||
|
+ ld->list_head_offset = OFFSET(kobject_entry);
|
||||||
|
+
|
||||||
|
+ cnt = do_list(ld);
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < cnt; i++) {
|
||||||
|
+ readmem(ld->list_ptr[i] + OFFSET(kobject_name), KVADDR, &name_addr,
|
||||||
|
+ sizeof(ulong), "kobject.name", FAULT_ON_ERROR);
|
||||||
|
+ read_string(name_addr, buf, sizeof(buf)-1);
|
||||||
|
+ if (CRASHDEBUG(1))
|
||||||
|
+ fprintf(fp, "kobject: %lx name: %s\n", ld->list_ptr[i], buf);
|
||||||
|
+ if (STREQ(buf, target_name)) {
|
||||||
|
+ /* entry is subsys_private.subsys.kobj. See bus_to_subsys(). */
|
||||||
|
+ private = ld->list_ptr[i] - OFFSET(kset_kobj)
|
||||||
|
+ - OFFSET(subsys_private_subsys);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ FREEBUF(ld->list_ptr);
|
||||||
|
+
|
||||||
|
+ return private;
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From 364b2e413c69daf189d2bc0238e3ba9b0dcbd937 Mon Sep 17 00:00:00 2001
|
From d3682a7e57036b226d395541b590ebc460123b04 Mon Sep 17 00:00:00 2001
|
||||||
From: Lianbo Jiang <lijiang@redhat.com>
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
Date: Mon, 23 May 2022 18:04:13 +0800
|
Date: Mon, 23 May 2022 18:04:13 +0800
|
||||||
Subject: [PATCH 02/18] sbitmapq: remove struct and member validation in
|
Subject: [PATCH 02/89] sbitmapq: remove struct and member validation in
|
||||||
sbitmapq_init()
|
sbitmapq_init()
|
||||||
|
|
||||||
Let's remove the struct and member validation from sbitmapq_init(), which
|
Let's remove the struct and member validation from sbitmapq_init(), which
|
||||||
@ -58,5 +58,5 @@ index 96a61e6c2c71..7693eef6cebd 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
--
|
--
|
||||||
2.30.2
|
2.37.1
|
||||||
|
|
||||||
|
@ -0,0 +1,345 @@
|
|||||||
|
From 77d8621876c1c6a3a25b91e464ba588a542485fb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Date: Thu, 18 May 2023 16:53:54 +0900
|
||||||
|
Subject: [PATCH 2/5] x86_64: Fix "bt" command printing stale entries on Linux
|
||||||
|
6.4 and later
|
||||||
|
|
||||||
|
Kernel commit fb799447ae29 ("x86,objtool: Split UNWIND_HINT_EMPTY in
|
||||||
|
two"), which is contained in Linux 6.4 and later kernels, changed
|
||||||
|
ORC_TYPE_CALL macro from 0 to 2. As a result, the "bt" command cannot
|
||||||
|
use ORC entries, and can display stale entries in a call trace.
|
||||||
|
|
||||||
|
crash> bt 1
|
||||||
|
PID: 1 TASK: ffff93cd06294180 CPU: 51 COMMAND: "systemd"
|
||||||
|
#0 [ffffb72bc00cbc98] __schedule at ffffffff86e52aae
|
||||||
|
#1 [ffffb72bc00cbd00] schedule at ffffffff86e52f6a
|
||||||
|
#2 [ffffb72bc00cbd18] schedule_hrtimeout_range_clock at ffffffff86e58ef5
|
||||||
|
#3 [ffffb72bc00cbd88] ep_poll at ffffffff8669624d
|
||||||
|
#4 [ffffb72bc00cbe28] do_epoll_wait at ffffffff86696371
|
||||||
|
#5 [ffffb72bc00cbe30] do_timerfd_settime at ffffffff8669902b <<
|
||||||
|
#6 [ffffb72bc00cbe60] __x64_sys_epoll_wait at ffffffff86696bf0
|
||||||
|
#7 [ffffb72bc00cbeb0] do_syscall_64 at ffffffff86e3feb9
|
||||||
|
#8 [ffffb72bc00cbee0] __task_pid_nr_ns at ffffffff863330d7 <<
|
||||||
|
#9 [ffffb72bc00cbf08] syscall_exit_to_user_mode at ffffffff86e466b2 << stale entries
|
||||||
|
#10 [ffffb72bc00cbf18] do_syscall_64 at ffffffff86e3fec9 <<
|
||||||
|
#11 [ffffb72bc00cbf50] entry_SYSCALL_64_after_hwframe at ffffffff870000aa
|
||||||
|
|
||||||
|
Also, kernel commit ffb1b4a41016 added a member to struct orc_entry.
|
||||||
|
Although this does not affect the crash's unwinder, its debugging
|
||||||
|
information can be displayed incorrectly.
|
||||||
|
|
||||||
|
To fix these,
|
||||||
|
(1) introduce "kernel_orc_entry_6_4" structure corresponding to 6.4 and
|
||||||
|
abstruction layer "orc_entry" structure in crash,
|
||||||
|
(2) switch ORC_TYPE_CALL to 2 or 0 with kernel's orc_entry structure.
|
||||||
|
|
||||||
|
Related orc_entry history:
|
||||||
|
v4.14 39358a033b2e introduced struct orc_entry
|
||||||
|
v4.19 d31a580266ee added orc_entry.end member
|
||||||
|
v6.3 ffb1b4a41016 added orc_entry.signal member
|
||||||
|
v6.4 fb799447ae29 removed end member and changed type member to 3 bits
|
||||||
|
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
defs.h | 28 ++++++++++++-
|
||||||
|
x86_64.c | 119 +++++++++++++++++++++++++++++++++++++++++++------------
|
||||||
|
2 files changed, 119 insertions(+), 28 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index 11fdc17e60d0..bfda0c48d37b 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -6363,9 +6363,29 @@ typedef struct __attribute__((__packed__)) {
|
||||||
|
unsigned int sp_reg:4;
|
||||||
|
unsigned int bp_reg:4;
|
||||||
|
unsigned int type:2;
|
||||||
|
+ unsigned int signal:1;
|
||||||
|
unsigned int end:1;
|
||||||
|
} kernel_orc_entry;
|
||||||
|
|
||||||
|
+typedef struct __attribute__((__packed__)) {
|
||||||
|
+ signed short sp_offset;
|
||||||
|
+ signed short bp_offset;
|
||||||
|
+ unsigned int sp_reg:4;
|
||||||
|
+ unsigned int bp_reg:4;
|
||||||
|
+ unsigned int type:3;
|
||||||
|
+ unsigned int signal:1;
|
||||||
|
+} kernel_orc_entry_6_4;
|
||||||
|
+
|
||||||
|
+typedef struct orc_entry {
|
||||||
|
+ signed short sp_offset;
|
||||||
|
+ signed short bp_offset;
|
||||||
|
+ unsigned int sp_reg;
|
||||||
|
+ unsigned int bp_reg;
|
||||||
|
+ unsigned int type;
|
||||||
|
+ unsigned int signal;
|
||||||
|
+ unsigned int end;
|
||||||
|
+} orc_entry;
|
||||||
|
+
|
||||||
|
struct ORC_data {
|
||||||
|
int module_ORC;
|
||||||
|
uint lookup_num_blocks;
|
||||||
|
@@ -6376,10 +6396,13 @@ struct ORC_data {
|
||||||
|
ulong orc_lookup;
|
||||||
|
ulong ip_entry;
|
||||||
|
ulong orc_entry;
|
||||||
|
- kernel_orc_entry kernel_orc_entry;
|
||||||
|
+ orc_entry orc_entry_data;
|
||||||
|
+ int has_signal;
|
||||||
|
+ int has_end;
|
||||||
|
};
|
||||||
|
|
||||||
|
-#define ORC_TYPE_CALL 0
|
||||||
|
+#define ORC_TYPE_CALL ((machdep->flags & ORC_6_4) ? 2 : 0)
|
||||||
|
+/* The below entries are not used and must be updated if we use them. */
|
||||||
|
#define ORC_TYPE_REGS 1
|
||||||
|
#define ORC_TYPE_REGS_IRET 2
|
||||||
|
#define UNWIND_HINT_TYPE_SAVE 3
|
||||||
|
@@ -6456,6 +6479,7 @@ struct machine_specific {
|
||||||
|
#define ORC (0x4000)
|
||||||
|
#define KPTI (0x8000)
|
||||||
|
#define L1TF (0x10000)
|
||||||
|
+#define ORC_6_4 (0x20000)
|
||||||
|
|
||||||
|
#define VM_FLAGS (VM_ORIG|VM_2_6_11|VM_XEN|VM_XEN_RHEL4|VM_5LEVEL)
|
||||||
|
|
||||||
|
diff --git a/x86_64.c b/x86_64.c
|
||||||
|
index 693a08bea758..87e87ae6e1e8 100644
|
||||||
|
--- a/x86_64.c
|
||||||
|
+++ b/x86_64.c
|
||||||
|
@@ -132,9 +132,9 @@ static void GART_init(void);
|
||||||
|
static void x86_64_exception_stacks_init(void);
|
||||||
|
static int in_START_KERNEL_map(ulong);
|
||||||
|
static ulong orc_ip(ulong);
|
||||||
|
-static kernel_orc_entry *__orc_find(ulong, ulong, uint, ulong);
|
||||||
|
-static kernel_orc_entry *orc_find(ulong);
|
||||||
|
-static kernel_orc_entry *orc_module_find(ulong);
|
||||||
|
+static orc_entry *__orc_find(ulong, ulong, uint, ulong);
|
||||||
|
+static orc_entry *orc_find(ulong);
|
||||||
|
+static orc_entry *orc_module_find(ulong);
|
||||||
|
static ulong ip_table_to_vaddr(ulong);
|
||||||
|
static void orc_dump(ulong);
|
||||||
|
|
||||||
|
@@ -806,6 +806,8 @@ x86_64_dump_machdep_table(ulong arg)
|
||||||
|
fprintf(fp, "%sFRAMESIZE_DEBUG", others++ ? "|" : "");
|
||||||
|
if (machdep->flags & ORC)
|
||||||
|
fprintf(fp, "%sORC", others++ ? "|" : "");
|
||||||
|
+ if (machdep->flags & ORC_6_4)
|
||||||
|
+ fprintf(fp, "%sORC_6_4", others++ ? "|" : "");
|
||||||
|
if (machdep->flags & FRAMEPOINTER)
|
||||||
|
fprintf(fp, "%sFRAMEPOINTER", others++ ? "|" : "");
|
||||||
|
if (machdep->flags & GART_REGION)
|
||||||
|
@@ -980,6 +982,8 @@ x86_64_dump_machdep_table(ulong arg)
|
||||||
|
fprintf(fp, " ORC_data: %s", machdep->flags & ORC ? "\n" : "(unused)\n");
|
||||||
|
if (machdep->flags & ORC) {
|
||||||
|
fprintf(fp, " module_ORC: %s\n", ms->orc.module_ORC ? "TRUE" : "FALSE");
|
||||||
|
+ fprintf(fp, " has_signal: %s\n", ms->orc.has_signal ? "TRUE" : "FALSE");
|
||||||
|
+ fprintf(fp, " has_end: %s\n", ms->orc.has_end ? "TRUE" : "FALSE");
|
||||||
|
fprintf(fp, " lookup_num_blocks: %d\n", ms->orc.lookup_num_blocks);
|
||||||
|
fprintf(fp, " __start_orc_unwind_ip: %lx\n", ms->orc.__start_orc_unwind_ip);
|
||||||
|
fprintf(fp, " __stop_orc_unwind_ip: %lx\n", ms->orc.__stop_orc_unwind_ip);
|
||||||
|
@@ -988,14 +992,18 @@ x86_64_dump_machdep_table(ulong arg)
|
||||||
|
fprintf(fp, " orc_lookup: %lx\n", ms->orc.orc_lookup);
|
||||||
|
fprintf(fp, " ip_entry: %lx\n", ms->orc.ip_entry);
|
||||||
|
fprintf(fp, " orc_entry: %lx\n", ms->orc.orc_entry);
|
||||||
|
- fprintf(fp, " kernel_orc_entry:\n");
|
||||||
|
- fprintf(fp, " sp_offset: %d\n", ms->orc.kernel_orc_entry.sp_offset);
|
||||||
|
- fprintf(fp, " bp_offset: %d\n", ms->orc.kernel_orc_entry.bp_offset);
|
||||||
|
- fprintf(fp, " sp_reg: %d\n", ms->orc.kernel_orc_entry.sp_reg);
|
||||||
|
- fprintf(fp, " bp_reg: %d\n", ms->orc.kernel_orc_entry.bp_reg);
|
||||||
|
- fprintf(fp, " type: %d\n", ms->orc.kernel_orc_entry.type);
|
||||||
|
- if (MEMBER_EXISTS("orc_entry", "end"))
|
||||||
|
- fprintf(fp, " end: %d\n", ms->orc.kernel_orc_entry.end);
|
||||||
|
+ fprintf(fp, " orc_entry_data:\n");
|
||||||
|
+ fprintf(fp, " sp_offset: %d\n", ms->orc.orc_entry_data.sp_offset);
|
||||||
|
+ fprintf(fp, " bp_offset: %d\n", ms->orc.orc_entry_data.bp_offset);
|
||||||
|
+ fprintf(fp, " sp_reg: %d\n", ms->orc.orc_entry_data.sp_reg);
|
||||||
|
+ fprintf(fp, " bp_reg: %d\n", ms->orc.orc_entry_data.bp_reg);
|
||||||
|
+ fprintf(fp, " type: %d\n", ms->orc.orc_entry_data.type);
|
||||||
|
+ if (ms->orc.has_signal)
|
||||||
|
+ fprintf(fp, " signal: %d\n", ms->orc.orc_entry_data.signal);
|
||||||
|
+ else
|
||||||
|
+ fprintf(fp, " signal: (n/a)\n");
|
||||||
|
+ if (ms->orc.has_end)
|
||||||
|
+ fprintf(fp, " end: %d\n", ms->orc.orc_entry_data.end);
|
||||||
|
else
|
||||||
|
fprintf(fp, " end: (n/a)\n");
|
||||||
|
}
|
||||||
|
@@ -6440,6 +6448,12 @@ x86_64_ORC_init(void)
|
||||||
|
MEMBER_OFFSET_INIT(inactive_task_frame_bp, "inactive_task_frame", "bp");
|
||||||
|
MEMBER_OFFSET_INIT(inactive_task_frame_ret_addr, "inactive_task_frame", "ret_addr");
|
||||||
|
|
||||||
|
+ orc->has_signal = MEMBER_EXISTS("orc_entry", "signal"); /* added at 6.3 */
|
||||||
|
+ orc->has_end = MEMBER_EXISTS("orc_entry", "end"); /* removed at 6.4 */
|
||||||
|
+
|
||||||
|
+ if (orc->has_signal && !orc->has_end)
|
||||||
|
+ machdep->flags |= ORC_6_4;
|
||||||
|
+
|
||||||
|
machdep->flags |= ORC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -8522,7 +8536,7 @@ x86_64_get_framesize(struct bt_info *bt, ulong textaddr, ulong rsp, char *stack_
|
||||||
|
int reterror;
|
||||||
|
int arg_exists;
|
||||||
|
int exception;
|
||||||
|
- kernel_orc_entry *korc;
|
||||||
|
+ orc_entry *korc;
|
||||||
|
|
||||||
|
if (!(bt->flags & BT_FRAMESIZE_DEBUG)) {
|
||||||
|
if ((bt->flags & BT_FRAMESIZE_IGNORE_MASK) ||
|
||||||
|
@@ -8608,11 +8622,14 @@ x86_64_get_framesize(struct bt_info *bt, ulong textaddr, ulong rsp, char *stack_
|
||||||
|
|
||||||
|
if ((machdep->flags & ORC) && (korc = orc_find(textaddr))) {
|
||||||
|
if (CRASHDEBUG(1)) {
|
||||||
|
+ struct ORC_data *orc = &machdep->machspec->orc;
|
||||||
|
fprintf(fp,
|
||||||
|
"rsp: %lx textaddr: %lx -> spo: %d bpo: %d spr: %d bpr: %d type: %d",
|
||||||
|
rsp, textaddr, korc->sp_offset, korc->bp_offset,
|
||||||
|
korc->sp_reg, korc->bp_reg, korc->type);
|
||||||
|
- if (MEMBER_EXISTS("orc_entry", "end"))
|
||||||
|
+ if (orc->has_signal)
|
||||||
|
+ fprintf(fp, " signal: %d", korc->signal);
|
||||||
|
+ if (orc->has_end)
|
||||||
|
fprintf(fp, " end: %d", korc->end);
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
}
|
||||||
|
@@ -9118,7 +9135,53 @@ orc_ip(ulong ip)
|
||||||
|
return (ip + ip_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static kernel_orc_entry *
|
||||||
|
+static orc_entry *
|
||||||
|
+orc_get_entry(struct ORC_data *orc)
|
||||||
|
+{
|
||||||
|
+ struct orc_entry *entry = &orc->orc_entry_data;
|
||||||
|
+
|
||||||
|
+ if (machdep->flags & ORC_6_4) {
|
||||||
|
+ kernel_orc_entry_6_4 korc;
|
||||||
|
+
|
||||||
|
+ if (!readmem(orc->orc_entry, KVADDR, &korc, sizeof(kernel_orc_entry_6_4),
|
||||||
|
+ "kernel orc_entry", RETURN_ON_ERROR|QUIET))
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ entry->sp_offset = korc.sp_offset;
|
||||||
|
+ entry->bp_offset = korc.bp_offset;
|
||||||
|
+ entry->sp_reg = korc.sp_reg;
|
||||||
|
+ entry->bp_reg = korc.bp_reg;
|
||||||
|
+ entry->type = korc.type;
|
||||||
|
+ entry->signal = korc.signal;
|
||||||
|
+ } else {
|
||||||
|
+ kernel_orc_entry korc;
|
||||||
|
+
|
||||||
|
+ if (!readmem(orc->orc_entry, KVADDR, &korc, sizeof(kernel_orc_entry),
|
||||||
|
+ "kernel orc_entry", RETURN_ON_ERROR|QUIET))
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ entry->sp_offset = korc.sp_offset;
|
||||||
|
+ entry->bp_offset = korc.bp_offset;
|
||||||
|
+ entry->sp_reg = korc.sp_reg;
|
||||||
|
+ entry->bp_reg = korc.bp_reg;
|
||||||
|
+ entry->type = korc.type;
|
||||||
|
+ if (orc->has_end) {
|
||||||
|
+ /*
|
||||||
|
+ * orc_entry.signal was inserted before orc_entry.end.
|
||||||
|
+ * see ffb1b4a41016.
|
||||||
|
+ */
|
||||||
|
+ if (orc->has_signal) {
|
||||||
|
+ entry->signal = korc.signal;
|
||||||
|
+ entry->end = korc.end;
|
||||||
|
+ } else
|
||||||
|
+ entry->end = korc.signal; /* on purpose */
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return entry;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static orc_entry *
|
||||||
|
__orc_find(ulong ip_table_ptr, ulong u_table_ptr, uint num_entries, ulong ip)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
@@ -9128,7 +9191,7 @@ __orc_find(ulong ip_table_ptr, ulong u_table_ptr, uint num_entries, ulong ip)
|
||||||
|
int *ip_table = (int *)ip_table_ptr;
|
||||||
|
struct ORC_data *orc = &machdep->machspec->orc;
|
||||||
|
ulong vaddr;
|
||||||
|
- kernel_orc_entry *korc;
|
||||||
|
+ orc_entry *korc;
|
||||||
|
|
||||||
|
if (CRASHDEBUG(2)) {
|
||||||
|
int i, ip_entry;
|
||||||
|
@@ -9172,18 +9235,20 @@ __orc_find(ulong ip_table_ptr, ulong u_table_ptr, uint num_entries, ulong ip)
|
||||||
|
|
||||||
|
orc->ip_entry = (ulong)found;
|
||||||
|
orc->orc_entry = u_table_ptr + (index * SIZE(orc_entry));
|
||||||
|
- if (!readmem(orc->orc_entry, KVADDR, &orc->kernel_orc_entry,
|
||||||
|
- sizeof(kernel_orc_entry), "kernel orc_entry", RETURN_ON_ERROR|QUIET))
|
||||||
|
+
|
||||||
|
+ if (!orc_get_entry(orc))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
- korc = &orc->kernel_orc_entry;
|
||||||
|
+ korc = &orc->orc_entry_data;
|
||||||
|
|
||||||
|
if (CRASHDEBUG(2)) {
|
||||||
|
fprintf(fp, " found: %lx index: %d\n", (ulong)found, index);
|
||||||
|
fprintf(fp,
|
||||||
|
" orc_entry: %lx sp_offset: %d bp_offset: %d sp_reg: %d bp_reg: %d type: %d",
|
||||||
|
orc->orc_entry, korc->sp_offset, korc->bp_offset, korc->sp_reg, korc->bp_reg, korc->type);
|
||||||
|
- if (MEMBER_EXISTS("orc_entry", "end"))
|
||||||
|
+ if (orc->has_signal)
|
||||||
|
+ fprintf(fp, " signal: %d", korc->signal);
|
||||||
|
+ if (orc->has_end)
|
||||||
|
fprintf(fp, " end: %d", korc->end);
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
}
|
||||||
|
@@ -9196,7 +9261,7 @@ __orc_find(ulong ip_table_ptr, ulong u_table_ptr, uint num_entries, ulong ip)
|
||||||
|
#define LOOKUP_START_IP (unsigned long)kt->stext
|
||||||
|
#define LOOKUP_STOP_IP (unsigned long)kt->etext
|
||||||
|
|
||||||
|
-static kernel_orc_entry *
|
||||||
|
+static orc_entry *
|
||||||
|
orc_find(ulong ip)
|
||||||
|
{
|
||||||
|
unsigned int idx, start, stop;
|
||||||
|
@@ -9266,7 +9331,7 @@ orc_find(ulong ip)
|
||||||
|
orc->__start_orc_unwind + (start * SIZE(orc_entry)), stop - start, ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static kernel_orc_entry *
|
||||||
|
+static orc_entry *
|
||||||
|
orc_module_find(ulong ip)
|
||||||
|
{
|
||||||
|
struct load_module *lm;
|
||||||
|
@@ -9313,7 +9378,7 @@ static void
|
||||||
|
orc_dump(ulong ip)
|
||||||
|
{
|
||||||
|
struct ORC_data *orc = &machdep->machspec->orc;
|
||||||
|
- kernel_orc_entry *korc;
|
||||||
|
+ orc_entry *korc;
|
||||||
|
ulong vaddr, offset;
|
||||||
|
struct syment *sp, *orig;
|
||||||
|
|
||||||
|
@@ -9336,13 +9401,15 @@ next_in_func:
|
||||||
|
fprintf(fp, "%s+%ld -> ", sp->name, offset);
|
||||||
|
else
|
||||||
|
fprintf(fp, "(unresolved) -> ");
|
||||||
|
- if (!readmem(orc->orc_entry, KVADDR, &orc->kernel_orc_entry, sizeof(kernel_orc_entry),
|
||||||
|
- "kernel orc_entry", RETURN_ON_ERROR))
|
||||||
|
+
|
||||||
|
+ if (!orc_get_entry(orc))
|
||||||
|
error(FATAL, "cannot read orc_entry\n");
|
||||||
|
- korc = &orc->kernel_orc_entry;
|
||||||
|
+ korc = &orc->orc_entry_data;
|
||||||
|
fprintf(fp, "orc: %lx spo: %d bpo: %d spr: %d bpr: %d type: %d",
|
||||||
|
orc->orc_entry, korc->sp_offset, korc->bp_offset, korc->sp_reg, korc->bp_reg, korc->type);
|
||||||
|
- if (MEMBER_EXISTS("orc_entry", "end"))
|
||||||
|
+ if (orc->has_signal)
|
||||||
|
+ fprintf(fp, " signal: %d", korc->signal);
|
||||||
|
+ if (orc->has_end)
|
||||||
|
fprintf(fp, " end: %d", korc->end);
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,48 @@
|
|||||||
|
From ec1e61b33a705b8be8d116a541c7b076b0429deb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Date: Mon, 12 Jun 2023 18:50:05 +0800
|
||||||
|
Subject: [PATCH 3/5] Fix invalid structure size error during crash startup on
|
||||||
|
ppc64
|
||||||
|
|
||||||
|
The crash utility will fail to start session on ppc64 with the following
|
||||||
|
error:
|
||||||
|
|
||||||
|
# crash vmlinux vmcore -s
|
||||||
|
|
||||||
|
crash: invalid structure size: note_buf
|
||||||
|
FILE: diskdump.c LINE: 121 FUNCTION: have_crash_notes()
|
||||||
|
|
||||||
|
[./crash] error trace: 101859ac => 10291798 => 10291450 => 10266038
|
||||||
|
|
||||||
|
10266038: SIZE_verify+156
|
||||||
|
10291450: have_crash_notes+308
|
||||||
|
10291798: map_cpus_to_prstatus_kdump_cmprs+448
|
||||||
|
101859ac: task_init+11980
|
||||||
|
|
||||||
|
The reason is that the size of note_buf is not initialized before using
|
||||||
|
SIZE(note_buf) in the have_crash_notes() on some architectures including
|
||||||
|
ppc64. Let's initialize it in task_init() to fix this issue.
|
||||||
|
|
||||||
|
Fixes: db8c030857b4 ("diskdump/netdump: fix segmentation fault caused by failure of stopping CPUs")
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
task.c | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/task.c b/task.c
|
||||||
|
index 88941c7b0e4d..2b7467b4193d 100644
|
||||||
|
--- a/task.c
|
||||||
|
+++ b/task.c
|
||||||
|
@@ -675,6 +675,9 @@ task_init(void)
|
||||||
|
tt->this_task = pid_to_task(active_pid);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
+ if (INVALID_SIZE(note_buf))
|
||||||
|
+ STRUCT_SIZE_INIT(note_buf, "note_buf_t");
|
||||||
|
+
|
||||||
|
if (KDUMP_DUMPFILE())
|
||||||
|
map_cpus_to_prstatus();
|
||||||
|
else if (ELF_NOTES_VALID() && DISKDUMP_DUMPFILE())
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,86 @@
|
|||||||
|
From 342cf340ed0386880fe2a3115d6bef32eabb511b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Date: Thu, 18 May 2023 11:48:28 +0900
|
||||||
|
Subject: [PATCH 3/6] Fix "kmem -v" option displaying no regions on Linux 6.3
|
||||||
|
and later
|
||||||
|
|
||||||
|
Kernel commit 869176a09606 ("mm/vmalloc.c: add flags to mark vm_map_ram
|
||||||
|
area"), which is contained in Linux 6.3 and later, added "flags" member
|
||||||
|
to struct vmap_area. This was the revival of the "flags" member as
|
||||||
|
kernel commit 688fcbfc06e4 had eliminated it before.
|
||||||
|
|
||||||
|
As a result, crash started to use the old procedure using the member and
|
||||||
|
displays no vmalloc'd regions, because it does not have the same flag
|
||||||
|
value as the old one.
|
||||||
|
|
||||||
|
crash> kmem -v
|
||||||
|
VMAP_AREA VM_STRUCT ADDRESS RANGE SIZE
|
||||||
|
crash>
|
||||||
|
|
||||||
|
To fix this, also check if vmap_area.purge_list exists, which was
|
||||||
|
introduced with the flags and removed later, to determine that the flags
|
||||||
|
member is the old one.
|
||||||
|
|
||||||
|
Related vmap_area history:
|
||||||
|
v2.6.28 db64fe02258f introduced vmap_area with flags and purge_list
|
||||||
|
v5.4 688fcbfc06e4 removed flags
|
||||||
|
v5.11 96e2db456135 removed purge_list
|
||||||
|
v6.3 869176a09606 added flags again
|
||||||
|
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
defs.h | 1 +
|
||||||
|
memory.c | 4 +++-
|
||||||
|
symbols.c | 1 +
|
||||||
|
3 files changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index 21cc760444d1..bfa07c3f5150 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -2216,6 +2216,7 @@ struct offset_table { /* stash of commonly-used offsets */
|
||||||
|
long in6_addr_in6_u;
|
||||||
|
long kset_kobj;
|
||||||
|
long subsys_private_subsys;
|
||||||
|
+ long vmap_area_purge_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct size_table { /* stash of commonly-used sizes */
|
||||||
|
diff --git a/memory.c b/memory.c
|
||||||
|
index 953fc380c03c..15fa8b2f08f1 100644
|
||||||
|
--- a/memory.c
|
||||||
|
+++ b/memory.c
|
||||||
|
@@ -429,6 +429,7 @@ vm_init(void)
|
||||||
|
MEMBER_OFFSET_INIT(vmap_area_vm, "vmap_area", "vm");
|
||||||
|
if (INVALID_MEMBER(vmap_area_vm))
|
||||||
|
MEMBER_OFFSET_INIT(vmap_area_vm, "vmap_area", "private");
|
||||||
|
+ MEMBER_OFFSET_INIT(vmap_area_purge_list, "vmap_area", "purge_list");
|
||||||
|
STRUCT_SIZE_INIT(vmap_area, "vmap_area");
|
||||||
|
if (VALID_MEMBER(vmap_area_va_start) &&
|
||||||
|
VALID_MEMBER(vmap_area_va_end) &&
|
||||||
|
@@ -9063,7 +9064,8 @@ dump_vmap_area(struct meminfo *vi)
|
||||||
|
readmem(ld->list_ptr[i], KVADDR, vmap_area_buf,
|
||||||
|
SIZE(vmap_area), "vmap_area struct", FAULT_ON_ERROR);
|
||||||
|
|
||||||
|
- if (VALID_MEMBER(vmap_area_flags)) {
|
||||||
|
+ if (VALID_MEMBER(vmap_area_flags) &&
|
||||||
|
+ VALID_MEMBER(vmap_area_purge_list)) {
|
||||||
|
flags = ULONG(vmap_area_buf + OFFSET(vmap_area_flags));
|
||||||
|
if (flags != VM_VM_AREA)
|
||||||
|
continue;
|
||||||
|
diff --git a/symbols.c b/symbols.c
|
||||||
|
index f0721023816d..7b1d59203b90 100644
|
||||||
|
--- a/symbols.c
|
||||||
|
+++ b/symbols.c
|
||||||
|
@@ -9169,6 +9169,7 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
|
OFFSET(vmap_area_vm));
|
||||||
|
fprintf(fp, " vmap_area_flags: %ld\n",
|
||||||
|
OFFSET(vmap_area_flags));
|
||||||
|
+ fprintf(fp, " vmap_area_purge_list: %ld\n", OFFSET(vmap_area_purge_list));
|
||||||
|
|
||||||
|
fprintf(fp, " module_size_of_struct: %ld\n",
|
||||||
|
OFFSET(module_size_of_struct));
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From a295cb40cd5d24fb5995cc78d29c5def3843d285 Mon Sep 17 00:00:00 2001
|
From 0242075b6b4321419790f196c405c088394b9462 Mon Sep 17 00:00:00 2001
|
||||||
From: Lianbo Jiang <lijiang@redhat.com>
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
Date: Mon, 23 May 2022 18:04:14 +0800
|
Date: Mon, 23 May 2022 18:04:14 +0800
|
||||||
Subject: [PATCH 03/18] sbitmapq: fix invalid offset for
|
Subject: [PATCH 03/89] sbitmapq: fix invalid offset for
|
||||||
"sbitmap_queue_alloc_hint" on Linux v5.13-rc1
|
"sbitmap_queue_alloc_hint" on Linux v5.13-rc1
|
||||||
|
|
||||||
Kernel commit c548e62bcf6a ("scsi: sbitmap: Move allocation hint
|
Kernel commit c548e62bcf6a ("scsi: sbitmap: Move allocation hint
|
||||||
@ -21,7 +21,7 @@ Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
|||||||
3 files changed, 16 insertions(+), 2 deletions(-)
|
3 files changed, 16 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
diff --git a/defs.h b/defs.h
|
diff --git a/defs.h b/defs.h
|
||||||
index a6735d07b32f..0aeb98c4f654 100644
|
index 984348062bcb..8b4cc38f73bf 100644
|
||||||
--- a/defs.h
|
--- a/defs.h
|
||||||
+++ b/defs.h
|
+++ b/defs.h
|
||||||
@@ -2168,6 +2168,7 @@ struct offset_table { /* stash of commonly-used offsets */
|
@@ -2168,6 +2168,7 @@ struct offset_table { /* stash of commonly-used offsets */
|
||||||
@ -32,7 +32,7 @@ index a6735d07b32f..0aeb98c4f654 100644
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct size_table { /* stash of commonly-used sizes */
|
struct size_table { /* stash of commonly-used sizes */
|
||||||
@@ -5907,6 +5908,7 @@ struct sbitmap_context {
|
@@ -5915,6 +5916,7 @@ struct sbitmap_context {
|
||||||
unsigned shift;
|
unsigned shift;
|
||||||
unsigned map_nr;
|
unsigned map_nr;
|
||||||
ulong map_addr;
|
ulong map_addr;
|
||||||
@ -101,10 +101,10 @@ index 7693eef6cebd..2921d5447c65 100644
|
|||||||
MEMBER_OFFSET_INIT(sbitmap_queue_sb, "sbitmap_queue", "sb");
|
MEMBER_OFFSET_INIT(sbitmap_queue_sb, "sbitmap_queue", "sb");
|
||||||
MEMBER_OFFSET_INIT(sbitmap_queue_alloc_hint, "sbitmap_queue", "alloc_hint");
|
MEMBER_OFFSET_INIT(sbitmap_queue_alloc_hint, "sbitmap_queue", "alloc_hint");
|
||||||
diff --git a/symbols.c b/symbols.c
|
diff --git a/symbols.c b/symbols.c
|
||||||
index ba5e2741347d..fd0eb06899f0 100644
|
index 4afbc227da97..d5ce3e0873a1 100644
|
||||||
--- a/symbols.c
|
--- a/symbols.c
|
||||||
+++ b/symbols.c
|
+++ b/symbols.c
|
||||||
@@ -10708,6 +10708,8 @@ dump_offset_table(char *spec, ulong makestruct)
|
@@ -10720,6 +10720,8 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
OFFSET(sbitmap_map_nr));
|
OFFSET(sbitmap_map_nr));
|
||||||
fprintf(fp, " sbitmap_map: %ld\n",
|
fprintf(fp, " sbitmap_map: %ld\n",
|
||||||
OFFSET(sbitmap_map));
|
OFFSET(sbitmap_map));
|
||||||
@ -114,5 +114,5 @@ index ba5e2741347d..fd0eb06899f0 100644
|
|||||||
OFFSET(sbitmap_queue_sb));
|
OFFSET(sbitmap_queue_sb));
|
||||||
fprintf(fp, " sbitmap_queue_alloc_hint: %ld\n",
|
fprintf(fp, " sbitmap_queue_alloc_hint: %ld\n",
|
||||||
--
|
--
|
||||||
2.30.2
|
2.37.1
|
||||||
|
|
||||||
|
@ -0,0 +1,68 @@
|
|||||||
|
From 91a76958e4a8a9fb67ac61166ff36e8dc961b3b9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
|
||||||
|
Date: Wed, 7 Jun 2023 18:37:33 +0900
|
||||||
|
Subject: [PATCH 4/5] Revert "Fix segfault in arm64_is_kernel_exception_frame()
|
||||||
|
when corrupt stack pointer address is given"
|
||||||
|
|
||||||
|
This reverts commit 9868ebc8e648e5791764a51567a23efae7170d9b.
|
||||||
|
|
||||||
|
The commit 9868ebc8e648e5791764a51567a23efae7170d9b causes the issue
|
||||||
|
that bt command fails to show backtraces for the tasks that is running
|
||||||
|
in the user mode at the moment of the kernel panic as follows:
|
||||||
|
|
||||||
|
crash> bt 1734
|
||||||
|
PID: 1734 TASK: ffff000000392200 CPU: 4 COMMAND: "insmod"
|
||||||
|
bt: invalid stack pointer is given
|
||||||
|
|
||||||
|
The root cause is that while the commit added a sanity check into
|
||||||
|
STACK_OFFSET_TYPE() to validate if a given candidate address of any
|
||||||
|
interrupt or exception frame is contained within the range of the
|
||||||
|
corresponding kernel stack, the premise that the STACK_OFFSET_TYPE()
|
||||||
|
should not return out-of-the-buffer address, is wrong.
|
||||||
|
|
||||||
|
Reexamining the relevant surrounding part of the backtracing code, it
|
||||||
|
looks to me now that the STACK_OFFSET_TYPE() is originally expected to
|
||||||
|
return an out-of-the-buffer address, like the address of the top of
|
||||||
|
the corresponding kernel stack, e.g. at here:
|
||||||
|
|
||||||
|
static int
|
||||||
|
arm64_in_kdump_text(struct bt_info *bt, struct arm64_stackframe *frame)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
if (bt->flags & BT_USER_SPACE)
|
||||||
|
start = (ulong *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(bt->stacktop))];
|
||||||
|
else {
|
||||||
|
|
||||||
|
Note that the above bt 1734 aborts here.
|
||||||
|
|
||||||
|
Hence, the current implementation policy around STACK_OFFSET_TYPE()
|
||||||
|
looks that the caller side is responsible for understanding the fact
|
||||||
|
in advance and for avoiding making buffer overrun carefully.
|
||||||
|
|
||||||
|
To fix this issue, revert the commit.
|
||||||
|
|
||||||
|
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
defs.h | 5 +----
|
||||||
|
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index bfda0c48d37b..3e7d6cfbc6a8 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -976,10 +976,7 @@ struct bt_info {
|
||||||
|
|
||||||
|
#define STACK_OFFSET_TYPE(OFF) \
|
||||||
|
(((ulong)(OFF) > STACKSIZE()) ? \
|
||||||
|
- (((ulong)(OFF) < (ulong)(bt->stackbase) || (ulong)(OFF) >= (ulong)(bt->stackbase) + STACKSIZE()) ? \
|
||||||
|
- error(FATAL, "invalid stack pointer is given\n") : \
|
||||||
|
- (ulong)((ulong)(OFF) - (ulong)(bt->stackbase))) : \
|
||||||
|
- (ulong)(OFF))
|
||||||
|
+ (ulong)((ulong)(OFF) - (ulong)(bt->stackbase)) : (ulong)(OFF))
|
||||||
|
|
||||||
|
#define GET_STACK_ULONG(OFF) \
|
||||||
|
*((ulong *)((char *)(&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(OFF))])))
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,225 @@
|
|||||||
|
From a0eceb041dfa248d66f9f9a455106184b7823bec Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rongwei Wang <rongwei.wang@linux.alibaba.com>
|
||||||
|
Date: Mon, 29 May 2023 19:55:51 +0800
|
||||||
|
Subject: [PATCH 4/6] arm64/x86_64: Enhance "vtop" command to show zero_pfn
|
||||||
|
information
|
||||||
|
|
||||||
|
Enhance the "vtop" command to show "ZERO PAGE" information when PTE or
|
||||||
|
PMD has attached to {huge_}zero_pfn. For example:
|
||||||
|
|
||||||
|
crash> vtop -c 13674 ffff8917e000
|
||||||
|
VIRTUAL PHYSICAL
|
||||||
|
ffff8917e000 836e71000
|
||||||
|
|
||||||
|
PAGE DIRECTORY: ffff000802f8d000
|
||||||
|
PGD: ffff000802f8dff8 => 884e29003
|
||||||
|
PUD: ffff000844e29ff0 => 884e93003
|
||||||
|
PMD: ffff000844e93240 => 840413003
|
||||||
|
PTE: ffff000800413bf0 => 160000836e71fc3
|
||||||
|
PAGE: 836e71000 (ZERO PAGE)
|
||||||
|
...
|
||||||
|
|
||||||
|
Hugepage case:
|
||||||
|
crash> vtop -c 14538 ffff95800000
|
||||||
|
VIRTUAL PHYSICAL
|
||||||
|
ffff95800000 910c00000
|
||||||
|
|
||||||
|
PAGE DIRECTORY: ffff000801fa0000
|
||||||
|
PGD: ffff000801fa0ff8 => 884f53003
|
||||||
|
PUD: ffff000844f53ff0 => 8426cb003
|
||||||
|
PMD: ffff0008026cb560 => 60000910c00fc1
|
||||||
|
PAGE: 910c00000 (2MB, ZERO PAGE)
|
||||||
|
...
|
||||||
|
|
||||||
|
Note that
|
||||||
|
1. support displaying zero page only for THP (except for 1G THP)
|
||||||
|
2. do not support hugetlb cases.
|
||||||
|
|
||||||
|
Signed-off-by: Rongwei Wang <rongwei.wang@linux.alibaba.com>
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
arm64.c | 24 ++++++++++++++++--------
|
||||||
|
defs.h | 5 +++++
|
||||||
|
memory.c | 23 +++++++++++++++++++++++
|
||||||
|
x86_64.c | 9 +++++----
|
||||||
|
4 files changed, 49 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arm64.c b/arm64.c
|
||||||
|
index 56fb841f43f8..efbdccbec9d3 100644
|
||||||
|
--- a/arm64.c
|
||||||
|
+++ b/arm64.c
|
||||||
|
@@ -1787,7 +1787,8 @@ arm64_vtop_2level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
|
||||||
|
if ((pgd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
|
||||||
|
ulong sectionbase = (pgd_val & SECTION_PAGE_MASK_512MB) & PHYS_MASK;
|
||||||
|
if (verbose) {
|
||||||
|
- fprintf(fp, " PAGE: %lx (512MB)\n\n", sectionbase);
|
||||||
|
+ fprintf(fp, " PAGE: %lx (512MB%s)\n\n", sectionbase,
|
||||||
|
+ IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" : "");
|
||||||
|
arm64_translate_pte(pgd_val, 0, 0);
|
||||||
|
}
|
||||||
|
*paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_512MB);
|
||||||
|
@@ -1806,7 +1807,8 @@ arm64_vtop_2level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
|
||||||
|
if (pte_val & PTE_VALID) {
|
||||||
|
*paddr = (PAGEBASE(pte_val) & PHYS_MASK) + PAGEOFFSET(vaddr);
|
||||||
|
if (verbose) {
|
||||||
|
- fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr));
|
||||||
|
+ fprintf(fp, " PAGE: %lx %s\n\n", PAGEBASE(*paddr),
|
||||||
|
+ IS_ZEROPAGE(PAGEBASE(*paddr)) ? "(ZERO PAGE)" : "");
|
||||||
|
arm64_translate_pte(pte_val, 0, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
@@ -1859,7 +1861,8 @@ arm64_vtop_3level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
|
||||||
|
if ((pmd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
|
||||||
|
ulong sectionbase = PTE_TO_PHYS(pmd_val) & SECTION_PAGE_MASK_512MB;
|
||||||
|
if (verbose) {
|
||||||
|
- fprintf(fp, " PAGE: %lx (512MB)\n\n", sectionbase);
|
||||||
|
+ fprintf(fp, " PAGE: %lx (512MB%s)\n\n", sectionbase,
|
||||||
|
+ IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" : "");
|
||||||
|
arm64_translate_pte(pmd_val, 0, 0);
|
||||||
|
}
|
||||||
|
*paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_512MB);
|
||||||
|
@@ -1878,7 +1881,8 @@ arm64_vtop_3level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
|
||||||
|
if (pte_val & PTE_VALID) {
|
||||||
|
*paddr = PTE_TO_PHYS(pte_val) + PAGEOFFSET(vaddr);
|
||||||
|
if (verbose) {
|
||||||
|
- fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr));
|
||||||
|
+ fprintf(fp, " PAGE: %lx %s\n\n", PAGEBASE(*paddr),
|
||||||
|
+ IS_ZEROPAGE(PAGEBASE(*paddr)) ? "(ZERO PAGE)" : "");
|
||||||
|
arm64_translate_pte(pte_val, 0, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
@@ -1940,7 +1944,8 @@ arm64_vtop_3level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
|
||||||
|
if ((pmd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
|
||||||
|
ulong sectionbase = (pmd_val & SECTION_PAGE_MASK_2MB) & PHYS_MASK;
|
||||||
|
if (verbose) {
|
||||||
|
- fprintf(fp, " PAGE: %lx (2MB)\n\n", sectionbase);
|
||||||
|
+ fprintf(fp, " PAGE: %lx (2MB%s)\n\n", sectionbase,
|
||||||
|
+ IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" : "");
|
||||||
|
arm64_translate_pte(pmd_val, 0, 0);
|
||||||
|
}
|
||||||
|
*paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_2MB);
|
||||||
|
@@ -1959,7 +1964,8 @@ arm64_vtop_3level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
|
||||||
|
if (pte_val & PTE_VALID) {
|
||||||
|
*paddr = (PAGEBASE(pte_val) & PHYS_MASK) + PAGEOFFSET(vaddr);
|
||||||
|
if (verbose) {
|
||||||
|
- fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr));
|
||||||
|
+ fprintf(fp, " PAGE: %lx %s\n\n", PAGEBASE(*paddr),
|
||||||
|
+ IS_ZEROPAGE(PAGEBASE(*paddr)) ? "(ZERO PAGE)" : "");
|
||||||
|
arm64_translate_pte(pte_val, 0, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
@@ -2029,7 +2035,8 @@ arm64_vtop_4level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
|
||||||
|
if ((pmd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
|
||||||
|
ulong sectionbase = (pmd_val & SECTION_PAGE_MASK_2MB) & PHYS_MASK;
|
||||||
|
if (verbose) {
|
||||||
|
- fprintf(fp, " PAGE: %lx (2MB)\n\n", sectionbase);
|
||||||
|
+ fprintf(fp, " PAGE: %lx (2MB%s)\n\n", sectionbase,
|
||||||
|
+ IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" : "");
|
||||||
|
arm64_translate_pte(pmd_val, 0, 0);
|
||||||
|
}
|
||||||
|
*paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_2MB);
|
||||||
|
@@ -2048,7 +2055,8 @@ arm64_vtop_4level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
|
||||||
|
if (pte_val & PTE_VALID) {
|
||||||
|
*paddr = (PAGEBASE(pte_val) & PHYS_MASK) + PAGEOFFSET(vaddr);
|
||||||
|
if (verbose) {
|
||||||
|
- fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr));
|
||||||
|
+ fprintf(fp, " PAGE: %lx %s\n\n", PAGEBASE(*paddr),
|
||||||
|
+ IS_ZEROPAGE(PAGEBASE(*paddr)) ? "(ZERO PAGE)" : "");
|
||||||
|
arm64_translate_pte(pte_val, 0, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index bfa07c3f5150..7d8bb8ab3de1 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -2619,6 +2619,8 @@ struct vm_table { /* kernel VM-related data */
|
||||||
|
char *name;
|
||||||
|
} *pageflags_data;
|
||||||
|
ulong max_mem_section_nr;
|
||||||
|
+ ulong zero_paddr;
|
||||||
|
+ ulong huge_zero_paddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NODES (0x1)
|
||||||
|
@@ -3000,6 +3002,9 @@ struct load_module {
|
||||||
|
#define VIRTPAGEBASE(X) (((ulong)(X)) & (ulong)machdep->pagemask)
|
||||||
|
#define PHYSPAGEBASE(X) (((physaddr_t)(X)) & (physaddr_t)machdep->pagemask)
|
||||||
|
|
||||||
|
+#define IS_ZEROPAGE(paddr) ((paddr) == vt->zero_paddr || \
|
||||||
|
+ (paddr) == vt->huge_zero_paddr)
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Sparse memory stuff
|
||||||
|
* These must follow the definitions in the kernel mmzone.h
|
||||||
|
diff --git a/memory.c b/memory.c
|
||||||
|
index 15fa8b2f08f1..ea3005a5c01f 100644
|
||||||
|
--- a/memory.c
|
||||||
|
+++ b/memory.c
|
||||||
|
@@ -1209,6 +1209,27 @@ vm_init(void)
|
||||||
|
machdep->memory_size()));
|
||||||
|
vt->paddr_prlen = strlen(buf);
|
||||||
|
|
||||||
|
+ vt->zero_paddr = ~0UL;
|
||||||
|
+ if (kernel_symbol_exists("zero_pfn")) {
|
||||||
|
+ ulong zero_pfn;
|
||||||
|
+
|
||||||
|
+ if (readmem(symbol_value("zero_pfn"), KVADDR,
|
||||||
|
+ &zero_pfn, sizeof(zero_pfn),
|
||||||
|
+ "read zero_pfn", QUIET|RETURN_ON_ERROR))
|
||||||
|
+ vt->zero_paddr = zero_pfn << PAGESHIFT();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ vt->huge_zero_paddr = ~0UL;
|
||||||
|
+ if (kernel_symbol_exists("huge_zero_pfn")) {
|
||||||
|
+ ulong huge_zero_pfn;
|
||||||
|
+
|
||||||
|
+ if (readmem(symbol_value("huge_zero_pfn"), KVADDR,
|
||||||
|
+ &huge_zero_pfn, sizeof(huge_zero_pfn),
|
||||||
|
+ "read huge_zero_pfn", QUIET|RETURN_ON_ERROR) &&
|
||||||
|
+ huge_zero_pfn != ~0UL)
|
||||||
|
+ vt->huge_zero_paddr = huge_zero_pfn << PAGESHIFT();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (vt->flags & PERCPU_KMALLOC_V1)
|
||||||
|
vt->dump_kmem_cache = dump_kmem_cache_percpu_v1;
|
||||||
|
else if (vt->flags & PERCPU_KMALLOC_V2)
|
||||||
|
@@ -14065,6 +14086,8 @@ dump_vm_table(int verbose)
|
||||||
|
} else {
|
||||||
|
fprintf(fp, " node_online_map: (unused)\n");
|
||||||
|
}
|
||||||
|
+ fprintf(fp, " zero_paddr: %lx\n", vt->zero_paddr);
|
||||||
|
+ fprintf(fp, " huge_zero_paddr: %lx\n", vt->huge_zero_paddr);
|
||||||
|
fprintf(fp, " nr_vm_stat_items: %d\n", vt->nr_vm_stat_items);
|
||||||
|
fprintf(fp, " vm_stat_items: %s", (vt->flags & VM_STAT) ?
|
||||||
|
"\n" : "(not used)\n");
|
||||||
|
diff --git a/x86_64.c b/x86_64.c
|
||||||
|
index 5019c69e452e..693a08bea758 100644
|
||||||
|
--- a/x86_64.c
|
||||||
|
+++ b/x86_64.c
|
||||||
|
@@ -2114,8 +2114,9 @@ x86_64_uvtop_level4(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, in
|
||||||
|
goto no_upage;
|
||||||
|
if (pmd_pte & _PAGE_PSE) {
|
||||||
|
if (verbose) {
|
||||||
|
- fprintf(fp, " PAGE: %lx (2MB)\n\n",
|
||||||
|
- PAGEBASE(pmd_pte) & PHYSICAL_PAGE_MASK);
|
||||||
|
+ fprintf(fp, " PAGE: %lx (2MB%s)\n\n",
|
||||||
|
+ PAGEBASE(pmd_pte) & PHYSICAL_PAGE_MASK,
|
||||||
|
+ IS_ZEROPAGE(PAGEBASE(pmd_pte) & PHYSICAL_PAGE_MASK) ? ", ZERO PAGE" : "");
|
||||||
|
x86_64_translate_pte(pmd_pte, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2143,8 +2144,8 @@ x86_64_uvtop_level4(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, in
|
||||||
|
*paddr = (PAGEBASE(pte) & PHYSICAL_PAGE_MASK) + PAGEOFFSET(uvaddr);
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
- fprintf(fp, " PAGE: %lx\n\n",
|
||||||
|
- PAGEBASE(*paddr) & PHYSICAL_PAGE_MASK);
|
||||||
|
+ fprintf(fp, " PAGE: %lx %s\n\n", PAGEBASE(*paddr) & PHYSICAL_PAGE_MASK,
|
||||||
|
+ IS_ZEROPAGE(PAGEBASE(*paddr) & PHYSICAL_PAGE_MASK) ? "(ZERO PAGE)" : "");
|
||||||
|
x86_64_translate_pte(pte, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From 530fe6ad7e4d7ff6254596c1219d25ed929e3867 Mon Sep 17 00:00:00 2001
|
From ccdf0e45c66ca0bbe3eb468c661b405971801c2e Mon Sep 17 00:00:00 2001
|
||||||
From: Lianbo Jiang <lijiang@redhat.com>
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
Date: Mon, 23 May 2022 18:04:15 +0800
|
Date: Mon, 23 May 2022 18:04:15 +0800
|
||||||
Subject: [PATCH 04/18] sbitmapq: fix invalid offset for
|
Subject: [PATCH 04/89] sbitmapq: fix invalid offset for
|
||||||
"sbitmap_queue_round_robin" on Linux v5.13-rc1
|
"sbitmap_queue_round_robin" on Linux v5.13-rc1
|
||||||
|
|
||||||
Kernel commit efe1f3a1d583 ("scsi: sbitmap: Maintain allocation
|
Kernel commit efe1f3a1d583 ("scsi: sbitmap: Maintain allocation
|
||||||
@ -22,7 +22,7 @@ Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
|||||||
3 files changed, 14 insertions(+), 2 deletions(-)
|
3 files changed, 14 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
diff --git a/defs.h b/defs.h
|
diff --git a/defs.h b/defs.h
|
||||||
index 0aeb98c4f654..ecbced24d2e3 100644
|
index 8b4cc38f73bf..66f74f640d84 100644
|
||||||
--- a/defs.h
|
--- a/defs.h
|
||||||
+++ b/defs.h
|
+++ b/defs.h
|
||||||
@@ -2169,6 +2169,7 @@ struct offset_table { /* stash of commonly-used offsets */
|
@@ -2169,6 +2169,7 @@ struct offset_table { /* stash of commonly-used offsets */
|
||||||
@ -33,7 +33,7 @@ index 0aeb98c4f654..ecbced24d2e3 100644
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct size_table { /* stash of commonly-used sizes */
|
struct size_table { /* stash of commonly-used sizes */
|
||||||
@@ -5909,6 +5910,7 @@ struct sbitmap_context {
|
@@ -5917,6 +5918,7 @@ struct sbitmap_context {
|
||||||
unsigned map_nr;
|
unsigned map_nr;
|
||||||
ulong map_addr;
|
ulong map_addr;
|
||||||
ulong alloc_hint;
|
ulong alloc_hint;
|
||||||
@ -86,10 +86,10 @@ index 2921d5447c65..7b318b533702 100644
|
|||||||
MEMBER_OFFSET_INIT(sbitmap_queue_sb, "sbitmap_queue", "sb");
|
MEMBER_OFFSET_INIT(sbitmap_queue_sb, "sbitmap_queue", "sb");
|
||||||
MEMBER_OFFSET_INIT(sbitmap_queue_alloc_hint, "sbitmap_queue", "alloc_hint");
|
MEMBER_OFFSET_INIT(sbitmap_queue_alloc_hint, "sbitmap_queue", "alloc_hint");
|
||||||
diff --git a/symbols.c b/symbols.c
|
diff --git a/symbols.c b/symbols.c
|
||||||
index fd0eb06899f0..5d12a021c769 100644
|
index d5ce3e0873a1..7431aaecec9d 100644
|
||||||
--- a/symbols.c
|
--- a/symbols.c
|
||||||
+++ b/symbols.c
|
+++ b/symbols.c
|
||||||
@@ -10710,6 +10710,8 @@ dump_offset_table(char *spec, ulong makestruct)
|
@@ -10722,6 +10722,8 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
OFFSET(sbitmap_map));
|
OFFSET(sbitmap_map));
|
||||||
fprintf(fp, " sbitmap_alloc_hint: %ld\n",
|
fprintf(fp, " sbitmap_alloc_hint: %ld\n",
|
||||||
OFFSET(sbitmap_alloc_hint));
|
OFFSET(sbitmap_alloc_hint));
|
||||||
@ -99,5 +99,5 @@ index fd0eb06899f0..5d12a021c769 100644
|
|||||||
OFFSET(sbitmap_queue_sb));
|
OFFSET(sbitmap_queue_sb));
|
||||||
fprintf(fp, " sbitmap_queue_alloc_hint: %ld\n",
|
fprintf(fp, " sbitmap_queue_alloc_hint: %ld\n",
|
||||||
--
|
--
|
||||||
2.30.2
|
2.37.1
|
||||||
|
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
From 6c8cd9b5dcf48221e5f75fc5850bb4719d77acce Mon Sep 17 00:00:00 2001
|
||||||
|
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
|
||||||
|
Date: Wed, 7 Jun 2023 18:37:34 +0900
|
||||||
|
Subject: [PATCH 5/5] arm64: Fix again segfault in
|
||||||
|
arm64_is_kernel_exception_frame() when corrupt stack pointer address is given
|
||||||
|
|
||||||
|
This is the second trial from the commit
|
||||||
|
9868ebc8e648e5791764a51567a23efae7170d9b that was reverted at the
|
||||||
|
previous commit.
|
||||||
|
|
||||||
|
As described in the previous commit, result of STACK_OFFSET_TYPE() can
|
||||||
|
be an address out of bt->stackbuf and hence the address needs to be
|
||||||
|
checked prior to being referred to as an pt_regs object.
|
||||||
|
|
||||||
|
So, to fix the issue, let's check if stkptr points to within the range
|
||||||
|
of the kernel stack first.
|
||||||
|
|
||||||
|
[ kh: added a warning at Lianbo's suggestion ]
|
||||||
|
|
||||||
|
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
arm64.c | 6 ++++++
|
||||||
|
1 file changed, 6 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/arm64.c b/arm64.c
|
||||||
|
index efbdccbec9d3..67b1a2244810 100644
|
||||||
|
--- a/arm64.c
|
||||||
|
+++ b/arm64.c
|
||||||
|
@@ -2381,6 +2381,12 @@ arm64_is_kernel_exception_frame(struct bt_info *bt, ulong stkptr)
|
||||||
|
struct arm64_pt_regs *regs;
|
||||||
|
struct machine_specific *ms = machdep->machspec;
|
||||||
|
|
||||||
|
+ if (stkptr > STACKSIZE() && !INSTACK(stkptr, bt)) {
|
||||||
|
+ if (CRASHDEBUG(1))
|
||||||
|
+ error(WARNING, "stkptr: %lx is outside the kernel stack range\n", stkptr);
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
regs = (struct arm64_pt_regs *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(stkptr))];
|
||||||
|
|
||||||
|
if (INSTACK(regs->sp, bt) && INSTACK(regs->regs[29], bt) &&
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,165 @@
|
|||||||
|
From db8c030857b4e318728c51c20da687906c109d0d Mon Sep 17 00:00:00 2001
|
||||||
|
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
|
||||||
|
Date: Tue, 30 May 2023 19:38:34 +0900
|
||||||
|
Subject: [PATCH 5/6] diskdump/netdump: fix segmentation fault caused by
|
||||||
|
failure of stopping CPUs
|
||||||
|
|
||||||
|
There's no NMI on ARM. Hence, stopping the non-panicking CPUs from the
|
||||||
|
panicking CPU via IPI can fail easily if interrupts are being masked
|
||||||
|
in those moment. Moreover, crash_notes are not initialized for such
|
||||||
|
unstopped CPUs and the corresponding NT_PRSTATUS notes are not
|
||||||
|
attached to vmcore. However, crash utility never takes it
|
||||||
|
consideration such uninitialized crash_notes and then ends with
|
||||||
|
mapping different NT_PRSTATUS to actually unstopped CPUs. This corrupt
|
||||||
|
mapping can result crash utility into segmentation fault in the
|
||||||
|
operations where register values in NT_PRSTATUS notes are used.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
crash> bt 1408
|
||||||
|
PID: 1408 TASK: ffff000003e22200 CPU: 2 COMMAND: "repro"
|
||||||
|
Segmentation fault (core dumped)
|
||||||
|
|
||||||
|
crash> help -D
|
||||||
|
diskdump_data:
|
||||||
|
filename: 127.0.0.1-2023-05-26-02:21:27/vmcore-ld1
|
||||||
|
flags: 46 (KDUMP_CMPRS_LOCAL|ERROR_EXCLUDED|LZO_SUPPORTED)
|
||||||
|
...snip...
|
||||||
|
notes_buf: 1815df0
|
||||||
|
num_vmcoredd_notes: 0
|
||||||
|
num_prstatus_notes: 5
|
||||||
|
notes[0]: 1815df0 (NT_PRSTATUS)
|
||||||
|
si.signo: 0 si.code: 0 si.errno: 0
|
||||||
|
...snip...
|
||||||
|
PSTATE: 80400005 FPVALID: 00000000
|
||||||
|
notes[4]: 1808f10 (NT_PRSTATUS)
|
||||||
|
Segmentation fault (core dumped)
|
||||||
|
|
||||||
|
To fix this issue, let's map NT_PRSTATUS to some CPU only if the
|
||||||
|
corresponding crash_notes is checked to be initialized.
|
||||||
|
|
||||||
|
[ kh: moved existence check for crash_notes out of the loop ]
|
||||||
|
|
||||||
|
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
defs.h | 1 +
|
||||||
|
diskdump.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
netdump.c | 7 ++++++-
|
||||||
|
3 files changed, 51 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index 7d8bb8ab3de1..6520d2f13f48 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -7118,6 +7118,7 @@ int dumpfile_is_split(void);
|
||||||
|
void show_split_dumpfiles(void);
|
||||||
|
void x86_process_elf_notes(void *, unsigned long);
|
||||||
|
void *diskdump_get_prstatus_percpu(int);
|
||||||
|
+int have_crash_notes(int cpu);
|
||||||
|
void map_cpus_to_prstatus_kdump_cmprs(void);
|
||||||
|
void diskdump_display_regs(int, FILE *);
|
||||||
|
void process_elf32_notes(void *, ulong);
|
||||||
|
diff --git a/diskdump.c b/diskdump.c
|
||||||
|
index 94bca4ded572..2c284ff3f97f 100644
|
||||||
|
--- a/diskdump.c
|
||||||
|
+++ b/diskdump.c
|
||||||
|
@@ -101,12 +101,54 @@ int dumpfile_is_split(void)
|
||||||
|
return KDUMP_SPLIT();
|
||||||
|
}
|
||||||
|
|
||||||
|
+int have_crash_notes(int cpu)
|
||||||
|
+{
|
||||||
|
+ ulong crash_notes, notes_ptr;
|
||||||
|
+ char *buf, *p;
|
||||||
|
+ Elf64_Nhdr *note = NULL;
|
||||||
|
+
|
||||||
|
+ if (!readmem(symbol_value("crash_notes"), KVADDR, &crash_notes,
|
||||||
|
+ sizeof(crash_notes), "crash_notes", RETURN_ON_ERROR)) {
|
||||||
|
+ error(WARNING, "cannot read \"crash_notes\"\n");
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF))
|
||||||
|
+ notes_ptr = crash_notes + kt->__per_cpu_offset[cpu];
|
||||||
|
+ else
|
||||||
|
+ notes_ptr = crash_notes;
|
||||||
|
+
|
||||||
|
+ buf = GETBUF(SIZE(note_buf));
|
||||||
|
+
|
||||||
|
+ if (!readmem(notes_ptr, KVADDR, buf,
|
||||||
|
+ SIZE(note_buf), "note_buf_t", RETURN_ON_ERROR)) {
|
||||||
|
+ error(WARNING, "cpu %d: cannot read NT_PRSTATUS note\n", cpu);
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ note = (Elf64_Nhdr *)buf;
|
||||||
|
+ p = buf + sizeof(Elf64_Nhdr);
|
||||||
|
+
|
||||||
|
+ if (note->n_type != NT_PRSTATUS) {
|
||||||
|
+ error(WARNING, "cpu %d: invalid NT_PRSTATUS note (n_type != NT_PRSTATUS)\n", cpu);
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!STRNEQ(p, "CORE")) {
|
||||||
|
+ error(WARNING, "cpu %d: invalid NT_PRSTATUS note (name != \"CORE\")\n", cpu);
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return TRUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
map_cpus_to_prstatus_kdump_cmprs(void)
|
||||||
|
{
|
||||||
|
void **nt_ptr;
|
||||||
|
int online, i, j, nrcpus;
|
||||||
|
size_t size;
|
||||||
|
+ int crash_notes_exists;
|
||||||
|
|
||||||
|
if (pc->flags2 & QEMU_MEM_DUMP_COMPRESSED) /* notes exist for all cpus */
|
||||||
|
goto resize_note_pointers;
|
||||||
|
@@ -129,9 +171,10 @@ map_cpus_to_prstatus_kdump_cmprs(void)
|
||||||
|
* Re-populate the array with the notes mapping to online cpus
|
||||||
|
*/
|
||||||
|
nrcpus = (kt->kernel_NR_CPUS ? kt->kernel_NR_CPUS : NR_CPUS);
|
||||||
|
+ crash_notes_exists = kernel_symbol_exists("crash_notes");
|
||||||
|
|
||||||
|
for (i = 0, j = 0; i < nrcpus; i++) {
|
||||||
|
- if (in_cpu_map(ONLINE_MAP, i)) {
|
||||||
|
+ if (in_cpu_map(ONLINE_MAP, i) && (!crash_notes_exists || have_crash_notes(i))) {
|
||||||
|
dd->nt_prstatus_percpu[i] = nt_ptr[j++];
|
||||||
|
dd->num_prstatus_notes =
|
||||||
|
MAX(dd->num_prstatus_notes, i+1);
|
||||||
|
diff --git a/netdump.c b/netdump.c
|
||||||
|
index 4eba66cecb55..61ddeaa08831 100644
|
||||||
|
--- a/netdump.c
|
||||||
|
+++ b/netdump.c
|
||||||
|
@@ -75,6 +75,7 @@ map_cpus_to_prstatus(void)
|
||||||
|
void **nt_ptr;
|
||||||
|
int online, i, j, nrcpus;
|
||||||
|
size_t size;
|
||||||
|
+ int crash_notes_exists;
|
||||||
|
|
||||||
|
if (pc->flags2 & QEMU_MEM_DUMP_ELF) /* notes exist for all cpus */
|
||||||
|
return;
|
||||||
|
@@ -97,10 +98,14 @@ map_cpus_to_prstatus(void)
|
||||||
|
* Re-populate the array with the notes mapping to online cpus
|
||||||
|
*/
|
||||||
|
nrcpus = (kt->kernel_NR_CPUS ? kt->kernel_NR_CPUS : NR_CPUS);
|
||||||
|
+ crash_notes_exists = kernel_symbol_exists("crash_notes");
|
||||||
|
|
||||||
|
for (i = 0, j = 0; i < nrcpus; i++) {
|
||||||
|
- if (in_cpu_map(ONLINE_MAP, i))
|
||||||
|
+ if (in_cpu_map(ONLINE_MAP, i) && (!crash_notes_exists || have_crash_notes(i))) {
|
||||||
|
nd->nt_prstatus_percpu[i] = nt_ptr[j++];
|
||||||
|
+ nd->num_prstatus_notes =
|
||||||
|
+ MAX(nd->num_prstatus_notes, i+1);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
FREEBUF(nt_ptr);
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From 3750803f6ae5f5ad071f86ca916dbbb17b7a83a5 Mon Sep 17 00:00:00 2001
|
From 0637e7bee77f127ff6a36fc7a9e52408a3106173 Mon Sep 17 00:00:00 2001
|
||||||
From: Lianbo Jiang <lijiang@redhat.com>
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
Date: Mon, 23 May 2022 18:04:16 +0800
|
Date: Mon, 23 May 2022 18:04:16 +0800
|
||||||
Subject: [PATCH 05/18] sbitmapq: fix invalid offset for "sbitmap_word_depth"
|
Subject: [PATCH 05/89] sbitmapq: fix invalid offset for "sbitmap_word_depth"
|
||||||
on Linux v5.18-rc1
|
on Linux v5.18-rc1
|
||||||
|
|
||||||
Kernel commit 3301bc53358a ("lib/sbitmap: kill 'depth' from sbitmap_word")
|
Kernel commit 3301bc53358a ("lib/sbitmap: kill 'depth' from sbitmap_word")
|
||||||
@ -97,5 +97,5 @@ index 7b318b533702..e8ebd62fe01c 100644
|
|||||||
scanned += depth;
|
scanned += depth;
|
||||||
word = w_word & ~w_cleared;
|
word = w_word & ~w_cleared;
|
||||||
--
|
--
|
||||||
2.30.2
|
2.37.1
|
||||||
|
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
From 9868ebc8e648e5791764a51567a23efae7170d9b Mon Sep 17 00:00:00 2001
|
||||||
|
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
|
||||||
|
Date: Tue, 30 May 2023 19:38:35 +0900
|
||||||
|
Subject: [PATCH 6/6] Fix segfault in arm64_is_kernel_exception_frame() when
|
||||||
|
corrupt stack pointer address is given
|
||||||
|
|
||||||
|
Due to the corrupted mapping fixed by the previous commit,
|
||||||
|
arm64_is_kernel_exception_frame() can receive invalid stack pointer
|
||||||
|
address via the 2nd argument; different NT_PRSTATUS contains different
|
||||||
|
task's stack pointer address. However, macro STACK_OFFSET_TYPE() never
|
||||||
|
checks if a given address is within the range of the kernel stack of
|
||||||
|
the corresponding task and hence can result in referring to outside of
|
||||||
|
bt->stackbuf.
|
||||||
|
|
||||||
|
static int
|
||||||
|
arm64_is_kernel_exception_frame(struct bt_info *bt, ulong stkptr)
|
||||||
|
{
|
||||||
|
struct arm64_pt_regs *regs;
|
||||||
|
struct machine_specific *ms = machdep->machspec;
|
||||||
|
|
||||||
|
regs = (struct arm64_pt_regs *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(stkptr))];
|
||||||
|
|
||||||
|
=> if (INSTACK(regs->sp, bt) && INSTACK(regs->regs[29], bt) &&
|
||||||
|
!(regs->pstate & (0xffffffff00000000ULL | PSR_MODE32_BIT)) &&
|
||||||
|
is_kernel_text(regs->pc) &&
|
||||||
|
is_kernel_text(regs->regs[30] | ms->CONFIG_ARM64_KERNELPACMASK)) {
|
||||||
|
|
||||||
|
To fix this issue, check if the given stack pointer address points to
|
||||||
|
the range of the kernel stack of the corresponding task, and abort if
|
||||||
|
it turns out to be invalid.
|
||||||
|
|
||||||
|
Although the corrupted mapping has already been fixed, this fix is
|
||||||
|
still needed because corrupt stack pointer address can still be passed
|
||||||
|
here from different reasons. Consider, for example, that data on the
|
||||||
|
kernel stack can be modified abnormally due to any kernel bugs or
|
||||||
|
hardware issues.
|
||||||
|
|
||||||
|
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
defs.h | 5 ++++-
|
||||||
|
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index 6520d2f13f48..11fdc17e60d0 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -976,7 +976,10 @@ struct bt_info {
|
||||||
|
|
||||||
|
#define STACK_OFFSET_TYPE(OFF) \
|
||||||
|
(((ulong)(OFF) > STACKSIZE()) ? \
|
||||||
|
- (ulong)((ulong)(OFF) - (ulong)(bt->stackbase)) : (ulong)(OFF))
|
||||||
|
+ (((ulong)(OFF) < (ulong)(bt->stackbase) || (ulong)(OFF) >= (ulong)(bt->stackbase) + STACKSIZE()) ? \
|
||||||
|
+ error(FATAL, "invalid stack pointer is given\n") : \
|
||||||
|
+ (ulong)((ulong)(OFF) - (ulong)(bt->stackbase))) : \
|
||||||
|
+ (ulong)(OFF))
|
||||||
|
|
||||||
|
#define GET_STACK_ULONG(OFF) \
|
||||||
|
*((ulong *)((char *)(&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(OFF))])))
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From 6833262bf87177d8affe4f91b2e7d2c76ecdf636 Mon Sep 17 00:00:00 2001
|
From 3ce590be037dc11c31a013e435484926276eee9f Mon Sep 17 00:00:00 2001
|
||||||
From: Qi Zheng <zhengqi.arch@bytedance.com>
|
From: Qi Zheng <zhengqi.arch@bytedance.com>
|
||||||
Date: Tue, 24 May 2022 20:25:53 +0800
|
Date: Tue, 24 May 2022 20:25:53 +0800
|
||||||
Subject: [PATCH 07/18] bt: x86_64: filter out idle task stack
|
Subject: [PATCH 06/89] bt: x86_64: filter out idle task stack
|
||||||
|
|
||||||
When we use crash to troubleshoot softlockup and other problems,
|
When we use crash to troubleshoot softlockup and other problems,
|
||||||
we often use the 'bt -a' command to print the stacks of running
|
we often use the 'bt -a' command to print the stacks of running
|
||||||
@ -62,10 +62,10 @@ Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
|||||||
4 files changed, 53 insertions(+), 2 deletions(-)
|
4 files changed, 53 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
diff --git a/defs.h b/defs.h
|
diff --git a/defs.h b/defs.h
|
||||||
index ecbced24d2e3..c8444b4e54eb 100644
|
index 66f74f640d84..52e4b14aa27c 100644
|
||||||
--- a/defs.h
|
--- a/defs.h
|
||||||
+++ b/defs.h
|
+++ b/defs.h
|
||||||
@@ -5832,6 +5832,7 @@ ulong cpu_map_addr(const char *type);
|
@@ -5840,6 +5840,7 @@ ulong cpu_map_addr(const char *type);
|
||||||
#define BT_SHOW_ALL_REGS (0x2000000000000ULL)
|
#define BT_SHOW_ALL_REGS (0x2000000000000ULL)
|
||||||
#define BT_REGS_NOT_FOUND (0x4000000000000ULL)
|
#define BT_REGS_NOT_FOUND (0x4000000000000ULL)
|
||||||
#define BT_OVERFLOW_STACK (0x8000000000000ULL)
|
#define BT_OVERFLOW_STACK (0x8000000000000ULL)
|
||||||
@ -74,10 +74,10 @@ index ecbced24d2e3..c8444b4e54eb 100644
|
|||||||
|
|
||||||
#define BT_REF_HEXVAL (0x1)
|
#define BT_REF_HEXVAL (0x1)
|
||||||
diff --git a/help.c b/help.c
|
diff --git a/help.c b/help.c
|
||||||
index 51a0fe3d687c..e1bbc5abe029 100644
|
index 00712a690593..00c833da13cc 100644
|
||||||
--- a/help.c
|
--- a/help.c
|
||||||
+++ b/help.c
|
+++ b/help.c
|
||||||
@@ -1909,12 +1909,14 @@ char *help_bt[] = {
|
@@ -1915,12 +1915,14 @@ char *help_bt[] = {
|
||||||
"bt",
|
"bt",
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"[-a|-c cpu(s)|-g|-r|-t|-T|-l|-e|-E|-f|-F|-o|-O|-v|-p] [-R ref] [-s [-x|d]]"
|
"[-a|-c cpu(s)|-g|-r|-t|-T|-l|-e|-E|-f|-F|-o|-O|-v|-p] [-R ref] [-s [-x|d]]"
|
||||||
@ -93,7 +93,7 @@ index 51a0fe3d687c..e1bbc5abe029 100644
|
|||||||
" -p display the stack trace of the panic task only.",
|
" -p display the stack trace of the panic task only.",
|
||||||
" (only applicable to crash dumps)",
|
" (only applicable to crash dumps)",
|
||||||
" -c cpu display the stack trace of the active task on one or more CPUs,",
|
" -c cpu display the stack trace of the active task on one or more CPUs,",
|
||||||
@@ -2004,6 +2006,35 @@ char *help_bt[] = {
|
@@ -2010,6 +2012,35 @@ char *help_bt[] = {
|
||||||
" DS: 002b ESI: bfffc8a0 ES: 002b EDI: 00000000 ",
|
" DS: 002b ESI: bfffc8a0 ES: 002b EDI: 00000000 ",
|
||||||
" SS: 002b ESP: bfffc82c EBP: bfffd224 ",
|
" SS: 002b ESP: bfffc82c EBP: bfffd224 ",
|
||||||
" CS: 0023 EIP: 400d032e ERR: 0000008e EFLAGS: 00000246 ",
|
" CS: 0023 EIP: 400d032e ERR: 0000008e EFLAGS: 00000246 ",
|
||||||
@ -130,7 +130,7 @@ index 51a0fe3d687c..e1bbc5abe029 100644
|
|||||||
" %s> bt -c 0,1",
|
" %s> bt -c 0,1",
|
||||||
" PID: 0 TASK: ffffffff81a8d020 CPU: 0 COMMAND: \"swapper\"",
|
" PID: 0 TASK: ffffffff81a8d020 CPU: 0 COMMAND: \"swapper\"",
|
||||||
diff --git a/kernel.c b/kernel.c
|
diff --git a/kernel.c b/kernel.c
|
||||||
index d0921cf567d9..411e9da1e54f 100644
|
index 9ae7ee1ebe64..185b09335733 100644
|
||||||
--- a/kernel.c
|
--- a/kernel.c
|
||||||
+++ b/kernel.c
|
+++ b/kernel.c
|
||||||
@@ -2503,7 +2503,7 @@ cmd_bt(void)
|
@@ -2503,7 +2503,7 @@ cmd_bt(void)
|
||||||
@ -168,10 +168,10 @@ index d0921cf567d9..411e9da1e54f 100644
|
|||||||
bt->stkptr = esp;
|
bt->stkptr = esp;
|
||||||
return;
|
return;
|
||||||
diff --git a/x86_64.c b/x86_64.c
|
diff --git a/x86_64.c b/x86_64.c
|
||||||
index ecaefd2f46a8..cfafbcc4dabe 100644
|
index 1305afd791a1..f4e5d9e77cef 100644
|
||||||
--- a/x86_64.c
|
--- a/x86_64.c
|
||||||
+++ b/x86_64.c
|
+++ b/x86_64.c
|
||||||
@@ -4918,6 +4918,9 @@ x86_64_get_stack_frame(struct bt_info *bt, ulong *pcp, ulong *spp)
|
@@ -4915,6 +4915,9 @@ x86_64_get_stack_frame(struct bt_info *bt, ulong *pcp, ulong *spp)
|
||||||
if (bt->flags & BT_DUMPFILE_SEARCH)
|
if (bt->flags & BT_DUMPFILE_SEARCH)
|
||||||
return x86_64_get_dumpfile_stack_frame(bt, pcp, spp);
|
return x86_64_get_dumpfile_stack_frame(bt, pcp, spp);
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ index ecaefd2f46a8..cfafbcc4dabe 100644
|
|||||||
if (pcp)
|
if (pcp)
|
||||||
*pcp = x86_64_get_pc(bt);
|
*pcp = x86_64_get_pc(bt);
|
||||||
if (spp)
|
if (spp)
|
||||||
@@ -4960,6 +4963,9 @@ x86_64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *rip, ulong *rsp)
|
@@ -4957,6 +4960,9 @@ x86_64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *rip, ulong *rsp)
|
||||||
estack = -1;
|
estack = -1;
|
||||||
panic = FALSE;
|
panic = FALSE;
|
||||||
|
|
||||||
@ -191,7 +191,7 @@ index ecaefd2f46a8..cfafbcc4dabe 100644
|
|||||||
panic_task = tt->panic_task == bt->task ? TRUE : FALSE;
|
panic_task = tt->panic_task == bt->task ? TRUE : FALSE;
|
||||||
|
|
||||||
if (panic_task && bt->machdep) {
|
if (panic_task && bt->machdep) {
|
||||||
@@ -5098,6 +5104,8 @@ next_sysrq:
|
@@ -5095,6 +5101,8 @@ next_sysrq:
|
||||||
if (!panic_task && STREQ(sym, "crash_nmi_callback")) {
|
if (!panic_task && STREQ(sym, "crash_nmi_callback")) {
|
||||||
*rip = *up;
|
*rip = *up;
|
||||||
*rsp = bt->stackbase + ((char *)(up) - bt->stackbuf);
|
*rsp = bt->stackbase + ((char *)(up) - bt->stackbuf);
|
||||||
@ -201,5 +201,5 @@ index ecaefd2f46a8..cfafbcc4dabe 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
--
|
--
|
||||||
2.30.2
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From 0f162febebc4d11a165dd40cee00f3b0ba691a52 Mon Sep 17 00:00:00 2001
|
From f436ae7f01db8ec13080f41a2754b2d282166ed7 Mon Sep 17 00:00:00 2001
|
||||||
From: Qi Zheng <zhengqi.arch@bytedance.com>
|
From: Qi Zheng <zhengqi.arch@bytedance.com>
|
||||||
Date: Tue, 24 May 2022 20:25:54 +0800
|
Date: Tue, 24 May 2022 20:25:54 +0800
|
||||||
Subject: [PATCH 08/18] bt: arm64: add support for 'bt -n idle'
|
Subject: [PATCH 07/89] bt: arm64: add support for 'bt -n idle'
|
||||||
|
|
||||||
The '-n idle' option of bt command can help us filter the
|
The '-n idle' option of bt command can help us filter the
|
||||||
stack of the idle process when debugging the dumpfiles
|
stack of the idle process when debugging the dumpfiles
|
||||||
@ -65,10 +65,10 @@ index 65f6cdf69fa6..0f615cf52bef 100644
|
|||||||
if (!ret)
|
if (!ret)
|
||||||
error(WARNING,
|
error(WARNING,
|
||||||
diff --git a/help.c b/help.c
|
diff --git a/help.c b/help.c
|
||||||
index e1bbc5abe029..99214c1590fa 100644
|
index 00c833da13cc..e1ac6f93fde2 100644
|
||||||
--- a/help.c
|
--- a/help.c
|
||||||
+++ b/help.c
|
+++ b/help.c
|
||||||
@@ -1915,7 +1915,7 @@ char *help_bt[] = {
|
@@ -1921,7 +1921,7 @@ char *help_bt[] = {
|
||||||
" -a displays the stack traces of the active task on each CPU.",
|
" -a displays the stack traces of the active task on each CPU.",
|
||||||
" (only applicable to crash dumps)",
|
" (only applicable to crash dumps)",
|
||||||
" -A same as -a, but also displays vector registers (S390X only).",
|
" -A same as -a, but also displays vector registers (S390X only).",
|
||||||
@ -78,7 +78,7 @@ index e1bbc5abe029..99214c1590fa 100644
|
|||||||
" -p display the stack trace of the panic task only.",
|
" -p display the stack trace of the panic task only.",
|
||||||
" (only applicable to crash dumps)",
|
" (only applicable to crash dumps)",
|
||||||
diff --git a/kernel.c b/kernel.c
|
diff --git a/kernel.c b/kernel.c
|
||||||
index 411e9da1e54f..a521ef30cdb0 100644
|
index 185b09335733..bd0bf8c6cf03 100644
|
||||||
--- a/kernel.c
|
--- a/kernel.c
|
||||||
+++ b/kernel.c
|
+++ b/kernel.c
|
||||||
@@ -2673,7 +2673,8 @@ cmd_bt(void)
|
@@ -2673,7 +2673,8 @@ cmd_bt(void)
|
||||||
@ -92,5 +92,5 @@ index 411e9da1e54f..a521ef30cdb0 100644
|
|||||||
else
|
else
|
||||||
option_not_supported(c);
|
option_not_supported(c);
|
||||||
--
|
--
|
||||||
2.30.2
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From 7095c8fd029e3a33117e3b67de73f504686ebfe2 Mon Sep 17 00:00:00 2001
|
From 0a988a8b46741aad6f2503163735ae72485cd04f Mon Sep 17 00:00:00 2001
|
||||||
From: Lianbo Jiang <lijiang@redhat.com>
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
Date: Thu, 2 Jun 2022 20:12:55 +0800
|
Date: Thu, 2 Jun 2022 20:12:55 +0800
|
||||||
Subject: [PATCH 10/18] Enhance "dev -d|-D" options to support blk-mq sbitmap
|
Subject: [PATCH 08/89] Enhance "dev -d|-D" options to support blk-mq sbitmap
|
||||||
|
|
||||||
Since Linux 5.16-rc1, which kernel commit 9a14d6ce4135 ("block: remove
|
Since Linux 5.16-rc1, which kernel commit 9a14d6ce4135 ("block: remove
|
||||||
debugfs blk_mq_ctx dispatched/merged/completed attributes") removed the
|
debugfs blk_mq_ctx dispatched/merged/completed attributes") removed the
|
||||||
@ -19,7 +19,7 @@ Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
|||||||
3 files changed, 238 insertions(+), 39 deletions(-)
|
3 files changed, 238 insertions(+), 39 deletions(-)
|
||||||
|
|
||||||
diff --git a/defs.h b/defs.h
|
diff --git a/defs.h b/defs.h
|
||||||
index c8444b4e54eb..2681586a33dc 100644
|
index 52e4b14aa27c..f2b6ab14c6aa 100644
|
||||||
--- a/defs.h
|
--- a/defs.h
|
||||||
+++ b/defs.h
|
+++ b/defs.h
|
||||||
@@ -2170,6 +2170,16 @@ struct offset_table { /* stash of commonly-used offsets */
|
@@ -2170,6 +2170,16 @@ struct offset_table { /* stash of commonly-used offsets */
|
||||||
@ -337,10 +337,10 @@ index a493e51ac95c..4be4c96df8b0 100644
|
|||||||
MEMBER_OFFSET_INIT(subsys_private_klist_devices, "subsys_private",
|
MEMBER_OFFSET_INIT(subsys_private_klist_devices, "subsys_private",
|
||||||
"klist_devices");
|
"klist_devices");
|
||||||
diff --git a/symbols.c b/symbols.c
|
diff --git a/symbols.c b/symbols.c
|
||||||
index 5d12a021c769..c1f09556d710 100644
|
index 7431aaecec9d..520debdb311e 100644
|
||||||
--- a/symbols.c
|
--- a/symbols.c
|
||||||
+++ b/symbols.c
|
+++ b/symbols.c
|
||||||
@@ -10385,6 +10385,12 @@ dump_offset_table(char *spec, ulong makestruct)
|
@@ -10397,6 +10397,12 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
OFFSET(kset_list));
|
OFFSET(kset_list));
|
||||||
fprintf(fp, " request_list_count: %ld\n",
|
fprintf(fp, " request_list_count: %ld\n",
|
||||||
OFFSET(request_list_count));
|
OFFSET(request_list_count));
|
||||||
@ -353,7 +353,7 @@ index 5d12a021c769..c1f09556d710 100644
|
|||||||
fprintf(fp, " request_queue_in_flight: %ld\n",
|
fprintf(fp, " request_queue_in_flight: %ld\n",
|
||||||
OFFSET(request_queue_in_flight));
|
OFFSET(request_queue_in_flight));
|
||||||
fprintf(fp, " request_queue_rq: %ld\n",
|
fprintf(fp, " request_queue_rq: %ld\n",
|
||||||
@@ -10393,10 +10399,25 @@ dump_offset_table(char *spec, ulong makestruct)
|
@@ -10405,10 +10411,25 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
OFFSET(request_queue_mq_ops));
|
OFFSET(request_queue_mq_ops));
|
||||||
fprintf(fp, " request_queue_queue_ctx: %ld\n",
|
fprintf(fp, " request_queue_queue_ctx: %ld\n",
|
||||||
OFFSET(request_queue_queue_ctx));
|
OFFSET(request_queue_queue_ctx));
|
||||||
@ -379,7 +379,7 @@ index 5d12a021c769..c1f09556d710 100644
|
|||||||
fprintf(fp, " subsys_private_klist_devices: %ld\n",
|
fprintf(fp, " subsys_private_klist_devices: %ld\n",
|
||||||
OFFSET(subsys_private_klist_devices));
|
OFFSET(subsys_private_klist_devices));
|
||||||
fprintf(fp, " subsystem_kset: %ld\n",
|
fprintf(fp, " subsystem_kset: %ld\n",
|
||||||
@@ -11003,6 +11024,7 @@ dump_offset_table(char *spec, ulong makestruct)
|
@@ -11015,6 +11036,7 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
fprintf(fp, " sbitmap: %ld\n", SIZE(sbitmap));
|
fprintf(fp, " sbitmap: %ld\n", SIZE(sbitmap));
|
||||||
fprintf(fp, " sbitmap_queue: %ld\n", SIZE(sbitmap_queue));
|
fprintf(fp, " sbitmap_queue: %ld\n", SIZE(sbitmap_queue));
|
||||||
fprintf(fp, " sbq_wait_state: %ld\n", SIZE(sbq_wait_state));
|
fprintf(fp, " sbq_wait_state: %ld\n", SIZE(sbq_wait_state));
|
||||||
@ -388,5 +388,5 @@ index 5d12a021c769..c1f09556d710 100644
|
|||||||
fprintf(fp, "\n array_table:\n");
|
fprintf(fp, "\n array_table:\n");
|
||||||
/*
|
/*
|
||||||
--
|
--
|
||||||
2.30.2
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From 68ce0b9a35d77d767872dd1a729c50e4695a30a8 Mon Sep 17 00:00:00 2001
|
From 7b91ac6d20b741c1c8487a04d2b9d8aee5772471 Mon Sep 17 00:00:00 2001
|
||||||
From: Lianbo Jiang <lijiang@redhat.com>
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
Date: Thu, 2 Jun 2022 20:12:56 +0800
|
Date: Thu, 2 Jun 2022 20:12:56 +0800
|
||||||
Subject: [PATCH 11/18] Fix for "dev -d|-D" options to support blk-mq change on
|
Subject: [PATCH 09/89] Fix for "dev -d|-D" options to support blk-mq change on
|
||||||
Linux v5.18-rc1
|
Linux v5.18-rc1
|
||||||
|
|
||||||
Kernel commit 4e5cc99e1e48 ("blk-mq: manage hctx map via xarray") removed
|
Kernel commit 4e5cc99e1e48 ("blk-mq: manage hctx map via xarray") removed
|
||||||
@ -27,7 +27,7 @@ Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
|||||||
3 files changed, 36 insertions(+), 9 deletions(-)
|
3 files changed, 36 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
diff --git a/defs.h b/defs.h
|
diff --git a/defs.h b/defs.h
|
||||||
index 2681586a33dc..7d3b73422f48 100644
|
index f2b6ab14c6aa..c524a05d8105 100644
|
||||||
--- a/defs.h
|
--- a/defs.h
|
||||||
+++ b/defs.h
|
+++ b/defs.h
|
||||||
@@ -2180,6 +2180,7 @@ struct offset_table { /* stash of commonly-used offsets */
|
@@ -2180,6 +2180,7 @@ struct offset_table { /* stash of commonly-used offsets */
|
||||||
@ -104,10 +104,10 @@ index 4be4c96df8b0..0172c83ffaea 100644
|
|||||||
"rq_dispatched");
|
"rq_dispatched");
|
||||||
MEMBER_OFFSET_INIT(blk_mq_ctx_rq_completed, "blk_mq_ctx",
|
MEMBER_OFFSET_INIT(blk_mq_ctx_rq_completed, "blk_mq_ctx",
|
||||||
diff --git a/symbols.c b/symbols.c
|
diff --git a/symbols.c b/symbols.c
|
||||||
index c1f09556d710..bee1faf92c83 100644
|
index 520debdb311e..69004a2e66e3 100644
|
||||||
--- a/symbols.c
|
--- a/symbols.c
|
||||||
+++ b/symbols.c
|
+++ b/symbols.c
|
||||||
@@ -10403,6 +10403,8 @@ dump_offset_table(char *spec, ulong makestruct)
|
@@ -10415,6 +10415,8 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
OFFSET(request_queue_queue_hw_ctx));
|
OFFSET(request_queue_queue_hw_ctx));
|
||||||
fprintf(fp, " request_queue_nr_hw_queues: %ld\n",
|
fprintf(fp, " request_queue_nr_hw_queues: %ld\n",
|
||||||
OFFSET(request_queue_nr_hw_queues));
|
OFFSET(request_queue_nr_hw_queues));
|
||||||
@ -117,5 +117,5 @@ index c1f09556d710..bee1faf92c83 100644
|
|||||||
OFFSET(blk_mq_ctx_rq_dispatched));
|
OFFSET(blk_mq_ctx_rq_dispatched));
|
||||||
fprintf(fp, " blk_mq_ctx_rq_completed: %ld\n",
|
fprintf(fp, " blk_mq_ctx_rq_completed: %ld\n",
|
||||||
--
|
--
|
||||||
2.30.2
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From c672d7a4c290712b32c54329cbdc1e74d122e813 Mon Sep 17 00:00:00 2001
|
From 2d9e180858b3212507fcba7a7cb9d13f6a935a2f Mon Sep 17 00:00:00 2001
|
||||||
From: Lianbo Jiang <lijiang@redhat.com>
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
Date: Mon, 6 Jun 2022 19:09:16 +0800
|
Date: Mon, 6 Jun 2022 19:09:16 +0800
|
||||||
Subject: [PATCH 12/18] Doc: update man page for the "bpf" and "sbitmapq"
|
Subject: [PATCH 10/89] Doc: update man page for the "bpf" and "sbitmapq"
|
||||||
commands
|
commands
|
||||||
|
|
||||||
The information of the "bpf" and "sbitmapq" commands is missing in the man
|
The information of the "bpf" and "sbitmapq" commands is missing in the man
|
||||||
@ -39,5 +39,5 @@ index 1f3657b11e4c..e553a0b4adb3 100644
|
|||||||
searches a range of user or kernel memory space for given value.
|
searches a range of user or kernel memory space for given value.
|
||||||
.TP
|
.TP
|
||||||
--
|
--
|
||||||
2.30.2
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From 9ce31a14d1083cbb2beb4a8e6eb7b88234b79a99 Mon Sep 17 00:00:00 2001
|
From aff3d6e19c9a9ffe4e5d55850aa42a4dc9cf0485 Mon Sep 17 00:00:00 2001
|
||||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
Date: Fri, 10 Jun 2022 11:49:47 +0900
|
Date: Fri, 10 Jun 2022 11:49:47 +0900
|
||||||
Subject: [PATCH 13/18] sbitmapq: Fix for sbitmap_queue without ws_active
|
Subject: [PATCH 11/89] sbitmapq: Fix for sbitmap_queue without ws_active
|
||||||
member
|
member
|
||||||
|
|
||||||
The sbitmap_queue.ws_active member was added by kernel commit 5d2ee7122c73
|
The sbitmap_queue.ws_active member was added by kernel commit 5d2ee7122c73
|
||||||
@ -44,5 +44,5 @@ index e8ebd62fe01c..152c28e6875f 100644
|
|||||||
sqc->round_robin = BOOL(sbitmap_queue_buf + OFFSET(sbitmap_queue_round_robin));
|
sqc->round_robin = BOOL(sbitmap_queue_buf + OFFSET(sbitmap_queue_round_robin));
|
||||||
sqc->min_shallow_depth = UINT(sbitmap_queue_buf + OFFSET(sbitmap_queue_min_shallow_depth));
|
sqc->min_shallow_depth = UINT(sbitmap_queue_buf + OFFSET(sbitmap_queue_min_shallow_depth));
|
||||||
--
|
--
|
||||||
2.30.2
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From 0d3e86fee5eead93b521a0e20a0e099ede4ab72b Mon Sep 17 00:00:00 2001
|
From 040e8be3b13746d1f64a36040b4ca613cf18eff0 Mon Sep 17 00:00:00 2001
|
||||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
Date: Fri, 10 Jun 2022 11:49:47 +0900
|
Date: Fri, 10 Jun 2022 11:49:47 +0900
|
||||||
Subject: [PATCH 14/18] sbitmapq: Fix for sbitmap_word without cleared member
|
Subject: [PATCH 12/89] sbitmapq: Fix for sbitmap_word without cleared member
|
||||||
|
|
||||||
The sbitmap_word.cleared member was added by kernel commit ea86ea2cdced
|
The sbitmap_word.cleared member was added by kernel commit ea86ea2cdced
|
||||||
("sbitmap: ammortize cost of clearing bits") at Linux 5.0. Without the
|
("sbitmap: ammortize cost of clearing bits") at Linux 5.0. Without the
|
||||||
@ -106,5 +106,5 @@ index 152c28e6875f..c9f7209f9e3e 100644
|
|||||||
fprintf(fp, "map_nr = %u\n", sc->map_nr);
|
fprintf(fp, "map_nr = %u\n", sc->map_nr);
|
||||||
|
|
||||||
--
|
--
|
||||||
2.30.2
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From 12fe6c7cdd768f87ce6e903a2bbfb0c0591585c5 Mon Sep 17 00:00:00 2001
|
From 8ea476439a57ee5552c752c582faf1d057ea4f6d Mon Sep 17 00:00:00 2001
|
||||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
Date: Fri, 10 Jun 2022 11:49:47 +0900
|
Date: Fri, 10 Jun 2022 11:49:47 +0900
|
||||||
Subject: [PATCH 15/18] sbitmapq: Fix for sbitmap_queue without
|
Subject: [PATCH 13/89] sbitmapq: Fix for sbitmap_queue without
|
||||||
min_shallow_depth member
|
min_shallow_depth member
|
||||||
|
|
||||||
The sbitmap_queue.min_shallow_depth member was added by kernel commit
|
The sbitmap_queue.min_shallow_depth member was added by kernel commit
|
||||||
@ -45,5 +45,5 @@ index c9f7209f9e3e..bb2f19e6207b 100644
|
|||||||
FREEBUF(sbitmap_queue_buf);
|
FREEBUF(sbitmap_queue_buf);
|
||||||
}
|
}
|
||||||
--
|
--
|
||||||
2.30.2
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From c07068266b41450ca6821ee0a1a3adf34206015f Mon Sep 17 00:00:00 2001
|
From 04b6edada1180b0391ddf980d09b4bac8a0c3aba Mon Sep 17 00:00:00 2001
|
||||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
Date: Fri, 10 Jun 2022 15:21:53 +0900
|
Date: Fri, 10 Jun 2022 15:21:53 +0900
|
||||||
Subject: [PATCH 16/18] Make "dev -d|-D" options parse sbitmap on Linux 4.18
|
Subject: [PATCH 14/89] Make "dev -d|-D" options parse sbitmap on Linux 4.18
|
||||||
and later
|
and later
|
||||||
|
|
||||||
There have been a few reports that the "dev -d|-D" options displayed
|
There have been a few reports that the "dev -d|-D" options displayed
|
||||||
@ -80,5 +80,5 @@ index 0172c83ffaea..db97f8aebdc2 100644
|
|||||||
sizeof(ulong), "request_queue.queue_ctx",
|
sizeof(ulong), "request_queue.queue_ctx",
|
||||||
FAULT_ON_ERROR);
|
FAULT_ON_ERROR);
|
||||||
--
|
--
|
||||||
2.30.2
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From 6bc3b74c6e2b0aaebe1bc164594e53b010efef56 Mon Sep 17 00:00:00 2001
|
From 60af53c7b69df11dec05d2a396e5272856e4243d Mon Sep 17 00:00:00 2001
|
||||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
Date: Fri, 10 Jun 2022 15:52:34 +0900
|
Date: Fri, 10 Jun 2022 15:52:34 +0900
|
||||||
Subject: [PATCH 17/18] sbitmapq: Fix for kernels without struct
|
Subject: [PATCH 15/89] sbitmapq: Fix for kernels without struct
|
||||||
wait_queue_head
|
wait_queue_head
|
||||||
|
|
||||||
The current struct wait_queue_head was renamed by kernel commit
|
The current struct wait_queue_head was renamed by kernel commit
|
||||||
@ -40,5 +40,5 @@ index bb2f19e6207b..be5d30a8ea88 100644
|
|||||||
sbq_wait_state_buf = GETBUF(sbq_wait_state_size);
|
sbq_wait_state_buf = GETBUF(sbq_wait_state_size);
|
||||||
|
|
||||||
--
|
--
|
||||||
2.30.2
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From b8f2ae6b494d706b1e4855b439c4930a6a6a2f5c Mon Sep 17 00:00:00 2001
|
From 46db4c6a66067d96248be664a09fdd93575cb0f2 Mon Sep 17 00:00:00 2001
|
||||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
Date: Fri, 10 Jun 2022 16:00:14 +0900
|
Date: Fri, 10 Jun 2022 16:00:14 +0900
|
||||||
Subject: [PATCH 18/18] sbitmapq: Limit kernels without sbitmap again
|
Subject: [PATCH 16/89] sbitmapq: Limit kernels without sbitmap again
|
||||||
|
|
||||||
commit 364b2e413c69 ("sbitmapq: remove struct and member validation
|
commit 364b2e413c69 ("sbitmapq: remove struct and member validation
|
||||||
in sbitmapq_init()") allowed the use of the "sbitmapq" command
|
in sbitmapq_init()") allowed the use of the "sbitmapq" command
|
||||||
@ -39,5 +39,5 @@ index be5d30a8ea88..12d6512a1e4d 100644
|
|||||||
MEMBER_OFFSET_INIT(sbitmap_word_word, "sbitmap_word", "word");
|
MEMBER_OFFSET_INIT(sbitmap_word_word, "sbitmap_word", "word");
|
||||||
MEMBER_OFFSET_INIT(sbitmap_word_cleared, "sbitmap_word", "cleared");
|
MEMBER_OFFSET_INIT(sbitmap_word_cleared, "sbitmap_word", "cleared");
|
||||||
--
|
--
|
||||||
2.30.2
|
2.37.1
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From f623cad20b092002d627a03451ea256add2e53d0 Mon Sep 17 00:00:00 2001
|
From b6b1f17766583873cde5335e6e631fe3887cb564 Mon Sep 17 00:00:00 2001
|
||||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
Date: Wed, 15 Jun 2022 10:50:13 +0900
|
Date: Wed, 15 Jun 2022 10:50:13 +0900
|
||||||
Subject: [PATCH 01/28] Fix for "dev" command on Linux 5.11 and later
|
Subject: [PATCH 17/89] Fix for "dev" command on Linux 5.11 and later
|
||||||
|
|
||||||
The following kernel commits eventually removed the bdev_map array in
|
The following kernel commits eventually removed the bdev_map array in
|
||||||
Linux v5.11 kernel:
|
Linux v5.11 kernel:
|
@ -1,7 +1,7 @@
|
|||||||
From 6bc60e8cc87701c8f68c1cda56dd7120b5565700 Mon Sep 17 00:00:00 2001
|
From 21c2bf4844893fe9499fda156d043b0ff6c5f3af Mon Sep 17 00:00:00 2001
|
||||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
Date: Wed, 22 Jun 2022 08:32:59 +0900
|
Date: Wed, 22 Jun 2022 08:32:59 +0900
|
||||||
Subject: [PATCH 02/28] Extend field length of task attributes
|
Subject: [PATCH 18/89] Extend field length of task attributes
|
||||||
|
|
||||||
Nowadays, some machines have many CPU cores and memory, and some
|
Nowadays, some machines have many CPU cores and memory, and some
|
||||||
distributions have a larger kernel.pid_max parameter, e.g. 7 digits.
|
distributions have a larger kernel.pid_max parameter, e.g. 7 digits.
|
@ -1,7 +1,7 @@
|
|||||||
From 1c918c621e48f53ea69a143aabc59c8366102236 Mon Sep 17 00:00:00 2001
|
From 00f8699daacba46fd706758024c375825264db32 Mon Sep 17 00:00:00 2001
|
||||||
From: Hari Bathini <hbathini@linux.ibm.com>
|
From: Hari Bathini <hbathini@linux.ibm.com>
|
||||||
Date: Mon, 4 Jul 2022 10:55:41 +0530
|
Date: Mon, 4 Jul 2022 10:55:41 +0530
|
||||||
Subject: [PATCH 03/28] ppc64: fix bt for '-S' case
|
Subject: [PATCH 19/89] ppc64: fix bt for '-S' case
|
||||||
|
|
||||||
Passing '-S' option to 'bt' command was intended to specify the stack
|
Passing '-S' option to 'bt' command was intended to specify the stack
|
||||||
pointer manually. But get_stack_frame() handling on ppc64 is ignoring
|
pointer manually. But get_stack_frame() handling on ppc64 is ignoring
|
@ -1,7 +1,7 @@
|
|||||||
From 6a89173a25450b679e4a713793b2ed36b077fe56 Mon Sep 17 00:00:00 2001
|
From 32282bab0edf1aebd96bb8fe5ee66b3855474831 Mon Sep 17 00:00:00 2001
|
||||||
From: Hari Bathini <hbathini@linux.ibm.com>
|
From: Hari Bathini <hbathini@linux.ibm.com>
|
||||||
Date: Mon, 4 Jul 2022 10:55:42 +0530
|
Date: Mon, 4 Jul 2022 10:55:42 +0530
|
||||||
Subject: [PATCH 04/28] ppc64: dynamically allocate h/w interrupt stack
|
Subject: [PATCH 20/89] ppc64: dynamically allocate h/w interrupt stack
|
||||||
|
|
||||||
Only older kernel (v2.4) used h/w interrupt stack to store frames when
|
Only older kernel (v2.4) used h/w interrupt stack to store frames when
|
||||||
CPU received IPI. Memory used for this in 'struct machine_specific' is
|
CPU received IPI. Memory used for this in 'struct machine_specific' is
|
@ -1,7 +1,7 @@
|
|||||||
From 4dbf7e296f6fde05894a55e23fbaf0d50e3b38b9 Mon Sep 17 00:00:00 2001
|
From 275b62afe8fd7446fc31025998b6d0fd47ec8be0 Mon Sep 17 00:00:00 2001
|
||||||
From: Hari Bathini <hbathini@linux.ibm.com>
|
From: Hari Bathini <hbathini@linux.ibm.com>
|
||||||
Date: Mon, 4 Jul 2022 10:55:43 +0530
|
Date: Mon, 4 Jul 2022 10:55:43 +0530
|
||||||
Subject: [PATCH 05/28] ppc64: rename ppc64_paca_init to
|
Subject: [PATCH 21/89] ppc64: rename ppc64_paca_init to
|
||||||
ppc64_paca_percpu_offset_init
|
ppc64_paca_percpu_offset_init
|
||||||
|
|
||||||
ppc64_paca_init() function is specifically used to initialize percpu
|
ppc64_paca_init() function is specifically used to initialize percpu
|
@ -1,7 +1,7 @@
|
|||||||
From f256095c61355d8db11502709ab3a084343f2bec Mon Sep 17 00:00:00 2001
|
From 26b0949228786562fdf73fef145a829c0adb9c70 Mon Sep 17 00:00:00 2001
|
||||||
From: Hari Bathini <hbathini@linux.ibm.com>
|
From: Hari Bathini <hbathini@linux.ibm.com>
|
||||||
Date: Mon, 4 Jul 2022 10:55:44 +0530
|
Date: Mon, 4 Jul 2022 10:55:44 +0530
|
||||||
Subject: [PATCH 06/28] ppc64: handle backtrace when CPU is in an emergency
|
Subject: [PATCH 22/89] ppc64: handle backtrace when CPU is in an emergency
|
||||||
stack
|
stack
|
||||||
|
|
||||||
A CPU could be in an emergency stack when it is running in real mode
|
A CPU could be in an emergency stack when it is running in real mode
|
@ -1,7 +1,7 @@
|
|||||||
From 9429b15851f184fbff187d9a751451c9ed8ae5c9 Mon Sep 17 00:00:00 2001
|
From 5ef39b9dda5ab29ddbbc72d54829ddbc66238518 Mon Sep 17 00:00:00 2001
|
||||||
From: Hari Bathini <hbathini@linux.ibm.com>
|
From: Hari Bathini <hbathini@linux.ibm.com>
|
||||||
Date: Mon, 4 Jul 2022 10:55:45 +0530
|
Date: Mon, 4 Jul 2022 10:55:45 +0530
|
||||||
Subject: [PATCH 07/28] ppc64: print emergency stacks info with 'mach' command
|
Subject: [PATCH 23/89] ppc64: print emergency stacks info with 'mach' command
|
||||||
|
|
||||||
Print top address of emergency stacks with 'mach' command.
|
Print top address of emergency stacks with 'mach' command.
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From 656f0b50866247a2fdb2d0c917f0a7a3f34c2e7d Mon Sep 17 00:00:00 2001
|
From 1365bde4820805457a35743be2dbb1035f4eeede Mon Sep 17 00:00:00 2001
|
||||||
From: Hari Bathini <hbathini@linux.ibm.com>
|
From: Hari Bathini <hbathini@linux.ibm.com>
|
||||||
Date: Mon, 4 Jul 2022 10:55:46 +0530
|
Date: Mon, 4 Jul 2022 10:55:46 +0530
|
||||||
Subject: [PATCH 08/28] ppc64: use a variable for machdep->machspec
|
Subject: [PATCH 24/89] ppc64: use a variable for machdep->machspec
|
||||||
|
|
||||||
machdpep->machspec is referred to multiple times. The compiler would
|
machdpep->machspec is referred to multiple times. The compiler would
|
||||||
likely optimize this but nonetheless, use a variable to optimize in
|
likely optimize this but nonetheless, use a variable to optimize in
|
@ -1,7 +1,7 @@
|
|||||||
From b077c3569788f5eb5ddf85bf41026b452d253a90 Mon Sep 17 00:00:00 2001
|
From ee5ab26db61025b2f5ed3a4b529394187df54d36 Mon Sep 17 00:00:00 2001
|
||||||
From: Qianli Zhao <qianli.zhao@horizon.ai>
|
From: Qianli Zhao <qianli.zhao@horizon.ai>
|
||||||
Date: Mon, 4 Jul 2022 16:40:01 +0800
|
Date: Mon, 4 Jul 2022 16:40:01 +0800
|
||||||
Subject: [PATCH 09/28] arm64: Fix for st->_stext_vmlinux not initialized when
|
Subject: [PATCH 25/89] arm64: Fix for st->_stext_vmlinux not initialized when
|
||||||
set VA_BITS_ACTUAL
|
set VA_BITS_ACTUAL
|
||||||
|
|
||||||
Setting st->_stext_vmlinux to UNINITIALIZED to search for "_stext"
|
Setting st->_stext_vmlinux to UNINITIALIZED to search for "_stext"
|
@ -1,7 +1,7 @@
|
|||||||
From 6132fe21e0d5f2951c860f8850aeaacf1588dfb0 Mon Sep 17 00:00:00 2001
|
From f141628a62b795f52a5d57f5d3e844b6a49114da Mon Sep 17 00:00:00 2001
|
||||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
Date: Fri, 22 Jul 2022 13:44:50 +0900
|
Date: Fri, 22 Jul 2022 13:44:50 +0900
|
||||||
Subject: [PATCH 10/28] Fix gcc-11 compiler warnings on filesys.c
|
Subject: [PATCH 26/89] Fix gcc-11 compiler warnings on filesys.c
|
||||||
|
|
||||||
Without the patch, the following gcc-11 compiler warnings are emitted
|
Without the patch, the following gcc-11 compiler warnings are emitted
|
||||||
for filesys.c:
|
for filesys.c:
|
@ -1,7 +1,7 @@
|
|||||||
From 98484914b7f4ba34da0625baa0ed6d449c1fa3ad Mon Sep 17 00:00:00 2001
|
From 12898df249a5db826d2390467aaadd49de29074e Mon Sep 17 00:00:00 2001
|
||||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
Date: Fri, 22 Jul 2022 13:44:50 +0900
|
Date: Fri, 22 Jul 2022 13:44:50 +0900
|
||||||
Subject: [PATCH 11/28] Fix gcc-11 compiler warning on symbols.c
|
Subject: [PATCH 27/89] Fix gcc-11 compiler warning on symbols.c
|
||||||
|
|
||||||
Without the patch, the following gcc-11 compiler warning is emitted for
|
Without the patch, the following gcc-11 compiler warning is emitted for
|
||||||
symbols.c:
|
symbols.c:
|
@ -1,7 +1,7 @@
|
|||||||
From 9bb8a48d9424fc00ccd073125cdee9613b389cc6 Mon Sep 17 00:00:00 2001
|
From 8d9e6c5b02c9c417264b76279b8f77b0995b6f74 Mon Sep 17 00:00:00 2001
|
||||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
Date: Fri, 22 Jul 2022 13:44:50 +0900
|
Date: Fri, 22 Jul 2022 13:44:50 +0900
|
||||||
Subject: [PATCH 12/28] Fix gcc-11 compiler warning on makedumpfile.c
|
Subject: [PATCH 28/89] Fix gcc-11 compiler warning on makedumpfile.c
|
||||||
|
|
||||||
Without the patch, the following gcc-11 compiler warning is emitted for
|
Without the patch, the following gcc-11 compiler warning is emitted for
|
||||||
makedumpfile.c:
|
makedumpfile.c:
|
@ -1,7 +1,7 @@
|
|||||||
From 75739a08e952b6bd7434f4625a8fbe921361cbe8 Mon Sep 17 00:00:00 2001
|
From 6618a57d40ff48726c26d54813f3f8090037760b Mon Sep 17 00:00:00 2001
|
||||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
Date: Fri, 22 Jul 2022 13:44:50 +0900
|
Date: Fri, 22 Jul 2022 13:44:50 +0900
|
||||||
Subject: [PATCH 13/28] Fix gcc-11 compiler warning on kvmdump.c
|
Subject: [PATCH 29/89] Fix gcc-11 compiler warning on kvmdump.c
|
||||||
|
|
||||||
Without the patch, the following gcc-11 compiler warning is emitted for
|
Without the patch, the following gcc-11 compiler warning is emitted for
|
||||||
kvmdump.c:
|
kvmdump.c:
|
@ -1,7 +1,7 @@
|
|||||||
From b584eb81ff27e42547d01c521b488aaeaa35b460 Mon Sep 17 00:00:00 2001
|
From 59e9621ac2a7cb3f001fdab53c1e7e3590f8762d Mon Sep 17 00:00:00 2001
|
||||||
From: Lianbo Jiang <lijiang@redhat.com>
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
Date: Thu, 28 Jul 2022 15:11:20 +0800
|
Date: Thu, 28 Jul 2022 15:11:20 +0800
|
||||||
Subject: [PATCH 14/28] x86_64: Fix for AMD SME issue
|
Subject: [PATCH 30/89] x86_64: Fix for AMD SME issue
|
||||||
|
|
||||||
Kernel commit changes(see [1]/[2]) may cause the failure of crash-utility
|
Kernel commit changes(see [1]/[2]) may cause the failure of crash-utility
|
||||||
with the following error:
|
with the following error:
|
@ -1,7 +1,7 @@
|
|||||||
From 619e36c18791333ee3a7fea759ce20396e711a46 Mon Sep 17 00:00:00 2001
|
From 6be4f19f32bfa6d5a52580b733afca8a5b849c23 Mon Sep 17 00:00:00 2001
|
||||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
Date: Mon, 22 Aug 2022 11:59:46 +0900
|
Date: Mon, 22 Aug 2022 11:59:46 +0900
|
||||||
Subject: [PATCH 15/28] Makefile: Fix unnecessary re-patching with
|
Subject: [PATCH 31/89] Makefile: Fix unnecessary re-patching with
|
||||||
coreutils-9.0
|
coreutils-9.0
|
||||||
|
|
||||||
"sum" command in coreutils-9.0 (e.g. Fedora 36) started to output a file
|
"sum" command in coreutils-9.0 (e.g. Fedora 36) started to output a file
|
||||||
@ -17,7 +17,7 @@ Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
|||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
diff --git a/Makefile b/Makefile
|
diff --git a/Makefile b/Makefile
|
||||||
index 059759b3e4ab..dd81df6c198c 100644
|
index c031db4ca23f..2549d1d39273 100644
|
||||||
--- a/Makefile
|
--- a/Makefile
|
||||||
+++ b/Makefile
|
+++ b/Makefile
|
||||||
@@ -269,7 +269,7 @@ rebuild:
|
@@ -269,7 +269,7 @@ rebuild:
|
@ -1,7 +1,7 @@
|
|||||||
From 28a41ec7a471474094d8ab39f3a69b44d0f9ebcf Mon Sep 17 00:00:00 2001
|
From 1bd4bd41e67dae5a970d34f33c566812f9f2c6af Mon Sep 17 00:00:00 2001
|
||||||
From: Huang Shijie <shijie@os.amperecomputing.com>
|
From: Huang Shijie <shijie@os.amperecomputing.com>
|
||||||
Date: Mon, 22 Aug 2022 09:29:32 +0000
|
Date: Mon, 22 Aug 2022 09:29:32 +0000
|
||||||
Subject: [PATCH 16/28] arm64: use TCR_EL1_T1SZ to get the correct info if
|
Subject: [PATCH 32/89] arm64: use TCR_EL1_T1SZ to get the correct info if
|
||||||
vabits_actual is missing
|
vabits_actual is missing
|
||||||
|
|
||||||
After kernel commit 0d9b1ffefabe ("arm64: mm: make vabits_actual a build
|
After kernel commit 0d9b1ffefabe ("arm64: mm: make vabits_actual a build
|
@ -1,7 +1,7 @@
|
|||||||
From c32abfea658ef33c20a942700277cb52baf95bfa Mon Sep 17 00:00:00 2001
|
From 5df8fdf1f591176682e6fac18e6631c3a2aab1dc Mon Sep 17 00:00:00 2001
|
||||||
From: Tao Liu <ltao@redhat.com>
|
From: Tao Liu <ltao@redhat.com>
|
||||||
Date: Thu, 25 Aug 2022 14:39:44 +0800
|
Date: Thu, 25 Aug 2022 14:39:44 +0800
|
||||||
Subject: [PATCH 17/28] Fix "task -R" by adding end identifier for union in
|
Subject: [PATCH 33/89] Fix "task -R" by adding end identifier for union in
|
||||||
task_struct
|
task_struct
|
||||||
|
|
||||||
Previously, the start and end identifiers for union are " {\n" and
|
Previously, the start and end identifiers for union are " {\n" and
|
@ -1,7 +1,7 @@
|
|||||||
From 5948cb9b3e622e3c87216c7c6479f509c8aeb7c1 Mon Sep 17 00:00:00 2001
|
From 38064b8d5866f8a4f7e7867f187ad95e67f16209 Mon Sep 17 00:00:00 2001
|
||||||
From: Tao Liu <ltao@redhat.com>
|
From: Tao Liu <ltao@redhat.com>
|
||||||
Date: Wed, 16 Nov 2022 17:36:03 +0800
|
Date: Wed, 16 Nov 2022 17:36:03 +0800
|
||||||
Subject: [PATCH 18/28] Let gdb get kernel module symbols info from crash
|
Subject: [PATCH 34/89] Let gdb get kernel module symbols info from crash
|
||||||
|
|
||||||
Gdb will try to resolve an address to its corresponding symbol name such as
|
Gdb will try to resolve an address to its corresponding symbol name such as
|
||||||
when printing a structure. It works fine for kernel symbols, because gdb can
|
when printing a structure. It works fine for kernel symbols, because gdb can
|
||||||
@ -65,7 +65,7 @@ index f8fbfdfd1152..b7d76330141a 100644
|
|||||||
void restore_gdb_sanity(void);
|
void restore_gdb_sanity(void);
|
||||||
int is_gdb_command(int, ulong);
|
int is_gdb_command(int, ulong);
|
||||||
diff --git a/gdb-7.6.patch b/gdb-7.6.patch
|
diff --git a/gdb-7.6.patch b/gdb-7.6.patch
|
||||||
index c63ad7d81cb0..f1c3aa734241 100644
|
index c63ad7d81cb0..d0becd055666 100644
|
||||||
--- a/gdb-7.6.patch
|
--- a/gdb-7.6.patch
|
||||||
+++ b/gdb-7.6.patch
|
+++ b/gdb-7.6.patch
|
||||||
@@ -2568,3 +2568,36 @@ diff -up gdb-7.6/opcodes/configure.orig gdb-7.6/opcodes/configure
|
@@ -2568,3 +2568,36 @@ diff -up gdb-7.6/opcodes/configure.orig gdb-7.6/opcodes/configure
|
||||||
@ -106,7 +106,7 @@ index c63ad7d81cb0..f1c3aa734241 100644
|
|||||||
+ /* If the nearest symbol is too far away, don't print anything symbolic. */
|
+ /* If the nearest symbol is too far away, don't print anything symbolic. */
|
||||||
+
|
+
|
||||||
diff --git a/gdb_interface.c b/gdb_interface.c
|
diff --git a/gdb_interface.c b/gdb_interface.c
|
||||||
index 1f10006a2d63..f9d0018998df 100644
|
index 1f10006a2d63..95298a94c702 100644
|
||||||
--- a/gdb_interface.c
|
--- a/gdb_interface.c
|
||||||
+++ b/gdb_interface.c
|
+++ b/gdb_interface.c
|
||||||
@@ -945,6 +945,18 @@ gdb_print_callback(ulong addr)
|
@@ -945,6 +945,18 @@ gdb_print_callback(ulong addr)
|
@ -1,7 +1,7 @@
|
|||||||
From 93cd670426aaf4951bceb8f24f0ce63c24e16f5d Mon Sep 17 00:00:00 2001
|
From 6a766b5159ebb971a399bb32a8a58599df977cdb Mon Sep 17 00:00:00 2001
|
||||||
From: Tao Liu <ltao@redhat.com>
|
From: Tao Liu <ltao@redhat.com>
|
||||||
Date: Wed, 16 Nov 2022 20:09:22 +0800
|
Date: Wed, 16 Nov 2022 20:09:22 +0800
|
||||||
Subject: [PATCH 19/28] x86_64: Correct the identifier when locating the call
|
Subject: [PATCH 35/89] x86_64: Correct the identifier when locating the call
|
||||||
instruction
|
instruction
|
||||||
|
|
||||||
The previous implementation to locate the call instruction is
|
The previous implementation to locate the call instruction is
|
@ -1,7 +1,7 @@
|
|||||||
From 931ea86070e9b56bf698ae3a4f20647d42325d6d Mon Sep 17 00:00:00 2001
|
From 792730b32cb15b59af2833cfd6819b8408b20e89 Mon Sep 17 00:00:00 2001
|
||||||
From: "Chunguang.Xu" <chunguang.xu@shopee.com>
|
From: "Chunguang.Xu" <chunguang.xu@shopee.com>
|
||||||
Date: Thu, 25 Aug 2022 12:07:20 +0800
|
Date: Thu, 25 Aug 2022 12:07:20 +0800
|
||||||
Subject: [PATCH 20/28] Add debian/ubuntu vmlinux location to default search
|
Subject: [PATCH 36/89] Add debian/ubuntu vmlinux location to default search
|
||||||
dirs
|
dirs
|
||||||
|
|
||||||
Now crash cannot find debian/ubuntu kernel vmlinux, we need to
|
Now crash cannot find debian/ubuntu kernel vmlinux, we need to
|
@ -1,7 +1,7 @@
|
|||||||
From a4f8fe965e1ed0d27aff0cdf30e2c571da2e5356 Mon Sep 17 00:00:00 2001
|
From 1312fdbc514dc47e591b2d94994c6f467581c6f1 Mon Sep 17 00:00:00 2001
|
||||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
Date: Thu, 1 Sep 2022 14:03:09 +0900
|
Date: Thu, 1 Sep 2022 14:03:09 +0900
|
||||||
Subject: [PATCH 21/28] Fix gcc-12 compiler warnings on lkcd_*.c
|
Subject: [PATCH 37/89] Fix gcc-12 compiler warnings on lkcd_*.c
|
||||||
|
|
||||||
Without the patch, the following gcc-12 compiler warnings are emitted
|
Without the patch, the following gcc-12 compiler warnings are emitted
|
||||||
for lkcd_*.c:
|
for lkcd_*.c:
|
@ -1,7 +1,7 @@
|
|||||||
From 598377606649ee3cdcc1694d975bed27005612ee Mon Sep 17 00:00:00 2001
|
From 61e5c455516622cabf4a01c1643ca2175ef9510c Mon Sep 17 00:00:00 2001
|
||||||
From: Lianbo Jiang <lijiang@redhat.com>
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
Date: Wed, 16 Nov 2022 20:46:48 +0800
|
Date: Wed, 16 Nov 2022 20:46:48 +0800
|
||||||
Subject: [PATCH 22/28] Fix for the invalid linux_banner pointer issue
|
Subject: [PATCH 38/89] Fix for the invalid linux_banner pointer issue
|
||||||
|
|
||||||
Currently, crash may fail with the following error:
|
Currently, crash may fail with the following error:
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From 488896b1ab0ca8bc4cc6aa608b6ee1744ae480e7 Mon Sep 17 00:00:00 2001
|
From a72184ebeec704158a2b225fa7fe0869b9b93a93 Mon Sep 17 00:00:00 2001
|
||||||
From: Tao Liu <ltao@redhat.com>
|
From: Tao Liu <ltao@redhat.com>
|
||||||
Date: Mon, 19 Sep 2022 17:49:21 +0800
|
Date: Mon, 19 Sep 2022 17:49:21 +0800
|
||||||
Subject: [PATCH 23/28] Fix "kmem" failing to print task context when address
|
Subject: [PATCH 39/89] Fix "kmem" failing to print task context when address
|
||||||
is vmalloced stack
|
is vmalloced stack
|
||||||
|
|
||||||
When kernel enabled CONFIG_VMAP_STACK, stack can be allocated to
|
When kernel enabled CONFIG_VMAP_STACK, stack can be allocated to
|
||||||
@ -38,7 +38,7 @@ Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
|||||||
1 file changed, 4 insertions(+)
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
diff --git a/memory.c b/memory.c
|
diff --git a/memory.c b/memory.c
|
||||||
index a31a430e2823..e44b59d2e805 100644
|
index 7339f0cd0224..9ab578134fa1 100644
|
||||||
--- a/memory.c
|
--- a/memory.c
|
||||||
+++ b/memory.c
|
+++ b/memory.c
|
||||||
@@ -13477,6 +13477,10 @@ kmem_search(struct meminfo *mi)
|
@@ -13477,6 +13477,10 @@ kmem_search(struct meminfo *mi)
|
@ -1,7 +1,7 @@
|
|||||||
From d0726d96b92e5dacd1df56756e168a50a4e62589 Mon Sep 17 00:00:00 2001
|
From f18c391b650ace3cea6e48278b969425a328e4cf Mon Sep 17 00:00:00 2001
|
||||||
From: Tao Liu <ltao@redhat.com>
|
From: Tao Liu <ltao@redhat.com>
|
||||||
Date: Mon, 19 Sep 2022 17:49:22 +0800
|
Date: Mon, 19 Sep 2022 17:49:22 +0800
|
||||||
Subject: [PATCH 24/28] Fix page offset issue when converting physical to
|
Subject: [PATCH 40/89] Fix page offset issue when converting physical to
|
||||||
virtual address
|
virtual address
|
||||||
|
|
||||||
When trying to convert a physical address to its virtual
|
When trying to convert a physical address to its virtual
|
||||||
@ -23,7 +23,7 @@ Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
|||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
diff --git a/memory.c b/memory.c
|
diff --git a/memory.c b/memory.c
|
||||||
index e44b59d2e805..a60c3f9493f6 100644
|
index 9ab578134fa1..1b6f9ba17e57 100644
|
||||||
--- a/memory.c
|
--- a/memory.c
|
||||||
+++ b/memory.c
|
+++ b/memory.c
|
||||||
@@ -8861,7 +8861,7 @@ dump_vmlist(struct meminfo *vi)
|
@@ -8861,7 +8861,7 @@ dump_vmlist(struct meminfo *vi)
|
@ -1,7 +1,7 @@
|
|||||||
From 74759e0e9736e86c7d2439bfe74ca5eb51b0a52b Mon Sep 17 00:00:00 2001
|
From 2c24770e3ceab8eebd9788256967b79145f53123 Mon Sep 17 00:00:00 2001
|
||||||
From: Tao Liu <ltao@redhat.com>
|
From: Tao Liu <ltao@redhat.com>
|
||||||
Date: Mon, 19 Sep 2022 17:49:23 +0800
|
Date: Mon, 19 Sep 2022 17:49:23 +0800
|
||||||
Subject: [PATCH 25/28] Let "kmem" print task context with physical address
|
Subject: [PATCH 41/89] Let "kmem" print task context with physical address
|
||||||
|
|
||||||
Patch [1] enables "kmem" to print task context if the given virtual
|
Patch [1] enables "kmem" to print task context if the given virtual
|
||||||
address is a vmalloced stack.
|
address is a vmalloced stack.
|
||||||
@ -43,7 +43,7 @@ Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
|||||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
diff --git a/memory.c b/memory.c
|
diff --git a/memory.c b/memory.c
|
||||||
index a60c3f9493f6..ff6b571361eb 100644
|
index 1b6f9ba17e57..c80ef61bdcf7 100644
|
||||||
--- a/memory.c
|
--- a/memory.c
|
||||||
+++ b/memory.c
|
+++ b/memory.c
|
||||||
@@ -13506,6 +13506,10 @@ kmem_search(struct meminfo *mi)
|
@@ -13506,6 +13506,10 @@ kmem_search(struct meminfo *mi)
|
@ -1,7 +1,7 @@
|
|||||||
From edbd19bb260f7a98bc9e0b49fe2f0b8214885797 Mon Sep 17 00:00:00 2001
|
From e39a2560928ef6f7e8dad80cb9a7521bdf0495e3 Mon Sep 17 00:00:00 2001
|
||||||
From: Lianbo Jiang <lijiang@redhat.com>
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
Date: Tue, 4 Oct 2022 18:57:11 +0800
|
Date: Tue, 4 Oct 2022 18:57:11 +0800
|
||||||
Subject: [PATCH 26/28] ppc64: still allow to move on if the emergency stacks
|
Subject: [PATCH 42/89] ppc64: still allow to move on if the emergency stacks
|
||||||
info fails to initialize
|
info fails to initialize
|
||||||
|
|
||||||
Currently crash will fail and then exit, if the initialization of
|
Currently crash will fail and then exit, if the initialization of
|
@ -1,7 +1,7 @@
|
|||||||
From cdcf2d3f4c69ffa8a29b70120ee4fca6e390123b Mon Sep 17 00:00:00 2001
|
From 975265a8056566ace8eaa6cf532fd42754e915a9 Mon Sep 17 00:00:00 2001
|
||||||
From: Matias Ezequiel Vara Larsen <matiasevara@gmail.com>
|
From: Matias Ezequiel Vara Larsen <matiasevara@gmail.com>
|
||||||
Date: Mon, 24 Oct 2022 11:35:29 +0200
|
Date: Mon, 24 Oct 2022 11:35:29 +0200
|
||||||
Subject: [PATCH 27/28] Fix segmentation fault in
|
Subject: [PATCH 43/89] Fix segmentation fault in
|
||||||
page_flags_init_from_pageflag_names()
|
page_flags_init_from_pageflag_names()
|
||||||
|
|
||||||
When read_string() fails in page_flags_init_from_pageflag_names(),
|
When read_string() fails in page_flags_init_from_pageflag_names(),
|
||||||
@ -22,7 +22,7 @@ Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
|||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
diff --git a/memory.c b/memory.c
|
diff --git a/memory.c b/memory.c
|
||||||
index ff6b571361eb..ddbf458277f0 100644
|
index c80ef61bdcf7..8724c4aa3d8a 100644
|
||||||
--- a/memory.c
|
--- a/memory.c
|
||||||
+++ b/memory.c
|
+++ b/memory.c
|
||||||
@@ -6599,7 +6599,7 @@ page_flags_init_from_pageflag_names(void)
|
@@ -6599,7 +6599,7 @@ page_flags_init_from_pageflag_names(void)
|
@ -1,7 +1,7 @@
|
|||||||
From 74fe453f2b5ddf1e1571d006d486cb214817a0ed Mon Sep 17 00:00:00 2001
|
From 4a6f318a39f78648a3bb13d74e31e3a331254e30 Mon Sep 17 00:00:00 2001
|
||||||
From: Lianbo Jiang <lijiang@redhat.com>
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
Date: Wed, 9 Nov 2022 14:21:57 +0800
|
Date: Wed, 9 Nov 2022 14:21:57 +0800
|
||||||
Subject: [PATCH 28/28] Fix for "ps/vm" commands to display correct %MEM and
|
Subject: [PATCH 44/89] Fix for "ps/vm" commands to display correct %MEM and
|
||||||
RSS values
|
RSS values
|
||||||
|
|
||||||
The ps/vm commands may print the bogus value of the %MEM and RSS, the
|
The ps/vm commands may print the bogus value of the %MEM and RSS, the
|
||||||
@ -25,7 +25,7 @@ Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
|||||||
1 file changed, 18 insertions(+), 5 deletions(-)
|
1 file changed, 18 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
diff --git a/memory.c b/memory.c
|
diff --git a/memory.c b/memory.c
|
||||||
index ddbf458277f0..2167281b6039 100644
|
index 8724c4aa3d8a..9c15c1b745ef 100644
|
||||||
--- a/memory.c
|
--- a/memory.c
|
||||||
+++ b/memory.c
|
+++ b/memory.c
|
||||||
@@ -4714,18 +4714,29 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
|
@@ -4714,18 +4714,29 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
|
@ -0,0 +1,72 @@
|
|||||||
|
From acd2b8a54e4532f859173fe9f0d1b92b44cbc848 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Aaron Tomlin <atomlin@redhat.com>
|
||||||
|
Date: Tue, 29 Nov 2022 14:05:26 +0000
|
||||||
|
Subject: [PATCH 45/89] ps: Provide an option to display no header line
|
||||||
|
|
||||||
|
One might often find it useful to redirect/or filter the output
|
||||||
|
generated by the 'ps' command. This simple patch provides an option
|
||||||
|
(i.e. '-H') to display no header line so it does not need to be
|
||||||
|
considered e.g.
|
||||||
|
|
||||||
|
crash> ps -u -H | head -5
|
||||||
|
1 0 1 ffff956e8028d280 IN 0.0 174276 9272 systemd
|
||||||
|
1067 1 2 ffff956e81380000 IN 0.1 59480 15788 systemd-journal
|
||||||
|
1080 1 0 ffff956e8d152940 IN 0.0 36196 3548 systemd-udevd
|
||||||
|
1278 1 6 ffff956e8aa60000 IN 0.0 17664 3072 systemd-oomd
|
||||||
|
1366 1 7 ffff956e88548000 IN 0.0 10868 2328 dbus-broker-lau
|
||||||
|
|
||||||
|
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
help.c | 3 ++-
|
||||||
|
task.c | 6 +++++-
|
||||||
|
2 files changed, 7 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/help.c b/help.c
|
||||||
|
index e1ac6f93fde2..2cb570b244f4 100644
|
||||||
|
--- a/help.c
|
||||||
|
+++ b/help.c
|
||||||
|
@@ -1385,7 +1385,7 @@ NULL
|
||||||
|
char *help_ps[] = {
|
||||||
|
"ps",
|
||||||
|
"display process status information",
|
||||||
|
-"[-k|-u|-G|-y policy] [-s] [-p|-c|-t|-[l|m][-C cpu]|-a|-g|-r|-S|-A]\n [pid | task | command] ...",
|
||||||
|
+"[-k|-u|-G|-y policy] [-s] [-p|-c|-t|-[l|m][-C cpu]|-a|-g|-r|-S|-A|-H]\n [pid | task | command] ...",
|
||||||
|
" This command displays process status for selected, or all, processes" ,
|
||||||
|
" in the system. If no arguments are entered, the process data is",
|
||||||
|
" is displayed for all processes. Specific processes may be selected",
|
||||||
|
@@ -1464,6 +1464,7 @@ char *help_ps[] = {
|
||||||
|
" -r display resource limits (rlimits) of selected, or all, tasks.",
|
||||||
|
" -S display a summary consisting of the number of tasks in a task state.",
|
||||||
|
" -A display only the active task on each cpu.",
|
||||||
|
+" -H display no header line.",
|
||||||
|
"\nEXAMPLES",
|
||||||
|
" Show the process status of all current tasks:\n",
|
||||||
|
" %s> ps",
|
||||||
|
diff --git a/task.c b/task.c
|
||||||
|
index db2abc8106a2..88941c7b0e4d 100644
|
||||||
|
--- a/task.c
|
||||||
|
+++ b/task.c
|
||||||
|
@@ -3504,7 +3504,7 @@ cmd_ps(void)
|
||||||
|
cpuspec = NULL;
|
||||||
|
flag = 0;
|
||||||
|
|
||||||
|
- while ((c = getopt(argcnt, args, "ASgstcpkuGlmarC:y:")) != EOF) {
|
||||||
|
+ while ((c = getopt(argcnt, args, "HASgstcpkuGlmarC:y:")) != EOF) {
|
||||||
|
switch(c)
|
||||||
|
{
|
||||||
|
case 'k':
|
||||||
|
@@ -3615,6 +3615,10 @@ cmd_ps(void)
|
||||||
|
flag |= PS_ACTIVE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ case 'H':
|
||||||
|
+ flag |= PS_NO_HEADER;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
default:
|
||||||
|
argerrs++;
|
||||||
|
break;
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,150 @@
|
|||||||
|
From 6122f0d067ed5c522ad11fb91b6db3ea1d34f355 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ding Hui <dinghui@sangfor.com.cn>
|
||||||
|
Date: Thu, 1 Dec 2022 15:01:45 +0800
|
||||||
|
Subject: [PATCH 46/89] arm64: fix backtraces of KASAN kernel dumpfile
|
||||||
|
truncated
|
||||||
|
|
||||||
|
We met "bt" command on KASAN kernel vmcore display truncated backtraces
|
||||||
|
like this:
|
||||||
|
|
||||||
|
crash> bt
|
||||||
|
PID: 4131 TASK: ffff8001521df000 CPU: 3 COMMAND: "bash"
|
||||||
|
#0 [ffff2000224b0cb0] machine_kexec_prepare at ffff2000200bff4c
|
||||||
|
|
||||||
|
After digging the root cause, it turns out that arm64_in_kdump_text()
|
||||||
|
found wrong bt->bptr at "machine_kexec" branch.
|
||||||
|
|
||||||
|
Disassemble machine_kexec() of KASAN vmlinux (gcc 7.3.0):
|
||||||
|
|
||||||
|
crash> dis -x machine_kexec
|
||||||
|
0xffff2000200bff50 <machine_kexec>: stp x29, x30, [sp,#-208]!
|
||||||
|
0xffff2000200bff54 <machine_kexec+0x4>: mov x29, sp
|
||||||
|
0xffff2000200bff58 <machine_kexec+0x8>: stp x19, x20, [sp,#16]
|
||||||
|
0xffff2000200bff5c <machine_kexec+0xc>: str x24, [sp,#56]
|
||||||
|
0xffff2000200bff60 <machine_kexec+0x10>: str x26, [sp,#72]
|
||||||
|
0xffff2000200bff64 <machine_kexec+0x14>: mov x2, #0x8ab3
|
||||||
|
0xffff2000200bff68 <machine_kexec+0x18>: add x1, x29, #0x70
|
||||||
|
0xffff2000200bff6c <machine_kexec+0x1c>: lsr x1, x1, #3
|
||||||
|
0xffff2000200bff70 <machine_kexec+0x20>: movk x2, #0x41b5, lsl #16
|
||||||
|
0xffff2000200bff74 <machine_kexec+0x24>: mov x19, #0x200000000000
|
||||||
|
0xffff2000200bff78 <machine_kexec+0x28>: adrp x3, 0xffff2000224b0000
|
||||||
|
0xffff2000200bff7c <machine_kexec+0x2c>: movk x19, #0xdfff, lsl #48
|
||||||
|
0xffff2000200bff80 <machine_kexec+0x30>: add x3, x3, #0xcb0
|
||||||
|
0xffff2000200bff84 <machine_kexec+0x34>: add x4, x1, x19
|
||||||
|
0xffff2000200bff88 <machine_kexec+0x38>: stp x2, x3, [x29,#112]
|
||||||
|
0xffff2000200bff8c <machine_kexec+0x3c>: adrp x2, 0xffff2000200bf000 <swsusp_arch_resume+0x1e8>
|
||||||
|
0xffff2000200bff90 <machine_kexec+0x40>: add x2, x2, #0xf50
|
||||||
|
0xffff2000200bff94 <machine_kexec+0x44>: str x2, [x29,#128]
|
||||||
|
0xffff2000200bff98 <machine_kexec+0x48>: mov w2, #0xf1f1f1f1
|
||||||
|
0xffff2000200bff9c <machine_kexec+0x4c>: str w2, [x1,x19]
|
||||||
|
0xffff2000200bffa0 <machine_kexec+0x50>: mov w2, #0xf200
|
||||||
|
0xffff2000200bffa4 <machine_kexec+0x54>: mov w1, #0xf3f3f3f3
|
||||||
|
0xffff2000200bffa8 <machine_kexec+0x58>: movk w2, #0xf2f2, lsl #16
|
||||||
|
0xffff2000200bffac <machine_kexec+0x5c>: stp w2, w1, [x4,#4]
|
||||||
|
|
||||||
|
We notice that:
|
||||||
|
1. machine_kexec() start address is 0xffff2000200bff50
|
||||||
|
2. the instruction at machine_kexec+0x44 stores the same value
|
||||||
|
0xffff2000200bff50 (comes from 0xffff2000200bf000 + 0xf50)
|
||||||
|
into stack postion [x29,#128].
|
||||||
|
|
||||||
|
When arm64_in_kdump_text() searches for LR from stack, it met
|
||||||
|
0xffff2000200bff50 firstly, so got wrong bt->bptr.
|
||||||
|
|
||||||
|
We know that the real LR is always greater than the start address
|
||||||
|
of a function, so let's fix it by changing the search conditon to
|
||||||
|
(*ptr > xxx_start) && (*ptr < xxx_end).
|
||||||
|
|
||||||
|
Signed-off-by: Ding Hui <dinghui@sangfor.com.cn>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
arm64.c | 18 +++++++++---------
|
||||||
|
1 file changed, 9 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arm64.c b/arm64.c
|
||||||
|
index c3e26a371a61..7e8a7db1fcc4 100644
|
||||||
|
--- a/arm64.c
|
||||||
|
+++ b/arm64.c
|
||||||
|
@@ -3479,7 +3479,7 @@ arm64_in_kdump_text(struct bt_info *bt, struct arm64_stackframe *frame)
|
||||||
|
ms = machdep->machspec;
|
||||||
|
for (ptr = start - 8; ptr >= base; ptr--) {
|
||||||
|
if (bt->flags & BT_OPT_BACK_TRACE) {
|
||||||
|
- if ((*ptr >= ms->crash_kexec_start) &&
|
||||||
|
+ if ((*ptr > ms->crash_kexec_start) &&
|
||||||
|
(*ptr < ms->crash_kexec_end) &&
|
||||||
|
INSTACK(*(ptr - 1), bt)) {
|
||||||
|
bt->bptr = ((ulong)(ptr - 1) - (ulong)base)
|
||||||
|
@@ -3488,7 +3488,7 @@ arm64_in_kdump_text(struct bt_info *bt, struct arm64_stackframe *frame)
|
||||||
|
fprintf(fp, "%lx: %lx (crash_kexec)\n", bt->bptr, *ptr);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
- if ((*ptr >= ms->crash_save_cpu_start) &&
|
||||||
|
+ if ((*ptr > ms->crash_save_cpu_start) &&
|
||||||
|
(*ptr < ms->crash_save_cpu_end) &&
|
||||||
|
INSTACK(*(ptr - 1), bt)) {
|
||||||
|
bt->bptr = ((ulong)(ptr - 1) - (ulong)base)
|
||||||
|
@@ -3498,14 +3498,14 @@ arm64_in_kdump_text(struct bt_info *bt, struct arm64_stackframe *frame)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
- if ((*ptr >= ms->machine_kexec_start) && (*ptr < ms->machine_kexec_end)) {
|
||||||
|
+ if ((*ptr > ms->machine_kexec_start) && (*ptr < ms->machine_kexec_end)) {
|
||||||
|
bt->bptr = ((ulong)ptr - (ulong)base)
|
||||||
|
+ task_to_stackbase(bt->tc->task);
|
||||||
|
if (CRASHDEBUG(1))
|
||||||
|
fprintf(fp, "%lx: %lx (machine_kexec)\n", bt->bptr, *ptr);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
- if ((*ptr >= ms->crash_kexec_start) && (*ptr < ms->crash_kexec_end)) {
|
||||||
|
+ if ((*ptr > ms->crash_kexec_start) && (*ptr < ms->crash_kexec_end)) {
|
||||||
|
/*
|
||||||
|
* Stash the first crash_kexec frame in case the machine_kexec
|
||||||
|
* frame is not found.
|
||||||
|
@@ -3519,7 +3519,7 @@ arm64_in_kdump_text(struct bt_info *bt, struct arm64_stackframe *frame)
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
- if ((*ptr >= ms->crash_save_cpu_start) && (*ptr < ms->crash_save_cpu_end)) {
|
||||||
|
+ if ((*ptr > ms->crash_save_cpu_start) && (*ptr < ms->crash_save_cpu_end)) {
|
||||||
|
bt->bptr = ((ulong)ptr - (ulong)base)
|
||||||
|
+ task_to_stackbase(bt->tc->task);
|
||||||
|
if (CRASHDEBUG(1))
|
||||||
|
@@ -3566,7 +3566,7 @@ arm64_in_kdump_text_on_irq_stack(struct bt_info *bt)
|
||||||
|
|
||||||
|
for (ptr = start - 8; ptr >= base; ptr--) {
|
||||||
|
if (bt->flags & BT_OPT_BACK_TRACE) {
|
||||||
|
- if ((*ptr >= ms->crash_kexec_start) &&
|
||||||
|
+ if ((*ptr > ms->crash_kexec_start) &&
|
||||||
|
(*ptr < ms->crash_kexec_end) &&
|
||||||
|
INSTACK(*(ptr - 1), bt)) {
|
||||||
|
bt->bptr = ((ulong)(ptr - 1) - (ulong)base) + stackbase;
|
||||||
|
@@ -3576,7 +3576,7 @@ arm64_in_kdump_text_on_irq_stack(struct bt_info *bt)
|
||||||
|
FREEBUF(stackbuf);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
- if ((*ptr >= ms->crash_save_cpu_start) &&
|
||||||
|
+ if ((*ptr > ms->crash_save_cpu_start) &&
|
||||||
|
(*ptr < ms->crash_save_cpu_end) &&
|
||||||
|
INSTACK(*(ptr - 1), bt)) {
|
||||||
|
bt->bptr = ((ulong)(ptr - 1) - (ulong)base) + stackbase;
|
||||||
|
@@ -3587,7 +3587,7 @@ arm64_in_kdump_text_on_irq_stack(struct bt_info *bt)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
- if ((*ptr >= ms->crash_kexec_start) && (*ptr < ms->crash_kexec_end)) {
|
||||||
|
+ if ((*ptr > ms->crash_kexec_start) && (*ptr < ms->crash_kexec_end)) {
|
||||||
|
bt->bptr = ((ulong)ptr - (ulong)base) + stackbase;
|
||||||
|
if (CRASHDEBUG(1))
|
||||||
|
fprintf(fp, "%lx: %lx (crash_kexec on IRQ stack)\n",
|
||||||
|
@@ -3595,7 +3595,7 @@ arm64_in_kdump_text_on_irq_stack(struct bt_info *bt)
|
||||||
|
FREEBUF(stackbuf);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
- if ((*ptr >= ms->crash_save_cpu_start) && (*ptr < ms->crash_save_cpu_end)) {
|
||||||
|
+ if ((*ptr > ms->crash_save_cpu_start) && (*ptr < ms->crash_save_cpu_end)) {
|
||||||
|
bt->bptr = ((ulong)ptr - (ulong)base) + stackbase;
|
||||||
|
if (CRASHDEBUG(1))
|
||||||
|
fprintf(fp, "%lx: %lx (crash_save_cpu on IRQ stack)\n",
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,37 @@
|
|||||||
|
From 69786ee12c4842d2cbd39ea42df65c45fb043edd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavankumar Kondeti <quic_pkondeti@quicinc.com>
|
||||||
|
Date: Thu, 8 Dec 2022 09:55:07 +0530
|
||||||
|
Subject: [PATCH 47/89] arm64: handle vabits_actual symbol missing case
|
||||||
|
|
||||||
|
After kernel commit 0d9b1ffefabe ("arm64: mm: make vabits_actual
|
||||||
|
a build time constant if possible") introduced in Linux v5.19,
|
||||||
|
the crash will not find vabits_actual symbol if VA_BITS <= 48.
|
||||||
|
Add a fallback option to initialize VA_BITS based on the user
|
||||||
|
supplied machdep option.
|
||||||
|
|
||||||
|
Tested ramdumps loading in both 6.0 and 5.15 kernels.
|
||||||
|
|
||||||
|
Signed-off-by: Pavankumar Kondeti <quic_pkondeti@quicinc.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
arm64.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/arm64.c b/arm64.c
|
||||||
|
index 7e8a7db1fcc4..56fb841f43f8 100644
|
||||||
|
--- a/arm64.c
|
||||||
|
+++ b/arm64.c
|
||||||
|
@@ -4671,6 +4671,10 @@ arm64_calc_VA_BITS(void)
|
||||||
|
return;
|
||||||
|
} else if (arm64_set_va_bits_by_tcr()) {
|
||||||
|
return;
|
||||||
|
+ } else if (machdep->machspec->VA_BITS_ACTUAL) {
|
||||||
|
+ machdep->machspec->VA_BITS = machdep->machspec->VA_BITS_ACTUAL;
|
||||||
|
+ machdep->machspec->VA_START = _VA_START(machdep->machspec->VA_BITS_ACTUAL);
|
||||||
|
+ return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(sp = symbol_search("swapper_pg_dir")) &&
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,144 @@
|
|||||||
|
From 1f6b58b323f669293b4ef8d497fe7867d1411143 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Date: Wed, 7 Dec 2022 09:46:56 +0900
|
||||||
|
Subject: [PATCH 48/89] x86_64: Fix for move of per-cpu variables into struct
|
||||||
|
pcpu_hot
|
||||||
|
|
||||||
|
The following kernel commits, which are contained in Linux 6.2-rc1 and
|
||||||
|
later kernels, introduced struct pcpu_hot and moved several per-cpu
|
||||||
|
variables into it.
|
||||||
|
|
||||||
|
d7b6d709a76a x86/percpu: Move irq_stack variables next to current_task
|
||||||
|
7443b296e699 x86/percpu: Move cpu_number next to current_task
|
||||||
|
e57ef2ed97c1 x86: Put hot per CPU variables into a struct
|
||||||
|
|
||||||
|
Without the patch, crash fails to start session with the following
|
||||||
|
error:
|
||||||
|
|
||||||
|
$ crash vmlinux vmcore
|
||||||
|
...
|
||||||
|
bt: invalid size request: 0 type: "stack contents"
|
||||||
|
bt: read of stack at 0 failed
|
||||||
|
<segmentation violation in gdb>
|
||||||
|
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
x86_64.c | 44 +++++++++++++++++++++++++++++++++-----------
|
||||||
|
1 file changed, 33 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/x86_64.c b/x86_64.c
|
||||||
|
index 292c240e887e..1113a1055f77 100644
|
||||||
|
--- a/x86_64.c
|
||||||
|
+++ b/x86_64.c
|
||||||
|
@@ -1287,12 +1287,15 @@ x86_64_per_cpu_init(void)
|
||||||
|
{
|
||||||
|
int i, cpus, cpunumber;
|
||||||
|
struct machine_specific *ms;
|
||||||
|
- struct syment *irq_sp, *curr_sp, *cpu_sp, *hardirq_stack_ptr_sp;
|
||||||
|
+ struct syment *irq_sp, *curr_sp, *cpu_sp, *hardirq_stack_ptr_sp, *pcpu_sp;
|
||||||
|
ulong hardirq_stack_ptr;
|
||||||
|
ulong __per_cpu_load = 0;
|
||||||
|
+ long hardirq_addr = 0, cpu_addr = 0, curr_addr = 0;
|
||||||
|
|
||||||
|
ms = machdep->machspec;
|
||||||
|
|
||||||
|
+ pcpu_sp = per_cpu_symbol_search("pcpu_hot");
|
||||||
|
+
|
||||||
|
hardirq_stack_ptr_sp = per_cpu_symbol_search("hardirq_stack_ptr");
|
||||||
|
irq_sp = per_cpu_symbol_search("per_cpu__irq_stack_union");
|
||||||
|
cpu_sp = per_cpu_symbol_search("per_cpu__cpu_number");
|
||||||
|
@@ -1321,7 +1324,7 @@ x86_64_per_cpu_init(void)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!cpu_sp || (!irq_sp && !hardirq_stack_ptr_sp))
|
||||||
|
+ if (!pcpu_sp && (!cpu_sp || (!irq_sp && !hardirq_stack_ptr_sp)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (MEMBER_EXISTS("irq_stack_union", "irq_stack"))
|
||||||
|
@@ -1334,10 +1337,21 @@ x86_64_per_cpu_init(void)
|
||||||
|
if (kernel_symbol_exists("__per_cpu_load"))
|
||||||
|
__per_cpu_load = symbol_value("__per_cpu_load");
|
||||||
|
|
||||||
|
+ if (pcpu_sp) {
|
||||||
|
+ hardirq_addr = pcpu_sp->value + MEMBER_OFFSET("pcpu_hot", "hardirq_stack_ptr");
|
||||||
|
+ cpu_addr = pcpu_sp->value + MEMBER_OFFSET("pcpu_hot", "cpu_number");
|
||||||
|
+ curr_addr = pcpu_sp->value + MEMBER_OFFSET("pcpu_hot", "current_task");
|
||||||
|
+ } else {
|
||||||
|
+ if (hardirq_stack_ptr_sp)
|
||||||
|
+ hardirq_addr = hardirq_stack_ptr_sp->value;
|
||||||
|
+ cpu_addr = cpu_sp->value;
|
||||||
|
+ curr_addr = curr_sp->value;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
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],
|
||||||
|
+ if (!readmem(cpu_addr + kt->__per_cpu_offset[i],
|
||||||
|
KVADDR, &cpunumber, sizeof(int),
|
||||||
|
"cpu number (per_cpu)", QUIET|RETURN_ON_ERROR))
|
||||||
|
break;
|
||||||
|
@@ -1346,8 +1360,8 @@ x86_64_per_cpu_init(void)
|
||||||
|
break;
|
||||||
|
cpus++;
|
||||||
|
|
||||||
|
- if (hardirq_stack_ptr_sp) {
|
||||||
|
- if (!readmem(hardirq_stack_ptr_sp->value + kt->__per_cpu_offset[i],
|
||||||
|
+ if (pcpu_sp || hardirq_stack_ptr_sp) {
|
||||||
|
+ if (!readmem(hardirq_addr + kt->__per_cpu_offset[i],
|
||||||
|
KVADDR, &hardirq_stack_ptr, sizeof(void *),
|
||||||
|
"hardirq_stack_ptr (per_cpu)", QUIET|RETURN_ON_ERROR))
|
||||||
|
continue;
|
||||||
|
@@ -1370,13 +1384,13 @@ x86_64_per_cpu_init(void)
|
||||||
|
else
|
||||||
|
kt->cpus = cpus;
|
||||||
|
|
||||||
|
- if (DUMPFILE() && curr_sp) {
|
||||||
|
+ if (DUMPFILE() && (pcpu_sp || curr_sp)) {
|
||||||
|
if ((ms->current = calloc(kt->cpus, sizeof(ulong))) == NULL)
|
||||||
|
error(FATAL,
|
||||||
|
"cannot calloc %d x86_64 current pointers!\n",
|
||||||
|
kt->cpus);
|
||||||
|
for (i = 0; i < kt->cpus; i++)
|
||||||
|
- if (!readmem(curr_sp->value + kt->__per_cpu_offset[i],
|
||||||
|
+ if (!readmem(curr_addr + kt->__per_cpu_offset[i],
|
||||||
|
KVADDR, &ms->current[i], sizeof(ulong),
|
||||||
|
"current_task (per_cpu)", RETURN_ON_ERROR))
|
||||||
|
continue;
|
||||||
|
@@ -5622,11 +5636,19 @@ x86_64_get_smp_cpus(void)
|
||||||
|
char *cpu_pda_buf;
|
||||||
|
ulong level4_pgt, cpu_pda_addr;
|
||||||
|
struct syment *sp;
|
||||||
|
- ulong __per_cpu_load = 0;
|
||||||
|
+ ulong __per_cpu_load = 0, cpu_addr;
|
||||||
|
|
||||||
|
if (!VALID_STRUCT(x8664_pda)) {
|
||||||
|
- if (!(sp = per_cpu_symbol_search("per_cpu__cpu_number")) ||
|
||||||
|
- !(kt->flags & PER_CPU_OFF))
|
||||||
|
+
|
||||||
|
+ if (!(kt->flags & PER_CPU_OFF))
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ if ((sp = per_cpu_symbol_search("pcpu_hot")) &&
|
||||||
|
+ (cpu_addr = MEMBER_OFFSET("pcpu_hot", "cpu_number")) != INVALID_OFFSET)
|
||||||
|
+ cpu_addr += sp->value;
|
||||||
|
+ else if ((sp = per_cpu_symbol_search("per_cpu__cpu_number")))
|
||||||
|
+ cpu_addr = sp->value;
|
||||||
|
+ else
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (kernel_symbol_exists("__per_cpu_load"))
|
||||||
|
@@ -5635,7 +5657,7 @@ x86_64_get_smp_cpus(void)
|
||||||
|
for (i = cpus = 0; i < NR_CPUS; i++) {
|
||||||
|
if (__per_cpu_load && kt->__per_cpu_offset[i] == __per_cpu_load)
|
||||||
|
break;
|
||||||
|
- if (!readmem(sp->value + kt->__per_cpu_offset[i],
|
||||||
|
+ if (!readmem(cpu_addr + kt->__per_cpu_offset[i],
|
||||||
|
KVADDR, &cpunumber, sizeof(int),
|
||||||
|
"cpu number (per_cpu)", QUIET|RETURN_ON_ERROR))
|
||||||
|
break;
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,163 @@
|
|||||||
|
From c05bbb36fcb468bce384ee4b8e30a0f5748bc4ae Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Date: Thu, 15 Dec 2022 11:31:38 +0900
|
||||||
|
Subject: [PATCH 49/89] Fix for mm_struct.rss_stat conversion into
|
||||||
|
percpu_counter
|
||||||
|
|
||||||
|
Kernel commit f1a7941243c1 ("mm: convert mm's rss stats into
|
||||||
|
percpu_counter"), which is contained in Linux 6.2-rc1 and later
|
||||||
|
kernels, changed mm_struct.rss_stat from struct mm_rss_stat into an
|
||||||
|
array of struct percpu_counter.
|
||||||
|
|
||||||
|
Without the patch, "ps" and several commands fail with the following
|
||||||
|
error message:
|
||||||
|
|
||||||
|
ps: invalid structure member offset: mm_rss_stat_count
|
||||||
|
FILE: memory.c LINE: 4724 FUNCTION: get_task_mem_usage()
|
||||||
|
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
defs.h | 3 +++
|
||||||
|
kernel.c | 2 ++
|
||||||
|
memory.c | 14 +++++++++++++-
|
||||||
|
symbols.c | 6 ++++--
|
||||||
|
tools.c | 28 ++++++++++++++++++++++++++++
|
||||||
|
5 files changed, 50 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index b7d76330141a..e4732c885371 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -2181,6 +2181,7 @@ struct offset_table { /* stash of commonly-used offsets */
|
||||||
|
long blk_mq_tags_nr_reserved_tags;
|
||||||
|
long blk_mq_tags_rqs;
|
||||||
|
long request_queue_hctx_table;
|
||||||
|
+ long percpu_counter_counters;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct size_table { /* stash of commonly-used sizes */
|
||||||
|
@@ -2351,6 +2352,7 @@ struct size_table { /* stash of commonly-used sizes */
|
||||||
|
long sbitmap_queue;
|
||||||
|
long sbq_wait_state;
|
||||||
|
long blk_mq_tags;
|
||||||
|
+ long percpu_counter;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct array_table {
|
||||||
|
@@ -5307,6 +5309,7 @@ struct rb_node *rb_right(struct rb_node *, struct rb_node *);
|
||||||
|
struct rb_node *rb_left(struct rb_node *, struct rb_node *);
|
||||||
|
struct rb_node *rb_next(struct rb_node *);
|
||||||
|
struct rb_node *rb_last(struct rb_root *);
|
||||||
|
+long percpu_counter_sum_positive(ulong fbc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* symbols.c
|
||||||
|
diff --git a/kernel.c b/kernel.c
|
||||||
|
index 2a1c1c391414..3ca513962970 100644
|
||||||
|
--- a/kernel.c
|
||||||
|
+++ b/kernel.c
|
||||||
|
@@ -316,6 +316,8 @@ kernel_init()
|
||||||
|
}
|
||||||
|
|
||||||
|
MEMBER_OFFSET_INIT(percpu_counter_count, "percpu_counter", "count");
|
||||||
|
+ MEMBER_OFFSET_INIT(percpu_counter_counters, "percpu_counter", "counters");
|
||||||
|
+ STRUCT_SIZE_INIT(percpu_counter, "percpu_counter");
|
||||||
|
|
||||||
|
if (STRUCT_EXISTS("runqueue")) {
|
||||||
|
rqstruct = "runqueue";
|
||||||
|
diff --git a/memory.c b/memory.c
|
||||||
|
index 9c15c1b745ef..9d003713534b 100644
|
||||||
|
--- a/memory.c
|
||||||
|
+++ b/memory.c
|
||||||
|
@@ -4713,7 +4713,7 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
|
||||||
|
/*
|
||||||
|
* Latest kernels have mm_struct.mm_rss_stat[].
|
||||||
|
*/
|
||||||
|
- if (VALID_MEMBER(mm_struct_rss_stat)) {
|
||||||
|
+ if (VALID_MEMBER(mm_struct_rss_stat) && VALID_MEMBER(mm_rss_stat_count)) {
|
||||||
|
long anonpages, filepages, count;
|
||||||
|
|
||||||
|
anonpages = tt->anonpages;
|
||||||
|
@@ -4737,6 +4737,18 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
|
||||||
|
(anonpages * sizeof(long)));
|
||||||
|
if (count > 0)
|
||||||
|
rss += count;
|
||||||
|
+
|
||||||
|
+ } else if (VALID_MEMBER(mm_struct_rss_stat)) {
|
||||||
|
+ /* 6.2: struct percpu_counter rss_stat[NR_MM_COUNTERS] */
|
||||||
|
+ ulong fbc;
|
||||||
|
+
|
||||||
|
+ fbc = tc->mm_struct + OFFSET(mm_struct_rss_stat) +
|
||||||
|
+ (tt->filepages * SIZE(percpu_counter));
|
||||||
|
+ rss += percpu_counter_sum_positive(fbc);
|
||||||
|
+
|
||||||
|
+ fbc = tc->mm_struct + OFFSET(mm_struct_rss_stat) +
|
||||||
|
+ (tt->anonpages * SIZE(percpu_counter));
|
||||||
|
+ rss += percpu_counter_sum_positive(fbc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check whether SPLIT_RSS_COUNTING is enabled */
|
||||||
|
diff --git a/symbols.c b/symbols.c
|
||||||
|
index a94660538492..657f50706819 100644
|
||||||
|
--- a/symbols.c
|
||||||
|
+++ b/symbols.c
|
||||||
|
@@ -10645,8 +10645,8 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
|
OFFSET(ktime_t_nsec));
|
||||||
|
fprintf(fp, " atomic_t_counter: %ld\n",
|
||||||
|
OFFSET(atomic_t_counter));
|
||||||
|
- fprintf(fp, " percpu_counter_count: %ld\n",
|
||||||
|
- OFFSET(percpu_counter_count));
|
||||||
|
+ fprintf(fp, " percpu_counter_count: %ld\n", OFFSET(percpu_counter_count));
|
||||||
|
+ fprintf(fp, " percpu_counter_counters: %ld\n", OFFSET(percpu_counter_counters));
|
||||||
|
fprintf(fp, " sk_buff_head_next: %ld\n",
|
||||||
|
OFFSET(sk_buff_head_next));
|
||||||
|
fprintf(fp, " sk_buff_head_qlen: %ld\n",
|
||||||
|
@@ -11040,6 +11040,8 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
|
fprintf(fp, " sbq_wait_state: %ld\n", SIZE(sbq_wait_state));
|
||||||
|
fprintf(fp, " blk_mq_tags: %ld\n", SIZE(blk_mq_tags));
|
||||||
|
|
||||||
|
+ fprintf(fp, " percpu_counter: %ld\n", SIZE(percpu_counter));
|
||||||
|
+
|
||||||
|
fprintf(fp, "\n array_table:\n");
|
||||||
|
/*
|
||||||
|
* Use get_array_length() for those fields not set up at init-time;
|
||||||
|
diff --git a/tools.c b/tools.c
|
||||||
|
index 6fa3c70bac2b..7f64bd6328cf 100644
|
||||||
|
--- a/tools.c
|
||||||
|
+++ b/tools.c
|
||||||
|
@@ -6902,3 +6902,31 @@ rb_last(struct rb_root *root)
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+long
|
||||||
|
+percpu_counter_sum_positive(ulong fbc)
|
||||||
|
+{
|
||||||
|
+ int i, count;
|
||||||
|
+ ulong addr;
|
||||||
|
+ long ret;
|
||||||
|
+
|
||||||
|
+ if (INVALID_MEMBER(percpu_counter_count))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ readmem(fbc + OFFSET(percpu_counter_count), KVADDR, &ret,
|
||||||
|
+ sizeof(long long), "percpu_counter.count", FAULT_ON_ERROR);
|
||||||
|
+
|
||||||
|
+ if (INVALID_MEMBER(percpu_counter_counters)) /* !CONFIG_SMP */
|
||||||
|
+ return (ret < 0) ? 0 : ret;
|
||||||
|
+
|
||||||
|
+ readmem(fbc + OFFSET(percpu_counter_counters), KVADDR, &addr,
|
||||||
|
+ sizeof(void *), "percpu_counter.counters", FAULT_ON_ERROR);
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < kt->cpus; i++) {
|
||||||
|
+ readmem(addr + kt->__per_cpu_offset[i], KVADDR, &count,
|
||||||
|
+ sizeof(int), "percpu_counter.counters count", FAULT_ON_ERROR);
|
||||||
|
+ ret += count;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return (ret < 0) ? 0 : ret;
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,48 @@
|
|||||||
|
From 1c56f2a37c79fa07c64dce34605d7b4a8a903243 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Date: Wed, 21 Dec 2022 17:09:08 +0800
|
||||||
|
Subject: [PATCH 50/89] Fix "mount" command to appropriately display the mount
|
||||||
|
dumps
|
||||||
|
|
||||||
|
Recently the following failure has been observed on some vmcores when
|
||||||
|
using the mount command:
|
||||||
|
|
||||||
|
crash> mount
|
||||||
|
MOUNT SUPERBLK TYPE DEVNAME DIRNAME
|
||||||
|
ffff97a4818a3480 ffff979500013800 rootfs none /
|
||||||
|
ffff97e4846ca700 ffff97e484653000 sysfs sysfs /sys
|
||||||
|
...
|
||||||
|
ffff97b484753420 0 mount: invalid kernel virtual address: 0 type: "super_block buffer"
|
||||||
|
|
||||||
|
The kernel virtual address of the super_block is zero when the mount
|
||||||
|
command fails with the vfsmnt address 0xffff97b484753420. And the
|
||||||
|
remaining mount information will be discarded. That is not expected.
|
||||||
|
|
||||||
|
Check the address and skip it with a warning, if this is an invalid
|
||||||
|
kernel virtual address, that can avoid truncating the remaining mount
|
||||||
|
dumps.
|
||||||
|
|
||||||
|
Reported-by: Dave Wysochanski <dwysocha@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
filesys.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/filesys.c b/filesys.c
|
||||||
|
index c2ea78de821d..d64b54a9b822 100644
|
||||||
|
--- a/filesys.c
|
||||||
|
+++ b/filesys.c
|
||||||
|
@@ -1491,6 +1491,10 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex
|
||||||
|
}
|
||||||
|
|
||||||
|
sbp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb));
|
||||||
|
+ if (!IS_KVADDR(sbp)) {
|
||||||
|
+ error(WARNING, "cannot get super_block from vfsmnt: 0x%lx\n", *vfsmnt);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (flags)
|
||||||
|
fprintf(fp, "%s", mount_hdr);
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
692
SOURCES/0051-Add-RISCV64-framework-code-support.patch
Normal file
692
SOURCES/0051-Add-RISCV64-framework-code-support.patch
Normal file
@ -0,0 +1,692 @@
|
|||||||
|
From 8ac8ab4f0e2d81b51b79b30f410c09e394b17e9c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xianting Tian <xianting.tian@linux.alibaba.com>
|
||||||
|
Date: Thu, 20 Oct 2022 09:50:06 +0800
|
||||||
|
Subject: [PATCH 51/89] Add RISCV64 framework code support
|
||||||
|
|
||||||
|
This patch mainly added some environment configurations, macro definitions,
|
||||||
|
specific architecture structures and some function declarations supported
|
||||||
|
by the RISCV64 architecture.
|
||||||
|
|
||||||
|
We can use the build command to get the simplest version crash tool:
|
||||||
|
make target=RISCV64 -j2
|
||||||
|
|
||||||
|
Co-developed-by: Lifang Xia <lifang_xia@linux.alibaba.com>
|
||||||
|
Signed-off-by: Xianting Tian <xianting.tian@linux.alibaba.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
Makefile | 7 +-
|
||||||
|
README | 6 +-
|
||||||
|
configure.c | 43 ++++++++++++-
|
||||||
|
defs.h | 154 +++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
diskdump.c | 11 +++-
|
||||||
|
help.c | 6 +-
|
||||||
|
lkcd_vmdump_v1.h | 8 +--
|
||||||
|
lkcd_vmdump_v2_v3.h | 8 +--
|
||||||
|
netdump.c | 9 ++-
|
||||||
|
ramdump.c | 2 +
|
||||||
|
riscv64.c | 54 ++++++++++++++++
|
||||||
|
symbols.c | 10 +++
|
||||||
|
12 files changed, 294 insertions(+), 24 deletions(-)
|
||||||
|
create mode 100644 riscv64.c
|
||||||
|
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index 2549d1d39273..c0de5ef8ff75 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -64,7 +64,7 @@ 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 mips64.c sparc64.c \
|
||||||
|
+ arm.c arm64.c mips.c mips64.c riscv64.c sparc64.c \
|
||||||
|
extensions.c remote.c va_server.c va_server_v1.c symbols.c cmdline.c \
|
||||||
|
lkcd_common.c lkcd_v1.c lkcd_v2_v3.c lkcd_v5.c lkcd_v7.c lkcd_v8.c\
|
||||||
|
lkcd_fix_mem.c s390_dump.c lkcd_x86_trace.c \
|
||||||
|
@@ -84,7 +84,7 @@ 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 mips64.o sparc64.o \
|
||||||
|
+ arm.o arm64.o mips.o mips64.o riscv64.o sparc64.o \
|
||||||
|
extensions.o remote.o va_server.o va_server_v1.o symbols.o cmdline.o \
|
||||||
|
lkcd_common.o lkcd_v1.o lkcd_v2_v3.o lkcd_v5.o lkcd_v7.o lkcd_v8.o \
|
||||||
|
lkcd_fix_mem.o s390_dump.o netdump.o diskdump.o makedumpfile.o xendump.o \
|
||||||
|
@@ -447,6 +447,9 @@ mips.o: ${GENERIC_HFILES} ${REDHAT_HFILES} mips.c
|
||||||
|
mips64.o: ${GENERIC_HFILES} ${REDHAT_HFILES} mips64.c
|
||||||
|
${CC} -c ${CRASH_CFLAGS} mips64.c ${WARNING_OPTIONS} ${WARNING_ERROR}
|
||||||
|
|
||||||
|
+riscv64.o: ${GENERIC_HFILES} ${REDHAT_HFILES} riscv64.c
|
||||||
|
+ ${CC} -c ${CRASH_CFLAGS} riscv64.c ${WARNING_OPTIONS} ${WARNING_ERROR}
|
||||||
|
+
|
||||||
|
sparc64.o: ${GENERIC_HFILES} ${REDHAT_HFILES} sparc64.c
|
||||||
|
${CC} -c ${CRASH_CFLAGS} sparc64.c ${WARNING_OPTIONS} ${WARNING_ERROR}
|
||||||
|
|
||||||
|
diff --git a/README b/README
|
||||||
|
index 00386f6f8224..13a9de5d2ccb 100644
|
||||||
|
--- a/README
|
||||||
|
+++ b/README
|
||||||
|
@@ -37,8 +37,8 @@
|
||||||
|
These are the current prerequisites:
|
||||||
|
|
||||||
|
o At this point, x86, ia64, x86_64, ppc64, ppc, arm, arm64, alpha, mips,
|
||||||
|
- mips64, s390 and s390x-based kernels are supported. Other architectures
|
||||||
|
- may be addressed in the future.
|
||||||
|
+ mips64, riscv64, s390 and s390x-based kernels are supported. Other
|
||||||
|
+ architectures may be addressed in the future.
|
||||||
|
|
||||||
|
o One size fits all -- the utility can be run on any Linux kernel version
|
||||||
|
version dating back to 2.2.5-15. A primary design goal is to always
|
||||||
|
@@ -98,6 +98,8 @@
|
||||||
|
arm64 dumpfiles may be built by typing "make target=ARM64".
|
||||||
|
o On an x86_64 host, an x86_64 binary that can be used to analyze
|
||||||
|
ppc64le dumpfiles may be built by typing "make target=PPC64".
|
||||||
|
+ o On an x86_64 host, an x86_64 binary that can be used to analyze
|
||||||
|
+ riscv64 dumpfiles may be built by typing "make target=RISCV64".
|
||||||
|
|
||||||
|
Traditionally when vmcores are compressed via the makedumpfile(8) facility
|
||||||
|
the libz compression library is used, and by default the crash utility
|
||||||
|
diff --git a/configure.c b/configure.c
|
||||||
|
index b691a139b960..7de89553dbd3 100644
|
||||||
|
--- a/configure.c
|
||||||
|
+++ b/configure.c
|
||||||
|
@@ -107,6 +107,7 @@ void add_extra_lib(char *);
|
||||||
|
#undef MIPS
|
||||||
|
#undef SPARC64
|
||||||
|
#undef MIPS64
|
||||||
|
+#undef RISCV64
|
||||||
|
|
||||||
|
#define UNKNOWN 0
|
||||||
|
#define X86 1
|
||||||
|
@@ -122,6 +123,7 @@ void add_extra_lib(char *);
|
||||||
|
#define MIPS 11
|
||||||
|
#define SPARC64 12
|
||||||
|
#define MIPS64 13
|
||||||
|
+#define RISCV64 14
|
||||||
|
|
||||||
|
#define TARGET_X86 "TARGET=X86"
|
||||||
|
#define TARGET_ALPHA "TARGET=ALPHA"
|
||||||
|
@@ -136,6 +138,7 @@ void add_extra_lib(char *);
|
||||||
|
#define TARGET_MIPS "TARGET=MIPS"
|
||||||
|
#define TARGET_MIPS64 "TARGET=MIPS64"
|
||||||
|
#define TARGET_SPARC64 "TARGET=SPARC64"
|
||||||
|
+#define TARGET_RISCV64 "TARGET=RISCV64"
|
||||||
|
|
||||||
|
#define TARGET_CFLAGS_X86 "TARGET_CFLAGS=-D_FILE_OFFSET_BITS=64"
|
||||||
|
#define TARGET_CFLAGS_ALPHA "TARGET_CFLAGS="
|
||||||
|
@@ -158,6 +161,8 @@ void add_extra_lib(char *);
|
||||||
|
#define TARGET_CFLAGS_MIPS_ON_X86_64 "TARGET_CFLAGS=-m32 -D_FILE_OFFSET_BITS=64"
|
||||||
|
#define TARGET_CFLAGS_MIPS64 "TARGET_CFLAGS="
|
||||||
|
#define TARGET_CFLAGS_SPARC64 "TARGET_CFLAGS="
|
||||||
|
+#define TARGET_CFLAGS_RISCV64 "TARGET_CFLAGS="
|
||||||
|
+#define TARGET_CFLAGS_RISCV64_ON_X86_64 "TARGET_CFLAGS="
|
||||||
|
|
||||||
|
#define GDB_TARGET_DEFAULT "GDB_CONF_FLAGS="
|
||||||
|
#define GDB_TARGET_ARM_ON_X86 "GDB_CONF_FLAGS=--target=arm-elf-linux"
|
||||||
|
@@ -168,6 +173,7 @@ void add_extra_lib(char *);
|
||||||
|
#define GDB_TARGET_PPC64_ON_X86_64 "GDB_CONF_FLAGS=--target=powerpc64le-unknown-linux-gnu"
|
||||||
|
#define GDB_TARGET_MIPS_ON_X86 "GDB_CONF_FLAGS=--target=mipsel-elf-linux"
|
||||||
|
#define GDB_TARGET_MIPS_ON_X86_64 "GDB_CONF_FLAGS=--target=mipsel-elf-linux CFLAGS=-m32"
|
||||||
|
+#define GDB_TARGET_RISCV64_ON_X86_64 "GDB_CONF_FLAGS=--target=riscv64-unknown-linux-gnu"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The original plan was to allow the use of a particular version
|
||||||
|
@@ -394,6 +400,9 @@ get_current_configuration(struct supported_gdb_version *sp)
|
||||||
|
#ifdef __sparc_v9__
|
||||||
|
target_data.target = SPARC64;
|
||||||
|
#endif
|
||||||
|
+#if defined(__riscv) && (__riscv_xlen == 64)
|
||||||
|
+ target_data.target = RISCV64;
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
set_initial_target(sp);
|
||||||
|
|
||||||
|
@@ -447,6 +456,12 @@ get_current_configuration(struct supported_gdb_version *sp)
|
||||||
|
if ((target_data.initial_gdb_target != UNKNOWN) &&
|
||||||
|
(target_data.host != target_data.initial_gdb_target))
|
||||||
|
arch_mismatch(sp);
|
||||||
|
+ } else if ((target_data.target == X86_64) &&
|
||||||
|
+ (name_to_target((char *)target_data.target_as_param) == RISCV64)) {
|
||||||
|
+ /*
|
||||||
|
+ * Build an RISCV64 crash binary on an X86_64 host.
|
||||||
|
+ */
|
||||||
|
+ target_data.target = RISCV64;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"\ntarget=%s is not supported on the %s host architecture\n\n",
|
||||||
|
@@ -487,6 +502,14 @@ get_current_configuration(struct supported_gdb_version *sp)
|
||||||
|
(target_data.target != MIPS64))
|
||||||
|
arch_mismatch(sp);
|
||||||
|
|
||||||
|
+ if ((target_data.initial_gdb_target == RISCV64) &&
|
||||||
|
+ (target_data.target != RISCV64)) {
|
||||||
|
+ if (target_data.target == X86_64)
|
||||||
|
+ target_data.target = RISCV64;
|
||||||
|
+ else
|
||||||
|
+ arch_mismatch(sp);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if ((target_data.initial_gdb_target == X86) &&
|
||||||
|
(target_data.target != X86)) {
|
||||||
|
if (target_data.target == X86_64)
|
||||||
|
@@ -650,6 +673,9 @@ show_configuration(void)
|
||||||
|
case SPARC64:
|
||||||
|
printf("TARGET: SPARC64\n");
|
||||||
|
break;
|
||||||
|
+ case RISCV64:
|
||||||
|
+ printf("TARGET: RISCV64\n");
|
||||||
|
+ break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(target_data.program)) {
|
||||||
|
@@ -767,6 +793,14 @@ build_configure(struct supported_gdb_version *sp)
|
||||||
|
target = TARGET_SPARC64;
|
||||||
|
target_CFLAGS = TARGET_CFLAGS_SPARC64;
|
||||||
|
break;
|
||||||
|
+ case RISCV64:
|
||||||
|
+ target = TARGET_RISCV64;
|
||||||
|
+ if (target_data.host == X86_64) {
|
||||||
|
+ target_CFLAGS = TARGET_CFLAGS_RISCV64_ON_X86_64;
|
||||||
|
+ gdb_conf_flags = GDB_TARGET_RISCV64_ON_X86_64;
|
||||||
|
+ } else
|
||||||
|
+ target_CFLAGS = TARGET_CFLAGS_RISCV64;
|
||||||
|
+ break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ldflags = get_extra_flags("LDFLAGS.extra", NULL);
|
||||||
|
@@ -1364,7 +1398,7 @@ make_spec_file(struct supported_gdb_version *sp)
|
||||||
|
printf("Vendor: Red Hat, Inc.\n");
|
||||||
|
printf("Packager: Dave Anderson <anderson@redhat.com>\n");
|
||||||
|
printf("ExclusiveOS: Linux\n");
|
||||||
|
- printf("ExclusiveArch: %%{ix86} alpha ia64 ppc ppc64 ppc64pseries ppc64iseries x86_64 s390 s390x arm aarch64 ppc64le mips mipsel mips64el sparc64\n");
|
||||||
|
+ printf("ExclusiveArch: %%{ix86} alpha ia64 ppc ppc64 ppc64pseries ppc64iseries x86_64 s390 s390x arm aarch64 ppc64le mips mipsel mips64el sparc64 riscv64\n");
|
||||||
|
printf("Buildroot: %%{_tmppath}/%%{name}-root\n");
|
||||||
|
printf("BuildRequires: ncurses-devel zlib-devel bison\n");
|
||||||
|
printf("Requires: binutils\n");
|
||||||
|
@@ -1597,6 +1631,8 @@ set_initial_target(struct supported_gdb_version *sp)
|
||||||
|
target_data.initial_gdb_target = MIPS;
|
||||||
|
else if (strncmp(buf, "SPARC64", strlen("SPARC64")) == 0)
|
||||||
|
target_data.initial_gdb_target = SPARC64;
|
||||||
|
+ else if (strncmp(buf, "RISCV64", strlen("RISCV64")) == 0)
|
||||||
|
+ target_data.initial_gdb_target = RISCV64;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
@@ -1617,6 +1653,7 @@ target_to_name(int target)
|
||||||
|
case MIPS: return("MIPS");
|
||||||
|
case MIPS64: return("MIPS64");
|
||||||
|
case SPARC64: return("SPARC64");
|
||||||
|
+ case RISCV64: return("RISCV64");
|
||||||
|
}
|
||||||
|
|
||||||
|
return "UNKNOWN";
|
||||||
|
@@ -1681,6 +1718,10 @@ name_to_target(char *name)
|
||||||
|
return MIPS64;
|
||||||
|
else if (strncmp(name, "sparc64", strlen("sparc64")) == 0)
|
||||||
|
return SPARC64;
|
||||||
|
+ else if (strncmp(name, "RISCV64", strlen("RISCV64")) == 0)
|
||||||
|
+ return RISCV64;
|
||||||
|
+ else if (strncmp(name, "riscv64", strlen("riscv64")) == 0)
|
||||||
|
+ return RISCV64;
|
||||||
|
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index e4732c885371..f46b666dde13 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -76,7 +76,7 @@
|
||||||
|
#if !defined(X86) && !defined(X86_64) && !defined(ALPHA) && !defined(PPC) && \
|
||||||
|
!defined(IA64) && !defined(PPC64) && !defined(S390) && !defined(S390X) && \
|
||||||
|
!defined(ARM) && !defined(ARM64) && !defined(MIPS) && !defined(MIPS64) && \
|
||||||
|
- !defined(SPARC64)
|
||||||
|
+ !defined(RISCV64) && !defined(SPARC64)
|
||||||
|
#ifdef __alpha__
|
||||||
|
#define ALPHA
|
||||||
|
#endif
|
||||||
|
@@ -118,6 +118,9 @@
|
||||||
|
#ifdef __sparc_v9__
|
||||||
|
#define SPARC64
|
||||||
|
#endif
|
||||||
|
+#if defined(__riscv) && (__riscv_xlen == 64)
|
||||||
|
+#define RISCV64
|
||||||
|
+#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef X86
|
||||||
|
@@ -159,6 +162,9 @@
|
||||||
|
#ifdef SPARC64
|
||||||
|
#define NR_CPUS (4096)
|
||||||
|
#endif
|
||||||
|
+#ifdef RISCV64
|
||||||
|
+#define NR_CPUS (256)
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
#define NR_DEVICE_DUMPS (64)
|
||||||
|
|
||||||
|
@@ -3486,6 +3492,63 @@ struct arm64_stackframe {
|
||||||
|
#define _MAX_PHYSMEM_BITS 48
|
||||||
|
#endif /* MIPS64 */
|
||||||
|
|
||||||
|
+#ifdef RISCV64
|
||||||
|
+#define _64BIT_
|
||||||
|
+#define MACHINE_TYPE "RISCV64"
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Direct memory mapping
|
||||||
|
+ */
|
||||||
|
+#define PTOV(X) \
|
||||||
|
+ (((unsigned long)(X)+(machdep->kvbase)) - machdep->machspec->phys_base)
|
||||||
|
+#define VTOP(X) ({ \
|
||||||
|
+ ulong _X = X; \
|
||||||
|
+ (THIS_KERNEL_VERSION >= LINUX(5,13,0) && \
|
||||||
|
+ (_X) >= machdep->machspec->kernel_link_addr) ? \
|
||||||
|
+ (((unsigned long)(_X)-(machdep->machspec->kernel_link_addr)) + \
|
||||||
|
+ machdep->machspec->phys_base): \
|
||||||
|
+ (((unsigned long)(_X)-(machdep->kvbase)) + \
|
||||||
|
+ machdep->machspec->phys_base); \
|
||||||
|
+ })
|
||||||
|
+#define PAGEBASE(X) (((ulong)(X)) & (ulong)machdep->pagemask)
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Stack size order
|
||||||
|
+ */
|
||||||
|
+#define THREAD_SIZE_ORDER 2
|
||||||
|
+
|
||||||
|
+#define PAGE_OFFSET (machdep->machspec->page_offset)
|
||||||
|
+#define VMALLOC_START (machdep->machspec->vmalloc_start_addr)
|
||||||
|
+#define VMALLOC_END (machdep->machspec->vmalloc_end)
|
||||||
|
+#define VMEMMAP_VADDR (machdep->machspec->vmemmap_vaddr)
|
||||||
|
+#define VMEMMAP_END (machdep->machspec->vmemmap_end)
|
||||||
|
+#define MODULES_VADDR (machdep->machspec->modules_vaddr)
|
||||||
|
+#define MODULES_END (machdep->machspec->modules_end)
|
||||||
|
+#define IS_VMALLOC_ADDR(X) riscv64_IS_VMALLOC_ADDR((ulong)(X))
|
||||||
|
+
|
||||||
|
+/* from arch/riscv/include/asm/pgtable.h */
|
||||||
|
+#define __SWP_TYPE_SHIFT 6
|
||||||
|
+#define __SWP_TYPE_BITS 5
|
||||||
|
+#define __SWP_TYPE_MASK ((1UL << __SWP_TYPE_BITS) - 1)
|
||||||
|
+#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
|
||||||
|
+
|
||||||
|
+#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS)
|
||||||
|
+
|
||||||
|
+#define SWP_TYPE(entry) (((entry) >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK)
|
||||||
|
+#define SWP_OFFSET(entry) ((entry) >> __SWP_OFFSET_SHIFT)
|
||||||
|
+#define __swp_type(entry) SWP_TYPE(entry)
|
||||||
|
+#define __swp_offset(entry) SWP_OFFSET(entry)
|
||||||
|
+
|
||||||
|
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 1 : 2)
|
||||||
|
+
|
||||||
|
+/* from arch/riscv/include/asm/sparsemem.h */
|
||||||
|
+#define _SECTION_SIZE_BITS 27
|
||||||
|
+#define _MAX_PHYSMEM_BITS 56 /* 56-bit physical address supported */
|
||||||
|
+#define PHYS_MASK_SHIFT _MAX_PHYSMEM_BITS
|
||||||
|
+#define PHYS_MASK (((1UL) << PHYS_MASK_SHIFT) - 1)
|
||||||
|
+
|
||||||
|
+#endif /* RISCV64 */
|
||||||
|
+
|
||||||
|
#ifdef X86
|
||||||
|
#define _32BIT_
|
||||||
|
#define MACHINE_TYPE "X86"
|
||||||
|
@@ -4534,6 +4597,10 @@ struct machine_specific {
|
||||||
|
#define MAX_HEXADDR_STRLEN (16)
|
||||||
|
#define UVADDR_PRLEN (16)
|
||||||
|
#endif
|
||||||
|
+#ifdef RISCV64
|
||||||
|
+#define MAX_HEXADDR_STRLEN (16)
|
||||||
|
+#define UVADDR_PRLEN (16)
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
#define BADADDR ((ulong)(-1))
|
||||||
|
#define BADVAL ((ulong)(-1))
|
||||||
|
@@ -5131,6 +5198,9 @@ void dump_build_data(void);
|
||||||
|
#ifdef MIPS64
|
||||||
|
#define machdep_init(X) mips64_init(X)
|
||||||
|
#endif
|
||||||
|
+#ifdef RISCV64
|
||||||
|
+#define machdep_init(X) riscv64_init(X)
|
||||||
|
+#endif
|
||||||
|
#ifdef SPARC64
|
||||||
|
#define machdep_init(X) sparc64_init(X)
|
||||||
|
#endif
|
||||||
|
@@ -5618,6 +5688,9 @@ void display_help_screen(char *);
|
||||||
|
#ifdef SPARC64
|
||||||
|
#define dump_machdep_table(X) sparc64_dump_machdep_table(X)
|
||||||
|
#endif
|
||||||
|
+#ifdef RISCV64
|
||||||
|
+#define dump_machdep_table(X) riscv64_dump_machdep_table(X)
|
||||||
|
+#endif
|
||||||
|
extern char *help_pointer[];
|
||||||
|
extern char *help_alias[];
|
||||||
|
extern char *help_ascii[];
|
||||||
|
@@ -6695,6 +6768,85 @@ struct machine_specific {
|
||||||
|
|
||||||
|
#endif /* MIPS64 */
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * riscv64.c
|
||||||
|
+ */
|
||||||
|
+void riscv64_display_regs_from_elf_notes(int, FILE *);
|
||||||
|
+
|
||||||
|
+#ifdef RISCV64
|
||||||
|
+void riscv64_init(int);
|
||||||
|
+void riscv64_dump_machdep_table(ulong);
|
||||||
|
+int riscv64_IS_VMALLOC_ADDR(ulong);
|
||||||
|
+
|
||||||
|
+#define display_idt_table() \
|
||||||
|
+ error(FATAL, "-d option is not applicable to RISCV64 architecture\n")
|
||||||
|
+
|
||||||
|
+/* from arch/riscv/include/asm/ptrace.h */
|
||||||
|
+struct riscv64_register {
|
||||||
|
+ ulong regs[36];
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct riscv64_pt_regs {
|
||||||
|
+ ulong badvaddr;
|
||||||
|
+ ulong cause;
|
||||||
|
+ ulong epc;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct riscv64_unwind_frame {
|
||||||
|
+ ulong fp;
|
||||||
|
+ ulong sp;
|
||||||
|
+ ulong pc;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#define KSYMS_START (0x1)
|
||||||
|
+
|
||||||
|
+struct machine_specific {
|
||||||
|
+ ulong phys_base;
|
||||||
|
+ ulong page_offset;
|
||||||
|
+ ulong vmalloc_start_addr;
|
||||||
|
+ ulong vmalloc_end;
|
||||||
|
+ ulong vmemmap_vaddr;
|
||||||
|
+ ulong vmemmap_end;
|
||||||
|
+ ulong modules_vaddr;
|
||||||
|
+ ulong modules_end;
|
||||||
|
+ ulong kernel_link_addr;
|
||||||
|
+
|
||||||
|
+ ulong _page_present;
|
||||||
|
+ ulong _page_read;
|
||||||
|
+ ulong _page_write;
|
||||||
|
+ ulong _page_exec;
|
||||||
|
+ ulong _page_user;
|
||||||
|
+ ulong _page_global;
|
||||||
|
+ ulong _page_accessed;
|
||||||
|
+ ulong _page_dirty;
|
||||||
|
+ ulong _page_soft;
|
||||||
|
+
|
||||||
|
+ ulong _pfn_shift;
|
||||||
|
+
|
||||||
|
+ struct riscv64_register *crash_task_regs;
|
||||||
|
+};
|
||||||
|
+/* from arch/riscv/include/asm/pgtable-bits.h */
|
||||||
|
+#define _PAGE_PRESENT (machdep->machspec->_page_present)
|
||||||
|
+#define _PAGE_READ (machdep->machspec->_page_read)
|
||||||
|
+#define _PAGE_WRITE (machdep->machspec->_page_write)
|
||||||
|
+#define _PAGE_EXEC (machdep->machspec->_page_exec)
|
||||||
|
+#define _PAGE_USER (machdep->machspec->_page_user)
|
||||||
|
+#define _PAGE_GLOBAL (machdep->machspec->_page_global)
|
||||||
|
+#define _PAGE_ACCESSED (machdep->machspec->_page_accessed)
|
||||||
|
+#define _PAGE_DIRTY (machdep->machspec->_page_dirty)
|
||||||
|
+#define _PAGE_SOFT (machdep->machspec->_page_soft)
|
||||||
|
+#define _PAGE_SEC (machdep->machspec->_page_sec)
|
||||||
|
+#define _PAGE_SHARE (machdep->machspec->_page_share)
|
||||||
|
+#define _PAGE_BUF (machdep->machspec->_page_buf)
|
||||||
|
+#define _PAGE_CACHE (machdep->machspec->_page_cache)
|
||||||
|
+#define _PAGE_SO (machdep->machspec->_page_so)
|
||||||
|
+#define _PAGE_SPECIAL _PAGE_SOFT
|
||||||
|
+#define _PAGE_TABLE _PAGE_PRESENT
|
||||||
|
+#define _PAGE_PROT_NONE _PAGE_READ
|
||||||
|
+#define _PAGE_PFN_SHIFT 10
|
||||||
|
+
|
||||||
|
+#endif /* RISCV64 */
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* sparc64.c
|
||||||
|
*/
|
||||||
|
diff --git a/diskdump.c b/diskdump.c
|
||||||
|
index 09fac543011a..136cbd63f799 100644
|
||||||
|
--- a/diskdump.c
|
||||||
|
+++ b/diskdump.c
|
||||||
|
@@ -622,6 +622,9 @@ restart:
|
||||||
|
else if (STRNEQ(header->utsname.machine, "aarch64") &&
|
||||||
|
machine_type_mismatch(file, "ARM64", NULL, 0))
|
||||||
|
goto err;
|
||||||
|
+ else if (STRNEQ(header->utsname.machine, "riscv64") &&
|
||||||
|
+ machine_type_mismatch(file, "RISCV64", NULL, 0))
|
||||||
|
+ goto err;
|
||||||
|
|
||||||
|
if (header->block_size != block_size) {
|
||||||
|
block_size = header->block_size;
|
||||||
|
@@ -780,6 +783,8 @@ restart:
|
||||||
|
dd->machine_type = EM_AARCH64;
|
||||||
|
else if (machine_type("SPARC64"))
|
||||||
|
dd->machine_type = EM_SPARCV9;
|
||||||
|
+ else if (machine_type("RISCV64"))
|
||||||
|
+ dd->machine_type = EM_RISCV;
|
||||||
|
else {
|
||||||
|
error(INFO, "%s: unsupported machine type: %s\n",
|
||||||
|
DISKDUMP_VALID() ? "diskdump" : "compressed kdump",
|
||||||
|
@@ -1751,7 +1756,8 @@ 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("MIPS64")) {
|
||||||
|
+ machine_type("SPARC64") || machine_type("MIPS64") ||
|
||||||
|
+ machine_type("RISCV64")) {
|
||||||
|
note64 = (void *)dd->notes_buf + tot;
|
||||||
|
len = sizeof(Elf64_Nhdr);
|
||||||
|
if (STRNEQ((char *)note64 + len, "QEMU"))
|
||||||
|
@@ -2558,7 +2564,8 @@ dump_registers_for_compressed_kdump(void)
|
||||||
|
if (!KDUMP_CMPRS_VALID() || (dd->header->header_version < 4) ||
|
||||||
|
!(machine_type("X86") || machine_type("X86_64") ||
|
||||||
|
machine_type("ARM64") || machine_type("PPC64") ||
|
||||||
|
- machine_type("MIPS") || machine_type("MIPS64")))
|
||||||
|
+ machine_type("MIPS") || machine_type("MIPS64") ||
|
||||||
|
+ machine_type("RISCV64")))
|
||||||
|
error(FATAL, "-r option not supported for this dumpfile\n");
|
||||||
|
|
||||||
|
if (machine_type("ARM64") && (kt->cpus != dd->num_prstatus_notes))
|
||||||
|
diff --git a/help.c b/help.c
|
||||||
|
index 2cb570b244f4..bfba43f6e9fd 100644
|
||||||
|
--- a/help.c
|
||||||
|
+++ b/help.c
|
||||||
|
@@ -9518,8 +9518,8 @@ char *README[] = {
|
||||||
|
" These are the current prerequisites: ",
|
||||||
|
"",
|
||||||
|
" o At this point, x86, ia64, x86_64, ppc64, ppc, arm, arm64, alpha, mips,",
|
||||||
|
-" mips64, s390 and s390x-based kernels are supported. Other architectures",
|
||||||
|
-" may be addressed in the future.",
|
||||||
|
+" mips64, riscv64, s390 and s390x-based kernels are supported. Other",
|
||||||
|
+" architectures may be addressed in the future.",
|
||||||
|
"",
|
||||||
|
" o One size fits all -- the utility can be run on any Linux kernel version",
|
||||||
|
" version dating back to 2.2.5-15. A primary design goal is to always",
|
||||||
|
@@ -9578,6 +9578,8 @@ README_ENTER_DIRECTORY,
|
||||||
|
" arm64 dumpfiles may be built by typing \"make target=ARM64\".",
|
||||||
|
" o On an x86_64 host, an x86_64 binary that can be used to analyze",
|
||||||
|
" ppc64le dumpfiles may be built by typing \"make target=PPC64\".",
|
||||||
|
+" o On an x86_64 host, an x86_64 binary that can be used to analyze",
|
||||||
|
+" riscv64 dumpfiles may be built by typing \"make target=RISCV64\".",
|
||||||
|
"",
|
||||||
|
" Traditionally when vmcores are compressed via the makedumpfile(8) facility",
|
||||||
|
" the libz compression library is used, and by default the crash utility",
|
||||||
|
diff --git a/lkcd_vmdump_v1.h b/lkcd_vmdump_v1.h
|
||||||
|
index 4933427fc755..98ee09495869 100644
|
||||||
|
--- a/lkcd_vmdump_v1.h
|
||||||
|
+++ b/lkcd_vmdump_v1.h
|
||||||
|
@@ -114,14 +114,8 @@ typedef struct _dump_header_s {
|
||||||
|
struct new_utsname dh_utsname;
|
||||||
|
|
||||||
|
/* the dump registers */
|
||||||
|
-#ifndef IA64
|
||||||
|
-#ifndef S390
|
||||||
|
-#ifndef S390X
|
||||||
|
-#ifndef ARM64
|
||||||
|
+#if !defined(IA64) && !defined(S390) && !defined(S390X) && !defined(ARM64) && !defined(RISCV64)
|
||||||
|
struct pt_regs dh_regs;
|
||||||
|
-#endif
|
||||||
|
-#endif
|
||||||
|
-#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* the address of the current task */
|
||||||
|
diff --git a/lkcd_vmdump_v2_v3.h b/lkcd_vmdump_v2_v3.h
|
||||||
|
index 984c2c25e3c6..ef3067f88e1e 100644
|
||||||
|
--- a/lkcd_vmdump_v2_v3.h
|
||||||
|
+++ b/lkcd_vmdump_v2_v3.h
|
||||||
|
@@ -37,7 +37,7 @@
|
||||||
|
|
||||||
|
#if defined(ARM) || defined(X86) || defined(PPC) || defined(S390) || \
|
||||||
|
defined(S390X) || defined(ARM64) || defined(MIPS) || \
|
||||||
|
- defined(MIPS64) || defined(SPARC64)
|
||||||
|
+ defined(MIPS64) || defined(SPARC64) || defined(RISCV64)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Kernel header file for Linux crash dumps.
|
||||||
|
@@ -84,13 +84,9 @@ typedef struct _dump_header_asm_s {
|
||||||
|
uint32_t dha_eip;
|
||||||
|
|
||||||
|
/* the dump registers */
|
||||||
|
-#ifndef S390
|
||||||
|
-#ifndef S390X
|
||||||
|
-#ifndef ARM64
|
||||||
|
+#if !defined(S390) && !defined(S390X) && !defined(ARM64) && !defined(RISCV64)
|
||||||
|
struct pt_regs dha_regs;
|
||||||
|
#endif
|
||||||
|
-#endif
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
} dump_header_asm_t;
|
||||||
|
|
||||||
|
diff --git a/netdump.c b/netdump.c
|
||||||
|
index e8721d89f1a3..c4c8baae0d20 100644
|
||||||
|
--- a/netdump.c
|
||||||
|
+++ b/netdump.c
|
||||||
|
@@ -300,6 +300,12 @@ is_netdump(char *file, ulong source_query)
|
||||||
|
goto bailout;
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ case EM_RISCV:
|
||||||
|
+ if (machine_type_mismatch(file, "RISCV64", NULL,
|
||||||
|
+ source_query))
|
||||||
|
+ goto bailout;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
default:
|
||||||
|
if (machine_type_mismatch(file, "(unknown)", NULL,
|
||||||
|
source_query))
|
||||||
|
@@ -2935,7 +2941,8 @@ dump_registers_for_elf_dumpfiles(void)
|
||||||
|
|
||||||
|
if (!(machine_type("X86") || machine_type("X86_64") ||
|
||||||
|
machine_type("ARM64") || machine_type("PPC64") ||
|
||||||
|
- machine_type("MIPS") || machine_type("MIPS64")))
|
||||||
|
+ machine_type("MIPS") || machine_type("MIPS64") ||
|
||||||
|
+ machine_type("RISCV64")))
|
||||||
|
error(FATAL, "-r option not supported for this dumpfile\n");
|
||||||
|
|
||||||
|
if (NETDUMP_DUMPFILE()) {
|
||||||
|
diff --git a/ramdump.c b/ramdump.c
|
||||||
|
index a206fcbbab3c..d2bd7ffb0b4b 100644
|
||||||
|
--- a/ramdump.c
|
||||||
|
+++ b/ramdump.c
|
||||||
|
@@ -188,6 +188,8 @@ char *ramdump_to_elf(void)
|
||||||
|
e_machine = EM_MIPS;
|
||||||
|
else if (machine_type("X86_64"))
|
||||||
|
e_machine = EM_X86_64;
|
||||||
|
+ else if (machine_type("RISCV64"))
|
||||||
|
+ e_machine = EM_RISCV;
|
||||||
|
else
|
||||||
|
error(FATAL, "ramdump: unsupported machine type: %s\n",
|
||||||
|
MACHINE_TYPE);
|
||||||
|
diff --git a/riscv64.c b/riscv64.c
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000000..4f858a418a8c
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/riscv64.c
|
||||||
|
@@ -0,0 +1,54 @@
|
||||||
|
+/* riscv64.c - core analysis suite
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2022 Alibaba Group Holding Limited.
|
||||||
|
+ *
|
||||||
|
+ * This program is free software; you can redistribute it and/or modify
|
||||||
|
+ * it under the terms of the GNU General Public License as published by
|
||||||
|
+ * the Free Software Foundation; either version 2 of the License, or
|
||||||
|
+ * (at your option) any later version.
|
||||||
|
+ *
|
||||||
|
+ * This program is distributed in the hope that it will be useful,
|
||||||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
+ * GNU General Public License for more details.
|
||||||
|
+ */
|
||||||
|
+#include "defs.h"
|
||||||
|
+#ifdef RISCV64
|
||||||
|
+
|
||||||
|
+#include <elf.h>
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+riscv64_dump_machdep_table(ulong arg)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Include both vmalloc'd and module address space as VMALLOC space.
|
||||||
|
+ */
|
||||||
|
+int
|
||||||
|
+riscv64_IS_VMALLOC_ADDR(ulong vaddr)
|
||||||
|
+{
|
||||||
|
+ return ((vaddr >= VMALLOC_START && vaddr <= VMALLOC_END) ||
|
||||||
|
+ (vaddr >= VMEMMAP_VADDR && vaddr <= VMEMMAP_END) ||
|
||||||
|
+ (vaddr >= MODULES_VADDR && vaddr <= MODULES_END));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+riscv64_init(int when)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+riscv64_display_regs_from_elf_notes(int cpu, FILE *ofp)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#else /* !RISCV64 */
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+riscv64_display_regs_from_elf_notes(int cpu, FILE *ofp)
|
||||||
|
+{
|
||||||
|
+ return;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif /* !RISCV64 */
|
||||||
|
diff --git a/symbols.c b/symbols.c
|
||||||
|
index 657f50706819..d1b35a56aa71 100644
|
||||||
|
--- a/symbols.c
|
||||||
|
+++ b/symbols.c
|
||||||
|
@@ -3745,6 +3745,11 @@ is_kernel(char *file)
|
||||||
|
goto bailout;
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ case EM_RISCV:
|
||||||
|
+ if (machine_type_mismatch(file, "RISCV64", NULL, 0))
|
||||||
|
+ goto bailout;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
default:
|
||||||
|
if (machine_type_mismatch(file, "(unknown)", NULL, 0))
|
||||||
|
goto bailout;
|
||||||
|
@@ -4004,6 +4009,11 @@ is_shared_object(char *file)
|
||||||
|
if (machine_type("MIPS64"))
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
+
|
||||||
|
+ case EM_RISCV:
|
||||||
|
+ if (machine_type("RISCV64"))
|
||||||
|
+ return TRUE;
|
||||||
|
+ break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CRASHDEBUG(1))
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
44
SOURCES/0053-RISCV64-Add-dis-command-support.patch
Normal file
44
SOURCES/0053-RISCV64-Add-dis-command-support.patch
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
From 4876c73ca54a8ee2e02032d1b10832e0de9adde3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xianting Tian <xianting.tian@linux.alibaba.com>
|
||||||
|
Date: Thu, 20 Oct 2022 09:50:08 +0800
|
||||||
|
Subject: [PATCH 53/89] RISCV64: Add 'dis' command support
|
||||||
|
|
||||||
|
Use generic_dis_filter() function to support dis command implementation.
|
||||||
|
|
||||||
|
With this patch, we can get the disassembled code,
|
||||||
|
crash> dis __crash_kexec
|
||||||
|
0xffffffff80088580 <__crash_kexec>: addi sp,sp,-352
|
||||||
|
0xffffffff80088582 <__crash_kexec+2>: sd s0,336(sp)
|
||||||
|
0xffffffff80088584 <__crash_kexec+4>: sd s1,328(sp)
|
||||||
|
0xffffffff80088586 <__crash_kexec+6>: sd s2,320(sp)
|
||||||
|
0xffffffff80088588 <__crash_kexec+8>: addi s0,sp,352
|
||||||
|
0xffffffff8008858a <__crash_kexec+10>: sd ra,344(sp)
|
||||||
|
0xffffffff8008858c <__crash_kexec+12>: sd s3,312(sp)
|
||||||
|
0xffffffff8008858e <__crash_kexec+14>: sd s4,304(sp)
|
||||||
|
0xffffffff80088590 <__crash_kexec+16>: auipc s2,0x1057
|
||||||
|
0xffffffff80088594 <__crash_kexec+20>: addi s2,s2,-1256
|
||||||
|
0xffffffff80088598 <__crash_kexec+24>: ld a5,0(s2)
|
||||||
|
0xffffffff8008859c <__crash_kexec+28>: mv s1,a0
|
||||||
|
0xffffffff8008859e <__crash_kexec+30>: auipc a0,0xfff
|
||||||
|
|
||||||
|
Signed-off-by: Xianting Tian <xianting.tian@linux.alibaba.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
riscv64.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/riscv64.c b/riscv64.c
|
||||||
|
index d8de3d56e1b7..1e20a09a81ae 100644
|
||||||
|
--- a/riscv64.c
|
||||||
|
+++ b/riscv64.c
|
||||||
|
@@ -988,6 +988,7 @@ riscv64_init(int when)
|
||||||
|
machdep->is_task_addr = riscv64_is_task_addr;
|
||||||
|
machdep->get_smp_cpus = riscv64_get_smp_cpus;
|
||||||
|
machdep->value_to_symbol = generic_machdep_value_to_symbol;
|
||||||
|
+ machdep->dis_filter = generic_dis_filter;
|
||||||
|
machdep->show_interrupts = generic_show_interrupts;
|
||||||
|
machdep->get_irq_affinity = generic_get_irq_affinity;
|
||||||
|
machdep->init_kernel_pgd = NULL; /* pgd set by symbol_value("swapper_pg_dir") */
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
36
SOURCES/0054-RISCV64-Add-irq-command-support.patch
Normal file
36
SOURCES/0054-RISCV64-Add-irq-command-support.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
From b4d78e7f96564ecbdbfe4b4b70a1c6d65429bbb9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xianting Tian <xianting.tian@linux.alibaba.com>
|
||||||
|
Date: Thu, 20 Oct 2022 09:50:09 +0800
|
||||||
|
Subject: [PATCH 54/89] RISCV64: Add irq command support
|
||||||
|
|
||||||
|
With the patch, we can get the irq info,
|
||||||
|
crash> irq
|
||||||
|
IRQ IRQ_DESC/_DATA IRQACTION NAME
|
||||||
|
0 (unused) (unused)
|
||||||
|
1 ff60000001329600 ff60000001d17180 "101000.rtc"
|
||||||
|
2 ff60000001329800 ff60000001d17680 "ttyS0"
|
||||||
|
3 ff60000001329a00 ff60000001c33c00 "virtio0"
|
||||||
|
4 ff60000001329c00 ff60000001c33f80 "virtio1"
|
||||||
|
5 ff6000000120f400 ff60000001216000 "riscv-timer"
|
||||||
|
|
||||||
|
Signed-off-by: Xianting Tian <xianting.tian@linux.alibaba.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
riscv64.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/riscv64.c b/riscv64.c
|
||||||
|
index 1e20a09a81ae..2355daca7aac 100644
|
||||||
|
--- a/riscv64.c
|
||||||
|
+++ b/riscv64.c
|
||||||
|
@@ -989,6 +989,7 @@ riscv64_init(int when)
|
||||||
|
machdep->get_smp_cpus = riscv64_get_smp_cpus;
|
||||||
|
machdep->value_to_symbol = generic_machdep_value_to_symbol;
|
||||||
|
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->init_kernel_pgd = NULL; /* pgd set by symbol_value("swapper_pg_dir") */
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
413
SOURCES/0055-RISCV64-Add-bt-command-support.patch
Normal file
413
SOURCES/0055-RISCV64-Add-bt-command-support.patch
Normal file
@ -0,0 +1,413 @@
|
|||||||
|
From 75afbf54dd183b05a8b7363390df4a198155580a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xianting Tian <xianting.tian@linux.alibaba.com>
|
||||||
|
Date: Thu, 20 Oct 2022 09:50:10 +0800
|
||||||
|
Subject: [PATCH 55/89] RISCV64: Add 'bt' command support
|
||||||
|
|
||||||
|
1, Add the implementation to get stack frame from active & inactive
|
||||||
|
task's stack.
|
||||||
|
2, Add 'bt -l' command support get a line number associated with a
|
||||||
|
current pc address.
|
||||||
|
3, Add 'bt -f' command support to display all stack data contained
|
||||||
|
in a frame
|
||||||
|
|
||||||
|
With the patch, we can get the backtrace,
|
||||||
|
crash> bt
|
||||||
|
PID: 113 TASK: ff6000000226c200 CPU: 0 COMMAND: "sh"
|
||||||
|
#0 [ff20000010333b90] riscv_crash_save_regs at ffffffff800078f8
|
||||||
|
#1 [ff20000010333cf0] panic at ffffffff806578c6
|
||||||
|
#2 [ff20000010333d50] sysrq_reset_seq_param_set at ffffffff8038c03c
|
||||||
|
#3 [ff20000010333da0] __handle_sysrq at ffffffff8038c604
|
||||||
|
#4 [ff20000010333e00] write_sysrq_trigger at ffffffff8038cae4
|
||||||
|
#5 [ff20000010333e20] proc_reg_write at ffffffff801b7ee8
|
||||||
|
#6 [ff20000010333e40] vfs_write at ffffffff80152bb2
|
||||||
|
#7 [ff20000010333e80] ksys_write at ffffffff80152eda
|
||||||
|
#8 [ff20000010333ed0] sys_write at ffffffff80152f52
|
||||||
|
|
||||||
|
crash> bt -l
|
||||||
|
PID: 113 TASK: ff6000000226c200 CPU: 0 COMMAND: "sh"
|
||||||
|
#0 [ff20000010333b90] riscv_crash_save_regs at ffffffff800078f8
|
||||||
|
/buildroot/qemu_riscv64_virt_defconfig/build/linux-custom/arch/riscv/kernel/crash_save_regs.S: 47
|
||||||
|
#1 [ff20000010333cf0] panic at ffffffff806578c6
|
||||||
|
/buildroot/qemu_riscv64_virt_defconfig/build/linux-custom/kernel/panic.c: 276
|
||||||
|
... ...
|
||||||
|
|
||||||
|
crash> bt -f
|
||||||
|
PID: 113 TASK: ff6000000226c200 CPU: 0 COMMAND: "sh"
|
||||||
|
#0 [ff20000010333b90] riscv_crash_save_regs at ffffffff800078f8
|
||||||
|
[PC: ffffffff800078f8 RA: ffffffff806578c6 SP: ff20000010333b90 SIZE: 352]
|
||||||
|
ff20000010333b90: ff20000010333bb0 ffffffff800078f8
|
||||||
|
ff20000010333ba0: ffffffff8008862c ff20000010333b90
|
||||||
|
ff20000010333bb0: ffffffff810dde38 ff6000000226c200
|
||||||
|
ff20000010333bc0: ffffffff8032be68 0720072007200720
|
||||||
|
... ...
|
||||||
|
|
||||||
|
Signed-off-by: Xianting Tian <xianting.tian@linux.alibaba.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
netdump.c | 13 +++
|
||||||
|
riscv64.c | 283 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 296 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/netdump.c b/netdump.c
|
||||||
|
index c4c8baae0d20..4ef5807a641b 100644
|
||||||
|
--- a/netdump.c
|
||||||
|
+++ b/netdump.c
|
||||||
|
@@ -42,6 +42,7 @@ static void get_netdump_regs_ppc64(struct bt_info *, ulong *, ulong *);
|
||||||
|
static void get_netdump_regs_arm(struct bt_info *, ulong *, ulong *);
|
||||||
|
static void get_netdump_regs_arm64(struct bt_info *, ulong *, ulong *);
|
||||||
|
static void get_netdump_regs_mips(struct bt_info *, ulong *, ulong *);
|
||||||
|
+static void get_netdump_regs_riscv(struct bt_info *, ulong *, ulong *);
|
||||||
|
static void check_dumpfile_size(char *);
|
||||||
|
static int proc_kcore_init_32(FILE *, int);
|
||||||
|
static int proc_kcore_init_64(FILE *, int);
|
||||||
|
@@ -2675,6 +2676,10 @@ get_netdump_regs(struct bt_info *bt, ulong *eip, ulong *esp)
|
||||||
|
return get_netdump_regs_mips(bt, eip, esp);
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ case EM_RISCV:
|
||||||
|
+ get_netdump_regs_riscv(bt, eip, esp);
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
default:
|
||||||
|
error(FATAL,
|
||||||
|
"support for ELF machine type %d not available\n",
|
||||||
|
@@ -2931,6 +2936,8 @@ display_regs_from_elf_notes(int cpu, FILE *ofp)
|
||||||
|
mips_display_regs_from_elf_notes(cpu, ofp);
|
||||||
|
} else if (machine_type("MIPS64")) {
|
||||||
|
mips64_display_regs_from_elf_notes(cpu, ofp);
|
||||||
|
+ } else if (machine_type("RISCV64")) {
|
||||||
|
+ riscv64_display_regs_from_elf_notes(cpu, ofp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -3877,6 +3884,12 @@ get_netdump_regs_mips(struct bt_info *bt, ulong *eip, ulong *esp)
|
||||||
|
machdep->get_stack_frame(bt, eip, esp);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+get_netdump_regs_riscv(struct bt_info *bt, ulong *eip, ulong *esp)
|
||||||
|
+{
|
||||||
|
+ machdep->get_stack_frame(bt, eip, esp);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int
|
||||||
|
is_partial_netdump(void)
|
||||||
|
{
|
||||||
|
diff --git a/riscv64.c b/riscv64.c
|
||||||
|
index 2355daca7aac..4c9b35bb93f2 100644
|
||||||
|
--- a/riscv64.c
|
||||||
|
+++ b/riscv64.c
|
||||||
|
@@ -33,6 +33,17 @@ static int riscv64_uvtop(struct task_context *tc, ulong vaddr,
|
||||||
|
static int riscv64_kvtop(struct task_context *tc, ulong kvaddr,
|
||||||
|
physaddr_t *paddr, int verbose);
|
||||||
|
static void riscv64_cmd_mach(void);
|
||||||
|
+static void riscv64_stackframe_init(void);
|
||||||
|
+static void riscv64_back_trace_cmd(struct bt_info *bt);
|
||||||
|
+static int riscv64_get_dumpfile_stack_frame(struct bt_info *bt,
|
||||||
|
+ ulong *nip, ulong *ksp);
|
||||||
|
+static void riscv64_get_stack_frame(struct bt_info *bt, ulong *pcp,
|
||||||
|
+ ulong *spp);
|
||||||
|
+static int riscv64_get_frame(struct bt_info *bt, ulong *pcp,
|
||||||
|
+ ulong *spp);
|
||||||
|
+static void riscv64_display_full_frame(struct bt_info *bt,
|
||||||
|
+ struct riscv64_unwind_frame *current,
|
||||||
|
+ struct riscv64_unwind_frame *previous);
|
||||||
|
static int riscv64_translate_pte(ulong, void *, ulonglong);
|
||||||
|
static int riscv64_init_active_task_regs(void);
|
||||||
|
static int riscv64_get_crash_notes(void);
|
||||||
|
@@ -498,6 +509,275 @@ no_page:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * 'bt -f' command output
|
||||||
|
+ * Display all stack data contained in a frame
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+riscv64_display_full_frame(struct bt_info *bt, struct riscv64_unwind_frame *current,
|
||||||
|
+ struct riscv64_unwind_frame *previous)
|
||||||
|
+{
|
||||||
|
+ int i, u_idx;
|
||||||
|
+ ulong *up;
|
||||||
|
+ ulong words, addr;
|
||||||
|
+ char buf[BUFSIZE];
|
||||||
|
+
|
||||||
|
+ if (previous->sp < current->sp)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (!(INSTACK(previous->sp, bt) && INSTACK(current->sp, bt)))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ words = (previous->sp - current->sp) / sizeof(ulong) + 1;
|
||||||
|
+ addr = current->sp;
|
||||||
|
+ u_idx = (current->sp - bt->stackbase) / sizeof(ulong);
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < words; i++, u_idx++) {
|
||||||
|
+ if (!(i & 1))
|
||||||
|
+ fprintf(fp, "%s %lx: ", i ? "\n" : "", addr);
|
||||||
|
+
|
||||||
|
+ up = (ulong *)(&bt->stackbuf[u_idx*sizeof(ulong)]);
|
||||||
|
+ fprintf(fp, "%s ", format_stack_entry(bt, buf, *up, 0));
|
||||||
|
+ addr += sizeof(ulong);
|
||||||
|
+ }
|
||||||
|
+ fprintf(fp, "\n");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+riscv64_stackframe_init(void)
|
||||||
|
+{
|
||||||
|
+ long task_struct_thread = MEMBER_OFFSET("task_struct", "thread");
|
||||||
|
+
|
||||||
|
+ /* from arch/riscv/include/asm/processor.h */
|
||||||
|
+ long thread_reg_ra = MEMBER_OFFSET("thread_struct", "ra");
|
||||||
|
+ long thread_reg_sp = MEMBER_OFFSET("thread_struct", "sp");
|
||||||
|
+ long thread_reg_fp = MEMBER_OFFSET("thread_struct", "s");
|
||||||
|
+
|
||||||
|
+ if ((task_struct_thread == INVALID_OFFSET) ||
|
||||||
|
+ (thread_reg_ra == INVALID_OFFSET) ||
|
||||||
|
+ (thread_reg_sp == INVALID_OFFSET) ||
|
||||||
|
+ (thread_reg_fp == INVALID_OFFSET) )
|
||||||
|
+ error(FATAL,
|
||||||
|
+ "cannot determine thread_struct offsets\n");
|
||||||
|
+
|
||||||
|
+ ASSIGN_OFFSET(task_struct_thread_context_pc) =
|
||||||
|
+ task_struct_thread + thread_reg_ra;
|
||||||
|
+ ASSIGN_OFFSET(task_struct_thread_context_sp) =
|
||||||
|
+ task_struct_thread + thread_reg_sp;
|
||||||
|
+ ASSIGN_OFFSET(task_struct_thread_context_fp) =
|
||||||
|
+ task_struct_thread + thread_reg_fp;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+riscv64_dump_backtrace_entry(struct bt_info *bt, struct syment *sym,
|
||||||
|
+ struct riscv64_unwind_frame *current,
|
||||||
|
+ struct riscv64_unwind_frame *previous, int level)
|
||||||
|
+{
|
||||||
|
+ const char *name = sym ? sym->name : "(invalid)";
|
||||||
|
+ struct load_module *lm;
|
||||||
|
+ char *name_plus_offset = NULL;
|
||||||
|
+ struct syment *symp;
|
||||||
|
+ ulong symbol_offset;
|
||||||
|
+ char buf[BUFSIZE];
|
||||||
|
+
|
||||||
|
+ if (bt->flags & BT_SYMBOL_OFFSET) {
|
||||||
|
+ symp = value_search(current->pc, &symbol_offset);
|
||||||
|
+
|
||||||
|
+ if (symp && symbol_offset)
|
||||||
|
+ name_plus_offset =
|
||||||
|
+ value_to_symstr(current->pc, buf, bt->radix);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fprintf(fp, "%s#%d [%016lx] %s at %016lx",
|
||||||
|
+ level < 10 ? " " : "",
|
||||||
|
+ level,
|
||||||
|
+ current->sp,
|
||||||
|
+ name_plus_offset ? name_plus_offset : name,
|
||||||
|
+ current->pc);
|
||||||
|
+
|
||||||
|
+ if (module_symbol(current->pc, NULL, &lm, NULL, 0))
|
||||||
|
+ fprintf(fp, " [%s]", lm->mod_name);
|
||||||
|
+
|
||||||
|
+ fprintf(fp, "\n");
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * 'bt -l', get a line number associated with a current pc address.
|
||||||
|
+ */
|
||||||
|
+ if (bt->flags & BT_LINE_NUMBERS) {
|
||||||
|
+ get_line_number(current->pc, buf, FALSE);
|
||||||
|
+ if (strlen(buf))
|
||||||
|
+ fprintf(fp, " %s\n", buf);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* bt -f */
|
||||||
|
+ if (bt->flags & BT_FULL) {
|
||||||
|
+ fprintf(fp, " "
|
||||||
|
+ "[PC: %016lx RA: %016lx SP: %016lx SIZE: %ld]\n",
|
||||||
|
+ current->pc,
|
||||||
|
+ previous->pc,
|
||||||
|
+ current->sp,
|
||||||
|
+ previous->sp - current->sp);
|
||||||
|
+ riscv64_display_full_frame(bt, current, previous);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Unroll a kernel stack.
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+riscv64_back_trace_cmd(struct bt_info *bt)
|
||||||
|
+{
|
||||||
|
+ struct riscv64_unwind_frame current, previous;
|
||||||
|
+ struct stackframe curr_frame;
|
||||||
|
+ int level = 0;
|
||||||
|
+
|
||||||
|
+ if (bt->flags & BT_REGS_NOT_FOUND)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ current.pc = bt->instptr;
|
||||||
|
+ current.sp = bt->stkptr;
|
||||||
|
+ current.fp = bt->frameptr;
|
||||||
|
+
|
||||||
|
+ if (!INSTACK(current.sp, bt))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ for (;;) {
|
||||||
|
+ struct syment *symbol = NULL;
|
||||||
|
+ struct stackframe *frameptr;
|
||||||
|
+ ulong low, high;
|
||||||
|
+ ulong offset;
|
||||||
|
+
|
||||||
|
+ if (CRASHDEBUG(8))
|
||||||
|
+ fprintf(fp, "level %d pc %#lx sp %lx fp 0x%lx\n",
|
||||||
|
+ level, current.pc, current.sp, current.fp);
|
||||||
|
+
|
||||||
|
+ /* Validate frame pointer */
|
||||||
|
+ low = current.sp + sizeof(struct stackframe);
|
||||||
|
+ high = bt->stacktop;
|
||||||
|
+ if (current.fp < low || current.fp > high || current.fp & 0x7) {
|
||||||
|
+ if (CRASHDEBUG(8))
|
||||||
|
+ fprintf(fp, "fp 0x%lx sp 0x%lx low 0x%lx high 0x%lx\n",
|
||||||
|
+ current.fp, current.sp, low, high);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ symbol = value_search(current.pc, &offset);
|
||||||
|
+ if (!symbol)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ frameptr = (struct stackframe *)current.fp - 1;
|
||||||
|
+ if (!readmem((ulong)frameptr, KVADDR, &curr_frame,
|
||||||
|
+ sizeof(curr_frame), "get stack frame", RETURN_ON_ERROR))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ previous.pc = curr_frame.ra;
|
||||||
|
+ previous.fp = curr_frame.fp;
|
||||||
|
+ previous.sp = current.fp;
|
||||||
|
+
|
||||||
|
+ riscv64_dump_backtrace_entry(bt, symbol, ¤t, &previous, level++);
|
||||||
|
+
|
||||||
|
+ current.pc = previous.pc;
|
||||||
|
+ current.fp = previous.fp;
|
||||||
|
+ current.sp = previous.sp;
|
||||||
|
+
|
||||||
|
+ if (CRASHDEBUG(8))
|
||||||
|
+ fprintf(fp, "next %d pc %#lx sp %#lx fp %lx\n",
|
||||||
|
+ level, current.pc, current.sp, current.fp);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Get a stack frame combination of pc and ra from the most relevant spot.
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+riscv64_get_stack_frame(struct bt_info *bt, ulong *pcp, ulong *spp)
|
||||||
|
+{
|
||||||
|
+ ulong ksp = 0, nip = 0;
|
||||||
|
+ int ret = 0;
|
||||||
|
+
|
||||||
|
+ if (DUMPFILE() && is_task_active(bt->task))
|
||||||
|
+ ret = riscv64_get_dumpfile_stack_frame(bt, &nip, &ksp);
|
||||||
|
+ else
|
||||||
|
+ ret = riscv64_get_frame(bt, &nip, &ksp);
|
||||||
|
+
|
||||||
|
+ if (!ret)
|
||||||
|
+ error(WARNING, "cannot determine starting stack frame for task %lx\n",
|
||||||
|
+ bt->task);
|
||||||
|
+
|
||||||
|
+ if (pcp)
|
||||||
|
+ *pcp = nip;
|
||||||
|
+ if (spp)
|
||||||
|
+ *spp = ksp;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Get the starting point for the active cpu in a diskdump.
|
||||||
|
+ */
|
||||||
|
+static int
|
||||||
|
+riscv64_get_dumpfile_stack_frame(struct bt_info *bt, ulong *nip, ulong *ksp)
|
||||||
|
+{
|
||||||
|
+ const struct machine_specific *ms = machdep->machspec;
|
||||||
|
+ struct riscv64_register *regs;
|
||||||
|
+ ulong epc, sp;
|
||||||
|
+
|
||||||
|
+ if (!ms->crash_task_regs) {
|
||||||
|
+ bt->flags |= BT_REGS_NOT_FOUND;
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * We got registers for panic task from crash_notes. Just return them.
|
||||||
|
+ */
|
||||||
|
+ regs = &ms->crash_task_regs[bt->tc->processor];
|
||||||
|
+ epc = regs->regs[RISCV64_REGS_EPC];
|
||||||
|
+ sp = regs->regs[RISCV64_REGS_SP];
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Set stack frame ptr.
|
||||||
|
+ */
|
||||||
|
+ bt->frameptr = regs->regs[RISCV64_REGS_FP];
|
||||||
|
+
|
||||||
|
+ if (nip)
|
||||||
|
+ *nip = epc;
|
||||||
|
+ if (ksp)
|
||||||
|
+ *ksp = sp;
|
||||||
|
+
|
||||||
|
+ bt->machdep = regs;
|
||||||
|
+
|
||||||
|
+ return TRUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Do the work for riscv64_get_stack_frame() for non-active tasks.
|
||||||
|
+ * Get SP and PC values for idle tasks.
|
||||||
|
+ */
|
||||||
|
+static int
|
||||||
|
+riscv64_get_frame(struct bt_info *bt, ulong *pcp, ulong *spp)
|
||||||
|
+{
|
||||||
|
+ if (!bt->tc || !(tt->flags & THREAD_INFO))
|
||||||
|
+ return FALSE;
|
||||||
|
+
|
||||||
|
+ if (!readmem(bt->task + OFFSET(task_struct_thread_context_pc),
|
||||||
|
+ KVADDR, pcp, sizeof(*pcp),
|
||||||
|
+ "thread_struct.ra",
|
||||||
|
+ RETURN_ON_ERROR))
|
||||||
|
+ return FALSE;
|
||||||
|
+
|
||||||
|
+ if (!readmem(bt->task + OFFSET(task_struct_thread_context_sp),
|
||||||
|
+ KVADDR, spp, sizeof(*spp),
|
||||||
|
+ "thread_struct.sp",
|
||||||
|
+ RETURN_ON_ERROR))
|
||||||
|
+ return FALSE;
|
||||||
|
+
|
||||||
|
+ if (!readmem(bt->task + OFFSET(task_struct_thread_context_fp),
|
||||||
|
+ KVADDR, &bt->frameptr, sizeof(bt->frameptr),
|
||||||
|
+ "thread_struct.fp",
|
||||||
|
+ RETURN_ON_ERROR))
|
||||||
|
+ return FALSE;
|
||||||
|
+
|
||||||
|
+ return TRUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
riscv64_vtop_4level_4k(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
|
||||||
|
{
|
||||||
|
@@ -978,6 +1258,8 @@ riscv64_init(int when)
|
||||||
|
machdep->uvtop = riscv64_uvtop;
|
||||||
|
machdep->kvtop = riscv64_kvtop;
|
||||||
|
machdep->cmd_mach = riscv64_cmd_mach;
|
||||||
|
+ machdep->get_stack_frame = riscv64_get_stack_frame;
|
||||||
|
+ machdep->back_trace = riscv64_back_trace_cmd;
|
||||||
|
|
||||||
|
machdep->vmalloc_start = riscv64_vmalloc_start;
|
||||||
|
machdep->processor_speed = riscv64_processor_speed;
|
||||||
|
@@ -998,6 +1280,7 @@ riscv64_init(int when)
|
||||||
|
case POST_GDB:
|
||||||
|
machdep->section_size_bits = _SECTION_SIZE_BITS;
|
||||||
|
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
|
||||||
|
+ riscv64_stackframe_init();
|
||||||
|
riscv64_page_type_init();
|
||||||
|
|
||||||
|
if (!machdep->hz)
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
80
SOURCES/0056-RISCV64-Add-help-r-command-support.patch
Normal file
80
SOURCES/0056-RISCV64-Add-help-r-command-support.patch
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
From 15ac3968a929adebc27985be77fe90d3847abd57 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xianting Tian <xianting.tian@linux.alibaba.com>
|
||||||
|
Date: Thu, 20 Oct 2022 09:50:11 +0800
|
||||||
|
Subject: [PATCH 56/89] RISCV64: Add 'help -r' command support
|
||||||
|
|
||||||
|
Add support form printing out the registers from the dump file.
|
||||||
|
|
||||||
|
With the patch, we can get the regs,
|
||||||
|
crash> help -r
|
||||||
|
CPU 0:
|
||||||
|
epc : 00ffffffa5537400 ra : ffffffff80088620 sp : ff2000001039bb90
|
||||||
|
gp : ffffffff810dde38 tp : ff60000002269600 t0 : ffffffff8032be5c
|
||||||
|
t1 : 0720072007200720 t2 : 666666666666663c s0 : ff2000001039bcf0
|
||||||
|
s1 : 0000000000000000 a0 : ff2000001039bb98 a1 : 0000000000000001
|
||||||
|
a2 : 0000000000000010 a3 : 0000000000000000 a4 : 0000000000000000
|
||||||
|
a5 : ff60000001c7d000 a6 : 000000000000003c a7 : ffffffff8035c998
|
||||||
|
s2 : ffffffff810df0a8 s3 : ffffffff810df718 s4 : ff2000001039bb98
|
||||||
|
s5 : 0000000000000000 s6 : 0000000000000007 s7 : ffffffff80c4a468
|
||||||
|
s8 : 00fffffffde45410 s9 : 0000000000000007 s10: 00aaaaaad1640700
|
||||||
|
s11: 0000000000000001 t3 : ff60000001218f00 t4 : ff60000001218f00
|
||||||
|
t5 : ff60000001218000 t6 : ff2000001039b988
|
||||||
|
|
||||||
|
Signed-off-by: Xianting Tian <xianting.tian@linux.alibaba.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
riscv64.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 38 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/riscv64.c b/riscv64.c
|
||||||
|
index 4c9b35bb93f2..6d1d3b5f36d1 100644
|
||||||
|
--- a/riscv64.c
|
||||||
|
+++ b/riscv64.c
|
||||||
|
@@ -1320,6 +1320,44 @@ riscv64_init(int when)
|
||||||
|
void
|
||||||
|
riscv64_display_regs_from_elf_notes(int cpu, FILE *ofp)
|
||||||
|
{
|
||||||
|
+ const struct machine_specific *ms = machdep->machspec;
|
||||||
|
+ struct riscv64_register *regs;
|
||||||
|
+
|
||||||
|
+ if (!ms->crash_task_regs) {
|
||||||
|
+ error(INFO, "registers not collected for cpu %d\n", cpu);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ regs = &ms->crash_task_regs[cpu];
|
||||||
|
+ if (!regs->regs[RISCV64_REGS_SP] && !regs->regs[RISCV64_REGS_EPC]) {
|
||||||
|
+ error(INFO, "registers not collected for cpu %d\n", cpu);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Print riscv64 32 regs */
|
||||||
|
+ fprintf(ofp,
|
||||||
|
+ "epc : " REG_FMT " ra : " REG_FMT " sp : " REG_FMT "\n"
|
||||||
|
+ " gp : " REG_FMT " tp : " REG_FMT " t0 : " REG_FMT "\n"
|
||||||
|
+ " t1 : " REG_FMT " t2 : " REG_FMT " s0 : " REG_FMT "\n"
|
||||||
|
+ " s1 : " REG_FMT " a0 : " REG_FMT " a1 : " REG_FMT "\n"
|
||||||
|
+ " a2 : " REG_FMT " a3 : " REG_FMT " a4 : " REG_FMT "\n"
|
||||||
|
+ " a5 : " REG_FMT " a6 : " REG_FMT " a7 : " REG_FMT "\n"
|
||||||
|
+ " s2 : " REG_FMT " s3 : " REG_FMT " s4 : " REG_FMT "\n"
|
||||||
|
+ " s5 : " REG_FMT " s6 : " REG_FMT " s7 : " REG_FMT "\n"
|
||||||
|
+ " s8 : " REG_FMT " s9 : " REG_FMT " s10: " REG_FMT "\n"
|
||||||
|
+ " s11: " REG_FMT " t3 : " REG_FMT " t4 : " REG_FMT "\n"
|
||||||
|
+ " t5 : " REG_FMT " t6 : " REG_FMT "\n",
|
||||||
|
+ regs->regs[0], regs->regs[1], regs->regs[2],
|
||||||
|
+ regs->regs[3], regs->regs[4], regs->regs[5],
|
||||||
|
+ regs->regs[6], regs->regs[7], regs->regs[8],
|
||||||
|
+ regs->regs[9], regs->regs[10], regs->regs[11],
|
||||||
|
+ regs->regs[12], regs->regs[13], regs->regs[14],
|
||||||
|
+ regs->regs[15], regs->regs[16], regs->regs[17],
|
||||||
|
+ regs->regs[18], regs->regs[19], regs->regs[20],
|
||||||
|
+ regs->regs[21], regs->regs[22], regs->regs[23],
|
||||||
|
+ regs->regs[24], regs->regs[25], regs->regs[26],
|
||||||
|
+ regs->regs[27], regs->regs[28], regs->regs[29],
|
||||||
|
+ regs->regs[30], regs->regs[31]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* !RISCV64 */
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
141
SOURCES/0057-RISCV64-Add-help-m-M-command-support.patch
Normal file
141
SOURCES/0057-RISCV64-Add-help-m-M-command-support.patch
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
From 012c8ebc3d6d71c995522dcf8d8aad530cdb4d02 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xianting Tian <xianting.tian@linux.alibaba.com>
|
||||||
|
Date: Thu, 20 Oct 2022 09:50:12 +0800
|
||||||
|
Subject: [PATCH 57/89] RISCV64: Add 'help -m/M' command support
|
||||||
|
|
||||||
|
Add riscv64_dump_machdep_table() implementation, display machdep_table.
|
||||||
|
|
||||||
|
crash> help -m
|
||||||
|
flags: 80 ()
|
||||||
|
kvbase: ff60000000000000
|
||||||
|
identity_map_base: ff60000000000000
|
||||||
|
pagesize: 4096
|
||||||
|
pageshift: 12
|
||||||
|
pagemask: fffffffffffff000
|
||||||
|
pageoffset: fff
|
||||||
|
pgdir_shift: 48
|
||||||
|
ptrs_per_pgd: 512
|
||||||
|
ptrs_per_pte: 512
|
||||||
|
stacksize: 16384
|
||||||
|
hz: 250
|
||||||
|
memsize: 1071644672 (0x3fe00000)
|
||||||
|
bits: 64
|
||||||
|
back_trace: riscv64_back_trace_cmd()
|
||||||
|
processor_speed: riscv64_processor_speed()
|
||||||
|
uvtop: riscv64_uvtop()
|
||||||
|
kvtop: riscv64_kvtop()
|
||||||
|
get_stack_frame: riscv64_get_stack_frame()
|
||||||
|
get_stackbase: generic_get_stackbase()
|
||||||
|
get_stacktop: generic_get_stacktop()
|
||||||
|
translate_pte: riscv64_translate_pte()
|
||||||
|
memory_size: generic_memory_size()
|
||||||
|
vmalloc_start: riscv64_vmalloc_start()
|
||||||
|
is_task_addr: riscv64_is_task_addr()
|
||||||
|
verify_symbol: riscv64_verify_symbol()
|
||||||
|
dis_filter: generic_dis_filter()
|
||||||
|
dump_irq: generic_dump_irq()
|
||||||
|
show_interrupts: generic_show_interrupts()
|
||||||
|
get_irq_affinity: generic_get_irq_affinity()
|
||||||
|
cmd_mach: riscv64_cmd_mach()
|
||||||
|
get_smp_cpus: riscv64_get_smp_cpus()
|
||||||
|
is_kvaddr: riscv64_is_kvaddr()
|
||||||
|
is_uvaddr: riscv64_is_uvaddr()
|
||||||
|
verify_paddr: generic_verify_paddr()
|
||||||
|
init_kernel_pgd: NULL
|
||||||
|
value_to_symbol: generic_machdep_value_to_symbol()
|
||||||
|
line_number_hooks: NULL
|
||||||
|
last_pgd_read: ffffffff810e9000
|
||||||
|
last_p4d_read: 81410000
|
||||||
|
last_pud_read: 81411000
|
||||||
|
last_pmd_read: 81412000
|
||||||
|
last_ptbl_read: 81415000
|
||||||
|
pgd: 560d586f3ab0
|
||||||
|
p4d: 560d586f4ac0
|
||||||
|
pud: 560d586f5ad0
|
||||||
|
pmd: 560d586f6ae0
|
||||||
|
ptbl: 560d586f7af0
|
||||||
|
section_size_bits: 27
|
||||||
|
max_physmem_bits: 56
|
||||||
|
sections_per_root: 0
|
||||||
|
machspec: 560d57d204a0
|
||||||
|
|
||||||
|
Signed-off-by: Xianting Tian <xianting.tian@linux.alibaba.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
riscv64.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
1 file changed, 59 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/riscv64.c b/riscv64.c
|
||||||
|
index 6d1d3b5f36d1..5e8c7d12227c 100644
|
||||||
|
--- a/riscv64.c
|
||||||
|
+++ b/riscv64.c
|
||||||
|
@@ -132,7 +132,65 @@ riscv64_verify_symbol(const char *name, ulong value, char type)
|
||||||
|
void
|
||||||
|
riscv64_dump_machdep_table(ulong arg)
|
||||||
|
{
|
||||||
|
- /* TODO: */
|
||||||
|
+ int others = 0;
|
||||||
|
+
|
||||||
|
+ fprintf(fp, " flags: %lx (", machdep->flags);
|
||||||
|
+ if (machdep->flags & KSYMS_START)
|
||||||
|
+ fprintf(fp, "%sKSYMS_START", others++ ? "|" : "");
|
||||||
|
+ fprintf(fp, ")\n");
|
||||||
|
+
|
||||||
|
+ fprintf(fp, " kvbase: %lx\n", machdep->kvbase);
|
||||||
|
+ fprintf(fp, " identity_map_base: %lx\n", machdep->identity_map_base);
|
||||||
|
+ fprintf(fp, " pagesize: %d\n", machdep->pagesize);
|
||||||
|
+ fprintf(fp, " pageshift: %d\n", machdep->pageshift);
|
||||||
|
+ fprintf(fp, " pagemask: %llx\n", machdep->pagemask);
|
||||||
|
+ fprintf(fp, " pageoffset: %lx\n", machdep->pageoffset);
|
||||||
|
+ fprintf(fp, " pgdir_shift: %ld\n", machdep->machspec->va_bits - 9);
|
||||||
|
+ fprintf(fp, " ptrs_per_pgd: %u\n", PTRS_PER_PGD);
|
||||||
|
+ fprintf(fp, " ptrs_per_pte: %d\n", PTRS_PER_PTE);
|
||||||
|
+ fprintf(fp, " stacksize: %ld\n", machdep->stacksize);
|
||||||
|
+ fprintf(fp, " hz: %d\n", machdep->hz);
|
||||||
|
+ fprintf(fp, " memsize: %ld (0x%lx)\n",
|
||||||
|
+ machdep->memsize, machdep->memsize);
|
||||||
|
+ fprintf(fp, " bits: %d\n", machdep->bits);
|
||||||
|
+ fprintf(fp, " back_trace: riscv64_back_trace_cmd()\n");
|
||||||
|
+ fprintf(fp, " processor_speed: riscv64_processor_speed()\n");
|
||||||
|
+ fprintf(fp, " uvtop: riscv64_uvtop()\n");
|
||||||
|
+ fprintf(fp, " kvtop: riscv64_kvtop()\n");
|
||||||
|
+ fprintf(fp, " get_stack_frame: riscv64_get_stack_frame()\n");
|
||||||
|
+ fprintf(fp, " get_stackbase: generic_get_stackbase()\n");
|
||||||
|
+ fprintf(fp, " get_stacktop: generic_get_stacktop()\n");
|
||||||
|
+ fprintf(fp, " translate_pte: riscv64_translate_pte()\n");
|
||||||
|
+ fprintf(fp, " memory_size: generic_memory_size()\n");
|
||||||
|
+ fprintf(fp, " vmalloc_start: riscv64_vmalloc_start()\n");
|
||||||
|
+ fprintf(fp, " is_task_addr: riscv64_is_task_addr()\n");
|
||||||
|
+ fprintf(fp, " verify_symbol: riscv64_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: riscv64_cmd_mach()\n");
|
||||||
|
+ fprintf(fp, " get_smp_cpus: riscv64_get_smp_cpus()\n");
|
||||||
|
+ fprintf(fp, " is_kvaddr: riscv64_is_kvaddr()\n");
|
||||||
|
+ fprintf(fp, " is_uvaddr: riscv64_is_uvaddr()\n");
|
||||||
|
+ fprintf(fp, " verify_paddr: generic_verify_paddr()\n");
|
||||||
|
+ fprintf(fp, " init_kernel_pgd: NULL\n");
|
||||||
|
+ fprintf(fp, " value_to_symbol: generic_machdep_value_to_symbol()\n");
|
||||||
|
+ fprintf(fp, " line_number_hooks: NULL\n");
|
||||||
|
+ fprintf(fp, " last_pgd_read: %lx\n", machdep->last_pgd_read);
|
||||||
|
+ fprintf(fp, " last_p4d_read: %lx\n", machdep->machspec->last_p4d_read);
|
||||||
|
+ fprintf(fp, " last_pud_read: %lx\n", machdep->last_pud_read);
|
||||||
|
+ fprintf(fp, " last_pmd_read: %lx\n", machdep->last_pmd_read);
|
||||||
|
+ fprintf(fp, " last_ptbl_read: %lx\n", machdep->last_ptbl_read);
|
||||||
|
+ fprintf(fp, " pgd: %lx\n", (ulong)machdep->pgd);
|
||||||
|
+ fprintf(fp, " p4d: %lx\n", (ulong)machdep->machspec->p4d);
|
||||||
|
+ fprintf(fp, " pud: %lx\n", (ulong)machdep->pud);
|
||||||
|
+ fprintf(fp, " pmd: %lx\n", (ulong)machdep->pmd);
|
||||||
|
+ fprintf(fp, " ptbl: %lx\n", (ulong)machdep->ptbl);
|
||||||
|
+ fprintf(fp, " section_size_bits: %ld\n", machdep->section_size_bits);
|
||||||
|
+ fprintf(fp, " max_physmem_bits: %ld\n", machdep->max_physmem_bits);
|
||||||
|
+ fprintf(fp, " sections_per_root: %ld\n", machdep->sections_per_root);
|
||||||
|
+ fprintf(fp, " machspec: %lx\n", (ulong)machdep->machspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ulong
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
83
SOURCES/0058-RISCV64-Add-mach-command-support.patch
Normal file
83
SOURCES/0058-RISCV64-Add-mach-command-support.patch
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
From 7a942ad69e1a4270dba89de9bff4f93cd6d87578 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xianting Tian <xianting.tian@linux.alibaba.com>
|
||||||
|
Date: Thu, 20 Oct 2022 09:50:13 +0800
|
||||||
|
Subject: [PATCH 58/89] RISCV64: Add 'mach' command support
|
||||||
|
|
||||||
|
With the patch we can get some basic machine state information,
|
||||||
|
crash> mach
|
||||||
|
MACHINE TYPE: riscv64
|
||||||
|
MEMORY SIZE: 1 GB
|
||||||
|
CPUS: 1
|
||||||
|
PROCESSOR SPEED: (unknown)
|
||||||
|
HZ: 250
|
||||||
|
PAGE SIZE: 4096
|
||||||
|
KERNEL STACK SIZE: 16384
|
||||||
|
|
||||||
|
Signed-off-by: Xianting Tian <xianting.tian@linux.alibaba.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
riscv64.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
1 file changed, 44 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/riscv64.c b/riscv64.c
|
||||||
|
index 5e8c7d12227c..ff77e41b9407 100644
|
||||||
|
--- a/riscv64.c
|
||||||
|
+++ b/riscv64.c
|
||||||
|
@@ -116,10 +116,53 @@ static void riscv64_get_struct_page_size(struct machine_specific *ms)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * "mach" command output.
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+riscv64_display_machine_stats(void)
|
||||||
|
+{
|
||||||
|
+ struct new_utsname *uts;
|
||||||
|
+ char buf[BUFSIZE];
|
||||||
|
+ ulong mhz;
|
||||||
|
+
|
||||||
|
+ uts = &kt->utsname;
|
||||||
|
+
|
||||||
|
+ fprintf(fp, " MACHINE TYPE: %s\n", uts->machine);
|
||||||
|
+ fprintf(fp, " MEMORY SIZE: %s\n", get_memory_size(buf));
|
||||||
|
+ fprintf(fp, " CPUS: %d\n", get_cpus_to_display());
|
||||||
|
+ fprintf(fp, " PROCESSOR SPEED: ");
|
||||||
|
+ if ((mhz = machdep->processor_speed()))
|
||||||
|
+ fprintf(fp, "%ld Mhz\n", mhz);
|
||||||
|
+ else
|
||||||
|
+ fprintf(fp, "(unknown)\n");
|
||||||
|
+ fprintf(fp, " HZ: %d\n", machdep->hz);
|
||||||
|
+ fprintf(fp, " PAGE SIZE: %d\n", PAGESIZE());
|
||||||
|
+ fprintf(fp, " KERNEL STACK SIZE: %ld\n", STACKSIZE());
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
riscv64_cmd_mach(void)
|
||||||
|
{
|
||||||
|
- /* TODO: */
|
||||||
|
+ int c;
|
||||||
|
+
|
||||||
|
+ while ((c = getopt(argcnt, args, "cmo")) != EOF) {
|
||||||
|
+ switch (c) {
|
||||||
|
+ case 'c':
|
||||||
|
+ case 'm':
|
||||||
|
+ case 'o':
|
||||||
|
+ option_not_supported(c);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ argerrs++;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (argerrs)
|
||||||
|
+ cmd_usage(pc->curcmd, SYNOPSIS);
|
||||||
|
+
|
||||||
|
+ riscv64_display_machine_stats();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
From ba2d96e12463157fe2ed9c134ad9cf42481427e8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xianting Tian <xianting.tian@linux.alibaba.com>
|
||||||
|
Date: Thu, 20 Oct 2022 09:50:14 +0800
|
||||||
|
Subject: [PATCH 59/89] RISCV64: Add the implementation of symbol verify
|
||||||
|
|
||||||
|
Verify the symbol to accept or reject a symbol from the kernel namelist.
|
||||||
|
|
||||||
|
Signed-off-by: Xianting Tian <xianting.tian@linux.alibaba.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
riscv64.c | 15 ++++++++++++++-
|
||||||
|
1 file changed, 14 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/riscv64.c b/riscv64.c
|
||||||
|
index ff77e41b9407..6b9a68840d4c 100644
|
||||||
|
--- a/riscv64.c
|
||||||
|
+++ b/riscv64.c
|
||||||
|
@@ -165,10 +165,23 @@ riscv64_cmd_mach(void)
|
||||||
|
riscv64_display_machine_stats();
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Accept or reject a symbol from the kernel namelist.
|
||||||
|
+ */
|
||||||
|
static int
|
||||||
|
riscv64_verify_symbol(const char *name, ulong value, char type)
|
||||||
|
{
|
||||||
|
- /* TODO: */
|
||||||
|
+ if (CRASHDEBUG(8) && name && strlen(name))
|
||||||
|
+ fprintf(fp, "%08lx %s\n", value, name);
|
||||||
|
+
|
||||||
|
+ if (!(machdep->flags & KSYMS_START)) {
|
||||||
|
+ if (STREQ(name, "_text") || STREQ(name, "_stext"))
|
||||||
|
+ machdep->flags |= KSYMS_START;
|
||||||
|
+
|
||||||
|
+ return (name && strlen(name) && !STRNEQ(name, "__func__.") &&
|
||||||
|
+ !STRNEQ(name, "__crc_"));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,149 @@
|
|||||||
|
From 47d375ac822d413999c92520402c4868ce2275cc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Date: Fri, 16 Dec 2022 14:03:46 +0900
|
||||||
|
Subject: [PATCH 60/89] SLUB: Fix for offset change of struct slab members on
|
||||||
|
Linux 6.2-rc1
|
||||||
|
|
||||||
|
The following kernel commits split slab info from struct page into
|
||||||
|
struct slab in Linux 5.17.
|
||||||
|
|
||||||
|
d122019bf061 ("mm: Split slab into its own type")
|
||||||
|
07f910f9b729 ("mm: Remove slab from struct page")
|
||||||
|
|
||||||
|
Crash commit 5f390ed811b0 followed the change for SLUB, but crash still
|
||||||
|
uses the offset of page.lru inappropriately. Luckily, it could work
|
||||||
|
because it was the same value as the offset of slab.slab_list until
|
||||||
|
Linux 6.1.
|
||||||
|
|
||||||
|
However, kernel commit 130d4df57390 ("mm/sl[au]b: rearrange struct slab
|
||||||
|
fields to allow larger rcu_head") in Linux 6.2-rc1 changed the offset of
|
||||||
|
slab.slab_list. As a result, without the patch, "kmem -s|-S" options
|
||||||
|
print the following errors and fail to print values correctly for
|
||||||
|
kernels configured with CONFIG_SLUB.
|
||||||
|
|
||||||
|
crash> kmem -S filp
|
||||||
|
CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
|
||||||
|
kmem: filp: partial list slab: ffffcc650405ab88 invalid page.inuse: -1
|
||||||
|
ffff8fa0401eca00 232 1267 1792 56 8k filp
|
||||||
|
...
|
||||||
|
KMEM_CACHE_NODE NODE SLABS PARTIAL PER-CPU
|
||||||
|
ffff8fa0401cb8c0 0 56 24 8
|
||||||
|
NODE 0 PARTIAL:
|
||||||
|
SLAB MEMORY NODE TOTAL ALLOCATED FREE
|
||||||
|
kmem: filp: invalid partial list slab pointer: ffffcc650405ab88
|
||||||
|
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
defs.h | 1 +
|
||||||
|
memory.c | 16 ++++++++++------
|
||||||
|
symbols.c | 1 +
|
||||||
|
3 files changed, 12 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index 9c91f38328d0..31702e707bee 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -2188,6 +2188,7 @@ struct offset_table { /* stash of commonly-used offsets */
|
||||||
|
long blk_mq_tags_rqs;
|
||||||
|
long request_queue_hctx_table;
|
||||||
|
long percpu_counter_counters;
|
||||||
|
+ long slab_slab_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct size_table { /* stash of commonly-used sizes */
|
||||||
|
diff --git a/memory.c b/memory.c
|
||||||
|
index 9d003713534b..d05737cc1429 100644
|
||||||
|
--- a/memory.c
|
||||||
|
+++ b/memory.c
|
||||||
|
@@ -781,6 +781,8 @@ vm_init(void)
|
||||||
|
if (INVALID_MEMBER(page_slab))
|
||||||
|
MEMBER_OFFSET_INIT(page_slab, "slab", "slab_cache");
|
||||||
|
|
||||||
|
+ MEMBER_OFFSET_INIT(slab_slab_list, "slab", "slab_list");
|
||||||
|
+
|
||||||
|
MEMBER_OFFSET_INIT(page_slab_page, "page", "slab_page");
|
||||||
|
if (INVALID_MEMBER(page_slab_page))
|
||||||
|
ANON_MEMBER_OFFSET_INIT(page_slab_page, "page", "slab_page");
|
||||||
|
@@ -19474,6 +19476,7 @@ do_node_lists_slub(struct meminfo *si, ulong node_ptr, int node)
|
||||||
|
{
|
||||||
|
ulong next, last, list_head, flags;
|
||||||
|
int first;
|
||||||
|
+ long list_off = VALID_MEMBER(slab_slab_list) ? OFFSET(slab_slab_list) : OFFSET(page_lru);
|
||||||
|
|
||||||
|
if (!node_ptr)
|
||||||
|
return;
|
||||||
|
@@ -19487,7 +19490,7 @@ do_node_lists_slub(struct meminfo *si, ulong node_ptr, int node)
|
||||||
|
next == list_head ? " (empty)\n" : "");
|
||||||
|
first = 0;
|
||||||
|
while (next != list_head) {
|
||||||
|
- si->slab = last = next - OFFSET(page_lru);
|
||||||
|
+ si->slab = last = next - list_off;
|
||||||
|
if (first++ == 0)
|
||||||
|
fprintf(fp, " %s", slab_hdr);
|
||||||
|
|
||||||
|
@@ -19510,7 +19513,7 @@ do_node_lists_slub(struct meminfo *si, ulong node_ptr, int node)
|
||||||
|
|
||||||
|
if (!IS_KVADDR(next) ||
|
||||||
|
((next != list_head) &&
|
||||||
|
- !is_page_ptr(next - OFFSET(page_lru), NULL))) {
|
||||||
|
+ !is_page_ptr(next - list_off, NULL))) {
|
||||||
|
error(INFO,
|
||||||
|
"%s: partial list slab: %lx invalid page.lru.next: %lx\n",
|
||||||
|
si->curname, last, next);
|
||||||
|
@@ -19537,7 +19540,7 @@ do_node_lists_slub(struct meminfo *si, ulong node_ptr, int node)
|
||||||
|
next == list_head ? " (empty)\n" : "");
|
||||||
|
first = 0;
|
||||||
|
while (next != list_head) {
|
||||||
|
- si->slab = next - OFFSET(page_lru);
|
||||||
|
+ si->slab = next - list_off;
|
||||||
|
if (first++ == 0)
|
||||||
|
fprintf(fp, " %s", slab_hdr);
|
||||||
|
|
||||||
|
@@ -19754,6 +19757,7 @@ count_partial(ulong node, struct meminfo *si, ulong *free)
|
||||||
|
short inuse, objects;
|
||||||
|
ulong total_inuse;
|
||||||
|
ulong count = 0;
|
||||||
|
+ long list_off = VALID_MEMBER(slab_slab_list) ? OFFSET(slab_slab_list) : OFFSET(page_lru);
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
total_inuse = 0;
|
||||||
|
@@ -19765,12 +19769,12 @@ count_partial(ulong node, struct meminfo *si, ulong *free)
|
||||||
|
hq_open();
|
||||||
|
|
||||||
|
while (next != list_head) {
|
||||||
|
- if (!readmem(next - OFFSET(page_lru) + OFFSET(page_inuse),
|
||||||
|
+ if (!readmem(next - list_off + OFFSET(page_inuse),
|
||||||
|
KVADDR, &inuse, sizeof(ushort), "page.inuse", RETURN_ON_ERROR)) {
|
||||||
|
hq_close();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
- last = next - OFFSET(page_lru);
|
||||||
|
+ last = next - list_off;
|
||||||
|
|
||||||
|
if (inuse == -1) {
|
||||||
|
error(INFO,
|
||||||
|
@@ -19796,7 +19800,7 @@ count_partial(ulong node, struct meminfo *si, ulong *free)
|
||||||
|
}
|
||||||
|
if (!IS_KVADDR(next) ||
|
||||||
|
((next != list_head) &&
|
||||||
|
- !is_page_ptr(next - OFFSET(page_lru), NULL))) {
|
||||||
|
+ !is_page_ptr(next - list_off, NULL))) {
|
||||||
|
error(INFO, "%s: partial list slab: %lx invalid page.lru.next: %lx\n",
|
||||||
|
si->curname, last, next);
|
||||||
|
break;
|
||||||
|
diff --git a/symbols.c b/symbols.c
|
||||||
|
index d1b35a56aa71..9e6fca73eaf9 100644
|
||||||
|
--- a/symbols.c
|
||||||
|
+++ b/symbols.c
|
||||||
|
@@ -9722,6 +9722,7 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
|
OFFSET(slab_inuse));
|
||||||
|
fprintf(fp, " slab_free: %ld\n",
|
||||||
|
OFFSET(slab_free));
|
||||||
|
+ fprintf(fp, " slab_slab_list: %ld\n", OFFSET(slab_slab_list));
|
||||||
|
|
||||||
|
fprintf(fp, " kmem_cache_size: %ld\n",
|
||||||
|
OFFSET(kmem_cache_size));
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,49 @@
|
|||||||
|
From 699717c7720cb2a397ce59d0a0380c65d2693033 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Date: Fri, 23 Dec 2022 18:42:35 +0800
|
||||||
|
Subject: [PATCH 61/89] Fix for "kmem -i" to display correct SLAB statistics on
|
||||||
|
Linux 5.9 and later
|
||||||
|
|
||||||
|
Kernel commit d42f3245c7e2 ("mm: memcg: convert vmstat slab counters to
|
||||||
|
bytes"), which is contained in Linux v5.9-rc1 and later kernels, renamed
|
||||||
|
NR_SLAB_{RECLAIMABLE,UNRECLAIMABLE} to NR_SLAB_{RECLAIMABLE,UNRECLAIMABLE}_B.
|
||||||
|
|
||||||
|
Without the patch, "kmem -i" command will display incorrect SLAB
|
||||||
|
statistics:
|
||||||
|
|
||||||
|
crash> kmem -i | grep -e PAGES -e SLAB
|
||||||
|
PAGES TOTAL PERCENTAGE
|
||||||
|
SLAB 89458 349.4 MB 0% of TOTAL MEM
|
||||||
|
^^^^^ ^^^^^
|
||||||
|
|
||||||
|
With the patch, the actual result is:
|
||||||
|
crash> kmem -i | grep -e PAGES -e SLAB
|
||||||
|
PAGES TOTAL PERCENTAGE
|
||||||
|
SLAB 261953 1023.3 MB 0% of TOTAL MEM
|
||||||
|
|
||||||
|
Reported-by: Buland Kumar Singh <bsingh@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
---
|
||||||
|
memory.c | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/memory.c b/memory.c
|
||||||
|
index d05737cc1429..625a94b7d7d4 100644
|
||||||
|
--- a/memory.c
|
||||||
|
+++ b/memory.c
|
||||||
|
@@ -8388,6 +8388,11 @@ dump_kmeminfo(void)
|
||||||
|
get_slabs = nr_slab;
|
||||||
|
if (dump_vm_stat("NR_SLAB_UNRECLAIMABLE", &nr_slab, 0))
|
||||||
|
get_slabs += nr_slab;
|
||||||
|
+ } else if (dump_vm_stat("NR_SLAB_RECLAIMABLE_B", &nr_slab, 0)) {
|
||||||
|
+ /* 5.9 and later */
|
||||||
|
+ get_slabs = nr_slab;
|
||||||
|
+ if (dump_vm_stat("NR_SLAB_UNRECLAIMABLE_B", &nr_slab, 0))
|
||||||
|
+ get_slabs += nr_slab;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,49 @@
|
|||||||
|
From 4003c972c5ff0814847865a9f5487c8561a598ad Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Date: Tue, 27 Dec 2022 09:53:46 +0900
|
||||||
|
Subject: [PATCH 62/89] Fix build failure due to no EM_RISCV with glibc-2.23
|
||||||
|
and earlier
|
||||||
|
|
||||||
|
With glibc-2.23 and earlier (e.g. RHEL7), crash build fails with errors
|
||||||
|
like this due to EM_RISCV undeclared:
|
||||||
|
|
||||||
|
$ make -j 24 warn
|
||||||
|
TARGET: X86_64
|
||||||
|
CRASH: 8.0.2++
|
||||||
|
GDB: 10.2
|
||||||
|
...
|
||||||
|
symbols.c: In function 'is_kernel':
|
||||||
|
symbols.c:3746:8: error: 'EM_RISCV' undeclared (first use in this function)
|
||||||
|
case EM_RISCV:
|
||||||
|
^
|
||||||
|
...
|
||||||
|
|
||||||
|
Define EM_RISCV as 243 [1][2] if not defined.
|
||||||
|
|
||||||
|
[1] https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=94e73c95d9b5
|
||||||
|
[2] http://www.sco.com/developers/gabi/latest/ch4.eheader.html
|
||||||
|
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
defs.h | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index 31702e707bee..cb04562d0d92 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -3493,6 +3493,10 @@ struct arm64_stackframe {
|
||||||
|
#define _MAX_PHYSMEM_BITS 48
|
||||||
|
#endif /* MIPS64 */
|
||||||
|
|
||||||
|
+#ifndef EM_RISCV
|
||||||
|
+#define EM_RISCV 243
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#ifdef RISCV64
|
||||||
|
#define _64BIT_
|
||||||
|
#define MACHINE_TYPE "RISCV64"
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,46 @@
|
|||||||
|
From 652681dd7fa37a20d7ef3a51a27afa7d6d3f1872 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Date: Thu, 5 Jan 2023 17:18:51 +0900
|
||||||
|
Subject: [PATCH 63/89] SLAB: Fix for "kmem -s|-S" options on Linux 6.1 and
|
||||||
|
later
|
||||||
|
|
||||||
|
Kernel commit e36ce448a08d ("mm/slab: use kmalloc_node() for off slab
|
||||||
|
freelist_idx_t array allocation"), which is contained in Linux 6.1 and
|
||||||
|
later kernels, removed kmem_cache.freelist_cache member on kernels
|
||||||
|
configured with CONFIG_SLAB=y.
|
||||||
|
|
||||||
|
Without the patch, crash does not set SLAB_OVERLOAD_PAGE and
|
||||||
|
"kmem -s|-S" options fail with the following error:
|
||||||
|
|
||||||
|
kmem: invalid structure member offset: slab_list
|
||||||
|
FILE: memory.c LINE: 12156 FUNCTION: verify_slab_v2()
|
||||||
|
|
||||||
|
Use kmem_cache.freelist_size instead, which was introduced together
|
||||||
|
with kmem_cache.freelist_cache by kernel commit 8456a648cf44.
|
||||||
|
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
memory.c | 5 ++++-
|
||||||
|
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/memory.c b/memory.c
|
||||||
|
index 625a94b7d7d4..71ded688206f 100644
|
||||||
|
--- a/memory.c
|
||||||
|
+++ b/memory.c
|
||||||
|
@@ -535,8 +535,11 @@ vm_init(void)
|
||||||
|
/*
|
||||||
|
* slab: overload struct slab over struct page
|
||||||
|
* https://lkml.org/lkml/2013/10/16/155
|
||||||
|
+ *
|
||||||
|
+ * commit e36ce448a08d removed kmem_cache.freelist_cache in 6.1,
|
||||||
|
+ * so use freelist_size instead.
|
||||||
|
*/
|
||||||
|
- if (MEMBER_EXISTS("kmem_cache", "freelist_cache")) {
|
||||||
|
+ if (MEMBER_EXISTS("kmem_cache", "freelist_size")) {
|
||||||
|
vt->flags |= SLAB_OVERLOAD_PAGE;
|
||||||
|
ANON_MEMBER_OFFSET_INIT(page_s_mem, "page", "s_mem");
|
||||||
|
ANON_MEMBER_OFFSET_INIT(page_freelist, "page", "freelist");
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,233 @@
|
|||||||
|
From 4060546b051751e7e593100027d2a160723a17ee Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Date: Thu, 5 Jan 2023 17:36:42 +0900
|
||||||
|
Subject: [PATCH 64/89] SLAB: Fix for "kmem -s|-S" options on Linux 6.2-rc1 and
|
||||||
|
later
|
||||||
|
|
||||||
|
Kernel commit 130d4df57390 ("mm/sl[au]b: rearrange struct slab fields to
|
||||||
|
allow larger rcu_head"), which is contained in Linux 6.2-rc1 and later
|
||||||
|
kernels, changed the offset of slab.slab_list and now it's not equal to
|
||||||
|
the offset of page.lru.
|
||||||
|
|
||||||
|
Without the patch, "kmem -s|-S" options print errors and zeros for slab
|
||||||
|
counters like this for kernels configured with CONFIG_SLAB=y.
|
||||||
|
|
||||||
|
crash> kmem -s
|
||||||
|
CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
|
||||||
|
kmem: rpc_inode_cache: partial list: page/slab: fffff31ac4125190 bad active counter: 99476865
|
||||||
|
kmem: rpc_inode_cache: partial list: page/slab: fffff31ac4125190 bad s_mem pointer: 100000003
|
||||||
|
kmem: rpc_inode_cache: full list: page/slab: fffff31ac4125150 bad active counter: 99476225
|
||||||
|
kmem: rpc_inode_cache: full list: page/slab: fffff31ac4125150 bad active counter: 99476225
|
||||||
|
kmem: rpc_inode_cache: full list: page/slab: fffff31ac4125150 bad s_mem pointer: 100000005
|
||||||
|
ffff930202adfb40 704 0 0 0 4k rpc_inode_cache
|
||||||
|
...
|
||||||
|
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
memory.c | 45 +++++++++++++++++++++++++--------------------
|
||||||
|
1 file changed, 25 insertions(+), 20 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/memory.c b/memory.c
|
||||||
|
index 71ded688206f..156de2f7b5a3 100644
|
||||||
|
--- a/memory.c
|
||||||
|
+++ b/memory.c
|
||||||
|
@@ -78,6 +78,7 @@ struct meminfo { /* general purpose memory information structure */
|
||||||
|
int *freelist;
|
||||||
|
int freelist_index_size;
|
||||||
|
ulong random;
|
||||||
|
+ ulong list_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -553,6 +554,8 @@ vm_init(void)
|
||||||
|
MEMBER_OFFSET_INIT(page_freelist, "slab", "freelist");
|
||||||
|
if (INVALID_MEMBER(page_active))
|
||||||
|
MEMBER_OFFSET_INIT(page_active, "slab", "active");
|
||||||
|
+
|
||||||
|
+ MEMBER_OFFSET_INIT(slab_slab_list, "slab", "slab_list");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!VALID_STRUCT(kmem_slab_s) && VALID_STRUCT(slab_s)) {
|
||||||
|
@@ -10767,6 +10770,8 @@ dump_kmem_cache_percpu_v2(struct meminfo *si)
|
||||||
|
if (vt->flags & SLAB_OVERLOAD_PAGE) {
|
||||||
|
si->freelist = si->kmem_bufctl;
|
||||||
|
si->freelist_index_size = slab_freelist_index_size();
|
||||||
|
+ si->list_offset = VALID_MEMBER(slab_slab_list) ?
|
||||||
|
+ OFFSET(slab_slab_list) : OFFSET(page_lru);
|
||||||
|
}
|
||||||
|
for (i = 0; i < vt->kmem_max_cpus; i++)
|
||||||
|
si->cpudata[i] = (ulong *)
|
||||||
|
@@ -11983,7 +11988,7 @@ do_slab_chain_slab_overload_page(long cmd, struct meminfo *si)
|
||||||
|
}
|
||||||
|
last = si->slab;
|
||||||
|
|
||||||
|
- readmem(si->slab - OFFSET(page_lru), KVADDR, page_buf,
|
||||||
|
+ readmem(si->slab - si->list_offset, KVADDR, page_buf,
|
||||||
|
SIZE(page), "page (slab) buffer",
|
||||||
|
FAULT_ON_ERROR);
|
||||||
|
|
||||||
|
@@ -11996,8 +12001,7 @@ do_slab_chain_slab_overload_page(long cmd, struct meminfo *si)
|
||||||
|
|
||||||
|
si->num_slabs++;
|
||||||
|
|
||||||
|
- si->slab = ULONG(page_buf +
|
||||||
|
- OFFSET(page_lru));
|
||||||
|
+ si->slab = ULONG(page_buf + si->list_offset);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for slab transition. (Tony Dziedzic)
|
||||||
|
@@ -12024,11 +12028,11 @@ do_slab_chain_slab_overload_page(long cmd, struct meminfo *si)
|
||||||
|
case SLAB_WALKTHROUGH:
|
||||||
|
if (si->flags & SLAB_OVERLOAD_PAGE_PTR) {
|
||||||
|
specified_slab = si->spec_addr;
|
||||||
|
- si->slab = si->spec_addr + OFFSET(page_lru);
|
||||||
|
+ si->slab = si->spec_addr + si->list_offset;
|
||||||
|
} else {
|
||||||
|
specified_slab = si->slab;
|
||||||
|
if (si->slab)
|
||||||
|
- si->slab += OFFSET(page_lru);
|
||||||
|
+ si->slab += si->list_offset;
|
||||||
|
}
|
||||||
|
si->flags |= (SLAB_WALKTHROUGH|SLAB_FIRST_NODE);
|
||||||
|
si->flags &= ~SLAB_GET_COUNTS;
|
||||||
|
@@ -12082,7 +12086,7 @@ do_slab_chain_slab_overload_page(long cmd, struct meminfo *si)
|
||||||
|
if (si->slab == slab_chains[s])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- readmem(si->slab - OFFSET(page_lru), KVADDR, page_buf,
|
||||||
|
+ readmem(si->slab - si->list_offset, KVADDR, page_buf,
|
||||||
|
SIZE(page), "page (slab) buffer",
|
||||||
|
FAULT_ON_ERROR);
|
||||||
|
|
||||||
|
@@ -12242,7 +12246,7 @@ verify_slab_overload_page(struct meminfo *si, ulong last, int s)
|
||||||
|
|
||||||
|
errcnt = 0;
|
||||||
|
|
||||||
|
- if (!readmem(si->slab - OFFSET(page_lru), KVADDR, page_buf,
|
||||||
|
+ if (!readmem(si->slab - si->list_offset, KVADDR, page_buf,
|
||||||
|
SIZE(page), "page (slab) buffer", QUIET|RETURN_ON_ERROR)) {
|
||||||
|
error(INFO, "%s: %s list: bad slab pointer: %lx\n",
|
||||||
|
si->curname, list, si->slab);
|
||||||
|
@@ -12250,7 +12254,7 @@ verify_slab_overload_page(struct meminfo *si, ulong last, int s)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
- list_head = (struct kernel_list_head *)(page_buf + OFFSET(page_lru));
|
||||||
|
+ list_head = (struct kernel_list_head *)(page_buf + si->list_offset);
|
||||||
|
if (!IS_KVADDR((ulong)list_head->next) ||
|
||||||
|
!accessible((ulong)list_head->next)) {
|
||||||
|
error(INFO, "%s: %s list: page/slab: %lx bad next pointer: %lx\n",
|
||||||
|
@@ -12569,7 +12573,7 @@ dump_slab_overload_page(struct meminfo *si)
|
||||||
|
int tmp;
|
||||||
|
ulong slab_overload_page, freelist;
|
||||||
|
|
||||||
|
- slab_overload_page = si->slab - OFFSET(page_lru);
|
||||||
|
+ slab_overload_page = si->slab - si->list_offset;
|
||||||
|
|
||||||
|
readmem(slab_overload_page + OFFSET(page_s_mem),
|
||||||
|
KVADDR, &si->s_mem, sizeof(ulong),
|
||||||
|
@@ -12796,12 +12800,12 @@ gather_slab_free_list_slab_overload_page(struct meminfo *si)
|
||||||
|
|
||||||
|
if (CRASHDEBUG(1))
|
||||||
|
fprintf(fp, "slab page: %lx active: %ld si->c_num: %ld\n",
|
||||||
|
- si->slab - OFFSET(page_lru), si->s_inuse, si->c_num);
|
||||||
|
+ si->slab - si->list_offset, si->s_inuse, si->c_num);
|
||||||
|
|
||||||
|
if (si->s_inuse == si->c_num )
|
||||||
|
return;
|
||||||
|
|
||||||
|
- slab_overload_page = si->slab - OFFSET(page_lru);
|
||||||
|
+ slab_overload_page = si->slab - si->list_offset;
|
||||||
|
readmem(slab_overload_page + OFFSET(page_freelist),
|
||||||
|
KVADDR, &freelist, sizeof(void *), "page freelist",
|
||||||
|
FAULT_ON_ERROR);
|
||||||
|
@@ -13099,7 +13103,7 @@ dump_slab_objects_percpu(struct meminfo *si)
|
||||||
|
|
||||||
|
if ((si->flags & ADDRESS_SPECIFIED) &&
|
||||||
|
(vt->flags & SLAB_OVERLOAD_PAGE)) {
|
||||||
|
- readmem(si->slab - OFFSET(page_lru) + OFFSET(page_freelist),
|
||||||
|
+ readmem(si->slab - si->list_offset + OFFSET(page_freelist),
|
||||||
|
KVADDR, &freelist, sizeof(ulong), "page.freelist",
|
||||||
|
FAULT_ON_ERROR);
|
||||||
|
|
||||||
|
@@ -18713,6 +18717,9 @@ dump_kmem_cache_slub(struct meminfo *si)
|
||||||
|
|
||||||
|
si->cache_buf = GETBUF(SIZE(kmem_cache));
|
||||||
|
|
||||||
|
+ si->list_offset = VALID_MEMBER(slab_slab_list) ?
|
||||||
|
+ OFFSET(slab_slab_list) : OFFSET(page_lru);
|
||||||
|
+
|
||||||
|
if (VALID_MEMBER(page_objects) &&
|
||||||
|
OFFSET(page_objects) == OFFSET(page_inuse))
|
||||||
|
si->flags |= SLAB_BITFIELD;
|
||||||
|
@@ -19484,7 +19491,6 @@ do_node_lists_slub(struct meminfo *si, ulong node_ptr, int node)
|
||||||
|
{
|
||||||
|
ulong next, last, list_head, flags;
|
||||||
|
int first;
|
||||||
|
- long list_off = VALID_MEMBER(slab_slab_list) ? OFFSET(slab_slab_list) : OFFSET(page_lru);
|
||||||
|
|
||||||
|
if (!node_ptr)
|
||||||
|
return;
|
||||||
|
@@ -19498,7 +19504,7 @@ do_node_lists_slub(struct meminfo *si, ulong node_ptr, int node)
|
||||||
|
next == list_head ? " (empty)\n" : "");
|
||||||
|
first = 0;
|
||||||
|
while (next != list_head) {
|
||||||
|
- si->slab = last = next - list_off;
|
||||||
|
+ si->slab = last = next - si->list_offset;
|
||||||
|
if (first++ == 0)
|
||||||
|
fprintf(fp, " %s", slab_hdr);
|
||||||
|
|
||||||
|
@@ -19521,7 +19527,7 @@ do_node_lists_slub(struct meminfo *si, ulong node_ptr, int node)
|
||||||
|
|
||||||
|
if (!IS_KVADDR(next) ||
|
||||||
|
((next != list_head) &&
|
||||||
|
- !is_page_ptr(next - list_off, NULL))) {
|
||||||
|
+ !is_page_ptr(next - si->list_offset, NULL))) {
|
||||||
|
error(INFO,
|
||||||
|
"%s: partial list slab: %lx invalid page.lru.next: %lx\n",
|
||||||
|
si->curname, last, next);
|
||||||
|
@@ -19548,7 +19554,7 @@ do_node_lists_slub(struct meminfo *si, ulong node_ptr, int node)
|
||||||
|
next == list_head ? " (empty)\n" : "");
|
||||||
|
first = 0;
|
||||||
|
while (next != list_head) {
|
||||||
|
- si->slab = next - list_off;
|
||||||
|
+ si->slab = next - si->list_offset;
|
||||||
|
if (first++ == 0)
|
||||||
|
fprintf(fp, " %s", slab_hdr);
|
||||||
|
|
||||||
|
@@ -19765,7 +19771,6 @@ count_partial(ulong node, struct meminfo *si, ulong *free)
|
||||||
|
short inuse, objects;
|
||||||
|
ulong total_inuse;
|
||||||
|
ulong count = 0;
|
||||||
|
- long list_off = VALID_MEMBER(slab_slab_list) ? OFFSET(slab_slab_list) : OFFSET(page_lru);
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
total_inuse = 0;
|
||||||
|
@@ -19777,12 +19782,12 @@ count_partial(ulong node, struct meminfo *si, ulong *free)
|
||||||
|
hq_open();
|
||||||
|
|
||||||
|
while (next != list_head) {
|
||||||
|
- if (!readmem(next - list_off + OFFSET(page_inuse),
|
||||||
|
+ if (!readmem(next - si->list_offset + OFFSET(page_inuse),
|
||||||
|
KVADDR, &inuse, sizeof(ushort), "page.inuse", RETURN_ON_ERROR)) {
|
||||||
|
hq_close();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
- last = next - list_off;
|
||||||
|
+ last = next - si->list_offset;
|
||||||
|
|
||||||
|
if (inuse == -1) {
|
||||||
|
error(INFO,
|
||||||
|
@@ -19808,7 +19813,7 @@ count_partial(ulong node, struct meminfo *si, ulong *free)
|
||||||
|
}
|
||||||
|
if (!IS_KVADDR(next) ||
|
||||||
|
((next != list_head) &&
|
||||||
|
- !is_page_ptr(next - list_off, NULL))) {
|
||||||
|
+ !is_page_ptr(next - si->list_offset, NULL))) {
|
||||||
|
error(INFO, "%s: partial list slab: %lx invalid page.lru.next: %lx\n",
|
||||||
|
si->curname, last, next);
|
||||||
|
break;
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,633 @@
|
|||||||
|
From 5b61f450d213cda90dd0f50a02594a0b87151c89 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tao Liu <ltao@redhat.com>
|
||||||
|
Date: Tue, 10 Jan 2023 14:56:27 +0800
|
||||||
|
Subject: [PATCH 65/89] Port the maple tree data structures and functions
|
||||||
|
|
||||||
|
There have been two ways to iterate vm_area_struct until Linux 6.0:
|
||||||
|
1) by rbtree, aka vma.vm_rb;
|
||||||
|
2) by linked list, aka vma.vm_{next,prev}.
|
||||||
|
However with the maple tree patches[1][2] in Linux 6.1, vm_rb and
|
||||||
|
vm_{next,prev} are removed from vm_area_struct. The vm_area_dump()
|
||||||
|
in crash mainly uses the linked list for vma iteration, which will
|
||||||
|
not work for this case. So the maple tree iteration needs to be
|
||||||
|
ported to crash.
|
||||||
|
|
||||||
|
For crash, currently it only iteratively reads the maple tree,
|
||||||
|
no more rcu safe or maple tree modification features needed.
|
||||||
|
So we only port a subset of kernel maple tree features.
|
||||||
|
In addition, we need to modify the ported kernel source code,
|
||||||
|
making it compatible with crash.
|
||||||
|
|
||||||
|
This patch deals with the two issues:
|
||||||
|
1) Poring mt_dump() function and all its dependencies from
|
||||||
|
kernel source to crash, to enable crash maple tree iteration,
|
||||||
|
2) adapting the ported code with crash.
|
||||||
|
|
||||||
|
[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=524e00b36e8c547f5582eef3fb645a8d9fc5e3df
|
||||||
|
[2]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=763ecb035029f500d7e6dc99acd1ad299b7726a1
|
||||||
|
|
||||||
|
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
Makefile | 10 +-
|
||||||
|
defs.h | 19 +++
|
||||||
|
maple_tree.c | 407 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
maple_tree.h | 82 +++++++++++
|
||||||
|
4 files changed, 515 insertions(+), 3 deletions(-)
|
||||||
|
create mode 100644 maple_tree.c
|
||||||
|
create mode 100644 maple_tree.h
|
||||||
|
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index c0de5ef8ff75..b290836ffc83 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -59,6 +59,7 @@ IBM_HFILES=ibm_common.h
|
||||||
|
SADUMP_HFILES=sadump.h
|
||||||
|
UNWIND_HFILES=unwind.h unwind_i.h rse.h unwind_x86.h unwind_x86_64.h
|
||||||
|
VMWARE_HFILES=vmware_vmss.h
|
||||||
|
+MAPLE_TREE_HFILES=maple_tree.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 \
|
||||||
|
@@ -73,12 +74,12 @@ CFILES=main.c tools.c global_data.c memory.c filesys.c help.c task.c \
|
||||||
|
xen_hyper.c xen_hyper_command.c xen_hyper_global_data.c \
|
||||||
|
xen_hyper_dump_tables.c kvmdump.c qemu.c qemu-load.c sadump.c ipcs.c \
|
||||||
|
ramdump.c vmware_vmss.c vmware_guestdump.c \
|
||||||
|
- xen_dom0.c kaslr_helper.c sbitmap.c
|
||||||
|
+ xen_dom0.c kaslr_helper.c sbitmap.c maple_tree.c
|
||||||
|
|
||||||
|
SOURCE_FILES=${CFILES} ${GENERIC_HFILES} ${MCORE_HFILES} \
|
||||||
|
${REDHAT_CFILES} ${REDHAT_HFILES} ${UNWIND_HFILES} \
|
||||||
|
${LKCD_DUMP_HFILES} ${LKCD_TRACE_HFILES} ${LKCD_OBSOLETE_HFILES}\
|
||||||
|
- ${IBM_HFILES} ${SADUMP_HFILES} ${VMWARE_HFILES}
|
||||||
|
+ ${IBM_HFILES} ${SADUMP_HFILES} ${VMWARE_HFILES} ${MAPLE_TREE_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 \
|
||||||
|
@@ -93,7 +94,7 @@ OBJECT_FILES=main.o tools.o global_data.o memory.o filesys.o help.o task.o \
|
||||||
|
xen_hyper.o xen_hyper_command.o xen_hyper_global_data.o \
|
||||||
|
xen_hyper_dump_tables.o kvmdump.o qemu.o qemu-load.o sadump.o ipcs.o \
|
||||||
|
ramdump.o vmware_vmss.o vmware_guestdump.o \
|
||||||
|
- xen_dom0.o kaslr_helper.o sbitmap.o
|
||||||
|
+ xen_dom0.o kaslr_helper.o sbitmap.o maple_tree.o
|
||||||
|
|
||||||
|
MEMORY_DRIVER_FILES=memory_driver/Makefile memory_driver/crash.c memory_driver/README
|
||||||
|
|
||||||
|
@@ -548,6 +549,9 @@ kaslr_helper.o: ${GENERIC_HFILES} kaslr_helper.c
|
||||||
|
bpf.o: ${GENERIC_HFILES} bpf.c
|
||||||
|
${CC} -c ${CRASH_CFLAGS} bpf.c ${WARNING_OPTIONS} ${WARNING_ERROR}
|
||||||
|
|
||||||
|
+maple_tree.o: ${GENERIC_HFILES} ${MAPLE_TREE_HFILES} maple_tree.c
|
||||||
|
+ ${CC} -c ${CRASH_CFLAGS} maple_tree.c ${WARNING_OPTIONS} ${WARNING_ERROR}
|
||||||
|
+
|
||||||
|
${PROGRAM}: force
|
||||||
|
@$(MAKE) all
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index cb04562d0d92..46ed10e17cd2 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -2189,6 +2189,21 @@ struct offset_table { /* stash of commonly-used offsets */
|
||||||
|
long request_queue_hctx_table;
|
||||||
|
long percpu_counter_counters;
|
||||||
|
long slab_slab_list;
|
||||||
|
+ long mm_struct_mm_mt;
|
||||||
|
+ long maple_tree_ma_root;
|
||||||
|
+ long maple_tree_ma_flags;
|
||||||
|
+ long maple_node_parent;
|
||||||
|
+ long maple_node_ma64;
|
||||||
|
+ long maple_node_mr64;
|
||||||
|
+ long maple_node_slot;
|
||||||
|
+ long maple_arange_64_pivot;
|
||||||
|
+ long maple_arange_64_slot;
|
||||||
|
+ long maple_arange_64_gap;
|
||||||
|
+ long maple_arange_64_meta;
|
||||||
|
+ long maple_range_64_pivot;
|
||||||
|
+ long maple_range_64_slot;
|
||||||
|
+ long maple_metadata_end;
|
||||||
|
+ long maple_metadata_gap;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct size_table { /* stash of commonly-used sizes */
|
||||||
|
@@ -2360,6 +2375,8 @@ struct size_table { /* stash of commonly-used sizes */
|
||||||
|
long sbq_wait_state;
|
||||||
|
long blk_mq_tags;
|
||||||
|
long percpu_counter;
|
||||||
|
+ long maple_tree;
|
||||||
|
+ long maple_node;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct array_table {
|
||||||
|
@@ -5730,6 +5747,8 @@ int same_file(char *, char *);
|
||||||
|
#ifndef GDB_COMMON
|
||||||
|
int cleanup_memory_driver(void);
|
||||||
|
|
||||||
|
+void maple_init(void);
|
||||||
|
+int do_mptree(struct tree_data *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* help.c
|
||||||
|
diff --git a/maple_tree.c b/maple_tree.c
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000000..474faeda6252
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/maple_tree.c
|
||||||
|
@@ -0,0 +1,407 @@
|
||||||
|
+// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
+/*
|
||||||
|
+ * Maple Tree implementation
|
||||||
|
+ * Copyright (c) 2018-2022 Oracle Corporation
|
||||||
|
+ * Authors: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||||
|
+ * Matthew Wilcox <willy@infradead.org>
|
||||||
|
+ *
|
||||||
|
+ * The following are copied and modified from lib/maple_tree.c
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "maple_tree.h"
|
||||||
|
+#include "defs.h"
|
||||||
|
+
|
||||||
|
+unsigned char *mt_slots = NULL;
|
||||||
|
+unsigned char *mt_pivots = NULL;
|
||||||
|
+ulong mt_max[4] = {0};
|
||||||
|
+
|
||||||
|
+#define MAPLE_BUFSIZE 512
|
||||||
|
+
|
||||||
|
+static inline ulong mte_to_node(ulong maple_enode_entry)
|
||||||
|
+{
|
||||||
|
+ return maple_enode_entry & ~MAPLE_NODE_MASK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline enum maple_type mte_node_type(ulong maple_enode_entry)
|
||||||
|
+{
|
||||||
|
+ return (maple_enode_entry >> MAPLE_NODE_TYPE_SHIFT) &
|
||||||
|
+ MAPLE_NODE_TYPE_MASK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline ulong mt_slot(void **slots, unsigned char offset)
|
||||||
|
+{
|
||||||
|
+ return (ulong)slots[offset];
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool ma_is_leaf(const enum maple_type type)
|
||||||
|
+{
|
||||||
|
+ return type < maple_range_64;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*************** For cmd_tree ********************/
|
||||||
|
+
|
||||||
|
+struct maple_tree_ops {
|
||||||
|
+ void (*entry)(ulong node, ulong slot, const char *path,
|
||||||
|
+ ulong index, void *private);
|
||||||
|
+ void *private;
|
||||||
|
+ bool is_td;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static const char spaces[] = " ";
|
||||||
|
+
|
||||||
|
+static void do_mt_range64(ulong, ulong, ulong, uint, char *, ulong *,
|
||||||
|
+ struct maple_tree_ops *);
|
||||||
|
+static void do_mt_arange64(ulong, ulong, ulong, uint, char *, ulong *,
|
||||||
|
+ struct maple_tree_ops *);
|
||||||
|
+static void do_mt_entry(ulong, ulong, ulong, uint, uint, char *, ulong *,
|
||||||
|
+ struct maple_tree_ops *);
|
||||||
|
+static void do_mt_node(ulong, ulong, ulong, uint, char *, ulong *,
|
||||||
|
+ struct maple_tree_ops *);
|
||||||
|
+struct req_entry *fill_member_offsets(char *);
|
||||||
|
+void dump_struct_members_fast(struct req_entry *, int, ulong);
|
||||||
|
+void dump_struct_members_for_tree(struct tree_data *, int, ulong);
|
||||||
|
+
|
||||||
|
+static void mt_dump_range(ulong min, ulong max, uint depth)
|
||||||
|
+{
|
||||||
|
+ if (min == max)
|
||||||
|
+ fprintf(fp, "%.*s%lu: ", depth * 2, spaces, min);
|
||||||
|
+ else
|
||||||
|
+ fprintf(fp, "%.*s%lu-%lu: ", depth * 2, spaces, min, max);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool mt_is_reserved(ulong entry)
|
||||||
|
+{
|
||||||
|
+ return (entry < MAPLE_RESERVED_RANGE) && xa_is_internal(entry);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool mte_is_leaf(ulong maple_enode_entry)
|
||||||
|
+{
|
||||||
|
+ return ma_is_leaf(mte_node_type(maple_enode_entry));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static uint mt_height(char *mt_buf)
|
||||||
|
+{
|
||||||
|
+ return (UINT(mt_buf + OFFSET(maple_tree_ma_flags)) &
|
||||||
|
+ MT_FLAGS_HEIGHT_MASK)
|
||||||
|
+ >> MT_FLAGS_HEIGHT_OFFSET;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void dump_mt_range64(char *mr64_buf)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ fprintf(fp, " contents: ");
|
||||||
|
+ for (i = 0; i < mt_slots[maple_range_64] - 1; i++)
|
||||||
|
+ fprintf(fp, "%p %lu ",
|
||||||
|
+ VOID_PTR(mr64_buf + OFFSET(maple_range_64_slot)
|
||||||
|
+ + sizeof(void *) * i),
|
||||||
|
+ ULONG(mr64_buf + OFFSET(maple_range_64_pivot)
|
||||||
|
+ + sizeof(ulong) * i));
|
||||||
|
+ fprintf(fp, "%p\n", VOID_PTR(mr64_buf + OFFSET(maple_range_64_slot)
|
||||||
|
+ + sizeof(void *) * i));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void dump_mt_arange64(char *ma64_buf)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ fprintf(fp, " contents: ");
|
||||||
|
+ for (i = 0; i < mt_slots[maple_arange_64]; i++)
|
||||||
|
+ fprintf(fp, "%lu ", ULONG(ma64_buf + OFFSET(maple_arange_64_gap)
|
||||||
|
+ + sizeof(ulong) * i));
|
||||||
|
+
|
||||||
|
+ fprintf(fp, "| %02X %02X| ",
|
||||||
|
+ UCHAR(ma64_buf + OFFSET(maple_arange_64_meta) +
|
||||||
|
+ OFFSET(maple_metadata_end)),
|
||||||
|
+ UCHAR(ma64_buf + OFFSET(maple_arange_64_meta) +
|
||||||
|
+ OFFSET(maple_metadata_gap)));
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < mt_slots[maple_arange_64] - 1; i++)
|
||||||
|
+ fprintf(fp, "%p %lu ",
|
||||||
|
+ VOID_PTR(ma64_buf + OFFSET(maple_arange_64_slot) +
|
||||||
|
+ sizeof(void *) * i),
|
||||||
|
+ ULONG(ma64_buf + OFFSET(maple_arange_64_pivot) +
|
||||||
|
+ sizeof(ulong) * i));
|
||||||
|
+ fprintf(fp, "%p\n", VOID_PTR(ma64_buf + OFFSET(maple_arange_64_slot) +
|
||||||
|
+ sizeof(void *) * i));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void dump_mt_entry(ulong entry, ulong min, ulong max, uint depth)
|
||||||
|
+{
|
||||||
|
+ mt_dump_range(min, max, depth);
|
||||||
|
+
|
||||||
|
+ if (xa_is_value(entry))
|
||||||
|
+ fprintf(fp, "value %ld (0x%lx) [0x%lx]\n", xa_to_value(entry),
|
||||||
|
+ xa_to_value(entry), entry);
|
||||||
|
+ else if (xa_is_zero(entry))
|
||||||
|
+ fprintf(fp, "zero (%ld)\n", xa_to_internal(entry));
|
||||||
|
+ else if (mt_is_reserved(entry))
|
||||||
|
+ fprintf(fp, "UNKNOWN ENTRY (0x%lx)\n", entry);
|
||||||
|
+ else
|
||||||
|
+ fprintf(fp, "0x%lx\n", entry);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void dump_mt_node(ulong maple_node, char *node_data, uint type,
|
||||||
|
+ ulong min, ulong max, uint depth)
|
||||||
|
+{
|
||||||
|
+ mt_dump_range(min, max, depth);
|
||||||
|
+
|
||||||
|
+ fprintf(fp, "node 0x%lx depth %d type %d parent %p",
|
||||||
|
+ maple_node, depth, type,
|
||||||
|
+ maple_node ? VOID_PTR(node_data + OFFSET(maple_node_parent)) :
|
||||||
|
+ NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void do_mt_range64(ulong entry, ulong min, ulong max,
|
||||||
|
+ uint depth, char *path, ulong *global_index,
|
||||||
|
+ struct maple_tree_ops *ops)
|
||||||
|
+{
|
||||||
|
+ ulong maple_node_m_node = mte_to_node(entry);
|
||||||
|
+ char node_buf[MAPLE_BUFSIZE];
|
||||||
|
+ bool leaf = mte_is_leaf(entry);
|
||||||
|
+ ulong first = min, last;
|
||||||
|
+ int i;
|
||||||
|
+ int len = strlen(path);
|
||||||
|
+ struct tree_data *td = ops->is_td ? (struct tree_data *)ops->private : NULL;
|
||||||
|
+ char *mr64_buf;
|
||||||
|
+
|
||||||
|
+ if (SIZE(maple_node) > MAPLE_BUFSIZE)
|
||||||
|
+ error(FATAL, "MAPLE_BUFSIZE should be larger than maple_node struct");
|
||||||
|
+
|
||||||
|
+ readmem(maple_node_m_node, KVADDR, node_buf, SIZE(maple_node),
|
||||||
|
+ "mt_dump_range64 read maple_node", FAULT_ON_ERROR);
|
||||||
|
+
|
||||||
|
+ mr64_buf = node_buf + OFFSET(maple_node_mr64);
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < mt_slots[maple_range_64]; i++) {
|
||||||
|
+ last = max;
|
||||||
|
+
|
||||||
|
+ if (i < (mt_slots[maple_range_64] - 1))
|
||||||
|
+ last = ULONG(mr64_buf + OFFSET(maple_range_64_pivot) +
|
||||||
|
+ sizeof(ulong) * i);
|
||||||
|
+
|
||||||
|
+ else if (!VOID_PTR(mr64_buf + OFFSET(maple_range_64_slot) +
|
||||||
|
+ sizeof(void *) * i) &&
|
||||||
|
+ max != mt_max[mte_node_type(entry)])
|
||||||
|
+ break;
|
||||||
|
+ if (last == 0 && i > 0)
|
||||||
|
+ break;
|
||||||
|
+ if (leaf)
|
||||||
|
+ do_mt_entry(mt_slot((void **)(mr64_buf +
|
||||||
|
+ OFFSET(maple_range_64_slot)), i),
|
||||||
|
+ first, last, depth + 1, i, path, global_index, ops);
|
||||||
|
+ else if (VOID_PTR(mr64_buf + OFFSET(maple_range_64_slot) +
|
||||||
|
+ sizeof(void *) * i)) {
|
||||||
|
+ sprintf(path + len, "/%d", i);
|
||||||
|
+ do_mt_node(mt_slot((void **)(mr64_buf +
|
||||||
|
+ OFFSET(maple_range_64_slot)), i),
|
||||||
|
+ first, last, depth + 1, path, global_index, ops);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (last == max)
|
||||||
|
+ break;
|
||||||
|
+ if (last > max) {
|
||||||
|
+ fprintf(fp, "node %p last (%lu) > max (%lu) at pivot %d!\n",
|
||||||
|
+ mr64_buf, last, max, i);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ first = last + 1;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void do_mt_arange64(ulong entry, ulong min, ulong max,
|
||||||
|
+ uint depth, char *path, ulong *global_index,
|
||||||
|
+ struct maple_tree_ops *ops)
|
||||||
|
+{
|
||||||
|
+ ulong maple_node_m_node = mte_to_node(entry);
|
||||||
|
+ char node_buf[MAPLE_BUFSIZE];
|
||||||
|
+ bool leaf = mte_is_leaf(entry);
|
||||||
|
+ ulong first = min, last;
|
||||||
|
+ int i;
|
||||||
|
+ int len = strlen(path);
|
||||||
|
+ struct tree_data *td = ops->is_td ? (struct tree_data *)ops->private : NULL;
|
||||||
|
+ char *ma64_buf;
|
||||||
|
+
|
||||||
|
+ if (SIZE(maple_node) > MAPLE_BUFSIZE)
|
||||||
|
+ error(FATAL, "MAPLE_BUFSIZE should be larger than maple_node struct");
|
||||||
|
+
|
||||||
|
+ readmem(maple_node_m_node, KVADDR, node_buf, SIZE(maple_node),
|
||||||
|
+ "mt_dump_arange64 read maple_node", FAULT_ON_ERROR);
|
||||||
|
+
|
||||||
|
+ ma64_buf = node_buf + OFFSET(maple_node_ma64);
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < mt_slots[maple_arange_64]; i++) {
|
||||||
|
+ last = max;
|
||||||
|
+
|
||||||
|
+ if (i < (mt_slots[maple_arange_64] - 1))
|
||||||
|
+ last = ULONG(ma64_buf + OFFSET(maple_arange_64_pivot) +
|
||||||
|
+ sizeof(ulong) * i);
|
||||||
|
+ else if (!VOID_PTR(ma64_buf + OFFSET(maple_arange_64_slot) +
|
||||||
|
+ sizeof(void *) * i))
|
||||||
|
+ break;
|
||||||
|
+ if (last == 0 && i > 0)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ if (leaf)
|
||||||
|
+ do_mt_entry(mt_slot((void **)(ma64_buf +
|
||||||
|
+ OFFSET(maple_arange_64_slot)), i),
|
||||||
|
+ first, last, depth + 1, i, path, global_index, ops);
|
||||||
|
+ else if (VOID_PTR(ma64_buf + OFFSET(maple_arange_64_slot) +
|
||||||
|
+ sizeof(void *) * i)) {
|
||||||
|
+ sprintf(path + len, "/%d", i);
|
||||||
|
+ do_mt_node(mt_slot((void **)(ma64_buf +
|
||||||
|
+ OFFSET(maple_arange_64_slot)), i),
|
||||||
|
+ first, last, depth + 1, path, global_index, ops);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (last == max)
|
||||||
|
+ break;
|
||||||
|
+ if (last > max) {
|
||||||
|
+ fprintf(fp, "node %p last (%lu) > max (%lu) at pivot %d!\n",
|
||||||
|
+ ma64_buf, last, max, i);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ first = last + 1;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void do_mt_entry(ulong entry, ulong min, ulong max, uint depth,
|
||||||
|
+ uint index, char *path, ulong *global_index,
|
||||||
|
+ struct maple_tree_ops *ops)
|
||||||
|
+{
|
||||||
|
+ int print_radix = 0, i;
|
||||||
|
+ static struct req_entry **e = NULL;
|
||||||
|
+ struct tree_data *td = ops->is_td ? (struct tree_data *)ops->private : NULL;
|
||||||
|
+
|
||||||
|
+ if (!td)
|
||||||
|
+ return;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void do_mt_node(ulong entry, ulong min, ulong max,
|
||||||
|
+ uint depth, char *path, ulong *global_index,
|
||||||
|
+ struct maple_tree_ops *ops)
|
||||||
|
+{
|
||||||
|
+ ulong maple_node = mte_to_node(entry);
|
||||||
|
+ uint type = mte_node_type(entry);
|
||||||
|
+ uint i;
|
||||||
|
+ char node_buf[MAPLE_BUFSIZE];
|
||||||
|
+ struct tree_data *td = ops->is_td ? (struct tree_data *)ops->private : NULL;
|
||||||
|
+
|
||||||
|
+ if (SIZE(maple_node) > MAPLE_BUFSIZE)
|
||||||
|
+ error(FATAL, "MAPLE_BUFSIZE should be larger than maple_node struct");
|
||||||
|
+
|
||||||
|
+ readmem(maple_node, KVADDR, node_buf, SIZE(maple_node),
|
||||||
|
+ "mt_dump_node read maple_node", FAULT_ON_ERROR);
|
||||||
|
+
|
||||||
|
+ switch (type) {
|
||||||
|
+ case maple_dense:
|
||||||
|
+ for (i = 0; i < mt_slots[maple_dense]; i++) {
|
||||||
|
+ if (min + i > max)
|
||||||
|
+ fprintf(fp, "OUT OF RANGE: ");
|
||||||
|
+ do_mt_entry(mt_slot((void **)(node_buf + OFFSET(maple_node_slot)), i),
|
||||||
|
+ min + i, min + i, depth, i, path, global_index, ops);
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case maple_leaf_64:
|
||||||
|
+ case maple_range_64:
|
||||||
|
+ do_mt_range64(entry, min, max, depth, path, global_index, ops);
|
||||||
|
+ break;
|
||||||
|
+ case maple_arange_64:
|
||||||
|
+ do_mt_arange64(entry, min, max, depth, path, global_index, ops);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ fprintf(fp, " UNKNOWN TYPE\n");
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int do_maple_tree_traverse(ulong ptr, int is_root,
|
||||||
|
+ struct maple_tree_ops *ops)
|
||||||
|
+{
|
||||||
|
+ char path[BUFSIZE] = {0};
|
||||||
|
+ char tree_buf[MAPLE_BUFSIZE];
|
||||||
|
+ ulong entry;
|
||||||
|
+ struct tree_data *td = ops->is_td ? (struct tree_data *)ops->private : NULL;
|
||||||
|
+ ulong global_index = 0;
|
||||||
|
+
|
||||||
|
+ if (SIZE(maple_tree) > MAPLE_BUFSIZE)
|
||||||
|
+ error(FATAL, "MAPLE_BUFSIZE should be larger than maple_tree struct");
|
||||||
|
+
|
||||||
|
+ if (!is_root) {
|
||||||
|
+ strcpy(path, "direct");
|
||||||
|
+ do_mt_node(ptr, 0, mt_max[mte_node_type(ptr)],
|
||||||
|
+ 0, path, &global_index, ops);
|
||||||
|
+ } else {
|
||||||
|
+ readmem(ptr, KVADDR, tree_buf, SIZE(maple_tree),
|
||||||
|
+ "mt_dump read maple_tree", FAULT_ON_ERROR);
|
||||||
|
+ entry = ULONG(tree_buf + OFFSET(maple_tree_ma_root));
|
||||||
|
+
|
||||||
|
+ if (!xa_is_node(entry))
|
||||||
|
+ do_mt_entry(entry, 0, 0, 0, 0, path, &global_index, ops);
|
||||||
|
+ else if (entry) {
|
||||||
|
+ strcpy(path, "root");
|
||||||
|
+ do_mt_node(entry, 0, mt_max[mte_node_type(entry)], 0,
|
||||||
|
+ path, &global_index, ops);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int do_mptree(struct tree_data *td)
|
||||||
|
+{
|
||||||
|
+ struct maple_tree_ops ops = {
|
||||||
|
+ .entry = NULL,
|
||||||
|
+ .private = td,
|
||||||
|
+ .is_td = true,
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ int is_root = !(td->flags & TREE_NODE_POINTER);
|
||||||
|
+
|
||||||
|
+ do_maple_tree_traverse(td->start, is_root, &ops);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/***********************************************/
|
||||||
|
+void maple_init(void)
|
||||||
|
+{
|
||||||
|
+ int array_len;
|
||||||
|
+
|
||||||
|
+ STRUCT_SIZE_INIT(maple_tree, "maple_tree");
|
||||||
|
+ STRUCT_SIZE_INIT(maple_node, "maple_node");
|
||||||
|
+
|
||||||
|
+ MEMBER_OFFSET_INIT(maple_tree_ma_root, "maple_tree", "ma_root");
|
||||||
|
+ MEMBER_OFFSET_INIT(maple_tree_ma_flags, "maple_tree", "ma_flags");
|
||||||
|
+
|
||||||
|
+ MEMBER_OFFSET_INIT(maple_node_parent, "maple_node", "parent");
|
||||||
|
+ MEMBER_OFFSET_INIT(maple_node_ma64, "maple_node", "ma64");
|
||||||
|
+ MEMBER_OFFSET_INIT(maple_node_mr64, "maple_node", "mr64");
|
||||||
|
+ MEMBER_OFFSET_INIT(maple_node_slot, "maple_node", "slot");
|
||||||
|
+
|
||||||
|
+ MEMBER_OFFSET_INIT(maple_arange_64_pivot, "maple_arange_64", "pivot");
|
||||||
|
+ MEMBER_OFFSET_INIT(maple_arange_64_slot, "maple_arange_64", "slot");
|
||||||
|
+ MEMBER_OFFSET_INIT(maple_arange_64_gap, "maple_arange_64", "gap");
|
||||||
|
+ MEMBER_OFFSET_INIT(maple_arange_64_meta, "maple_arange_64", "meta");
|
||||||
|
+
|
||||||
|
+ MEMBER_OFFSET_INIT(maple_range_64_pivot, "maple_range_64", "pivot");
|
||||||
|
+ MEMBER_OFFSET_INIT(maple_range_64_slot, "maple_range_64", "slot");
|
||||||
|
+
|
||||||
|
+ MEMBER_OFFSET_INIT(maple_metadata_end, "maple_metadata", "end");
|
||||||
|
+ MEMBER_OFFSET_INIT(maple_metadata_gap, "maple_metadata", "gap");
|
||||||
|
+
|
||||||
|
+ array_len = get_array_length("mt_slots", NULL, sizeof(char));
|
||||||
|
+ mt_slots = calloc(array_len, sizeof(char));
|
||||||
|
+ readmem(symbol_value("mt_slots"), KVADDR, mt_slots,
|
||||||
|
+ array_len * sizeof(char), "maple_init read mt_slots",
|
||||||
|
+ RETURN_ON_ERROR);
|
||||||
|
+
|
||||||
|
+ array_len = get_array_length("mt_pivots", NULL, sizeof(char));
|
||||||
|
+ mt_pivots = calloc(array_len, sizeof(char));
|
||||||
|
+ readmem(symbol_value("mt_pivots"), KVADDR, mt_pivots,
|
||||||
|
+ array_len * sizeof(char), "maple_init read mt_pivots",
|
||||||
|
+ RETURN_ON_ERROR);
|
||||||
|
+
|
||||||
|
+ mt_max[maple_dense] = mt_slots[maple_dense];
|
||||||
|
+ mt_max[maple_leaf_64] = ULONG_MAX;
|
||||||
|
+ mt_max[maple_range_64] = ULONG_MAX;
|
||||||
|
+ mt_max[maple_arange_64] = ULONG_MAX;
|
||||||
|
+}
|
||||||
|
diff --git a/maple_tree.h b/maple_tree.h
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000000..f53d5aaffd2e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/maple_tree.h
|
||||||
|
@@ -0,0 +1,82 @@
|
||||||
|
+/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
|
+#ifndef _MAPLE_TREE_H
|
||||||
|
+#define _MAPLE_TREE_H
|
||||||
|
+/*
|
||||||
|
+ * Maple Tree - An RCU-safe adaptive tree for storing ranges
|
||||||
|
+ * Copyright (c) 2018-2022 Oracle
|
||||||
|
+ * Authors: Liam R. Howlett <Liam.Howlett@Oracle.com>
|
||||||
|
+ * Matthew Wilcox <willy@infradead.org>
|
||||||
|
+ *
|
||||||
|
+ * eXtensible Arrays
|
||||||
|
+ * Copyright (c) 2017 Microsoft Corporation
|
||||||
|
+ * Author: Matthew Wilcox <willy@infradead.org>
|
||||||
|
+ *
|
||||||
|
+ * See Documentation/core-api/xarray.rst for how to use the XArray.
|
||||||
|
+ */
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <limits.h>
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * The following are copied and modified from include/linux/maple_tree.h
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+enum maple_type {
|
||||||
|
+ maple_dense,
|
||||||
|
+ maple_leaf_64,
|
||||||
|
+ maple_range_64,
|
||||||
|
+ maple_arange_64,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#define MAPLE_NODE_MASK 255UL
|
||||||
|
+
|
||||||
|
+#define MT_FLAGS_HEIGHT_OFFSET 0x02
|
||||||
|
+#define MT_FLAGS_HEIGHT_MASK 0x7C
|
||||||
|
+
|
||||||
|
+#define MAPLE_NODE_TYPE_MASK 0x0F
|
||||||
|
+#define MAPLE_NODE_TYPE_SHIFT 0x03
|
||||||
|
+
|
||||||
|
+#define MAPLE_RESERVED_RANGE 4096
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * The following are copied and modified from include/linux/xarray.h
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#define XA_ZERO_ENTRY xa_mk_internal(257)
|
||||||
|
+
|
||||||
|
+static inline ulong xa_mk_internal(ulong v)
|
||||||
|
+{
|
||||||
|
+ return (v << 2) | 2;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool xa_is_internal(ulong entry)
|
||||||
|
+{
|
||||||
|
+ return (entry & 3) == 2;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool xa_is_node(ulong entry)
|
||||||
|
+{
|
||||||
|
+ return xa_is_internal(entry) && entry > 4096;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool xa_is_value(ulong entry)
|
||||||
|
+{
|
||||||
|
+ return entry & 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool xa_is_zero(ulong entry)
|
||||||
|
+{
|
||||||
|
+ return entry == XA_ZERO_ENTRY;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline unsigned long xa_to_internal(ulong entry)
|
||||||
|
+{
|
||||||
|
+ return entry >> 2;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline unsigned long xa_to_value(ulong entry)
|
||||||
|
+{
|
||||||
|
+ return entry >> 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif /* _MAPLE_TREE_H */
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
335
SOURCES/0066-Add-maple-tree-support-to-tree-command.patch
Normal file
335
SOURCES/0066-Add-maple-tree-support-to-tree-command.patch
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
From 4a6aba5dc85a2f491f752fb37dd2838c1141375d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tao Liu <ltao@redhat.com>
|
||||||
|
Date: Tue, 10 Jan 2023 14:56:28 +0800
|
||||||
|
Subject: [PATCH 66/89] Add maple tree support to "tree" command
|
||||||
|
|
||||||
|
The maple tree is a new data structure for crash, so "tree" command
|
||||||
|
needs to support it for users to dump and view the content of maple
|
||||||
|
trees. This patch achieves this by using ported mt_dump() and its
|
||||||
|
related functions from kernel and adapting them with "tree" command.
|
||||||
|
|
||||||
|
Also introduce a new -v arg specifically for dumping the complete
|
||||||
|
content of a maple tree:
|
||||||
|
|
||||||
|
crash> tree -t maple 0xffff9034c006aec0 -v
|
||||||
|
|
||||||
|
maple_tree(ffff9034c006aec0) flags 309, height 2 root 0xffff9034de70041e
|
||||||
|
|
||||||
|
0-18446744073709551615: node 0xffff9034de700400 depth 0 type 3 parent 0xffff9034c006aec1 contents:...
|
||||||
|
0-140112331583487: node 0xffff9034c01e8800 depth 1 type 1 parent 0xffff9034de700406 contents:...
|
||||||
|
0-94643156942847: (nil)
|
||||||
|
94643156942848-94643158024191: 0xffff9035131754c0
|
||||||
|
94643158024192-94643160117247: (nil)
|
||||||
|
...
|
||||||
|
|
||||||
|
The existing options of "tree" command can work as well:
|
||||||
|
|
||||||
|
crash> tree -t maple -r mm_struct.mm_mt 0xffff9034c006aec0 -p
|
||||||
|
ffff9035131754c0
|
||||||
|
index: 1 position: root/0/1
|
||||||
|
ffff9035131751c8
|
||||||
|
index: 2 position: root/0/3
|
||||||
|
ffff9035131757b8
|
||||||
|
index: 3 position: root/0/4
|
||||||
|
...
|
||||||
|
|
||||||
|
crash> tree -t maple 0xffff9034c006aec0 -p -x -s vm_area_struct.vm_start,vm_end
|
||||||
|
ffff9035131754c0
|
||||||
|
index: 1 position: root/0/1
|
||||||
|
vm_start = 0x5613d3c00000,
|
||||||
|
vm_end = 0x5613d3d08000,
|
||||||
|
ffff9035131751c8
|
||||||
|
index: 2 position: root/0/3
|
||||||
|
vm_start = 0x5613d3f07000,
|
||||||
|
vm_end = 0x5613d3f0b000,
|
||||||
|
ffff9035131757b8
|
||||||
|
index: 3 position: root/0/4
|
||||||
|
vm_start = 0x5613d3f0b000,
|
||||||
|
vm_end = 0x5613d3f14000,
|
||||||
|
....
|
||||||
|
|
||||||
|
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
defs.h | 1 +
|
||||||
|
maple_tree.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
tools.c | 67 +++++++++++++++++++++++++++++++++++++++-------------
|
||||||
|
3 files changed, 114 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index 46ed10e17cd2..cc9af21a6b64 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -2713,6 +2713,7 @@ struct tree_data {
|
||||||
|
#define TREE_PARSE_MEMBER (VERBOSE << 7)
|
||||||
|
#define TREE_READ_MEMBER (VERBOSE << 8)
|
||||||
|
#define TREE_LINEAR_ORDER (VERBOSE << 9)
|
||||||
|
+#define TREE_STRUCT_VERBOSE (VERBOSE << 10)
|
||||||
|
|
||||||
|
#define ALIAS_RUNTIME (1)
|
||||||
|
#define ALIAS_RCLOCAL (2)
|
||||||
|
diff --git a/maple_tree.c b/maple_tree.c
|
||||||
|
index 474faeda6252..471136f3eb1d 100644
|
||||||
|
--- a/maple_tree.c
|
||||||
|
+++ b/maple_tree.c
|
||||||
|
@@ -173,6 +173,10 @@ static void do_mt_range64(ulong entry, ulong min, ulong max,
|
||||||
|
|
||||||
|
mr64_buf = node_buf + OFFSET(maple_node_mr64);
|
||||||
|
|
||||||
|
+ if (td && td->flags & TREE_STRUCT_VERBOSE) {
|
||||||
|
+ dump_mt_range64(mr64_buf);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
for (i = 0; i < mt_slots[maple_range_64]; i++) {
|
||||||
|
last = max;
|
||||||
|
|
||||||
|
@@ -230,6 +234,10 @@ static void do_mt_arange64(ulong entry, ulong min, ulong max,
|
||||||
|
|
||||||
|
ma64_buf = node_buf + OFFSET(maple_node_ma64);
|
||||||
|
|
||||||
|
+ if (td && td->flags & TREE_STRUCT_VERBOSE) {
|
||||||
|
+ dump_mt_arange64(ma64_buf);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
for (i = 0; i < mt_slots[maple_arange_64]; i++) {
|
||||||
|
last = max;
|
||||||
|
|
||||||
|
@@ -275,6 +283,51 @@ static void do_mt_entry(ulong entry, ulong min, ulong max, uint depth,
|
||||||
|
|
||||||
|
if (!td)
|
||||||
|
return;
|
||||||
|
+
|
||||||
|
+ if (!td->count && td->structname_args) {
|
||||||
|
+ /*
|
||||||
|
+ * Retrieve all members' info only once (count == 0)
|
||||||
|
+ * After last iteration all memory will be freed up
|
||||||
|
+ */
|
||||||
|
+ e = (struct req_entry **)GETBUF(sizeof(*e) * td->structname_args);
|
||||||
|
+ for (i = 0; i < td->structname_args; i++)
|
||||||
|
+ e[i] = fill_member_offsets(td->structname[i]);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ td->count++;
|
||||||
|
+
|
||||||
|
+ if (td->flags & TREE_STRUCT_VERBOSE) {
|
||||||
|
+ dump_mt_entry(entry, min, max, depth);
|
||||||
|
+ } else if (td->flags & VERBOSE && entry)
|
||||||
|
+ fprintf(fp, "%lx\n", entry);
|
||||||
|
+ if (td->flags & TREE_POSITION_DISPLAY && entry)
|
||||||
|
+ fprintf(fp, " index: %ld position: %s/%u\n",
|
||||||
|
+ ++(*global_index), path, index);
|
||||||
|
+
|
||||||
|
+ if (td->structname) {
|
||||||
|
+ if (td->flags & TREE_STRUCT_RADIX_10)
|
||||||
|
+ print_radix = 10;
|
||||||
|
+ else if (td->flags & TREE_STRUCT_RADIX_16)
|
||||||
|
+ print_radix = 16;
|
||||||
|
+ else
|
||||||
|
+ print_radix = 0;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < td->structname_args; i++) {
|
||||||
|
+ switch (count_chars(td->structname[i], '.')) {
|
||||||
|
+ case 0:
|
||||||
|
+ dump_struct(td->structname[i], entry, print_radix);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ if (td->flags & TREE_PARSE_MEMBER)
|
||||||
|
+ dump_struct_members_for_tree(td, i, entry);
|
||||||
|
+ else if (td->flags & TREE_READ_MEMBER)
|
||||||
|
+ dump_struct_members_fast(e[i], print_radix, entry);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (e)
|
||||||
|
+ FREEBUF(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_mt_node(ulong entry, ulong min, ulong max,
|
||||||
|
@@ -293,6 +346,10 @@ static void do_mt_node(ulong entry, ulong min, ulong max,
|
||||||
|
readmem(maple_node, KVADDR, node_buf, SIZE(maple_node),
|
||||||
|
"mt_dump_node read maple_node", FAULT_ON_ERROR);
|
||||||
|
|
||||||
|
+ if (td && td->flags & TREE_STRUCT_VERBOSE) {
|
||||||
|
+ dump_mt_node(maple_node, node_buf, type, min, max, depth);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
switch (type) {
|
||||||
|
case maple_dense:
|
||||||
|
for (i = 0; i < mt_slots[maple_dense]; i++) {
|
||||||
|
@@ -335,6 +392,12 @@ static int do_maple_tree_traverse(ulong ptr, int is_root,
|
||||||
|
"mt_dump read maple_tree", FAULT_ON_ERROR);
|
||||||
|
entry = ULONG(tree_buf + OFFSET(maple_tree_ma_root));
|
||||||
|
|
||||||
|
+ if (td && td->flags & TREE_STRUCT_VERBOSE) {
|
||||||
|
+ fprintf(fp, "maple_tree(%lx) flags %X, height %u root 0x%lx\n\n",
|
||||||
|
+ ptr, UINT(tree_buf + OFFSET(maple_tree_ma_flags)),
|
||||||
|
+ mt_height(tree_buf), entry);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!xa_is_node(entry))
|
||||||
|
do_mt_entry(entry, 0, 0, 0, 0, path, &global_index, ops);
|
||||||
|
else if (entry) {
|
||||||
|
diff --git a/tools.c b/tools.c
|
||||||
|
index 7f64bd6328cf..cc5c3448b93e 100644
|
||||||
|
--- a/tools.c
|
||||||
|
+++ b/tools.c
|
||||||
|
@@ -30,7 +30,7 @@ static void dealloc_hq_entry(struct hq_entry *);
|
||||||
|
static void show_options(void);
|
||||||
|
static void dump_struct_members(struct list_data *, int, ulong);
|
||||||
|
static void rbtree_iteration(ulong, struct tree_data *, char *);
|
||||||
|
-static void dump_struct_members_for_tree(struct tree_data *, int, ulong);
|
||||||
|
+void dump_struct_members_for_tree(struct tree_data *, int, ulong);
|
||||||
|
|
||||||
|
struct req_entry {
|
||||||
|
char *arg, *name, **member;
|
||||||
|
@@ -40,8 +40,8 @@ struct req_entry {
|
||||||
|
};
|
||||||
|
|
||||||
|
static void print_value(struct req_entry *, unsigned int, ulong, unsigned int);
|
||||||
|
-static struct req_entry *fill_member_offsets(char *);
|
||||||
|
-static void dump_struct_members_fast(struct req_entry *, int, ulong);
|
||||||
|
+struct req_entry *fill_member_offsets(char *);
|
||||||
|
+void dump_struct_members_fast(struct req_entry *, int, ulong);
|
||||||
|
|
||||||
|
FILE *
|
||||||
|
set_error(char *target)
|
||||||
|
@@ -3666,7 +3666,7 @@ dump_struct_members_fast(struct req_entry *e, int radix, ulong p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static struct req_entry *
|
||||||
|
+struct req_entry *
|
||||||
|
fill_member_offsets(char *arg)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
@@ -4307,6 +4307,7 @@ dump_struct_members(struct list_data *ld, int idx, ulong next)
|
||||||
|
#define RADIXTREE_REQUEST (0x1)
|
||||||
|
#define RBTREE_REQUEST (0x2)
|
||||||
|
#define XARRAY_REQUEST (0x4)
|
||||||
|
+#define MAPLE_REQUEST (0x8)
|
||||||
|
|
||||||
|
void
|
||||||
|
cmd_tree()
|
||||||
|
@@ -4317,6 +4318,7 @@ cmd_tree()
|
||||||
|
struct datatype_member struct_member, *sm;
|
||||||
|
struct syment *sp;
|
||||||
|
ulong value;
|
||||||
|
+ char *type_name = NULL;
|
||||||
|
|
||||||
|
type_flag = 0;
|
||||||
|
root_offset = 0;
|
||||||
|
@@ -4324,25 +4326,33 @@ cmd_tree()
|
||||||
|
td = &tree_data;
|
||||||
|
BZERO(td, sizeof(struct tree_data));
|
||||||
|
|
||||||
|
- while ((c = getopt(argcnt, args, "xdt:r:o:s:S:plN")) != EOF) {
|
||||||
|
+ while ((c = getopt(argcnt, args, "xdt:r:o:s:S:plNv")) != EOF) {
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 't':
|
||||||
|
- if (type_flag & (RADIXTREE_REQUEST|RBTREE_REQUEST|XARRAY_REQUEST)) {
|
||||||
|
+ if (type_flag & (RADIXTREE_REQUEST|RBTREE_REQUEST|XARRAY_REQUEST|MAPLE_REQUEST)) {
|
||||||
|
error(INFO, "multiple tree types may not be entered\n");
|
||||||
|
cmd_usage(pc->curcmd, SYNOPSIS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (STRNEQ(optarg, "ra"))
|
||||||
|
- if (MEMBER_EXISTS("radix_tree_root", "xa_head"))
|
||||||
|
+ if (MEMBER_EXISTS("radix_tree_root", "xa_head")) {
|
||||||
|
type_flag = XARRAY_REQUEST;
|
||||||
|
- else
|
||||||
|
+ type_name = "Xarrays";
|
||||||
|
+ } else {
|
||||||
|
type_flag = RADIXTREE_REQUEST;
|
||||||
|
- else if (STRNEQ(optarg, "rb"))
|
||||||
|
+ type_name = "radix trees";
|
||||||
|
+ }
|
||||||
|
+ else if (STRNEQ(optarg, "rb")) {
|
||||||
|
type_flag = RBTREE_REQUEST;
|
||||||
|
- else if (STRNEQ(optarg, "x"))
|
||||||
|
+ type_name = "rbtrees";
|
||||||
|
+ } else if (STRNEQ(optarg, "x")) {
|
||||||
|
type_flag = XARRAY_REQUEST;
|
||||||
|
- else {
|
||||||
|
+ type_name = "Xarrays";
|
||||||
|
+ } else if (STRNEQ(optarg, "m")) {
|
||||||
|
+ type_flag = MAPLE_REQUEST;
|
||||||
|
+ type_name = "maple trees";
|
||||||
|
+ } else {
|
||||||
|
error(INFO, "invalid tree type: %s\n", optarg);
|
||||||
|
cmd_usage(pc->curcmd, SYNOPSIS);
|
||||||
|
}
|
||||||
|
@@ -4417,6 +4427,9 @@ cmd_tree()
|
||||||
|
"-d and -x are mutually exclusive\n");
|
||||||
|
td->flags |= TREE_STRUCT_RADIX_10;
|
||||||
|
break;
|
||||||
|
+ case 'v':
|
||||||
|
+ td->flags |= TREE_STRUCT_VERBOSE;
|
||||||
|
+ break;
|
||||||
|
default:
|
||||||
|
argerrs++;
|
||||||
|
break;
|
||||||
|
@@ -4426,13 +4439,17 @@ cmd_tree()
|
||||||
|
if (argerrs)
|
||||||
|
cmd_usage(pc->curcmd, SYNOPSIS);
|
||||||
|
|
||||||
|
- if ((type_flag & (XARRAY_REQUEST|RADIXTREE_REQUEST)) && (td->flags & TREE_LINEAR_ORDER))
|
||||||
|
- error(FATAL, "-l option is not applicable to %s\n",
|
||||||
|
- type_flag & RADIXTREE_REQUEST ? "radix trees" : "Xarrays");
|
||||||
|
+ if ((type_flag & (XARRAY_REQUEST|RADIXTREE_REQUEST|MAPLE_REQUEST)) &&
|
||||||
|
+ (td->flags & TREE_LINEAR_ORDER))
|
||||||
|
+ error(FATAL, "-l option is not applicable to %s\n", type_name);
|
||||||
|
|
||||||
|
- if ((type_flag & (XARRAY_REQUEST|RADIXTREE_REQUEST)) && (td->flags & TREE_NODE_OFFSET_ENTERED))
|
||||||
|
- error(FATAL, "-o option is not applicable to %s\n",
|
||||||
|
- type_flag & RADIXTREE_REQUEST ? "radix trees" : "Xarrays");
|
||||||
|
+ if ((type_flag & (XARRAY_REQUEST|RADIXTREE_REQUEST|MAPLE_REQUEST)) &&
|
||||||
|
+ (td->flags & TREE_NODE_OFFSET_ENTERED))
|
||||||
|
+ error(FATAL, "-o option is not applicable to %s\n", type_name);
|
||||||
|
+
|
||||||
|
+ if ((type_flag & (RBTREE_REQUEST|XARRAY_REQUEST|RADIXTREE_REQUEST)) &&
|
||||||
|
+ (td->flags & TREE_STRUCT_VERBOSE))
|
||||||
|
+ error(FATAL, "-v option is not applicable to %s\n", type_name);
|
||||||
|
|
||||||
|
if ((td->flags & TREE_ROOT_OFFSET_ENTERED) &&
|
||||||
|
(td->flags & TREE_NODE_POINTER))
|
||||||
|
@@ -4506,12 +4523,26 @@ next_arg:
|
||||||
|
if (td->flags & TREE_STRUCT_RADIX_16)
|
||||||
|
fprintf(fp, "%sTREE_STRUCT_RADIX_16",
|
||||||
|
others++ ? "|" : "");
|
||||||
|
+ if (td->flags & TREE_PARSE_MEMBER)
|
||||||
|
+ fprintf(fp, "%sTREE_PARSE_MEMBER",
|
||||||
|
+ others++ ? "|" : "");
|
||||||
|
+ if (td->flags & TREE_READ_MEMBER)
|
||||||
|
+ fprintf(fp, "%sTREE_READ_MEMBER",
|
||||||
|
+ others++ ? "|" : "");
|
||||||
|
+ if (td->flags & TREE_LINEAR_ORDER)
|
||||||
|
+ fprintf(fp, "%sTREE_LINEAR_ORDER",
|
||||||
|
+ others++ ? "|" : "");
|
||||||
|
+ if (td->flags & TREE_STRUCT_VERBOSE)
|
||||||
|
+ fprintf(fp, "%sTREE_STRUCT_VERBOSE",
|
||||||
|
+ others++ ? "|" : "");
|
||||||
|
fprintf(fp, ")\n");
|
||||||
|
fprintf(fp, " type: ");
|
||||||
|
if (type_flag & RADIXTREE_REQUEST)
|
||||||
|
fprintf(fp, "radix\n");
|
||||||
|
else if (type_flag & XARRAY_REQUEST)
|
||||||
|
fprintf(fp, "xarray\n");
|
||||||
|
+ else if (type_flag & MAPLE_REQUEST)
|
||||||
|
+ fprintf(fp, "maple\n");
|
||||||
|
else
|
||||||
|
fprintf(fp, "red-black%s",
|
||||||
|
type_flag & RBTREE_REQUEST ?
|
||||||
|
@@ -4532,6 +4563,8 @@ next_arg:
|
||||||
|
do_rdtree(td);
|
||||||
|
else if (type_flag & XARRAY_REQUEST)
|
||||||
|
do_xatree(td);
|
||||||
|
+ else if (type_flag & MAPLE_REQUEST)
|
||||||
|
+ do_mptree(td);
|
||||||
|
else
|
||||||
|
do_rbtree(td);
|
||||||
|
hq_close();
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
205
SOURCES/0067-Add-do_maple_tree-for-maple-tree-operations.patch
Normal file
205
SOURCES/0067-Add-do_maple_tree-for-maple-tree-operations.patch
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
From 7955002f1292f0c0d02076440b441ab7ebaf650d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tao Liu <ltao@redhat.com>
|
||||||
|
Date: Tue, 10 Jan 2023 14:56:29 +0800
|
||||||
|
Subject: [PATCH 67/89] Add do_maple_tree() for maple tree operations
|
||||||
|
|
||||||
|
do_maple_tree() is similar to do_radix_tree() and do_xarray(), which
|
||||||
|
takes the same do_maple_tree_traverse entry as tree command.
|
||||||
|
|
||||||
|
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
defs.h | 6 +++
|
||||||
|
maple_tree.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 151 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index cc9af21a6b64..b2389cd82fae 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -5750,6 +5750,12 @@ int cleanup_memory_driver(void);
|
||||||
|
|
||||||
|
void maple_init(void);
|
||||||
|
int do_mptree(struct tree_data *);
|
||||||
|
+ulong do_maple_tree(ulong, int, struct list_pair *);
|
||||||
|
+#define MAPLE_TREE_COUNT (1)
|
||||||
|
+#define MAPLE_TREE_SEARCH (2)
|
||||||
|
+#define MAPLE_TREE_DUMP (3)
|
||||||
|
+#define MAPLE_TREE_GATHER (4)
|
||||||
|
+#define MAPLE_TREE_DUMP_CB (5)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* help.c
|
||||||
|
diff --git a/maple_tree.c b/maple_tree.c
|
||||||
|
index 471136f3eb1d..807c17f7dfa0 100644
|
||||||
|
--- a/maple_tree.c
|
||||||
|
+++ b/maple_tree.c
|
||||||
|
@@ -40,6 +40,12 @@ static inline bool ma_is_leaf(const enum maple_type type)
|
||||||
|
|
||||||
|
/*************** For cmd_tree ********************/
|
||||||
|
|
||||||
|
+struct do_maple_tree_info {
|
||||||
|
+ ulong maxcount;
|
||||||
|
+ ulong count;
|
||||||
|
+ void *data;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct maple_tree_ops {
|
||||||
|
void (*entry)(ulong node, ulong slot, const char *path,
|
||||||
|
ulong index, void *private);
|
||||||
|
@@ -281,6 +287,9 @@ static void do_mt_entry(ulong entry, ulong min, ulong max, uint depth,
|
||||||
|
static struct req_entry **e = NULL;
|
||||||
|
struct tree_data *td = ops->is_td ? (struct tree_data *)ops->private : NULL;
|
||||||
|
|
||||||
|
+ if (ops->entry)
|
||||||
|
+ ops->entry(entry, entry, path, max, ops->private);
|
||||||
|
+
|
||||||
|
if (!td)
|
||||||
|
return;
|
||||||
|
|
||||||
|
@@ -424,6 +433,142 @@ int do_mptree(struct tree_data *td)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/************* For do_maple_tree *****************/
|
||||||
|
+static void do_maple_tree_count(ulong node, ulong slot, const char *path,
|
||||||
|
+ ulong index, void *private)
|
||||||
|
+{
|
||||||
|
+ struct do_maple_tree_info *info = private;
|
||||||
|
+ info->count++;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void do_maple_tree_search(ulong node, ulong slot, const char *path,
|
||||||
|
+ ulong index, void *private)
|
||||||
|
+{
|
||||||
|
+ struct do_maple_tree_info *info = private;
|
||||||
|
+ struct list_pair *lp = info->data;
|
||||||
|
+
|
||||||
|
+ if (lp->index == index) {
|
||||||
|
+ lp->value = (void *)slot;
|
||||||
|
+ info->count = 1;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void do_maple_tree_dump(ulong node, ulong slot, const char *path,
|
||||||
|
+ ulong index, void *private)
|
||||||
|
+{
|
||||||
|
+ struct do_maple_tree_info *info = private;
|
||||||
|
+ fprintf(fp, "[%lu] %lx\n", index, slot);
|
||||||
|
+ info->count++;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void do_maple_tree_gather(ulong node, ulong slot, const char *path,
|
||||||
|
+ ulong index, void *private)
|
||||||
|
+{
|
||||||
|
+ struct do_maple_tree_info *info = private;
|
||||||
|
+ struct list_pair *lp = info->data;
|
||||||
|
+
|
||||||
|
+ if (info->maxcount) {
|
||||||
|
+ lp[info->count].index = index;
|
||||||
|
+ lp[info->count].value = (void *)slot;
|
||||||
|
+
|
||||||
|
+ info->count++;
|
||||||
|
+ info->maxcount--;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void do_maple_tree_dump_cb(ulong node, ulong slot, const char *path,
|
||||||
|
+ ulong index, void *private)
|
||||||
|
+{
|
||||||
|
+ struct do_maple_tree_info *info = private;
|
||||||
|
+ struct list_pair *lp = info->data;
|
||||||
|
+ int (*cb)(ulong) = lp->value;
|
||||||
|
+
|
||||||
|
+ /* Caller defined operation */
|
||||||
|
+ if (!cb(slot)) {
|
||||||
|
+ error(FATAL, "do_maple_tree: callback "
|
||||||
|
+ "operation failed: entry: %ld item: %lx\n",
|
||||||
|
+ info->count, slot);
|
||||||
|
+ }
|
||||||
|
+ info->count++;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * do_maple_tree argument usage:
|
||||||
|
+ *
|
||||||
|
+ * root: Address of a maple_tree_root structure
|
||||||
|
+ *
|
||||||
|
+ * flag: MAPLE_TREE_COUNT - Return the number of entries in the tree.
|
||||||
|
+ * MAPLE_TREE_SEARCH - Search for an entry at lp->index; if found,
|
||||||
|
+ * store the entry in lp->value and return a count of 1; otherwise
|
||||||
|
+ * return a count of 0.
|
||||||
|
+ * MAPLE_TREE_DUMP - Dump all existing index/value pairs.
|
||||||
|
+ * MAPLE_TREE_GATHER - Store all existing index/value pairs in the
|
||||||
|
+ * passed-in array of list_pair structs starting at lp,
|
||||||
|
+ * returning the count of entries stored; the caller can/should
|
||||||
|
+ * limit the number of returned entries by putting the array size
|
||||||
|
+ * (max count) in the lp->index field of the first structure
|
||||||
|
+ * in the passed-in array.
|
||||||
|
+ * MAPLE_TREE_DUMP_CB - Similar with MAPLE_TREE_DUMP, but for each
|
||||||
|
+ * maple tree entry, a user defined callback at lp->value will
|
||||||
|
+ * be invoked.
|
||||||
|
+ *
|
||||||
|
+ * lp: Unused by MAPLE_TREE_COUNT and MAPLE_TREE_DUMP.
|
||||||
|
+ * A pointer to a list_pair structure for MAPLE_TREE_SEARCH.
|
||||||
|
+ * A pointer to an array of list_pair structures for
|
||||||
|
+ * MAPLE_TREE_GATHER; the dimension (max count) of the array may
|
||||||
|
+ * be stored in the index field of the first structure to avoid
|
||||||
|
+ * any chance of an overrun.
|
||||||
|
+ * For MAPLE_TREE_DUMP_CB, the lp->value must be initialized as a
|
||||||
|
+ * callback function. The callback prototype must be: int (*)(ulong);
|
||||||
|
+ */
|
||||||
|
+ulong
|
||||||
|
+do_maple_tree(ulong root, int flag, struct list_pair *lp)
|
||||||
|
+{
|
||||||
|
+ struct do_maple_tree_info info = {
|
||||||
|
+ .count = 0,
|
||||||
|
+ .data = lp,
|
||||||
|
+ };
|
||||||
|
+ struct maple_tree_ops ops = {
|
||||||
|
+ .private = &info,
|
||||||
|
+ .is_td = false,
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ switch (flag)
|
||||||
|
+ {
|
||||||
|
+ case MAPLE_TREE_COUNT:
|
||||||
|
+ ops.entry = do_maple_tree_count;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case MAPLE_TREE_SEARCH:
|
||||||
|
+ ops.entry = do_maple_tree_search;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case MAPLE_TREE_DUMP:
|
||||||
|
+ ops.entry = do_maple_tree_dump;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case MAPLE_TREE_GATHER:
|
||||||
|
+ if (!(info.maxcount = lp->index))
|
||||||
|
+ info.maxcount = (ulong)(-1); /* caller beware */
|
||||||
|
+
|
||||||
|
+ ops.entry = do_maple_tree_gather;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case MAPLE_TREE_DUMP_CB:
|
||||||
|
+ if (lp->value == NULL) {
|
||||||
|
+ error(FATAL, "do_maple_tree: need set callback function");
|
||||||
|
+ }
|
||||||
|
+ ops.entry = do_maple_tree_dump_cb;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ default:
|
||||||
|
+ error(FATAL, "do_maple_tree: invalid flag: %lx\n", flag);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ do_maple_tree_traverse(root, true, &ops);
|
||||||
|
+ return info.count;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/***********************************************/
|
||||||
|
void maple_init(void)
|
||||||
|
{
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,455 @@
|
|||||||
|
From 77e9fc571e2782b0eafe1d376cfd7f30fb08fecf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tao Liu <ltao@redhat.com>
|
||||||
|
Date: Tue, 10 Jan 2023 14:56:30 +0800
|
||||||
|
Subject: [PATCH 68/89] Introduce maple tree vma iteration to vm_area_dump()
|
||||||
|
|
||||||
|
Since memory.c:vm_area_dump() will iterate all vma, this patch mainly
|
||||||
|
introduces maple tree vma iteration to it.
|
||||||
|
|
||||||
|
We extract the code which handles each vma into a function. If
|
||||||
|
mm_struct_mmap exist, aka the linked list of vma iteration available,
|
||||||
|
we goto the original way; if not and mm_struct_mm_mt exist, aka
|
||||||
|
maple tree is available, then we goto the maple tree vma iteration.
|
||||||
|
|
||||||
|
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
Makefile | 2 +-
|
||||||
|
memory.c | 321 +++++++++++++++++++++++++++++++++----------------------
|
||||||
|
2 files changed, 193 insertions(+), 130 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index b290836ffc83..2af4dd0ae904 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -364,7 +364,7 @@ filesys.o: ${GENERIC_HFILES} filesys.c
|
||||||
|
help.o: ${GENERIC_HFILES} help.c
|
||||||
|
${CC} -c ${CRASH_CFLAGS} help.c ${WARNING_OPTIONS} ${WARNING_ERROR}
|
||||||
|
|
||||||
|
-memory.o: ${GENERIC_HFILES} memory.c
|
||||||
|
+memory.o: ${GENERIC_HFILES} ${MAPLE_TREE_HFILES} memory.c
|
||||||
|
${CC} -c ${CRASH_CFLAGS} memory.c ${WARNING_OPTIONS} ${WARNING_ERROR}
|
||||||
|
|
||||||
|
test.o: ${GENERIC_HFILES} test.c
|
||||||
|
diff --git a/memory.c b/memory.c
|
||||||
|
index 156de2f7b5a3..5141fbea4b40 100644
|
||||||
|
--- a/memory.c
|
||||||
|
+++ b/memory.c
|
||||||
|
@@ -21,6 +21,7 @@
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <byteswap.h>
|
||||||
|
+#include "maple_tree.h"
|
||||||
|
|
||||||
|
struct meminfo { /* general purpose memory information structure */
|
||||||
|
ulong cache; /* used by the various memory searching/dumping */
|
||||||
|
@@ -137,6 +138,27 @@ struct searchinfo {
|
||||||
|
char buf[BUFSIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
+struct handle_each_vm_area_args {
|
||||||
|
+ ulong task;
|
||||||
|
+ ulong flag;
|
||||||
|
+ ulong vaddr;
|
||||||
|
+ struct reference *ref;
|
||||||
|
+ char *vma_header;
|
||||||
|
+ char *buf1;
|
||||||
|
+ char *buf2;
|
||||||
|
+ char *buf3;
|
||||||
|
+ char *buf4;
|
||||||
|
+ char *buf5;
|
||||||
|
+ ulong vma;
|
||||||
|
+ char **vma_buf;
|
||||||
|
+ struct task_mem_usage *tm;
|
||||||
|
+ int *found;
|
||||||
|
+ int *single_vma_found;
|
||||||
|
+ unsigned int radix;
|
||||||
|
+ struct task_context *tc;
|
||||||
|
+ ulong *single_vma;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static char *memtype_string(int, int);
|
||||||
|
static char *error_handle_string(ulong);
|
||||||
|
static void collect_page_member_data(char *, struct meminfo *);
|
||||||
|
@@ -299,6 +321,7 @@ static void dump_page_flags(ulonglong);
|
||||||
|
static ulong kmem_cache_nodelists(ulong);
|
||||||
|
static void dump_hstates(void);
|
||||||
|
static ulong freelist_ptr(struct meminfo *, ulong, ulong);
|
||||||
|
+static ulong handle_each_vm_area(struct handle_each_vm_area_args *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Memory display modes specific to this file.
|
||||||
|
@@ -363,6 +386,10 @@ vm_init(void)
|
||||||
|
|
||||||
|
MEMBER_OFFSET_INIT(task_struct_mm, "task_struct", "mm");
|
||||||
|
MEMBER_OFFSET_INIT(mm_struct_mmap, "mm_struct", "mmap");
|
||||||
|
+ MEMBER_OFFSET_INIT(mm_struct_mm_mt, "mm_struct", "mm_mt");
|
||||||
|
+ if (VALID_MEMBER(mm_struct_mm_mt)) {
|
||||||
|
+ maple_init();
|
||||||
|
+ }
|
||||||
|
MEMBER_OFFSET_INIT(mm_struct_pgd, "mm_struct", "pgd");
|
||||||
|
MEMBER_OFFSET_INIT(mm_struct_rss, "mm_struct", "rss");
|
||||||
|
if (!VALID_MEMBER(mm_struct_rss))
|
||||||
|
@@ -3874,7 +3901,7 @@ bailout:
|
||||||
|
* for references -- and only then does a display
|
||||||
|
*/
|
||||||
|
|
||||||
|
-#define PRINT_VM_DATA() \
|
||||||
|
+#define PRINT_VM_DATA(buf4, buf5, tm) \
|
||||||
|
{ \
|
||||||
|
fprintf(fp, "%s %s ", \
|
||||||
|
mkstring(buf4, VADDR_PRLEN, CENTER|LJUST, "MM"), \
|
||||||
|
@@ -3896,9 +3923,9 @@ bailout:
|
||||||
|
mkstring(buf5, 8, CENTER|LJUST, NULL)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define PRINT_VMA_DATA() \
|
||||||
|
+#define PRINT_VMA_DATA(buf1, buf2, buf3, buf4, vma) \
|
||||||
|
fprintf(fp, "%s%s%s%s%s %6llx%s%s\n", \
|
||||||
|
- mkstring(buf4, VADDR_PRLEN, CENTER|LJUST|LONG_HEX, MKSTR(vma)), \
|
||||||
|
+ mkstring(buf4, VADDR_PRLEN, CENTER|LJUST|LONG_HEX, MKSTR(vma)),\
|
||||||
|
space(MINSPACE), \
|
||||||
|
mkstring(buf2, UVADDR_PRLEN, RJUST|LONG_HEX, MKSTR(vm_start)), \
|
||||||
|
space(MINSPACE), \
|
||||||
|
@@ -3925,18 +3952,137 @@ bailout:
|
||||||
|
(DO_REF_SEARCH(X) && (string_exists(S)) && FILENAME_COMPONENT((S),(X)->str))
|
||||||
|
#define VM_REF_FOUND(X) ((X) && ((X)->cmdflags & VM_REF_HEADER))
|
||||||
|
|
||||||
|
-ulong
|
||||||
|
-vm_area_dump(ulong task, ulong flag, ulong vaddr, struct reference *ref)
|
||||||
|
+static ulong handle_each_vm_area(struct handle_each_vm_area_args *args)
|
||||||
|
{
|
||||||
|
- struct task_context *tc;
|
||||||
|
- ulong vma;
|
||||||
|
+ char *dentry_buf, *file_buf;
|
||||||
|
ulong vm_start;
|
||||||
|
ulong vm_end;
|
||||||
|
- ulong vm_next, vm_mm;
|
||||||
|
- char *dentry_buf, *vma_buf, *file_buf;
|
||||||
|
+ ulong vm_mm;
|
||||||
|
ulonglong vm_flags;
|
||||||
|
ulong vm_file, inode;
|
||||||
|
ulong dentry, vfsmnt;
|
||||||
|
+
|
||||||
|
+ if ((args->flag & PHYSADDR) && !DO_REF_SEARCH(args->ref))
|
||||||
|
+ fprintf(fp, "%s", args->vma_header);
|
||||||
|
+
|
||||||
|
+ inode = 0;
|
||||||
|
+ BZERO(args->buf1, BUFSIZE);
|
||||||
|
+ *(args->vma_buf) = fill_vma_cache(args->vma);
|
||||||
|
+
|
||||||
|
+ vm_mm = ULONG(*(args->vma_buf) + OFFSET(vm_area_struct_vm_mm));
|
||||||
|
+ vm_end = ULONG(*(args->vma_buf) + OFFSET(vm_area_struct_vm_end));
|
||||||
|
+ vm_start = ULONG(*(args->vma_buf) + OFFSET(vm_area_struct_vm_start));
|
||||||
|
+ vm_flags = get_vm_flags(*(args->vma_buf));
|
||||||
|
+ vm_file = ULONG(*(args->vma_buf) + OFFSET(vm_area_struct_vm_file));
|
||||||
|
+
|
||||||
|
+ if (args->flag & PRINT_SINGLE_VMA) {
|
||||||
|
+ if (args->vma != *(args->single_vma))
|
||||||
|
+ return 0;
|
||||||
|
+ fprintf(fp, "%s", args->vma_header);
|
||||||
|
+ *(args->single_vma_found) = TRUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (args->flag & PRINT_VMA_STRUCTS) {
|
||||||
|
+ dump_struct("vm_area_struct", args->vma, args->radix);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (vm_file && !(args->flag & VERIFY_ADDR)) {
|
||||||
|
+ file_buf = fill_file_cache(vm_file);
|
||||||
|
+ dentry = ULONG(file_buf + OFFSET(file_f_dentry));
|
||||||
|
+ dentry_buf = NULL;
|
||||||
|
+ if (dentry) {
|
||||||
|
+ dentry_buf = fill_dentry_cache(dentry);
|
||||||
|
+ if (VALID_MEMBER(file_f_vfsmnt)) {
|
||||||
|
+ vfsmnt = ULONG(file_buf + OFFSET(file_f_vfsmnt));
|
||||||
|
+ get_pathname(dentry, args->buf1, BUFSIZE, 1, vfsmnt);
|
||||||
|
+ } else
|
||||||
|
+ get_pathname(dentry, args->buf1, BUFSIZE, 1, 0);
|
||||||
|
+ }
|
||||||
|
+ if ((args->flag & PRINT_INODES) && dentry)
|
||||||
|
+ inode = ULONG(dentry_buf + OFFSET(dentry_d_inode));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!(args->flag & UVADDR) || ((args->flag & UVADDR) &&
|
||||||
|
+ ((args->vaddr >= vm_start) && (args->vaddr < vm_end)))) {
|
||||||
|
+ *(args->found) = TRUE;
|
||||||
|
+
|
||||||
|
+ if (args->flag & VERIFY_ADDR)
|
||||||
|
+ return args->vma;
|
||||||
|
+
|
||||||
|
+ if (DO_REF_SEARCH(args->ref)) {
|
||||||
|
+ if (VM_REF_CHECK_HEXVAL(args->ref, args->vma) ||
|
||||||
|
+ VM_REF_CHECK_HEXVAL(args->ref, (ulong)vm_flags) ||
|
||||||
|
+ VM_REF_CHECK_STRING(args->ref, args->buf1)) {
|
||||||
|
+ if (!(args->ref->cmdflags & VM_REF_HEADER)) {
|
||||||
|
+ print_task_header(fp, args->tc, 0);
|
||||||
|
+ PRINT_VM_DATA(args->buf4, args->buf5, args->tm);
|
||||||
|
+ args->ref->cmdflags |= VM_REF_HEADER;
|
||||||
|
+ }
|
||||||
|
+ if (!(args->ref->cmdflags & VM_REF_VMA) ||
|
||||||
|
+ (args->ref->cmdflags & VM_REF_PAGE)) {
|
||||||
|
+ fprintf(fp, "%s", args->vma_header);
|
||||||
|
+ args->ref->cmdflags |= VM_REF_VMA;
|
||||||
|
+ args->ref->cmdflags &= ~VM_REF_PAGE;
|
||||||
|
+ args->ref->ref1 = args->vma;
|
||||||
|
+ }
|
||||||
|
+ PRINT_VMA_DATA(args->buf1, args->buf2,
|
||||||
|
+ args->buf3, args->buf4, args->vma);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (vm_area_page_dump(args->vma, args->task,
|
||||||
|
+ vm_start, vm_end, vm_mm, args->ref)) {
|
||||||
|
+ if (!(args->ref->cmdflags & VM_REF_HEADER)) {
|
||||||
|
+ print_task_header(fp, args->tc, 0);
|
||||||
|
+ PRINT_VM_DATA(args->buf4, args->buf5, args->tm);
|
||||||
|
+ args->ref->cmdflags |= VM_REF_HEADER;
|
||||||
|
+ }
|
||||||
|
+ if (!(args->ref->cmdflags & VM_REF_VMA) ||
|
||||||
|
+ (args->ref->ref1 != args->vma)) {
|
||||||
|
+ fprintf(fp, "%s", args->vma_header);
|
||||||
|
+ PRINT_VMA_DATA(args->buf1, args->buf2,
|
||||||
|
+ args->buf3, args->buf4, args->vma);
|
||||||
|
+ args->ref->cmdflags |= VM_REF_VMA;
|
||||||
|
+ args->ref->ref1 = args->vma;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ args->ref->cmdflags |= VM_REF_DISPLAY;
|
||||||
|
+ vm_area_page_dump(args->vma, args->task,
|
||||||
|
+ vm_start, vm_end, vm_mm, args->ref);
|
||||||
|
+ args->ref->cmdflags &= ~VM_REF_DISPLAY;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (inode) {
|
||||||
|
+ fprintf(fp, "%lx%s%s%s%s%s%6llx%s%lx %s\n",
|
||||||
|
+ args->vma, space(MINSPACE),
|
||||||
|
+ mkstring(args->buf2, UVADDR_PRLEN, RJUST|LONG_HEX,
|
||||||
|
+ MKSTR(vm_start)), space(MINSPACE),
|
||||||
|
+ mkstring(args->buf3, UVADDR_PRLEN, RJUST|LONG_HEX,
|
||||||
|
+ MKSTR(vm_end)), space(MINSPACE),
|
||||||
|
+ vm_flags, space(MINSPACE), inode, args->buf1);
|
||||||
|
+ } else {
|
||||||
|
+ PRINT_VMA_DATA(args->buf1, args->buf2,
|
||||||
|
+ args->buf3, args->buf4, args->vma);
|
||||||
|
+
|
||||||
|
+ if (args->flag & (PHYSADDR|PRINT_SINGLE_VMA))
|
||||||
|
+ vm_area_page_dump(args->vma, args->task,
|
||||||
|
+ vm_start, vm_end, vm_mm, args->ref);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (args->flag & UVADDR)
|
||||||
|
+ return args->vma;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+ulong
|
||||||
|
+vm_area_dump(ulong task, ulong flag, ulong vaddr, struct reference *ref)
|
||||||
|
+{
|
||||||
|
+ struct task_context *tc;
|
||||||
|
+ ulong vma;
|
||||||
|
ulong single_vma;
|
||||||
|
unsigned int radix;
|
||||||
|
int single_vma_found;
|
||||||
|
@@ -3948,6 +4094,10 @@ vm_area_dump(ulong task, ulong flag, ulong vaddr, struct reference *ref)
|
||||||
|
char buf4[BUFSIZE];
|
||||||
|
char buf5[BUFSIZE];
|
||||||
|
char vma_header[BUFSIZE];
|
||||||
|
+ char *vma_buf;
|
||||||
|
+ int i;
|
||||||
|
+ ulong mm_mt, entry_num;
|
||||||
|
+ struct list_pair *entry_list;
|
||||||
|
|
||||||
|
tc = task_to_context(task);
|
||||||
|
tm = &task_mem_usage;
|
||||||
|
@@ -3981,14 +4131,14 @@ vm_area_dump(ulong task, ulong flag, ulong vaddr, struct reference *ref)
|
||||||
|
if (VM_REF_CHECK_HEXVAL(ref, tm->mm_struct_addr) ||
|
||||||
|
VM_REF_CHECK_HEXVAL(ref, tm->pgd_addr)) {
|
||||||
|
print_task_header(fp, tc, 0);
|
||||||
|
- PRINT_VM_DATA();
|
||||||
|
+ PRINT_VM_DATA(buf4, buf5, tm);
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
return (ulong)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(flag & (UVADDR|PRINT_MM_STRUCT|PRINT_VMA_STRUCTS|PRINT_SINGLE_VMA)) &&
|
||||||
|
!DO_REF_SEARCH(ref))
|
||||||
|
- PRINT_VM_DATA();
|
||||||
|
+ PRINT_VM_DATA(buf4, buf5, tm);
|
||||||
|
|
||||||
|
if (!tm->mm_struct_addr) {
|
||||||
|
if (pc->curcmd_flags & MM_STRUCT_FORCE) {
|
||||||
|
@@ -4012,9 +4162,6 @@ vm_area_dump(ulong task, ulong flag, ulong vaddr, struct reference *ref)
|
||||||
|
return (ulong)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- readmem(tm->mm_struct_addr + OFFSET(mm_struct_mmap), KVADDR,
|
||||||
|
- &vma, sizeof(void *), "mm_struct mmap", FAULT_ON_ERROR);
|
||||||
|
-
|
||||||
|
sprintf(vma_header, "%s%s%s%s%s FLAGS%sFILE\n",
|
||||||
|
mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "VMA"),
|
||||||
|
space(MINSPACE),
|
||||||
|
@@ -4027,125 +4174,41 @@ vm_area_dump(ulong task, ulong flag, ulong vaddr, struct reference *ref)
|
||||||
|
!DO_REF_SEARCH(ref))
|
||||||
|
fprintf(fp, "%s", vma_header);
|
||||||
|
|
||||||
|
- for (found = FALSE; vma; vma = vm_next) {
|
||||||
|
-
|
||||||
|
- if ((flag & PHYSADDR) && !DO_REF_SEARCH(ref))
|
||||||
|
- fprintf(fp, "%s", vma_header);
|
||||||
|
-
|
||||||
|
- inode = 0;
|
||||||
|
- BZERO(buf1, BUFSIZE);
|
||||||
|
- vma_buf = fill_vma_cache(vma);
|
||||||
|
-
|
||||||
|
- vm_mm = ULONG(vma_buf + OFFSET(vm_area_struct_vm_mm));
|
||||||
|
- vm_end = ULONG(vma_buf + OFFSET(vm_area_struct_vm_end));
|
||||||
|
- vm_next = ULONG(vma_buf + OFFSET(vm_area_struct_vm_next));
|
||||||
|
- vm_start = ULONG(vma_buf + OFFSET(vm_area_struct_vm_start));
|
||||||
|
- vm_flags = get_vm_flags(vma_buf);
|
||||||
|
- vm_file = ULONG(vma_buf + OFFSET(vm_area_struct_vm_file));
|
||||||
|
-
|
||||||
|
- if (flag & PRINT_SINGLE_VMA) {
|
||||||
|
- if (vma != single_vma)
|
||||||
|
- continue;
|
||||||
|
- fprintf(fp, "%s", vma_header);
|
||||||
|
- single_vma_found = TRUE;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (flag & PRINT_VMA_STRUCTS) {
|
||||||
|
- dump_struct("vm_area_struct", vma, radix);
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
+ found = FALSE;
|
||||||
|
|
||||||
|
- if (vm_file && !(flag & VERIFY_ADDR)) {
|
||||||
|
- file_buf = fill_file_cache(vm_file);
|
||||||
|
- dentry = ULONG(file_buf + OFFSET(file_f_dentry));
|
||||||
|
- dentry_buf = NULL;
|
||||||
|
- if (dentry) {
|
||||||
|
- dentry_buf = fill_dentry_cache(dentry);
|
||||||
|
- if (VALID_MEMBER(file_f_vfsmnt)) {
|
||||||
|
- vfsmnt = ULONG(file_buf +
|
||||||
|
- OFFSET(file_f_vfsmnt));
|
||||||
|
- get_pathname(dentry, buf1, BUFSIZE,
|
||||||
|
- 1, vfsmnt);
|
||||||
|
- } else {
|
||||||
|
- get_pathname(dentry, buf1, BUFSIZE,
|
||||||
|
- 1, 0);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- if ((flag & PRINT_INODES) && dentry) {
|
||||||
|
- inode = ULONG(dentry_buf +
|
||||||
|
- OFFSET(dentry_d_inode));
|
||||||
|
+ struct handle_each_vm_area_args args = {
|
||||||
|
+ .task = task, .flag = flag, .vaddr = vaddr,
|
||||||
|
+ .ref = ref, .tc = tc, .radix = radix,
|
||||||
|
+ .tm = tm, .buf1 = buf1, .buf2 = buf2,
|
||||||
|
+ .buf3 = buf3, .buf4 = buf4, .buf5 = buf5,
|
||||||
|
+ .vma_header = vma_header, .single_vma = &single_vma,
|
||||||
|
+ .single_vma_found = &single_vma_found, .found = &found,
|
||||||
|
+ .vma_buf = &vma_buf,
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ if (INVALID_MEMBER(mm_struct_mmap) && VALID_MEMBER(mm_struct_mm_mt)) {
|
||||||
|
+ mm_mt = tm->mm_struct_addr + OFFSET(mm_struct_mm_mt);
|
||||||
|
+ entry_num = do_maple_tree(mm_mt, MAPLE_TREE_COUNT, NULL);
|
||||||
|
+ entry_list = (struct list_pair *)GETBUF(entry_num * sizeof(struct list_pair));
|
||||||
|
+ do_maple_tree(mm_mt, MAPLE_TREE_GATHER, entry_list);
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < entry_num; i++) {
|
||||||
|
+ if (!!(args.vma = (ulong)entry_list[i].value) &&
|
||||||
|
+ handle_each_vm_area(&args)) {
|
||||||
|
+ FREEBUF(entry_list);
|
||||||
|
+ return args.vma;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- if (!(flag & UVADDR) || ((flag & UVADDR) &&
|
||||||
|
- ((vaddr >= vm_start) && (vaddr < vm_end)))) {
|
||||||
|
- found = TRUE;
|
||||||
|
-
|
||||||
|
- if (flag & VERIFY_ADDR)
|
||||||
|
- return vma;
|
||||||
|
-
|
||||||
|
- if (DO_REF_SEARCH(ref)) {
|
||||||
|
- if (VM_REF_CHECK_HEXVAL(ref, vma) ||
|
||||||
|
- VM_REF_CHECK_HEXVAL(ref, (ulong)vm_flags) ||
|
||||||
|
- VM_REF_CHECK_STRING(ref, buf1)) {
|
||||||
|
- if (!(ref->cmdflags & VM_REF_HEADER)) {
|
||||||
|
- print_task_header(fp, tc, 0);
|
||||||
|
- PRINT_VM_DATA();
|
||||||
|
- ref->cmdflags |= VM_REF_HEADER;
|
||||||
|
- }
|
||||||
|
- if (!(ref->cmdflags & VM_REF_VMA) ||
|
||||||
|
- (ref->cmdflags & VM_REF_PAGE)) {
|
||||||
|
- fprintf(fp, "%s", vma_header);
|
||||||
|
- ref->cmdflags |= VM_REF_VMA;
|
||||||
|
- ref->cmdflags &= ~VM_REF_PAGE;
|
||||||
|
- ref->ref1 = vma;
|
||||||
|
- }
|
||||||
|
- PRINT_VMA_DATA();
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (vm_area_page_dump(vma, task,
|
||||||
|
- vm_start, vm_end, vm_mm, ref)) {
|
||||||
|
- if (!(ref->cmdflags & VM_REF_HEADER)) {
|
||||||
|
- print_task_header(fp, tc, 0);
|
||||||
|
- PRINT_VM_DATA();
|
||||||
|
- ref->cmdflags |= VM_REF_HEADER;
|
||||||
|
- }
|
||||||
|
- if (!(ref->cmdflags & VM_REF_VMA) ||
|
||||||
|
- (ref->ref1 != vma)) {
|
||||||
|
- fprintf(fp, "%s", vma_header);
|
||||||
|
- PRINT_VMA_DATA();
|
||||||
|
- ref->cmdflags |= VM_REF_VMA;
|
||||||
|
- ref->ref1 = vma;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ref->cmdflags |= VM_REF_DISPLAY;
|
||||||
|
- vm_area_page_dump(vma, task,
|
||||||
|
- vm_start, vm_end, vm_mm, ref);
|
||||||
|
- ref->cmdflags &= ~VM_REF_DISPLAY;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (inode) {
|
||||||
|
- fprintf(fp, "%lx%s%s%s%s%s%6llx%s%lx %s\n",
|
||||||
|
- vma, space(MINSPACE),
|
||||||
|
- mkstring(buf2, UVADDR_PRLEN, RJUST|LONG_HEX,
|
||||||
|
- MKSTR(vm_start)), space(MINSPACE),
|
||||||
|
- mkstring(buf3, UVADDR_PRLEN, RJUST|LONG_HEX,
|
||||||
|
- MKSTR(vm_end)), space(MINSPACE),
|
||||||
|
- vm_flags, space(MINSPACE), inode, buf1);
|
||||||
|
- } else {
|
||||||
|
- PRINT_VMA_DATA();
|
||||||
|
-
|
||||||
|
- if (flag & (PHYSADDR|PRINT_SINGLE_VMA))
|
||||||
|
- vm_area_page_dump(vma, task,
|
||||||
|
- vm_start, vm_end, vm_mm, ref);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (flag & UVADDR)
|
||||||
|
+ FREEBUF(entry_list);
|
||||||
|
+ } else {
|
||||||
|
+ readmem(tm->mm_struct_addr + OFFSET(mm_struct_mmap), KVADDR,
|
||||||
|
+ &vma, sizeof(void *), "mm_struct mmap", FAULT_ON_ERROR);
|
||||||
|
+ while (vma) {
|
||||||
|
+ args.vma = vma;
|
||||||
|
+ if (handle_each_vm_area(&args))
|
||||||
|
return vma;
|
||||||
|
- }
|
||||||
|
+ vma = ULONG(vma_buf + OFFSET(vm_area_struct_vm_next));
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag & VERIFY_ADDR)
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,135 @@
|
|||||||
|
From a3dbd5c455992baf6bfc196b9059a2b485823b83 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tao Liu <ltao@redhat.com>
|
||||||
|
Date: Tue, 10 Jan 2023 14:56:31 +0800
|
||||||
|
Subject: [PATCH 69/89] Update the help text of "tree" command for maple tree
|
||||||
|
|
||||||
|
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
help.c | 86 +++++++++++++++++++++++++++++++++++++++++++---------------
|
||||||
|
1 file changed, 64 insertions(+), 22 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/help.c b/help.c
|
||||||
|
index bfba43f6e9fd..7ceefa06732b 100644
|
||||||
|
--- a/help.c
|
||||||
|
+++ b/help.c
|
||||||
|
@@ -6313,19 +6313,20 @@ NULL
|
||||||
|
|
||||||
|
char *help_tree[] = {
|
||||||
|
"tree",
|
||||||
|
-"display radix tree, XArray or red-black tree",
|
||||||
|
-"[-t [radix|xarray|rbtree]] [-r offset] [-[s|S] struct[.member[,member]]]\n -[x|d] [-o offset] [-l] [-p] [-N] start",
|
||||||
|
-" This command dumps the contents of a radix tree, an XAarray, or a red-black",
|
||||||
|
-" tree. The arguments are as follows:\n",
|
||||||
|
+"display radix tree, XArray, red-black tree or maple tree",
|
||||||
|
+"[-t [radix|xarray|rbtree|maple]] [-r offset] [-[s|S] struct[.member[,member]]]\n"
|
||||||
|
+" -[x|d] [-o offset] [-l] [-p] [-v] [-N] start",
|
||||||
|
+" This command dumps the contents of a radix tree, an XAarray, a red-black",
|
||||||
|
+" tree, or a maple tree. The arguments are as follows:\n",
|
||||||
|
" -t type The type of tree to dump; the type string can be one of ",
|
||||||
|
-" \"radix\", \"rbtree\", or \"xarray\", or alternatively, \"ra\",",
|
||||||
|
-" \"rb\" or \"x\" are acceptable. If not specified, rbtree is the",
|
||||||
|
-" default type.",
|
||||||
|
+" \"radix\", \"rbtree\", \"xarray\", or \"maple\", or alternatively,",
|
||||||
|
+" \"ra\", \"rb\", \"x\" or \"m\" are acceptable. If not specified,",
|
||||||
|
+" rbtree is the default type.",
|
||||||
|
" -r offset If the \"start\" argument is the address of a data structure that",
|
||||||
|
-" contains an radix_tree_root, xarray or rb_root structure, then this",
|
||||||
|
-" is the offset to that structure member. If the offset is non-zero,",
|
||||||
|
-" then this option is required. The offset may be entered in either",
|
||||||
|
-" of two manners:",
|
||||||
|
+" contains an radix_tree_root, maple_tree, xarray or rb_root",
|
||||||
|
+" structure, then this is the offset to that structure member. If",
|
||||||
|
+" the offset is non-zero, then this option is required. The offset",
|
||||||
|
+" may be entered in either of two manners:",
|
||||||
|
" 1. In \"structure.member\" format.",
|
||||||
|
" 2. A number of bytes.",
|
||||||
|
" -o offset For red-black trees only, the offset of the rb_node within its ",
|
||||||
|
@@ -6354,25 +6355,26 @@ char *help_tree[] = {
|
||||||
|
" -p Display the node's position information, showing the relationship",
|
||||||
|
" between it and the root. For red-black trees, a position that",
|
||||||
|
" indicates \"root/l/r\" means that the node is the right child",
|
||||||
|
-" of the left child of the root node. For radix trees and xarrays,",
|
||||||
|
-" the index, the height, and the slot index values are shown with",
|
||||||
|
-" respect to the root.",
|
||||||
|
+" of the left child of the root node. For radix trees, xarrays and",
|
||||||
|
+" maple trees, the index, the height, and the slot index values are",
|
||||||
|
+" shown with respect to the root.",
|
||||||
|
" -x Override default output format with hexadecimal format.",
|
||||||
|
" -d Override default output format with decimal format.",
|
||||||
|
+" -v For maple trees only, dump the contents of each maple tree node.",
|
||||||
|
" ",
|
||||||
|
" The meaning of the \"start\" argument, which can be expressed either in",
|
||||||
|
" hexadecimal format or symbolically, depends upon whether the -N option",
|
||||||
|
" is prepended:",
|
||||||
|
" ",
|
||||||
|
-" start The address of a radix_tree_root, xarray or rb_root structure, or",
|
||||||
|
-" the address of a structure containing the radix_tree_root, xarray",
|
||||||
|
-" or rb_root structure; if the latter, then the \"-r offset\" option",
|
||||||
|
-" must be used if the member offset of the root structure is ",
|
||||||
|
-" non-zero.",
|
||||||
|
+" start The address of a radix_tree_root, maple_tree, xarray or rb_root",
|
||||||
|
+" structure, or the address of a structure containing the",
|
||||||
|
+" radix_tree_root, maple_tree, xarray or rb_root structure; if the",
|
||||||
|
+" latter, then the \"-r offset\" option must be used if the member",
|
||||||
|
+" offset of the root structure is non-zero.",
|
||||||
|
" ",
|
||||||
|
-" -N start The address of a radix_tree_node, xa_node or rb_node structure,",
|
||||||
|
-" bypassing the radix_tree_root, xarray, or rb_root that points",
|
||||||
|
-" to it.",
|
||||||
|
+" -N start The address of a radix_tree_node, maple_node, xa_node or rb_node",
|
||||||
|
+" structure, bypassing the radix_tree_root, maple_tree, xarray, or",
|
||||||
|
+" rb_root that points to it.",
|
||||||
|
"",
|
||||||
|
"\nEXAMPLES",
|
||||||
|
" The vmap_area_root is a standalone rb_root structure. Display the ",
|
||||||
|
@@ -6709,6 +6711,46 @@ char *help_tree[] = {
|
||||||
|
" _refcount = {",
|
||||||
|
" counter = 0x1",
|
||||||
|
" }",
|
||||||
|
+"",
|
||||||
|
+" The -v option is introduced specifically for dumping the complete content of",
|
||||||
|
+" maple tree:",
|
||||||
|
+"",
|
||||||
|
+" %s> tree -t maple 0xffff9034c006aec0 -v",
|
||||||
|
+"",
|
||||||
|
+" maple_tree(ffff9034c006aec0) flags 309, height 2 root 0xffff9034de70041e",
|
||||||
|
+"",
|
||||||
|
+" 0-18446744073709551615: node 0xffff9034de700400 depth 0 type 3 parent ...",
|
||||||
|
+" 0-140112331583487: node 0xffff9034c01e8800 depth 1 type 1 parent ...",
|
||||||
|
+" 0-94643156942847: 0x0",
|
||||||
|
+" 94643156942848-94643158024191: 0xffff9035131754c0",
|
||||||
|
+" 94643158024192-94643160117247: 0x0",
|
||||||
|
+" ...",
|
||||||
|
+"",
|
||||||
|
+" The existing options can work as well for maple tree:",
|
||||||
|
+"",
|
||||||
|
+" %s> tree -t maple -r mm_struct.mm_mt 0xffff9034c006aec0 -p",
|
||||||
|
+" ffff9035131754c0",
|
||||||
|
+" index: 1 position: root/0/1",
|
||||||
|
+" ffff9035131751c8",
|
||||||
|
+" index: 2 position: root/0/3",
|
||||||
|
+" ffff9035131757b8",
|
||||||
|
+" index: 3 position: root/0/4",
|
||||||
|
+" ...",
|
||||||
|
+"",
|
||||||
|
+" %s> tree -t maple 0xffff9034c006aec0 -p -x -s vm_area_struct.vm_start,vm_end",
|
||||||
|
+" ffff9035131754c0",
|
||||||
|
+" index: 1 position: root/0/1",
|
||||||
|
+" vm_start = 0x5613d3c00000,",
|
||||||
|
+" vm_end = 0x5613d3d08000,",
|
||||||
|
+" ffff9035131751c8",
|
||||||
|
+" index: 2 position: root/0/3",
|
||||||
|
+" vm_start = 0x5613d3f07000,",
|
||||||
|
+" vm_end = 0x5613d3f0b000,",
|
||||||
|
+" ffff9035131757b8",
|
||||||
|
+" index: 3 position: root/0/4",
|
||||||
|
+" vm_start = 0x5613d3f0b000,",
|
||||||
|
+" vm_end = 0x5613d3f14000,",
|
||||||
|
+" ....",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,52 @@
|
|||||||
|
From 198ce92c480baa71e3c70694b7049432f8a5a6ec Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tao Liu <ltao@redhat.com>
|
||||||
|
Date: Tue, 10 Jan 2023 14:56:32 +0800
|
||||||
|
Subject: [PATCH 70/89] Dump maple tree offset variables by "help -o"
|
||||||
|
|
||||||
|
In the previous patches, some variables are added to offset_table and
|
||||||
|
size_table, print them out with "help -o" command.
|
||||||
|
|
||||||
|
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
symbols.c | 17 +++++++++++++++++
|
||||||
|
1 file changed, 17 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/symbols.c b/symbols.c
|
||||||
|
index 9e6fca73eaf9..20bfac35c1f6 100644
|
||||||
|
--- a/symbols.c
|
||||||
|
+++ b/symbols.c
|
||||||
|
@@ -10778,6 +10778,21 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
|
OFFSET(sbq_wait_state_wait_cnt));
|
||||||
|
fprintf(fp, " sbq_wait_state_wait: %ld\n",
|
||||||
|
OFFSET(sbq_wait_state_wait));
|
||||||
|
+ fprintf(fp, " mm_struct_mm_mt: %ld\n", OFFSET(mm_struct_mm_mt));
|
||||||
|
+ fprintf(fp, " maple_tree_ma_root: %ld\n", OFFSET(maple_tree_ma_root));
|
||||||
|
+ fprintf(fp, " maple_tree_ma_flags: %ld\n", OFFSET(maple_tree_ma_flags));
|
||||||
|
+ fprintf(fp, " maple_node_parent: %ld\n", OFFSET(maple_node_parent));
|
||||||
|
+ fprintf(fp, " maple_node_ma64: %ld\n", OFFSET(maple_node_ma64));
|
||||||
|
+ fprintf(fp, " maple_node_mr64: %ld\n", OFFSET(maple_node_mr64));
|
||||||
|
+ fprintf(fp, " maple_node_slot: %ld\n", OFFSET(maple_node_slot));
|
||||||
|
+ fprintf(fp, " maple_arange_64_pivot: %ld\n", OFFSET(maple_arange_64_pivot));
|
||||||
|
+ fprintf(fp, " maple_arange_64_slot: %ld\n", OFFSET(maple_arange_64_slot));
|
||||||
|
+ fprintf(fp, " maple_arange_64_gap: %ld\n", OFFSET(maple_arange_64_gap));
|
||||||
|
+ fprintf(fp, " maple_arange_64_meta: %ld\n", OFFSET(maple_arange_64_meta));
|
||||||
|
+ fprintf(fp, " maple_range_64_pivot: %ld\n", OFFSET(maple_range_64_pivot));
|
||||||
|
+ fprintf(fp, " maple_range_64_slot: %ld\n", OFFSET(maple_range_64_slot));
|
||||||
|
+ fprintf(fp, " maple_metadata_end: %ld\n", OFFSET(maple_metadata_end));
|
||||||
|
+ fprintf(fp, " maple_metadata_gap: %ld\n", OFFSET(maple_metadata_gap));
|
||||||
|
|
||||||
|
fprintf(fp, "\n size_table:\n");
|
||||||
|
fprintf(fp, " page: %ld\n", SIZE(page));
|
||||||
|
@@ -11050,6 +11065,8 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
|
fprintf(fp, " sbitmap_queue: %ld\n", SIZE(sbitmap_queue));
|
||||||
|
fprintf(fp, " sbq_wait_state: %ld\n", SIZE(sbq_wait_state));
|
||||||
|
fprintf(fp, " blk_mq_tags: %ld\n", SIZE(blk_mq_tags));
|
||||||
|
+ fprintf(fp, " maple_tree: %ld\n", SIZE(maple_tree));
|
||||||
|
+ fprintf(fp, " maple_node: %ld\n", SIZE(maple_node));
|
||||||
|
|
||||||
|
fprintf(fp, " percpu_counter: %ld\n", SIZE(percpu_counter));
|
||||||
|
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,80 @@
|
|||||||
|
From a39b03603eba70d630121390f50abbc186bc8f56 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Date: Mon, 13 Feb 2023 11:12:12 +0800
|
||||||
|
Subject: [PATCH 71/89] Fix for "bt" command printing "bogus exception frame"
|
||||||
|
warning
|
||||||
|
|
||||||
|
Currently, the "bt" command may print a bogus exception frame
|
||||||
|
and the remaining frame will be truncated on x86_64 when using the
|
||||||
|
"virsh send-key <kvm guest> KEY_LEFTALT KEY_SYSRQ KEY_C" command
|
||||||
|
to trigger a panic from the KVM host. For example:
|
||||||
|
|
||||||
|
crash> bt
|
||||||
|
PID: 0 TASK: ffff9e7a47e32f00 CPU: 3 COMMAND: "swapper/3"
|
||||||
|
#0 [ffffba7900118bb8] machine_kexec at ffffffff87e5c2c7
|
||||||
|
#1 [ffffba7900118c08] __crash_kexec at ffffffff87f9500d
|
||||||
|
#2 [ffffba7900118cd0] panic at ffffffff87edfff9
|
||||||
|
#3 [ffffba7900118d50] sysrq_handle_crash at ffffffff883ce2c1
|
||||||
|
...
|
||||||
|
#16 [ffffba7900118fd8] handle_edge_irq at ffffffff87f559f2
|
||||||
|
#17 [ffffba7900118ff0] asm_call_on_stack at ffffffff88800fa2
|
||||||
|
--- <IRQ stack> ---
|
||||||
|
#18 [ffffba790008bda0] asm_call_on_stack at ffffffff88800fa2
|
||||||
|
RIP: ffffffffffffffff RSP: 0000000000000124 RFLAGS: 00000003
|
||||||
|
RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000000
|
||||||
|
RDX: ffffffff88800c1e RSI: 0000000000000000 RDI: 0000000000000000
|
||||||
|
RBP: 0000000000000001 R8: 0000000000000000 R9: 0000000000000000
|
||||||
|
R10: 0000000000000000 R11: ffffffff88760555 R12: ffffba790008be08
|
||||||
|
R13: ffffffff87f18002 R14: ffff9e7a47e32f00 R15: ffff9e7bb6198e00
|
||||||
|
ORIG_RAX: 0000000000000000 CS: 0003 SS: 0000
|
||||||
|
bt: WARNING: possibly bogus exception frame
|
||||||
|
crash>
|
||||||
|
|
||||||
|
The following related kernel commits cause the current issue, crash
|
||||||
|
needs to adjust the value of irq_eframe_link.
|
||||||
|
|
||||||
|
Related kernel commits:
|
||||||
|
[1] v5.8: 931b94145981 ("x86/entry: Provide helpers for executing on the irqstack")
|
||||||
|
[2] v5.8: fa5e5c409213 ("x86/entry: Use idtentry for interrupts")
|
||||||
|
[3] v5.12: 52d743f3b712 ("x86/softirq: Remove indirection in do_softirq_own_stack()")
|
||||||
|
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
---
|
||||||
|
x86_64.c | 13 +++++++++++++
|
||||||
|
1 file changed, 13 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/x86_64.c b/x86_64.c
|
||||||
|
index 1113a1055f77..27b1167ec630 100644
|
||||||
|
--- a/x86_64.c
|
||||||
|
+++ b/x86_64.c
|
||||||
|
@@ -3935,6 +3935,11 @@ in_exception_stack:
|
||||||
|
if (irq_eframe) {
|
||||||
|
bt->flags |= BT_EXCEPTION_FRAME;
|
||||||
|
i = (irq_eframe - bt->stackbase)/sizeof(ulong);
|
||||||
|
+ if (symbol_exists("asm_common_interrupt")) {
|
||||||
|
+ i -= 1;
|
||||||
|
+ up = (ulong *)(&bt->stackbuf[i*sizeof(ulong)]);
|
||||||
|
+ bt->instptr = *up;
|
||||||
|
+ }
|
||||||
|
x86_64_print_stack_entry(bt, ofp, level, i, bt->instptr);
|
||||||
|
bt->flags &= ~(ulonglong)BT_EXCEPTION_FRAME;
|
||||||
|
cs = x86_64_exception_frame(EFRAME_PRINT|EFRAME_CS, 0,
|
||||||
|
@@ -6513,6 +6518,14 @@ x86_64_irq_eframe_link_init(void)
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
+ if (symbol_exists("asm_common_interrupt")) {
|
||||||
|
+ if (symbol_exists("asm_call_on_stack"))
|
||||||
|
+ machdep->machspec->irq_eframe_link = -64;
|
||||||
|
+ else
|
||||||
|
+ machdep->machspec->irq_eframe_link = -32;
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (THIS_KERNEL_VERSION < LINUX(2,6,9))
|
||||||
|
return;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,144 @@
|
|||||||
|
From 3c9c16c545319958d7fa14ef5ab8934fc5449d83 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Aureau, Georges (Kernel Tools ERT)" <georges.aureau@hpe.com>
|
||||||
|
Date: Wed, 8 Feb 2023 12:09:03 +0000
|
||||||
|
Subject: [PATCH 72/89] Fix "kmem -s|-S" not working properly on RHEL8.6 and
|
||||||
|
later
|
||||||
|
|
||||||
|
For CONFIG_SLAB_FREELIST_HARDENED, the crash memory.c:freelist_ptr()
|
||||||
|
code is checking for an additional bswap using a simple release test eg.
|
||||||
|
THIS_KERNEL_VERSION >= LINUX(5,7,0), basically checking for RHEL9 and
|
||||||
|
beyond.
|
||||||
|
|
||||||
|
However, for RHEL8.6 and later, we have CONFIG_SLAB_FREELIST_HARDENED=y,
|
||||||
|
and we also have the additional bswap, but the current crash is not
|
||||||
|
handling this case, hence "kmem -s|-S" will not work properly, and free
|
||||||
|
objects will not be counted nor reported properly.
|
||||||
|
|
||||||
|
An example from a RHEL8.6 x86_64 kdump, a kmem cache with a single slab
|
||||||
|
having 42 objects, only the freelist head is seen as free as crash can't
|
||||||
|
walk freelist next pointers, and crash is wrongly reporting 41 allocated
|
||||||
|
objects:
|
||||||
|
|
||||||
|
crash> sys | grep RELEASE
|
||||||
|
RELEASE: 4.18.0-372.9.1.el8.x86_64
|
||||||
|
crash> kmem -s nfs_commit_data
|
||||||
|
CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
|
||||||
|
ffff9ad40c7cb2c0 728 41 42 1 32k nfs_commit_data
|
||||||
|
|
||||||
|
When properly accounting for the additional bswap, we can walk the
|
||||||
|
freelist and find 38 free objects, and crash is now reporting only 4
|
||||||
|
allocated objects:
|
||||||
|
|
||||||
|
crash> kmem -s nfs_commit_data
|
||||||
|
CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
|
||||||
|
ffff9ad40c7cb2c0 728 4 42 1 32k nfs_commit_data
|
||||||
|
|
||||||
|
Signed-off-by: Georges Aureau <georges.aureau@hpe.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
defs.h | 1 +
|
||||||
|
memory.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
2 files changed, 49 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index b2389cd82fae..ae5d1244e8b3 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -2638,6 +2638,7 @@ struct vm_table { /* kernel VM-related data */
|
||||||
|
#define SLAB_OVERLOAD_PAGE (0x8000000)
|
||||||
|
#define SLAB_CPU_CACHE (0x10000000)
|
||||||
|
#define SLAB_ROOT_CACHES (0x20000000)
|
||||||
|
+#define FREELIST_PTR_BSWAP (0x40000000)
|
||||||
|
|
||||||
|
#define IS_FLATMEM() (vt->flags & FLATMEM)
|
||||||
|
#define IS_DISCONTIGMEM() (vt->flags & DISCONTIGMEM)
|
||||||
|
diff --git a/memory.c b/memory.c
|
||||||
|
index 5141fbea4b40..e0742c1bd3a4 100644
|
||||||
|
--- a/memory.c
|
||||||
|
+++ b/memory.c
|
||||||
|
@@ -320,6 +320,7 @@ static void dump_per_cpu_offsets(void);
|
||||||
|
static void dump_page_flags(ulonglong);
|
||||||
|
static ulong kmem_cache_nodelists(ulong);
|
||||||
|
static void dump_hstates(void);
|
||||||
|
+static void freelist_ptr_init(void);
|
||||||
|
static ulong freelist_ptr(struct meminfo *, ulong, ulong);
|
||||||
|
static ulong handle_each_vm_area(struct handle_each_vm_area_args *);
|
||||||
|
|
||||||
|
@@ -789,6 +790,8 @@ vm_init(void)
|
||||||
|
MEMBER_OFFSET_INIT(kmem_cache_name, "kmem_cache", "name");
|
||||||
|
MEMBER_OFFSET_INIT(kmem_cache_flags, "kmem_cache", "flags");
|
||||||
|
MEMBER_OFFSET_INIT(kmem_cache_random, "kmem_cache", "random");
|
||||||
|
+ if (VALID_MEMBER(kmem_cache_random))
|
||||||
|
+ freelist_ptr_init();
|
||||||
|
MEMBER_OFFSET_INIT(kmem_cache_cpu_freelist, "kmem_cache_cpu", "freelist");
|
||||||
|
MEMBER_OFFSET_INIT(kmem_cache_cpu_page, "kmem_cache_cpu", "page");
|
||||||
|
if (INVALID_MEMBER(kmem_cache_cpu_page))
|
||||||
|
@@ -13932,6 +13935,8 @@ dump_vm_table(int verbose)
|
||||||
|
fprintf(fp, "%sSLAB_CPU_CACHE", others++ ? "|" : "");\
|
||||||
|
if (vt->flags & SLAB_ROOT_CACHES)
|
||||||
|
fprintf(fp, "%sSLAB_ROOT_CACHES", others++ ? "|" : "");\
|
||||||
|
+ if (vt->flags & FREELIST_PTR_BSWAP)
|
||||||
|
+ fprintf(fp, "%sFREELIST_PTR_BSWAP", others++ ? "|" : "");\
|
||||||
|
if (vt->flags & USE_VMAP_AREA)
|
||||||
|
fprintf(fp, "%sUSE_VMAP_AREA", others++ ? "|" : "");\
|
||||||
|
if (vt->flags & CONFIG_NUMA)
|
||||||
|
@@ -19519,13 +19524,55 @@ count_free_objects(struct meminfo *si, ulong freelist)
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * With CONFIG_SLAB_FREELIST_HARDENED, freelist_ptr's are crypted with xor's,
|
||||||
|
+ * and for recent release with an additionnal bswap. Some releases prio to 5.7.0
|
||||||
|
+ * may be using the additionnal bswap. The only easy and reliable way to tell is
|
||||||
|
+ * to inspect assembly code (eg. "__slab_free") for a bswap instruction.
|
||||||
|
+ */
|
||||||
|
+static int
|
||||||
|
+freelist_ptr_bswap_x86(void)
|
||||||
|
+{
|
||||||
|
+ char buf1[BUFSIZE];
|
||||||
|
+ char buf2[BUFSIZE];
|
||||||
|
+ char *arglist[MAXARGS];
|
||||||
|
+ int found;
|
||||||
|
+
|
||||||
|
+ sprintf(buf1, "disassemble __slab_free");
|
||||||
|
+ open_tmpfile();
|
||||||
|
+ if (!gdb_pass_through(buf1, pc->tmpfile, GNU_RETURN_ON_ERROR)) {
|
||||||
|
+ close_tmpfile();
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ rewind(pc->tmpfile);
|
||||||
|
+ found = FALSE;
|
||||||
|
+ while (fgets(buf2, BUFSIZE, pc->tmpfile)) {
|
||||||
|
+ if (parse_line(buf2, arglist) < 3)
|
||||||
|
+ continue;
|
||||||
|
+ if (STREQ(arglist[2], "bswap")) {
|
||||||
|
+ found = TRUE;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ close_tmpfile();
|
||||||
|
+ return found;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+freelist_ptr_init(void)
|
||||||
|
+{
|
||||||
|
+ if (THIS_KERNEL_VERSION >= LINUX(5,7,0) ||
|
||||||
|
+ ((machine_type("X86_64") || machine_type("X86")) && freelist_ptr_bswap_x86()))
|
||||||
|
+ vt->flags |= FREELIST_PTR_BSWAP;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static ulong
|
||||||
|
freelist_ptr(struct meminfo *si, ulong ptr, ulong ptr_addr)
|
||||||
|
{
|
||||||
|
if (VALID_MEMBER(kmem_cache_random)) {
|
||||||
|
/* CONFIG_SLAB_FREELIST_HARDENED */
|
||||||
|
|
||||||
|
- if (THIS_KERNEL_VERSION >= LINUX(5,7,0))
|
||||||
|
+ if (vt->flags & FREELIST_PTR_BSWAP)
|
||||||
|
ptr_addr = (sizeof(long) == 8) ? bswap_64(ptr_addr)
|
||||||
|
: bswap_32(ptr_addr);
|
||||||
|
return (ptr ^ si->random ^ ptr_addr);
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,106 @@
|
|||||||
|
From 49f689eda0bc3331beb70df17ac4990034460f2b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Date: Thu, 9 Feb 2023 20:15:46 +0800
|
||||||
|
Subject: [PATCH 73/89] Fix for "net -s" option to show IPv6 addresses on Linux
|
||||||
|
3.13 and later
|
||||||
|
|
||||||
|
Currently, the "net -s" option fails to show IPv6 addresses and ports
|
||||||
|
for the SOURCE-PORT and DESTINATION-PORT columns on Linux 3.13 and later
|
||||||
|
kernels, which have kernel commit efe4208f47f907 ("ipv6: make lookups
|
||||||
|
simpler and faster"). For example:
|
||||||
|
|
||||||
|
crash> net -s
|
||||||
|
PID: 305524 TASK: ffff9bc449895580 CPU: 6 COMMAND: "sshd"
|
||||||
|
FD SOCKET SOCK FAMILY:TYPE SOURCE-PORT DESTINATION-PORT
|
||||||
|
3 ffff9bc446e9a680 ffff9bc4455b5940 UNIX:DGRAM
|
||||||
|
4 ffff9bc446e9c600 ffff9bc3b2b24e00 INET6:STREAM
|
||||||
|
|
||||||
|
With the patch:
|
||||||
|
|
||||||
|
crash> net -s
|
||||||
|
PID: 305524 TASK: ffff9bc449895580 CPU: 6 COMMAND: "sshd"
|
||||||
|
FD SOCKET SOCK FAMILY:TYPE SOURCE-PORT DESTINATION-PORT
|
||||||
|
3 ffff9bc446e9a680 ffff9bc4455b5940 UNIX:DGRAM
|
||||||
|
4 ffff9bc446e9c600 ffff9bc3b2b24e00 INET6:STREAM xxxx:xx:x:xxxx:xxxx:xxxx:xxxx:xxxx-22 yyyy:yy:y:yyyy:yyyy:yyyy:yyyy:yyyy-44870
|
||||||
|
|
||||||
|
Reported-by: Buland Kumar Singh <bsingh@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
---
|
||||||
|
defs.h | 3 +++
|
||||||
|
net.c | 20 +++++++++++++++-----
|
||||||
|
symbols.c | 3 +++
|
||||||
|
3 files changed, 21 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index ae5d1244e8b3..801781749666 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -2204,6 +2204,9 @@ struct offset_table { /* stash of commonly-used offsets */
|
||||||
|
long maple_range_64_slot;
|
||||||
|
long maple_metadata_end;
|
||||||
|
long maple_metadata_gap;
|
||||||
|
+ long sock_sk_common;
|
||||||
|
+ long sock_common_skc_v6_daddr;
|
||||||
|
+ long sock_common_skc_v6_rcv_saddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct size_table { /* stash of commonly-used sizes */
|
||||||
|
diff --git a/net.c b/net.c
|
||||||
|
index 7c9c8bd9c98d..aa445ab7ee13 100644
|
||||||
|
--- a/net.c
|
||||||
|
+++ b/net.c
|
||||||
|
@@ -199,6 +199,9 @@ net_init(void)
|
||||||
|
MEMBER_OFFSET_INIT(sock_common_skc_family,
|
||||||
|
"sock_common", "skc_family");
|
||||||
|
MEMBER_OFFSET_INIT(sock_sk_type, "sock", "sk_type");
|
||||||
|
+ MEMBER_OFFSET_INIT(sock_sk_common, "sock", "__sk_common");
|
||||||
|
+ MEMBER_OFFSET_INIT(sock_common_skc_v6_daddr, "sock_common", "skc_v6_daddr");
|
||||||
|
+ MEMBER_OFFSET_INIT(sock_common_skc_v6_rcv_saddr, "sock_common", "skc_v6_rcv_saddr");
|
||||||
|
/*
|
||||||
|
* struct inet_sock {
|
||||||
|
* struct sock sk;
|
||||||
|
@@ -1104,12 +1107,19 @@ get_sock_info(ulong sock, char *buf)
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SOCK_V2:
|
||||||
|
- if (INVALID_MEMBER(ipv6_pinfo_rcv_saddr) ||
|
||||||
|
- INVALID_MEMBER(ipv6_pinfo_daddr))
|
||||||
|
+ if (VALID_MEMBER(ipv6_pinfo_rcv_saddr) &&
|
||||||
|
+ VALID_MEMBER(ipv6_pinfo_daddr)) {
|
||||||
|
+ ipv6_rcv_saddr = ipv6_pinfo + OFFSET(ipv6_pinfo_rcv_saddr);
|
||||||
|
+ ipv6_daddr = ipv6_pinfo + OFFSET(ipv6_pinfo_daddr);
|
||||||
|
+ } else if (VALID_MEMBER(sock_sk_common) &&
|
||||||
|
+ VALID_MEMBER(sock_common_skc_v6_daddr) &&
|
||||||
|
+ VALID_MEMBER(sock_common_skc_v6_rcv_saddr)) {
|
||||||
|
+ ipv6_rcv_saddr = sock + OFFSET(sock_sk_common) + OFFSET(sock_common_skc_v6_rcv_saddr);
|
||||||
|
+ ipv6_daddr = sock + OFFSET(sock_sk_common) + OFFSET(sock_common_skc_v6_daddr);
|
||||||
|
+ } else {
|
||||||
|
+ sprintf(&buf[strlen(buf)], "%s", "(cannot get IPv6 addresses)");
|
||||||
|
break;
|
||||||
|
-
|
||||||
|
- ipv6_rcv_saddr = ipv6_pinfo + OFFSET(ipv6_pinfo_rcv_saddr);
|
||||||
|
- ipv6_daddr = ipv6_pinfo + OFFSET(ipv6_pinfo_daddr);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (!readmem(ipv6_rcv_saddr, KVADDR, u6_addr16_src, SIZE(in6_addr),
|
||||||
|
"ipv6_rcv_saddr buffer", QUIET|RETURN_ON_ERROR))
|
||||||
|
diff --git a/symbols.c b/symbols.c
|
||||||
|
index 20bfac35c1f6..54115d753601 100644
|
||||||
|
--- a/symbols.c
|
||||||
|
+++ b/symbols.c
|
||||||
|
@@ -9830,8 +9830,11 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
|
|
||||||
|
fprintf(fp, " sock_sk_type: %ld\n",
|
||||||
|
OFFSET(sock_sk_type));
|
||||||
|
+ fprintf(fp, " sock_sk_common: %ld\n", OFFSET(sock_sk_common));
|
||||||
|
fprintf(fp, " sock_common_skc_family: %ld\n",
|
||||||
|
OFFSET(sock_common_skc_family));
|
||||||
|
+ fprintf(fp, " sock_common_skc_v6_daddr: %ld\n", OFFSET(sock_common_skc_v6_daddr));
|
||||||
|
+ fprintf(fp, " sock_common_skc_v6_rcv_saddr: %ld\n", OFFSET(sock_common_skc_v6_rcv_saddr));
|
||||||
|
fprintf(fp, " socket_alloc_vfs_inode: %ld\n",
|
||||||
|
OFFSET(socket_alloc_vfs_inode));
|
||||||
|
fprintf(fp, " inet_sock_inet: %ld\n",
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,56 @@
|
|||||||
|
From b13a2f3c2885bc638d1e413ef9e7c59a8ec8f81d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Date: Tue, 14 Feb 2023 22:37:08 +0800
|
||||||
|
Subject: [PATCH 74/89] Fix for "kmem -i" option to not print invalid values
|
||||||
|
for CACHED
|
||||||
|
|
||||||
|
The "kmem -i" option may output a bogus statistics for CACHED, which
|
||||||
|
might be observed when some extreme situations occur in kernel, such as
|
||||||
|
OOM, disk IO errors, etc.
|
||||||
|
|
||||||
|
The following result of calculation may be a negative value, refer to
|
||||||
|
the dump_kmeminfo():
|
||||||
|
page_cache_size = nr_file_pages - swapper_space_nrpages - buffer_pages;
|
||||||
|
|
||||||
|
As a result, the negative value will be converted to unsigned long
|
||||||
|
integer, eventually it overflows and is printed as big integers.
|
||||||
|
|
||||||
|
crash> kmem -i
|
||||||
|
PAGES TOTAL PERCENTAGE
|
||||||
|
TOTAL MEM 255314511 973.9 GB ----
|
||||||
|
FREE 533574 2 GB 0% of TOTAL MEM
|
||||||
|
USED 254780937 971.9 GB 99% of TOTAL MEM
|
||||||
|
SHARED 1713 6.7 MB 0% of TOTAL MEM
|
||||||
|
BUFFERS 374 1.5 MB 0% of TOTAL MEM
|
||||||
|
CACHED -114 70368744177664 GB 72251060080% of TOTAL MEM
|
||||||
|
^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^
|
||||||
|
...
|
||||||
|
|
||||||
|
Let's normalize it to zero with an info message to fix such cornor cases.
|
||||||
|
|
||||||
|
Reported-by: Buland Kumar Singh <bsingh@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
---
|
||||||
|
memory.c | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/memory.c b/memory.c
|
||||||
|
index e0742c1bd3a4..d9cd616f19de 100644
|
||||||
|
--- a/memory.c
|
||||||
|
+++ b/memory.c
|
||||||
|
@@ -8615,6 +8615,11 @@ dump_kmeminfo(void)
|
||||||
|
page_cache_size = 0;
|
||||||
|
|
||||||
|
|
||||||
|
+ if (page_cache_size < 0) {
|
||||||
|
+ error(INFO, "page_cache_size went negative (%ld), setting to 0\n",
|
||||||
|
+ page_cache_size);
|
||||||
|
+ page_cache_size = 0;
|
||||||
|
+ }
|
||||||
|
pct = (page_cache_size * 100)/totalram_pages;
|
||||||
|
fprintf(fp, "%13s %7ld %11s %3ld%% of TOTAL MEM\n",
|
||||||
|
"CACHED", page_cache_size,
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,78 @@
|
|||||||
|
From cce90e242f74ab81e411f2f65f5d5a9fb5022416 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Date: Wed, 15 Feb 2023 16:24:57 +0800
|
||||||
|
Subject: [PATCH 75/89] Fix for "bt" command unnecessarily printing an
|
||||||
|
exception frame
|
||||||
|
|
||||||
|
Kernel commit 7d65f4a65532 ("irq: Consolidate do_softirq() arch overriden
|
||||||
|
implementations") renamed the call_softirq to do_softirq_own_stack, and
|
||||||
|
there is no exception frame also when coming from do_softirq_own_stack.
|
||||||
|
Without the patch, crash may unnecessarily output an exception frame with
|
||||||
|
a warning as below:
|
||||||
|
|
||||||
|
crash> foreach bt
|
||||||
|
...
|
||||||
|
PID: 0 TASK: ffff914f820a8000 CPU: 25 COMMAND: "swapper/25"
|
||||||
|
#0 [fffffe0000504e48] crash_nmi_callback at ffffffffa665d763
|
||||||
|
#1 [fffffe0000504e50] nmi_handle at ffffffffa662a423
|
||||||
|
#2 [fffffe0000504ea8] default_do_nmi at ffffffffa6fe7dc9
|
||||||
|
#3 [fffffe0000504ec8] do_nmi at ffffffffa662a97f
|
||||||
|
#4 [fffffe0000504ef0] end_repeat_nmi at ffffffffa70015e8
|
||||||
|
[exception RIP: clone_endio+172]
|
||||||
|
RIP: ffffffffc005c1ec RSP: ffffa1d403d08e98 RFLAGS: 00000246
|
||||||
|
RAX: 0000000000000000 RBX: ffff915326fba230 RCX: 0000000000000018
|
||||||
|
RDX: ffffffffc0075400 RSI: 0000000000000000 RDI: ffff915326fba230
|
||||||
|
RBP: ffff915326fba1c0 R8: 0000000000001000 R9: ffff915308d6d2a0
|
||||||
|
R10: 000000a97dfe5e10 R11: ffffa1d40038fe98 R12: ffff915302babc40
|
||||||
|
R13: ffff914f94360000 R14: 0000000000000000 R15: 0000000000000000
|
||||||
|
ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
|
||||||
|
--- <NMI exception stack> ---
|
||||||
|
#5 [ffffa1d403d08e98] clone_endio at ffffffffc005c1ec [dm_mod]
|
||||||
|
#6 [ffffa1d403d08ed0] blk_update_request at ffffffffa6a96954
|
||||||
|
#7 [ffffa1d403d08f10] scsi_end_request at ffffffffa6c9b968
|
||||||
|
#8 [ffffa1d403d08f48] scsi_io_completion at ffffffffa6c9bb3e
|
||||||
|
#9 [ffffa1d403d08f90] blk_complete_reqs at ffffffffa6aa0e95
|
||||||
|
#10 [ffffa1d403d08fa0] __softirqentry_text_start at ffffffffa72000dc
|
||||||
|
#11 [ffffa1d403d08ff0] do_softirq_own_stack at ffffffffa7000f9a
|
||||||
|
--- <IRQ stack> ---
|
||||||
|
#12 [ffffa1d40038fe70] do_softirq_own_stack at ffffffffa7000f9a
|
||||||
|
[exception RIP: unknown or invalid address]
|
||||||
|
RIP: 0000000000000000 RSP: 0000000000000000 RFLAGS: 00000000
|
||||||
|
RAX: ffffffffa672eae5 RBX: ffffffffa83b34e0 RCX: ffffffffa672eb12
|
||||||
|
RDX: 0000000000000010 RSI: 8b7d6c8869010c00 RDI: 0000000000000085
|
||||||
|
RBP: 0000000000000286 R8: ffff914f820a8000 R9: ffffffffa67a94e0
|
||||||
|
R10: 0000000000000286 R11: ffffffffa66fb4c5 R12: ffffffffa67a898b
|
||||||
|
R13: 0000000000000000 R14: fffffffffffffff8 R15: ffffffffa67a1e68
|
||||||
|
ORIG_RAX: 0000000000000000 CS: 0000 SS: ffffffffa672edff
|
||||||
|
bt: WARNING: possibly bogus exception frame
|
||||||
|
#13 [ffffa1d40038ff30] start_secondary at ffffffffa665fa2c
|
||||||
|
#14 [ffffa1d40038ff50] secondary_startup_64_no_verify at ffffffffa6600116
|
||||||
|
...
|
||||||
|
|
||||||
|
Reported-by: Marco Patalano <mpatalan@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
x86_64.c | 5 +++--
|
||||||
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/x86_64.c b/x86_64.c
|
||||||
|
index 27b1167ec630..31c249699066 100644
|
||||||
|
--- a/x86_64.c
|
||||||
|
+++ b/x86_64.c
|
||||||
|
@@ -3822,10 +3822,11 @@ in_exception_stack:
|
||||||
|
up -= 1;
|
||||||
|
bt->instptr = *up;
|
||||||
|
/*
|
||||||
|
- * No exception frame when coming from call_softirq.
|
||||||
|
+ * No exception frame when coming from do_softirq_own_stack
|
||||||
|
+ * or call_softirq.
|
||||||
|
*/
|
||||||
|
if ((sp = value_search(bt->instptr, &offset)) &&
|
||||||
|
- STREQ(sp->name, "call_softirq"))
|
||||||
|
+ (STREQ(sp->name, "do_softirq_own_stack") || STREQ(sp->name, "call_softirq")))
|
||||||
|
irq_eframe = 0;
|
||||||
|
bt->frameptr = 0;
|
||||||
|
done = FALSE;
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,63 @@
|
|||||||
|
From 39a938a62d0153a98ab3d1115d845b904192a832 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Date: Tue, 21 Feb 2023 11:03:26 +0800
|
||||||
|
Subject: [PATCH 76/89] Fix for "dis" command to correctly display the offset
|
||||||
|
of disassembly code
|
||||||
|
|
||||||
|
For gdb-10.2, the disassembly code may start with "=>", which needs to
|
||||||
|
be stripped when calculating the address. Otherwise, parsing the address
|
||||||
|
will fail because the current code always assumes that it starts with the
|
||||||
|
"0x". For example:
|
||||||
|
|
||||||
|
crash> gdb disassemble 0xffffffffa2317add
|
||||||
|
Dump of assembler code for function native_queued_spin_lock_slowpath:
|
||||||
|
...
|
||||||
|
0xffffffffa2317ad3 <+35>: mov %edx,%eax
|
||||||
|
0xffffffffa2317ad5 <+37>: lock cmpxchg %ecx,(%rdi)
|
||||||
|
=> 0xffffffffa2317ad9 <+41>: cmp %eax,%edx
|
||||||
|
0xffffffffa2317adb <+43>: jne 0xffffffffa2317ac0 ...
|
||||||
|
0xffffffffa2317add <+45>: pop %rbp
|
||||||
|
...
|
||||||
|
|
||||||
|
Without the patch:
|
||||||
|
crash> dis 0xffffffffa2317add -r | tail -5
|
||||||
|
0xffffffffa2317ad3 <native_queued_spin_lock_slowpath+35>: mov %edx,%eax
|
||||||
|
0xffffffffa2317ad5 <native_queued_spin_lock_slowpath+37>: lock cmpxchg %ecx,(%rdi)
|
||||||
|
0xffffffffa2317ad5 <native_queued_spin_lock_slowpath+37>: cmp %eax,%edx
|
||||||
|
^^
|
||||||
|
0xffffffffa2317adb <native_queued_spin_lock_slowpath+43>: jne 0xffffffffa2317ac0 ...
|
||||||
|
0xffffffffa2317add <native_queued_spin_lock_slowpath+45>: pop %rbp
|
||||||
|
|
||||||
|
With the patch:
|
||||||
|
|
||||||
|
crash> dis 0xffffffffa2317add -r | tail -5
|
||||||
|
0xffffffffa2317ad3 <native_queued_spin_lock_slowpath+35>: mov %edx,%eax
|
||||||
|
0xffffffffa2317ad5 <native_queued_spin_lock_slowpath+37>: lock cmpxchg %ecx,(%rdi)
|
||||||
|
0xffffffffa2317ad9 <native_queued_spin_lock_slowpath+41>: cmp %eax,%edx
|
||||||
|
0xffffffffa2317adb <native_queued_spin_lock_slowpath+43>: jne 0xffffffffa2317ac0 ...
|
||||||
|
0xffffffffa2317add <native_queued_spin_lock_slowpath+45>: pop %rbp
|
||||||
|
|
||||||
|
Reported-by: Vernon Lovejoy <vlovejoy@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
kernel.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/kernel.c b/kernel.c
|
||||||
|
index 3ca513962970..3f2d9a15a78d 100644
|
||||||
|
--- a/kernel.c
|
||||||
|
+++ b/kernel.c
|
||||||
|
@@ -2113,6 +2113,10 @@ cmd_dis(void)
|
||||||
|
rewind(pc->tmpfile);
|
||||||
|
|
||||||
|
while (fgets(buf2, BUFSIZE, pc->tmpfile)) {
|
||||||
|
+
|
||||||
|
+ if (STRNEQ(buf2, "=>"))
|
||||||
|
+ shift_string_left(buf2, 2);
|
||||||
|
+
|
||||||
|
strip_beginning_whitespace(buf2);
|
||||||
|
|
||||||
|
if (do_load_module_filter)
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,300 @@
|
|||||||
|
From 04a84a7071b34958f80633ea7bf96652810dadba Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Date: Mon, 20 Feb 2023 10:28:53 +0900
|
||||||
|
Subject: [PATCH 77/89] x86_64: Fix "bt" command on kernels with
|
||||||
|
random_kstack_offset=on
|
||||||
|
|
||||||
|
On kernels configured with CONFIG_RANDOMIZE_KSTACK_OFFSET=y and
|
||||||
|
random_kstack_offset=on, a random offset is added to task stacks with
|
||||||
|
__kstack_alloca() at the beginning of do_syscall_64() and other syscall
|
||||||
|
entry functions. This eventually does the following instruction.
|
||||||
|
|
||||||
|
<do_syscall_64+32>: sub %rax,%rsp
|
||||||
|
|
||||||
|
On the other hand, crash uses only a part of data for ORC unwinder to
|
||||||
|
unwind stacks and if an ip value doesn't have a usable ORC data, it
|
||||||
|
caluculates the frame size with parsing the assembly of the function.
|
||||||
|
|
||||||
|
However, crash cannot calculate the frame size correctly with the
|
||||||
|
instruction above, and prints stale return addresses like this:
|
||||||
|
|
||||||
|
crash> bt 1
|
||||||
|
PID: 1 TASK: ffff9c250023b880 CPU: 0 COMMAND: "systemd"
|
||||||
|
#0 [ffffb7e5c001fc80] __schedule at ffffffff91ae2b16
|
||||||
|
#1 [ffffb7e5c001fd00] schedule at ffffffff91ae2ed3
|
||||||
|
#2 [ffffb7e5c001fd18] schedule_hrtimeout_range_clock at ffffffff91ae7ed8
|
||||||
|
#3 [ffffb7e5c001fda8] ep_poll at ffffffff913ef828
|
||||||
|
#4 [ffffb7e5c001fe48] do_epoll_wait at ffffffff913ef943
|
||||||
|
#5 [ffffb7e5c001fe80] __x64_sys_epoll_wait at ffffffff913f0130
|
||||||
|
#6 [ffffb7e5c001fed0] do_syscall_64 at ffffffff91ad7169
|
||||||
|
#7 [ffffb7e5c001fef0] do_syscall_64 at ffffffff91ad7179 <<
|
||||||
|
#8 [ffffb7e5c001ff10] syscall_exit_to_user_mode at ffffffff91adaab2 << stale entries
|
||||||
|
#9 [ffffb7e5c001ff20] do_syscall_64 at ffffffff91ad7179 <<
|
||||||
|
#10 [ffffb7e5c001ff50] entry_SYSCALL_64_after_hwframe at ffffffff91c0009b
|
||||||
|
RIP: 00007f258d9427ae RSP: 00007fffda631d60 RFLAGS: 00000293
|
||||||
|
...
|
||||||
|
|
||||||
|
To fix this, enhance the use of ORC data. The ORC unwinder often uses
|
||||||
|
%rbp value, so keep it from exception frames and inactive task stacks.
|
||||||
|
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
defs.h | 1 +
|
||||||
|
symbols.c | 1 +
|
||||||
|
x86_64.c | 118 ++++++++++++++++++++++++++++++++++++++----------------
|
||||||
|
3 files changed, 85 insertions(+), 35 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index 801781749666..3c6fa3b0d228 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -2207,6 +2207,7 @@ struct offset_table { /* stash of commonly-used offsets */
|
||||||
|
long sock_sk_common;
|
||||||
|
long sock_common_skc_v6_daddr;
|
||||||
|
long sock_common_skc_v6_rcv_saddr;
|
||||||
|
+ long inactive_task_frame_bp;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct size_table { /* stash of commonly-used sizes */
|
||||||
|
diff --git a/symbols.c b/symbols.c
|
||||||
|
index 54115d753601..fc55da678ecd 100644
|
||||||
|
--- a/symbols.c
|
||||||
|
+++ b/symbols.c
|
||||||
|
@@ -8834,6 +8834,7 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
|
OFFSET(task_struct_tss_ksp));
|
||||||
|
fprintf(fp, " task_struct_thread_eip: %ld\n",
|
||||||
|
OFFSET(task_struct_thread_eip));
|
||||||
|
+ fprintf(fp, " inactive_task_frame_bp: %ld\n", OFFSET(inactive_task_frame_bp));
|
||||||
|
fprintf(fp, " inactive_task_frame_ret_addr: %ld\n",
|
||||||
|
OFFSET(inactive_task_frame_ret_addr));
|
||||||
|
fprintf(fp, " task_struct_thread_esp: %ld\n",
|
||||||
|
diff --git a/x86_64.c b/x86_64.c
|
||||||
|
index 31c249699066..86abea00c9d6 100644
|
||||||
|
--- a/x86_64.c
|
||||||
|
+++ b/x86_64.c
|
||||||
|
@@ -122,7 +122,7 @@ static int x86_64_do_not_cache_framesize(struct syment *, ulong);
|
||||||
|
static int x86_64_framesize_cache_func(int, ulong, int *, int, struct syment *);
|
||||||
|
static ulong x86_64_get_framepointer(struct bt_info *, ulong);
|
||||||
|
int search_for_eframe_target_caller(struct bt_info *, ulong, int *);
|
||||||
|
-static int x86_64_get_framesize(struct bt_info *, ulong, ulong);
|
||||||
|
+static int x86_64_get_framesize(struct bt_info *, ulong, ulong, char *);
|
||||||
|
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 *);
|
||||||
|
@@ -3639,7 +3639,7 @@ in_exception_stack:
|
||||||
|
bt, ofp);
|
||||||
|
rsp += SIZE(pt_regs); /* guaranteed kernel mode */
|
||||||
|
if (bt->eframe_ip && ((framesize = x86_64_get_framesize(bt,
|
||||||
|
- bt->eframe_ip, rsp)) >= 0))
|
||||||
|
+ bt->eframe_ip, rsp, NULL)) >= 0))
|
||||||
|
rsp += framesize;
|
||||||
|
level++;
|
||||||
|
irq_eframe = 0;
|
||||||
|
@@ -3671,7 +3671,7 @@ in_exception_stack:
|
||||||
|
case BACKTRACE_ENTRY_DISPLAYED:
|
||||||
|
level++;
|
||||||
|
if ((framesize = x86_64_get_framesize(bt,
|
||||||
|
- bt->eframe_ip ? bt->eframe_ip : *up, rsp)) >= 0) {
|
||||||
|
+ bt->eframe_ip ? bt->eframe_ip : *up, rsp, NULL)) >= 0) {
|
||||||
|
rsp += framesize;
|
||||||
|
i += framesize/sizeof(ulong);
|
||||||
|
}
|
||||||
|
@@ -3744,7 +3744,7 @@ in_exception_stack:
|
||||||
|
}
|
||||||
|
|
||||||
|
level++;
|
||||||
|
- if ((framesize = x86_64_get_framesize(bt, bt->instptr, rsp)) >= 0)
|
||||||
|
+ if ((framesize = x86_64_get_framesize(bt, bt->instptr, rsp, NULL)) >= 0)
|
||||||
|
rsp += framesize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -3796,7 +3796,7 @@ in_exception_stack:
|
||||||
|
case BACKTRACE_ENTRY_DISPLAYED:
|
||||||
|
level++;
|
||||||
|
if ((framesize = x86_64_get_framesize(bt,
|
||||||
|
- bt->eframe_ip ? bt->eframe_ip : *up, rsp)) >= 0) {
|
||||||
|
+ bt->eframe_ip ? bt->eframe_ip : *up, rsp, NULL)) >= 0) {
|
||||||
|
rsp += framesize;
|
||||||
|
i += framesize/sizeof(ulong);
|
||||||
|
}
|
||||||
|
@@ -3906,24 +3906,34 @@ in_exception_stack:
|
||||||
|
(STREQ(rip_symbol, "thread_return") ||
|
||||||
|
STREQ(rip_symbol, "schedule") ||
|
||||||
|
STREQ(rip_symbol, "__schedule"))) {
|
||||||
|
- if (STREQ(rip_symbol, "__schedule")) {
|
||||||
|
- i = (rsp - bt->stackbase)/sizeof(ulong);
|
||||||
|
- x86_64_print_stack_entry(bt, ofp, level,
|
||||||
|
- i, bt->instptr);
|
||||||
|
- level++;
|
||||||
|
- rsp = __schedule_frame_adjust(rsp, bt);
|
||||||
|
- if (STREQ(closest_symbol(bt->instptr), "schedule"))
|
||||||
|
+ if ((machdep->flags & ORC) && VALID_MEMBER(inactive_task_frame_ret_addr)) {
|
||||||
|
+ /*
|
||||||
|
+ * %rsp should have the address of inactive_task_frame, so
|
||||||
|
+ * skip the registers before ret_addr to adjust rsp.
|
||||||
|
+ */
|
||||||
|
+ if (CRASHDEBUG(1))
|
||||||
|
+ fprintf(fp, "rsp: %lx rbp: %lx\n", rsp, bt->bptr);
|
||||||
|
+ rsp += OFFSET(inactive_task_frame_ret_addr);
|
||||||
|
+ } else {
|
||||||
|
+ if (STREQ(rip_symbol, "__schedule")) {
|
||||||
|
+ i = (rsp - bt->stackbase)/sizeof(ulong);
|
||||||
|
+ x86_64_print_stack_entry(bt, ofp, level,
|
||||||
|
+ i, bt->instptr);
|
||||||
|
+ level++;
|
||||||
|
+ rsp = __schedule_frame_adjust(rsp, bt);
|
||||||
|
+ if (STREQ(closest_symbol(bt->instptr), "schedule"))
|
||||||
|
+ bt->flags |= BT_SCHEDULE;
|
||||||
|
+ } else
|
||||||
|
bt->flags |= BT_SCHEDULE;
|
||||||
|
- } else
|
||||||
|
- bt->flags |= BT_SCHEDULE;
|
||||||
|
-
|
||||||
|
- if (bt->flags & BT_SCHEDULE) {
|
||||||
|
- i = (rsp - bt->stackbase)/sizeof(ulong);
|
||||||
|
- x86_64_print_stack_entry(bt, ofp, level,
|
||||||
|
- i, bt->instptr);
|
||||||
|
- bt->flags &= ~(ulonglong)BT_SCHEDULE;
|
||||||
|
- rsp += sizeof(ulong);
|
||||||
|
- level++;
|
||||||
|
+
|
||||||
|
+ if (bt->flags & BT_SCHEDULE) {
|
||||||
|
+ i = (rsp - bt->stackbase)/sizeof(ulong);
|
||||||
|
+ x86_64_print_stack_entry(bt, ofp, level,
|
||||||
|
+ i, bt->instptr);
|
||||||
|
+ bt->flags &= ~(ulonglong)BT_SCHEDULE;
|
||||||
|
+ rsp += sizeof(ulong);
|
||||||
|
+ level++;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -3954,7 +3964,7 @@ in_exception_stack:
|
||||||
|
irq_eframe = 0;
|
||||||
|
bt->flags |= BT_EFRAME_TARGET;
|
||||||
|
if (bt->eframe_ip && ((framesize = x86_64_get_framesize(bt,
|
||||||
|
- bt->eframe_ip, rsp)) >= 0))
|
||||||
|
+ bt->eframe_ip, rsp, NULL)) >= 0))
|
||||||
|
rsp += framesize;
|
||||||
|
bt->flags &= ~BT_EFRAME_TARGET;
|
||||||
|
}
|
||||||
|
@@ -4041,7 +4051,7 @@ in_exception_stack:
|
||||||
|
case BACKTRACE_ENTRY_DISPLAYED:
|
||||||
|
level++;
|
||||||
|
if ((framesize = x86_64_get_framesize(bt,
|
||||||
|
- bt->eframe_ip ? bt->eframe_ip : *up, rsp)) >= 0) {
|
||||||
|
+ bt->eframe_ip ? bt->eframe_ip : *up, rsp, (char *)up)) >= 0) {
|
||||||
|
rsp += framesize;
|
||||||
|
i += framesize/sizeof(ulong);
|
||||||
|
}
|
||||||
|
@@ -4752,7 +4762,8 @@ x86_64_exception_frame(ulong flags, ulong kvaddr, char *local,
|
||||||
|
bt->instptr = rip;
|
||||||
|
bt->stkptr = rsp;
|
||||||
|
bt->bptr = rbp;
|
||||||
|
- }
|
||||||
|
+ } else if (machdep->flags & ORC)
|
||||||
|
+ bt->bptr = rbp;
|
||||||
|
|
||||||
|
if (kvaddr)
|
||||||
|
FREEBUF(pt_regs_buf);
|
||||||
|
@@ -5312,6 +5323,10 @@ x86_64_get_sp(struct bt_info *bt)
|
||||||
|
OFFSET(thread_struct_rsp), KVADDR,
|
||||||
|
&rsp, sizeof(void *),
|
||||||
|
"thread_struct rsp", FAULT_ON_ERROR);
|
||||||
|
+ if ((machdep->flags & ORC) && VALID_MEMBER(inactive_task_frame_bp)) {
|
||||||
|
+ readmem(rsp + OFFSET(inactive_task_frame_bp), KVADDR, &bt->bptr,
|
||||||
|
+ sizeof(void *), "inactive_task_frame.bp", FAULT_ON_ERROR);
|
||||||
|
+ }
|
||||||
|
return rsp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -6418,6 +6433,9 @@ x86_64_ORC_init(void)
|
||||||
|
orc->__stop_orc_unwind = symbol_value("__stop_orc_unwind");
|
||||||
|
orc->orc_lookup = symbol_value("orc_lookup");
|
||||||
|
|
||||||
|
+ MEMBER_OFFSET_INIT(inactive_task_frame_bp, "inactive_task_frame", "bp");
|
||||||
|
+ MEMBER_OFFSET_INIT(inactive_task_frame_ret_addr, "inactive_task_frame", "ret_addr");
|
||||||
|
+
|
||||||
|
machdep->flags |= ORC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -8480,7 +8498,7 @@ search_for_eframe_target_caller(struct bt_info *bt, ulong stkptr, int *framesize
|
||||||
|
(BT_OLD_BACK_TRACE|BT_TEXT_SYMBOLS|BT_TEXT_SYMBOLS_ALL|BT_FRAMESIZE_DISABLE)
|
||||||
|
|
||||||
|
static int
|
||||||
|
-x86_64_get_framesize(struct bt_info *bt, ulong textaddr, ulong rsp)
|
||||||
|
+x86_64_get_framesize(struct bt_info *bt, ulong textaddr, ulong rsp, char *stack_ptr)
|
||||||
|
{
|
||||||
|
int c, framesize, instr, arg, max;
|
||||||
|
struct syment *sp;
|
||||||
|
@@ -8581,19 +8599,49 @@ x86_64_get_framesize(struct bt_info *bt, ulong textaddr, ulong rsp)
|
||||||
|
if ((machdep->flags & ORC) && (korc = orc_find(textaddr))) {
|
||||||
|
if (CRASHDEBUG(1)) {
|
||||||
|
fprintf(fp,
|
||||||
|
- "rsp: %lx textaddr: %lx framesize: %d -> spo: %d bpo: %d spr: %d bpr: %d type: %d %s",
|
||||||
|
- rsp, textaddr, framesize, korc->sp_offset, korc->bp_offset,
|
||||||
|
- korc->sp_reg, korc->bp_reg, korc->type,
|
||||||
|
- (korc->type == ORC_TYPE_CALL) && (korc->sp_reg == ORC_REG_SP) ? "" : "(UNUSED)");
|
||||||
|
+ "rsp: %lx textaddr: %lx -> spo: %d bpo: %d spr: %d bpr: %d type: %d",
|
||||||
|
+ rsp, textaddr, korc->sp_offset, korc->bp_offset,
|
||||||
|
+ korc->sp_reg, korc->bp_reg, korc->type);
|
||||||
|
if (MEMBER_EXISTS("orc_entry", "end"))
|
||||||
|
fprintf(fp, " end: %d", korc->end);
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
- if ((korc->type == ORC_TYPE_CALL) && (korc->sp_reg == ORC_REG_SP)) {
|
||||||
|
- framesize = (korc->sp_offset - 8);
|
||||||
|
- return (x86_64_framesize_cache_func(FRAMESIZE_ENTER, textaddr,
|
||||||
|
- &framesize, exception, NULL));
|
||||||
|
+ if (korc->type == ORC_TYPE_CALL) {
|
||||||
|
+ ulong prev_sp = 0, prev_bp = 0;
|
||||||
|
+ framesize = -1;
|
||||||
|
+
|
||||||
|
+ if (korc->sp_reg == ORC_REG_SP) {
|
||||||
|
+ framesize = (korc->sp_offset - 8);
|
||||||
|
+
|
||||||
|
+ /* rsp points to a return address, so +8 to use sp_offset */
|
||||||
|
+ prev_sp = (rsp + 8) + korc->sp_offset;
|
||||||
|
+ if (CRASHDEBUG(1))
|
||||||
|
+ fprintf(fp, "rsp: %lx prev_sp: %lx framesize: %d\n",
|
||||||
|
+ rsp, prev_sp, framesize);
|
||||||
|
+ } else if ((korc->sp_reg == ORC_REG_BP) && bt->bptr) {
|
||||||
|
+ prev_sp = bt->bptr + korc->sp_offset;
|
||||||
|
+ framesize = (prev_sp - (rsp + 8) - 8);
|
||||||
|
+ if (CRASHDEBUG(1))
|
||||||
|
+ fprintf(fp, "rsp: %lx rbp: %lx prev_sp: %lx framesize: %d\n",
|
||||||
|
+ rsp, bt->bptr, prev_sp, framesize);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((korc->bp_reg == ORC_REG_PREV_SP) && prev_sp) {
|
||||||
|
+ prev_bp = prev_sp + korc->bp_offset;
|
||||||
|
+ if (stack_ptr && INSTACK(prev_bp, bt)) {
|
||||||
|
+ bt->bptr = ULONG(stack_ptr + (prev_bp - rsp));
|
||||||
|
+ if (CRASHDEBUG(1))
|
||||||
|
+ fprintf(fp, "rsp: %lx prev_sp: %lx prev_bp: %lx -> %lx\n",
|
||||||
|
+ rsp, prev_sp, prev_bp, bt->bptr);
|
||||||
|
+ } else
|
||||||
|
+ bt->bptr = 0;
|
||||||
|
+ } else if ((korc->bp_reg != ORC_REG_UNDEFINED))
|
||||||
|
+ bt->bptr = 0;
|
||||||
|
+
|
||||||
|
+ if (framesize >= 0)
|
||||||
|
+ /* Do not cache this, possibly it may be variable. */
|
||||||
|
+ return framesize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -8749,7 +8797,7 @@ x86_64_framesize_debug(struct bt_info *bt)
|
||||||
|
if (!bt->hp->eip)
|
||||||
|
error(INFO, "x86_64_framesize_debug: ignoring command\n");
|
||||||
|
else
|
||||||
|
- x86_64_get_framesize(bt, bt->hp->eip, 0);
|
||||||
|
+ x86_64_get_framesize(bt, bt->hp->eip, 0, NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -3:
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,169 @@
|
|||||||
|
From dbc45587f2c0024f0bc801a967bed9bd8d9f218c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tao Liu <ltao@redhat.com>
|
||||||
|
Date: Wed, 22 Feb 2023 14:32:09 +0800
|
||||||
|
Subject: [PATCH 78/89] Fix for "search -u" option failing in maple tree kernel
|
||||||
|
|
||||||
|
Kernel with maple tree enabled doesn't have mmap as a member of mm_struct[1],
|
||||||
|
so OFFSET(mm_struct_mmap) case needed to be handled differently for
|
||||||
|
maple tree kernel.
|
||||||
|
|
||||||
|
Before:
|
||||||
|
crash> search -u a
|
||||||
|
|
||||||
|
search: invalid structure member offset: mm_struct_mmap
|
||||||
|
FILE: memory.c LINE: 14255 FUNCTION: address_space_start()
|
||||||
|
|
||||||
|
[crash] error trace: 549500 => 548fff => 5f1c91 => 5f1c13
|
||||||
|
|
||||||
|
5f1c13: OFFSET_verify.part.36+51
|
||||||
|
5f1c91: OFFSET_verify+49
|
||||||
|
548fff: address_space_start+106
|
||||||
|
549500: cmd_search+855
|
||||||
|
|
||||||
|
search: invalid structure member offset: mm_struct_mmap
|
||||||
|
FILE: memory.c LINE: 14255 FUNCTION: address_space_start()
|
||||||
|
|
||||||
|
After:
|
||||||
|
crash> search -u a
|
||||||
|
7ffea63e6440: a
|
||||||
|
|
||||||
|
[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=763ecb035029f500d7e6dc99acd1ad299b7726a1
|
||||||
|
|
||||||
|
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
memory.c | 89 +++++++++++++++++++++++++++++++++++++++++---------------
|
||||||
|
1 file changed, 65 insertions(+), 24 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/memory.c b/memory.c
|
||||||
|
index d9cd616f19de..c4a6ecd18004 100644
|
||||||
|
--- a/memory.c
|
||||||
|
+++ b/memory.c
|
||||||
|
@@ -14245,14 +14245,28 @@ vaddr_type(ulong vaddr, struct task_context *tc)
|
||||||
|
static int
|
||||||
|
address_space_start(struct task_context *tc, ulong *addr)
|
||||||
|
{
|
||||||
|
- ulong vma;
|
||||||
|
+ ulong mm_mt, entry_num, i, vma = 0;
|
||||||
|
char *vma_buf;
|
||||||
|
+ struct list_pair *entry_list;
|
||||||
|
|
||||||
|
if (!tc->mm_struct)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
- fill_mm_struct(tc->mm_struct);
|
||||||
|
- vma = ULONG(tt->mm_struct + OFFSET(mm_struct_mmap));
|
||||||
|
+ if (INVALID_MEMBER(mm_struct_mmap) && VALID_MEMBER(mm_struct_mm_mt)) {
|
||||||
|
+ mm_mt = tc->mm_struct + OFFSET(mm_struct_mm_mt);
|
||||||
|
+ entry_num = do_maple_tree(mm_mt, MAPLE_TREE_COUNT, NULL);
|
||||||
|
+ entry_list = (struct list_pair *)GETBUF(entry_num * sizeof(struct list_pair));
|
||||||
|
+ do_maple_tree(mm_mt, MAPLE_TREE_GATHER, entry_list);
|
||||||
|
+ for (i = 0; i < entry_num; i++) {
|
||||||
|
+ if (!!(vma = (ulong)entry_list[i].value))
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ FREEBUF(entry_list);
|
||||||
|
+ } else {
|
||||||
|
+ fill_mm_struct(tc->mm_struct);
|
||||||
|
+ vma = ULONG(tt->mm_struct + OFFSET(mm_struct_mmap));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!vma)
|
||||||
|
return FALSE;
|
||||||
|
vma_buf = fill_vma_cache(vma);
|
||||||
|
@@ -15491,6 +15505,30 @@ search_physical(struct searchinfo *si)
|
||||||
|
FREEBUF(pagebuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool
|
||||||
|
+check_vma(ulong vma, ulong vaddr, ulong *vm_next, ulong *nextvaddr)
|
||||||
|
+{
|
||||||
|
+ char *vma_buf;
|
||||||
|
+ ulong vm_start, vm_end;
|
||||||
|
+
|
||||||
|
+ vma_buf = fill_vma_cache(vma);
|
||||||
|
+
|
||||||
|
+ vm_start = ULONG(vma_buf + OFFSET(vm_area_struct_vm_start));
|
||||||
|
+ vm_end = ULONG(vma_buf + OFFSET(vm_area_struct_vm_end));
|
||||||
|
+ if (vm_next)
|
||||||
|
+ *vm_next = ULONG(vma_buf + OFFSET(vm_area_struct_vm_next));
|
||||||
|
+
|
||||||
|
+ if (vaddr <= vm_start) {
|
||||||
|
+ *nextvaddr = vm_start;
|
||||||
|
+ return TRUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((vaddr > vm_start) && (vaddr < vm_end)) {
|
||||||
|
+ *nextvaddr = vaddr;
|
||||||
|
+ return TRUE;
|
||||||
|
+ }
|
||||||
|
+ return FALSE;
|
||||||
|
+}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the next mapped user virtual address page that comes after
|
||||||
|
@@ -15500,37 +15538,40 @@ static int
|
||||||
|
next_upage(struct task_context *tc, ulong vaddr, ulong *nextvaddr)
|
||||||
|
{
|
||||||
|
ulong vma, total_vm;
|
||||||
|
- char *vma_buf;
|
||||||
|
- ulong vm_start, vm_end;
|
||||||
|
ulong vm_next;
|
||||||
|
+ ulong mm_mt, entry_num, i;
|
||||||
|
+ struct list_pair *entry_list;
|
||||||
|
|
||||||
|
if (!tc->mm_struct)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
- fill_mm_struct(tc->mm_struct);
|
||||||
|
- vma = ULONG(tt->mm_struct + OFFSET(mm_struct_mmap));
|
||||||
|
+ fill_mm_struct(tc->mm_struct);
|
||||||
|
+ vaddr = VIRTPAGEBASE(vaddr) + PAGESIZE(); /* first possible page */
|
||||||
|
total_vm = ULONG(tt->mm_struct + OFFSET(mm_struct_total_vm));
|
||||||
|
-
|
||||||
|
- if (!vma || (total_vm == 0))
|
||||||
|
+ if (!total_vm)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
- vaddr = VIRTPAGEBASE(vaddr) + PAGESIZE(); /* first possible page */
|
||||||
|
-
|
||||||
|
- for ( ; vma; vma = vm_next) {
|
||||||
|
- vma_buf = fill_vma_cache(vma);
|
||||||
|
-
|
||||||
|
- vm_start = ULONG(vma_buf + OFFSET(vm_area_struct_vm_start));
|
||||||
|
- vm_end = ULONG(vma_buf + OFFSET(vm_area_struct_vm_end));
|
||||||
|
- vm_next = ULONG(vma_buf + OFFSET(vm_area_struct_vm_next));
|
||||||
|
-
|
||||||
|
- if (vaddr <= vm_start) {
|
||||||
|
- *nextvaddr = vm_start;
|
||||||
|
- return TRUE;
|
||||||
|
+ if (INVALID_MEMBER(mm_struct_mmap) && VALID_MEMBER(mm_struct_mm_mt)) {
|
||||||
|
+ mm_mt = tc->mm_struct + OFFSET(mm_struct_mm_mt);
|
||||||
|
+ entry_num = do_maple_tree(mm_mt, MAPLE_TREE_COUNT, NULL);
|
||||||
|
+ entry_list = (struct list_pair *)GETBUF(entry_num * sizeof(struct list_pair));
|
||||||
|
+ do_maple_tree(mm_mt, MAPLE_TREE_GATHER, entry_list);
|
||||||
|
+ for (i = 0; i < entry_num; i++) {
|
||||||
|
+ if (!!(vma = (ulong)entry_list[i].value) &&
|
||||||
|
+ check_vma(vma, vaddr, NULL, nextvaddr)) {
|
||||||
|
+ FREEBUF(entry_list);
|
||||||
|
+ return TRUE;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
+ FREEBUF(entry_list);
|
||||||
|
+ } else {
|
||||||
|
+ vma = ULONG(tt->mm_struct + OFFSET(mm_struct_mmap));
|
||||||
|
|
||||||
|
- if ((vaddr > vm_start) && (vaddr < vm_end)) {
|
||||||
|
- *nextvaddr = vaddr;
|
||||||
|
- return TRUE;
|
||||||
|
+ if (!vma)
|
||||||
|
+ return FALSE;
|
||||||
|
+ for ( ; vma; vma = vm_next) {
|
||||||
|
+ if (check_vma(vma, vaddr, &vm_next, nextvaddr))
|
||||||
|
+ return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,258 @@
|
|||||||
|
From f4acc0e222aedf720e796fd386f2dc15bbb665e9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Date: Tue, 7 Mar 2023 17:14:25 +0800
|
||||||
|
Subject: [PATCH 79/89] Enhance "net" command to display IPv6 address of
|
||||||
|
network interface
|
||||||
|
|
||||||
|
Currently, the "net" command displays only the IPv4 address of a network
|
||||||
|
interface. Support outputting IPv6 addresses. For example:
|
||||||
|
|
||||||
|
Without the patch:
|
||||||
|
crash> net
|
||||||
|
NET_DEVICE NAME IP ADDRESS(ES)
|
||||||
|
ffff8d01b1205000 lo 127.0.0.1
|
||||||
|
ffff8d0087e40000 eno1 192.168.122.2
|
||||||
|
|
||||||
|
With the patch:
|
||||||
|
crash> net
|
||||||
|
NET_DEVICE NAME IP ADDRESS(ES)
|
||||||
|
ffff8d01b1205000 lo 127.0.0.1, ::1
|
||||||
|
ffff8d0087e40000 eno1 192.168.122.2, xxxx:xx:x:xxxx:xxxx:xxx:xxxx:xxxx, yyyy::yyyy:yyy:yyyy:yyyy
|
||||||
|
|
||||||
|
Also align with longer device names.
|
||||||
|
|
||||||
|
Related kernel commit:
|
||||||
|
502a2ffd7376 ("ipv6: convert idev_list to list macros")
|
||||||
|
|
||||||
|
Reported-by: Buland Kumar Singh <bsingh@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
---
|
||||||
|
defs.h | 6 +++
|
||||||
|
net.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++-----
|
||||||
|
symbols.c | 6 +++
|
||||||
|
3 files changed, 112 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index 3c6fa3b0d228..6cfc21487497 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -2208,6 +2208,12 @@ struct offset_table { /* stash of commonly-used offsets */
|
||||||
|
long sock_common_skc_v6_daddr;
|
||||||
|
long sock_common_skc_v6_rcv_saddr;
|
||||||
|
long inactive_task_frame_bp;
|
||||||
|
+ long net_device_ip6_ptr;
|
||||||
|
+ long inet6_dev_addr_list;
|
||||||
|
+ long inet6_ifaddr_addr;
|
||||||
|
+ long inet6_ifaddr_if_list;
|
||||||
|
+ long inet6_ifaddr_if_next;
|
||||||
|
+ long in6_addr_in6_u;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct size_table { /* stash of commonly-used sizes */
|
||||||
|
diff --git a/net.c b/net.c
|
||||||
|
index aa445ab7ee13..987dc8934942 100644
|
||||||
|
--- a/net.c
|
||||||
|
+++ b/net.c
|
||||||
|
@@ -71,6 +71,7 @@ static void print_neighbour_q(ulong, int);
|
||||||
|
static void get_netdev_info(ulong, struct devinfo *);
|
||||||
|
static void get_device_name(ulong, char *);
|
||||||
|
static long get_device_address(ulong, char **, long);
|
||||||
|
+static void get_device_ip6_address(ulong, char **, long);
|
||||||
|
static void get_sock_info(ulong, char *);
|
||||||
|
static void dump_arp(void);
|
||||||
|
static void arp_state_to_flags(unsigned char);
|
||||||
|
@@ -114,6 +115,13 @@ net_init(void)
|
||||||
|
net->dev_ip_ptr = MEMBER_OFFSET_INIT(net_device_ip_ptr,
|
||||||
|
"net_device", "ip_ptr");
|
||||||
|
MEMBER_OFFSET_INIT(net_device_dev_list, "net_device", "dev_list");
|
||||||
|
+ MEMBER_OFFSET_INIT(net_device_ip6_ptr, "net_device", "ip6_ptr");
|
||||||
|
+ MEMBER_OFFSET_INIT(inet6_dev_addr_list, "inet6_dev", "addr_list");
|
||||||
|
+ MEMBER_OFFSET_INIT(inet6_ifaddr_addr, "inet6_ifaddr", "addr");
|
||||||
|
+ MEMBER_OFFSET_INIT(inet6_ifaddr_if_list, "inet6_ifaddr", "if_list");
|
||||||
|
+ MEMBER_OFFSET_INIT(inet6_ifaddr_if_next, "inet6_ifaddr", "if_next");
|
||||||
|
+ MEMBER_OFFSET_INIT(in6_addr_in6_u, "in6_addr", "in6_u");
|
||||||
|
+
|
||||||
|
MEMBER_OFFSET_INIT(net_dev_base_head, "net", "dev_base_head");
|
||||||
|
ARRAY_LENGTH_INIT(net->net_device_name_index,
|
||||||
|
net_device_name, "net_device.name", NULL, sizeof(char));
|
||||||
|
@@ -466,7 +474,7 @@ show_net_devices(ulong task)
|
||||||
|
buf = GETBUF(buflen);
|
||||||
|
flen = MAX(VADDR_PRLEN, strlen(net->netdevice));
|
||||||
|
|
||||||
|
- fprintf(fp, "%s NAME IP ADDRESS(ES)\n",
|
||||||
|
+ fprintf(fp, "%s NAME IP ADDRESS(ES)\n",
|
||||||
|
mkstring(upper_case(net->netdevice, buf),
|
||||||
|
flen, CENTER|LJUST, NULL));
|
||||||
|
|
||||||
|
@@ -475,9 +483,10 @@ show_net_devices(ulong task)
|
||||||
|
mkstring(buf, flen, CENTER|RJUST|LONG_HEX, MKSTR(next)));
|
||||||
|
|
||||||
|
get_device_name(next, buf);
|
||||||
|
- fprintf(fp, "%-6s ", buf);
|
||||||
|
+ fprintf(fp, "%-10s ", buf);
|
||||||
|
|
||||||
|
- buflen = get_device_address(next, &buf, buflen);
|
||||||
|
+ get_device_address(next, &buf, buflen);
|
||||||
|
+ get_device_ip6_address(next, &buf, buflen);
|
||||||
|
fprintf(fp, "%s\n", buf);
|
||||||
|
|
||||||
|
readmem(next+net->dev_next, KVADDR, &next,
|
||||||
|
@@ -503,7 +512,7 @@ show_net_devices_v2(ulong task)
|
||||||
|
buf = GETBUF(buflen);
|
||||||
|
flen = MAX(VADDR_PRLEN, strlen(net->netdevice));
|
||||||
|
|
||||||
|
- fprintf(fp, "%s NAME IP ADDRESS(ES)\n",
|
||||||
|
+ fprintf(fp, "%s NAME IP ADDRESS(ES)\n",
|
||||||
|
mkstring(upper_case(net->netdevice, buf),
|
||||||
|
flen, CENTER|LJUST, NULL));
|
||||||
|
|
||||||
|
@@ -528,9 +537,10 @@ show_net_devices_v2(ulong task)
|
||||||
|
MKSTR(ld->list_ptr[i])));
|
||||||
|
|
||||||
|
get_device_name(ld->list_ptr[i], buf);
|
||||||
|
- fprintf(fp, "%-6s ", buf);
|
||||||
|
+ fprintf(fp, "%-10s ", buf);
|
||||||
|
|
||||||
|
- buflen = get_device_address(ld->list_ptr[i], &buf, buflen);
|
||||||
|
+ get_device_address(ld->list_ptr[i], &buf, buflen);
|
||||||
|
+ get_device_ip6_address(ld->list_ptr[i], &buf, buflen);
|
||||||
|
fprintf(fp, "%s\n", buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -556,7 +566,7 @@ show_net_devices_v3(ulong task)
|
||||||
|
buf = GETBUF(buflen);
|
||||||
|
flen = MAX(VADDR_PRLEN, strlen(net->netdevice));
|
||||||
|
|
||||||
|
- fprintf(fp, "%s NAME IP ADDRESS(ES)\n",
|
||||||
|
+ fprintf(fp, "%s NAME IP ADDRESS(ES)\n",
|
||||||
|
mkstring(upper_case(net->netdevice, buf),
|
||||||
|
flen, CENTER|LJUST, NULL));
|
||||||
|
|
||||||
|
@@ -591,9 +601,10 @@ show_net_devices_v3(ulong task)
|
||||||
|
MKSTR(ld->list_ptr[i])));
|
||||||
|
|
||||||
|
get_device_name(ld->list_ptr[i], buf);
|
||||||
|
- fprintf(fp, "%-6s ", buf);
|
||||||
|
+ fprintf(fp, "%-10s ", buf);
|
||||||
|
|
||||||
|
- buflen = get_device_address(ld->list_ptr[i], &buf, buflen);
|
||||||
|
+ get_device_address(ld->list_ptr[i], &buf, buflen);
|
||||||
|
+ get_device_ip6_address(ld->list_ptr[i], &buf, buflen);
|
||||||
|
fprintf(fp, "%s\n", buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -925,6 +936,86 @@ get_device_address(ulong devaddr, char **bufp, long buflen)
|
||||||
|
return buflen;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+get_device_ip6_address(ulong devaddr, char **bufp, long buflen)
|
||||||
|
+{
|
||||||
|
+ ulong ip6_ptr = 0, pos = 0, bufsize = buflen, addr = 0;
|
||||||
|
+ struct in6_addr ip6_addr;
|
||||||
|
+ char *buf;
|
||||||
|
+ char str[INET6_ADDRSTRLEN] = {0};
|
||||||
|
+ char buffer[INET6_ADDRSTRLEN + 2] = {0};
|
||||||
|
+ uint len = 0;
|
||||||
|
+
|
||||||
|
+ buf = *bufp;
|
||||||
|
+ pos = strlen(buf);
|
||||||
|
+
|
||||||
|
+ readmem(devaddr + OFFSET(net_device_ip6_ptr), KVADDR,
|
||||||
|
+ &ip6_ptr, sizeof(ulong), "ip6_ptr", FAULT_ON_ERROR);
|
||||||
|
+
|
||||||
|
+ if (!ip6_ptr)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * 502a2ffd7376 ("ipv6: convert idev_list to list macros")
|
||||||
|
+ * v2.6.35-rc1~473^2~733
|
||||||
|
+ */
|
||||||
|
+ if (VALID_MEMBER(inet6_ifaddr_if_list)) {
|
||||||
|
+ struct list_data list_data, *ld;
|
||||||
|
+ ulong cnt = 0, i;
|
||||||
|
+
|
||||||
|
+ ld = &list_data;
|
||||||
|
+ BZERO(ld, sizeof(struct list_data));
|
||||||
|
+ ld->flags |= LIST_ALLOCATE;
|
||||||
|
+ ld->start = ip6_ptr + OFFSET(inet6_dev_addr_list);
|
||||||
|
+ ld->list_head_offset = OFFSET(inet6_ifaddr_if_list);
|
||||||
|
+ cnt = do_list(ld);
|
||||||
|
+
|
||||||
|
+ for (i = 1; i < cnt; i++) {
|
||||||
|
+
|
||||||
|
+ addr = ld->list_ptr[i] + OFFSET(inet6_ifaddr_addr);
|
||||||
|
+ readmem(addr + OFFSET(in6_addr_in6_u), KVADDR, &ip6_addr,
|
||||||
|
+ sizeof(struct in6_addr), "in6_addr.in6_u", FAULT_ON_ERROR);
|
||||||
|
+
|
||||||
|
+ inet_ntop(AF_INET6, (void*)&ip6_addr, str, INET6_ADDRSTRLEN);
|
||||||
|
+ sprintf(buffer, "%s%s", pos ? ", " : "", str);
|
||||||
|
+ len = strlen(buffer);
|
||||||
|
+ if (pos + len >= bufsize) {
|
||||||
|
+ RESIZEBUF(*bufp, bufsize, bufsize + buflen);
|
||||||
|
+ buf = *bufp;
|
||||||
|
+ BZERO(buf + bufsize, buflen);
|
||||||
|
+ bufsize += buflen;
|
||||||
|
+ }
|
||||||
|
+ BCOPY(buffer, &buf[pos], len);
|
||||||
|
+ pos += len;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ FREEBUF(ld->list_ptr);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ readmem(ip6_ptr + OFFSET(inet6_dev_addr_list), KVADDR,
|
||||||
|
+ &addr, sizeof(void *), "inet6_dev.addr_list", FAULT_ON_ERROR);
|
||||||
|
+
|
||||||
|
+ while (addr) {
|
||||||
|
+ readmem(addr + OFFSET(in6_addr_in6_u), KVADDR, &ip6_addr,
|
||||||
|
+ sizeof(struct in6_addr), "in6_addr.in6_u", FAULT_ON_ERROR);
|
||||||
|
+ inet_ntop(AF_INET6, (void*)&ip6_addr, str, INET6_ADDRSTRLEN);
|
||||||
|
+ sprintf(buffer, "%s%s", pos ? ", " : "", str);
|
||||||
|
+ len = strlen(buffer);
|
||||||
|
+
|
||||||
|
+ if (pos + len >= bufsize) {
|
||||||
|
+ RESIZEBUF(*bufp, bufsize, bufsize + buflen);
|
||||||
|
+ buf = *bufp;
|
||||||
|
+ BZERO(buf + bufsize, buflen);
|
||||||
|
+ bufsize += buflen;
|
||||||
|
+ }
|
||||||
|
+ BCOPY(buffer, &buf[pos], len);
|
||||||
|
+ pos += len;
|
||||||
|
+ readmem(addr + OFFSET(inet6_ifaddr_if_next), KVADDR, &addr,
|
||||||
|
+ sizeof(void *), "inet6_ifaddr.if_next", FAULT_ON_ERROR);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Get the family, type, local and destination address/port pairs.
|
||||||
|
*/
|
||||||
|
diff --git a/symbols.c b/symbols.c
|
||||||
|
index fc55da678ecd..158c95459bec 100644
|
||||||
|
--- a/symbols.c
|
||||||
|
+++ b/symbols.c
|
||||||
|
@@ -9799,6 +9799,7 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
|
OFFSET(net_device_addr_len));
|
||||||
|
fprintf(fp, " net_device_ip_ptr: %ld\n",
|
||||||
|
OFFSET(net_device_ip_ptr));
|
||||||
|
+ fprintf(fp, " net_device_ip6_ptr: %ld\n", OFFSET(net_device_ip6_ptr));
|
||||||
|
fprintf(fp, " net_device_dev_list: %ld\n",
|
||||||
|
OFFSET(net_device_dev_list));
|
||||||
|
fprintf(fp, " net_dev_base_head: %ld\n",
|
||||||
|
@@ -9851,6 +9852,11 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
|
fprintf(fp, " inet_opt_num: %ld\n",
|
||||||
|
OFFSET(inet_opt_num));
|
||||||
|
|
||||||
|
+ fprintf(fp, " inet6_dev_addr_list: %ld\n", OFFSET(inet6_dev_addr_list));
|
||||||
|
+ fprintf(fp, " inet6_ifaddr_addr: %ld\n", OFFSET(inet6_ifaddr_addr));
|
||||||
|
+ fprintf(fp, " inet6_ifaddr_if_list: %ld\n", OFFSET(inet6_ifaddr_if_list));
|
||||||
|
+ fprintf(fp, " inet6_ifaddr_if_next: %ld\n", OFFSET(inet6_ifaddr_if_next));
|
||||||
|
+ fprintf(fp, " in6_addr_in6_u: %ld\n", OFFSET(in6_addr_in6_u));
|
||||||
|
fprintf(fp, " ipv6_pinfo_rcv_saddr: %ld\n",
|
||||||
|
OFFSET(ipv6_pinfo_rcv_saddr));
|
||||||
|
fprintf(fp, " ipv6_pinfo_daddr: %ld\n",
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,44 @@
|
|||||||
|
From 0f2e551ef1f9bb10b2fef0c3ac27e9d32488cc47 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Date: Wed, 8 Mar 2023 20:22:02 +0800
|
||||||
|
Subject: [PATCH 80/89] Fix for "net -n" option to properly deal with an
|
||||||
|
invalid argument
|
||||||
|
|
||||||
|
The help/man page of the "net" command suggests that "-n" option can
|
||||||
|
accept two kinds of argument: PID or task_struct pointer. However,
|
||||||
|
the "net -n" command accepts an invalid argument and shows the
|
||||||
|
namespace of the current context silently. For example:
|
||||||
|
|
||||||
|
crash> net -n 1000000000
|
||||||
|
NET_DEVICE NAME IP ADDRESS(ES)
|
||||||
|
ffff949dc11d7000 lo 127.0.0.1
|
||||||
|
ffff949dcc01c000 eno49 192.168.122.17
|
||||||
|
|
||||||
|
With the patch, emit an error expectedly.
|
||||||
|
|
||||||
|
crash> net -n 1000000000
|
||||||
|
net: invalid task or pid value: 1000000000
|
||||||
|
|
||||||
|
Reported-by: Buland Kumar Singh <bsingh@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
net.c | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/net.c b/net.c
|
||||||
|
index 987dc8934942..18c238be346d 100644
|
||||||
|
--- a/net.c
|
||||||
|
+++ b/net.c
|
||||||
|
@@ -420,6 +420,9 @@ cmd_net(void)
|
||||||
|
case STR_PID:
|
||||||
|
case STR_TASK:
|
||||||
|
task = tc->task;
|
||||||
|
+ break;
|
||||||
|
+ case STR_INVALID:
|
||||||
|
+ error(FATAL, "invalid task or pid value: %s\n", args[optind]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,160 @@
|
|||||||
|
From b29bd2b531502ca0274ad9c4531417920102fb26 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Date: Fri, 10 Mar 2023 02:38:26 +0000
|
||||||
|
Subject: [PATCH 81/89] Fix "kmem -n" option to display memory blocks on Linux
|
||||||
|
6.3-rc1 and later
|
||||||
|
|
||||||
|
Kernel commit d2bf38c088e0 ("driver core: remove private pointer from
|
||||||
|
struct bus_type") removed the bus_type.p member, and the "kmem -n"
|
||||||
|
option fails with the following error before displaying memory block
|
||||||
|
information on Linux 6.3-rc1 and later kernels.
|
||||||
|
|
||||||
|
kmem: invalid structure member offset: bus_type_p
|
||||||
|
FILE: memory.c LINE: 17852 FUNCTION: init_memory_block()
|
||||||
|
|
||||||
|
Search bus_kset.list instead for subsys_private of memory subsys.
|
||||||
|
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
defs.h | 2 ++
|
||||||
|
memory.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++------
|
||||||
|
symbols.c | 2 ++
|
||||||
|
3 files changed, 61 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/defs.h b/defs.h
|
||||||
|
index 6cfc21487497..9091397a7012 100644
|
||||||
|
--- a/defs.h
|
||||||
|
+++ b/defs.h
|
||||||
|
@@ -2214,6 +2214,8 @@ struct offset_table { /* stash of commonly-used offsets */
|
||||||
|
long inet6_ifaddr_if_list;
|
||||||
|
long inet6_ifaddr_if_next;
|
||||||
|
long in6_addr_in6_u;
|
||||||
|
+ long kset_kobj;
|
||||||
|
+ long subsys_private_subsys;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct size_table { /* stash of commonly-used sizes */
|
||||||
|
diff --git a/memory.c b/memory.c
|
||||||
|
index c4a6ecd18004..592a5ef49d50 100644
|
||||||
|
--- a/memory.c
|
||||||
|
+++ b/memory.c
|
||||||
|
@@ -17822,6 +17822,13 @@ static void
|
||||||
|
init_memory_block_offset(void)
|
||||||
|
{
|
||||||
|
MEMBER_OFFSET_INIT(bus_type_p, "bus_type", "p");
|
||||||
|
+ if (INVALID_MEMBER(bus_type_p)) {
|
||||||
|
+ MEMBER_OFFSET_INIT(kset_list, "kset", "list");
|
||||||
|
+ MEMBER_OFFSET_INIT(kset_kobj, "kset", "kobj");
|
||||||
|
+ MEMBER_OFFSET_INIT(kobject_name, "kobject", "name");
|
||||||
|
+ MEMBER_OFFSET_INIT(kobject_entry, "kobject", "entry");
|
||||||
|
+ MEMBER_OFFSET_INIT(subsys_private_subsys, "subsys_private", "subsys");
|
||||||
|
+ }
|
||||||
|
MEMBER_OFFSET_INIT(subsys_private_klist_devices,
|
||||||
|
"subsys_private", "klist_devices");
|
||||||
|
MEMBER_OFFSET_INIT(klist_k_list, "klist", "k_list");
|
||||||
|
@@ -17842,15 +17849,60 @@ init_memory_block_offset(void)
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
-init_memory_block(struct list_data *ld, int *klistcnt, ulong **klistbuf)
|
||||||
|
+init_memory_block(int *klistcnt, ulong **klistbuf)
|
||||||
|
{
|
||||||
|
- ulong memory_subsys = symbol_value("memory_subsys");
|
||||||
|
ulong private, klist, start;
|
||||||
|
+ struct list_data list_data, *ld;
|
||||||
|
+
|
||||||
|
+ ld = &list_data;
|
||||||
|
+ private = 0;
|
||||||
|
|
||||||
|
init_memory_block_offset();
|
||||||
|
|
||||||
|
- readmem(memory_subsys + OFFSET(bus_type_p), KVADDR, &private,
|
||||||
|
- sizeof(void *), "memory_subsys.private", FAULT_ON_ERROR);
|
||||||
|
+ /*
|
||||||
|
+ * v6.3-rc1
|
||||||
|
+ * d2bf38c088e0 driver core: remove private pointer from struct bus_type
|
||||||
|
+ */
|
||||||
|
+ if (INVALID_MEMBER(bus_type_p)) {
|
||||||
|
+ int i, cnt;
|
||||||
|
+ char buf[32];
|
||||||
|
+ ulong bus_kset, list, name;
|
||||||
|
+
|
||||||
|
+ BZERO(ld, sizeof(struct list_data));
|
||||||
|
+
|
||||||
|
+ get_symbol_data("bus_kset", sizeof(ulong), &bus_kset);
|
||||||
|
+ readmem(bus_kset + OFFSET(kset_list), KVADDR, &list,
|
||||||
|
+ sizeof(ulong), "bus_kset.list", FAULT_ON_ERROR);
|
||||||
|
+
|
||||||
|
+ ld->flags |= LIST_ALLOCATE;
|
||||||
|
+ ld->start = list;
|
||||||
|
+ ld->end = bus_kset + OFFSET(kset_list);
|
||||||
|
+ ld->list_head_offset = OFFSET(kobject_entry);
|
||||||
|
+
|
||||||
|
+ cnt = do_list(ld);
|
||||||
|
+ for (i = 0; i < cnt; i++) {
|
||||||
|
+ readmem(ld->list_ptr[i] + OFFSET(kobject_name), KVADDR, &name,
|
||||||
|
+ sizeof(ulong), "kobject.name", FAULT_ON_ERROR);
|
||||||
|
+ read_string(name, buf, sizeof(buf)-1);
|
||||||
|
+ if (CRASHDEBUG(1))
|
||||||
|
+ fprintf(fp, "kobject: %lx name: %s\n", ld->list_ptr[i], buf);
|
||||||
|
+ if (STREQ(buf, "memory")) {
|
||||||
|
+ /* entry is subsys_private.subsys.kobj. See bus_to_subsys(). */
|
||||||
|
+ private = ld->list_ptr[i] - OFFSET(kset_kobj)
|
||||||
|
+ - OFFSET(subsys_private_subsys);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ FREEBUF(ld->list_ptr);
|
||||||
|
+ } else {
|
||||||
|
+ ulong memory_subsys = symbol_value("memory_subsys");
|
||||||
|
+ readmem(memory_subsys + OFFSET(bus_type_p), KVADDR, &private,
|
||||||
|
+ sizeof(void *), "memory_subsys.private", FAULT_ON_ERROR);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!private)
|
||||||
|
+ error(FATAL, "cannot determine subsys_private for memory.\n");
|
||||||
|
+
|
||||||
|
klist = private + OFFSET(subsys_private_klist_devices) +
|
||||||
|
OFFSET(klist_k_list);
|
||||||
|
BZERO(ld, sizeof(struct list_data));
|
||||||
|
@@ -17875,7 +17927,6 @@ dump_memory_blocks(int initialize)
|
||||||
|
ulong memory_block, device;
|
||||||
|
ulong *klistbuf;
|
||||||
|
int klistcnt, i;
|
||||||
|
- struct list_data list_data;
|
||||||
|
char mb_hdr[BUFSIZE];
|
||||||
|
char paddr_hdr[BUFSIZE];
|
||||||
|
char buf1[BUFSIZE];
|
||||||
|
@@ -17892,7 +17943,7 @@ dump_memory_blocks(int initialize)
|
||||||
|
if (initialize)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- init_memory_block(&list_data, &klistcnt, &klistbuf);
|
||||||
|
+ init_memory_block(&klistcnt, &klistbuf);
|
||||||
|
|
||||||
|
if ((symbol_exists("memory_block_size_probed")) ||
|
||||||
|
(MEMBER_EXISTS("memory_block", "end_section_nr")))
|
||||||
|
diff --git a/symbols.c b/symbols.c
|
||||||
|
index 158c95459bec..1d083b876f87 100644
|
||||||
|
--- a/symbols.c
|
||||||
|
+++ b/symbols.c
|
||||||
|
@@ -10416,6 +10416,7 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
|
OFFSET(kobject_entry));
|
||||||
|
fprintf(fp, " kset_list: %ld\n",
|
||||||
|
OFFSET(kset_list));
|
||||||
|
+ fprintf(fp, " kset_kobj: %ld\n", OFFSET(kset_kobj));
|
||||||
|
fprintf(fp, " request_list_count: %ld\n",
|
||||||
|
OFFSET(request_list_count));
|
||||||
|
fprintf(fp, " request_cmd_flags: %ld\n",
|
||||||
|
@@ -10453,6 +10454,7 @@ dump_offset_table(char *spec, ulong makestruct)
|
||||||
|
fprintf(fp, " blk_mq_tags_rqs: %ld\n",
|
||||||
|
OFFSET(blk_mq_tags_rqs));
|
||||||
|
|
||||||
|
+ fprintf(fp, " subsys_private_subsys: %ld\n", OFFSET(subsys_private_subsys));
|
||||||
|
fprintf(fp, " subsys_private_klist_devices: %ld\n",
|
||||||
|
OFFSET(subsys_private_klist_devices));
|
||||||
|
fprintf(fp, " subsystem_kset: %ld\n",
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
33
SOURCES/0082-xen-fix-stacksize.patch
Normal file
33
SOURCES/0082-xen-fix-stacksize.patch
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
From ba48bd462728515dd3eed562f1a97125e3417ceb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Juergen Gross <jgross@suse.com>
|
||||||
|
Date: Wed, 15 Mar 2023 12:18:48 +0100
|
||||||
|
Subject: [PATCH 82/89] xen: fix stacksize
|
||||||
|
|
||||||
|
The size of the percpu stack area of Xen on x86_64 is 8 pages, not 2.
|
||||||
|
This is the case since Xen commit 0b630aa340ec in 2007.
|
||||||
|
|
||||||
|
While not really critical in its current usage, it should be corrected
|
||||||
|
nevertheless.
|
||||||
|
|
||||||
|
Signed-off-by: Juergen Gross <jgross@suse.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
x86_64.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/x86_64.c b/x86_64.c
|
||||||
|
index 86abea00c9d6..619b9f566613 100644
|
||||||
|
--- a/x86_64.c
|
||||||
|
+++ b/x86_64.c
|
||||||
|
@@ -8104,7 +8104,7 @@ x86_64_init_hyper(int when)
|
||||||
|
machdep->pageshift = ffs(machdep->pagesize) - 1;
|
||||||
|
machdep->pageoffset = machdep->pagesize - 1;
|
||||||
|
machdep->pagemask = ~((ulonglong)machdep->pageoffset);
|
||||||
|
- machdep->stacksize = machdep->pagesize * 2;
|
||||||
|
+ machdep->stacksize = machdep->pagesize * 8;
|
||||||
|
if ((machdep->pgd = (char *)malloc(PAGESIZE())) == NULL)
|
||||||
|
error(FATAL, "cannot malloc pgd space.");
|
||||||
|
if ((machdep->pud = (char *)malloc(PAGESIZE())) == NULL)
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,111 @@
|
|||||||
|
From 907516256dd60ed20feaa2a8fd9e2bf148099ec3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Juergen Gross <jgross@suse.com>
|
||||||
|
Date: Wed, 15 Mar 2023 12:18:49 +0100
|
||||||
|
Subject: [PATCH 83/89] xen: get stack address via stack_base array if
|
||||||
|
available
|
||||||
|
|
||||||
|
Since many years now the stack address of each percpu stack is
|
||||||
|
available via the stack_base[] array (Xen commit 3cb68d2b59ab made
|
||||||
|
it visible). Use that instead of the indirect method via the percpu
|
||||||
|
variables tss_init or tss_page, especially as the layout of tss_page
|
||||||
|
has changed in Xen 4.16 (Xen commit 91d26ed304ff5), resulting in the
|
||||||
|
stack no longer to be found.
|
||||||
|
|
||||||
|
Signed-off-by: Juergen Gross <jgross@suse.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
xen_hyper.c | 56 ++++++++++++++++++++++++++++++-----------------------
|
||||||
|
1 file changed, 32 insertions(+), 24 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/xen_hyper.c b/xen_hyper.c
|
||||||
|
index 1030c0ae25d7..19501de94f4b 100644
|
||||||
|
--- a/xen_hyper.c
|
||||||
|
+++ b/xen_hyper.c
|
||||||
|
@@ -324,7 +324,7 @@ void
|
||||||
|
xen_hyper_x86_pcpu_init(void)
|
||||||
|
{
|
||||||
|
ulong cpu_info;
|
||||||
|
- ulong init_tss_base, init_tss;
|
||||||
|
+ ulong init_tss_base, init_tss, stack_base = 0;
|
||||||
|
ulong sp;
|
||||||
|
struct xen_hyper_pcpu_context *pcc;
|
||||||
|
char *buf, *bp;
|
||||||
|
@@ -340,34 +340,40 @@ xen_hyper_x86_pcpu_init(void)
|
||||||
|
}
|
||||||
|
/* get physical cpu context */
|
||||||
|
xen_hyper_alloc_pcpu_context_space(XEN_HYPER_MAX_CPUS());
|
||||||
|
- if (symbol_exists("per_cpu__init_tss")) {
|
||||||
|
+ if (symbol_exists("stack_base")) {
|
||||||
|
+ stack_base = symbol_value("stack_base");
|
||||||
|
+ flag = 0;
|
||||||
|
+ } else if (symbol_exists("per_cpu__init_tss")) {
|
||||||
|
init_tss_base = symbol_value("per_cpu__init_tss");
|
||||||
|
- flag = TRUE;
|
||||||
|
+ flag = 1;
|
||||||
|
} else if (symbol_exists("per_cpu__tss_page")) {
|
||||||
|
- init_tss_base = symbol_value("per_cpu__tss_page");
|
||||||
|
- flag = TRUE;
|
||||||
|
+ init_tss_base = symbol_value("per_cpu__tss_page");
|
||||||
|
+ flag = 1;
|
||||||
|
} else {
|
||||||
|
init_tss_base = symbol_value("init_tss");
|
||||||
|
- flag = FALSE;
|
||||||
|
+ flag = 2;
|
||||||
|
}
|
||||||
|
- buf = GETBUF(XEN_HYPER_SIZE(tss));
|
||||||
|
+ if (flag)
|
||||||
|
+ buf = GETBUF(XEN_HYPER_SIZE(tss));
|
||||||
|
for_cpu_indexes(i, cpuid)
|
||||||
|
{
|
||||||
|
- if (flag)
|
||||||
|
- init_tss = xen_hyper_per_cpu(init_tss_base, cpuid);
|
||||||
|
- else
|
||||||
|
- init_tss = init_tss_base +
|
||||||
|
- XEN_HYPER_SIZE(tss) * cpuid;
|
||||||
|
- if (!readmem(init_tss, KVADDR, buf,
|
||||||
|
- XEN_HYPER_SIZE(tss), "init_tss", RETURN_ON_ERROR)) {
|
||||||
|
- error(FATAL, "cannot read init_tss.\n");
|
||||||
|
- }
|
||||||
|
- if (machine_type("X86")) {
|
||||||
|
- sp = ULONG(buf + XEN_HYPER_OFFSET(tss_esp0));
|
||||||
|
- } else if (machine_type("X86_64")) {
|
||||||
|
- sp = ULONG(buf + XEN_HYPER_OFFSET(tss_rsp0));
|
||||||
|
- } else
|
||||||
|
- sp = 0;
|
||||||
|
+ if (flag) {
|
||||||
|
+ if (flag == 1)
|
||||||
|
+ init_tss = xen_hyper_per_cpu(init_tss_base, cpuid);
|
||||||
|
+ else
|
||||||
|
+ init_tss = init_tss_base + XEN_HYPER_SIZE(tss) * cpuid;
|
||||||
|
+ readmem(init_tss, KVADDR, buf,
|
||||||
|
+ XEN_HYPER_SIZE(tss), "init_tss", FAULT_ON_ERROR);
|
||||||
|
+ if (machine_type("X86")) {
|
||||||
|
+ sp = ULONG(buf + XEN_HYPER_OFFSET(tss_esp0));
|
||||||
|
+ } else if (machine_type("X86_64")) {
|
||||||
|
+ sp = ULONG(buf + XEN_HYPER_OFFSET(tss_rsp0));
|
||||||
|
+ } else
|
||||||
|
+ sp = 0;
|
||||||
|
+ } else {
|
||||||
|
+ readmem(stack_base + sizeof(ulong) * cpuid, KVADDR, &sp,
|
||||||
|
+ sizeof(ulong), "stack_base", FAULT_ON_ERROR);
|
||||||
|
+ }
|
||||||
|
cpu_info = XEN_HYPER_GET_CPU_INFO(sp);
|
||||||
|
if (CRASHDEBUG(1)) {
|
||||||
|
fprintf(fp, "sp=%lx, cpu_info=%lx\n", sp, cpu_info);
|
||||||
|
@@ -377,9 +383,11 @@ xen_hyper_x86_pcpu_init(void)
|
||||||
|
}
|
||||||
|
pcc = &xhpct->context_array[cpuid];
|
||||||
|
xen_hyper_store_pcpu_context(pcc, cpu_info, bp);
|
||||||
|
- xen_hyper_store_pcpu_context_tss(pcc, init_tss, buf);
|
||||||
|
+ if (flag)
|
||||||
|
+ xen_hyper_store_pcpu_context_tss(pcc, init_tss, buf);
|
||||||
|
}
|
||||||
|
- FREEBUF(buf);
|
||||||
|
+ if (flag)
|
||||||
|
+ FREEBUF(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(IA64)
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
178
SOURCES/0084-xen-adjust-to-new-scheduler-structures.patch
Normal file
178
SOURCES/0084-xen-adjust-to-new-scheduler-structures.patch
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
From 9e8155297e16f8d8804d151dd75cc489447c1fe7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Juergen Gross <jgross@suse.com>
|
||||||
|
Date: Wed, 15 Mar 2023 12:18:50 +0100
|
||||||
|
Subject: [PATCH 84/89] xen: adjust to new scheduler structures
|
||||||
|
|
||||||
|
There has been a significant modification regarding scheduler data in
|
||||||
|
the Xen hypervisor (Xen commit d62fefa4d459). Adapt to new structures
|
||||||
|
and removed fields.
|
||||||
|
|
||||||
|
Note that this is only the bare minimum to not let crash error out when
|
||||||
|
opening a vmcore in Xen mode with a recent Xen version.
|
||||||
|
|
||||||
|
Signed-off-by: Juergen Gross <jgross@suse.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
xen_hyper.c | 63 +++++++++++++++++++++++++++--------------
|
||||||
|
xen_hyper_defs.h | 4 ++-
|
||||||
|
xen_hyper_dump_tables.c | 4 +++
|
||||||
|
3 files changed, 49 insertions(+), 22 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/xen_hyper.c b/xen_hyper.c
|
||||||
|
index 19501de94f4b..dbbfdaa3c154 100644
|
||||||
|
--- a/xen_hyper.c
|
||||||
|
+++ b/xen_hyper.c
|
||||||
|
@@ -415,13 +415,21 @@ void
|
||||||
|
xen_hyper_misc_init(void)
|
||||||
|
{
|
||||||
|
XEN_HYPER_STRUCT_SIZE_INIT(schedule_data, "schedule_data");
|
||||||
|
- XEN_HYPER_MEMBER_OFFSET_INIT(schedule_data_schedule_lock, "schedule_data", "schedule_lock");
|
||||||
|
- XEN_HYPER_MEMBER_OFFSET_INIT(schedule_data_curr, "schedule_data", "curr");
|
||||||
|
- if (MEMBER_EXISTS("schedule_data", "idle"))
|
||||||
|
- XEN_HYPER_MEMBER_OFFSET_INIT(schedule_data_idle, "schedule_data", "idle");
|
||||||
|
- XEN_HYPER_MEMBER_OFFSET_INIT(schedule_data_sched_priv, "schedule_data", "sched_priv");
|
||||||
|
- XEN_HYPER_MEMBER_OFFSET_INIT(schedule_data_s_timer, "schedule_data", "s_timer");
|
||||||
|
- XEN_HYPER_MEMBER_OFFSET_INIT(schedule_data_tick, "schedule_data", "tick");
|
||||||
|
+ XEN_HYPER_STRUCT_SIZE_INIT(sched_resource, "sched_resource");
|
||||||
|
+ if (XEN_HYPER_VALID_SIZE(schedule_data)) {
|
||||||
|
+ XEN_HYPER_MEMBER_OFFSET_INIT(schedule_data_schedule_lock, "schedule_data", "schedule_lock");
|
||||||
|
+ XEN_HYPER_MEMBER_OFFSET_INIT(schedule_data_curr, "schedule_data", "curr");
|
||||||
|
+ if (MEMBER_EXISTS("schedule_data", "idle"))
|
||||||
|
+ XEN_HYPER_MEMBER_OFFSET_INIT(schedule_data_idle, "schedule_data", "idle");
|
||||||
|
+ XEN_HYPER_MEMBER_OFFSET_INIT(schedule_data_sched_priv, "schedule_data", "sched_priv");
|
||||||
|
+ XEN_HYPER_MEMBER_OFFSET_INIT(schedule_data_s_timer, "schedule_data", "s_timer");
|
||||||
|
+ XEN_HYPER_MEMBER_OFFSET_INIT(schedule_data_tick, "schedule_data", "tick");
|
||||||
|
+ } else if (XEN_HYPER_VALID_SIZE(sched_resource)) {
|
||||||
|
+ XEN_HYPER_MEMBER_OFFSET_INIT(schedule_data_schedule_lock, "sched_resource", "schedule_lock");
|
||||||
|
+ XEN_HYPER_MEMBER_OFFSET_INIT(schedule_data_curr, "sched_resource", "curr");
|
||||||
|
+ XEN_HYPER_MEMBER_OFFSET_INIT(schedule_data_sched_priv, "sched_resource", "sched_priv");
|
||||||
|
+ XEN_HYPER_MEMBER_OFFSET_INIT(schedule_data_s_timer, "sched_resource", "s_timer");
|
||||||
|
+ }
|
||||||
|
|
||||||
|
XEN_HYPER_STRUCT_SIZE_INIT(scheduler, "scheduler");
|
||||||
|
XEN_HYPER_MEMBER_OFFSET_INIT(scheduler_name, "scheduler", "name");
|
||||||
|
@@ -465,6 +473,7 @@ xen_hyper_schedule_init(void)
|
||||||
|
long *schedulers_buf;
|
||||||
|
int nr_schedulers;
|
||||||
|
struct xen_hyper_sched_context *schc;
|
||||||
|
+ long buf_size;
|
||||||
|
char *buf;
|
||||||
|
char opt_name_buf[XEN_HYPER_OPT_SCHED_SIZE];
|
||||||
|
int i, cpuid, flag;
|
||||||
|
@@ -559,28 +568,39 @@ xen_hyper_schedule_init(void)
|
||||||
|
}
|
||||||
|
BZERO(xhscht->sched_context_array,
|
||||||
|
sizeof(struct xen_hyper_sched_context) * XEN_HYPER_MAX_CPUS());
|
||||||
|
- buf = GETBUF(XEN_HYPER_SIZE(schedule_data));
|
||||||
|
- if (symbol_exists("per_cpu__schedule_data")) {
|
||||||
|
+ if (symbol_exists("per_cpu__sched_res")) {
|
||||||
|
+ addr = symbol_value("per_cpu__sched_res");
|
||||||
|
+ buf_size = XEN_HYPER_SIZE(sched_resource);
|
||||||
|
+ flag = 0;
|
||||||
|
+ } else if (symbol_exists("per_cpu__schedule_data")) {
|
||||||
|
addr = symbol_value("per_cpu__schedule_data");
|
||||||
|
- flag = TRUE;
|
||||||
|
+ buf_size = XEN_HYPER_SIZE(schedule_data);
|
||||||
|
+ flag = 1;
|
||||||
|
} else {
|
||||||
|
addr = symbol_value("schedule_data");
|
||||||
|
- flag = FALSE;
|
||||||
|
+ buf_size = XEN_HYPER_SIZE(schedule_data);
|
||||||
|
+ flag = 2;
|
||||||
|
}
|
||||||
|
+ buf = GETBUF(buf_size);
|
||||||
|
for_cpu_indexes(i, cpuid)
|
||||||
|
{
|
||||||
|
schc = &xhscht->sched_context_array[cpuid];
|
||||||
|
if (flag) {
|
||||||
|
- schc->schedule_data =
|
||||||
|
- xen_hyper_per_cpu(addr, i);
|
||||||
|
+ if (flag == 1) {
|
||||||
|
+ schc->schedule_data =
|
||||||
|
+ xen_hyper_per_cpu(addr, i);
|
||||||
|
+ } else {
|
||||||
|
+ schc->schedule_data = addr +
|
||||||
|
+ XEN_HYPER_SIZE(schedule_data) * i;
|
||||||
|
+ }
|
||||||
|
+ readmem(schc->schedule_data,
|
||||||
|
+ KVADDR, buf, XEN_HYPER_SIZE(schedule_data),
|
||||||
|
+ "schedule_data", FAULT_ON_ERROR);
|
||||||
|
} else {
|
||||||
|
- schc->schedule_data = addr +
|
||||||
|
- XEN_HYPER_SIZE(schedule_data) * i;
|
||||||
|
- }
|
||||||
|
- if (!readmem(schc->schedule_data,
|
||||||
|
- KVADDR, buf, XEN_HYPER_SIZE(schedule_data),
|
||||||
|
- "schedule_data", RETURN_ON_ERROR)) {
|
||||||
|
- error(FATAL, "cannot read schedule_data.\n");
|
||||||
|
+ schc->sched_resource = xen_hyper_per_cpu(addr, i);
|
||||||
|
+ readmem(schc->sched_resource,
|
||||||
|
+ KVADDR, buf, XEN_HYPER_SIZE(sched_resource),
|
||||||
|
+ "sched_resource", FAULT_ON_ERROR);
|
||||||
|
}
|
||||||
|
schc->cpu_id = cpuid;
|
||||||
|
schc->curr = ULONG(buf + XEN_HYPER_OFFSET(schedule_data_curr));
|
||||||
|
@@ -1597,7 +1617,8 @@ xen_hyper_store_vcpu_context(struct xen_hyper_vcpu_context *vcc,
|
||||||
|
vcc->next_in_list = ULONG(vcp + XEN_HYPER_OFFSET(vcpu_next_in_list));
|
||||||
|
if (XEN_HYPER_VALID_MEMBER(vcpu_sleep_tick))
|
||||||
|
vcc->sleep_tick = ULONG(vcp + XEN_HYPER_OFFSET(vcpu_sleep_tick));
|
||||||
|
- vcc->sched_priv = ULONG(vcp + XEN_HYPER_OFFSET(vcpu_sched_priv));
|
||||||
|
+ if (XEN_HYPER_VALID_MEMBER(vcpu_sched_priv))
|
||||||
|
+ vcc->sched_priv = ULONG(vcp + XEN_HYPER_OFFSET(vcpu_sched_priv));
|
||||||
|
vcc->state = INT(vcp + XEN_HYPER_OFFSET(vcpu_runstate) +
|
||||||
|
XEN_HYPER_OFFSET(vcpu_runstate_info_state));
|
||||||
|
vcc->state_entry_time = ULONGLONG(vcp +
|
||||||
|
diff --git a/xen_hyper_defs.h b/xen_hyper_defs.h
|
||||||
|
index acf910abe15e..dccc6ebff109 100644
|
||||||
|
--- a/xen_hyper_defs.h
|
||||||
|
+++ b/xen_hyper_defs.h
|
||||||
|
@@ -551,6 +551,7 @@ struct xen_hyper_sched_context {
|
||||||
|
ulong idle;
|
||||||
|
ulong sched_priv;
|
||||||
|
ulong tick;
|
||||||
|
+ ulong sched_resource;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct xen_hyper_sched_table {
|
||||||
|
@@ -602,6 +603,7 @@ struct xen_hyper_size_table {
|
||||||
|
long vcpu;
|
||||||
|
long vcpu_runstate_info;
|
||||||
|
long xen_crash_xen_regs_t; /* elf note v2 */
|
||||||
|
+ long sched_resource;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct xen_hyper_offset_table {
|
||||||
|
@@ -692,7 +694,7 @@ struct xen_hyper_offset_table {
|
||||||
|
/* mm_struct */
|
||||||
|
long mm_struct_pgd;
|
||||||
|
#endif
|
||||||
|
- /* schedule_data */
|
||||||
|
+ /* schedule_data or sched_resource */
|
||||||
|
long schedule_data_schedule_lock;
|
||||||
|
long schedule_data_curr;
|
||||||
|
long schedule_data_idle;
|
||||||
|
diff --git a/xen_hyper_dump_tables.c b/xen_hyper_dump_tables.c
|
||||||
|
index 0360d25740ac..227ffc4ae4e4 100644
|
||||||
|
--- a/xen_hyper_dump_tables.c
|
||||||
|
+++ b/xen_hyper_dump_tables.c
|
||||||
|
@@ -558,6 +558,8 @@ xen_hyper_dump_xen_hyper_sched_table(int verbose)
|
||||||
|
flag, (buf, "%d]\n", i));
|
||||||
|
XEN_HYPER_PRI(fp, len, "schedule_data: ", buf, flag,
|
||||||
|
(buf, "%lx\n", schc->schedule_data));
|
||||||
|
+ XEN_HYPER_PRI(fp, len, "sched_resource: ", buf, flag,
|
||||||
|
+ (buf, "%lx\n", schc->sched_resource));
|
||||||
|
XEN_HYPER_PRI(fp, len, "curr: ", buf, flag,
|
||||||
|
(buf, "%lx\n", schc->curr));
|
||||||
|
XEN_HYPER_PRI(fp, len, "idle: ", buf, flag,
|
||||||
|
@@ -630,6 +632,8 @@ xen_hyper_dump_xen_hyper_size_table(char *spec, ulong makestruct)
|
||||||
|
(buf, "%ld\n", xen_hyper_size_table.note_buf_t));
|
||||||
|
XEN_HYPER_PRI(fp, len, "schedule_data: ", buf, flag,
|
||||||
|
(buf, "%ld\n", xen_hyper_size_table.schedule_data));
|
||||||
|
+ XEN_HYPER_PRI(fp, len, "sched_resource: ", buf, flag,
|
||||||
|
+ (buf, "%ld\n", xen_hyper_size_table.sched_resource));
|
||||||
|
XEN_HYPER_PRI(fp, len, "scheduler: ", buf, flag,
|
||||||
|
(buf, "%ld\n", xen_hyper_size_table.scheduler));
|
||||||
|
XEN_HYPER_PRI(fp, len, "shared_info: ", buf, flag,
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,70 @@
|
|||||||
|
From 1cebb3d75b45fedc734dac8563782a3e6d86f23b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Date: Thu, 23 Mar 2023 13:18:07 +0800
|
||||||
|
Subject: [PATCH 85/89] Fix "vm -M" option to properly deal with an invalid
|
||||||
|
argument
|
||||||
|
|
||||||
|
The "vm -M" option can accept an invalid address and print the virtual
|
||||||
|
memory data of a task without an error like this:
|
||||||
|
|
||||||
|
crash> vm -M 0xdeadbeef
|
||||||
|
PID: 92960 TASK: ffff99157976cc80 CPU: 0 COMMAND: "crash"
|
||||||
|
MM PGD RSS TOTAL_VM
|
||||||
|
ffff991573bfdf00 ffff9915857f2000 449020k 2427076k
|
||||||
|
VMA START END FLAGS FILE
|
||||||
|
ffff99158718d1c8 400000 4de000 8000071 /home/crash/crash
|
||||||
|
...
|
||||||
|
|
||||||
|
The reasons are
|
||||||
|
- htoll() only converts a hexadecimal string to an unsigned long long
|
||||||
|
value and does not evaluate whether it's a valid kernel virtual
|
||||||
|
address or not, and
|
||||||
|
- The specified value is used only when the task's mm_struct is NULL.
|
||||||
|
|
||||||
|
Also, this behavior is not described enough in its help text, so it's
|
||||||
|
confusing for users.
|
||||||
|
|
||||||
|
Let's add a check on the converted value regardless of the task's
|
||||||
|
mm_struct and add a description of the behavior to its help text.
|
||||||
|
|
||||||
|
With the patch:
|
||||||
|
crash> vm -M 0xdeadbeef
|
||||||
|
vm: invalid mm_struct address: 0xdeadbeef
|
||||||
|
|
||||||
|
Reported-by: Buland Kumar Singh <bsingh@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
[ kh: rewrote commit message ]
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
---
|
||||||
|
help.c | 1 +
|
||||||
|
memory.c | 2 ++
|
||||||
|
2 files changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/help.c b/help.c
|
||||||
|
index 7ceefa06732b..738bbca2e563 100644
|
||||||
|
--- a/help.c
|
||||||
|
+++ b/help.c
|
||||||
|
@@ -4701,6 +4701,7 @@ char *help_vm[] = {
|
||||||
|
" However, if the address can be determined from the kernel stack,",
|
||||||
|
" it can be entered manually in order to try to resurrect the",
|
||||||
|
" virtual memory data of the task.",
|
||||||
|
+" NOTE: this option is only used when the task's mm_struct is NULL.",
|
||||||
|
" -R reference search for references to this number or filename.",
|
||||||
|
" -m dump the mm_struct associated with the task.",
|
||||||
|
" -v dump all of the vm_area_structs associated with the task.",
|
||||||
|
diff --git a/memory.c b/memory.c
|
||||||
|
index 592a5ef49d50..0568f18eb9b7 100644
|
||||||
|
--- a/memory.c
|
||||||
|
+++ b/memory.c
|
||||||
|
@@ -3559,6 +3559,8 @@ cmd_vm(void)
|
||||||
|
case 'M':
|
||||||
|
pc->curcmd_private = htoll(optarg, FAULT_ON_ERROR, NULL);
|
||||||
|
pc->curcmd_flags |= MM_STRUCT_FORCE;
|
||||||
|
+ if (!IS_KVADDR(pc->curcmd_private))
|
||||||
|
+ error(FATAL, "invalid mm_struct address: %s\n", optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,81 @@
|
|||||||
|
From a83349d6ce9773f151a7f88e032c259f94a2fbde Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Date: Mon, 10 Apr 2023 11:41:16 +0800
|
||||||
|
Subject: [PATCH 86/89] Fix "fuser" command to properly deal with an invalid
|
||||||
|
argument
|
||||||
|
|
||||||
|
The man page of the "fuser" command suggests that the argument can be a
|
||||||
|
full pathname or inode address. However, the "fuser" command accepts an
|
||||||
|
invalid argument and prints a bogus result as below:
|
||||||
|
|
||||||
|
crash> fuser x
|
||||||
|
PID TASK COMM USAGE
|
||||||
|
100507 ffff9914431f4c80 "packagekitd" fd
|
||||||
|
100508 ffff991574e59980 "gmain" fd
|
||||||
|
100509 ffff9914431f3300 "gdbus" fd
|
||||||
|
102020 ffff991574400000 "sshd" fd
|
||||||
|
102043 ffff991441d19980 "sshd" fd
|
||||||
|
|
||||||
|
The current fuser command has no checking mechanism to determine if an
|
||||||
|
argument is valid or not. Let's add it to handle such cases.
|
||||||
|
|
||||||
|
With the patch:
|
||||||
|
crash> fuser x
|
||||||
|
fuser: invalid argument: x
|
||||||
|
|
||||||
|
In addition, also add a note that fuser does not expect an argument other
|
||||||
|
than an inode address and full pathname, and if others are specified, the
|
||||||
|
output can be an unexpected result.
|
||||||
|
|
||||||
|
Reported-by: Buland Kumar Singh <bsingh@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
---
|
||||||
|
filesys.c | 8 +++++++-
|
||||||
|
help.c | 4 ++++
|
||||||
|
2 files changed, 11 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/filesys.c b/filesys.c
|
||||||
|
index d64b54a9b822..1d0ee7f0b24a 100644
|
||||||
|
--- a/filesys.c
|
||||||
|
+++ b/filesys.c
|
||||||
|
@@ -3398,6 +3398,7 @@ cmd_fuser(void)
|
||||||
|
char fuser_header[BUFSIZE];
|
||||||
|
int doing_fds, doing_mmap, len;
|
||||||
|
int fuser_header_printed, lockd_header_printed;
|
||||||
|
+ ulong spec_addr;
|
||||||
|
|
||||||
|
while ((c = getopt(argcnt, args, "")) != EOF) {
|
||||||
|
switch(c)
|
||||||
|
@@ -3421,7 +3422,12 @@ cmd_fuser(void)
|
||||||
|
|
||||||
|
doing_fds = doing_mmap = 0;
|
||||||
|
while (args[optind]) {
|
||||||
|
- spec_string = args[optind];
|
||||||
|
+ spec_string = args[optind];
|
||||||
|
+ spec_addr = htol(spec_string, RETURN_ON_ERROR|QUIET, NULL);
|
||||||
|
+ if ((spec_addr == BADADDR || !IS_KVADDR(spec_addr)) &&
|
||||||
|
+ spec_string[0] != '/')
|
||||||
|
+ error(FATAL, "invalid argument: %s\n", args[optind]);
|
||||||
|
+
|
||||||
|
if (STRNEQ(spec_string, "0x") && hexadecimal(spec_string, 0))
|
||||||
|
shift_string_left(spec_string, 2);
|
||||||
|
len = strlen(spec_string);
|
||||||
|
diff --git a/help.c b/help.c
|
||||||
|
index 738bbca2e563..26f0d75b8699 100644
|
||||||
|
--- a/help.c
|
||||||
|
+++ b/help.c
|
||||||
|
@@ -7996,6 +7996,10 @@ char *help_fuser[] = {
|
||||||
|
" listed.\n",
|
||||||
|
" pathname the full pathname of the file.",
|
||||||
|
" inode the hexadecimal inode address for the file.",
|
||||||
|
+"",
|
||||||
|
+" NOTE: This commmand does not expect arguments other than inode address",
|
||||||
|
+" or full pathname. If others are specified, the command may accept them,",
|
||||||
|
+" but an unexpected output can be displayed.",
|
||||||
|
"\nEXAMPLES",
|
||||||
|
" Display the tasks using file /usr/lib/libkfm.so.2.0.0\n",
|
||||||
|
" %s> fuser /usr/lib/libkfm.so.2.0.0",
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,115 @@
|
|||||||
|
From a447ef800c93ab5bbde91a1e7751cf13c2e831fb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tao Liu <ltao@redhat.com>
|
||||||
|
Date: Thu, 20 Apr 2023 18:25:22 +0800
|
||||||
|
Subject: [PATCH 87/89] Replace lseek/read into pread for kcore and vmcore
|
||||||
|
reading
|
||||||
|
|
||||||
|
Previously crash uses lseek/read for kcore and vmcore reading, this involves
|
||||||
|
2 syscalls. And we can replace them with pread, only 1 syscall is needed for
|
||||||
|
kcore/vmcore reading, and we can have a better performance. Please note there
|
||||||
|
are plenty of places in crash using lseek/read, this patch doesn't modify all
|
||||||
|
of them, just the most commonly used kcore and diskdump vmcore reading.
|
||||||
|
|
||||||
|
Signed-off-by: Tao Liu <ltao@redhat.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
diskdump.c | 25 +++++++++++++++++++------
|
||||||
|
netdump.c | 15 ++++++++++-----
|
||||||
|
2 files changed, 29 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/diskdump.c b/diskdump.c
|
||||||
|
index 90e67d7df1db..1f3685cea89e 100644
|
||||||
|
--- a/diskdump.c
|
||||||
|
+++ b/diskdump.c
|
||||||
|
@@ -515,16 +515,22 @@ arm_kdump_header_adjust(int header_version)
|
||||||
|
static int
|
||||||
|
read_pd(int fd, off_t offset, page_desc_t *pd)
|
||||||
|
{
|
||||||
|
- const off_t failed = (off_t)-1;
|
||||||
|
+ int ret;
|
||||||
|
|
||||||
|
if (FLAT_FORMAT()) {
|
||||||
|
if (!read_flattened_format(fd, offset, pd, sizeof(*pd)))
|
||||||
|
return READ_ERROR;
|
||||||
|
} else {
|
||||||
|
- if (lseek(fd, offset, SEEK_SET) == failed)
|
||||||
|
+ if (offset < 0) {
|
||||||
|
+ if (CRASHDEBUG(8))
|
||||||
|
+ fprintf(fp, "read_pd: invalid offset: %lx\n", offset);
|
||||||
|
return SEEK_ERROR;
|
||||||
|
- if (read(fd, pd, sizeof(*pd)) != sizeof(*pd))
|
||||||
|
+ }
|
||||||
|
+ if ((ret = pread(fd, pd, sizeof(*pd), offset)) != sizeof(*pd)) {
|
||||||
|
+ if (ret == -1 && CRASHDEBUG(8))
|
||||||
|
+ fprintf(fp, "read_pd: pread error: %s\n", strerror(errno));
|
||||||
|
return READ_ERROR;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -1125,7 +1131,6 @@ cache_page(physaddr_t paddr)
|
||||||
|
off_t seek_offset;
|
||||||
|
page_desc_t pd;
|
||||||
|
const int block_size = dd->block_size;
|
||||||
|
- const off_t failed = (off_t)-1;
|
||||||
|
ulong retlen;
|
||||||
|
#ifdef ZSTD
|
||||||
|
static ZSTD_DCtx *dctx = NULL;
|
||||||
|
@@ -1190,10 +1195,18 @@ cache_page(physaddr_t paddr)
|
||||||
|
return PAGE_INCOMPLETE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
- if (lseek(dd->dfd, pd.offset, SEEK_SET) == failed)
|
||||||
|
+ if (pd.offset < 0) {
|
||||||
|
+ if (CRASHDEBUG(8))
|
||||||
|
+ fprintf(fp, "read_diskdump/cache_page: invalid offset: %lx\n",
|
||||||
|
+ pd.offset);
|
||||||
|
return SEEK_ERROR;
|
||||||
|
- if (read(dd->dfd, dd->compressed_page, pd.size) != pd.size)
|
||||||
|
+ }
|
||||||
|
+ if ((ret = pread(dd->dfd, dd->compressed_page, pd.size, pd.offset)) != pd.size) {
|
||||||
|
+ if (ret == -1 && CRASHDEBUG(8))
|
||||||
|
+ fprintf(fp, "read_diskdump/cache_page: pread error: %s\n",
|
||||||
|
+ strerror(errno));
|
||||||
|
return READ_ERROR;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pd.flags & DUMP_DH_COMPRESSED_ZLIB) {
|
||||||
|
diff --git a/netdump.c b/netdump.c
|
||||||
|
index 4ef5807a641b..04a49e5515bb 100644
|
||||||
|
--- a/netdump.c
|
||||||
|
+++ b/netdump.c
|
||||||
|
@@ -4336,7 +4336,7 @@ no_nt_prstatus_exists:
|
||||||
|
int
|
||||||
|
read_proc_kcore(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
|
||||||
|
{
|
||||||
|
- int i;
|
||||||
|
+ int i, ret;
|
||||||
|
size_t readcnt;
|
||||||
|
ulong kvaddr;
|
||||||
|
Elf32_Phdr *lp32;
|
||||||
|
@@ -4436,11 +4436,16 @@ read_proc_kcore(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
|
||||||
|
if (offset == UNINITIALIZED)
|
||||||
|
return SEEK_ERROR;
|
||||||
|
|
||||||
|
- if (lseek(fd, offset, SEEK_SET) != offset)
|
||||||
|
- perror("lseek");
|
||||||
|
-
|
||||||
|
- if (read(fd, bufptr, readcnt) != readcnt)
|
||||||
|
+ if (offset < 0) {
|
||||||
|
+ if (CRASHDEBUG(8))
|
||||||
|
+ fprintf(fp, "read_proc_kcore: invalid offset: %lx\n", offset);
|
||||||
|
+ return SEEK_ERROR;
|
||||||
|
+ }
|
||||||
|
+ if ((ret = pread(fd, bufptr, readcnt, offset)) != readcnt) {
|
||||||
|
+ if (ret == -1 && CRASHDEBUG(8))
|
||||||
|
+ fprintf(fp, "read_proc_kcore: pread error: %s\n", strerror(errno));
|
||||||
|
return READ_ERROR;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
From a1d0ff0e0d113ada3b4baac25c583be7c96b0950 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
Date: Tue, 25 Apr 2023 09:31:04 +0900
|
||||||
|
Subject: [PATCH 88/89] Fix "net" command on kernel configured with
|
||||||
|
CONFIG_IPV6=m
|
||||||
|
|
||||||
|
On a kernel configured with CONFIG_IPV6=m, struct inet6_ifaddr is not
|
||||||
|
defined in kernel. Without the patch, the "net" command fails with the
|
||||||
|
following error.
|
||||||
|
|
||||||
|
net: invalid structure member offset: inet6_ifaddr_if_next
|
||||||
|
FILE: net.c LINE: 1017 FUNCTION: get_device_ip6_address()
|
||||||
|
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
---
|
||||||
|
net.c | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/net.c b/net.c
|
||||||
|
index 18c238be346d..31d3f2bf7c2f 100644
|
||||||
|
--- a/net.c
|
||||||
|
+++ b/net.c
|
||||||
|
@@ -996,6 +996,9 @@ get_device_ip6_address(ulong devaddr, char **bufp, long buflen)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (INVALID_MEMBER(inet6_ifaddr_if_next))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
readmem(ip6_ptr + OFFSET(inet6_dev_addr_list), KVADDR,
|
||||||
|
&addr, sizeof(void *), "inet6_dev.addr_list", FAULT_ON_ERROR);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
@ -0,0 +1,38 @@
|
|||||||
|
From 8986cceb699a27c720b42a9b2456f8e19d5422cd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
Date: Mon, 8 May 2023 17:05:49 +0800
|
||||||
|
Subject: [PATCH 89/89] gdb-7.6: fix for whatis command causes crash coredump
|
||||||
|
|
||||||
|
8ecb59f85679 ("Print non-Ada unions without crashing")
|
||||||
|
* cp-abi.c (value_rtti_type): Check HAVE_CPLUS_STRUCT.
|
||||||
|
|
||||||
|
This is a RHEL-Only patch.
|
||||||
|
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
gdb-7.6.patch | 12 ++++++++++++
|
||||||
|
1 file changed, 12 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/gdb-7.6.patch b/gdb-7.6.patch
|
||||||
|
index d0becd055666..f25f5f159e50 100644
|
||||||
|
--- a/gdb-7.6.patch
|
||||||
|
+++ b/gdb-7.6.patch
|
||||||
|
@@ -2601,3 +2601,15 @@ diff -up gdb-7.6/opcodes/configure.orig gdb-7.6/opcodes/configure
|
||||||
|
|
||||||
|
/* If the nearest symbol is too far away, don't print anything symbolic. */
|
||||||
|
|
||||||
|
+--- gdb-7.6/gdb/cp-abi.c.orig
|
||||||
|
++++ gdb-7.6/gdb/cp-abi.c
|
||||||
|
+@@ -113,7 +113,8 @@ value_rtti_type (struct value *v, int *full,
|
||||||
|
+ struct type *ret = NULL;
|
||||||
|
+ volatile struct gdb_exception e;
|
||||||
|
+
|
||||||
|
+- if ((current_cp_abi.rtti_type) == NULL)
|
||||||
|
++ if ((current_cp_abi.rtti_type) == NULL ||
|
||||||
|
++ !HAVE_CPLUS_STRUCT (check_typedef (value_type (v))))
|
||||||
|
+ return NULL;
|
||||||
|
+ TRY_CATCH (e, RETURN_MASK_ERROR)
|
||||||
|
+ {
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user