 
                                        
                                
                         
                        
                                
                                
                                        
                                                
                                        
                                        
                                        [RFC PATCH 00/15] Support module memory layout change on Linux 6.4
                                
                                
                                
                                    
                                        by HAGIO KAZUHITO(萩尾 一仁)
                                    
                                
                                
                                        This patchset supports module memory layout change on Linux 6.4 by
kernel commit [1].  Without the patchset, crash cannot even start a
session with an error message like this:
  crash: invalid structure member offset: module_core_size
         FILE: kernel.c  LINE: 3787  FUNCTION: module_init()
(For the current crash, you can use "crash --no_modules" option without
module functionalities to avoid the failure of startup.)
This patchset is also located at GitHub [2].
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit...
[2] https://github.com/k-hagio/crash/tree/6.4-module.wip2
Probably most of module and symbol functions will work, though maybe 
there might be lack of fixes for some functions and there might be my 
misunderstanding of crash code.  (There are also some functions not 
fixed because crash does not use them for the recent kernels.)
Please let me know if there are any bugs and comments on the design, 
coding style and etc.
* The current patchset is a draft and kind of POC, fixes are piled up 
and no code and performance optimization.  I will rearrange them later. 
* Currently enum mod_mem_type is backported from the kernel as it is, 
because I'm not sure whether it's likely to change soon.
* The new module memory areas are scattered, and managed by the 
following struct load_module members.
struct load_module {
...
         /* For 6.4 module_memory */
         struct module_memory mem[MOD_MEM_NUM_TYPES];
         struct syment **symtable;
         struct syment **symend;
         struct syment *ext_symtable[MOD_MEM_NUM_TYPES];
         struct syment *ext_symend[MOD_MEM_NUM_TYPES];
         struct syment *load_symtable[MOD_MEM_NUM_TYPES];
         struct syment *load_symend[MOD_MEM_NUM_TYPES];
         int address_order[MOD_MEM_NUM_TYPES];
         int nr_mems;
};
* "sym -M" output is ordered by module text start address on a 
per-module basis for now. (how can I say...)  So if you get all of 
module symbols in address order, need to sort them.  But modules will be 
mixed.
crash> sym -M | grep MODULE          # displayed per module
...
ffffffffc046f000 MODULE TEXT START: dm_mirror
ffffffffc0472000 MODULE TEXT END: dm_mirror
ffffffffc0473000 MODULE DATA START: dm_mirror
ffffffffc0475000 MODULE DATA END: dm_mirror
ffffffffc0476000 MODULE RODATA START: dm_mirror
ffffffffc0478000 MODULE RODATA END: dm_mirror
ffffffffc044b000 MODULE RO_AFTER_INIT START: libata  # lower than the 
previous
ffffffffc044c000 MODULE RO_AFTER_INIT END: libata
ffffffffc0479000 MODULE TEXT START: libata
ffffffffc049d000 MODULE TEXT END: libata
ffffffffc049e000 MODULE DATA START: libata
ffffffffc04c8000 MODULE DATA END: libata
...
crash> sym -M | grep MODULE | sort   # displayed in address order
...
ffffffffc0468000 MODULE RODATA START: dm_region_hash
ffffffffc046a000 MODULE RODATA END: dm_region_hash
ffffffffc046b000 MODULE RODATA START: t10_pi
ffffffffc046c000 MODULE RODATA END: t10_pi
ffffffffc046d000 MODULE TEXT START: ghash_clmulni_intel
ffffffffc046e000 MODULE TEXT END: ghash_clmulni_intel
ffffffffc046f000 MODULE TEXT START: dm_mirror
ffffffffc0472000 MODULE TEXT END: dm_mirror
...
Kazuhito Hagio (15):
  Add support for struct module_memory on Linux 6.4 and later
  Support "sym -l|-M|-m" options
  Make "sym -m" option print symbols in address order
  Fix verify_module() and next_module_vaddr()
  Fix {lowest,highest}_modules_address() and is_kernel_text()
  Support "mod -s|-S" options
  Support percpu symbols for "sym" options
  Support "mod -d|-D" options
  Support "sym -n" option
  Support "sym -p" option
  Fix module_symbol() and is_kernel_text()
  Remove unused find_mod_etext() in store_module_symbols_v3()
  Fix get_section, check_for_dups, symbol_query, symbol_name_count
  Fix symbol_search_next, symbol_complete_match and get_syment_array
  mod: Change "BASE" on header to "TEXT_BASE" to clarify
 defs.h         |   45 ++
 gdb-10.2.patch |   16 +
 kernel.c       |   47 +-
 memory.c       |   36 +-
 symbols.c      | 1571 +++++++++++++++++++++++++++++++++++++++++++++---
 5 files changed, 1616 insertions(+), 99 deletions(-)
-- 
2.31.1
                                
                         
                        
                                
                                2 years, 4 months
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                                
                                 
                                        
                                
                         
                        
                                
                                
                                        
                                                
                                        
                                        
                                        [Question] crash-arm64 cannot determine VA_BITS_ACTUAL for qemu dump-guest-memory
                                
                                
                                
                                    
                                        by Qiwu.Chen
                                    
                                
                                
                                        Dear Mantainers,
