[PATCH] arm64: add tag_ignore machdep option
by Vinayak Menon
Raw ramdumps without vmcoreinfo does not work currently
with pointer authentication or memory tagging enabled.
The arm capability array can be queried but that creates
a dependency on the bits identifying the capabilities.
Add a machdep option instead to ignore the tags when any
feature using the tag bits is enabled.
Signed-off-by: Vinayak Menon <vinayakm.list(a)gmail.com>
---
arm64.c | 26 +++++++++++++++++++-------
crash.8 | 1 +
defs.h | 1 +
help.c | 1 +
4 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/arm64.c b/arm64.c
index 37aed07..3ed6795 100644
--- a/arm64.c
+++ b/arm64.c
@@ -745,7 +745,8 @@ arm64_parse_machdep_arg_l(char *argstring, char *param, ulong *value)
char *p;
len = strlen(param);
- if (!STRNEQ(argstring, param) || (argstring[len] != '='))
+ if (!STRNEQ(argstring, param) || (!STRNEQ(argstring, "tag_ignore") &&
+ (argstring[len] != '=')))
return FALSE;
if ((LASTCHAR(argstring) == 'm') ||
@@ -763,6 +764,8 @@ arm64_parse_machdep_arg_l(char *argstring, char *param, ulong *value)
*value = dtol(p, flags, &err);
} else if (STRNEQ(argstring, "vabits_actual")) {
*value = dtol(p, flags, &err);
+ } else if (STRNEQ(argstring, "tag_ignore")) {
+ *value = 1;
} else if (megabytes) {
*value = dtol(p, flags, &err);
if (!err)
@@ -797,12 +800,6 @@ arm64_parse_cmdline_args(void)
if (!machdep->cmdline_args[index])
break;
- if (!strstr(machdep->cmdline_args[index], "=")) {
- error(WARNING, "ignoring --machdep option: %x\n",
- machdep->cmdline_args[index]);
- continue;
- }
-
strcpy(buf, machdep->cmdline_args[index]);
for (p = buf; *p; p++) {
@@ -838,6 +835,11 @@ arm64_parse_cmdline_args(void)
"setting vabits_actual to: %ld\n\n",
machdep->machspec->VA_BITS_ACTUAL);
continue;
+ } else if (arm64_parse_machdep_arg_l(arglist[i], "tag_ignore",
+ &machdep->machspec->tag_ignore)) {
+ error(NOTE,
+ "setting tag_ignore\n\n");
+ continue;
}
error(WARNING, "ignoring --machdep option: %s\n",
@@ -4122,6 +4124,9 @@ arm64_swp_offset(ulong pte)
return pte;
}
+#define __GENMASK_ULL(h, l) \
+ (((~0ULL) - (1ULL << (l)) + 1) & \
+ (~0ULL >> (64 - 1 - (h))))
static void arm64_calc_KERNELPACMASK(void)
{
ulong value;
@@ -4133,6 +4138,13 @@ static void arm64_calc_KERNELPACMASK(void)
machdep->machspec->CONFIG_ARM64_KERNELPACMASK = value;
if (CRASHDEBUG(1))
fprintf(fp, "CONFIG_ARM64_KERNELPACMASK: %lx\n", value);
+ } else if (machdep->machspec->VA_BITS_ACTUAL &&
+ machdep->machspec->tag_ignore) {
+ machdep->machspec->CONFIG_ARM64_KERNELPACMASK =
+ __GENMASK_ULL(63, machdep->machspec->VA_BITS_ACTUAL);
+ if (CRASHDEBUG(1))
+ fprintf(fp, "CONFIG_ARM64_KERNELPACMASK: %lx\n",
+ machdep->machspec->CONFIG_ARM64_KERNELPACMASK);
}
}
diff --git a/crash.8 b/crash.8
index 5020ce1..91f01fc 100644
--- a/crash.8
+++ b/crash.8
@@ -289,6 +289,7 @@ ARM64:
kimage_voffset=<kimage_voffset-value>
max_physmem_bits=<value>
vabits_actual=<value>
+ tag_ignore
X86:
page_offset=<CONFIG_PAGE_OFFSET-value>
.fi
diff --git a/defs.h b/defs.h
index 35b983a..cd3bcf9 100644
--- a/defs.h
+++ b/defs.h
@@ -3331,6 +3331,7 @@ struct machine_specific {
ulong VA_START;
ulong CONFIG_ARM64_KERNELPACMASK;
ulong physvirt_offset;
+ ulong tag_ignore;
};
struct arm64_stackframe {
diff --git a/help.c b/help.c
index 531f50a..d66125b 100644
--- a/help.c
+++ b/help.c
@@ -182,6 +182,7 @@ char *program_usage_info[] = {
" kimage_voffset=<kimage_voffset-value>",
" max_physmem_bits=<value>",
" vabits_actual=<value>",
+ " tag_ignore",
" X86:",
" page_offset=<CONFIG_PAGE_OFFSET-value>",
"",
--
3 years, 5 months
[PATCH 1/2] crash-utility/arm64: rename ARM64_PAGE_OFFSET_ACTUAL as ARM64_FLIP_PAGE_OFFSET_ACTUAL
by Pingfan Liu
Renaming, so it is better to reflect the flip layout of kernel VA, which
is introduced by kernel commit 14c127c957c1 ("arm64: mm: Flip kernel VA space")
Signed-off-by: Pingfan Liu <piliu(a)redhat.com>
Cc: HAGIO KAZUHITO <k-hagio-ab(a)nec.com>
Cc: Lianbo Jiang <lijiang(a)redhat.com>
Cc: Mark Salter <msalter(a)redhat.com>
Cc: Mark Langsdorf <mlangsdo(a)redhat.com>
Cc: Jeremy Linton <jlinton(a)redhat.com>
To: crash-utility(a)redhat.com
---
arm64.c | 8 ++++----
defs.h | 3 ++-
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/arm64.c b/arm64.c
index a0bee62..132a39d 100644
--- a/arm64.c
+++ b/arm64.c
@@ -221,9 +221,9 @@ arm64_init(int when)
arm64_calc_KERNELPACMASK();
ms = machdep->machspec;
if (ms->VA_BITS_ACTUAL) {
- ms->page_offset = ARM64_PAGE_OFFSET_ACTUAL;
- machdep->identity_map_base = ARM64_PAGE_OFFSET_ACTUAL;
- machdep->kvbase = ARM64_PAGE_OFFSET_ACTUAL;
+ ms->page_offset = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
+ machdep->identity_map_base = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
+ machdep->kvbase = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
ms->userspace_top = ARM64_USERSPACE_TOP_ACTUAL;
} else {
ms->page_offset = ARM64_PAGE_OFFSET;
@@ -404,7 +404,7 @@ arm64_init(int when)
fprintf(fp, "CONFIG_ARM64_VA_BITS: %ld\n", ms->CONFIG_ARM64_VA_BITS);
fprintf(fp, " VA_BITS_ACTUAL: %ld\n", ms->VA_BITS_ACTUAL);
fprintf(fp, "(calculated) VA_BITS: %ld\n", ms->VA_BITS);
- fprintf(fp, " PAGE_OFFSET: %lx\n", ARM64_PAGE_OFFSET_ACTUAL);
+ fprintf(fp, " PAGE_OFFSET: %lx\n", ARM64_FLIP_PAGE_OFFSET_ACTUAL);
fprintf(fp, " VA_START: %lx\n", ms->VA_START);
fprintf(fp, " modules: %lx - %lx\n", ms->modules_vaddr, ms->modules_end);
fprintf(fp, " vmalloc: %lx - %lx\n", ms->vmalloc_start_addr, ms->vmalloc_end);
diff --git a/defs.h b/defs.h
index 64f2bcb..d8e0f30 100644
--- a/defs.h
+++ b/defs.h
@@ -3219,7 +3219,8 @@ typedef signed int s32;
#define ARM64_PAGE_OFFSET ((0xffffffffffffffffUL) \
<< (machdep->machspec->VA_BITS - 1))
-#define ARM64_PAGE_OFFSET_ACTUAL ((0xffffffffffffffffUL) \
+/* after kernel commit 14c127c957c1 ("arm64: mm: Flip kernel VA space") */
+#define ARM64_FLIP_PAGE_OFFSET_ACTUAL ((0xffffffffffffffffUL) \
- ((1UL) << machdep->machspec->VA_BITS_ACTUAL) + 1)
#define ARM64_USERSPACE_TOP ((1UL) << machdep->machspec->VA_BITS)
--
2.29.2
3 years, 5 months
[PATCH] extension: Fix crash segfaults when loading same extension with different names twice
by Tao Liu
If a same extension(Eg: extensions/trace.so) with two different names are loaded by
"extend" command twice, it sometimes segfaults crash.
It's because crash uses RTLD_NOW|RTLD_GLOBAL flags of dlopen to load an extension.
RTDL_GLOBAL will make symbols defined by this shared object available for
symbol resolution of subsequently loaded shared objects. So symbols with the same
name will be exported from the former to the latter. In this case, when 2 extensions
only differ from file names, the subsequently loaded extension will have unexpected
initial values for global varibles.
This patch adds RTLD_DEEPBIND flag to dlopen, making extensions using its
own symbols preference to symbols with the same name contained by others.
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
extensions.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/extensions.c b/extensions.c
index d23b1e3..e07f9a9 100644
--- a/extensions.c
+++ b/extensions.c
@@ -317,7 +317,7 @@ load_extension(char *lib)
* _init() function before dlopen() returns below.
*/
pc->curext = ext;
- ext->handle = dlopen(ext->filename, RTLD_NOW|RTLD_GLOBAL);
+ ext->handle = dlopen(ext->filename, RTLD_NOW|RTLD_GLOBAL|RTLD_DEEPBIND);
if (!ext->handle) {
strcpy(buf, dlerror());
--
2.29.2
3 years, 5 months
[PATCH] Do not pass through the 'sy' command to GDB
by Lianbo Jiang
The 'sy' command may be misused, which is mistakenly considered as
the 'symbol-file' command in the crash utility, this will discard
symbol table from the current symbol file, and eventually caused the
failure of crash utility after executing the 'sys' command as below:
crash> sy
GNU_GET_DATATYPE[sy]: returned via gdb_error_hook
Discard symbol table from `/usr/lib/debug/usr/lib/modules/5.11.0-2.el9.x86_64/vmlinux'? (y or n) Please answer y or n.
Discard symbol table from `/usr/lib/debug/usr/lib/modules/5.11.0-2.el9.x86_64/vmlinux'? (y or n) No symbol file now.
crash> sys
GNU_GET_SYMBOL_TYPE: returned via gdb_error_hook
double free or corruption (!prev)
Aborted (core dumped)
Actually, the 'symbol-file' command has been added to the gdb-prohibited
list. To prevent current error, let's add the 'sy' command to the list
so that the crash utility does not pass the 'sy' command directly to GDB.
Signed-off-by: Lianbo Jiang <lijiang(a)redhat.com>
---
gdb_interface.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gdb_interface.c b/gdb_interface.c
index f4f4dd3993db..1f10006a2d63 100644
--- a/gdb_interface.c
+++ b/gdb_interface.c
@@ -702,7 +702,7 @@ static char *prohibited_list[] = {
"clear", "disable", "enable", "condition", "ignore", "frame",
"select-frame", "f", "up", "down", "catch", "tcatch", "return",
"file", "exec-file", "core-file", "symbol-file", "load", "si", "ni",
- "shell",
+ "shell", "sy",
NULL /* must be last */
};
--
2.29.2
3 years, 5 months
[PATCH] struct: fix struct print member array of list_heads
by John Pittman
Due to the way that an array of list_head entries are printed,
parsing of them fails. Note the difference in spacing between the
double opening and double closing brackets.
crash> struct blk_mq_ctx.rq_lists ffffc447ffc0f740
<-->rq_lists = {{
next = 0xffffc447ffc0f748,
prev = 0xffffc447ffc0f748
}, {
next = 0xffffc447ffc0f758,
prev = 0xffffc447ffc0f758
}, {
next = 0xffffc447ffc0f768,
prev = 0xffffc447ffc0f768
<---->}}
As parse_for_member() relies on opening and closing brackets having
the same spacing, make a condition for these arrays of list_head
members.
Before:
crash> struct blk_mq_ctx.rq_completed ffffc447ffc0f740
crash>
After:
crash> struct blk_mq_ctx.rq_completed ffffc447ffc0f740
rq_completed = {221, 1333}
Signed-off-by: John Pittman <jpittman(a)redhat.com>
---
symbols.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/symbols.c b/symbols.c
index 215d523..a2d5c6c 100644
--- a/symbols.c
+++ b/symbols.c
@@ -7918,7 +7918,8 @@ parse_for_member(struct datatype_member *dm, ulong flag)
sprintf(lookfor2, " %s[", s);
next_item:
while (fgets(buf, BUFSIZE, pc->tmpfile)) {
- if (embed && (count_leading_spaces(buf) == embed))
+ if ((embed && (count_leading_spaces(buf) == embed)) ||
+ (strstr(buf, "}}") && embed == count_leading_spaces(buf) - 2))
embed = 0;
if (!on && !embed && strstr(buf, "= {") && !strstr(buf, lookfor1))
@@ -7940,6 +7941,11 @@ next_item:
!strstr(buf, "}")) || (buf[0] == '}')) {
break;
}
+ if (indent && (on > 1) && indent == count_leading_spaces(buf) - 2 &&
+ strstr(buf, "}}")) {
+ fprintf(pc->saved_fp, "%s", buf);
+ break;
+ }
if (!indent) {
if ((p1 = strstr(buf, ", \n")))
sprintf(p1, "\n");
--
2.17.2
3 years, 5 months
[PATCH] crash extension: trace
by Wengang Wang
>From a UEK5 vmcore, I see that
crash> p &__start___trace_bprintk_fmt
$1 = (const char *(*)[]) 0xffffffffa163f1d0
crash> p &__stop___trace_bprintk_fmt
$2 = (const char *(*)[]) 0xffffffffa163f1f0
so (0xffffffffa163f1f0 - 0xffffffffa163f1d0)/8 = 4.
there are two zero addresses at index 2 and 3.
crash> rd __start___trace_bprintk_fmt 4
ffffffffa163f1d0: ffffffffa11ccdca ffffffffa11ccdca ................
ffffffffa163f1e0: 0000000000000000 0000000000000000 ................
current implementation will fail (no output for trace show command)
on seeing the zero addresses.
fix: ignore zero addresses in add_print_address.
tested to be good (compared the ftrace log from vmcore and that from live system).
Signed-off-by: Wengang Wang <wen.gang.wang(a)oracle.com>
---
extensions/trace.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/extensions/trace.c b/extensions/trace.c
index c26b6c7..491e4eb 100644
--- a/extensions/trace.c
+++ b/extensions/trace.c
@@ -2226,6 +2226,8 @@ static int add_print_address(long address)
size_t len;
int i;
+ if (!address)
+ return 0;
len = read_string(address, string, sizeof(string));
if (!len)
return -1;
--
1.8.3.1
3 years, 5 months
[PATCH] arm64: store phy_offset and memstart_addr separately
by Pingfan Liu
With kernel commit 7bc1a0f9e176 ("arm64: mm: use single quantity to
represent the PA to VA translation"), memstart_addr can be negative,
which makes it different from real phy_offset.
In crash utility, PTOV() needs memstart_addr, while getting PFN offset
in a dumpfile, phy_offset is required. So storing them separately for
different purpose.
Signed-off-by: Pingfan Liu <piliu(a)redhat.com>
Cc: Lianbo Jiang <lijiang(a)redhat.com>
To: crash-utility(a)redhat.com
---
arm64.c | 22 +++++++++++++++++++---
defs.h | 1 +
2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/arm64.c b/arm64.c
index 37aed07..e560d07 100644
--- a/arm64.c
+++ b/arm64.c
@@ -687,6 +687,7 @@ arm64_dump_machdep_table(ulong arg)
fprintf(fp, " kimage_voffset: %016lx\n", ms->kimage_voffset);
}
fprintf(fp, " phys_offset: %lx\n", ms->phys_offset);
+ fprintf(fp, " memstart_addr: %lx\n", ms->memstart_addr);
fprintf(fp, "__exception_text_start: %lx\n", ms->__exception_text_start);
fprintf(fp, " __exception_text_end: %lx\n", ms->__exception_text_end);
fprintf(fp, " __irqentry_text_start: %lx\n", ms->__irqentry_text_start);
@@ -987,7 +988,7 @@ arm64_calc_physvirt_offset(void)
ulong physvirt_offset;
struct syment *sp;
- ms->physvirt_offset = ms->phys_offset - ms->page_offset;
+ ms->physvirt_offset = ms->memstart_addr - ms->page_offset;
if ((sp = kernel_symbol_search("physvirt_offset")) &&
machdep->machspec->kimage_voffset) {
@@ -1028,7 +1029,11 @@ arm64_calc_phys_offset(void)
ms->kimage_voffset && (sp = kernel_symbol_search("memstart_addr"))) {
if (pc->flags & PROC_KCORE) {
if ((string = pc->read_vmcoreinfo("NUMBER(PHYS_OFFSET)"))) {
- ms->phys_offset = htol(string, QUIET, NULL);
+ ms->memstart_addr = htol(string, QUIET, NULL);
+ if (ms->memstart_addr < 0)
+ ms->phys_offset = ms->memstart_addr + 0xffff000000000000 - 0xfff0000000000000;
+ else
+ ms->phys_offset = ms->memstart_addr;
free(string);
return;
}
@@ -1080,7 +1085,18 @@ arm64_calc_phys_offset(void)
} else if (DISKDUMP_DUMPFILE() && diskdump_phys_base(&phys_offset)) {
ms->phys_offset = phys_offset;
} else if (KDUMP_DUMPFILE() && arm64_kdump_phys_base(&phys_offset)) {
- ms->phys_offset = phys_offset;
+ /*
+ * When running a 52bits kernel on 48bits hardware. Kernel plays a trick:
+ * if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52) && (vabits_actual != 52))
+ * memstart_addr -= _PAGE_OFFSET(48) - _PAGE_OFFSET(52);
+ *
+ * In crash, this should be detected to get a real physical start address.
+ */
+ ms->memstart_addr = phys_offset;
+ if ((long)phys_offset < 0)
+ ms->phys_offset = phys_offset + 0xffff000000000000 - 0xfff0000000000000;
+ else
+ ms->phys_offset = phys_offset;
} else {
error(WARNING,
"phys_offset cannot be determined from the dumpfile.\n");
diff --git a/defs.h b/defs.h
index 35b983a..64f2bcb 100644
--- a/defs.h
+++ b/defs.h
@@ -3290,6 +3290,7 @@ struct machine_specific {
ulong modules_vaddr;
ulong modules_end;
ulong phys_offset;
+ long memstart_addr;
ulong __exception_text_start;
ulong __exception_text_end;
struct arm64_pt_regs *panic_task_regs;
--
2.29.2
3 years, 5 months
[PATCH v2 17/17] MIPS64: Add mips64 architecture support information
by Youling Tang
Add mips64 architecture support information to the README and help.c files.
Signed-off-by: Huacai Chen <chenhuacai(a)loongson.cn>
Signed-off-by: Youling Tang <tangyouling(a)loongson.cn>
---
v1 -> v2:
- New patch.
README | 4 ++--
help.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/README b/README
index d4a8309..936737f 100644
--- a/README
+++ b/README
@@ -37,8 +37,8 @@
These are the current prerequisites:
o At this point, x86, ia64, x86_64, ppc64, ppc, arm, arm64, alpha, mips,
- s390 and s390x-based kernels are supported. Other architectures may be
- addressed in the future.
+ mips64, s390 and s390x-based kernels are supported. Other architectures
+ may be addressed in the future.
o One size fits all -- the utility can be run on any Linux kernel version
version dating back to 2.2.5-15. A primary design goal is to always
diff --git a/help.c b/help.c
index 531f50a..bd41466 100644
--- a/help.c
+++ b/help.c
@@ -9320,8 +9320,8 @@ char *README[] = {
" These are the current prerequisites: ",
"",
" o At this point, x86, ia64, x86_64, ppc64, ppc, arm, arm64, alpha, mips,",
-" s390 and s390x-based kernels are supported. Other architectures may be",
-" addressed in the future.",
+" mips64, s390 and s390x-based kernels are supported. Other architectures",
+" may be addressed in the future.",
"",
" o One size fits all -- the utility can be run on any Linux kernel version",
" version dating back to 2.2.5-15. A primary design goal is to always",
--
2.1.0
3 years, 5 months
[PATCH v2 16/17] MIPS64: Add 'help -r' command support
by Youling Tang
Add support form printing out the registers from the dump file. We don't
take the registers directly from the ELF notes but instead use the version
we've saved into the machine_specific structure. If we don't do this,
we'd get misleading output when the number of ELF notes don't match the
number of online CPUs.
E.g. Without this patch:
crash> help -r
help: -r option not supported for this dumpfile
E.g. With this patch:
crash> help -r
...
CPU 3:
R0: 0000000000000000 R1: 0000000000000001 R2: 9800000254f3c400
R3: 0000000000000000 R4: ffffffff8123b6b0 R5: 0000000000000000
R6: 9800000243bcf200 R7: fffffffffffffff8 R8: fffffffffffffffd
R9: 00180000000000ff R10: ffffffff810e29a8 R11: ffffffff80e84190
R12: 000000005400cce0 R13: 0000000000000000 R14: 0000000000000040
R15: 6e69636e79732074 R16: ffffffff81200000 R17: ffffffff81240000
R18: 0000000000000000 R19: ffffffff81430000 R20: 980000024291f938
R21: 0000000000000001 R22: 980000024aef7320 R23: ffffffff81430000
R24: 0000000000000002 R25: ffffffff80878b58 R26: 0000000000000000
R27: 0000000000000000 R28: 980000024291c000 R29: 980000024291f930
R30: 9800000243bcf200 R31: ffffffff802fff00
LO: ffffffff81210000 HI: ffffffff81210000
EPC: ffffffff802fff84 BADVADDR: ffffffff802bbe9c
STATUS: ffffffff81430000 CAUSE: 9800000243bcf200
Signed-off-by: Huacai Chen <chenhuacai(a)loongson.cn>
Signed-off-by: Youling Tang <tangyouling(a)loongson.cn>
---
v1 -> v2:
- Add the use of MIPS64 (MACHINE_TYPE).
diskdump.c | 11 ++++++++--
mips64.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netdump.c | 4 +++-
3 files changed, 82 insertions(+), 3 deletions(-)
diff --git a/diskdump.c b/diskdump.c
index 3726c9d..3853b2b 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2486,6 +2486,12 @@ diskdump_display_regs(int cpu, FILE *ofp)
UINT(user_regs + OFFSET(user_regs_struct_eflags))
);
}
+
+ if (machine_type("MIPS"))
+ mips_display_regs_from_elf_notes(cpu, ofp);
+
+ if (machine_type("MIPS64"))
+ mips64_display_regs_from_elf_notes(cpu, ofp);
}
void
@@ -2494,8 +2500,9 @@ dump_registers_for_compressed_kdump(void)
int c;
if (!KDUMP_CMPRS_VALID() || (dd->header->header_version < 4) ||
- !(machine_type("X86") || machine_type("X86_64") ||
- machine_type("ARM64") || machine_type("PPC64")))
+ !(machine_type("X86") || machine_type("X86_64") ||
+ machine_type("ARM64") || machine_type("PPC64") ||
+ machine_type("MIPS") || machine_type("MIPS64")))
error(FATAL, "-r option not supported for this dumpfile\n");
if (machine_type("ARM64") && (kt->cpus != dd->num_prstatus_notes))
diff --git a/mips64.c b/mips64.c
index 95f198f..62ed799 100644
--- a/mips64.c
+++ b/mips64.c
@@ -1277,9 +1277,79 @@ mips64_init(int when)
}
}
+/*
+ * 'help -r' command output
+ */
void
mips64_display_regs_from_elf_notes(int cpu, FILE *ofp)
{
+ const struct machine_specific *ms = machdep->machspec;
+ struct mips64_register *regs;
+
+ if (!ms->crash_task_regs) {
+ error(INFO, "registers not collected for cpu %d\n", cpu);
+ return;
+ }
+
+ regs = &ms->crash_task_regs[cpu];
+ if (!regs->regs[MIPS64_EF_R29] && !regs->regs[MIPS64_EF_CP0_EPC]) {
+ error(INFO, "registers not collected for cpu %d\n", cpu);
+ return;
+ }
+
+ fprintf(ofp,
+ " R0: %016lx R1: %016lx R2: %016lx\n"
+ " R3: %016lx R4: %016lx R5: %016lx\n"
+ " R6: %016lx R7: %016lx R8: %016lx\n"
+ " R9: %016lx R10: %016lx R11: %016lx\n"
+ " R12: %016lx R13: %016lx R14: %016lx\n"
+ " R15: %016lx R16: %016lx R17: %016lx\n"
+ " R18: %016lx R19: %016lx R20: %016lx\n"
+ " R21: %016lx R22: %016lx R23: %016lx\n"
+ " R24: %016lx R25: %016lx R26: %016lx\n"
+ " R27: %016lx R28: %016lx R29: %016lx\n"
+ " R30: %016lx R31: %016lx\n"
+ " LO: %016lx HI: %016lx\n"
+ " EPC: %016lx BADVADDR: %016lx\n"
+ " STATUS: %016lx CAUSE: %016lx\n",
+ regs->regs[MIPS64_EF_R0],
+ regs->regs[MIPS64_EF_R0 + 1],
+ regs->regs[MIPS64_EF_R0 + 2],
+ regs->regs[MIPS64_EF_R0 + 3],
+ regs->regs[MIPS64_EF_R0 + 4],
+ regs->regs[MIPS64_EF_R0 + 5],
+ regs->regs[MIPS64_EF_R0 + 6],
+ regs->regs[MIPS64_EF_R0 + 7],
+ regs->regs[MIPS64_EF_R0 + 8],
+ regs->regs[MIPS64_EF_R0 + 9],
+ regs->regs[MIPS64_EF_R0 + 10],
+ regs->regs[MIPS64_EF_R0 + 11],
+ regs->regs[MIPS64_EF_R0 + 12],
+ regs->regs[MIPS64_EF_R0 + 13],
+ regs->regs[MIPS64_EF_R0 + 14],
+ regs->regs[MIPS64_EF_R0 + 15],
+ regs->regs[MIPS64_EF_R0 + 16],
+ regs->regs[MIPS64_EF_R0 + 17],
+ regs->regs[MIPS64_EF_R0 + 18],
+ regs->regs[MIPS64_EF_R0 + 19],
+ regs->regs[MIPS64_EF_R0 + 20],
+ regs->regs[MIPS64_EF_R0 + 21],
+ regs->regs[MIPS64_EF_R0 + 22],
+ regs->regs[MIPS64_EF_R0 + 23],
+ regs->regs[MIPS64_EF_R0 + 24],
+ regs->regs[MIPS64_EF_R0 + 25],
+ regs->regs[MIPS64_EF_R0 + 26],
+ regs->regs[MIPS64_EF_R0 + 27],
+ regs->regs[MIPS64_EF_R0 + 28],
+ regs->regs[MIPS64_EF_R0 + 29],
+ regs->regs[MIPS64_EF_R0 + 30],
+ regs->regs[MIPS64_EF_R0 + 31],
+ regs->regs[MIPS64_EF_LO],
+ regs->regs[MIPS64_EF_HI],
+ regs->regs[MIPS64_EF_CP0_EPC],
+ regs->regs[MIPS64_EF_CP0_BADVADDR],
+ regs->regs[MIPS64_EF_CP0_STATUS],
+ regs->regs[MIPS64_EF_CP0_CAUSE]);
}
#else /* !MIPS64 */
diff --git a/netdump.c b/netdump.c
index d08f3ca..7238c92 100644
--- a/netdump.c
+++ b/netdump.c
@@ -2923,6 +2923,8 @@ display_regs_from_elf_notes(int cpu, FILE *ofp)
UINT(user_regs + sizeof(ulong) * 34));
} else if (machine_type("MIPS")) {
mips_display_regs_from_elf_notes(cpu, ofp);
+ } else if (machine_type("MIPS64")) {
+ mips64_display_regs_from_elf_notes(cpu, ofp);
}
}
@@ -2933,7 +2935,7 @@ dump_registers_for_elf_dumpfiles(void)
if (!(machine_type("X86") || machine_type("X86_64") ||
machine_type("ARM64") || machine_type("PPC64") ||
- machine_type("MIPS")))
+ machine_type("MIPS") || machine_type("MIPS64")))
error(FATAL, "-r option not supported for this dumpfile\n");
if (NETDUMP_DUMPFILE()) {
--
2.1.0
3 years, 5 months
[PATCH 07/16] MIPS: Fix display memory size issue
by Youling Tang
"__node_data" instead of "node_data" is used in the MIPS architecture,
so "__node_data" is used to replace "node_data" to improve the use of
next_online_pgdat() functions in the MIPS architecture.
E.g. Without this patch:
...
MEMORY: 0
...
With this patch:
...
MEMORY: 7.5 GB
...
Signed-off-by: Huacai Chen <chenhuacai(a)loongson.cn>
Signed-off-by: Youling Tang <tangyouling(a)loongson.cn>
---
memory.c | 28 ++++++++++++++++++----------
1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/memory.c b/memory.c
index 33b0ca7..5347958 100644
--- a/memory.c
+++ b/memory.c
@@ -17820,22 +17820,28 @@ next_online_pgdat(int node)
char buf[BUFSIZE];
ulong pgdat;
+#ifndef __mips__
+#define NODE_DATA_VAR "node_data"
+#else
+#define NODE_DATA_VAR "__node_data"
+#endif
+
/*
- * Default -- look for type: struct pglist_data node_data[]
+ * Default -- look for type: node_data[]/__node_data[]
*/
if (LKCD_KERNTYPES()) {
- if (!kernel_symbol_exists("node_data"))
+ if (!kernel_symbol_exists(NODE_DATA_VAR))
goto pgdat2;
/*
- * Just index into node_data[] without checking that it is
- * an array; kerntypes have no such symbol information.
+ * Just index into node_data[]/__node_data[] without checking that
+ * it is an array; kerntypes have no such symbol information.
*/
} else {
- if (get_symbol_type("node_data", NULL, NULL) != TYPE_CODE_ARRAY)
+ if (get_symbol_type(NODE_DATA_VAR, NULL, NULL) != TYPE_CODE_ARRAY)
goto pgdat2;
open_tmpfile();
- sprintf(buf, "whatis node_data");
+ sprintf(buf, "whatis " NODE_DATA_VAR);
if (!gdb_pass_through(buf, fp, GNU_RETURN_ON_ERROR)) {
close_tmpfile();
goto pgdat2;
@@ -17848,14 +17854,15 @@ next_online_pgdat(int node)
close_tmpfile();
if ((!strstr(buf, "struct pglist_data *") &&
- !strstr(buf, "pg_data_t *")) ||
+ !strstr(buf, "pg_data_t *") &&
+ !strstr(buf, "struct node_data *")) ||
(count_chars(buf, '[') != 1) ||
(count_chars(buf, ']') != 1))
goto pgdat2;
}
- if (!readmem(symbol_value("node_data") + (node * sizeof(void *)),
- KVADDR, &pgdat, sizeof(void *), "node_data", RETURN_ON_ERROR) ||
+ if (!readmem(symbol_value(NODE_DATA_VAR) + (node * sizeof(void *)),
+ KVADDR, &pgdat, sizeof(void *), NODE_DATA_VAR, RETURN_ON_ERROR) ||
!IS_KVADDR(pgdat))
goto pgdat2;
@@ -17883,7 +17890,8 @@ pgdat2:
close_tmpfile();
if ((!strstr(buf, "struct pglist_data *") &&
- !strstr(buf, "pg_data_t *")) ||
+ !strstr(buf, "pg_data_t *") &&
+ !strstr(buf, "struct node_data *")) ||
(count_chars(buf, '[') != 1) ||
(count_chars(buf, ']') != 1))
goto pgdat3;
--
2.1.0
3 years, 5 months