[PATCH] arm64: fix regression for the determination of VA_BITS and section_size_bits
by qiwu.chen@transsion.com
1. The commit f02c8e87 will cause a regression issue for the determination of VA_BITS
on Linux 4.19 and earlier kernels, the crash session fails during initialization with
the error message due to get a wrong vabits_actual:
vmcoreinfo : vabits_actual: 27
crash: invalid kernel virtual address: ffffffa890a41318 type: "kernel_config_data"
WARNING: cannot read kernel_config_data
crash: invalid kernel virtual address: ffffffa89106db50 type: "possible"
WARNING: cannot read cpu_possible_map
crash: invalid kernel virtual address: ffffffa89106db48 type: "present"
WARNING: cannot read cpu_present_map
crash: invalid kernel virtual address: ffffffa89106db40 type: "online"
WARNING: cannot read cpu_online_map
crash: invalid kernel virtual address: ffffffa89106db58 type: "active"
WARNING: cannot read cpu_active_map
crash: invalid kernel virtual address: ffffffa89143cb80 type: "shadow_timekeeper xtime_sec"
crash: invalid kernel virtual address: ffffffa89107b76c type: "init_uts_ns"
WARNING: invalid linux_banner pointer: ffffffa890a30018
crash: vmlinux and SYS_COREDUMP do not match!
Fix it by remove arm64_set_va_bits_by_tcr() if vabits_actual is missing.
2. The commit 568c6f04 will cause a regression issue for the determination of section_size_bits
on Linux 5.12 and earlier kernels. The section_size_bits compatible with linux upstream and
android GKI changes should be:
Before android-12-GKI or Linux 5.12:
SECTION_SIZE_BITS = 30
After android-12-gki:
SECTION_SIZE_BITS = 27 when defined 4K_PAGES or 16K_PAGES.
SECTION_SIZE_BITS = 29 when defined 64K_PAGES.
Fixes: f02c8e87 ("arm64: use TCR_EL1_T1SZ to get the correct info if vabits_actual is missing")
Fixes: 568c6f04 ("arm64: section_size_bits compatible with macro definitions")
Signed-off-by: qiwu.chen <qiwu.chen(a)transsion.com>
---
arm64.c | 37 ++++++++++++++++++-------------------
1 file changed, 18 insertions(+), 19 deletions(-)
diff --git a/arm64.c b/arm64.c
index b3040d7..176c465 100644
--- a/arm64.c
+++ b/arm64.c
@@ -1613,8 +1613,15 @@ arm64_get_section_size_bits(void)
{
int ret;
char *string;
+ bool is_ikconfig_avail;
- if (THIS_KERNEL_VERSION >= LINUX(5,12,0)) {
+ if (arm64_get_vmcoreinfo(&machdep->section_size_bits, "NUMBER(SECTION_SIZE_BITS)", NUM_DEC))
+ goto exit;
+
+ is_ikconfig_avail = kt->ikconfig_flags & IKCONFIG_AVAIL ? TRUE : FALSE;
+ /* The commit reduce section size for arm64 sparsemem is introduced on linux-v5.12 and android-12-GKI */
+ if (THIS_KERNEL_VERSION >= LINUX(5,12,0) || (is_ikconfig_avail &&
+ get_kernel_config("CONFIG_ANDROID_KABI_RESERVE", NULL) == IKCONFIG_Y)) {
if (machdep->pagesize == 65536)
machdep->section_size_bits = _SECTION_SIZE_BITS_5_12_64K;
else
@@ -1622,24 +1629,18 @@ arm64_get_section_size_bits(void)
} else
machdep->section_size_bits = _SECTION_SIZE_BITS;
- if (arm64_get_vmcoreinfo(&machdep->section_size_bits, "NUMBER(SECTION_SIZE_BITS)", NUM_DEC)) {
- /* nothing */
- } else if (kt->ikconfig_flags & IKCONFIG_AVAIL) {
- if ((ret = get_kernel_config("CONFIG_MEMORY_HOTPLUG", NULL)) == IKCONFIG_Y) {
- if ((ret = get_kernel_config("CONFIG_HOTPLUG_SIZE_BITS", &string)) == IKCONFIG_STR)
- machdep->section_size_bits = atol(string);
- }
-
- /* arm64: reduce section size for sparsemem */
- if ((ret = get_kernel_config("CONFIG_ARM64_4K_PAGES", NULL)) == IKCONFIG_Y
- || (ret = get_kernel_config("CONFIG_ARM64_16K_PAGES", NULL)) == IKCONFIG_Y)
- machdep->section_size_bits = _SECTION_SIZE_BITS_5_12;
- else if ((ret = get_kernel_config("CONFIG_ARM64_64K_PAGES", NULL)) == IKCONFIG_Y)
- machdep->section_size_bits = _SECTION_SIZE_BITS_5_12_64K;
+ /* section_size_bits for arm64 vendor special case */
+ if (is_ikconfig_avail && get_kernel_config("CONFIG_MEMORY_HOTPLUG", NULL) == IKCONFIG_Y) {
+ if (get_kernel_config("CONFIG_HOTPLUG_SIZE_BITS", &string) == IKCONFIG_STR)
+ machdep->section_size_bits = atol(string);
}
- if (CRASHDEBUG(1))
- fprintf(fp, "SECTION_SIZE_BITS: %ld\n", machdep->section_size_bits);
+exit:
+ if (machdep->section_size_bits) {
+ if (CRASHDEBUG(1))
+ fprintf(fp, "SECTION_SIZE_BITS: %ld\n", machdep->section_size_bits);
+ } else
+ error(FATAL, "cannot determine SECTION_SIZE_BITS\n");
}
/*
@@ -4733,8 +4734,6 @@ arm64_calc_VA_BITS(void)
*/
machdep->flags |= FLIPPED_VM;
return;
- } else if (arm64_set_va_bits_by_tcr()) {
- return;
} else if (machdep->machspec->VA_BITS_ACTUAL) {
machdep->machspec->VA_BITS = machdep->machspec->VA_BITS_ACTUAL;
machdep->machspec->VA_START = _VA_START(machdep->machspec->VA_BITS_ACTUAL);
--
2.25.1
2 months, 4 weeks
Fix irq_stack_size on ARM64
by wonderzyp@gmail.com
When using the crash tool to parse the ARM64 dump file with KASAN enabled, I found that using the bt -a command will cause this tool to crash, the following is the backtrace infomation.
(gdb) bt
#0 0x00005635ac2b166b in arm64_unwind_frame (frame=0x7ffdaf35cb70, bt=0x7ffdaf35d430)
at arm64.c:2821
#1 arm64_back_trace_cmd (bt=0x7ffdaf35d430) at arm64.c:3306
#2 0x00005635ac27b108 in back_trace (bt=bt@entry=0x7ffdaf35d430) at kernel.c:3239
#3 0x00005635ac2880ae in cmd_bt () at kernel.c:2863
#4 0x00005635ac1f16dc in exec_command () at main.c:893
#5 0x00005635ac1f192a in main_loop () at main.c:840
#6 0x00005635ac50df81 in captured_main (data=<optimized out>) at main.c:1284
#7 gdb_main (args=<optimized out>) at main.c:1313
#8 0x00005635ac50e000 in gdb_main_entry (argc=<optimized out>, argv=<optimized out>)
at main.c:1338
#9 0x00005635ac1ea2a5 in main (argc=5, argv=0x7ffdaf35dde8) at main.c:721
Eventually, I found that it was may caused by not setting irq_stack_size properly, and provide this patch to solve it.
From 34b28aa8c11e77d20adec4f7705a14d239c8a55f Mon Sep 17 00:00:00 2001
From: wonderzyp <wonderzyp(a)qq.com>
Date: Mon, 8 Jul 2024 20:11:38 +0800
Subject: [PATCH 1131/1131] set_arm64_irq_stack_size
Signed-off-by: Yeping Zheng <wonderzyp(a)gmail.com>
---
arm64.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 47 insertions(+), 2 deletions(-)
diff --git a/arm64.c b/arm64.c
index b3040d7..39d891b 100644
--- a/arm64.c
+++ b/arm64.c
@@ -93,6 +93,7 @@ static void arm64_calc_VA_BITS(void);
static int arm64_is_uvaddr(ulong, struct task_context *);
static void arm64_calc_KERNELPACMASK(void);
static int arm64_get_vmcoreinfo(unsigned long *vaddr, const char *label, int base);
+static ulong arm64_set_irq_stack_size(struct machine_specific *ms);
struct kernel_range {
unsigned long modules_vaddr, modules_end;
@@ -2223,8 +2224,14 @@ arm64_irq_stack_init(void)
if (MEMBER_EXISTS("thread_union", "stack")) {
if ((sz = MEMBER_SIZE("thread_union", "stack")) > 0)
ms->irq_stack_size = sz;
- } else
- ms->irq_stack_size = ARM64_IRQ_STACK_SIZE;
+ } else {
+ ulong res = arm64_set_irq_stack_size(ms);
+ if (res > 0){
+ ms->irq_stack_size = res;
+ } else {
+ ms->irq_stack_size = ARM64_IRQ_STACK_SIZE;
+ }
+ }
machdep->flags |= IRQ_STACKS;
@@ -4921,6 +4928,44 @@ static void arm64_calc_KERNELPACMASK(void)
}
}
+static ulong arm64_set_irq_stack_size(struct machine_specific *ms)
+{
+ char *string;
+ int ret;
+ int KASAN_THREAD_SHIFT = 0;
+ int MIN_THREAD_SHIFT;
+ ulong ARM64_PAGE_SHIFT;
+ ulong THREAD_SHIFT = 0;
+ ulong THREAD_SIZE;
+ if (kt->ikconfig_flags & IKCONFIG_AVAIL) {
+ if ((ret = get_kernel_config("CONFIG_KASAN_GENERIC", NULL) == IKCONFIG_Y) ||
+ (ret = get_kernel_config("CONFIG_KASAN_SW_TAGS", NULL) == IKCONFIG_Y)) {
+ KASAN_THREAD_SHIFT = 1;
+ }
+ }
+ MIN_THREAD_SHIFT = 14 + KASAN_THREAD_SHIFT;
+
+ if (kt->ikconfig_flags & IKCONFIG_AVAIL) {
+ if ((ret = get_kernel_config("CONFIG_VMAP_STACK", NULL)) == IKCONFIG_Y){
+ if ((ret = get_kernel_config("CONFIG_ARM64_PAGE_SHIFT", &string)) == IKCONFIG_STR){
+ ARM64_PAGE_SHIFT = atol(string);
+ }
+ if (MIN_THREAD_SHIFT < ARM64_PAGE_SHIFT){
+ THREAD_SHIFT = ARM64_PAGE_SHIFT;
+ } else {
+ THREAD_SHIFT = MIN_THREAD_SHIFT;
+ }
+ }
+ }
+
+ if (THREAD_SHIFT == 0) {
+ return -1;
+ }
+
+ THREAD_SIZE = ((1UL) << THREAD_SHIFT);
+ return THREAD_SIZE;
+}
+
#endif /* ARM64 */
--
2.25.1
3 months, 2 weeks
[PATCH v5 00/14] gdb stack unwinding support for crash utility
by Tao Liu
This patchset is a rebase/merged version of the following 3 patchsets:
1): [PATCH v10 0/5] Improve stack unwind on ppc64 [1]
2): [PATCH 0/5] x86_64 gdb stack unwinding support [2]
3): Clean up on top of one-thread-v2 [3]
A complete description of gdb stack unwinding support for crash can be
found in [1].
This patchset can be divided into the following 2 parts:
1) part1: arch independent, mainly modify on the
crash_target.c/gdb_interface.c files, in preparation of the
gdb side.
2) part2: arch specific part, for implementing ppc64/x86_64/arm64/vmware
gdb stack unwinding support.
=== part 2
- arm64:
arm64: Add gdb stack unwinding support
- vmware:
vmware_guestdump: Various format versions support
set_context(): check if context is already current
- x86_64:
x86_64: Fix invalid input "=>" for bt command
Fix cpumask_t recursive dependence issue
x86_64: Add gdb stack unwinding support
- ppc64:
ppc64: correct gdb passthroughs by implementing machdep->get_cpu_reg
=== part 1
Stop stack unwinding at non-kernel address
Fix gdb_interface: restore gdb's output streams at end of gdb_interface
Print task pid/command instead of CPU index
Rename get_cpu_reg to get_current_task_reg
Let crash change gdb context
Leave only one gdb thread for crash
Remove 'frame' from prohibited commands list
===
v5 -> v4:
1) Plenty of code refactoring based on Lianbo's comments on v4.
2) Removed the magic number when dealing with regs bitmap, see [6].
3) Rebased the patchset on top of latest upstream:
("1c6da3eaff8207 arm64: Fix bt command show wrong stacktrace on ramdump source")
v4 -> v3:
Fixed the author issue in [PATCH v3 06/16] Fix gdb_interface: restore gdb's
output streams at end of gdb_interface.
v3 -> v2:
1) Updated CC list as pointed out in [4]
2) Compiling issues as in [5]
v2 -> v1:
1) Added the patch: x86_64: Fix invalid input "=>" for bt command,
thanks for Kazu's testing.
2) Modify the patch: x86_64: Add gdb stack unwinding support, added the
pcp_save, spp_save and sp, for restoring the value in match of the original
code logic.
[1]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00469.html
[2]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00488.html
[3]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00554.html
[4]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00681.html
[5]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00715.html
[6]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00819.html
Aditya Gupta (2):
Remove 'frame' from prohibited commands list
ppc64: correct gdb passthroughs by implementing machdep->get_cpu_reg
Alexey Makhalov (2):
set_context(): check if context is already current
vmware_guestdump: Various format versions support
Tao Liu (10):
Leave only one gdb thread for crash
Let crash change gdb context
Rename get_cpu_reg to get_current_task_reg
Print task pid/command instead of CPU index
Fix gdb_interface: restore gdb's output streams at end of
gdb_interface
Stop stack unwinding at non-kernel address
x86_64: Add gdb stack unwinding support
Fix cpumask_t recursive dependence issue
x86_64: Fix invalid input "=>" for bt command
arm64: Add gdb stack unwinding support
arm64.c | 114 +++++++++++++++-
crash_target.c | 71 ++++++----
defs.h | 194 ++++++++++++++++++++++++++-
gdb-10.2.patch | 79 +++++++++++
gdb_interface.c | 35 ++---
kernel.c | 65 +++++++--
ppc64.c | 175 ++++++++++++++++++++++++-
symbols.c | 15 +++
task.c | 34 +++--
tools.c | 13 +-
unwind_x86_64.h | 4 -
vmware_guestdump.c | 316 +++++++++++++++++++++++++++++++-------------
x86_64.c | 319 ++++++++++++++++++++++++++++++++++++++++-----
xen_hyper.c | 2 +-
14 files changed, 1224 insertions(+), 212 deletions(-)
--
2.40.1
3 months, 2 weeks
[PATCH v2] arm64: fix regression for the determination of section_size_bits
by qiwu.chen@transsion.com
The commit 568c6f04 will cause a regression issue for the determination of
section_size_bits on kernel version before android12-5.10 or Linux-v5.12.
The section_size_bits is supposed to be compatible with linux upstream and
android GKI version:
Before android12-5.10 or Linux-v5.12:
SECTION_SIZE_BITS = 30
After android12-5.10 or Linux-v5.12:
SECTION_SIZE_BITS = 27 when defined 4K_PAGES or 16K_PAGES.
SECTION_SIZE_BITS = 29 when defined 64K_PAGES.
Introduce arm64_get_andriod_gki_version() to get Andriod GKI version by ut->release.
The Andriod GKI version is determined either by arm64_get_andriod_gki_version()
or the kernel config "CONFIG_ANDROID_KABI_RESERVE".
Fixes: 568c6f04 ("arm64: section_size_bits compatible with macro definitions")
Signed-off-by: qiwu.chen <qiwu.chen(a)transsion.com>
---
arm64.c | 68 ++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 51 insertions(+), 17 deletions(-)
diff --git a/arm64.c b/arm64.c
index 78e6609..679f2ab 100644
--- a/arm64.c
+++ b/arm64.c
@@ -95,6 +95,13 @@ static void arm64_calc_KERNELPACMASK(void);
static void arm64_recalc_KERNELPACMASK(void);
static int arm64_get_vmcoreinfo(unsigned long *vaddr, const char *label, int base);
+/* Andriod GKI version definition */
+struct andriod_gki_version {
+ int kernel_version;
+ int kernel_patch_level;
+ int android_version;
+};
+
struct kernel_range {
unsigned long modules_vaddr, modules_end;
unsigned long vmalloc_start_addr, vmalloc_end;
@@ -1615,6 +1622,30 @@ arm64_calc_phys_offset(void)
fprintf(fp, "using %lx as phys_offset\n", ms->phys_offset);
}
+/*
+ * Determine Andriod GKI vmcore by reading "android" from ut->release.
+ * The prefix of Andriod GKI release version is:
+ * Kernel Version - Android release version
+ * For example:
+ * 5.10.209-android12, 5.15.148-android13
+ */
+static bool arm64_get_andriod_gki_version(struct andriod_gki_version *version)
+{
+ char *p;
+ struct new_utsname *uts = &kt->utsname;
+
+ if ((p = strstr(uts->release, "android"))) {
+ sscanf(uts->release, "%d.%d", &version->kernel_version, &version->kernel_patch_level);
+ sscanf(p, "android%d", &version->android_version);
+ if (CRASHDEBUG(1))
+ fprintf(fp, "andriod_gki_version: andriod%d-%d.%d\n",
+ version->android_version, version->kernel_version, version->kernel_patch_level);
+ return true;
+ }
+
+ return false;
+}
+
/*
* Determine SECTION_SIZE_BITS either by reading VMCOREINFO or the kernel
* config, otherwise use the 64-bit ARM default definiton.
@@ -1624,8 +1655,17 @@ arm64_get_section_size_bits(void)
{
int ret;
char *string;
+ bool is_ikconfig_avail;
+ struct andriod_gki_version ver = {0};
- if (THIS_KERNEL_VERSION >= LINUX(5,12,0)) {
+ if (arm64_get_vmcoreinfo(&machdep->section_size_bits, "NUMBER(SECTION_SIZE_BITS)", NUM_DEC))
+ goto exit;
+
+ is_ikconfig_avail = kt->ikconfig_flags & IKCONFIG_AVAIL ? TRUE : FALSE;
+ /* The commit reduce section size for arm64 sparsemem is introduced since linux-v5.12 and android-12-5.10 */
+ if (THIS_KERNEL_VERSION >= LINUX(5,12,0) ||
+ (is_ikconfig_avail && get_kernel_config("CONFIG_ANDROID_KABI_RESERVE", NULL) == IKCONFIG_Y) ||
+ (arm64_get_andriod_gki_version(&ver) && (ver.kernel_version * 100 + ver.kernel_patch_level >= 510) && ver.android_version >= 12)) {
if (machdep->pagesize == 65536)
machdep->section_size_bits = _SECTION_SIZE_BITS_5_12_64K;
else
@@ -1633,24 +1673,18 @@ arm64_get_section_size_bits(void)
} else
machdep->section_size_bits = _SECTION_SIZE_BITS;
- if (arm64_get_vmcoreinfo(&machdep->section_size_bits, "NUMBER(SECTION_SIZE_BITS)", NUM_DEC)) {
- /* nothing */
- } else if (kt->ikconfig_flags & IKCONFIG_AVAIL) {
- if ((ret = get_kernel_config("CONFIG_MEMORY_HOTPLUG", NULL)) == IKCONFIG_Y) {
- if ((ret = get_kernel_config("CONFIG_HOTPLUG_SIZE_BITS", &string)) == IKCONFIG_STR)
- machdep->section_size_bits = atol(string);
- }
-
- /* arm64: reduce section size for sparsemem */
- if ((ret = get_kernel_config("CONFIG_ARM64_4K_PAGES", NULL)) == IKCONFIG_Y
- || (ret = get_kernel_config("CONFIG_ARM64_16K_PAGES", NULL)) == IKCONFIG_Y)
- machdep->section_size_bits = _SECTION_SIZE_BITS_5_12;
- else if ((ret = get_kernel_config("CONFIG_ARM64_64K_PAGES", NULL)) == IKCONFIG_Y)
- machdep->section_size_bits = _SECTION_SIZE_BITS_5_12_64K;
+ /* section_size_bits for arm64 vendor special case */
+ if (is_ikconfig_avail && get_kernel_config("CONFIG_MEMORY_HOTPLUG", NULL) == IKCONFIG_Y) {
+ if (get_kernel_config("CONFIG_HOTPLUG_SIZE_BITS", &string) == IKCONFIG_STR)
+ machdep->section_size_bits = atol(string);
}
- if (CRASHDEBUG(1))
- fprintf(fp, "SECTION_SIZE_BITS: %ld\n", machdep->section_size_bits);
+exit:
+ if (machdep->section_size_bits) {
+ if (CRASHDEBUG(1))
+ fprintf(fp, "SECTION_SIZE_BITS: %ld\n", machdep->section_size_bits);
+ } else
+ error(FATAL, "cannot determine SECTION_SIZE_BITS\n");
}
/*
--
2.25.1
3 months, 2 weeks
[PATCH] arm64: fix the determination of vmemmap and struct_page_size
by qiwu.chen@transsion.com
Currently, the vmemmap ptr addr is determined by the vmcoreinfo of "SYMBOL(vmemmap)", which leads to an invalid vmemmap addr showed by "help -m" for dump files without the vmcoreinfo. The value of vmemmap_end is simply set to -1 for available VA_BITS_ACTUAL case in arm64_calc_virtual_memory_ranges(), and the struct_page_size value is 0.
crash> help -m |grep vmem
vmemmap_vaddr: fffffffeffe00000
vmemmap_end: ffffffffffffffff
vmemmap: 0000000000000000
crash> help -m |grep struct_page_size
struct_page_size: 0
Introduce arm64_get_vmemmap_page_ptr() to fix the determination of vmemmap ptr addr, and fix the determination of vmemmap_end and struct_page_size in arm64_calc_virtual_memory_ranges().
crash> help -m |grep vmem
vmemmap_vaddr: fffffffeffe00000
vmemmap_end: ffffffffffe00000
vmemmap: fffffffefee00000
crash> help -m |grep struct_page_size
struct_page_size: 64
Signed-off-by: qiwu.chen <qiwu.chen(a)qq.com>
---
arm64.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/arm64.c b/arm64.c
index 78e6609..ef495ec 100644
--- a/arm64.c
+++ b/arm64.c
@@ -159,7 +159,6 @@ 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)) {
@@ -175,6 +174,25 @@ arm64_vmemmap_is_page_ptr(ulong addr, physaddr_t *phys)
return FALSE;
}
+static void arm64_get_vmemmap_page_ptr(void)
+{
+ struct machine_specific *ms = machdep->machspec;
+
+ /* If vmemmap exists, it means kernel enabled CONFIG_SPARSEMEM_VMEMMAP */
+ if (arm64_get_vmcoreinfo(&ms->vmemmap, "SYMBOL(vmemmap)", NUM_HEX))
+ goto out;
+
+ /* The global symbol of vmemmap is removed since kernel commit 7bc1a0f9e1765 */
+ if (!kernel_symbol_exists("vmemmap"))
+ ms->vmemmap = ms->vmemmap_vaddr - ((ms->phys_offset >> machdep->pageshift) * ms->struct_page_size);
+ else
+ ms->vmemmap = symbol_value("vmemmap");
+
+out:
+ if (ms->vmemmap)
+ machdep->is_page_ptr = arm64_vmemmap_is_page_ptr;
+}
+
/*
* Do all necessary machine-specific setup here. This is called several times
* during initialization.
@@ -443,10 +461,6 @@ 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;
machdep->eframe_search = arm64_eframe_search;
@@ -498,6 +512,7 @@ arm64_init(int when)
if (!ms->struct_page_size)
arm64_calc_virtual_memory_ranges();
+ arm64_get_vmemmap_page_ptr();
arm64_get_section_size_bits();
if (!machdep->max_physmem_bits) {
@@ -4841,6 +4856,7 @@ arm64_calc_virtual_memory_ranges(void)
return;
STRUCT_SIZE_INIT(page, "page");
+ ms->struct_page_size = SIZE(page);
switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K))
{
@@ -4868,7 +4884,8 @@ arm64_calc_virtual_memory_ranges(void)
vmemmap_start = (-vmemmap_size - MEGABYTES(2));
ms->vmalloc_end = vmalloc_end - 1;
ms->vmemmap_vaddr = vmemmap_start;
- ms->vmemmap_end = -1;
+ ms->vmemmap_end = vmemmap_start + vmemmap_size;
+
return;
}
--
2.25.1
3 months, 3 weeks
[PATCH] arm64: Introduction of support for 16K page with 3-level table support
by Kuan-Ying Lee
Introduction of ARM64 support for 16K page size with 3-level page
table and 47 VA bits.
Signed-off-by: Kuan-Ying Lee <kuan-ying.lee(a)canonical.com>
---
arm64.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
defs.h | 16 ++++++++
2 files changed, 126 insertions(+), 4 deletions(-)
diff --git a/arm64.c b/arm64.c
index b3040d757946..5356ae1f5cce 100644
--- a/arm64.c
+++ b/arm64.c
@@ -42,6 +42,7 @@ static int arm64_kvtop(struct task_context *, ulong, physaddr_t *, int);
static int arm64_uvtop(struct task_context *, ulong, physaddr_t *, int);
static int arm64_vtop_2level_64k(ulong, ulong, physaddr_t *, int);
static int arm64_vtop_3level_64k(ulong, ulong, physaddr_t *, int);
+static int arm64_vtop_3level_16k(ulong, ulong, physaddr_t *, int);
static int arm64_vtop_3level_4k(ulong, ulong, physaddr_t *, int);
static int arm64_vtop_4level_4k(ulong, ulong, physaddr_t *, int);
static ulong arm64_get_task_pgd(ulong);
@@ -261,8 +262,7 @@ arm64_init(int when)
machdep->pagesize = 4096;
break;
case 2:
- /* TODO: machdep->pagesize = 16384; */
- error(FATAL, "16K pages not supported.");
+ machdep->pagesize = 16384;
break;
case 3:
machdep->pagesize = 65536;
@@ -392,6 +392,26 @@ arm64_init(int when)
error(FATAL, "cannot malloc ptbl space.");
break;
+ case 16384:
+ if (machdep->machspec->VA_BITS > PGDIR_SHIFT_L3_16K) {
+ machdep->flags |= VM_L3_16K;
+ if (!machdep->ptrs_per_pgd)
+ machdep->ptrs_per_pgd = PTRS_PER_PGD_L3_16K;
+ if ((machdep->pgd =
+ (char *)malloc(machdep->ptrs_per_pgd * 8)) == NULL)
+ error(FATAL, "cannot malloc pgd space.");
+ if ((machdep->pmd =
+ (char *)malloc(PTRS_PER_PMD_L3_16K * 8)) == NULL)
+ error(FATAL, "cannot malloc pmd space.");
+ if ((machdep->ptbl =
+ (char *)malloc(PTRS_PER_PTE_L3_16K * 8)) == NULL)
+ error(FATAL, "cannot malloc ptbl space.");
+ } else {
+ error(FATAL, "we only support 47 bits, 3 level for 16K page now.");
+ }
+ machdep->pud = NULL; /* not used */
+ break;
+
case 65536:
if (kernel_symbol_exists("idmap_ptrs_per_pgd") &&
readmem(symbol_value("idmap_ptrs_per_pgd"), KVADDR,
@@ -1018,6 +1038,8 @@ arm64_dump_machdep_table(ulong arg)
fprintf(fp, "%sVM_L2_64K", others++ ? "|" : "");
if (machdep->flags & VM_L3_64K)
fprintf(fp, "%sVM_L3_64K", others++ ? "|" : "");
+ if (machdep->flags & VM_L3_16K)
+ fprintf(fp, "%sVM_L3_16K", others++ ? "|" : "");
if (machdep->flags & VM_L3_4K)
fprintf(fp, "%sVM_L3_4K", others++ ? "|" : "");
if (machdep->flags & VM_L4_4K)
@@ -1065,6 +1087,8 @@ arm64_dump_machdep_table(ulong arg)
"arm64_vtop_3level_4k" :
machdep->flags & VM_L4_4K ?
"arm64_vtop_4level_4k" :
+ machdep->flags & VM_L3_16K ?
+ "arm64_vtop_3level_16k" :
machdep->flags & VM_L3_64K ?
"arm64_vtop_3level_64k" : "arm64_vtop_2level_64k");
fprintf(fp, " kvtop: arm64_kvtop()->%s()\n",
@@ -1072,6 +1096,8 @@ arm64_dump_machdep_table(ulong arg)
"arm64_vtop_3level_4k" :
machdep->flags & VM_L4_4K ?
"arm64_vtop_4level_4k" :
+ machdep->flags & VM_L3_16K ?
+ "arm64_vtop_3level_16k" :
machdep->flags & VM_L3_64K ?
"arm64_vtop_3level_64k" : "arm64_vtop_2level_64k");
fprintf(fp, " get_task_pgd: arm64_get_task_pgd()\n");
@@ -1107,6 +1133,7 @@ arm64_dump_machdep_table(ulong arg)
fprintf(fp, " last_pgd_read: %lx\n", machdep->last_pgd_read);
fprintf(fp, " last_pud_read: ");
if ((PAGESIZE() == 65536) ||
+ (PAGESIZE() == 16384) ||
((PAGESIZE() == 4096) && !(machdep->flags & VM_L4_4K)))
fprintf(fp, "(not used)\n");
else
@@ -1761,7 +1788,7 @@ arm64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbos
kernel_pgd = vt->kernel_pgd[0];
*paddr = 0;
- switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K))
+ switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K|VM_L3_16K))
{
case VM_L2_64K:
return arm64_vtop_2level_64k(kernel_pgd, kvaddr, paddr, verbose);
@@ -1771,6 +1798,8 @@ arm64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbos
return arm64_vtop_3level_4k(kernel_pgd, kvaddr, paddr, verbose);
case VM_L4_4K:
return arm64_vtop_4level_4k(kernel_pgd, kvaddr, paddr, verbose);
+ case VM_L3_16K:
+ return arm64_vtop_3level_16k(kernel_pgd, kvaddr, paddr, verbose);
default:
return FALSE;
}
@@ -1786,7 +1815,7 @@ arm64_uvtop(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, int verbos
*paddr = 0;
- switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K))
+ switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K|VM_L3_16K))
{
case VM_L2_64K:
return arm64_vtop_2level_64k(user_pgd, uvaddr, paddr, verbose);
@@ -1796,6 +1825,8 @@ arm64_uvtop(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, int verbos
return arm64_vtop_3level_4k(user_pgd, uvaddr, paddr, verbose);
case VM_L4_4K:
return arm64_vtop_4level_4k(user_pgd, uvaddr, paddr, verbose);
+ case VM_L3_16K:
+ return arm64_vtop_3level_16k(user_pgd, uvaddr, paddr, verbose);
default:
return FALSE;
}
@@ -1812,6 +1843,7 @@ arm64_uvtop(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, int verbos
#define PMD_TYPE_SECT 1
#define PMD_TYPE_TABLE 2
#define SECTION_PAGE_MASK_2MB ((long)(~((MEGABYTES(2))-1)))
+#define SECTION_PAGE_MASK_32MB ((long)(~((MEGABYTES(32))-1)))
#define SECTION_PAGE_MASK_512MB ((long)(~((MEGABYTES(512))-1)))
#define SECTION_PAGE_MASK_1GB ((long)(~((GIGABYTES(1))-1)))
@@ -1954,6 +1986,80 @@ no_page:
return FALSE;
}
+static int
+arm64_vtop_3level_16k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
+{
+ ulong *pgd_base, *pgd_ptr, pgd_val;
+ ulong *pmd_base, *pmd_ptr, pmd_val;
+ ulong *pte_base, *pte_ptr, pte_val;
+
+ if (verbose)
+ fprintf(fp, "PAGE DIRECTORY: %lx\n", pgd);
+
+ pgd_base = (ulong *)pgd;
+ FILL_PGD(pgd_base, KVADDR, machdep->ptrs_per_pgd * sizeof(ulong));
+ pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L3_16K) & (machdep->ptrs_per_pgd - 1));
+ pgd_val = ULONG(machdep->pgd + PGDIR_OFFSET_L3_16K(pgd_ptr));
+ if (verbose)
+ fprintf(fp, " PGD: %lx => %lx\n", (ulong)pgd_ptr, pgd_val);
+ if (!pgd_val)
+ goto no_page;
+
+ /*
+ * #define __PAGETABLE_PUD_FOLDED
+ */
+
+ pmd_base = (ulong *)PTOV(PTE_TO_PHYS(pgd_val));
+ FILL_PMD(pmd_base, KVADDR, PTRS_PER_PMD_L3_16K * sizeof(ulong));
+ pmd_ptr = pmd_base + (((vaddr) >> PMD_SHIFT_L3_16K) & (PTRS_PER_PMD_L3_16K - 1));
+ pmd_val = ULONG(machdep->pmd + PAGEOFFSET(pmd_ptr));
+ if (verbose)
+ fprintf(fp, " PMD: %lx => %lx\n", (ulong)pmd_ptr, pmd_val);
+ if (!pmd_val)
+ goto no_page;
+
+ if ((pmd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
+ ulong sectionbase = PTE_TO_PHYS(pmd_val) & SECTION_PAGE_MASK_32MB;
+ if (verbose) {
+ fprintf(fp, " PAGE: %lx (32MB%s)\n\n", sectionbase,
+ IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" : "");
+ arm64_translate_pte(pmd_val, 0, 0);
+ }
+ *paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_32MB);
+ return TRUE;
+ }
+
+ pte_base = (ulong *)PTOV(PTE_TO_PHYS(pmd_val));
+ FILL_PTBL(pte_base, KVADDR, PTRS_PER_PTE_L3_16K * sizeof(ulong));
+ pte_ptr = pte_base + (((vaddr) >> machdep->pageshift) & (PTRS_PER_PTE_L3_16K - 1));
+ pte_val = ULONG(machdep->ptbl + PAGEOFFSET(pte_ptr));
+ if (verbose)
+ fprintf(fp, " PTE: %lx => %lx\n", (ulong)pte_ptr, pte_val);
+ if (!pte_val)
+ goto no_page;
+
+ if (pte_val & PTE_VALID) {
+ *paddr = PTE_TO_PHYS(pte_val) + PAGEOFFSET(vaddr);
+ if (verbose) {
+ fprintf(fp, " PAGE: %lx %s\n\n", PAGEBASE(*paddr),
+ IS_ZEROPAGE(PAGEBASE(*paddr)) ? "(ZERO PAGE)" : "");
+ arm64_translate_pte(pte_val, 0, 0);
+ }
+ } else {
+ if (IS_UVADDR(vaddr, NULL))
+ *paddr = pte_val;
+ if (verbose) {
+ fprintf(fp, "\n");
+ arm64_translate_pte(pte_val, 0, 0);
+ }
+ goto no_page;
+ }
+
+ return TRUE;
+no_page:
+ return FALSE;
+}
+
static int
arm64_vtop_3level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
{
diff --git a/defs.h b/defs.h
index 49e6923ede54..1b7649d9f05c 100644
--- a/defs.h
+++ b/defs.h
@@ -3302,6 +3302,21 @@ typedef signed int s32;
#define PGDIR_MASK_48VA (~(PGDIR_SIZE_48VA - 1))
#define PGDIR_OFFSET_48VA(X) (((ulong)(X)) & (PGDIR_SIZE_48VA - 1))
+/*
+ * 3-levels / 16K pages
+ * 47-bit VA
+ */
+#define PTRS_PER_PGD_L3_16K ((1UL) << (47 - 36))
+#define PTRS_PER_PMD_L3_16K (2048)
+#define PTRS_PER_PTE_L3_16K (2048)
+#define PGDIR_SHIFT_L3_16K (36)
+#define PGDIR_SIZE_L3_16K ((1UL) << PGDIR_SHIFT_L3_16K)
+#define PGDIR_MASK_L3_16K (~(PGDIR_SIZE_L3_16K-1))
+#define PMD_SHIFT_L3_16K (25)
+#define PMD_SIZE_L3_16K (1UL << PMD_SHIFT_L3_16K)
+#define PMD_MASK_L3_16K (~(PMD_SIZE_L3_16K-1))
+#define PGDIR_OFFSET_L3_16K(X) (((ulong)(X)) & ((machdep->ptrs_per_pgd * 8) - 1))
+
/*
* 3-levels / 64K pages
*/
@@ -3367,6 +3382,7 @@ typedef signed int s32;
#define HAS_PHYSVIRT_OFFSET (0x800)
#define OVERFLOW_STACKS (0x1000)
#define ARM64_MTE (0x2000)
+#define VM_L3_16K (0x4000)
/*
* Get kimage_voffset from /dev/crash
--
2.34.1
3 months, 3 weeks
Re: [PATCH v4 15/16] vmware_guestdump: Various format versions support
by lijiang
On Fri, May 31, 2024 at 5:38 PM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Fri, 31 May 2024 17:19:38 +0800
> From: Tao Liu <ltao(a)redhat.com>
> Subject: [Crash-utility] [PATCH v4 15/16] vmware_guestdump: Various
> format versions support
> To: devel(a)lists.crash-utility.osci.io
> Cc: Alexey Makhalov <alexey.makhalov(a)broadcom.com>, Mahesh J
> Salgaonkar <mahesh(a)linux.ibm.com>, "Naveen N . Rao"
> <naveen.n.rao(a)linux.vnet.ibm.com>, Lianbo Jiang <
> lijiang(a)redhat.com>
> Message-ID: <20240531091939.97828-16-ltao(a)redhat.com>
> Content-Type: text/plain; charset=UTF-8
>
> From: Alexey Makhalov <alexey.makhalov(a)broadcom.com>
>
> There are several versions of debug.guest format. Current version of
> the code is able to parse only version 4.
>
> Improve parser to support other known versions. Split data structures
> on sub-structures and introduce a helper functions to calculate a gap
> between them based on the version number. Implement additional data
> structure (struct mainmeminfo_old) and logic specifically for original
> (version 1) format support.
>
> Cc: Sourabh Jain <sourabhjain(a)linux.ibm.com>
> Cc: Hari Bathini <hbathini(a)linux.ibm.com>
> Cc: Mahesh J Salgaonkar <mahesh(a)linux.ibm.com>
> Cc: Naveen N. Rao <naveen.n.rao(a)linux.vnet.ibm.com>
> Cc: Lianbo Jiang <lijiang(a)redhat.com>
> Cc: HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab(a)nec.com>
> Cc: Tao Liu <ltao(a)redhat.com>
> Cc: Alexey Makhalov <alexey.makhalov(a)broadcom.com>
> Signed-off-by: Alexey Makhalov <alexey.makhalov(a)broadcom.com>
> ---
> vmware_guestdump.c | 316 ++++++++++++++++++++++++++++++++-------------
> 1 file changed, 229 insertions(+), 87 deletions(-)
>
>
The current patch is still not improved, commented on it there:
https://www.spinics.net/linux/fedora/redhat-crash-utility/msg11627.html
Thanks
Lianbo
> diff --git a/vmware_guestdump.c b/vmware_guestdump.c
> index 5be26c8..5c7ee4d 100644
> --- a/vmware_guestdump.c
> +++ b/vmware_guestdump.c
> @@ -2,6 +2,8 @@
> * vmware_guestdump.c
> *
> * Copyright (c) 2020 VMware, Inc.
> + * Copyright (c) 2024 Broadcom. All Rights Reserved. The term "Broadcom"
> + * refers to Broadcom Inc. and/or its subsidiaries.
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published by
> @@ -13,7 +15,7 @@
> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> * GNU General Public License for more details.
> *
> - * Author: Alexey Makhalov <amakhalov(a)vmware.com>
> + * Author: Alexey Makhalov <alexey.makhalov(a)broadcom.com>
> */
>
> #include "defs.h"
> @@ -21,20 +23,31 @@
>
> #define LOGPRX "vmw: "
>
> -#define GUESTDUMP_VERSION 4
> -#define GUESTDUMP_MAGIC1 1
> -#define GUESTDUMP_MAGIC2 0
> -
> +/*
> + * debug.guest file layout
> + * 00000000: guest dump header, it includes:
> + * 1. Version (4 bytes) \
> + * 2. Number of Virtual CPUs (4 bytes) } - struct
> guestdumpheader
> + * 3. Reserved gap
> + * 4. Main Memory information - struct mainmeminfo{,_old}
> + * (use get_vcpus_offset() to get total size of guestdumpheader)
> + * vcpus_offset: ---------\
> + * 1. struct vcpu_state1 \
> + * 2. reserved gap } num_vcpus times
> + * 3. struct vcpu_state2 /
> + * 4. 4KB of reserved data /
> + * --------/
> + *
> + */
> struct guestdumpheader {
> uint32_t version;
> uint32_t num_vcpus;
> - uint8_t magic1;
> - uint8_t reserved1;
> - uint32_t cpu_vendor;
> - uint64_t magic2;
> +} __attribute__((packed)) hdr;
> +
> +struct mainmeminfo {
> uint64_t last_addr;
> uint64_t memsize_in_pages;
> - uint32_t reserved2;
> + uint32_t reserved1;
> uint32_t mem_holes;
> struct memhole {
> uint64_t ppn;
> @@ -42,14 +55,36 @@ struct guestdumpheader {
> } holes[2];
> } __attribute__((packed));
>
> -struct vcpu_state {
> +/* Used by version 1 only */
> +struct mainmeminfo_old {
> + uint64_t last_addr;
> + uint32_t memsize_in_pages;
> + uint32_t reserved1;
> + uint32_t mem_holes;
> + struct memhole1 {
> + uint32_t ppn;
> + uint32_t pages;
> + } holes[2];
> + /* There are additional fields, see get_vcpus_offset()
> calculation. */
> +} __attribute__((packed));
> +
> +/* First half of vcpu_state */
> +struct vcpu_state1 {
> uint32_t cr0;
> uint64_t cr2;
> uint64_t cr3;
> uint64_t cr4;
> uint64_t reserved1[10];
> uint64_t idt_base;
> - uint16_t reserved2[21];
> +} __attribute__((packed));
> +
> +/*
> + * Unused fields between vcpu_state1 and vcpu_state2 swill be skipped.
> + * See get_vcpu_gapsize() calculation.
> + */
> +
> +/* Second half of vcpu_state */
> +struct vcpu_state2 {
> struct x86_64_pt_regs {
> uint64_t r15;
> uint64_t r14;
> @@ -76,9 +111,41 @@ struct vcpu_state {
> uint8_t reserved3[65];
> } __attribute__((packed));
>
> +/*
> + * Returns the size of the guest dump header.
> + */
> +static inline long
> +get_vcpus_offset(uint32_t version, int mem_holes)
> +{
> + switch (version) {
> + case 1: /* ESXi 6.7 and older */
> + return sizeof(struct guestdumpheader) + 13 +
> sizeof(struct mainmeminfo_old) +
> + (mem_holes == -1 ? 0 : 8 * mem_holes + 4);
> + case 3: /* ESXi 6.8 */
> + return sizeof(struct guestdumpheader) + 14 +
> sizeof(struct mainmeminfo);
> + case 4: /* ESXi 7.0 */
> + case 5: /* ESXi 8.0 */
> + return sizeof(struct guestdumpheader) + 14 +
> sizeof(struct mainmeminfo);
> + case 6: /* ESXi 8.0u2 */
> + return sizeof(struct guestdumpheader) + 15 +
> sizeof(struct mainmeminfo);
> +
> + }
> + return 0;
> +}
> +
> +/*
> + * Returns the size of reserved (unused) fields in the middle of
> vcpu_state structure.
> + */
> +static inline long
> +get_vcpu_gapsize(uint32_t version)
> +{
> + if (version < 4)
> + return 45;
> + return 42;
> +}
>
> /*
> - * vmware_guestdump is extension to vmware_vmss with ability to debug
> + * vmware_guestdump is an extension to the vmware_vmss with ability to
> debug
> * debug.guest and debug.vmem files.
> *
> * debug.guest.gz and debug.vmem.gz can be obtained using following
> @@ -86,73 +153,136 @@ struct vcpu_state {
> * monitor.mini-suspend_on_panic = TRUE
> * monitor.suspend_on_triplefault = TRUE
> *
> - * guestdump (debug.guest) is simplified version of *.vmss which does
> - * not contain full VM state, but minimal guest state, such as memory
> + * guestdump (debug.guest) is a simplified version of the *.vmss which
> does
> + * not contain a full VM state, but minimal guest state, such as a memory
> * layout and CPUs state, needed for debugger. is_vmware_guestdump()
> * and vmware_guestdump_init() functions parse guestdump header and
> - * populate vmss data structure (from vmware_vmss.c). As result, all
> + * populate vmss data structure (from vmware_vmss.c). In result, all
> * handlers (except mempry_dump) from vmware_vmss.c can be reused.
> *
> - * debug.guest does not have dedicated header magic or signature for
> - * its format. To probe debug.guest we need to perform header fields
> - * and file size validity. In addition, check for the filename
> - * extension, which must be ".guest".
> + * debug.guest does not have a dedicated header magic or file format
> signature
> + * To probe debug.guest we need to perform series of validations. In
> addition,
> + * we check for the filename extension, which must be ".guest".
> */
> -
> int
> is_vmware_guestdump(char *filename)
> {
> - struct guestdumpheader hdr;
> + struct mainmeminfo mmi;
> + long vcpus_offset;
> FILE *fp;
> - uint64_t filesize, holes_sum = 0;
> + uint64_t filesize, expected_filesize, holes_sum = 0;
> int i;
>
> if (strcmp(filename + strlen(filename) - 6, ".guest"))
> return FALSE;
>
> - if ((fp = fopen(filename, "r")) == NULL) {
> + if ((fp = fopen(filename, "r")) == NULL) {
> error(INFO, LOGPRX"Failed to open '%s': [Error %d] %s\n",
> - filename, errno, strerror(errno));
> + filename, errno, strerror(errno));
> return FALSE;
> - }
> + }
>
> if (fread(&hdr, sizeof(struct guestdumpheader), 1, fp) != 1) {
> error(INFO, LOGPRX"Failed to read '%s' from file '%s':
> [Error %d] %s\n",
> - "guestdumpheader", filename, errno, strerror(errno));
> + "guestdumpheader", filename, errno,
> strerror(errno));
> + fclose(fp);
> + return FALSE;
> + }
> +
> + vcpus_offset = get_vcpus_offset(hdr.version, -1 /* Unknown yet,
> adjust it later */);
> +
> + if (!vcpus_offset) {
> + if (CRASHDEBUG(1))
> + error(INFO, LOGPRX"Not supported version %d\n",
> hdr.version);
> fclose(fp);
> return FALSE;
> }
>
> + if (hdr.version == 1) {
> + struct mainmeminfo_old tmp;
> + if (fseek(fp, vcpus_offset - sizeof(struct
> mainmeminfo_old), SEEK_SET) == -1) {
> + if (CRASHDEBUG(1))
> + error(INFO, LOGPRX"Failed to fseek '%s':
> [Error %d] %s\n",
> + filename, errno,
> strerror(errno));
> + fclose(fp);
> + return FALSE;
> + }
> +
> + if (fread(&tmp, sizeof(struct mainmeminfo_old), 1, fp) !=
> 1) {
> + if (CRASHDEBUG(1))
> + error(INFO, LOGPRX"Failed to read '%s'
> from file '%s': [Error %d] %s\n",
> + "mainmeminfo_old",
> filename, errno, strerror(errno));
> + fclose(fp);
> + return FALSE;
> + }
> + mmi.last_addr = tmp.last_addr;
> + mmi.memsize_in_pages = tmp.memsize_in_pages;
> + mmi.mem_holes = tmp.mem_holes;
> + mmi.holes[0].ppn = tmp.holes[0].ppn;
> + mmi.holes[0].pages = tmp.holes[0].pages;
> + mmi.holes[1].ppn = tmp.holes[1].ppn;
> + mmi.holes[1].pages = tmp.holes[1].pages;
> + /* vcpu_offset adjustment for mem_holes is required only
> for version 1. */
> + vcpus_offset = get_vcpus_offset(hdr.version,
> mmi.mem_holes);
> + } else {
> + if (fseek(fp, vcpus_offset - sizeof(struct mainmeminfo),
> SEEK_SET) == -1) {
> + if (CRASHDEBUG(1))
> + error(INFO, LOGPRX"Failed to fseek '%s':
> [Error %d] %s\n",
> + filename, errno,
> strerror(errno));
> + fclose(fp);
> + return FALSE;
> + }
> +
> + if (fread(&mmi, sizeof(struct mainmeminfo), 1, fp) != 1) {
> + if (CRASHDEBUG(1))
> + error(INFO, LOGPRX"Failed to read '%s'
> from file '%s': [Error %d] %s\n",
> + "mainmeminfo", filename,
> errno, strerror(errno));
> + fclose(fp);
> + return FALSE;
> + }
> + }
> if (fseek(fp, 0L, SEEK_END) == -1) {
> - error(INFO, LOGPRX"Failed to fseek '%s': [Error %d] %s\n",
> - filename, errno, strerror(errno));
> + if (CRASHDEBUG(1))
> + error(INFO, LOGPRX"Failed to fseek '%s': [Error
> %d] %s\n",
> + filename, errno, strerror(errno));
> fclose(fp);
> return FALSE;
> }
> filesize = ftell(fp);
> fclose(fp);
>
> - if (hdr.mem_holes > 2)
> - goto unrecognized;
> + if (mmi.mem_holes > 2) {
> + if (CRASHDEBUG(1))
> + error(INFO, LOGPRX"Unexpected mmi.mem_holes value
> %d\n",
> + mmi.mem_holes);
> + return FALSE;
> + }
>
> - for (i = 0; i < hdr.mem_holes; i++) {
> + for (i = 0; i < mmi.mem_holes; i++) {
> /* hole start page */
> - vmss.regions[i].startpagenum = hdr.holes[i].ppn;
> + vmss.regions[i].startpagenum = mmi.holes[i].ppn;
> /* hole end page */
> - vmss.regions[i].startppn = hdr.holes[i].ppn +
> hdr.holes[i].pages;
> - holes_sum += hdr.holes[i].pages;
> + vmss.regions[i].startppn = mmi.holes[i].ppn +
> mmi.holes[i].pages;
> + holes_sum += mmi.holes[i].pages;
> + }
> +
> + if ((mmi.last_addr + 1) != ((mmi.memsize_in_pages + holes_sum) <<
> VMW_PAGE_SHIFT)) {
> + if (CRASHDEBUG(1))
> + error(INFO, LOGPRX"Memory size check failed\n");
> + return FALSE;
> }
>
> - if (hdr.version != GUESTDUMP_VERSION ||
> - hdr.magic1 != GUESTDUMP_MAGIC1 ||
> - hdr.magic2 != GUESTDUMP_MAGIC2 ||
> - (hdr.last_addr + 1) != ((hdr.memsize_in_pages + holes_sum) <<
> VMW_PAGE_SHIFT) ||
> - filesize != sizeof(struct guestdumpheader) +
> - hdr.num_vcpus * (sizeof (struct vcpu_state) + VMW_PAGE_SIZE))
> - goto unrecognized;
> + expected_filesize = vcpus_offset + hdr.num_vcpus * (sizeof(struct
> vcpu_state1) +
> + get_vcpu_gapsize(hdr.version) + sizeof(struct vcpu_state2)
> + VMW_PAGE_SIZE);
> + if (filesize != expected_filesize) {
> + if (CRASHDEBUG(1))
> + error(INFO, LOGPRX"Incorrect file size: %d !=
> %d\n",
> + filesize, expected_filesize);
> + return FALSE;
> + }
>
> - vmss.memsize = hdr.memsize_in_pages << VMW_PAGE_SHIFT;
> - vmss.regionscount = hdr.mem_holes + 1;
> + vmss.memsize = mmi.memsize_in_pages << VMW_PAGE_SHIFT;
> + vmss.regionscount = mmi.mem_holes + 1;
> vmss.memoffset = 0;
> vmss.num_vcpus = hdr.num_vcpus;
> return TRUE;
> @@ -169,7 +299,8 @@ vmware_guestdump_init(char *filename, FILE *ofp)
> FILE *fp = NULL;
> int i, result = TRUE;
> char *vmem_filename = NULL;
> - struct vcpu_state vs;
> + struct vcpu_state1 vs1;
> + struct vcpu_state2 vs2;
> char *p;
>
> if (!machine_type("X86") && !machine_type("X86_64")) {
> @@ -180,14 +311,14 @@ vmware_guestdump_init(char *filename, FILE *ofp)
> goto exit;
> }
>
> - if ((fp = fopen(filename, "r")) == NULL) {
> + if ((fp = fopen(filename, "r")) == NULL) {
> error(INFO, LOGPRX"Failed to open '%s': [Error %d] %s\n",
> filename, errno, strerror(errno));
> result = FALSE;
> goto exit;
> - }
> + }
>
> - if (fseek(fp, sizeof(struct guestdumpheader), SEEK_SET) == -1) {
> + if (fseek(fp, get_vcpus_offset(hdr.version, vmss.regionscount -
> 1), SEEK_SET) == -1) {
> error(INFO, LOGPRX"Failed to fseek '%s': [Error %d] %s\n",
> filename, errno, strerror(errno));
> result = FALSE;
> @@ -203,7 +334,19 @@ vmware_guestdump_init(char *filename, FILE *ofp)
> }
>
> for (i = 0; i < vmss.num_vcpus; i++) {
> - if (fread(&vs, sizeof(struct vcpu_state), 1, fp) != 1) {
> + if (fread(&vs1, sizeof(struct vcpu_state1), 1, fp) != 1) {
> + error(INFO, LOGPRX"Failed to read '%s' from file
> '%s': [Error %d] %s\n",
> + "vcpu_state", filename, errno,
> strerror(errno));
> + result = FALSE;
> + goto exit;
> + }
> + if (fseek(fp, get_vcpu_gapsize(hdr.version), SEEK_CUR) ==
> -1) {
> + error(INFO, LOGPRX"Failed to read '%s' from file
> '%s': [Error %d] %s\n",
> + "vcpu_state", filename, errno,
> strerror(errno));
> + result = FALSE;
> + goto exit;
> + }
> + if (fread(&vs2, sizeof(struct vcpu_state2), 1, fp) != 1) {
> error(INFO, LOGPRX"Failed to read '%s' from file
> '%s': [Error %d] %s\n",
> "vcpu_state", filename, errno,
> strerror(errno));
> result = FALSE;
> @@ -217,29 +360,29 @@ vmware_guestdump_init(char *filename, FILE *ofp)
> }
> vmss.vcpu_regs[i] = 0;
>
> - vmss.regs64[i]->rax = vs.regs64.rax;
> - vmss.regs64[i]->rcx = vs.regs64.rcx;
> - vmss.regs64[i]->rdx = vs.regs64.rdx;
> - vmss.regs64[i]->rbx = vs.regs64.rbx;
> - vmss.regs64[i]->rbp = vs.regs64.rbp;
> - vmss.regs64[i]->rsp = vs.regs64.rsp;
> - vmss.regs64[i]->rsi = vs.regs64.rsi;
> - vmss.regs64[i]->rdi = vs.regs64.rdi;
> - vmss.regs64[i]->r8 = vs.regs64.r8;
> - vmss.regs64[i]->r9 = vs.regs64.r9;
> - vmss.regs64[i]->r10 = vs.regs64.r10;
> - vmss.regs64[i]->r11 = vs.regs64.r11;
> - vmss.regs64[i]->r12 = vs.regs64.r12;
> - vmss.regs64[i]->r13 = vs.regs64.r13;
> - vmss.regs64[i]->r14 = vs.regs64.r14;
> - vmss.regs64[i]->r15 = vs.regs64.r15;
> - vmss.regs64[i]->idtr = vs.idt_base;
> - vmss.regs64[i]->cr[0] = vs.cr0;
> - vmss.regs64[i]->cr[2] = vs.cr2;
> - vmss.regs64[i]->cr[3] = vs.cr3;
> - vmss.regs64[i]->cr[4] = vs.cr4;
> - vmss.regs64[i]->rip = vs.regs64.rip;
> - vmss.regs64[i]->rflags = vs.regs64.eflags;
> + vmss.regs64[i]->rax = vs2.regs64.rax;
> + vmss.regs64[i]->rcx = vs2.regs64.rcx;
> + vmss.regs64[i]->rdx = vs2.regs64.rdx;
> + vmss.regs64[i]->rbx = vs2.regs64.rbx;
> + vmss.regs64[i]->rbp = vs2.regs64.rbp;
> + vmss.regs64[i]->rsp = vs2.regs64.rsp;
> + vmss.regs64[i]->rsi = vs2.regs64.rsi;
> + vmss.regs64[i]->rdi = vs2.regs64.rdi;
> + vmss.regs64[i]->r8 = vs2.regs64.r8;
> + vmss.regs64[i]->r9 = vs2.regs64.r9;
> + vmss.regs64[i]->r10 = vs2.regs64.r10;
> + vmss.regs64[i]->r11 = vs2.regs64.r11;
> + vmss.regs64[i]->r12 = vs2.regs64.r12;
> + vmss.regs64[i]->r13 = vs2.regs64.r13;
> + vmss.regs64[i]->r14 = vs2.regs64.r14;
> + vmss.regs64[i]->r15 = vs2.regs64.r15;
> + vmss.regs64[i]->idtr = vs1.idt_base;
> + vmss.regs64[i]->cr[0] = vs1.cr0;
> + vmss.regs64[i]->cr[2] = vs1.cr2;
> + vmss.regs64[i]->cr[3] = vs1.cr3;
> + vmss.regs64[i]->cr[4] = vs1.cr4;
> + vmss.regs64[i]->rip = vs2.regs64.rip;
> + vmss.regs64[i]->rflags = vs2.regs64.eflags;
>
> vmss.vcpu_regs[i] = REGS_PRESENT_ALL;
> }
> @@ -268,9 +411,9 @@ vmware_guestdump_init(char *filename, FILE *ofp)
> fprintf(ofp, LOGPRX"vmem file: %s\n\n", vmem_filename);
>
> if (CRASHDEBUG(1)) {
> - vmware_guestdump_memory_dump(ofp);
> - dump_registers_for_vmss_dump();
> - }
> + vmware_guestdump_memory_dump(ofp);
> + dump_registers_for_vmss_dump();
> + }
>
> exit:
> if (fp)
> @@ -296,24 +439,23 @@ exit:
> int
> vmware_guestdump_memory_dump(FILE *ofp)
> {
> + uint64_t holes_sum = 0;
> + unsigned i;
> +
> fprintf(ofp, "vmware_guestdump:\n");
> fprintf(ofp, " Header: version=%d num_vcpus=%llu\n",
> - GUESTDUMP_VERSION, (ulonglong)vmss.num_vcpus);
> + hdr.version, (ulonglong)vmss.num_vcpus);
> fprintf(ofp, "Total memory: %llu\n", (ulonglong)vmss.memsize);
>
> - if (vmss.regionscount > 1) {
> - uint64_t holes_sum = 0;
> - unsigned i;
>
> - fprintf(ofp, "Memory regions[%d]:\n", vmss.regionscount);
> - fprintf(ofp, " [0x%016x-", 0);
> - for (i = 0; i < vmss.regionscount - 1; i++) {
> - fprintf(ofp, "0x%016llx]\n",
> (ulonglong)vmss.regions[i].startpagenum << VMW_PAGE_SHIFT);
> - fprintf(ofp, " [0x%016llx-",
> (ulonglong)vmss.regions[i].startppn << VMW_PAGE_SHIFT);
> - holes_sum += vmss.regions[i].startppn -
> vmss.regions[i].startpagenum;
> - }
> - fprintf(ofp, "0x%016llx]\n", (ulonglong)vmss.memsize +
> (holes_sum << VMW_PAGE_SHIFT));
> + fprintf(ofp, "Memory regions[%d]:\n", vmss.regionscount);
> + fprintf(ofp, " [0x%016x-", 0);
> + for (i = 0; i < vmss.regionscount - 1; i++) {
> + fprintf(ofp, "0x%016llx]\n",
> (ulonglong)vmss.regions[i].startpagenum << VMW_PAGE_SHIFT);
> + fprintf(ofp, " [0x%016llx-",
> (ulonglong)vmss.regions[i].startppn << VMW_PAGE_SHIFT);
> + holes_sum += vmss.regions[i].startppn -
> vmss.regions[i].startpagenum;
> }
> + fprintf(ofp, "0x%016llx]\n", (ulonglong)vmss.memsize + (holes_sum
> << VMW_PAGE_SHIFT));
>
> return TRUE;
> }
> --
> 2.40.1
>
4 months
Re: [PATCH v4 14/16] x86_64: fix gdb bt for vmware dumps (Tao Liu)
by lijiang
On Fri, May 31, 2024 at 5:38 PM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Fri, 31 May 2024 17:19:37 +0800
> From: Tao Liu <ltao(a)redhat.com>
> Subject: [Crash-utility] [PATCH v4 14/16] x86_64: fix gdb bt for
> vmware dumps
> To: devel(a)lists.crash-utility.osci.io
> Cc: Alexey Makhalov <alexey.makhalov(a)broadcom.com>, Mahesh J
> Salgaonkar <mahesh(a)linux.ibm.com>, "Naveen N . Rao"
> <naveen.n.rao(a)linux.vnet.ibm.com>, Lianbo Jiang <
> lijiang(a)redhat.com>
> Message-ID: <20240531091939.97828-15-ltao(a)redhat.com>
> Content-Type: text/plain; charset=UTF-8
>
> From: Alexey Makhalov <alexey.makhalov(a)broadcom.com>
>
> vmware_vmss_get_cpu_reg() whould be called only for active tasks
> to get their registers from corresponding CPUs.
> Otherwise, the standard path of fetching pt_regs from the memory
> (inactive_task_frame) should be used.
>
> Cc: Sourabh Jain <sourabhjain(a)linux.ibm.com>
> Cc: Hari Bathini <hbathini(a)linux.ibm.com>
> Cc: Mahesh J Salgaonkar <mahesh(a)linux.ibm.com>
> Cc: Naveen N. Rao <naveen.n.rao(a)linux.vnet.ibm.com>
> Cc: Lianbo Jiang <lijiang(a)redhat.com>
> Cc: HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab(a)nec.com>
> Cc: Tao Liu <ltao(a)redhat.com>
> Cc: Alexey Makhalov <alexey.makhalov(a)broadcom.com>
> Signed-off-by: Alexey Makhalov <alexey.makhalov(a)broadcom.com>
> ---
> x86_64.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/x86_64.c b/x86_64.c
> index 47c215f..617a4ab 100644
> --- a/x86_64.c
> +++ b/x86_64.c
> @@ -9232,7 +9232,10 @@ x86_64_get_current_task_reg(int regno, const char
> *name,
> if (!tc)
> return FALSE;
>
> - if (VMSS_DUMPFILE())
> + /*
> + * Task is active, grab CPU's registers
> + */
> + if (is_task_active(tc->task) && VMSS_DUMPFILE())
> return vmware_vmss_get_cpu_reg(tc->processor, regno, name,
> size, value);
>
>
Can you try to fold this change into the [PATCH 09/16]? And add the current
descriptions in the patch log.
Thanks
Lianbo
BZERO(&bt_setup, sizeof(struct bt_info));
> --
> 2.40.1
>
4 months
Re: [PATCH v4 13/16] set_context(): check if context is already current
by lijiang
On Fri, May 31, 2024 at 5:38 PM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Fri, 31 May 2024 17:19:36 +0800
> From: Tao Liu <ltao(a)redhat.com>
> Subject: [Crash-utility] [PATCH v4 13/16] set_context(): check if
> context is already current
> To: devel(a)lists.crash-utility.osci.io
> Cc: Alexey Makhalov <alexey.makhalov(a)broadcom.com>, Mahesh J
> Salgaonkar <mahesh(a)linux.ibm.com>, "Naveen N . Rao"
> <naveen.n.rao(a)linux.vnet.ibm.com>, Lianbo Jiang <
> lijiang(a)redhat.com>
> Message-ID: <20240531091939.97828-14-ltao(a)redhat.com>
> Content-Type: text/plain; charset=UTF-8
>
> From: Alexey Makhalov <alexey.makhalov(a)broadcom.com>
>
> By doing it we avoid dropping gdb caches unnecessarily.
>
> Cc: Sourabh Jain <sourabhjain(a)linux.ibm.com>
> Cc: Hari Bathini <hbathini(a)linux.ibm.com>
> Cc: Mahesh J Salgaonkar <mahesh(a)linux.ibm.com>
> Cc: Naveen N. Rao <naveen.n.rao(a)linux.vnet.ibm.com>
> Cc: Lianbo Jiang <lijiang(a)redhat.com>
> Cc: HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab(a)nec.com>
> Cc: Tao Liu <ltao(a)redhat.com>
> Cc: Alexey Makhalov <alexey.makhalov(a)broadcom.com>
> Signed-off-by: Alexey Makhalov <alexey.makhalov(a)broadcom.com>
> ---
> task.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/task.c b/task.c
> index 8c00837..3814f6d 100644
> --- a/task.c
> +++ b/task.c
> @@ -5287,6 +5287,9 @@ set_context(ulong task, ulong pid, uint
> update_gdb_thread)
> struct task_context *tc;
> int found;
>
> + if (CURRENT_CONTEXT() && CURRENT_TASK() == task)
> + return TRUE;
> +
>
Seems it makes sense.
I would suggest also adding the pid checking as below:
+ if (CURRENT_CONTEXT() && (CURRENT_TASK() == task || CURRENT_PID()
== pid))
+ return TRUE;
+
What do you think?
Thanks
Lianbo
tc = FIRST_CONTEXT();
>
> for (i = 0, found = FALSE; i < RUNNING_TASKS(); i++, tc++) {
> --
> 2.40.1
>
4 months
Re: [PATCH v4 11/16] Fix cpumask_t recursive dependence issue
by lijiang
On Fri, May 31, 2024 at 5:33 PM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Fri, 31 May 2024 17:19:34 +0800
> From: Tao Liu <ltao(a)redhat.com>
> Subject: [Crash-utility] [PATCH v4 11/16] Fix cpumask_t recursive
> dependence issue
> To: devel(a)lists.crash-utility.osci.io
> Cc: Mahesh J Salgaonkar <mahesh(a)linux.ibm.com>, "Naveen N . Rao"
> <naveen.n.rao(a)linux.vnet.ibm.com>, Lianbo Jiang <
> lijiang(a)redhat.com>,
> Alexey Makhalov <alexey.makhalov(a)broadcom.com>
> Message-ID: <20240531091939.97828-12-ltao(a)redhat.com>
> Content-Type: text/plain; charset=UTF-8
>
> There is recursive dependence for cpumask_t and will exhause the stack,
> see the following stack trace:
>
> (gdb) bt
> ...snip...
> #61965 0x00000000005de98c in datatype_info (name=name@entry=0xa5b1fd
> "cpumask_t", member=member@entry=0x0, dm=dm@entry=0xfffffffffffffffc) at
> symbols.c:6694
> #61966 0x000000000057e4ea in cpu_map_size ...
> #61967 0x000000000058e7bd in get_cpus_online ...
> #61968 0x000000000061fa4b in diskdump_get_prstatus_percpu ...
> #61969 0x0000000000616d74 in get_netdump_regs_x86_64 ...
> #61970 0x0000000000585290 in get_dumpfile_regs ...
> #61971 0x00000000005b7a3c in x86_64_get_current_task_reg ...
> #61972 0x0000000000650389 in crash_target::fetch_registers ...
> #61973 0x00000000008f385a in target_fetch_registers ...
> #61974 0x000000000086ecda in regcache::raw_update ...
> #61975 regcache::raw_update ...
> #61976 0x000000000086ed7a in readable_regcache::raw_read ...
> #61977 0x000000000086f063 in readable_regcache::cooked_read_value ...
> #61978 0x000000000089c4ee in sentinel_frame_prev_register ...
> #61979 0x0000000000786c76 in frame_unwind_register_value ...
> #61980 0x0000000000786f18 in frame_register_unwind ...
> #61981 0x0000000000787267 in frame_unwind_register ...
> #61982 0x00000000007ad9b0 in i386_unwind_pc ...
> #61983 0x00000000007866c0 in frame_unwind_pc ...
> #61984 0x000000000078679c in get_frame_pc ...
> #61985 get_frame_address_in_block ...
> #61986 0x0000000000786849 in get_frame_address_in_block_if_available ...
> #61987 0x0000000000691466 in get_frame_block ...
> #61988 0x00000000008b9430 in get_selected_block ...
> #61989 0x000000000084f8f2 in parse_exp_in_context ...
> #61990 0x000000000084f9e5 in parse_exp_1 ...
> #61991 parse_expression ...
> #61992 0x00000000008d44da in gdb_get_datatype ...
> #61993 gdb_command_funnel_1 ...
> #61994 0x00000000008d48ae in gdb_command_funnel ...
> #61995 0x000000000059cc42 in gdb_interface ...
> #61996 0x00000000005de98c in datatype_info (name=name@entry=0xa5b1fd
> "cpumask_t", member=member@entry=0x0, dm=dm@entry=0xfffffffffffffffc) at
> symbols.c:6694
> #61997 0x000000000057e4ea in cpu_map_size ...
> #61998 0x000000000058e7bd in get_cpus_online () ...
> #61999 0x000000000061fa4b in diskdump_get_prstatus_percpu ...
> #62000 0x0000000000616d74 in get_netdump_regs_x86_64 ...
> #62001 0x0000000000585290 in get_dumpfile_regs ...
> #62002 0x00000000005b7a3c in x86_64_get_current_task_reg ...
> #62003 0x0000000000650389 in crash_target::fetch_registers ...
>
> The cpumask_t will be recursively evaluated. This patch will
> fix the bug.
>
> Cc: Sourabh Jain <sourabhjain(a)linux.ibm.com>
> Cc: Hari Bathini <hbathini(a)linux.ibm.com>
> Cc: Mahesh J Salgaonkar <mahesh(a)linux.ibm.com>
> Cc: Naveen N. Rao <naveen.n.rao(a)linux.vnet.ibm.com>
> Cc: Lianbo Jiang <lijiang(a)redhat.com>
> Cc: HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab(a)nec.com>
> Cc: Tao Liu <ltao(a)redhat.com>
> Cc: Alexey Makhalov <alexey.makhalov(a)broadcom.com>
> Signed-off-by: Tao Liu <ltao(a)redhat.com>
> ---
> defs.h | 1 +
> kernel.c | 17 ++++++++++-------
> 2 files changed, 11 insertions(+), 7 deletions(-)
>
> diff --git a/defs.h b/defs.h
> index ed52cc3..fd00462 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -2429,6 +2429,7 @@ struct size_table { /* stash of
> commonly-used sizes */
> long maple_tree;
> long maple_node;
> long module_memory;
> + long cpumask_t;
> };
>
>
Can you add the cpumask_t into the dump_offset_table()?
struct array_table {
> diff --git a/kernel.c b/kernel.c
> index 3730c55..2cae305 100644
> --- a/kernel.c
> +++ b/kernel.c
> @@ -157,6 +157,7 @@ kernel_init()
> if (!(kt->cpu_flags = (ulong *)calloc(NR_CPUS, sizeof(ulong))))
> error(FATAL, "cannot malloc cpu_flags array");
>
> + STRUCT_SIZE_INIT(cpumask_t, "cpumask_t");
> cpu_maps_init();
>
> kt->stext = symbol_value("_stext");
> @@ -913,9 +914,10 @@ cpu_map_size(const char *type)
> struct gnu_request req;
>
> if (LKCD_KERNTYPES()) {
> - if ((len = STRUCT_SIZE("cpumask_t")) < 0)
> - error(FATAL, "cannot determine type cpumask_t\n");
> - return len;
> + if (INVALID_SIZE(cpumask_t))
> + error(FATAL, "cannot determine type cpumask_t\n");
> + else
> + return SIZE(cpumask_t);
>
Let's remove the 'else', keep the original style:
+ if (INVALID_SIZE(cpumask_t))
+ error(FATAL, "Invalid type cpumask_t\n");
+
+ return SIZE(cpumask_t);
}
>
> sprintf(map_symbol, "cpu_%s_map", type);
> @@ -925,11 +927,10 @@ cpu_map_size(const char *type)
> return len;
> }
>
> - len = STRUCT_SIZE("cpumask_t");
> - if (len < 0)
> + if (INVALID_SIZE(cpumask_t))
> return sizeof(ulong);
> else
> - return len;
> + return SIZE(cpumask_t);
>
Ditto.
+ if (INVALID_SIZE(cpumask_t))
return sizeof(ulong);
- else
- return len;
+
+ return SIZE(cpumask_t);
> }
>
> /*
> @@ -952,8 +953,10 @@ cpu_maps_init(void)
> { ACTIVE_MAP, "active" },
> };
>
> - if ((len = STRUCT_SIZE("cpumask_t")) < 0)
> + if (INVALID_SIZE(cpumask_t))
> len = sizeof(ulong);
> + else
> + len = SIZE(cpumask_t);
>
> buf = GETBUF(len);
>
In addition, I still found two similar calls as below. Can you try to make
similar changes in those two functions?
1. kernel.c:
void
generic_get_irq_affinity(int irq)
{
...
if ((len = STRUCT_SIZE("cpumask_t")) < 0)
len = DIV_ROUND_UP(kt->cpus, BITS_PER_LONG) * sizeof(ulong);
...
}
2. tools.
ulong *
get_cpumask_buf(void)
{
int cpulen;
if ((cpulen = STRUCT_SIZE("cpumask_t")) < 0)
cpulen = DIV_ROUND_UP(kt->cpus, BITS_PER_LONG) *
sizeof(ulong);
return (ulong *)GETBUF(cpulen);
}
Thanks
Lianbo
> --
> 2.40.1
>
4 months