I meet a problem that the latest crash tool built for ARM64 cannot load the vmcore genarated by Qemu ARM64 guest OS. 
1) The vmcore captured by "dump-guest-memory" cmd in qemu monitor mode:
(qemu)  dump-guest-memory vmcore
$ file vmcore
vmcore: ELF 64-bit LSB core file, ARM aarch64, version 1 (SYSV), SVR4-style
My host OS installed qemu-system-aarch64 version is 6.2.0
$ qemu-system-aarch64 --version
QEMU emulator version 6.2.0
2) The test for linux version both 5.0 and 5.15 which disable kaslr is NG, but test linux version 4.0 loading vmcore is OK.
Here's the error log while crash tool loading linux-5.15 vmcore:
$ crash64 vmlinux vmcore
crash64 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.
crash64: cannot determine VA_BITS_ACTUAL
3) It seems crash tool cannot get vabits_actual from vmcore, so I append "vabits_actual=48" to crash cmd:
$ crash-arm64 vmlinux vmcore -m vabits_actual=48
The result shows some symbols seek error:
crash-arm64: seek error: kernel virtual address: ffff800011769918  type: "possible"WARNING: cannot read cpu_possible_map
crash-arm64: seek error: kernel virtual address: ffff800011769958  type: "present"
WARNING: cannot read cpu_present_map
crash-arm64: seek error: kernel virtual address: ffff800011769938  type: "online"
WARNING: cannot read cpu_online_map
crash-arm64: seek error: kernel virtual address: ffff800011769978  type: "active"
WARNING: cannot read cpu_active_map
crash-arm64: seek error: kernel virtual address: ffff800011936390  type: "shadow_timekeeper xtime_sec"
xtime timespec.tv_sec: 55fcd060743a: Thu Feb 11 04:14:50 CST 2997960
crash-arm64: seek error: kernel virtual address: ffff800011771268  type: "init_uts_ns"
The attachment is the detailed log which append "-d 1" to crash cmd.
Could you please help this?
Thanks
                                
                         
                        
                                
                                2 years, 5 months
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                                
                                 
                                        
                                
                         
                        
                                
                                
                                        
                                                
                                        
                                        
                                        [PATCH v2] Output prompt when stdin is not a TTY.
                                
                                
                                
                                    
                                        by Hsin-Yi Wang
                                    
                                
                                
                                        When stdin is not a TTY, prompt ("crash> ") won't be displayed. If
another process interact with crash with piped stdin/stdout, it will not
get the prompt as a delimiter.
Compared to other debugger like gdb, crash seems intended to give a
prompt in this case in the beginning of process_command_line(). It
checks if pc->flags does NOT have any of
READLINE|SILENT|CMDLINE_IFILE|RCHOME_IFILE|RCLOCAL_IFILE, a
prompt should be printed. The check will never be true since READLINE is
set in setup_environment() unconditionally.
It makes more sense to change the READLINE flag in the check to TTY
instead. Besides this change, the prompt in process_command_line() should
only be print when it's not in the middle of processing the input file
recovering from a previous FATAL command, because the prompt will be
displayed by the exec_input_file().
Additionally, when stdin is not TTY, repeat the command line from user
after prompt, which can give more context.
The prompt and command line can be opt out by using the silent (-s) flag.
Signed-off-by: Hsin-Yi Wang <hsinyi(a)chromium.org>
---
v1: https://listman.redhat.com/archives/crash-utility/2023-May/010740.html
v1->v2:
1. remove additional prompt when recovering from FATAL command from
file.
2. fix a few space/tab indent.
---
 cmdline.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/cmdline.c b/cmdline.c
index ded6551..b7f919a 100644
--- a/cmdline.c
+++ b/cmdline.c
@@ -64,8 +64,8 @@ process_command_line(void)
 	fp = stdout;
 	BZERO(pc->command_line, BUFSIZE);
 
-	if (!(pc->flags & 
-	    (READLINE|SILENT|CMDLINE_IFILE|RCHOME_IFILE|RCLOCAL_IFILE))) 
+	if (!pc->ifile_in_progress && !(pc->flags &
+	    (TTY|SILENT|CMDLINE_IFILE|RCHOME_IFILE|RCLOCAL_IFILE)))
 		fprintf(fp, "%s", pc->prompt);
 	fflush(fp);
 
@@ -136,12 +136,16 @@ process_command_line(void)
 			add_history(pc->command_line);
 		
 		check_special_handling(pc->command_line);
