Merge branch 'c8-beta' into a8-beta

a8-beta changed/a8-beta/crash-7.3.2-4.el8.alma
eabdullin 2 months ago committed by root
commit 8231e9e47f

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -0,0 +1,111 @@
From 28a41ec7a471474094d8ab39f3a69b44d0f9ebcf Mon Sep 17 00:00:00 2001
From: Huang Shijie <shijie@os.amperecomputing.com>
Date: Mon, 22 Aug 2022 09:29:32 +0000
Subject: [PATCH 16/28] arm64: use TCR_EL1_T1SZ to get the correct info if
vabits_actual is missing
After kernel commit 0d9b1ffefabe ("arm64: mm: make vabits_actual a build
time constant if possible"), the vabits_actual is not compiled to kernel
symbols when "VA_BITS > 48" is false.
So the crash will not find the vabits_actual symbol, and it will fail
in the end like this:
# ./crash
...
WARNING: VA_BITS: calculated: 46 vmcoreinfo: 48
crash: invalid kernel virtual address: ffff88177ffff000 type: "pud page"
This patch introduces the arm64_set_va_bits_by_tcr(), and if crash cannot
find vabits_actual symbol, it will use the TCR_EL1_T1SZ register to get
the correct VA_BITS_ACTUAL/VA_BITS/VA_START.
Tested this patch with:
1.) the live mode with /proc/kcore
2.) the kdump file with /proc/vmcore.
Signed-off-by: Huang Shijie <shijie@os.amperecomputing.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
arm64.c | 51 ++++++++++++++++++++++++++++++++++-----------------
1 file changed, 34 insertions(+), 17 deletions(-)
diff --git a/arm64.c b/arm64.c
index b6b7aa11f4fe..c3e26a371a61 100644