Re: [Crash-utility] [PATCH] ppc64: do page traversal if vmemmap_list not populated
by lijiang
Hi, Aditya
Thank you for the patch.
On Mon, Sep 11, 2023 at 8:00 PM <crash-utility-request(a)redhat.com> wrote:
> From: Aditya Gupta <adityag(a)linux.ibm.com>
> To: crash-utility(a)redhat.com
> Cc: Hari Bathini <hbathini(a)linux.ibm.com>, Mahesh J Salgaonkar
> <mahesh(a)linux.ibm.com>, Sourabh Jain <sourabhjain(a)linux.ibm.com>,
> "Aneesh Kumar K.V" <aneesh.kumar(a)linux.ibm.com>
> Subject: [Crash-utility] [PATCH] ppc64: do page traversal if
> vmemmap_list not populated
> Message-ID: <20230911093032.419388-1-adityag(a)linux.ibm.com>
> Content-Type: text/plain; charset="US-ASCII"; x-default=true
>
> Currently 'crash-tool' fails on vmcore collected on upstream kernel on
> PowerPC64 with the error:
>
> crash: invalid kernel virtual address: 0 type: "first list entry
>
> Presently the address translation for vmemmap addresses is done using
> the vmemmap_list. But with the below commit in Linux, vmemmap_list can
> be empty, in case of Radix MMU on PowerPC64
>
> 368a0590d954: (powerpc/book3s64/vmemmap: switch radix to use a
> different vmemmap handling function)
>
> In case vmemmap_list is empty, then it's head is NULL, which crash tries
> to access and fails due to accessing NULL.
>
> Instead of depending on 'vmemmap_list' for address translation for
> vmemmap addresses, do a kernel pagetable walk to get the physical
> address associated with given virtual address
>
> Reviewed-by: Hari Bathini <hbathini(a)linux.ibm.com>
> Signed-off-by: Aditya Gupta <adityag(a)linux.ibm.com>
>
> ---
>
> Testing
> =======
>
> Git tree with patch applied:
> https://github.com/adi-g15-ibm/crash/tree/bugzilla-203296-list-v1
>
> This can be tested with '/proc/vmcore' as the vmcore, since makedumpfile
>
Can you help to describe in detail how to reproduce this issue? Or does
this require any kernel configs to be enabled first? I did not reproduce
the current issue with '/proc/kcore' or vmcore(via cp).
Test kernel commit: ce9ecca0238b ("Linux 6.6-rc2")
# ./crash /home/linux/vmlinux
/var/crash/127.0.0.1-2023-09-18-06\:58\:57/vmcore
crash 8.0.3++
Copyright (C) 2002-2022 Red Hat, Inc.
Copyright (C) 2004, 2005, 2006, 2010 IBM Corporation
Copyright (C) 1999-2006 Hewlett-Packard Co
Copyright (C) 2005, 2006, 2011, 2012 Fujitsu Limited
Copyright (C) 2006, 2007 VA Linux Systems Japan K.K.
Copyright (C) 2005, 2011, 2020-2022 NEC Corporation
Copyright (C) 1999, 2002, 2007 Silicon Graphics, Inc.
Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
Copyright (C) 2015, 2021 VMware, Inc.
This program is free software, covered by the GNU General Public License,
and you are welcome to change it and/or distribute copies of it under
certain conditions. Enter "help copying" to see the conditions.
This program has absolutely no warranty. Enter "help warranty" for details.
GNU gdb (GDB) 10.2
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html
>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "powerpc64le-unknown-linux-gnu".
Type "show configuration" for configuration details.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
KERNEL: /home/linux/vmlinux
DUMPFILE: /var/crash/127.0.0.1-2023-09-18-06:58:57/vmcore
CPUS: 8
DATE: Mon Sep 18 06:57:40 EDT 2023
UPTIME: 00:03:19
LOAD AVERAGE: 0.20, 0.31, 0.14
TASKS: 186
NODENAME: ibm-p9z-16-lp10.khw3.lab.eng.bos.redhat.com
RELEASE: 6.6.0-rc2
VERSION: #2 SMP Mon Sep 18 06:11:14 EDT 2023
MACHINE: ppc64le (2800 Mhz)
MEMORY: 16 GB
PANIC: "Kernel panic - not syncing: sysrq triggered crash"
PID: 4337
COMMAND: "bash"
TASK: c000000052a49900 [THREAD_INFO: c000000052a49900]
CPU: 3
STATE: TASK_RUNNING (PANIC)
crash>
Thanks
Lianbo
also fails in absence of 'vmemmap_list' in upstream linux
>
> The fix for makedumpfile will also been sent to upstream
>
> ---
> ---
> ppc64.c | 47 +++++++++++++++++++++++++++++++++--------------
> 1 file changed, 33 insertions(+), 14 deletions(-)
>
> diff --git a/ppc64.c b/ppc64.c
> index fc34006f4863..1e84c5f56773 100644
> --- a/ppc64.c
> +++ b/ppc64.c
> @@ -1280,8 +1280,30 @@ void ppc64_vmemmap_init(void)
> long backing_size, virt_addr_offset, phys_offset, list_offset;
> ulong *vmemmap_list;
> char *vmemmap_buf;
> - struct machine_specific *ms;
> -
> + struct machine_specific *ms = machdep->machspec;
> +
> + ld = &list_data;
> + BZERO(ld, sizeof(struct list_data));
> +
> + /*
> + * vmemmap_list is missing or set to 0 in the kernel would imply
> + * vmemmap region is mapped in the kernel pagetable. So, read
> vmemmap_list
> + * anyway and use the translation method accordingly.
> + */
> + readmem(symbol_value("vmemmap_list"), KVADDR, &ld->start,
> sizeof(void *),
> + "vmemmap_list", RETURN_ON_ERROR);
> + if (!ld->start) {
> + /*
> + * vmemmap_list is set to 0 or missing. Do kernel
> pagetable walk
> + * for vmemmamp address translation.
> + */
> + ms->vmemmap_list = NULL;
> + ms->vmemmap_cnt = 0;
> +
> + machdep->flags |= VMEMMAP_AWARE;
> + return;
> + }
> +
> if (!(kernel_symbol_exists("vmemmap_list")) ||
> !(kernel_symbol_exists("mmu_psize_defs")) ||
> !(kernel_symbol_exists("mmu_vmemmap_psize")) ||
> @@ -1293,8 +1315,6 @@ void ppc64_vmemmap_init(void)
> !MEMBER_EXISTS("vmemmap_backing", "list"))
> return;
>
> - ms = machdep->machspec;
> -
> backing_size = STRUCT_SIZE("vmemmap_backing");
> virt_addr_offset = MEMBER_OFFSET("vmemmap_backing", "virt_addr");
> phys_offset = MEMBER_OFFSET("vmemmap_backing", "phys");
> @@ -1313,14 +1333,8 @@ void ppc64_vmemmap_init(void)
>
> ms->vmemmap_psize = 1 << shift;
>
> - ld = &list_data;
> - BZERO(ld, sizeof(struct list_data));
> - if (!readmem(symbol_value("vmemmap_list"),
> - KVADDR, &ld->start, sizeof(void *), "vmemmap_list",
> - RETURN_ON_ERROR))
> - return;
> - ld->end = symbol_value("vmemmap_list");
> - ld->list_head_offset = list_offset;
> + ld->end = symbol_value("vmemmap_list");
> + ld->list_head_offset = list_offset;
>
> hq_open();
> cnt = do_list(ld);
> @@ -1366,7 +1380,7 @@ ppc64_vmemmap_to_phys(ulong kvaddr, physaddr_t
> *paddr, int verbose)
> {
> int i;
> ulong offset;
> - struct machine_specific *ms;
> + struct machine_specific *ms = machdep->machspec;
>
> if (!(machdep->flags & VMEMMAP_AWARE)) {
> /*
> @@ -1386,7 +1400,12 @@ ppc64_vmemmap_to_phys(ulong kvaddr, physaddr_t
> *paddr, int verbose)
> return FALSE;
> }
>
> - ms = machdep->machspec;
> + /**
> + * When vmemmap_list is not populated, kernel does the mapping in
> init_mm
> + * page table, so do a pagetable walk in kernel page table
> + */
> + if (!ms->vmemmap_list)
> + return ppc64_vtop_level4(kvaddr, (ulong
> *)vt->kernel_pgd[0], paddr, verbose);
>
> for (i = 0; i < ms->vmemmap_cnt; i++) {
> if ((kvaddr >= ms->vmemmap_list[i].virt) &&
> --
> 2.41.0
>
11 months, 3 weeks
Re: [Crash-utility] Concerns regarding e17bebd049 ("dump: Set correct vaddr for ELF dump")
by Dave Young
Not sure if crash people subscribed to linux-debuggers, let's add more
cc for awareness about this thread.
On Thu, 21 Sept 2023 at 01:45, Stephen Brennan
<stephen.s.brennan(a)oracle.com> wrote:
>
> Stephen Brennan <stephen.s.brennan(a)oracle.com> writes:
> > Hi Jon,
> >
> > Jon Doron <arilou(a)gmail.com> writes:
> >> Hi Stephen,
> >> Like you have said the reason is as I wrote in the commit message,
> >> without "fixing" the vaddr GDB is messing up mapping and working with
> >> the generated core file.
> >
> > For the record I totally love this workaround :)
> >
> > It's clever and gets the job done and I would have done it in a
> > heartbeat. It's just that it does end up making vmcores that have
> > incorrect data, which is a pain for debuggers that are actually designed
> > to look at kernel core dumps.
> >
> >> This patch is almost 4 years old, perhaps some changes to GDB has been
> >> introduced to resolve this, I have not checked since then.
> >
> > Program Headers:
> > Type Offset VirtAddr PhysAddr
> > FileSiz MemSiz Flags Align
> > NOTE 0x0000000000000168 0x0000000000000000 0x0000000000000000
> > 0x0000000000001980 0x0000000000001980 0x0
> > LOAD 0x0000000000001ae8 0x0000000000000000 0x0000000000000000
> > 0x0000000080000000 0x0000000080000000 0x0
> > LOAD 0x0000000080001ae8 0x0000000000000000 0x00000000fffc0000
> > 0x0000000000040000 0x0000000000040000 0x0
> >
> > (gdb) info files
> > Local core dump file:
> > `/home/stepbren/repos/test_code/elf/dumpfile', file type elf64-x86-64.
> > 0x0000000000000000 - 0x0000000080000000 is load1
> > 0x0000000000000000 - 0x0000000000040000 is load2
> >
> > $ gdb --version
> > GNU gdb (GDB) Red Hat Enterprise Linux 10.2-10.0.2.el9
> > Copyright (C) 2021 Free Software Foundation, Inc.
> > License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
> > This is free software: you are free to change and redistribute it.
> > There is NO WARRANTY, to the extent permitted by law.
> >
> >
> > It doesn't *look like* anything has changed in this version of GDB. But
> > I'm not really certain that GDB is expected to use the physical
> > addresses in the load segments: it's not a kernel debugger.
> >
> > I think hacking the p_vaddr field _is_ the way to get GDB to behave in
> > the way you want: allow you to read physical memory addresses.
> >
> >> As I'm no longer using this feature and have not worked and tested it
> >> in a long while, so I have no obligations to this change, but perhaps
> >> someone else might be using it...
> >
> > I definitely think it's valuable for people to continue being able to
> > use QEMU vmcores generated with paging=off in GDB, even if GDB isn't
> > desgined for it. It seems like a useful hack that appeals to the lowest
> > common denominator: most people have GDB and not a purpose-built kernel
> > debugger. But maybe we could point to a program like the below that will
> > tweak the p_paddr field after the fact, in order to appeal to GDB's
> > sensibilities?
>
> And of course I sent the wrong copy of the file. Attached is the program
> I intended to send (which properly handles endianness and sets the vaddr
> as expected).
>
11 months, 3 weeks
[PATCH] Fix "vtop" command to display the swapinfo for arm64 kernel 6.1+
by 陈冠有
#define __SWP_TYPE_SHIFT 3
#define __SWP_TYPE_BITS 5
Before:
crash> vtop 70504000
VIRTUAL PHYSICAL
70504000 (not mapped)
PAGE DIRECTORY: ffffff80f265c000
PGD: ffffff80f265c008 => 800000141537003
PMD: ffffff8101537c10 => 800000141538003
PTE: ffffff8101538820 => 12bc3e04
PTE vtop: cannot determine swap location
After:
crash> vtop 70504000
VIRTUAL PHYSICAL
70504000 (not mapped)
PAGE DIRECTORY: ffffff80f265c000
PGD: ffffff80f265c008 => 800000141537003
PMD: ffffff8101537c10 => 800000141538003
PTE: ffffff8101538820 => 12bc3e04
PTE SWAP OFFSET
12bc3e04 /first_stage_ramdisk/dev/block/zram0 1227838
VMA START END FLAGS FILE
ffffff80dfe7b578 70504000 707bd000 100073
SWAP: /first_stage_ramdisk/dev/block/zram0 OFFSET: 1227838
Signed-off-by: chenguanyou <chenguanyou(a)xiaomi.com>
---
arm64.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/arm64.c b/arm64.c
index 39d5f04..ea1b51b 100644
--- a/arm64.c
+++ b/arm64.c
@@ -468,8 +468,16 @@ arm64_init(int when)
}
}
-
- if (THIS_KERNEL_VERSION >= LINUX(4,0,0)) {
+ if (THIS_KERNEL_VERSION >= LINUX(6,1,0)) {
+ ms->__SWP_TYPE_BITS = 5;
+ ms->__SWP_TYPE_SHIFT = 3;
+ ms->__SWP_TYPE_MASK = ((1UL << ms->__SWP_TYPE_BITS) - 1);
+ ms->__SWP_OFFSET_SHIFT = (ms->__SWP_TYPE_BITS + ms->__SWP_TYPE_SHIFT);
+ ms->__SWP_OFFSET_BITS = 50;
+ ms->__SWP_OFFSET_MASK = ((1UL << ms->__SWP_OFFSET_BITS) - 1);
+ ms->PTE_PROT_NONE = (1UL << 58);
+ ms->PTE_FILE = 0; /* unused */
+ } else if (THIS_KERNEL_VERSION >= LINUX(4,0,0)) {
ms->__SWP_TYPE_BITS = 6;
ms->__SWP_TYPE_SHIFT = 2;
ms->__SWP_TYPE_MASK = ((1UL << ms->__SWP_TYPE_BITS) - 1);
--
2.39.0
#/******本邮件及其附件含有小米公司的保密信息,仅限于发送给上面地址中列出的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制、或散发)本邮件中的信息。如果您错收了本邮件,请您立即电话或邮件通知发件人并删除本邮件! This e-mail and its attachments contain confidential information from XIAOMI, which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction, or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by phone or email immediately and delete it!******/#
11 months, 3 weeks
[PATCH v1] diskdump: add hook for additional checks on prstatus notes validity
by Aditya Gupta
Upstream crash reports these warnings on PowerPC64:
WARNING: cpu 0 invalid NT_PRSTATUS note (n_type != NT_PRSTATUS)
...
Apart from these warnings, register values are also invalid.
This warning was found in the commit:
commit db8c030857b4 ("diskdump/netdump: fix segmentation fault
caused by failure of stopping CPUs")
With above commit, crash checks whether 'crash_notes' is initialised,
before mapping PRSTATUS notes.
But some architectures such as PowerPC64, in fadump case
(firmware-assisted dump), don't populate 'crash_notes' since the
registers are already stored in the cpu notes in the vmcore.
Instead of checking 'crash_notes' for all architectures, introduce
a machdep hook ('is_cpu_prstatus_valid'), for architectures to
decide validity checks for PRSTATUS notes
A default hook ('diskdump_is_cpu_prstatus_valid') has also been provided
for all architectures other than PowerPC64, which checks if 'crash_notes'
for a given cpu is valid, maintaining the current behaviour
PowerPC64 doesn't utilise 'crash_notes' to get register values, so no
additional checks are required
Fixes: db8c030857b4 ("diskdump/netdump: fix segmentation fault caused by failure of stopping CPUs")
Signed-off-by: Aditya Gupta <adityag(a)linux.ibm.com>
---
Testing
=======
NOTE: To test this on PowerPC64 with upstream kernel dump, AND on system
with Radix MMU, following patch will also be needed to be applied:
Link: https://listman.redhat.com/archives/crash-utility/2023-September/010961.html
This is due to change in vmemmap address mapping for Radix MMU, since
following patch in the kernel:
368a0590d954: (powerpc/book3s64/vmemmap: switch radix to use a
different vmemmap handling function)
More details about the change are in the linked patch. Basically what
changed is, the address mapping for vmemmap address is now in kernel
page table, in case of Radix MMU, instead of 'vmemmap_list' which is currently
used in crash.
Git Tree for Testing
====================
1. With this patch (diskdump: add hook for additional ...) applied:
https://github.com/adi-g15-ibm/crash/tree/bugzilla-203256-list-v1
2. With both this and the linked patch (ppc64: do page traversal ...) applied:
https://github.com/adi-g15-ibm/crash/tree/bugzilla-203256-withupstreamradix
---
---
defs.h | 1 +
diskdump.c | 15 ++++++++++++---
ppc64.c | 10 ++++++++++
3 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/defs.h b/defs.h
index 96a7a2a31471..f7f56947e5ac 100644
--- a/defs.h
+++ b/defs.h
@@ -1073,6 +1073,7 @@ struct machdep_table {
int (*verify_line_number)(ulong, ulong, ulong);
void (*get_irq_affinity)(int);
void (*show_interrupts)(int, ulong *);
+ int (*is_cpu_prstatus_valid)(int cpu);
int (*is_page_ptr)(ulong, physaddr_t *);
int (*get_cpu_reg)(int, int, const char *, int, void *);
};
diff --git a/diskdump.c b/diskdump.c
index 2c284ff3f97f..ad9a00b08ce1 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -142,13 +142,22 @@ int have_crash_notes(int cpu)
return TRUE;
}
+int diskdump_is_cpu_prstatus_valid(int cpu)
+{
+ static int crash_notes_exists = -1;
+
+ if (crash_notes_exists == -1)
+ crash_notes_exists = kernel_symbol_exists("crash_notes");
+
+ return (!crash_notes_exists || have_crash_notes(cpu));
+}
+
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;
@@ -171,10 +180,9 @@ 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) && (!crash_notes_exists || have_crash_notes(i))) {
+ if (in_cpu_map(ONLINE_MAP, i) && machdep->is_cpu_prstatus_valid(i)) {
dd->nt_prstatus_percpu[i] = nt_ptr[j++];
dd->num_prstatus_notes =
MAX(dd->num_prstatus_notes, i+1);
@@ -1076,6 +1084,7 @@ diskdump_init(char *unused, FILE *fptr)
if (!DISKDUMP_VALID() && !KDUMP_CMPRS_VALID())
return FALSE;
+ machdep->is_cpu_prstatus_valid = diskdump_is_cpu_prstatus_valid;
dd->ofp = fptr;
return TRUE;
}
diff --git a/ppc64.c b/ppc64.c
index fc34006f4863..1159b8c3a8e7 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -298,6 +298,15 @@ struct machine_specific book3e_machine_specific = {
.is_vmaddr = book3e_is_vmaddr,
};
+/**
+ * No additional checks are required on PPC64, for checking if PRSTATUS notes
+ * is valid
+ */
+int ppc64_is_cpu_prstatus_valid(int cpu)
+{
+ return TRUE;
+}
+
#define SKIBOOT_BASE 0x30000000
/*
@@ -418,6 +427,7 @@ ppc64_init(int when)
break;
case POST_GDB:
+ machdep->is_cpu_prstatus_valid = ppc64_is_cpu_prstatus_valid;
ms = machdep->machspec;
if (!(machdep->flags & BOOK3E)) {
--
2.41.0
11 months, 3 weeks
Re: [Crash-utility] Question on crash:clear the screen
by lijiang
On Fri, Sep 15, 2023 at 4:48 PM <crash-utility-request(a)redhat.com> wrote:
> Date: Fri, 15 Sep 2023 16:46:33 +0800
> From: Shijie Huang <shijie(a)amperemail.onmicrosoft.com>
> To: crash-utility(a)redhat.com
> Subject: [Crash-utility] Question on crash:clear the screen
> Message-ID:
> <afc923d5-1f96-eb25-b1b5-407b8ba8ebbe(a)amperemail.onmicrosoft.com>
> Content-Type: text/plain; charset=UTF-8; format=flowed
>
> Hi all,
>
> I want to clear the screen when I use the crash.
>
> But I did not find such command in crash:
>
> "? #gdb shell clear " does not work..
>
> Could someone give me a hint about it?
>
>
The "shell" command is on the gdb-prohibited list, you can see it in the
"prohibited_list" array(gdb_interface.c).
Thanks
Lianbo
> Thanks
>
> Huang Shijie
>
11 months, 3 weeks
[PATCH] In verify_version() don't require specific syment type values for linux_banner symbol to get it's address
by David Mair
verify_version() in kernel.c gets a struct syment for linux_banner using symbol_search() and uses the value member of the result as the address of linux_banner in some cases based on the type member's value in the same struct syment. A small number of coredumps with an unhandled type ('B' or 'b') for linux_banner result in the address of linux_banner being loaded from the actual linux_banner data. This fails because the first ulong of the linux_banner ASCII text is treated as a dumped kernel address and attempting to access that in the core fails.
Based on a suggestion from Kazu, continue to get the struct syment for linux_banner using symbol_search(). Also use get_symbol_type() for linux_banner and use the result of that to decide where to get the linux_banner address from, disregarding the syment type member. If get_symbol_type() reports a TYPE_CODE_ARRAY (and by default with a warning) use the syment value member as the linux_banner address. If get_symbol_type() reports a TYPE_CODE_PTR read the address of linux_banner using get_symbol_data().
The else block doesn't strictly require braced content for a single switch statement but braces are included to match style of locally similar cases.
Signed-off-by: David Mair <dmair(a)suse.com>
---
diff --git a/kernel.c b/kernel.c
index 988206b..6dcf414 100644
--- a/kernel.c
+++ b/kernel.c
@@ -1076,13 +1076,21 @@ verify_version(void)
if (!(sp = symbol_search("linux_banner")))
error(FATAL, "linux_banner symbol does not exist?\n");
- else if ((sp->type == 'R') || (sp->type == 'r') ||
- (THIS_KERNEL_VERSION >= LINUX(2,6,11) && (sp->type == 'D' || sp->type == 'd')) ||
- (machine_type("ARM") && sp->type == 'T') ||
- (machine_type("ARM64")))
- linux_banner = symbol_value("linux_banner");
- else
- get_symbol_data("linux_banner", sizeof(ulong), &linux_banner);
+ else {
+ switch (get_symbol_type("linux_banner", NULL, NULL))
+ {
+ case TYPE_CODE_ARRAY:
+ linux_banner = sp->value;
+ break;
+ case TYPE_CODE_PTR:
+ get_symbol_data("linux_banner", sizeof(ulong), &linux_banner);
+ break;
+ default:
+ error(WARNING, "linux_banner is unknown type\n");
+ linux_banner = sp->value;
+ break;
+ }
+ }
if (!IS_KVADDR(linux_banner))
error(WARNING, "invalid linux_banner pointer: %lx\n",
11 months, 3 weeks
Re: [Crash-utility] [PATCH] In verify_version() don't require specific syment type values for linux_banner symbol to get it's address
by lijiang
Hi, David
Thank you for the update.
On Wed, Sep 13, 2023 at 8:00 PM <crash-utility-request(a)redhat.com> wrote:
> Date: Tue, 12 Sep 2023 18:11:33 -0600
> From: David Mair <dmair(a)suse.com>
> To: crash-utility(a)redhat.com
> Subject: [Crash-utility] [PATCH] In verify_version() don't require
> specific syment type values for linux_banner symbol to get it's
> address
> Message-ID: <55b4eb1f-8cdc-eca4-e370-1eed12133681(a)suse.com>
> Content-Type: text/plain; charset=UTF-8; format=flowed
>
> verify_version() in kernel.c gets a struct syment for linux_banner using
> symbol_search() and uses the value member of the result as the address of
> linux_banner in some cases based on the type member's value in the same
> struct syment. A small number of coredumps with an unhandled type ('B' or
> 'b') for linux_banner result in the address of linux_banner being loaded
> from the actual linux_banner data. This fails because the first ulong of
> the linux_banner ASCII text is treated as a dumped kernel address and
> attempting to access that in the core fails.
>
> Based on a suggestion from Kazu, continue to get the struct syment for
> linux_banner using symbol_search(). Also use get_symbol_type() for
> linux_banner and use the result of that to decide where to get the
> linux_banner address from, disregarding the syment type member. If
> get_symbol_type() reports a TYPE_CODE_ARRAY (and by default with a warning)
> use the syment value member as the linux_banner address. If
> get_symbol_type() reports a TYPE_CODE_PTR read the address of linux_banner
> using get_symbol_data().
>
> The else block doesn't strictly require braced content for a single switch
> statement but braces are included to match style of locally similar cases.
>
> Signed-off-by: David Mair <dmair(a)suse.com>
> ---
> diff --git a/kernel.c b/kernel.c
> index 988206b..6dcf414 100644
> --- a/kernel.c
> +++ b/kernel.c
> @@ -1076,13 +1076,21 @@ verify_version(void)
>
> if (!(sp = symbol_search("linux_banner")))
> error(FATAL, "linux_banner symbol does not exist?\n");
> - else if ((sp->type == 'R') || (sp->type == 'r') ||
> - (THIS_KERNEL_VERSION >= LINUX(2,6,11) && (sp->type == 'D'
> || sp->type == 'd')) ||
> - (machine_type("ARM") && sp->type == 'T') ||
> - (machine_type("ARM64")))
> - linux_banner = symbol_value("linux_banner");
> - else
> - get_symbol_data("linux_banner", sizeof(ulong),
> &linux_banner);
> + else {
> + switch (get_symbol_type("linux_banner", NULL, NULL))
> + {
> + case TYPE_CODE_ARRAY:
> + linux_banner = sp->value;
> + break;
> + case TYPE_CODE_PTR:
> + get_symbol_data("linux_banner", sizeof(ulong),
> &linux_banner);
> + break;
> + default:
> + error(WARNING, "linux_banner is unknown type\n");
> + linux_banner = sp->value;
> + break;
> + }
> + }
>
>
This change looks good to me. So: Ack
Thanks.
Lianbo
> if (!IS_KVADDR(linux_banner))
> error(WARNING, "invalid linux_banner pointer: %lx\n",
>
>
>
>
11 months, 3 weeks
[PATCH v3] Fix: move huge compressed obj from page to zspage
by 陈冠有
when zspage define 'huge', crash-utility zram decompress fail.
we need to be compatible with the previous kernel,
so we can't define 'huge' directly in zspage, just move to the right when calculating.
Before:
crash> mod -s zram zram.ko
MODULE NAME BASE SIZE OBJECT FILE
ffffffde224db800 zram ffffffde224d2000 57344 zram.ko
crash> mod -s zsmalloc zsmalloc.ko
MODULE NAME BASE SIZE OBJECT FILE
ffffffde224c5180 zsmalloc ffffffde224bf000 40960 zsmalloc.ko
crash> rd 0x13d89fb0
rd: zspage magic incorrect: b0
After:
crash> rd 0x13d89fb0
13d89fb0: c2b54f7170883b20 ;.pqO..
Link: https://lkml.kernel.org/r/20211115185909.3949505-6-minchan@kernel.org
Signed-off-by: chenguanyou <chenguanyou(a)xiaomi.com>
---
defs.h | 13 ++++++++++
diskdump.c | 70 ++++++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 71 insertions(+), 12 deletions(-)
diff --git a/defs.h b/defs.h
index 96a7a2a..0af69cc 100644
--- a/defs.h
+++ b/defs.h
@@ -2225,6 +2225,7 @@ struct offset_table { /* stash of commonly-used offsets */
long module_memory_base;
long module_memory_size;
long irq_data_irq;
+ long zspage_huge;
};
struct size_table { /* stash of commonly-used sizes */
@@ -7221,6 +7222,18 @@ struct zspage {
unsigned int freeobj;
};
+struct zspage6 {
+ struct {
+ unsigned int huge : 1;
+ unsigned int fullness : 2;
+ unsigned int class : 9;
+ unsigned int isolated : 3;
+ unsigned int magic : 8;
+ };
+ unsigned int inuse;
+ unsigned int freeobj;
+};
+
/*
* makedumpfile.c
*/
diff --git a/diskdump.c b/diskdump.c
index 2c284ff..0307656 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2754,6 +2754,9 @@ zram_init(void)
if (INVALID_MEMBER(zram_table_flag))
MEMBER_OFFSET_INIT(zram_table_flag, "zram_table_entry", "value");
STRUCT_SIZE_INIT(zram_table_entry, "zram_table_entry");
+ MEMBER_OFFSET_INIT(zspoll_size_class, "zs_pool", "size_class");
+ MEMBER_OFFSET_INIT(size_class_size, "size_class", "size");
+ MEMBER_OFFSET_INIT(zspage_huge, "zspage", "huge");
}
static unsigned char *
@@ -2761,9 +2764,11 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf)
{
ulong obj, off, class, page, zspage;
struct zspage zspage_s;
+ struct zspage6 zspage6_s;
physaddr_t paddr;
unsigned int obj_idx, class_idx, size;
ulong pages[2], sizes[2];
+ ulong zs_magic;
readmem(handle, KVADDR, &obj, sizeof(void *), "zram entry", FAULT_ON_ERROR);
obj >>= OBJ_TAG_BITS;
@@ -2772,11 +2777,19 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf)
readmem(page + OFFSET(page_private), KVADDR, &zspage,
sizeof(void *), "page_private", FAULT_ON_ERROR);
- readmem(zspage, KVADDR, &zspage_s, sizeof(struct zspage), "zspage", FAULT_ON_ERROR);
- class_idx = zspage_s.class;
- if (zspage_s.magic != ZSPAGE_MAGIC)
- error(FATAL, "zspage magic incorrect: %x\n", zspage_s.magic);
+ if (VALID_MEMBER(zspage_huge)) {
+ readmem(zspage, KVADDR, &zspage6_s, sizeof(struct zspage6), "zspage6", FAULT_ON_ERROR);
+ class_idx = zspage6_s.class;
+ zs_magic = zspage6_s.magic;
+ } else {
+ readmem(zspage, KVADDR, &zspage_s, sizeof(struct zspage), "zspage", FAULT_ON_ERROR);
+ class_idx = zspage_s.class;
+ zs_magic = zspage_s.magic;
+ }
+
+ if (zs_magic != ZSPAGE_MAGIC)
+ error(FATAL, "zspage magic incorrect: %x\n", zs_magic);
class = pool + OFFSET(zspoll_size_class);
class += (class_idx * sizeof(void *));
@@ -2794,8 +2807,13 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf)
}
pages[0] = page;
- readmem(page + OFFSET(page_freelist), KVADDR, &pages[1],
- sizeof(void *), "page_freelist", FAULT_ON_ERROR);
+ if (VALID_MEMBER(page_freelist)) {
+ readmem(page + OFFSET(page_freelist), KVADDR, &pages[1],
+ sizeof(void *), "page_freelist", FAULT_ON_ERROR);
+ } else {
+ readmem(page + OFFSET(page_index), KVADDR, &pages[1],
+ sizeof(void *), "page_index", FAULT_ON_ERROR);
+ }
sizes[0] = PAGESIZE() - off;
sizes[1] = size - sizes[0];
if (!is_page_ptr(pages[0], &paddr)) {
@@ -2812,9 +2830,15 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf)
readmem(paddr, PHYSADDR, zram_buf + sizes[0], sizes[1], "zram buffer[1]", FAULT_ON_ERROR);
out:
- readmem(page, KVADDR, &obj, sizeof(void *), "page flags", FAULT_ON_ERROR);
- if (!(obj & (1<<10))) { //PG_OwnerPriv1 flag
- return (zram_buf + ZS_HANDLE_SIZE);
+ if (!VALID_MEMBER(zspage_huge)) {
+ readmem(page, KVADDR, &obj, sizeof(void *), "page flags", FAULT_ON_ERROR);
+ if (!(obj & (1<<10))) { //PG_OwnerPriv1 flag
+ return (zram_buf + ZS_HANDLE_SIZE);
+ }
+ } else {
+ if (!zspage6_s.huge) {
+ return (zram_buf + ZS_HANDLE_SIZE);
+ }
}
return zram_buf;
@@ -2929,6 +2953,8 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
unsigned char *outbuf = NULL;
ulong zram, zram_table_entry, sector, index, entry, flags, size,
outsize, off;
+ unsigned long *same_buf = NULL;
+ bool is_same = false;
if (INVALID_MEMBER(zram_compressor)) {
zram_init();
@@ -2992,11 +3018,30 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
sizeof(void *), "entry of table", FAULT_ON_ERROR);
readmem(zram_table_entry + OFFSET(zram_table_flag), KVADDR, &flags,
sizeof(void *), "zram_table_flag", FAULT_ON_ERROR);
- if (!entry || (flags & ZRAM_FLAG_SAME_BIT)) {
- memset(buf, entry, len);
+
+ if (THIS_KERNEL_VERSION >= LINUX(5,1,0)) {
+ if (!entry || flags & (1 << (PAGESHIFT() + 1 + 1)))
+ is_same = true;
+ } else {
+ if (!entry || (flags & ZRAM_FLAG_SAME_BIT))
+ is_same = true;
+ }
+
+ if (is_same) {
+ same_buf = (unsigned long *)GETBUF(PAGESIZE());
+ for (int count = 0; count < PAGESIZE() / sizeof(unsigned long); count++) {
+ same_buf[count] = entry;
+ }
+ memcpy(buf, same_buf + off, PAGESIZE());
+ FREEBUF(same_buf);
goto out;
}
- size = flags & (ZRAM_FLAG_SHIFT -1);
+
+ if (THIS_KERNEL_VERSION >= LINUX(5,1,0)) {
+ size = flags & ((1 << (PAGESHIFT() + 1)) - 1);
+ } else {
+ size = flags & (ZRAM_FLAG_SHIFT -1);
+ }
if (size == 0) {
len = 0;
goto out;
--
2.39.0
#/******本邮件及其附件含有小米公司的保密信息,仅限于发送给上面地址中列出的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制、或散发)本邮件中的信息。如果您错收了本邮件,请您立即电话或邮件通知发件人并删除本邮件! This e-mail and its attachments contain confidential information from XIAOMI, which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction, or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by phone or email immediately and delete it!******/#
11 months, 3 weeks
Question on crash:clear the screen
by Shijie Huang
Hi all,
I want to clear the screen when I use the crash.
But I did not find such command in crash:
" #gdb shell clear " does not work..
Could someone give me a hint about it?
Thanks
Huang Shijie
CONFIDENTIALITY NOTICE: This e-mail message, including any attachments, is for the sole use of the intended recipient(s) and contains information that is confidential and proprietary to Ampere Computing or its subsidiaries. It is to be used solely for the purpose of furthering the parties' business relationship. Any unauthorized review, copying, or distribution of this email (or any attachments thereto) is strictly prohibited. If you are not the intended recipient, please contact the sender immediately and permanently delete the original and any copies of this email and any attachments thereto.
11 months, 4 weeks
[PATCH v2] Fix: move huge compressed obj from page to zspage
by 陈冠有
when zspage define 'huge', crash-utility zram decompress fail.
we need to be compatible with the previous kernel,
so we can't define 'huge' directly in zspage, just move to the right when calculating.
Link: https://lkml.kernel.org/r/20211115185909.3949505-6-minchan@kernel.org
Signed-off-by: chenguanyou <chenguanyou(a)xiaomi.com>
---
defs.h | 13 +++++++++++++
diskdump.c | 39 ++++++++++++++++++++++++++++++---------
2 files changed, 43 insertions(+), 9 deletions(-)
diff --git a/defs.h b/defs.h
index 96a7a2a..0af69cc 100644
--- a/defs.h
+++ b/defs.h
@@ -2225,6 +2225,7 @@ struct offset_table { /* stash of commonly-used offsets */
long module_memory_base;
long module_memory_size;
long irq_data_irq;
+ long zspage_huge;
};
struct size_table { /* stash of commonly-used sizes */
@@ -7221,6 +7222,18 @@ struct zspage {
unsigned int freeobj;
};
+struct zspage6 {
+ struct {
+ unsigned int huge : 1;
+ unsigned int fullness : 2;
+ unsigned int class : 9;
+ unsigned int isolated : 3;
+ unsigned int magic : 8;
+ };
+ unsigned int inuse;
+ unsigned int freeobj;
+};
+
/*
* makedumpfile.c
*/
diff --git a/diskdump.c b/diskdump.c
index 2c284ff..99a8112 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2761,9 +2761,11 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf)
{
ulong obj, off, class, page, zspage;
struct zspage zspage_s;
+ struct zspage6 zspage6_s;
physaddr_t paddr;
unsigned int obj_idx, class_idx, size;
ulong pages[2], sizes[2];
+ ulong zs_magic;
readmem(handle, KVADDR, &obj, sizeof(void *), "zram entry", FAULT_ON_ERROR);
obj >>= OBJ_TAG_BITS;
@@ -2772,11 +2774,19 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf)
readmem(page + OFFSET(page_private), KVADDR, &zspage,
sizeof(void *), "page_private", FAULT_ON_ERROR);
- readmem(zspage, KVADDR, &zspage_s, sizeof(struct zspage), "zspage", FAULT_ON_ERROR);
- class_idx = zspage_s.class;
- if (zspage_s.magic != ZSPAGE_MAGIC)
- error(FATAL, "zspage magic incorrect: %x\n", zspage_s.magic);
+ if (VALID_MEMBER(zspage_huge)) {
+ readmem(zspage, KVADDR, &zspage6_s, sizeof(struct zspage6), "zspage6", FAULT_ON_ERROR);
+ class_idx = zspage6_s.class;
+ zs_magic = zspage6_s.magic;
+ } else {
+ readmem(zspage, KVADDR, &zspage_s, sizeof(struct zspage), "zspage", FAULT_ON_ERROR);
+ class_idx = zspage_s.class;
+ zs_magic = zspage_s.magic;
+ }
+
+ if (zs_magic != ZSPAGE_MAGIC)
+ error(FATAL, "zspage magic incorrect: %x\n", zs_magic);
class = pool + OFFSET(zspoll_size_class);
class += (class_idx * sizeof(void *));
@@ -2794,8 +2804,13 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf)
}
pages[0] = page;
- readmem(page + OFFSET(page_freelist), KVADDR, &pages[1],
- sizeof(void *), "page_freelist", FAULT_ON_ERROR);
+ if (VALID_MEMBER(page_freelist)) {
+ readmem(page + OFFSET(page_freelist), KVADDR, &pages[1],
+ sizeof(void *), "page_freelist", FAULT_ON_ERROR);
+ } else {
+ readmem(page + OFFSET(page_index), KVADDR, &pages[1],
+ sizeof(void *), "page_index", FAULT_ON_ERROR);
+ }
sizes[0] = PAGESIZE() - off;
sizes[1] = size - sizes[0];
if (!is_page_ptr(pages[0], &paddr)) {
@@ -2812,9 +2827,15 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf)
readmem(paddr, PHYSADDR, zram_buf + sizes[0], sizes[1], "zram buffer[1]", FAULT_ON_ERROR);
out:
- readmem(page, KVADDR, &obj, sizeof(void *), "page flags", FAULT_ON_ERROR);
- if (!(obj & (1<<10))) { //PG_OwnerPriv1 flag
- return (zram_buf + ZS_HANDLE_SIZE);
+ if (!VALID_MEMBER(zspage_huge)) {
+ readmem(page, KVADDR, &obj, sizeof(void *), "page flags", FAULT_ON_ERROR);
+ if (!(obj & (1<<10))) { //PG_OwnerPriv1 flag
+ return (zram_buf + ZS_HANDLE_SIZE);
+ }
+ } else {
+ if (!zspage6_s.huge) {
+ return (zram_buf + ZS_HANDLE_SIZE);
+ }
}
return zram_buf;
--
2.39.0
#/******本邮件及其附件含有小米公司的保密信息,仅限于发送给上面地址中列出的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制、或散发)本邮件中的信息。如果您错收了本邮件,请您立即电话或邮件通知发件人并删除本邮件! This e-mail and its attachments contain confidential information from XIAOMI, which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction, or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by phone or email immediately and delete it!******/#
11 months, 4 weeks