-        } else {
-        	if (fgets(pc->command_line, BUFSIZE-1, stdin) == NULL)
+	} else {
+		if (fgets(pc->command_line, BUFSIZE-1, stdin) == NULL)
 			clean_exit(1);
+		if (!(pc->flags & SILENT)) {
+			fprintf(fp, "%s", pc->command_line);
+			fflush(fp);
+		}
 		clean_line(pc->command_line);
 		strcpy(pc->orig_line, pc->command_line);
-        }
+	}
 
 	/*
 	 *  First clean out all linefeeds and leading/trailing spaces.
-- 
2.41.0.rc0.172.g3f132b7071-goog
                                
                         
                        
                                
                                2 years, 5 months
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                                
                                 
                                        
                                
                         
                        
                                
                                
                                        
                                                
                                        
                                        
                                        [Question]  page excluded: kernel virtual address
                                
                                
                                
                                    
                                        by Qiwu.Chen
                                    
                                
                                
                                        Dear Mantainers,
I find there is an inevitable problem for linux-5.x ARM64 kdump that the error "page excluded: kernel virtual address: xxx" will be occured when read the address of ext4_super_block for ext4 filesystem in latest crash utility debugging enviroment.
1) Here's my reproduce steps:
crash64> mount
     MOUNT           SUPERBLK     TYPE   DEVNAME   DIRNAME
ffff000001e65180 ffff000001c1c000 rootfs none      /
ffff00002ea66000 ffff00000288e000 ext4   /dev/root /
crash64> struct super_block.s_fs_info -x ffff00000288e000  s_fs_info = 0xffff000002885000,
crash64> struct ext4_sb_info.s_es -x 0xffff000002885000
  s_es = 0xffff0000043c2400,
crash64> struct ext4_sb_info.s_es -x 0xffff0000043c2400
struct: page excluded: kernel virtual address: ffff0000043c2400  type: "gdb_readmem_callback"
crash64> rd 0xffff0000043c2400rd: page excluded: kernel virtual address: ffff0000043c2400  type: "64-bit KVADDR"
crash64> kmem -p 0xffff0000043c2400      PAGE       PHYSICAL      MAPPING       INDEX CNT FLAGS
fffffc000010f080 443c2000 ffff000002f93af0        0  2 ffff00000022036 referenced,uptodate,lru,active,private,mappedtodisk
crash64> vtop 0xffff0000043c2400
VIRTUAL           PHYSICAL
ffff0000043c2400  443c2400
PAGE DIRECTORY: ffff80001163b000
   PGD: ffff80001163b000 => 180000007fff9803
   PUD: ffff00003fff9000 => 180000007fff8803
   PMD: ffff00003fff8108 => 180000007ffe0803
   PTE: ffff00003ffe0e10 => 680000443c2f07
  PAGE: 443c2000
     PTE        PHYSICAL  FLAGS
680000443c2f07  443c2000  (VALID|SHARED|AF|NG|PXN|UXN)
      PAGE       PHYSICAL      MAPPING       INDEX CNT FLAGS
fffffc000010f080 443c2000 ffff000002f93af0        0  2 ffff00000022036 referenced,uptodate,lru,active,private,mappedtodisk
2) Here's the kernel virtual kernel memory layout for my tested arm64 kernel version 5.15, we can see 0xffff0000043c2400 is in the kernel linear memory region :
[    0.000000] Virtual kernel memory layout:[    0.000000]     modules : 0xffff800008000000 - 0xffff800010000000   (   128 MB)
[    0.000000]     vmalloc : 0xffff800010000000 - 0xfffffbfff0000000   (126975 GB)
[    0.000000]       .text : 0xffff800010000000 - 0xffff8000111a0000   ( 18048 KB)
[    0.000000]       .init : 0xffff800011640000 - 0xffff800011760000   (  1152 KB)
[    0.000000]     .rodata : 0xffff8000111a0000 - 0xffff800011636000   (  4696 KB)
[    0.000000]       .data : 0xffff800011760000 - 0xffff800011902200   (  1673 KB)
[    0.000000]        .bss : 0xffff800011902200 - 0xffff8000119c6fb0   (   788 KB)
[    0.000000]     fixed   : 0xfffffbfffdbf9000 - 0xfffffbfffe000000   (  4124 KB)
[    0.000000]     PCI I/O : 0xfffffbfffe800000 - 0xfffffbffff800000   (    16 MB)
[    0.000000]     vmemmap : 0xfffffc0000000000 - 0xfffffe0000000000   (  2048 GB maximum)
[    0.000000]               0xfffffc0000000000 - 0xfffffc0001000000   (    16 MB actual)
[    0.000000]     memory  : 0xffff000000000000 - 0xffff000040000000   (  1024 MB)
[    0.000000]     PAGE_OFFSET  : 0xffff000000000000
[    0.000000]     KIMAGE_VADDR  : 0xffff800010000000
[    0.000000]     kimage_voffset : 0xffff7fffcfe00000
[    0.000000]     PHYS_OFFSET  : 0x40000000
[    0.000000]     start memory  : 0x40000000
I have no idea whether this problem is something wrong with crash utility. Could anybody please help this?
Thanks
                                
                         
                        
                                
                                2 years, 5 months
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                                
                                 
                                        
                                
                         
                        
                                
                                
                                        
                                                
                                        
                                        
                                        [PATCH] Output prompt when stdin is not a TTY.
                                
                                
                                
                                    
                                        by Hsin-Yi Wang
                                    
                                
                                
                                        When stdin is not a TTY, prompt ("crash> ") won't be displayed. If
another process interact with crash with piped stdin/stdout, it will not
get the prompt as a delimiter.
Compared to other debugger like gdb, crash seems intended to give a
prompt in this case in the beginning of process_command_line(). It
checks if pc->flags does NOT have any of
READLINE|SILENT|CMDLINE_IFILE|RCHOME_IFILE|RCLOCAL_IFILE, a
prompt should be printed. The check will never be true since READLINE is
set in setup_environment() unconditionally. It makes more sense to
change the READLINE flag in the check to TTY instead.
Additionally, when stdin is not TTY, repeat the command line from user
after prompt, which can give more context.
The prompt and command line can be opt out by using the silent (-s) flag.
Signed-off-by: Hsin-Yi Wang <hsinyi(a)chromium.org>
---
v1:
- The original discussion: https://listman.redhat.com/archives/crash-utility/2023-May/010710.html
- Kazu: provide the idea to print the command line as well.
---
 cmdline.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/cmdline.c b/cmdline.c
index ded6551..9821d86 100644
--- a/cmdline.c
+++ b/cmdline.c
@@ -65,7 +65,7 @@ process_command_line(void)
 	BZERO(pc->command_line, BUFSIZE);
 
 	if (!(pc->flags & 
-	    (READLINE|SILENT|CMDLINE_IFILE|RCHOME_IFILE|RCLOCAL_IFILE))) 
+	    (TTY|SILENT|CMDLINE_IFILE|RCHOME_IFILE|RCLOCAL_IFILE)))
 		fprintf(fp, "%s", pc->prompt);
 	fflush(fp);
 
@@ -139,6 +139,10 @@ process_command_line(void)
         } else {
         	if (fgets(pc->command_line, BUFSIZE-1, stdin) == NULL)
 			clean_exit(1);
+		if (!(pc->flags & SILENT)) {
+			fprintf(fp, "%s", pc->command_line);
+			fflush(fp);
+		}
 		clean_line(pc->command_line);
 		strcpy(pc->orig_line, pc->command_line);
         }
-- 
2.41.0.rc0.172.g3f132b7071-goog
                                
                         
                        
                                
                                2 years, 5 months
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                                
                                 
                                        
                                
                         
                        
                                
                                
                                        
                                                
                                        
                                        
                                        Question on prompt behavior
                                
                                
                                
                                    
                                        by Hsin-Yi Wang
                                    
                                
                                
                                        hi crash-utility community,
When stdin is not a TTY, but all the other flags remain the same,
prompt ("crash> ") won't be displayed. An example use case is, the
stdin of crash is replaced by a piped fd connected to another process.
In process_command_line(), it checks if pc->flags does NOT have any of
the flag: READLINE|SILENT|CMDLINE_IFILE|RCHOME_IFILE|RCLOCAL_IFILE, a
prompt should be printed.
But in setup_environment(), pc->flags is set to have READLINE flag[2],
the above check will not be true at all.
Should READLINE be set for all cases in setup_environment()?
- If true, should the check in process_command_line() look for TTY
instead of READLINE? Since if pc->flags has TTY, [2] won't be true and
the prompt will be printed later in TTY's case[3].
- If false, where should be a proper place and conditions to set READLINE?
Or is the current behavior intended? I may not fully understand the
design logic. Any explanations are appreciated.
Thanks!
[1] https://github.com/crash-utility/crash/blob/05a3a328fcd8920e49926b6d1c9c8...
[2] https://github.com/crash-utility/crash/blob/8246dce99dd23457e8c7a3fe9609c...
[3] https://github.com/crash-utility/crash/blob/05a3a328fcd8920e49926b6d1c9c8...
                                
                         
                        
                                
                                2 years, 5 months
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                                
                                 
                                        
                                
                         
                        
                                
                                
                                        
                                                
                                        
                                        
                                        [PATCH 1/2] diskdump/netdump: fix segmentation fault caused by failure of stopping CPUs
                                
                                
                                
                                    
                                        by HATAYAMA Daisuke
                                    
                                
                                
                                        There's no NMI on ARM. Hence, stopping the non-panicking CPUs from the
panicking CPU via IPI can fail easily if interrupts are being masked
in those moment. Moreover, crash_notes are not initialized for such
unstopped CPUs and the corresponding NT_PRSTATUS notes are not
attached to vmcore. However, crash utility never takes it
consideration such uninitialized crash_notes and then ends with
mapping different NT_PRSTATUS to actually unstopped CPUs. This corrupt
mapping can result crash utility into segmentation fault in the
operations where register values in NT_PRSTATUS notes are used.
For example:
    crash> bt 1408
	PID: 1408     TASK: ffff000003e22200  CPU: 2    COMMAND: "repro"
	Segmentation fault (core dumped)
	crash> help -D
	diskdump_data:
			  filename: 127.0.0.1-2023-05-26-02:21:27/vmcore-ld1
				 flags: 46 (KDUMP_CMPRS_LOCAL|ERROR_EXCLUDED|LZO_SUPPORTED)
	...snip...
			   notes_buf: 1815df0
	  num_vmcoredd_notes: 0
	  num_prstatus_notes: 5
				notes[0]: 1815df0 (NT_PRSTATUS)
						  si.signo: 0  si.code: 0  si.errno: 0
	...snip...
						  PSTATE: 80400005   FPVALID: 00000000
				notes[4]: 1808f10 (NT_PRSTATUS)
	Segmentation fault (core dumped)
To fix this issue, let's map NT_PRSTATUS to some CPU only if the
corresponding crash_notes is checked to be initialized.
Signed-off-by: HATAYAMA Daisuke <d.hatayama(a)fujitsu.com>
---
 defs.h     |  1 +
 diskdump.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 netdump.c  |  5 ++++-
 3 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/defs.h b/defs.h
index 12ad6aa..72129a1 100644
--- a/defs.h
+++ b/defs.h
@@ -7111,6 +7111,7 @@ int dumpfile_is_split(void);
 void show_split_dumpfiles(void);
 void x86_process_elf_notes(void *, unsigned long);
 void *diskdump_get_prstatus_percpu(int);
+int have_crash_notes(int cpu);
 void map_cpus_to_prstatus_kdump_cmprs(void);
 void diskdump_display_regs(int, FILE *);
 void process_elf32_notes(void *, ulong);
diff --git a/diskdump.c b/diskdump.c
index cf5f5d9..11d29d3 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -101,6 +101,55 @@ int dumpfile_is_split(void)
 	return KDUMP_SPLIT();
 }
 
+int have_crash_notes(int cpu)
+{
+	ulong crash_notes, notes_ptr;
+	char *buf, *p;
+	Elf64_Nhdr *note = NULL;
+
+	if (!readmem(symbol_value("crash_notes"),
+		     KVADDR,
+		     &crash_notes,
+		     sizeof(crash_notes),
+		     "crash_notes",
+		     RETURN_ON_ERROR)) {
+		error(WARNING, "cannot read \"crash_notes\"\n");
+		return FALSE;
+	}
+
+	if (symbol_exists("__per_cpu_offset"))
+		notes_ptr = crash_notes + kt->__per_cpu_offset[cpu];
+	else
+		notes_ptr = crash_notes;
+
+	buf = GETBUF(SIZE(note_buf));
+
+	if (!readmem(notes_ptr,
+		     KVADDR,
+		     buf,
+		     SIZE(note_buf),
+		     "note_buf_t",
+		     RETURN_ON_ERROR)) {
+		error(WARNING, "cpu %d: cannot read NT_PRSTATUS note\n", cpu);
+		return FALSE;
+	}
+
+	note = (Elf64_Nhdr *)buf;
+	p = buf + sizeof(Elf64_Nhdr);
+
+	if (note->n_type != NT_PRSTATUS) {
+		error(WARNING, "cpu %d: invalid NT_PRSTATUS note (n_type != NT_PRSTATUS)\n", cpu);
+		return FALSE;
+	}
+
+	if (!STRNEQ(p, "CORE")) {
+		error(WARNING, "cpu %d: invalid NT_PRSTATUS note (name != \"CORE\")\n", cpu);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
 void
 map_cpus_to_prstatus_kdump_cmprs(void)
 {
@@ -131,7 +180,7 @@ map_cpus_to_prstatus_kdump_cmprs(void)
 	nrcpus = (kt->kernel_NR_CPUS ? kt->kernel_NR_CPUS : NR_CPUS);
 
 	for (i = 0, j = 0; i < nrcpus; i++) {
-		if (in_cpu_map(ONLINE_MAP, i)) {
+		if (in_cpu_map(ONLINE_MAP, i) && have_crash_notes(i)) {
 			dd->nt_prstatus_percpu[i] = nt_ptr[j++];
 			dd->num_prstatus_notes = 
 				MAX(dd->num_prstatus_notes, i+1);
diff --git a/netdump.c b/netdump.c
index 01af145..b272984 100644
--- a/netdump.c
+++ b/netdump.c
@@ -99,8 +99,11 @@ map_cpus_to_prstatus(void)
 	nrcpus = (kt->kernel_NR_CPUS ? kt->kernel_NR_CPUS : NR_CPUS);
 
 	for (i = 0, j = 0; i < nrcpus; i++) {
-		if (in_cpu_map(ONLINE_MAP, i))
+		if (in_cpu_map(ONLINE_MAP, i) && have_crash_notes(i)) {
 			nd->nt_prstatus_percpu[i] = nt_ptr[j++];
+			nd->num_prstatus_notes =
+				MAX(nd->num_prstatus_notes, i+1);
+		}
 	}
 
 	FREEBUF(nt_ptr);
-- 
2.25.1
                                
                         
                        
                                
                                2 years, 5 months
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                                
                                 
                                        
                                
                         
                        
                                
                                
                                        
                                                
                                        
                                        
                                        [PATCH RFC] arm64: show zero pfn information when using vtop
                                
                                
                                
                                    
                                        by Rongwei Wang
                                    
                                
                                
                                        Now vtop can not show us the page is zero pfn
when PTE or PMD has attached ZERO PAGE. This
patch supports show this information directly
when using vtop, likes:
crash> vtop -c 13674 ffff8917e000
VIRTUAL     PHYSICAL
ffff8917e000  836e71000
PAGE DIRECTORY: ffff000802f8d000
   PGD: ffff000802f8dff8 => 884e29003
   PUD: ffff000844e29ff0 => 884e93003
   PMD: ffff000844e93240 => 840413003
   PTE: ffff000800413bf0 => 160000836e71fc3
  PAGE: 836e71000  (ZERO PAGE)
      PTE        PHYSICAL   FLAGS
160000836e71fc3  836e71000  (VALID|USER|RDONLY|SHARED|AF|NG|PXN|UXN|SPECIAL)
      VMA           START       END     FLAGS FILE
ffff000844f51860 ffff8917c000 ffff8957d000 100073
      PAGE         PHYSICAL      MAPPING       INDEX CNT FLAGS
fffffe001fbb9c40  836e71000                0        0  1 2ffffc000001000 reserved
If huge page found:
crash> vtop -c 14538 ffff95800000
VIRTUAL     PHYSICAL
ffff95800000  910c00000
PAGE DIRECTORY: ffff000801fa0000
   PGD: ffff000801fa0ff8 => 884f53003
   PUD: ffff000844f53ff0 => 8426cb003
   PMD: ffff0008026cb560 => 60000910c00fc1
  PAGE: 910c00000  (2MB, ZERO PAGE)
     PTE        PHYSICAL   FLAGS
60000910c00fc1  910c00000  (VALID|USER|RDONLY|SHARED|AF|NG|PXN|UXN)
      VMA           START       END     FLAGS FILE
ffff0000caa711e0 ffff956a9000 ffff95aaa000 100073
      PAGE         PHYSICAL      MAPPING       INDEX CNT FLAGS
fffffe0023230000  910c00000                0        0  1 6ffffc000010000 head
That seems be sensible with this patch.
Signed-off-by: Rongwei Wang <rongwei.wang(a)linux.alibaba.com>
---
 arm64.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 defs.h  |  5 ++++
 2 files changed, 88 insertions(+), 9 deletions(-)
diff --git a/arm64.c b/arm64.c
index 56fb841..264572d 100644
--- a/arm64.c
+++ b/arm64.c
@@ -419,7 +419,25 @@ arm64_init(int when)
 		/* use machdep parameters */
 		arm64_calc_phys_offset();
 		arm64_calc_physvirt_offset();
