[PATCH v4] arm64: Add vmemmap support
by Huang Shijie
If the kernel exports the vmmemap then we can use that symbol in
crash to optimize access. vmmemap is just an array of page structs
after all.
This patch tries to:
1.) Get the "vmemmap" from the vmcore file.
If we can use the "vmemmap", we implement the arm64_vmemmap_is_page_ptr
and set it to machdep->is_page_ptr.
2.) We implement the fast page_to_pfn code in arm64_vmemmap_is_page_ptr.
3.) Dump it in "help -m"
Test result:
Without the this patch:
#files -p xxx > /dev/null (xxx is the inode of vmlinux which is 441M)
This costed about 185 seconds.
With the this patch:
#files -p xxx > /dev/null (xxx is the inode of vmlinux which is 441M)
This costed 3 seconds.
Signed-off-by: Huang Shijie <shijie(a)os.amperecomputing.com>
---
v3 --> v4:
Use "files -p" to measure the time.
Dump it in "help -m"
---
arm64.c | 26 ++++++++++++++++++++++++++
defs.h | 1 +
2 files changed, 27 insertions(+)
diff --git a/arm64.c b/arm64.c
index 57965c6..fc4ba64 100644
--- a/arm64.c
+++ b/arm64.c
@@ -117,6 +117,28 @@ static void arm64_calc_kernel_start(void)
ms->kimage_end = (sp ? sp->value : 0);
}
+static int
+arm64_vmemmap_is_page_ptr(ulong addr, physaddr_t *phys)
+{
+ ulong size = SIZE(page);
+ ulong pfn, nr;
+
+
+ if (IS_SPARSEMEM() && (machdep->flags & VMEMMAP) &&
+ (addr >= VMEMMAP_VADDR && addr <= VMEMMAP_END) &&
+ !((addr - VMEMMAP_VADDR) % size)) {
+
+ pfn = (addr - machdep->machspec->vmemmap) / size;
+ nr = pfn_to_section_nr(pfn);
+ if (valid_section_nr(nr)) {
+ if (phys)
+ *phys = PTOB(pfn);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
/*
* Do all necessary machine-specific setup here. This is called several times
* during initialization.
@@ -382,6 +404,9 @@ arm64_init(int when)
machdep->stacksize = ARM64_STACK_SIZE;
machdep->flags |= VMEMMAP;
+ /* If vmemmap exists, it means kernel enabled CONFIG_SPARSEMEM_VMEMMAP */
+ if (arm64_get_vmcoreinfo(&ms->vmemmap, "SYMBOL(vmemmap)", NUM_HEX))
+ machdep->is_page_ptr = arm64_vmemmap_is_page_ptr;
machdep->uvtop = arm64_uvtop;
machdep->is_uvaddr = arm64_is_uvaddr;
@@ -1096,6 +1121,7 @@ arm64_dump_machdep_table(ulong arg)
fprintf(fp, " vmemmap_vaddr: %016lx\n", ms->vmemmap_vaddr);
fprintf(fp, " vmemmap_end: %016lx\n", ms->vmemmap_end);
if (machdep->flags & NEW_VMEMMAP) {
+ fprintf(fp, " vmemmap: %016lx\n", ms->vmemmap);
fprintf(fp, " kimage_text: %016lx\n", ms->kimage_text);
fprintf(fp, " kimage_end: %016lx\n", ms->kimage_end);
fprintf(fp, " kimage_voffset: %016lx\n", ms->kimage_voffset);
diff --git a/defs.h b/defs.h
index 0558d13..3431a32 100644
--- a/defs.h
+++ b/defs.h
@@ -3486,6 +3486,7 @@ struct machine_specific {
ulong CONFIG_ARM64_KERNELPACMASK;
ulong physvirt_offset;
ulong struct_page_size;
+ ulong vmemmap;
};
struct arm64_stackframe {
--
2.40.1
8 months, 1 week
crash8.0.4 cannot get source line nums of functions from ko on android15-k6.6
by 王天明 (Tianming Wang)
Hi
I use crash8.0.4_arm64 to parse the ramdump of android15-k6.6, load the symbol of ko,
and disassemble the functions in ko through the "dis -lx" command.
I can get the assembly instructions, but I cannot get the corresponding assembly instructions. lines of source code.
The following error is reported when using the command
GNU_RESOLVE_TEXT_ADDR: returned via gdb_error_hook (1 buffer in use)
GNU_GET_FUNCTION_RANGE: returned via gdb_error_hook (1 buffer in use
I use the disassembly tool that comes with Android, such as objdump, to disassemble ko.
I can see the code lines corresponding to the functions in ko..
So, is this a problem with the gdb tool or is there something wrong with my ko symbol?
Thanks a lot.
________________________________
This email (including its attachments) is intended only for the person or entity to which it is addressed and may contain information that is privileged, confidential or otherwise protected from disclosure. Unauthorized use, dissemination, distribution or copying of this email or the information herein or taking any action in reliance on the contents of this email or the information herein, by anyone other than the intended recipient, or an employee or agent responsible for delivering the message to the intended recipient, is strictly prohibited. If you are not the intended recipient, please do not read, copy, use or disclose any part of this e-mail to others. Please notify the sender immediately and permanently delete this e-mail and any attachments if you received it in error. Internet communications cannot be guaranteed to be timely, secure, error-free or virus-free. The sender does not accept liability for any errors or omissions.
本邮件及其附件具有保密性质,受法律保护不得泄露,仅发送给本邮件所指特定收件人。严禁非经授权使用、宣传、发布或复制本邮件或其内容。若非该特定收件人,请勿阅读、复制、 使用或披露本邮件的任何内容。若误收本邮件,请从系统中永久性删除本邮件及所有附件,并以回复邮件的方式即刻告知发件人。无法保证互联网通信及时、安全、无误或防毒。发件人对任何错漏均不承担责任。
8 months, 3 weeks
[PATCH v6 0/5] Improve stack unwind on ppc64
by Aditya Gupta
The Problem:
============
Currently crash is unable to show function arguments and local variables, as
gdb can do. And functionality for moving between frames ('up'/'down') is not
working in crash.
Crash has 'gdb passthroughs' for things gdb can do, but the gdb passthroughs
'bt', 'frame', 'info locals', 'up', 'down' are not working either, due to
gdb not getting the register values from `crash_target::fetch_registers`,
which then uses `machdep->get_cpu_reg`, which is not implemented for PPC64
Proposed Solution:
==================
Fix the gdb passthroughs by implementing "machdep->get_cpu_reg" for PPC64.
This way, "gdb mode in crash" will support this feature for both ELF and
kdump-compressed vmcore formats, while "gdb" would only have supported ELF
format
This way other features of 'gdb', such as seeing
backtraces/registers/variables/arguments/local variables, moving up and
down stack frames, can be used with any ppc64 vmcore, irrespective of
being ELF format or kdump-compressed format.
Note: This doesn't support live debugging on ppc64, since registers are not
available to be read
Implications on Architectures:
====================================
No architecture other than PPC64 has been affected, other than in case of
'frame' command
As mentioned in patch #2, since frame will not be prohibited, so it will print:
crash> frame
#0 <unavailable> in ?? ()
Instead of before prohibited message:
crash> frame
crash: prohibited gdb command: frame
Major change will be in 'gdb mode' on PPC64, that it will print the frames, and
local variables, instead of failing with errors showing no frame, or showing
that couldn't get PC, it will be able to give all this information.
Testing:
========
Git tree with this patch series applied:
https://github.com/adi-g15-ibm/crash/tree/stack-unwind-v6
To test various gdb passthroughs:
(crash) set
(crash) set gdb on
gdb> thread
gdb> bt
gdb> info threads
gdb> info threads
gdb> info locals
gdb> info variables irq_rover_lock
gdb> info args
gdb> thread 2
gdb> set gdb off
(crash) set
(crash) set -c 6
(crash) gdb thread
(crash) bt
(crash) gdb bt
(crash) frame
(crash) up
(crash) down
(crash) info locals
Known Issues:
=============
1. In gdb mode, 'bt' might fail to show backtrace in few vmcores collected
from older kernels. This is a known issue due to register mismatch, and
its fix has been merged upstream:
This can also cause some 'invalid kernel virtual address' errors during gdb
unwinding the stack registers
Commit: https://github.com/torvalds/linux/commit/b684c09f09e7a6af3794d4233ef78581...
Fixing GDB passthroughs on other architectures
==============================================
Much of the work for making gdb passthroughs like 'gdb bt', 'gdb
thread', 'gdb info locals' etc. has been done by the patches introducing
'machdep->get_cpu_reg' and this series fixing some issues in that.
Other architectures should be able to fix these gdb functionalities by
simply implementing 'machdep->get_cpu_reg (cpu, regno, ...)'.
The reasoning behind that has been explained with a diagram in commit
description of patch #1
I will assist with my findings/observations fixing it on ppc64 whenever needed.
Changelog:
==========
V6:
+ changes in patch #5: fix bug introduced in v5 that caused initial gdb thread
to be thread 1
V5:
+ changes in patch #1: made ppc64_get_cpu_reg static, and remove unreachable
code
+ changes in patch #3: fixed typo 'ppc64_renum' instead of 'ppc64_regnum',
remove unneeded if condition
+ changes in patch #5: implement refresh regcache on per thread, instead of all
threads at once
V4:
+ fix segmentation fault in live debugging (change in patch #1)
+ mention live debugging not supported in cover letter and patch #1
+ fixed some checkpatch warnings (change in patch #5)
V3:
+ default gdb thread will be the crashing thread, instead of being
thread '0'
+ synchronise crash cpu and gdb thread context
+ fix bug in gdb_interface, that replaced gdb's output stream, losing
output in some cases, such as info threads and extra output in info
variables
+ fix 'info threads'
RFC V2:
- removed patch implementing 'frame', 'up', 'down' in crash
- updated the cover letter by removing the mention of those commands other
than the respective gdb passthrough
Aditya Gupta (5):
ppc64: correct gdb passthroughs by implementing machdep->get_cpu_reg
remove 'frame' from prohibited commands list
synchronise cpu context changes between crash/gdb
fix gdb_interface: restore gdb's output streams at end of
gdb_interface
fix 'info threads' command
crash_target.c | 44 ++++++++++++++++
defs.h | 130 +++++++++++++++++++++++++++++++++++++++++++++++-
gdb-10.2.patch | 110 +++++++++++++++++++++++++++++++++++++++-
gdb_interface.c | 2 +-
kernel.c | 47 +++++++++++++++--
ppc64.c | 95 +++++++++++++++++++++++++++++++++--
task.c | 14 ++++++
tools.c | 2 +-
8 files changed, 434 insertions(+), 10 deletions(-)
--
2.41.0
9 months, 1 week
Re: Google Container OS and crash 8.0.4
by HAGIO KAZUHITO(萩尾 一仁)
On 2024/01/15 22:37, Matt Suiche wrote:
> Is there an update available for this?
No.
I saw a kernel patch that removes module_load_offset [1] and will affect
the crash-utility, so I was thinking that it would be better to address
the issue together when it comes..
[1]
https://lore.kernel.org/linux-mm/20230918072955.2507221-5-rppt@kernel.org/
Thanks,
Kazu
>
> Thanks,
>
> From: Matt Suiche <matt.suiche(a)magnetforensics.com>
> Date: Wednesday, November 29, 2023 at 3:26 PM
> To: HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab(a)nec.com>, devel(a)lists.crash-utility.osci.io <devel(a)lists.crash-utility.osci.io>
> Subject: Re: [Crash-utility] Google Container OS and crash 8.0.4
> Apparently, CONFIG_KALLSYMS_ALL is not set in COS kernel
>
> Sent from my mobile device.
> ________________________________
> From: Matt Suiche <matt.suiche(a)magnetforensics.com>
> Sent: Wednesday, November 29, 2023 4:40:55 PM
> To: HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab(a)nec.com>; devel(a)lists.crash-utility.osci.io <devel(a)lists.crash-utility.osci.io>
> Subject: Re: [Crash-utility] Google Container OS and crash 8.0.4
>
> Yes, it would probably make more sense. You can also probably use _stext instead of module_load_offset too to compare the values as an assertion check.
>
> Sent from my mobile device.
> ________________________________
> From: HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab(a)nec.com>
> Sent: Wednesday, November 29, 2023 4:29 AM
> To: Matt Suiche <matt.suiche(a)magnetforensics.com>; devel(a)lists.crash-utility.osci.io <devel(a)lists.crash-utility.osci.io>
> Subject: Re: [Crash-utility] Google Container OS and crash 8.0.4
>
> On 2023/11/22 18:04, Matt Suiche wrote:
>> Sounds like this is the issue. Module_load_offset is not present, same
>> with init_task though.
>>
>> root@instance-2:~# grep -e _stext -e module_load_offset -e init_task
>> /proc/kallsyms
>> ffffffff89000000 T _stext
>> ffffffff8909e280 t ptrace_init_task
>> ffffffff891c6af0 T ftrace_graph_init_task
>> ffffffff89245ea0 T perf_event_init_task
>> ffffffff8aba3b46 T rcu_init_tasks_generic
>> root@instance-2:~#
>
> Yes, but I don't see the reason why it's not present in /proc/kallsyms,
> although it's present in the vmlinux..
>
> Recent kernels have vmcoreinfo in /proc/kcore, maybe we can use the
> KERNELOFFSET value instead of the module_load_offset symbol to determine
> whether KASLR is enabled. I might try it when I have time.
>
> Thanks,
> Kazu
>
>>
>> *From: *HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab(a)nec.com>
>> *Date: *Wednesday, November 22, 2023 at 12:01 PM
>> *To: *Matt Suiche <matt.suiche(a)magnetforensics.com>,
>> devel(a)lists.crash-utility.osci.io <devel(a)lists.crash-utility.osci.io>
>> *Subject: *EXTERNAL SENDER Re: [Crash-utility] Google Container OS and
>> crash 8.0.4
>>
>> On 2023/11/22 15:41, Matt Suiche wrote:
>>> Good point, enough the –kaslr=auto option worked well. Same when I passed --kaslr=0x8000000
>>
>> Good news.
>>
>> apparently module_load_offset symbol is needed in /proc/kallsyms to
>> enable the KASLR detection. I see it in the vmlinux.
>>
>> $ nm vmlinux-cos-5.15.133+ | grep module_load_offset
>> ffffffff82d83350 b module_load_offset
>>
>> Is it (and _stext) found in /proc/kallsyms? like
>>
>> # grep -e _stext -e module_load_offset /proc/kallsyms
>> ffffffffa0e00000 T _stext
>> ffffffffa3aafab8 b module_load_offset
>>
>>
>> PS. I will be out for the rest of this week, back next week.
>>
>> Thanks,
>> Kazu
>>
>> This email including any attachments may contain confidential material
>> for the sole use of the intended recipient. If you are not the intended
>> recipient please immediately notify the sender by reply email,
>> permanently delete this message and do not forward it or any part of it
>> to anyone else.
>>
>
> This email including any attachments may contain confidential material for the sole use of the intended recipient. If you are not the intended recipient please immediately notify the sender by reply email, permanently delete this message and do not forward it or any part of it to anyone else.
>
>
> Is there an update available for this?
>
> Thanks,
>
> *From: *Matt Suiche <matt.suiche(a)magnetforensics.com>
> *Date: *Wednesday, November 29, 2023 at 3:26 PM
> *To: *HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab(a)nec.com>,
> devel(a)lists.crash-utility.osci.io <devel(a)lists.crash-utility.osci.io>
> *Subject: *Re: [Crash-utility] Google Container OS and crash 8.0.4
>
> Apparently, CONFIG_KALLSYMS_ALL is not set in COS kernel
>
> Sent from my mobile device.
>
> ------------------------------------------------------------------------
>
> *From:*Matt Suiche <matt.suiche(a)magnetforensics.com>
> *Sent:* Wednesday, November 29, 2023 4:40:55 PM
> *To:* HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab(a)nec.com>;
> devel(a)lists.crash-utility.osci.io <devel(a)lists.crash-utility.osci.io>
> *Subject:* Re: [Crash-utility] Google Container OS and crash 8.0.4
>
> Yes, it would probably make more sense. You can also probably use _stext
> instead of module_load_offset too to compare the values as an assertion
> check.
>
> Sent from my mobile device.
>
> ------------------------------------------------------------------------
>
> *From:*HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab(a)nec.com>
> *Sent:* Wednesday, November 29, 2023 4:29 AM
> *To:* Matt Suiche <matt.suiche(a)magnetforensics.com>;
> devel(a)lists.crash-utility.osci.io <devel(a)lists.crash-utility.osci.io>
> *Subject:* Re: [Crash-utility] Google Container OS and crash 8.0.4
>
> On 2023/11/22 18:04, Matt Suiche wrote:
>> Sounds like this is the issue. Module_load_offset is not present, same
>> with init_task though.
>>
>> root@instance-2:~# grep -e _stext -e module_load_offset -e init_task
>> /proc/kallsyms
>> ffffffff89000000 T _stext
>> ffffffff8909e280 t ptrace_init_task
>> ffffffff891c6af0 T ftrace_graph_init_task
>> ffffffff89245ea0 T perf_event_init_task
>> ffffffff8aba3b46 T rcu_init_tasks_generic
>> root@instance-2:~#
>
> Yes, but I don't see the reason why it's not present in /proc/kallsyms,
> although it's present in the vmlinux..
>
> Recent kernels have vmcoreinfo in /proc/kcore, maybe we can use the
> KERNELOFFSET value instead of the module_load_offset symbol to determine
> whether KASLR is enabled. I might try it when I have time.
>
> Thanks,
> Kazu
>
>>
>> *From: *HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab(a)nec.com>
>> *Date: *Wednesday, November 22, 2023 at 12:01 PM
>> *To: *Matt Suiche <matt.suiche(a)magnetforensics.com>,
>> devel(a)lists.crash-utility.osci.io <devel(a)lists.crash-utility.osci.io>
>> *Subject: *EXTERNAL SENDER Re: [Crash-utility] Google Container OS and
>> crash 8.0.4
>>
>> On 2023/11/22 15:41, Matt Suiche wrote:
>>> Good point, enough the –kaslr=auto option worked well. Same when I passed --kaslr=0x8000000
>>
>> Good news.
>>
>> apparently module_load_offset symbol is needed in /proc/kallsyms to
>> enable the KASLR detection. I see it in the vmlinux.
>>
>> $ nm vmlinux-cos-5.15.133+ | grep module_load_offset
>> ffffffff82d83350 b module_load_offset
>>
>> Is it (and _stext) found in /proc/kallsyms? like
>>
>> # grep -e _stext -e module_load_offset /proc/kallsyms
>> ffffffffa0e00000 T _stext
>> ffffffffa3aafab8 b module_load_offset
>>
>>
>> PS. I will be out for the rest of this week, back next week.
>>
>> Thanks,
>> Kazu
>>
>> This email including any attachments may contain confidential material
>> for the sole use of the intended recipient. If you are not the intended
>> recipient please immediately notify the sender by reply email,
>> permanently delete this message and do not forward it or any part of it
>> to anyone else.
>>
>
> This email including any attachments may contain confidential material
> for the sole use of the intended recipient. If you are not the intended
> recipient please immediately notify the sender by reply email,
> permanently delete this message and do not forward it or any part of it
> to anyone else.
>
>
9 months, 1 week
Read orc_header section to detect ORC version
by nilayvaish@google.com
Folks
The Linux kernel commit b9f174c811e3ae4ae8959dc57e6adb9990e913f4 (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit...) added an ELF section for the ORC version identifier. I think the crash utility should use this section to identify the ORC version in use.
I want to implement this feature in the crash utility. As I understand it, we would need to read the kernel binary first, find out whether it has .orc_header section and then read the section to figure out the version of the ORC format in use.
I do not have familiarity with the code for the crash utility. Is it possible for someone to advise on whether the above sounds reasonable? If yes, then how to divide the functionality among the files? If no, then what would a reasonable to have this functionality?
Thanks!
9 months, 3 weeks
Re: [PATCH v6 1/5] ppc64: correct gdb passthroughs by implementing machdep->get_cpu_reg
by Lianbo Jiang
Hi, Aditya
Thank you for the great job.
The v6 patch set looks good to me, and I did not see any new issues in
my tests.
So for the v6: Ack.
Thanks
Lianbo
On 1/5/24 15:31, devel-request(a)lists.crash-utility.osci.io wrote:
> Date: Fri, 5 Jan 2024 13:00:23 +0530
> From: Aditya Gupta<adityag(a)linux.ibm.com>
> Subject: [Crash-utility] [PATCH v6 1/5] ppc64: correct gdb
> passthroughs by implementing machdep->get_cpu_reg
> To:<devel(a)lists.crash-utility.osci.io>,<lijiang(a)redhat.com>,
> Tao Liu<ltao(a)redhat.com>
> Cc: Mahesh J Salgaonkar<mahesh(a)linux.ibm.com>, "Naveen N. Rao"
> <naveen.n.rao(a)linux.vnet.ibm.com>
> Message-ID:<20240105073027.378928-2-adityag(a)linux.ibm.com>
> Content-Type: text/plain; charset=UTF-8
>
> Currently, gdb passthroughs of 'bt', 'frame', 'up', 'down', 'info
> locals' don't work. This is due to gdb not knowing the register values to
> unwind the stack frames
>
> Every gdb passthrough goes through `gdb_interface`. And then, gdb expects
> `crash_target::fetch_registers` to give it the register values, which is
> dependent on `machdep->get_cpu_reg` to read the register values for
> specific architecture.
>
> ┌────────────────────────┐
> gdb passthrough (eg. "bt") │ │
> crash ─────────────────────────▶│ │
> │ gdb_interface │
> │ │
> │ │
> │ ┌────────────────────┐ │
> fetch_registers │ │ │ │
> crash_target◀────────────────────────┼─┤ gdb │ │
> ─────────────────────────┼▶│ │ │
> Registers (SP,NIP, etc.)│ │ │ │
> │ │ │ │
> │ └────────────────────┘ │
> └────────────────────────┘
>
> Implement `machdep->get_cpu_reg` on PPC64, so that crash provides the
> register values to gdb to unwind stack frames properly
>
> With these changes, on powerpc, 'bt' command output in gdb mode, will look
> like this:
>
> gdb> bt
> #0 0xc0000000002a53e8 in crash_setup_regs (oldregs=<optimized out>, newregs=0xc00000000486f8d8) at ./arch/powerpc/include/asm/kexec.h:69
> #1 __crash_kexec (regs=<optimized out>) at kernel/kexec_core.c:974
> #2 0xc000000000168918 in panic (fmt=<optimized out>) at kernel/panic.c:358
> #3 0xc000000000b735f8 in sysrq_handle_crash (key=<optimized out>) at drivers/tty/sysrq.c:155
> #4 0xc000000000b742cc in __handle_sysrq (key=key@entry=99, check_mask=check_mask@entry=false) at drivers/tty/sysrq.c:602
> #5 0xc000000000b7506c in write_sysrq_trigger (file=<optimized out>, buf=<optimized out>, count=2, ppos=<optimized out>) at drivers/tty/sysrq.c:1163
> #6 0xc00000000069a7bc in pde_write (ppos=<optimized out>, count=<optimized out>, buf=<optimized out>, file=<optimized out>, pde=0xc000000009ed3a80) at fs/proc/inode.c:340
> #7 proc_reg_write (file=<optimized out>, buf=<optimized out>, count=<optimized out>, ppos=<optimized out>) at fs/proc/inode.c:352
> #8 0xc0000000005b3bbc in vfs_write (file=file@entry=0xc00000009dda7d00, buf=buf@entry=0xebcfc7c6040 <error: Cannot access memory at address 0xebcfc7c6040>, count=count@entry=2, pos=pos@entry=0xc00000000486fda0) at fs/read_write.c:582
>
> instead of earlier output without this patch:
>
> gdb> bt
> #0 <unavailable> in ?? ()
> Backtrace stopped: previous frame identical to this frame (corrupt stack?)
>
> Also, 'get_dumpfile_regs' has been introduced to get registers from
> multiple supported vmcore formats. Correspondingly a flag 'BT_NO_PRINT_REGS'
> has been introduced to tell helper functions to get registers, to not
> print registers with every call to backtrace in gdb.
>
> Note: This feature to support GDB unwinding doesn't support live debugging
>
> Signed-off-by: Aditya Gupta<adityag(a)linux.ibm.com>
> ---
> defs.h | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> kernel.c | 33 +++++++++++++++
> ppc64.c | 105 +++++++++++++++++++++++++++++++++++++++++++++--
> 3 files changed, 257 insertions(+), 3 deletions(-)
>
> diff --git a/defs.h b/defs.h
> index 5218a94fe4a4..615f3a37935a 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -6023,6 +6023,7 @@ int load_module_symbols_helper(char *);
> void unlink_module(struct load_module *);
> int check_specified_module_tree(char *, char *);
> int is_system_call(char *, ulong);
> +void get_dumpfile_regs(struct bt_info*, ulong*, ulong*);
> void generic_dump_irq(int);
> void generic_get_irq_affinity(int);
> void generic_show_interrupts(int, ulong *);
> @@ -6121,6 +6122,7 @@ ulong cpu_map_addr(const char *type);
> #define BT_REGS_NOT_FOUND (0x4000000000000ULL)
> #define BT_OVERFLOW_STACK (0x8000000000000ULL)
> #define BT_SKIP_IDLE (0x10000000000000ULL)
> +#define BT_NO_PRINT_REGS (0x20000000000000ULL)
> #define BT_SYMBOL_OFFSET (BT_SYMBOLIC_ARGS)
>
> #define BT_REF_HEXVAL (0x1)
> @@ -7854,4 +7856,124 @@ enum x86_64_regnum {
> LAST_REGNUM
> };
>
> +/*
> + * Register numbers to make crash_target->fetch_registers()
> + * ---> machdep->get_cpu_reg() work properly.
> + *
> + * These register numbers and names are given according to output of
> + * `rs6000_register_name`, because that is what was being used by
> + * crash_target::fetch_registers in case of PPC64
> + */
> +enum ppc64_regnum {
> + PPC64_R0_REGNUM = 0,
> + PPC64_R1_REGNUM,
> + PPC64_R2_REGNUM,
> + PPC64_R3_REGNUM,
> + PPC64_R4_REGNUM,
> + PPC64_R5_REGNUM,
> + PPC64_R6_REGNUM,
> + PPC64_R7_REGNUM,
> + PPC64_R8_REGNUM,
> + PPC64_R9_REGNUM,
> + PPC64_R10_REGNUM,
> + PPC64_R11_REGNUM,
> + PPC64_R12_REGNUM,
> + PPC64_R13_REGNUM,
> + PPC64_R14_REGNUM,
> + PPC64_R15_REGNUM,
> + PPC64_R16_REGNUM,
> + PPC64_R17_REGNUM,
> + PPC64_R18_REGNUM,
> + PPC64_R19_REGNUM,
> + PPC64_R20_REGNUM,
> + PPC64_R21_REGNUM,
> + PPC64_R22_REGNUM,
> + PPC64_R23_REGNUM,
> + PPC64_R24_REGNUM,
> + PPC64_R25_REGNUM,
> + PPC64_R26_REGNUM,
> + PPC64_R27_REGNUM,
> + PPC64_R28_REGNUM,
> + PPC64_R29_REGNUM,
> + PPC64_R30_REGNUM,
> + PPC64_R31_REGNUM,
> +
> + PPC64_F0_REGNUM = 32,
> + PPC64_F1_REGNUM,
> + PPC64_F2_REGNUM,
> + PPC64_F3_REGNUM,
> + PPC64_F4_REGNUM,
> + PPC64_F5_REGNUM,
> + PPC64_F6_REGNUM,
> + PPC64_F7_REGNUM,
> + PPC64_F8_REGNUM,
> + PPC64_F9_REGNUM,
> + PPC64_F10_REGNUM,
> + PPC64_F11_REGNUM,
> + PPC64_F12_REGNUM,
> + PPC64_F13_REGNUM,
> + PPC64_F14_REGNUM,
> + PPC64_F15_REGNUM,
> + PPC64_F16_REGNUM,
> + PPC64_F17_REGNUM,
> + PPC64_F18_REGNUM,
> + PPC64_F19_REGNUM,
> + PPC64_F20_REGNUM,
> + PPC64_F21_REGNUM,
> + PPC64_F22_REGNUM,
> + PPC64_F23_REGNUM,
> + PPC64_F24_REGNUM,
> + PPC64_F25_REGNUM,
> + PPC64_F26_REGNUM,
> + PPC64_F27_REGNUM,
> + PPC64_F28_REGNUM,
> + PPC64_F29_REGNUM,
> + PPC64_F30_REGNUM,
> + PPC64_F31_REGNUM,
> +
> + PPC64_PC_REGNUM = 64,
> + PPC64_MSR_REGNUM = 65,
> + PPC64_CR_REGNUM = 66,
> + PPC64_LR_REGNUM = 67,
> + PPC64_CTR_REGNUM = 68,
> + PPC64_XER_REGNUM = 69,
> + PPC64_FPSCR_REGNUM = 70,
> +
> + PPC64_VR0_REGNUM = 106,
> + PPC64_VR1_REGNUM,
> + PPC64_VR2_REGNUM,
> + PPC64_VR3_REGNUM,
> + PPC64_VR4_REGNUM,
> + PPC64_VR5_REGNUM,
> + PPC64_VR6_REGNUM,
> + PPC64_VR7_REGNUM,
> + PPC64_VR8_REGNUM,
> + PPC64_VR9_REGNUM,
> + PPC64_VR10_REGNUM,
> + PPC64_VR11_REGNUM,
> + PPC64_VR12_REGNUM,
> + PPC64_VR13_REGNUM,
> + PPC64_VR14_REGNUM,
> + PPC64_VR15_REGNUM,
> + PPC64_VR16_REGNUM,
> + PPC64_VR17_REGNUM,
> + PPC64_VR18_REGNUM,
> + PPC64_VR19_REGNUM,
> + PPC64_VR20_REGNUM,
> + PPC64_VR21_REGNUM,
> + PPC64_VR22_REGNUM,
> + PPC64_VR23_REGNUM,
> + PPC64_VR24_REGNUM,
> + PPC64_VR25_REGNUM,
> + PPC64_VR26_REGNUM,
> + PPC64_VR27_REGNUM,
> + PPC64_VR28_REGNUM,
> + PPC64_VR29_REGNUM,
> + PPC64_VR30_REGNUM,
> + PPC64_VR31_REGNUM,
> +
> + PPC64_VSCR_REGNUM = 138,
> + PPC64_VRSAVE_REGNU = 139
> +};
> +
> #endif /* !GDB_COMMON */
> diff --git a/kernel.c b/kernel.c
> index 6dcf414693e6..52b7ba09f390 100644
> --- a/kernel.c
> +++ b/kernel.c
> @@ -3533,6 +3533,39 @@ get_lkcd_regs(struct bt_info *bt, ulong *eip, ulong *esp)
> machdep->get_stack_frame(bt, eip, esp);
> }
>
> +void
> +get_dumpfile_regs(struct bt_info *bt, ulong *eip, ulong *esp)
> +{
> + bt->flags |= BT_NO_PRINT_REGS;
> +
> + if (NETDUMP_DUMPFILE())
> + get_netdump_regs(bt, eip, esp);
> + else if (KDUMP_DUMPFILE())
> + get_kdump_regs(bt, eip, esp);
> + else if (DISKDUMP_DUMPFILE())
> + get_diskdump_regs(bt, eip, esp);
> + else if (KVMDUMP_DUMPFILE())
> + get_kvmdump_regs(bt, eip, esp);
> + else if (LKCD_DUMPFILE())
> + get_lkcd_regs(bt, eip, esp);
> + else if (XENDUMP_DUMPFILE())
> + get_xendump_regs(bt, eip, esp);
> + else if (SADUMP_DUMPFILE())
> + get_sadump_regs(bt, eip, esp);
> + else if (VMSS_DUMPFILE())
> + get_vmware_vmss_regs(bt, eip, esp);
> + else if (REMOTE_PAUSED()) {
> + if (!is_task_active(bt->task) || !get_remote_regs(bt, eip, esp))
> + machdep->get_stack_frame(bt, eip, esp);
> + } else
> + machdep->get_stack_frame(bt, eip, esp);
> +
> + bt->flags &= ~BT_NO_PRINT_REGS;
> +
> + bt->instptr = *eip;
> + bt->stkptr = *esp;
> +}
> +
>
> /*
> * Store the head of the kernel module list for future use.
> diff --git a/ppc64.c b/ppc64.c
> index e8930a139e0d..ea4821d86b9e 100644
> --- a/ppc64.c
> +++ b/ppc64.c
> @@ -55,6 +55,8 @@ static void ppc64_set_bt_emergency_stack(enum emergency_stack_type type,
> static char * ppc64_check_eframe(struct ppc64_pt_regs *);
> static void ppc64_print_eframe(char *, struct ppc64_pt_regs *,
> struct bt_info *);
> +static int ppc64_get_cpu_reg(int cpu, int regno, const char *name, int size,
> + void *value);
> static void parse_cmdline_args(void);
> static int ppc64_paca_percpu_offset_init(int);
> static void ppc64_init_cpu_info(void);
> @@ -704,6 +706,8 @@ ppc64_init(int when)
> error(FATAL, "cannot malloc hwirqstack buffer space.");
> }
>
> + machdep->get_cpu_reg = ppc64_get_cpu_reg;
> +
> ppc64_init_paca_info();
>
> if (!machdep->hz) {
> @@ -2501,6 +2505,99 @@ ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs *regs,
> ppc64_print_nip_lr(regs, 1);
> }
>
> +static int
> +ppc64_get_cpu_reg(int cpu, int regno, const char *name, int size,
> + void *value)
> +{
> + struct bt_info bt_info, bt_setup;
> + struct task_context *tc;
> + struct ppc64_pt_regs *pt_regs;
> + ulong ip, sp;
> +
> + if (LIVE()) {
> + /* doesn't support reading registers in live dump */
> + return FALSE;
> + }
> +
> + /* Currently only handling registers available in ppc64_pt_regs:
> + *
> + * 0-31: r0-r31
> + * 64: pc/nip
> + * 65: msr
> + *
> + * 67: lr
> + * 68: ctr
> + */
> + switch (regno) {
> + case PPC64_R0_REGNUM ... PPC64_R31_REGNUM:
> +
> + case PPC64_PC_REGNUM:
> + case PPC64_MSR_REGNUM:
> + case PPC64_LR_REGNUM:
> + case PPC64_CTR_REGNUM:
> + break;
> +
> + default:
> + // return false if we can't get that register
> + if (CRASHDEBUG(1))
> + error(WARNING, "unsupported register, regno=%d\n", regno);
> + return FALSE;
> + }
> +
> + tc = CURRENT_CONTEXT();
> + BZERO(&bt_setup, sizeof(struct bt_info));
> + clone_bt_info(&bt_setup, &bt_info, tc);
> + fill_stackbuf(&bt_info);
> +
> + // reusing the get_dumpfile_regs function to get pt regs structure
> + get_dumpfile_regs(&bt_info, &sp, &ip);
> + pt_regs = (struct ppc64_pt_regs *)bt_info.machdep;
> +
> + if (!pt_regs) {
> + error(WARNING, "pt_regs not available for cpu %d\n", cpu);
> + return FALSE;
> + }
> +
> + switch (regno) {
> + case PPC64_R0_REGNUM ... PPC64_R31_REGNUM:
> + if (size != sizeof(pt_regs->gpr[regno]))
> + return FALSE; // size mismatch
> +
> + memcpy(value, &pt_regs->gpr[regno], size);
> + break;
> +
> + case PPC64_PC_REGNUM:
> + if (size != sizeof(pt_regs->nip))
> + return FALSE; // size mismatch
> +
> + memcpy(value, &pt_regs->nip, size);
> + break;
> +
> + case PPC64_MSR_REGNUM:
> + if (size != sizeof(pt_regs->msr))
> + return FALSE; // size mismatch
> +
> + memcpy(value, &pt_regs->msr, size);
> + break;
> +
> + case PPC64_LR_REGNUM:
> + if (size != sizeof(pt_regs->link))
> + return FALSE; // size mismatch
> +
> + memcpy(value, &pt_regs->link, size);
> + break;
> +
> + case PPC64_CTR_REGNUM:
> + if (size != sizeof(pt_regs->ctr))
> + return FALSE; // size mismatch
> +
> + memcpy(value, &pt_regs->ctr, size);
> + break;
> + }
> +
> + return TRUE;
> +}
> +
> /*
> * For vmcore typically saved with KDump or FADump, get SP and IP values
> * from the saved ptregs.
> @@ -2613,9 +2710,11 @@ 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);
> + if (!(bt->flags & BT_NO_PRINT_REGS)) {
> + /* 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.43.0
9 months, 3 weeks
Re: [PATCHv2] crash add log dmesg PRINTK_CALLER id support
by Lianbo Jiang
Hi, Edward and Kazu
Sorry for the late reply.
On 1/22/24 16:02, devel-request(a)lists.crash-utility.osci.io wrote:
> Date: Mon, 22 Jan 2024 08:01:50 +0000
> From: HAGIO KAZUHITO(萩尾 一仁)<k-hagio-ab(a)nec.com>
> Subject: [Crash-utility] Re: [PATCHv2] crash add log dmesg
> PRINTK_CALLER id support
> To: Edward Chron<echron(a)arista.com>,
> "devel(a)lists.crash-utility.osci.io"
> <devel(a)lists.crash-utility.osci.io>
> Cc:"echron(a)gmail.com" <echron(a)gmail.com>, Ivan Delalande
> <colona(a)arista.com>
> Message-ID:<d1d21cde-d15c-19f5-7068-92d64a1f19a7(a)nec.com>
> Content-Type: text/plain; charset="utf-8"
>
> On 2024/01/22 3:31, Edward Chron wrote:
>> Submission to Project: crash
>> Component: dmesg
>> Files: kernel.c printk.c symbols.c help.c defs.h
>> Code level patch applied against: 8.0.4++ - latest code pulled from
>> https://github.com/crash-utility/crash.git
>> crash Issue #164
>> Patch Version #2: per review from Hagio Kazuhito<k-hagio-ab(a)nec.com>
> Thanks for the update, looks good to me.
Could you please help add the kernel commit to patch log? Kazu.
15ff2069cb7f ("printk: Add caller information to printk() output.")
The code looks good to me, so: Ack.
Lianbo
>
> Acked-by: Kazuhito Hagio<k-hagio-ab(a)nec.com>
>
> Thanks,
> Kazu
>
>> Tested with Kernel version and makedumpfile version:
>> Linux Kernel Testing: Linux catalina 6.6.6 #4 SMP PREEMPT_DYNAMIC
>> Tue Dec 12 23:11:30 PST 2023 x86_64 GNU/Linux
>> Linux 5.4.264 #9 SMP
>> Thu Dec 21 07:00:08 PST 2023
>> makedumpfile Testing: makedumpfile: version 1.7.4++
>> (released on 6 Nov 2023)
>> Issue 13 for makedumpfile: adds support for
>> demsg PRINTK_CALLER id field patch applied
>> dmesg Testing: util-linux 2.39.3++
>> Issue 2609 for sys-utils dmesg: adds support for
>> dmesg PRINTK_CALLER id field to standard
>> dmesg kmsg interface patch applied
>>
>> Add support so that dmesg entries include the optional Linux Kernel
>> debug CONFIG option PRINTK_CALLER which adds an optional dmesg field
>> that contains the Thread Id or CPU Id that is issuing the printk to
>> add the message to the kernel ring buffer. If enabled, this CONFIG
>> option makes debugging simpler as dmesg entries for a specific
>> thread or CPU can be recognized.
>>
>> The dmesg command supports printing the PRINTK_CALLER field. The
>> old syslog format (dmesg -S) and recently support was added for dmesg
>> using /dev/kmsg interface with util-linux Issue #2609 as we upstreamed
>> a commit that is under review.
>>
>> We've upstreamed a patch for makedumpfile that adds support for
>> the PRINTK_CALLER id field so it will be available with the
>> commands:
>>
>> makedumpfile --dump-dmesg /proc/vmcore dmesgfile
>> makedumpfile --dump-dmesg -x vmlinux /proc/vmcore dmesgfile
>>
>> The additional field provided by PRINTK_CALLER is only present
>> if it was configured for the Linux kernel on the running system. The
>> PRINTK_CALLER is a debug option and not configured by default so the
>> dmesg output will only change for those kernels where the option was
>> configured when the kernel was built. For users who went to the
>> trouble to configure PRINTK_CALLER and have the extra field available
>> for debugging, having dmesg print the field is very helpful and so
>> will be makedumpfile and so it would be very useful to have crash
>> support for dump analysis.
>>
>> Size of the PRINTK_CALLER field is determined by the maximum number
>> tasks that can be run on the system which is limited by the value of
>> /proc/sys/kernel/pid_max as pid values are from 0 to value - 1.
>> This value determines the number of id digits needed by the caller id.
>> The PRINTK_CALLER field is printed as T<id> for a Task Id or C<id>
>> for a CPU Id for a printk in CPU context. The values are left space
>> padded and enclosed in parentheses such as:
>> [ T123] or [ C16]
>>
>> Displaying the PRINTK_CALLER field in the log/dmesg record output:
>> -----------------------------------------------------------------
>>
>> Given the layout of log/dmesg records printed by crash, for example:
>>
>> crash> log -m
>> ...
>> [ 0.000000] <7>e820: remove [mem 0xff000000-0xffffffff] reserved
>> [ 0.000000] <6>SMBIOS 3.4.0 present.
>> ...
>> [ 0.014179] <6>Secure boot disabled
>> [ 0.014179] <6>RAMDISK: [mem 0x3cf4f000-0x437bbfff]
>> ...
>> [ 663.328848] <6>sysrq: Trigger a crash
>> [ 663.328859] <0>Kernel panic - not syncing: sysrq triggered crash
>>
>> Our patch adds the PRINTK_CALLER field after the timestamp if the
>> printk_caller log / dmesg option (-c) is selected:
>>
>> crash> log -m -c
>> ...
>> [ 0.014179] [ T1] <6>Secure boot disabled
>> [ 0.014179] [ T29] <6>RAMDISK: [mem 0x3cf4f000-0x437bbfff]
>> ...
>>
>> This is consistent placement with dmesg and makedumpfile.
>>
>> To produce dmesg output with the PRINTK_CALLER id included, we add
>> a new log / dmesg command option: -c
>>
>> The PRINTK_CALLER id field is printed only if the -c option is selected.
>> The description of the log -c option that is seen in the help is:
>>
>> crash> log help
>>
>> log
>> dump system message buffer
>> [-Ttdmasc]
>>
>> ...
>> ...
>>
>> -c Display the caller id field that identifies either the thread id or
>> the CPU id (if in CPU context) that called printk(), if available.
>> Generally available on Linux 5.1 to 5.9 kernels configured with
>> CONFIG_PRINTK_CALLER or Linux 5.10 and later kernels.
>>
>> Also seen in the help file :
>>
>> Display the caller id that identifies the thread id of the task (begins
>> with 'T') or the processor id (begins with 'C' for in CPU context) that
>> called printk(), if available.
>>
>> crash> log -c
>> ...
>> [ 0.014179] [ T1] Secure boot disabled
>> [ 0.014179] [ T29] RAMDISK: [mem 0x3cf4f000-0x437bbfff]
>> [ 0.198789] [ C0] DMAR: DRHD: handling fault status reg 3
>> ...
>>
>> Signed-off-by: Ivan Delalande<colona(a)arista.com>
>> Signed-off-by: Edward Chron<echron(a)arista.com>
>> ---
>> defs.h | 18 ++++++++++++------
>> help.c | 19 +++++++++++++++++--
>> kernel.c | 25 ++++++++++++++++++++++++-
>> printk.c | 34 ++++++++++++++++++++++++++++++++++
>> symbols.c | 2 ++
>> 6 files changed, 98 insertions(+), 18 deletions(-)
>>
>> diff --git a/defs.h b/defs.h
>> index 2a29c07..488214f 100644
>> --- a/defs.h
>> +++ b/defs.h
>> @@ -2228,8 +2228,13 @@ struct offset_table { /* stash of commonly-used offsets */
>> long irq_data_irq;
>> long zspage_huge;
>> long zram_comp_algs;
>> + long log_caller_id;
>> };
>>
>> +/* caller_id default and max character sizes based on pid field size */
>> +#define PID_CHARS_MAX 16 /* Max Number of PID characters */
>> +#define PID_CHARS_DEFAULT 8 /* Default number of PID characters */
>> +
>> struct size_table { /* stash of commonly-used sizes */
>> long page;
>> long free_area_struct;
>> @@ -6044,12 +6049,13 @@ void dump_log(int);
>> void parse_kernel_version(char *);
>>
>> #define LOG_LEVEL(v) ((v) & 0x07)
>> -#define SHOW_LOG_LEVEL (0x1)
>> -#define SHOW_LOG_DICT (0x2)
>> -#define SHOW_LOG_TEXT (0x4)
>> -#define SHOW_LOG_AUDIT (0x8)
>> -#define SHOW_LOG_CTIME (0x10)
>> -#define SHOW_LOG_SAFE (0x20)
>> +#define SHOW_LOG_LEVEL (0x1)
>> +#define SHOW_LOG_DICT (0x2)
>> +#define SHOW_LOG_TEXT (0x4)
>> +#define SHOW_LOG_AUDIT (0x8)
>> +#define SHOW_LOG_CTIME (0x10)
>> +#define SHOW_LOG_SAFE (0x20)
>> +#define SHOW_LOG_CALLER (0x40)
>> void set_cpu(int);
>> void clear_machdep_cache(void);
>> struct stack_hook *gather_text_list(struct bt_info *);
>> diff --git a/help.c b/help.c
>> index a4319dd..ae02a57 100644
>> --- a/help.c
>> +++ b/help.c
>> @@ -4023,7 +4023,7 @@ NULL
>> char *help_log[] = {
>> "log",
>> "dump system message buffer",
>> -"[-Ttdmas]",
>> +"[-Ttdmasc]",
>> " This command dumps the kernel log_buf contents in chronological order. The",
>> " command supports the older log_buf formats, which may or may not contain a",
>> " timestamp inserted prior to each message, as well as the newer variable-length",
>> @@ -4046,7 +4046,11 @@ char *help_log[] = {
>> " been copied out to the user-space audit daemon.",
>> " -s Dump the printk logs remaining in kernel safe per-CPU buffers that",
>> " have not been flushed out to log_buf.",
>> -" ",
>> +" -c Display the caller id field that identifies either the thread id or",
>> +" the CPU id (if in CPU context) that called printk(), if available.",
>> +" Generally available on Linux 5.1 to 5.9 kernels configured with",
>> +" CONFIG_PRINTK_CALLER or Linux 5.10 and later kernels.",
>> +" ",
>> "\nEXAMPLES",
>> " Dump the kernel message buffer:\n",
>> " %s> log",
>> @@ -4214,6 +4218,17 @@ char *help_log[] = {
>> " CPU: 0 ADDR: ffff8ca4fbc1ad00 LEN: 0 MESSAGE_LOST: 0",
>> " (empty)",
>> " ...",
>> +" ",
>> +" Display the caller id that identifies the thread id of the task (begins",
>> +" with 'T') or the processor id (begins with 'C' for in CPU context) that",
>> +" called printk(), if available.\n",
>> +" %s> log -c",
>> +" ...",
>> +" [ 0.014179] [ T1] Secure boot disabled",
>> +" [ 0.014179] [ T29] RAMDISK: [mem 0x3cf4f000-0x437bbfff]",
>> +" [ 0.198789] [ C0] DMAR: DRHD: handling fault status reg 3",
>> +" ...",
>> +
>> NULL
>> };
>>
>> diff --git a/kernel.c b/kernel.c
>> index 6dcf414..bcd10f9 100644
>> --- a/kernel.c
>> +++ b/kernel.c
>> @@ -5089,7 +5089,7 @@ cmd_log(void)
>>
>> msg_flags = 0;
>>
>> - while ((c = getopt(argcnt, args, "Ttdmas")) != EOF) {
>> + while ((c = getopt(argcnt, args, "Ttdmasc")) != EOF) {
>> switch(c)
>> {
>> case 'T':
>> @@ -5110,6 +5110,9 @@ cmd_log(void)
>> case 's':
>> msg_flags |= SHOW_LOG_SAFE;
>> break;
>> + case 'c':
>> + msg_flags |= SHOW_LOG_CALLER;
>> + break;
>> default:
>> argerrs++;
>> break;
>> @@ -5369,6 +5372,24 @@ dump_log_entry(char *logptr, int msg_flags)
>> fprintf(fp, "%s", buf);
>> }
>>
>> + /* The PRINTK_CALLER id field was introduced with Linux-5.1 so if
>> + * requested, Kernel version >= 5.1 and field exists print caller_id.
>> + */
>> + if (msg_flags & SHOW_LOG_CALLER &&
>> + VALID_MEMBER(log_caller_id)) {
>> + const unsigned int cpuid = 0x80000000;
>> + char cbuf[PID_CHARS_MAX];
>> + unsigned int cid;
>> +
>> + /* Get id type, isolate just id value in cid for print */
>> + cid = UINT(logptr + OFFSET(log_caller_id));
>> + sprintf(cbuf, "%c%d", (cid & cpuid) ? 'C' : 'T', cid & ~cpuid);
>> + sprintf(buf, "[%*s] ", PID_CHARS_DEFAULT, cbuf);
>> +
>> + ilen += strlen(buf);
>> + fprintf(fp, "%s", buf);
>> + }
>> +
>> level = LOG_LEVEL(level);
>>
>> if (msg_flags & SHOW_LOG_LEVEL) {
>> @@ -5424,6 +5445,8 @@ dump_variable_length_record_log(int msg_flags)
>> * from log to printk_log. See 62e32ac3505a0cab.
>> */
>> log_struct_name = "printk_log";
>> + MEMBER_OFFSET_INIT(log_caller_id, "printk_log",
>> + "caller_id");
>> } else
>> log_struct_name = "log";
>>
>> diff --git a/printk.c b/printk.c
>> index 8658016..ae3fa4f 100644
>> --- a/printk.c
>> +++ b/printk.c
>> @@ -9,6 +9,7 @@ struct prb_map {
>> unsigned long desc_ring_count;
>> char *descs;
>> char *infos;
>> + unsigned int pid_max_chars;
>>
>> char *text_data_ring;
>> unsigned long text_data_ring_size;
>> @@ -162,6 +163,24 @@ dump_record(struct prb_map *m, unsigned long id, int msg_flags)
>> fprintf(fp, "%s", buf);
>> }
>>
>> + /*
>> + * The lockless ringbuffer introduced in Linux-5.10 always has
>> + * the caller_id field available, so if requested, print it.
>> + */
>> + if (msg_flags & SHOW_LOG_CALLER) {
>> + const unsigned int cpuid = 0x80000000;
>> + char cbuf[PID_CHARS_MAX];
>> + unsigned int cid;
>> +
>> + /* Get id type, isolate id value in cid for print */
>> + cid = UINT(info + OFFSET(printk_info_caller_id));
>> + sprintf(cbuf, "%c%d", (cid & cpuid) ? 'C' : 'T', cid & ~cpuid);
>> + sprintf(buf, "[%*s] ", m->pid_max_chars, cbuf);
>> +
>> + ilen += strlen(buf);
>> + fprintf(fp, "%s", buf);
>> + }
>> +
>> if (msg_flags & SHOW_LOG_LEVEL) {
>> level = UCHAR(info + OFFSET(printk_info_level)) >> 5;
>> sprintf(buf, "<%x>", level);
>> @@ -262,6 +281,21 @@ dump_lockless_record_log(int msg_flags)
>> goto out_text_data;
>> }
>>
>> + /* If caller_id was requested, get the pid_max value for print */
>> + if (msg_flags & SHOW_LOG_CALLER) {
>> + unsigned int pidmax;
>> +
>> + get_symbol_data("pid_max", sizeof(pidmax), &pidmax);
>> + if (pidmax <= 99999)
>> + m.pid_max_chars = 6;
>> + else if (pidmax <= 999999)
>> + m.pid_max_chars = 7;
>> + else
>> + m.pid_max_chars = PID_CHARS_DEFAULT;
>> + } else {
>> + m.pid_max_chars = PID_CHARS_DEFAULT;
>> + }
>> +
>> /* ready to go */
>>
>> tail_id = ULONG(m.desc_ring + OFFSET(prb_desc_ring_tail_id) +
>> diff --git a/symbols.c b/symbols.c
>> index 88a3fd1..554d109 100644
>> --- a/symbols.c
>> +++ b/symbols.c
>> @@ -11524,6 +11524,8 @@ dump_offset_table(char *spec, ulong makestruct)
>> OFFSET(log_level));
>> fprintf(fp, " log_flags_level: %ld\n",
>> OFFSET(log_flags_level));
>> + fprintf(fp, " log_caller_id: %ld\n",
>> + OFFSET(log_caller_id));
>>
>> fprintf(fp, " printk_info_seq: %ld\n", OFFSET(printk_info_seq));
>> fprintf(fp, " printk_info_ts_nseq: %ld\n", OFFSET(printk_info_ts_nsec));
9 months, 4 weeks
[PATCH] Fix "mount" command failure on Linux 6.8-rc1 and later
by HAGIO KAZUHITO(萩尾 一仁)
Kernel commit 2eea9ce4310d ("mounts: keep list of mounts in an rbtree")
changed the structure that keeps the list of mounts to an rbtree.
Without the patch, "mount" command fails with the following error:
crash> mount
mount: invalid structure member offset: mnt_namespace_list
FILE: filesys.c LINE: 1643 FUNCTION: get_mount_list()
Signed-off-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
---
defs.h | 3 +++
filesys.c | 29 +++++++++++++++++++++++++++++
symbols.c | 3 +++
3 files changed, 35 insertions(+)
diff --git a/defs.h b/defs.h
index d1edce9893d1..ca1ac79ffa3e 100644
--- a/defs.h
+++ b/defs.h
@@ -2236,6 +2236,9 @@ struct offset_table { /* stash of commonly-used offsets */
long zram_comp_algs;
long task_struct_thread_reg01;
long task_struct_thread_reg03;
+ long mnt_namespace_mounts;
+ long mnt_namespace_nr_mounts;
+ long mount_mnt_node;
};
struct size_table { /* stash of commonly-used sizes */
diff --git a/filesys.c b/filesys.c
index 1d0ee7f0b24a..81fe856699e1 100644
--- a/filesys.c
+++ b/filesys.c
@@ -1634,6 +1634,31 @@ get_mount_list(int *cntptr, struct task_context *namespace_context)
&mnt_ns, sizeof(void *), "nsproxy mnt_ns",
RETURN_ON_ERROR|QUIET))
error(FATAL, "cannot determine mount list location!\n");
+
+ /* Linux 6.8 and later keep list of mounts in an rbtree. */
+ if (VALID_MEMBER(mnt_namespace_nr_mounts)) {
+ uint nr_mounts;
+ ulong *mntlist, *l;
+ struct rb_root *mounts;
+ struct rb_node *node;
+
+ readmem(mnt_ns + OFFSET(mnt_namespace_nr_mounts), KVADDR, &nr_mounts,
+ sizeof(uint), "mnt_namespace.nr_mounts", FAULT_ON_ERROR);
+
+ if (!nr_mounts)
+ error(FATAL, "nr_mounts is zero!\n");
+
+ mounts = (struct rb_root *)(mnt_ns + OFFSET(mnt_namespace_mounts));
+
+ mntlist = (ulong *)GETBUF(sizeof(ulong) * nr_mounts);
+ l = mntlist;
+ for (node = rb_first(mounts); node; l++, node = rb_next(node))
+ *l = (ulong)node - OFFSET(mount_mnt_node);
+
+ *cntptr = nr_mounts;
+ return mntlist;
+ }
+
if (!readmem(mnt_ns + OFFSET(mnt_namespace_root), KVADDR,
&root, sizeof(void *), "mnt_namespace root",
RETURN_ON_ERROR|QUIET))
@@ -2063,6 +2088,10 @@ vfs_init(void)
MEMBER_OFFSET_INIT(nsproxy_mnt_ns, "nsproxy", "mnt_ns");
MEMBER_OFFSET_INIT(mnt_namespace_root, "mnt_namespace", "root");
MEMBER_OFFSET_INIT(mnt_namespace_list, "mnt_namespace", "list");
+ /* Linux 6.8 and later */
+ MEMBER_OFFSET_INIT(mnt_namespace_mounts, "mnt_namespace", "mounts");
+ MEMBER_OFFSET_INIT(mnt_namespace_nr_mounts, "mnt_namespace", "nr_mounts");
+ MEMBER_OFFSET_INIT(mount_mnt_node, "mount", "mnt_node");
} else if (THIS_KERNEL_VERSION >= LINUX(2,4,20)) {
if (CRASHDEBUG(2))
fprintf(fp, "hardwiring namespace stuff\n");
diff --git a/symbols.c b/symbols.c
index d43785d3126a..b07b101767c8 100644
--- a/symbols.c
+++ b/symbols.c
@@ -9925,6 +9925,8 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(mnt_namespace_root));
fprintf(fp, " mnt_namespace_list: %ld\n",
OFFSET(mnt_namespace_list));
+ fprintf(fp, " mnt_namespace_mounts: %ld\n", OFFSET(mnt_namespace_mounts));
+ fprintf(fp, " mnt_namespace_nr_mounts: %ld\n", OFFSET(mnt_namespace_nr_mounts));
fprintf(fp, " pid_namespace_idr: %ld\n",
OFFSET(pid_namespace_idr));
@@ -10581,6 +10583,7 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(mount_mnt_devname));
fprintf(fp, " mount_mnt: %ld\n",
OFFSET(mount_mnt));
+ fprintf(fp, " mount_mnt_node: %ld\n", OFFSET(mount_mnt_node));
fprintf(fp, " namespace_root: %ld\n",
OFFSET(namespace_root));
fprintf(fp, " namespace_list: %ld\n",
--
2.31.1
10 months
[Crash-utility][PATCH v3 00/10] add LoongArch64 platform support
by Ming Wang
This patch set are for Crash-utility tool, it make crash tool support on
loongarch64 architecture and the common commands(bt, p, rd, mod, log, set,
dis, and so on).
The patch sets were tested on a loongArch64 Loongson-3C5000 processor. Can
successfully enter the crash command line and support for common command.
...
KERNEL: vmlinux
DUMPFILE: /proc/kcore
CPUS: 16
DATE: Thu Jul 27 19:51:21 CST 2023
UPTIME: 06:35:11
LOAD AVERAGE: 0.15, 0.03, 0.01
TASKS: 257
NODENAME: localhost.localdomain
RELEASE: 5.10.0-60.102.0.128.oe2203.loongarch64
VERSION: #1 SMP Fri Jul 14 04:17:09 UTC 2023
MACHINE: loongarch64 (2200 Mhz)
MEMORY: 64 GB
PID: 2964
COMMAND: "crash"
TASK: 9000000098805500 [THREAD_INFO: 9000000094d48000]
CPU: 6
STATE: TASK_RUNNING (ACTIVE)
crash>
crash> dis -l start_kernel
/linux-loongarch64/init/main.c: 883
0x9000000001030818 <start_kernel>: 0x0141ee40
/linux-loongarch64/init/main.c: 879
0x900000000103081c <start_kernel+4>: 0x90000000
/linux-loongarch64/init/main.c: 883
0x9000000001030820 <start_kernel+8>: addu16i.d $zero, $t8, 8179(0x1ff3)
/linux-loongarch64/init/main.c: 879
...
About the LoongArch64 Architecture:
https://www.kernel.org/doc/html/latest/arch/loongarch/introduction.html
Changes between v2 and v3:
- Fix some compilation warnings.
- Fix build errors when without target.
- Some minor code adjustments.
Thanks and regards,
Ming
Ming Wang (10):
Add LoongArch64 framework code support
LoongArch64: Make the crash tool successfully enter the crash command
line
LoongArch64: Add 'pte' command support
LoongArch64: Add 'mach' command support
LoongArch64: Add 'bt' command support
LoongArch64: Add 'help -m/M' command support
LoongArch64: Add 'help -r' command support
LoongArch64: Add 'irq' command support
LoongArch64: Add "--kaslr" command line option support
LoongArch64: Add LoongArch64 architecture support information
Makefile | 7 +-
README | 4 +-
configure.c | 43 +-
crash.8 | 2 +-
defs.h | 164 +-
diskdump.c | 24 +-
gdb-10.2.patch | 12822 +++++++++++++++++++++++++++++++++++++++++-
help.c | 13 +-
lkcd_vmdump_v1.h | 2 +-
lkcd_vmdump_v2_v3.h | 5 +-
loongarch64.c | 1368 +++++
main.c | 3 +-
netdump.c | 27 +-
ramdump.c | 2 +
symbols.c | 33 +-
15 files changed, 14493 insertions(+), 26 deletions(-)
create mode 100644 loongarch64.c
base-commit: 53d2577cef98b76b122aade94349637a11e06138
--
2.39.2
10 months
[PATCH] crash add log dmesg PRINTK_CALLER id support
by Edward Chron
From: Edward Chron <echron(a)gmail.com>
Submission to Project: crash
Component: dmesg
Files: printk.c makedumpfile.c makedumpfile.h
Code level patch applied against: 8.0.4++ - latest code pulled from
https://github.com/crash-utility/crash.git
crash Issue #164
Tested with Kernel version and makedumpfile version:
Linux Kernel Testing: Linux catalina 6.6.6 #4 SMP PREEMPT_DYNAMIC
Tue Dec 12 23:11:30 PST 2023 x86_64 GNU/Linux
Linux 5.4.264 #9 SMP
Thu Dec 21 07:00:08 PST 2023
makedumpfile Testing: makedumpfile: version 1.7.4++
(released on 6 Nov 2023)
Issue 13 for makedumpfile: adds support for
demsg PRINTK_CALLER id field
dmesg Testing: util-linux 2.39.3++
Issue 2609 for sys-utils dmesg: adds support for
dmesg PRINTK_CALLER id field to standard
dmesg kmsg interface
Add support so that dmesg entries include the optional Linux Kernel
debug CONFIG option PRINTK_CALLER which adds an optional dmesg field
that contains the Thread Id or CPU Id that is issuing the printk to
add the message to the kernel ring buffer. If enabled, this CONFIG
option makes debugging simpler as dmesg entries for a specific
thread or CPU can be recognized.
The dmesg command supports printing the PRINTK_CALLER field. The
old syslog format (dmesg -S) and recently support was added for dmesg
using /dev/kmsg interface with util-linux Issue #2609 as we upstreamed
a commit that is under review.
We've upstreamed a patch for makedumpfile that adds support for
the PRINTK_CALLER id field so it will be available with the
commands:
makedumpfile --dump-dmesg /proc/vmcore dmesgfile
makedumpfile --dump-dmesg -x vmlinux /proc/vmcore dmesgfile
The additional field provided by PRINTK_CALLER is only present
if it was configured for the Linux kernel on the running system. The
PRINTK_CALLER is a debug option and not configured by default so the
dmesg output will only change for those kernels where the option was
configured when the kernel was built. For users who went to the
trouble to configure PRINTK_CALLER and have the extra field available
for debugging, having dmesg print the field is very helpful and so
will be makedumpfile and so it would be very useful to have crash
support for dump analysis.
Size of the PRINTK_CALLER field is determined by the maximum number
tasks that can be run on the system which is limited by the value of
/proc/sys/kernel/pid_max as pid values are from 0 to value - 1.
This value determines the number of id digits needed by the caller id.
The PRINTK_CALLER field is printed as T<id> for a Task Id or C<id>
for a CPU Id for a printk in CPU context. The values are left space
padded and enclosed in parentheses such as:
[ T123] or [ C16]
Displaying the PRINTK_CALLER field in the log/dmesg record output:
-----------------------------------------------------------------
Given the layout of log/dmesg records printed by crash, for example:
crash> log -m
...
[ 0.000000] <7>e820: remove [mem 0xff000000-0xffffffff] reserved
[ 0.000000] <6>SMBIOS 3.4.0 present.
...
[ 0.014179] <6>Secure boot disabled
[ 0.014179] <6>RAMDISK: [mem 0x3cf4f000-0x437bbfff]
...
[ 663.328848] <6>sysrq: Trigger a crash
[ 663.328859] <0>Kernel panic - not syncing: sysrq triggered crash
Our patch adds the PRINTK_CALLER field after the timestamp if the
printk_caller log / dmesg option (-P) is selected:
crash> log -m -P
...
[ 0.014179] [ T1] <6>Secure boot disabled
[ 0.014179] [ T29] <6>RAMDISK: [mem 0x3cf4f000-0x437bbfff]
...
This is consistent placement with dmesg and makedumpfile.
To produce dmesg output with the PRINTK_CALLER id included, we add
a new log / dmesg command option: -P
The PRINTK_CALLER id field is printed only if the -P option is selected.
The description of the log -P option that is seen in the help is:
crash> log help
log
dump system message buffer
[-TtdmasP]
...
...
-P Display the PRINTK_CALLER id field that identifies the thread id or
the CPU id of the task that issued the printk to add the message to
the kernel ring buffer. Displaying this field is only possible for
Linux kernels that are Linux 5.1 or newer since kernels prior to
Linux 5.1 did not provide a PRINTK_CALLER field. So, this option is
ignored for kernels older than Linux 5.1. The CONFIG_PRINTK_CALLER
kernel configuration option should be selected to make the caller_id
field available and for vmcore files your version of makedumpfile
must support dumping the caller_id field for it to be available here.
Also seen in the help file :
On systems that are properly configured to make the log caller_id field
available to the crash utility, you can select to print log records and
include the caller_id field with each log record. The log PRINTK_CALLER
id option (-P) will print either the Thread id or the CPU id depending on
the context of the process at the time the printk request was made. The
output of the thread id (begins with T) or the CPU id (begins with C) is
placed inside square brackets and is padded with leading space to keep
alignment. The caller_id field follows the timestamp field if that field
is selected:
crash> log -P
...
[ 0.014179] [ T1] Secure boot disabled
[ 0.014179] [ T29] RAMDISK: [mem 0x3cf4f000-0x437bbfff]
[ 0.198789] [ C0] DMAR: DRHD: handling fault status reg 3
...
crash> log -P -m
...
[ 0.014179] [ T1] <6>Secure boot disabled
[ 0.014179] [ T29] <6>RAMDISK: [mem 0x3cf4f000-0x437bbfff]
[ 0.198789] [ C0] <6>DMAR: DRHD: handling fault status reg 3
...
crash> log -t -P -m
...
[ T1] <6>Secure boot disabled
[ T29] <6>RAMDISK: [mem 0x3cf4f000-0x437bbfff]
[ C0] <6>DMAR: DRHD: handling fault status reg 3
...
crash> log -T -P -m
...
[Tue Dec 12 23:25:03 PST 2023] [ T1] <6>Secure boot disabled
[Tue Dec 12 23:25:03 PST 2023] [ T29] <6>RAMDISK: [mem 0x3cf4f000-0x437bbfff]
[Tue Dec 12 23:25:03 PST 2023] [ C0] <6>DMAR: DRHD: handling fault status reg 3
...
Signed-off-by: Ivan Delalande <colona(a)arista.com>
Signed-off-by: Edward Chron <echron(a)arista.com>
---
defs.h | 15 +++++++++------
help.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++--
kernel.c | 47 +++++++++++++++++++++++++++++++++++++++++++++--
printk.c | 39 +++++++++++++++++++++++++++++++++++++++
symbols.c | 2 ++
6 files changed, 150 insertions(+), 19 deletions(-)
diff --git a/defs.h b/defs.h
index 20237b7..a61e832 100644
--- a/defs.h
+++ b/defs.h
@@ -784,6 +784,7 @@ struct kernel_table { /* kernel data */
long log_len_OFFSET;
long log_text_len_OFFSET;
long log_dict_len_OFFSET;
+ ulong log_caller_id_OFFSET;
ulong phys_base_SYMBOL;
ulong _stext_SYMBOL;
} vmcoreinfo;
@@ -1943,6 +1944,7 @@ struct offset_table { /* stash of commonly-used offsets */
long log_dict_len;
long log_level;
long log_flags_level;
+ long log_caller_id;
long timekeeper_xtime_sec;
long neigh_table_hash_mask;
long sched_rt_entity_my_q;
@@ -6037,12 +6039,13 @@ void dump_log(int);
void parse_kernel_version(char *);
#define LOG_LEVEL(v) ((v) & 0x07)
-#define SHOW_LOG_LEVEL (0x1)
-#define SHOW_LOG_DICT (0x2)
-#define SHOW_LOG_TEXT (0x4)
-#define SHOW_LOG_AUDIT (0x8)
-#define SHOW_LOG_CTIME (0x10)
-#define SHOW_LOG_SAFE (0x20)
+#define SHOW_LOG_LEVEL (0x1)
+#define SHOW_LOG_DICT (0x2)
+#define SHOW_LOG_TEXT (0x4)
+#define SHOW_LOG_AUDIT (0x8)
+#define SHOW_LOG_CTIME (0x10)
+#define SHOW_LOG_SAFE (0x20)
+#define SHOW_LOG_CALLER (0x40)
void set_cpu(int);
void clear_machdep_cache(void);
struct stack_hook *gather_text_list(struct bt_info *);
diff --git a/help.c b/help.c
index cc7ab20..1de1292 100644
--- a/help.c
+++ b/help.c
@@ -4023,7 +4023,7 @@ NULL
char *help_log[] = {
"log",
"dump system message buffer",
-"[-Ttdmas]",
+"[-TtdmasP]",
" This command dumps the kernel log_buf contents in chronological order. The",
" command supports the older log_buf formats, which may or may not contain a",
" timestamp inserted prior to each message, as well as the newer variable-length",
@@ -4046,7 +4046,16 @@ char *help_log[] = {
" been copied out to the user-space audit daemon.",
" -s Dump the printk logs remaining in kernel safe per-CPU buffers that",
" have not been flushed out to log_buf.",
-" ",
+" -P Display the PRINTK_CALLER id field that identifies the thread id or",
+" the CPU id of the task that issued the printk to add the message to",
+" the kernel ring buffer. Displaying this field is only possible for",
+" Linux kernels that are Linux 5.1 or newer since kernels prior to",
+" Linux 5.1 did not provide a PRINTK_CALLER field. So, this option is",
+" ignored for kernels older than Linux 5.1. The CONFIG_PRINTK_CALLER",
+" kernel configuration option should be selected to make the caller_id",
+" field available and for vmcore files your version of makedumpfile",
+" must support dumping the caller_id field for it to be available here.",
+" ",
"\nEXAMPLES",
" Dump the kernel message buffer:\n",
" %s> log",
@@ -4214,6 +4223,41 @@ char *help_log[] = {
" CPU: 0 ADDR: ffff8ca4fbc1ad00 LEN: 0 MESSAGE_LOST: 0",
" (empty)",
" ...",
+" ",
+" On systems that are properly configured to make the log caller_id field",
+" available to the crash utility, you can select to print log records and",
+" include the caller_id field with each log record. The log PRINTK_CALLER",
+" id option (-P) will print either the Thread id or the CPU id depending on",
+" the context of the process at the time the printk request was made. The",
+" output of the thread id (begins with T) or the CPU id (begins with C) is",
+" placed inside square brackets and is padded with leading space to keep",
+" alignment. The caller_id field follows the timestamp field if that field",
+" is selected:\n",
+" %s> log -P",
+" ...",
+" [ 0.014179] [ T1] Secure boot disabled",
+" [ 0.014179] [ T29] RAMDISK: [mem 0x3cf4f000-0x437bbfff]",
+" [ 0.198789] [ C0] DMAR: DRHD: handling fault status reg 3",
+" ...",
+" %s> log -P -m",
+" ...",
+" [ 0.014179] [ T1] <6>Secure boot disabled",
+" [ 0.014179] [ T29] <6>RAMDISK: [mem 0x3cf4f000-0x437bbfff]",
+" [ 0.198789] [ C0] <6>DMAR: DRHD: handling fault status reg 3",
+" ...",
+" %s> log -t -P -m",
+" ...",
+" [ T1] <6>Secure boot disabled",
+" [ T29] <6>RAMDISK: [mem 0x3cf4f000-0x437bbfff]",
+" [ C0] <6>DMAR: DRHD: handling fault status reg 3",
+" ...",
+" %s> log -T -P -m",
+" ...",
+" [Tue Dec 12 23:25:03 PST 2023] [ T1] <6>Secure boot disabled",
+" [Tue Dec 12 23:25:03 PST 2023] [ T29] <6>RAMDISK: [mem 0x3cf4f000-0x437bbfff]",
+" [Tue Dec 12 23:25:03 PST 2023] [ C0] <6>DMAR: DRHD: handling fault status reg 3",
+" ...",
+
NULL
};
diff --git a/kernel.c b/kernel.c
index 6dcf414..0475b07 100644
--- a/kernel.c
+++ b/kernel.c
@@ -29,6 +29,9 @@
#endif
#include "bfd.h"
+#define PID_CHARS_MAX 16 /* Max Number of PID characters */
+#define PID_CHARS_DEFAULT 8 /* Default number of PID characters */
+
static void do_module_cmd(ulong, char *, ulong, char *, char *);
static void show_module_taint(void);
static char *find_module_objfile(char *, char *, char *);
@@ -5089,7 +5092,7 @@ cmd_log(void)
msg_flags = 0;
- while ((c = getopt(argcnt, args, "Ttdmas")) != EOF) {
+ while ((c = getopt(argcnt, args, "TtdmasP")) != EOF) {
switch(c)
{
case 'T':
@@ -5110,6 +5113,9 @@ cmd_log(void)
case 's':
msg_flags |= SHOW_LOG_SAFE;
break;
+ case 'P':
+ msg_flags |= SHOW_LOG_CALLER;
+ break;
default:
argerrs++;
break;
@@ -5369,6 +5375,29 @@ dump_log_entry(char *logptr, int msg_flags)
fprintf(fp, "%s", buf);
}
+ /* The PRINTK_CALLER id field was introduced with Linux-5.1 so if
+ * requested, Kernel version >= 5.1 and field exists print caller_id.
+ */
+ if (msg_flags & SHOW_LOG_CALLER &&
+ kt->kernel_version[0] >= 5 &&
+ kt->kernel_version[1] >= 1 &&
+ VALID_MEMBER(log_caller_id)) {
+ const unsigned int cpuid = 0x80000000;
+ char cidbuf[PID_CHARS_MAX];
+ unsigned int pkc;
+ char idtype;
+
+ /* Get id type, isolate id value in pkc for print */
+ pkc = UINT(logptr + OFFSET(log_caller_id));
+ idtype = (pkc & cpuid) ? 'C' : 'T';
+ pkc &= ~cpuid;
+ sprintf(cidbuf, "%c%d", idtype, pkc);
+ sprintf(buf, "[%*s] ", PID_CHARS_DEFAULT, cidbuf);
+
+ ilen += strlen(buf);
+ fprintf(fp, "%s", buf);
+ }
+
level = LOG_LEVEL(level);
if (msg_flags & SHOW_LOG_LEVEL) {
@@ -5424,8 +5453,13 @@ dump_variable_length_record_log(int msg_flags)
* from log to printk_log. See 62e32ac3505a0cab.
*/
log_struct_name = "printk_log";
- } else
+ if (MEMBER_EXISTS("printk_log", "caller_id"))
+ MEMBER_OFFSET_INIT(log_caller_id, "printk_log",
+ "caller_id");
+ } else {
log_struct_name = "log";
+ INVALID_MEMBER(log_caller_id);
+ }
STRUCT_SIZE_INIT(log, log_struct_name);
MEMBER_OFFSET_INIT(log_ts_nsec, log_struct_name, "ts_nsec");
@@ -11132,6 +11166,15 @@ get_log_from_vmcoreinfo(char *file)
vmc->log_dict_len_OFFSET);
free(string);
}
+ /* The caller_id field exists only in printk_log if kernel >= 5.1
+ * and if CONFIG_PRINTK_CALLER was set in the kernel config file*/
+ if ((string = pc->read_vmcoreinfo("OFFSET(printk_log.caller_id"))) {
+ vmc->log_dict_len_OFFSET = dtol(string, RETURN_ON_ERROR, NULL);
+ if (CRASHDEBUG(1))
+ fprintf(fp, "OFFSET(printk_log.caller_id): %ld\n",
+ vmc->log_caller_id_OFFSET);
+ free(string);
+ }
if ((string = pc->read_vmcoreinfo("SIZE(log)"))) {
vmc->log_SIZE = dtol(string, RETURN_ON_ERROR, NULL);
if (CRASHDEBUG(1))
diff --git a/printk.c b/printk.c
index 8658016..d1b3f40 100644
--- a/printk.c
+++ b/printk.c
@@ -9,6 +9,7 @@ struct prb_map {
unsigned long desc_ring_count;
char *descs;
char *infos;
+ unsigned int pid_max_chars;
char *text_data_ring;
unsigned long text_data_ring_size;
@@ -37,6 +38,9 @@ enum desc_state {
#define DESC_ID_MASK (~DESC_FLAGS_MASK)
#define DESC_ID(sv) ((sv) & DESC_ID_MASK)
+#define PID_CHARS_MAX 16 /* Max Number of PID characters */
+#define PID_CHARS_DEFAULT 8 /* Default number of PID characters */
+
/*
* get_desc_state() taken from kernel source:
*
@@ -162,6 +166,27 @@ dump_record(struct prb_map *m, unsigned long id, int msg_flags)
fprintf(fp, "%s", buf);
}
+ /*
+ * The lockless ringbuffer introduced in Linux-5.10 always has
+ * the caller_id field available, so if requested, print it.
+ */
+ if (msg_flags & SHOW_LOG_CALLER) {
+ const unsigned int cpuid = 0x80000000;
+ char cidbuf[PID_CHARS_MAX];
+ unsigned int pkc;
+ char idtype;
+
+ /* Get id type, isolate id value in pkc for print */
+ pkc = UINT(info + OFFSET(printk_info_caller_id));
+ idtype = (pkc & cpuid) ? 'C' : 'T';
+ pkc &= ~cpuid;
+ sprintf(cidbuf, "%c%d", idtype, pkc);
+ sprintf(buf, "[%*s] ", PID_CHARS_DEFAULT, cidbuf);
+
+ ilen += strlen(buf);
+ fprintf(fp, "%s", buf);
+ }
+
if (msg_flags & SHOW_LOG_LEVEL) {
level = UCHAR(info + OFFSET(printk_info_level)) >> 5;
sprintf(buf, "<%x>", level);
@@ -262,6 +287,20 @@ dump_lockless_record_log(int msg_flags)
goto out_text_data;
}
+ /* Get pid_max and fill it in if we need it */
+ if (msg_flags & SHOW_LOG_CALLER) {
+ char pid_chars[PID_CHARS_MAX];
+ size_t pc_size = sizeof(pid_chars);
+ size_t pid_chars_length;
+ unsigned int pid_max;
+
+ get_symbol_data("pid_max", sizeof(pid_max), &pid_max);
+ pid_chars_length = snprintf(pid_chars, pc_size, "%u", &pid_max);
+ m.pid_max_chars = pid_chars_length + 1;
+ } else {
+ m.pid_max_chars = PID_CHARS_DEFAULT;
+ }
+
/* ready to go */
tail_id = ULONG(m.desc_ring + OFFSET(prb_desc_ring_tail_id) +
diff --git a/symbols.c b/symbols.c
index 5d91991..7969409 100644
--- a/symbols.c
+++ b/symbols.c
@@ -11521,6 +11521,8 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(log_level));
fprintf(fp, " log_flags_level: %ld\n",
OFFSET(log_flags_level));
+ fprintf(fp, " log_caller_id: %ld\n",
+ OFFSET(log_caller_id));
fprintf(fp, " printk_info_seq: %ld\n", OFFSET(printk_info_seq));
fprintf(fp, " printk_info_ts_nseq: %ld\n", OFFSET(printk_info_ts_nsec));
--
2.43.0
10 months, 1 week