-	
+
+		if (kernel_symbol_exists("zero_pfn")) {
+				ulong zero_pfn = 0;
+
+				if (readmem(symbol_value("zero_pfn"), KVADDR,
+					      &zero_pfn, sizeof(zero_pfn),
+					      "read zero_pfn", QUIET|RETURN_ON_ERROR))
+					machdep->zero_pfn = zero_pfn;
+		}
+
+		if (kernel_symbol_exists("huge_zero_pfn")) {
+				ulong huge_zero_pfn = 0;
+
+				if (readmem(symbol_value("huge_zero_pfn"), KVADDR,
+					      &huge_zero_pfn, sizeof(huge_zero_pfn),
+					      "read huge_zero_pfn", QUIET|RETURN_ON_ERROR))
+					machdep->huge_zero_pfn = huge_zero_pfn;
+		}
+
 		if (CRASHDEBUG(1)) {
 			if (machdep->flags & NEW_VMEMMAP)
 				fprintf(fp, "kimage_voffset: %lx\n", 
@@ -1787,7 +1805,14 @@ arm64_vtop_2level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	if ((pgd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
 		ulong sectionbase = (pgd_val & SECTION_PAGE_MASK_512MB) & PHYS_MASK;
 		if (verbose) {
-			fprintf(fp, "  PAGE: %lx  (512MB)\n\n", sectionbase);
+			if (kernel_symbol_exists("huge_zero_pfn")) {
+				if (sectionbase == (HUGE_ZEROPFN() << PAGESHIFT()))
+					fprintf(fp, "  PAGE: %lx  (512MB, ZERO PAGE)\n\n",
+						HUGE_ZEROPFN() << PAGESHIFT());
+				else
+					fprintf(fp, "  PAGE: %lx  (512MB)\n\n", sectionbase);
+			} else
+				fprintf(fp, "  PAGE: %lx  (512MB)\n\n", sectionbase);
 			arm64_translate_pte(pgd_val, 0, 0);
 		}
 		*paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_512MB);
@@ -1806,7 +1831,14 @@ arm64_vtop_2level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	if (pte_val & PTE_VALID) {
 		*paddr = (PAGEBASE(pte_val) & PHYS_MASK) + PAGEOFFSET(vaddr);
 		if (verbose) {
-			fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
+			if (kernel_symbol_exists("zero_pfn")) {
+				if (PAGEBASE(*paddr) == (ZEROPFN() << PAGESHIFT()))
+					fprintf(fp, "  PAGE: %lx  (ZERO PAGE)\n\n",
+						ZEROPFN() << PAGESHIFT());
+				else
+					fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
+			} else
+				fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
 			arm64_translate_pte(pte_val, 0, 0);
 		}
 	} else {
@@ -1859,7 +1891,14 @@ arm64_vtop_3level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	if ((pmd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
 		ulong sectionbase = PTE_TO_PHYS(pmd_val) & SECTION_PAGE_MASK_512MB;
 		if (verbose) {
-			fprintf(fp, "  PAGE: %lx  (512MB)\n\n", sectionbase);
+			if (kernel_symbol_exists("huge_zero_pfn")) {
+				if (sectionbase == (HUGE_ZEROPFN() << PAGESHIFT()))
+					fprintf(fp, "  PAGE: %lx  (512MB, ZERO PAGE)\n\n",
+						HUGE_ZEROPFN() << PAGESHIFT());
+				else
+					fprintf(fp, "  PAGE: %lx  (512MB)\n\n", sectionbase);
+			} else
+				fprintf(fp, "  PAGE: %lx  (512MB)\n\n", sectionbase);
 			arm64_translate_pte(pmd_val, 0, 0);
 		}
 		*paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_512MB);
@@ -1878,7 +1917,14 @@ arm64_vtop_3level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	if (pte_val & PTE_VALID) {
 		*paddr = PTE_TO_PHYS(pte_val) + PAGEOFFSET(vaddr);
 		if (verbose) {
-			fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
+			if (kernel_symbol_exists("zero_pfn")) {
+				if (PAGEBASE(*paddr) == (ZEROPFN() << PAGESHIFT()))
+					fprintf(fp, "  PAGE: %lx  (ZERO PAGE)\n\n",
+						ZEROPFN() << PAGESHIFT());
+				else
+					fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
+			} else
+				fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
 			arm64_translate_pte(pte_val, 0, 0);
 		}
 	} else {
@@ -1940,7 +1986,14 @@ arm64_vtop_3level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	if ((pmd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
 		ulong sectionbase = (pmd_val & SECTION_PAGE_MASK_2MB) & PHYS_MASK;
 		if (verbose) {
-			fprintf(fp, "  PAGE: %lx  (2MB)\n\n", sectionbase);
+			if (kernel_symbol_exists("huge_zero_pfn")) {
+				if (sectionbase == (HUGE_ZEROPFN() << PAGESHIFT()))
+					fprintf(fp, "  PAGE: %lx  (2MB, ZERO PAGE)\n\n",
+						HUGE_ZEROPFN() << PAGESHIFT());
+				else
+					fprintf(fp, "  PAGE: %lx  (2MB)\n\n", sectionbase);
+			} else
+				fprintf(fp, "  PAGE: %lx  (2MB)\n\n", sectionbase);
 			arm64_translate_pte(pmd_val, 0, 0);
 		}
 		*paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_2MB);
@@ -1959,7 +2012,14 @@ arm64_vtop_3level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	if (pte_val & PTE_VALID) {
 		*paddr = (PAGEBASE(pte_val) & PHYS_MASK) + PAGEOFFSET(vaddr);
 		if (verbose) {
-			fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
+			if (kernel_symbol_exists("zero_pfn")) {
+				if (PAGEBASE(*paddr) == (ZEROPFN() << PAGESHIFT()))
+					fprintf(fp, "  PAGE: %lx  (ZERO PAGE)\n\n",
+						ZEROPFN() << PAGESHIFT());
+				else
+					fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
+			} else
+				fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
 			arm64_translate_pte(pte_val, 0, 0);
 		}
 	} else {
@@ -2029,7 +2089,14 @@ arm64_vtop_4level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	if ((pmd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
 		ulong sectionbase = (pmd_val & SECTION_PAGE_MASK_2MB) & PHYS_MASK;
 		if (verbose) {
-			fprintf(fp, "  PAGE: %lx  (2MB)\n\n", sectionbase);
+			if (kernel_symbol_exists("huge_zero_pfn")) {
+				if (sectionbase == (HUGE_ZEROPFN() << PAGESHIFT()))
+					fprintf(fp, "  PAGE: %lx  (2MB, ZERO PAGE)\n\n",
+						HUGE_ZEROPFN() << PAGESHIFT());
+				else
+					fprintf(fp, "  PAGE: %lx  (2MB)\n\n", sectionbase);
+			} else
+				fprintf(fp, "  PAGE: %lx  (2MB)\n\n", sectionbase);
 			arm64_translate_pte(pmd_val, 0, 0);
 		}
 		*paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_2MB);
@@ -2048,7 +2115,14 @@ arm64_vtop_4level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	if (pte_val & PTE_VALID) {
 		*paddr = (PAGEBASE(pte_val) & PHYS_MASK) + PAGEOFFSET(vaddr);
 		if (verbose) {
-			fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
+			if (kernel_symbol_exists("zero_pfn")) {
+				if (PAGEBASE(*paddr) == (ZEROPFN() << PAGESHIFT()))
+					fprintf(fp, "  PAGE: %lx  (ZERO PAGE)\n\n",
+						ZEROPFN() << PAGESHIFT());
+				else
+					fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
+			} else
+				fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
 			arm64_translate_pte(pte_val, 0, 0);
 		}
 	} else {
diff --git a/defs.h b/defs.h
index 12ad6aa..4ed2d0a 100644
--- a/defs.h
+++ b/defs.h
@@ -1071,6 +1071,8 @@ struct machdep_table {
         void (*show_interrupts)(int, ulong *);
 	int (*is_page_ptr)(ulong, physaddr_t *);
 	int (*get_cpu_reg)(int, int, const char *, int, void *);
+	ulong zero_pfn;
+	ulong huge_zero_pfn;
 };
 
 /*
@@ -2999,6 +3001,9 @@ struct load_module {
 #define VIRTPAGEBASE(X)  (((ulong)(X)) & (ulong)machdep->pagemask)
 #define PHYSPAGEBASE(X)  (((physaddr_t)(X)) & (physaddr_t)machdep->pagemask)
 
+#define ZEROPFN()    (machdep->zero_pfn)
+#define HUGE_ZEROPFN()   (machdep->huge_zero_pfn)
+
 /* 
  * Sparse memory stuff
  *  These must follow the definitions in the kernel mmzone.h
-- 
2.27.0
                                
                         
                        
                                
                                2 years, 5 months
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                                
                                 
                                        
                                
                         
                        
                                
                                
                                        
                                                
                                        
                                        
                                        Re: [Crash-utility] [PATCH v3] arm64/x86_64: show zero pfn information when using vtop
                                
                                
                                
                                    
                                        by lijiang
                                    
                                
                                
                                        Hi, Rongwei
Thank you for the patch.
On Tue, May 16, 2023 at 8:00 PM <crash-utility-request(a)redhat.com> wrote:
> Date: Tue, 16 May 2023 19:40:54 +0800
> From: Rongwei Wang <rongwei.wang(a)linux.alibaba.com>
> To: crash-utility(a)redhat.com,   k-hagio-ab(a)nec.com
> Subject: [Crash-utility] [PATCH v3] arm64/x86_64: show zero pfn
>         information when using vtop
> Message-ID: <20230516114054.63844-1-rongwei.wang(a)linux.alibaba.com>
> Content-Type: text/plain; charset="US-ASCII"; x-default=true
>
> Now vtop can not show us the page is zero pfn
> when PTE or PMD has attached ZERO PAGE. This
> patch supports show this information directly
> when using vtop, likes:
>
> crash> vtop -c 13674 ffff8917e000
> VIRTUAL     PHYSICAL
> ffff8917e000  836e71000
>
> PAGE DIRECTORY: ffff000802f8d000
>    PGD: ffff000802f8dff8 => 884e29003
>    PUD: ffff000844e29ff0 => 884e93003
>    PMD: ffff000844e93240 => 840413003
>    PTE: ffff000800413bf0 => 160000836e71fc3
>   PAGE: 836e71000  (ZERO PAGE)
> ...
>
> If huge page found:
>
> crash> vtop -c 14538 ffff95800000
> VIRTUAL     PHYSICAL
> ffff95800000  910c00000
>
> PAGE DIRECTORY: ffff000801fa0000
>    PGD: ffff000801fa0ff8 => 884f53003
>    PUD: ffff000844f53ff0 => 8426cb003
>    PMD: ffff0008026cb560 => 60000910c00fc1
>   PAGE: 910c00000  (2MB, ZERO PAGE)
> ...
>
>
I did some tests on x86 64 and aarch64 machines, and got the following
results.
[1] on x86 64, it does not print the "ZERO PAGE" when using 1G huge pages.
(but for 2M huge page, it works)
crash> vtop -c 2763 7fdfc0000000
VIRTUAL     PHYSICAL
7fdfc0000000  300000000
   PGD: 23b9ae7f8 => 8000000235031067
   PUD: 235031bf8 => 80000003000008e7
  PAGE: 300000000  (1GB)
      PTE         PHYSICAL   FLAGS
80000003000008e7  300000000  (PRESENT|RW|USER|ACCESSED|DIRTY|PSE|NX)
      VMA           START       END     FLAGS FILE
ffff9d65fc8a85c0 7fdfc0000000 7fe000000000 84400fb /mnt/hugetlbfs/test
      PAGE        PHYSICAL      MAPPING       INDEX CNT FLAGS
ffffef30cc000000 300000000 ffff9d65f5c35850        0  2 57ffffc001000c
uptodate,dirty,head
crash> help -v|grep zero
         zero_paddr: 221a37000
    huge_zero_paddr: 240000000
[2] on aarch64, it does not print the "ZERO PAGE"
crash> vtop -c 23390 ffff8d600000
VIRTUAL     PHYSICAL
ffff8d600000  cc800000
PAGE DIRECTORY: ffff224ba02d9000
   PGD: ffff224ba02d9ff8 => 80000017b38f003
   PUD: ffff224b7b38fff0 => 80000017b38e003
   PMD: ffff224b7b38e358 => e80000cc800f41
  PAGE: cc800000  (2MB)
     PTE        PHYSICAL  FLAGS
e80000cc800f41  cc800000  (VALID|USER|SHARED|AF|NG|PXN|UXN|DIRTY)
      VMA           START       END     FLAGS FILE
ffff224bb315f678 ffff8d600000 ffff8d800000 4400fb /mnt/hugetlbfs/test
      PAGE        PHYSICAL      MAPPING       INDEX CNT FLAGS
fffffc892b320000  cc800000 ffff224b5c48ac90        0  2 7ffff80001000c
uptodate,dirty,head
crash> help -v|grep zero
         zero_paddr: 142662000
    huge_zero_paddr: 111400000
I have one question:  can this patch print "ZERO PAGE" on x86 64 when using
1G huge pages? Or is it expected behavior on x86 64?
And It does not work on aarch64 machine to me. Did I miss anything else?
Thanks
Lianbo
                                
                         
                        
                                
                                2 years, 5 months
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                                
                                 
                                        
                                
                         
                        
                                
                                
                                        
                                                
                                        
                                        
                                        [PATCH] Fix "kmem -v" option displaying no regions on Linux 6.3 and later
                                
                                
                                
                                    
                                        by HAGIO KAZUHITO(萩尾 一仁)
                                    
                                
                                
                                        Kernel commit 869176a09606 ("mm/vmalloc.c: add flags to mark vm_map_ram
area"), which is contained in Linux 6.3 and later, added "flags" member
to struct vmap_area.  This was the revival of the "flags" member as
kernel commit 688fcbfc06e4 had eliminated it before.
As a result, crash started to use the old procedure using the member and
displays no vmalloc'd regions, because it does not have the same flag
value as the old one.
    crash> kmem -v
       VMAP_AREA         VM_STRUCT                 ADDRESS RANGE                SIZE
    crash> 
To fix this, also check if vmap_area.purge_list exists, which was
introduced with the flags and removed later, to determine that the flags
member is the old one.
Related vmap_area history:
 v2.6.28 db64fe02258f introduced vmap_area with flags and purge_list
 v5.4    688fcbfc06e4 removed flags
 v5.11   96e2db456135 removed purge_list
 v6.3    869176a09606 added flags again
Signed-off-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
---
 defs.h    | 1 +
 memory.c  | 4 +++-
 symbols.c | 1 +
 3 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/defs.h b/defs.h
index 21cc760444d1..bfa07c3f5150 100644
--- a/defs.h
+++ b/defs.h
@@ -2216,6 +2216,7 @@ struct offset_table {                    /* stash of commonly-used offsets */
 	long in6_addr_in6_u;
 	long kset_kobj;
 	long subsys_private_subsys;
+	long vmap_area_purge_list;
 };
 
 struct size_table {         /* stash of commonly-used sizes */
diff --git a/memory.c b/memory.c
index 953fc380c03c..15fa8b2f08f1 100644
--- a/memory.c
+++ b/memory.c
@@ -429,6 +429,7 @@ vm_init(void)
 	MEMBER_OFFSET_INIT(vmap_area_vm, "vmap_area", "vm");
 	if (INVALID_MEMBER(vmap_area_vm))
 		MEMBER_OFFSET_INIT(vmap_area_vm, "vmap_area", "private");
+	MEMBER_OFFSET_INIT(vmap_area_purge_list, "vmap_area", "purge_list");
 	STRUCT_SIZE_INIT(vmap_area, "vmap_area");
 	if (VALID_MEMBER(vmap_area_va_start) &&
 	    VALID_MEMBER(vmap_area_va_end) &&
@@ -9063,7 +9064,8 @@ dump_vmap_area(struct meminfo *vi)
 		readmem(ld->list_ptr[i], KVADDR, vmap_area_buf,
                         SIZE(vmap_area), "vmap_area struct", FAULT_ON_ERROR); 
 
-		if (VALID_MEMBER(vmap_area_flags)) {
+		if (VALID_MEMBER(vmap_area_flags) &&
+		    VALID_MEMBER(vmap_area_purge_list)) {
 			flags = ULONG(vmap_area_buf + OFFSET(vmap_area_flags));
 			if (flags != VM_VM_AREA)
 				continue;
diff --git a/symbols.c b/symbols.c
index f0721023816d..7b1d59203b90 100644
--- a/symbols.c
+++ b/symbols.c
@@ -9169,6 +9169,7 @@ dump_offset_table(char *spec, ulong makestruct)
 		OFFSET(vmap_area_vm));
 	fprintf(fp, "               vmap_area_flags: %ld\n", 
 		OFFSET(vmap_area_flags));
+	fprintf(fp, "          vmap_area_purge_list: %ld\n", OFFSET(vmap_area_purge_list));
 
 	fprintf(fp, "         module_size_of_struct: %ld\n", 
 		OFFSET(module_size_of_struct));
-- 
2.31.1
                                
                         
                        
                                
                                2 years, 5 months