Update gdb to 10.1
by Alexey Makhalov
Hi all,
I’m thinking to update gdb to recent version.
Are there any concerns?
What should I know? Any dependencies which force us to stick to 7.6?
The features I’m aiming are:
1) `offset` support in add-symbol-file, can be used to provide kaslr_offset to gdb
2) remove-symbol-file - can be used to remove original symbols after finding kaslr_offset
My high-level goal is to give gdb more resources (access to registers, memory, machine info - such as number CPUs), so we can use useful gdb commands as:
bt, frame, info locals
Thanks,
—Alexey
3 years, 2 months
[PATCH] MIPS64: Get the correct dump NOTE offsets
by Youling Tang
When using the dump compressed file dumpfile compressed by makedumpfile,
use the following command:
# crash vmlinux dumpfile -d 1
When you add the "-d num" option and want to view the debugging information,
it is found that you cannot enter the crash> command line normally, and stay
in the following position:
...
notes[3]: 20ec075fc (NT_PRSTATUS)
snapshot_task: 0
num_qemu_notes: 0
The reason is that it is stuck in the dump_note_offsets(fp) call, because the
MIPS64 match is not added, so that the NOTE offsets cannot be obtained.
When the match of MIPS64 is added, it can successfully enter the crash> command
line.
Signed-off-by: Youling Tang <tangyouling(a)loongson.cn>
---
diskdump.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/diskdump.c b/diskdump.c
index 3effb52..6680695 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -1700,7 +1700,7 @@ dump_note_offsets(FILE *fp)
qemu = FALSE;
if (machine_type("X86_64") || machine_type("S390X") ||
machine_type("ARM64") || machine_type("PPC64") ||
- machine_type("SPARC64")) {
+ machine_type("SPARC64") || machine_type("MIPS64")) {
note64 = (void *)dd->notes_buf + tot;
len = sizeof(Elf64_Nhdr);
if (STRNEQ((char *)note64 + len, "QEMU"))
--
2.1.0
3 years, 3 months
[PATCH 0/3] Some minor modifications
by Youling Tang
Youling Tang (3):
defs.h: Fix the value of TIF_SIGPENDING macro
MIPS64: Modify the comment of mips64_register structure
MIPS64: Add support for ramdump type
defs.h | 18 +++++++++---------
ramdump.c | 2 +-
2 files changed, 10 insertions(+), 10 deletions(-)
--
2.1.0
3 years, 3 months
[PATCH] MIPS32/64: Add 'irq' command support
by Youling Tang
Added support for the 'irq' series of commands in the MIPS32/64 architecture,
except for the 'irq -d' command, others can be used.
The result of using the 'irq' command without this patch is as follows:
irq: cannot determine number of IRQs
Signed-off-by: Youling Tang <tangyouling(a)loongson.cn>
---
mips.c | 10 ++++++++--
mips64.c | 14 ++++++++++++++
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/mips.c b/mips.c
index f73dfad..d6602e3 100644
--- a/mips.c
+++ b/mips.c
@@ -1126,8 +1126,14 @@ mips_init(int when)
machdep->get_irq_affinity = generic_get_irq_affinity;
machdep->section_size_bits = _SECTION_SIZE_BITS;
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
- ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc,
- "irq_desc", NULL, 0);
+
+ if (symbol_exists("irq_desc"))
+ ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc,
+ "irq_desc", NULL, 0);
+ else if (kernel_symbol_exists("nr_irqs"))
+ get_symbol_data("nr_irqs", sizeof(unsigned int),
+ &machdep->nr_irqs);
+
mips_stackframe_init();
if (!machdep->hz)
diff --git a/mips64.c b/mips64.c
index 62ed799..b1d6acf 100644
--- a/mips64.c
+++ b/mips64.c
@@ -1160,6 +1160,9 @@ mips64_dump_machdep_table(ulong arg)
fprintf(fp, " is_task_addr: mips64_is_task_addr()\n");
fprintf(fp, " verify_symbol: mips64_verify_symbol()\n");
fprintf(fp, " dis_filter: generic_dis_filter()\n");
+ fprintf(fp, " dump_irq: generic_dump_irq()\n");
+ fprintf(fp, " show_interrupts: generic_show_interrupts()\n");
+ fprintf(fp, " get_irq_affinity: generic_get_irq_affinity()\n");
fprintf(fp, " cmd_mach: mips64_cmd_mach()\n");
fprintf(fp, " get_smp_cpus: mips64_get_smp_cpus()\n");
fprintf(fp, " is_kvaddr: generic_is_kvaddr()\n");
@@ -1246,6 +1249,9 @@ mips64_init(int when)
machdep->is_task_addr = mips64_is_task_addr;
machdep->get_smp_cpus = mips64_get_smp_cpus;
machdep->dis_filter = generic_dis_filter;
+ machdep->dump_irq = generic_dump_irq;
+ machdep->show_interrupts = generic_show_interrupts;
+ machdep->get_irq_affinity = generic_get_irq_affinity;
machdep->value_to_symbol = generic_machdep_value_to_symbol;
machdep->init_kernel_pgd = NULL;
break;
@@ -1257,6 +1263,14 @@ mips64_init(int when)
mips64_stackframe_init();
if (!machdep->hz)
machdep->hz = 250;
+
+ if (symbol_exists("irq_desc"))
+ ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc,
+ "irq_desc", NULL, 0);
+ else if (kernel_symbol_exists("nr_irqs"))
+ get_symbol_data("nr_irqs", sizeof(unsigned int),
+ &machdep->nr_irqs);
+
MEMBER_OFFSET_INIT(elf_prstatus_pr_reg, "elf_prstatus",
"pr_reg");
STRUCT_SIZE_INIT(note_buf, "note_buf_t");
--
2.1.0
3 years, 3 months
[PATCH v2 1/2] arm64: add tag_mask machdep option
by Vinayak Menon
Raw ramdumps without vmcoreinfo does not work currently
with pointer authentication 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 mask the tags when PAC is enabled.
Signed-off-by: Vinayak Menon <vinayakm.list(a)gmail.com>
---
arm64.c | 20 +++++++++++++++-----
crash.8 | 1 +
defs.h | 1 +
help.c | 1 +
4 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/arm64.c b/arm64.c
index 37aed07..5b59972 100644
--- a/arm64.c
+++ b/arm64.c
@@ -763,6 +763,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_mask")) {
+ *value = htol(p, flags, &err);
} else if (megabytes) {
*value = dtol(p, flags, &err);
if (!err)
@@ -796,7 +798,6 @@ arm64_parse_cmdline_args(void)
for (index = 0; index < MAX_MACHDEP_ARGS; index++) {
if (!machdep->cmdline_args[index])
break;
-
if (!strstr(machdep->cmdline_args[index], "=")) {
error(WARNING, "ignoring --machdep option: %x\n",
machdep->cmdline_args[index]);
@@ -838,6 +839,12 @@ 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_mask",
+ &machdep->machspec->tag_mask)) {
+ error(NOTE,
+ "setting tag_mask to: %lx\n\n",
+ machdep->machspec->tag_mask);
+ continue;
}
error(WARNING, "ignoring --machdep option: %s\n",
@@ -4124,16 +4131,19 @@ arm64_swp_offset(ulong pte)
static void arm64_calc_KERNELPACMASK(void)
{
- ulong value;
+ ulong value = 0;
char *string;
if ((string = pc->read_vmcoreinfo("NUMBER(KERNELPACMASK)"))) {
value = htol(string, QUIET, NULL);
free(string);
- machdep->machspec->CONFIG_ARM64_KERNELPACMASK = value;
- if (CRASHDEBUG(1))
- fprintf(fp, "CONFIG_ARM64_KERNELPACMASK: %lx\n", value);
+ } else if (machdep->machspec->tag_mask) {
+ value = machdep->machspec->tag_mask;
}
+
+ machdep->machspec->CONFIG_ARM64_KERNELPACMASK = value;
+ if (CRASHDEBUG(1))
+ fprintf(fp, "CONFIG_ARM64_KERNELPACMASK: %lx\n", value);
}
#endif /* ARM64 */
diff --git a/crash.8 b/crash.8
index 5020ce1..de32bdb 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_mask=<value>
X86:
page_offset=<CONFIG_PAGE_OFFSET-value>
.fi
diff --git a/defs.h b/defs.h
index 35b983a..d406f5f 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_mask;
};
struct arm64_stackframe {
diff --git a/help.c b/help.c
index 531f50a..7f619d5 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_mask=<value>",
" X86:",
" page_offset=<CONFIG_PAGE_OFFSET-value>",
"",
3 years, 3 months
[PATCH 1/1] tools: list: create O option for specifying head node offset
by Firo Yang
This new O option is very useful to specify the head node
offset for listing linked list whose head node embedded has a
different offset to other node, e.g. dentry.d_subdirs(the head node)
and dentry.d_child.
Signed-off-by: Firo Yang <firo.yang(a)suse.com>
---
defs.h | 1 +
help.c | 12 +++++++++++-
tools.c | 30 +++++++++++++++++++++++++++---
3 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/defs.h b/defs.h
index 35b983a..764facf 100644
--- a/defs.h
+++ b/defs.h
@@ -2605,6 +2605,7 @@ struct list_data { /* generic structure used by do_list() to walk */
#define LIST_PARSE_MEMBER (VERBOSE << 13)
#define LIST_READ_MEMBER (VERBOSE << 14)
#define LIST_BRENT_ALGO (VERBOSE << 15)
+#define LIST_HEAD_OFFSET_ENTERED (VERBOSE << 16)
struct tree_data {
ulong flags;
diff --git a/help.c b/help.c
index 531f50a..b561f3b 100644
--- a/help.c
+++ b/help.c
@@ -5716,7 +5716,7 @@ char *help__list[] = {
"list",
"linked list",
"[[-o] offset][-e end][-[s|S] struct[.member[,member] [-l offset]] -[x|d]]"
-"\n [-r|-B] [-h|-H] start",
+"\n [-r|-B] [-h [-O head_offset]|-H] start",
" ",
" This command dumps the contents of a linked list. The entries in a linked",
" list are typically data structures that are tied together in one of two",
@@ -5800,6 +5800,16 @@ char *help__list[] = {
" -S struct Similar to -s, but instead of parsing gdb output, member values",
" are read directly from memory, so the command works much faster",
" for 1-, 2-, 4-, and 8-byte members.",
+" -O offset The -O option works only with -h option.",
+" It is used for specifying the offset of head node embedded in a",
+" structure, like dentry.d_subdirs or cgroup_subsys_state.children.",
+" The offset may be entered in either of two manners:",
+"",
+" 1. \"structure.member\" format.",
+" 2. a number of bytes.",
+"",
+" You can use it like the following:",
+" list -O <head node offset> -o <node offset> -h start -s <...>",
" -l offset Only used in conjunction with -s, if the start address argument",
" is a pointer to an embedded list head (or any other similar list",
" linkage structure whose first member points to the next linkage",
diff --git a/tools.c b/tools.c
index a26b101..792a567 100644
--- a/tools.c
+++ b/tools.c
@@ -3343,6 +3343,7 @@ void
cmd_list(void)
{
int c;
+ long head_member_offset; /* offset for head like denty.d_subdirs */
struct list_data list_data, *ld;
struct datatype_member struct_member, *sm;
struct syment *sp;
@@ -3353,7 +3354,7 @@ cmd_list(void)
BZERO(ld, sizeof(struct list_data));
struct_list_offset = 0;
- while ((c = getopt(argcnt, args, "BHhrs:S:e:o:xdl:")) != EOF) {
+ while ((c = getopt(argcnt, args, "BHhrs:S:e:o:O:xdl:")) != EOF) {
switch(c)
{
case 'B':
@@ -3394,6 +3395,24 @@ cmd_list(void)
optarg);
break;
+ case 'O':
+ if (ld->flags & LIST_HEAD_OFFSET_ENTERED)
+ error(FATAL,
+ "offset value %d (0x%lx) already entered\n",
+ head_member_offset, head_member_offset);
+ else if (IS_A_NUMBER(optarg))
+ head_member_offset = stol(optarg,
+ FAULT_ON_ERROR, NULL);
+ else if (arg_to_datatype(optarg,
+ sm, RETURN_ON_ERROR) > 1)
+ head_member_offset = sm->member_offset;
+ else
+ error(FATAL, "invalid -O argument: %s\n",
+ optarg);
+
+ ld->flags |= LIST_HEAD_OFFSET_ENTERED;
+ break;
+
case 'o':
if (ld->flags & LIST_OFFSET_ENTERED)
error(FATAL,
@@ -3599,8 +3618,13 @@ next_arg:
fprintf(fp, "(empty)\n");
return;
}
- } else
- ld->start += ld->list_head_offset;
+ } else {
+ if (ld->flags & LIST_HEAD_OFFSET_ENTERED)
+ readmem(ld->start + head_member_offset, KVADDR,
+ &ld->start, sizeof(void *), "LIST_HEAD contents", FAULT_ON_ERROR);
+ else
+ ld->start += ld->list_head_offset;
+ }
}
ld->flags &= ~(LIST_OFFSET_ENTERED|LIST_START_ENTERED);
--
2.30.2
3 years, 3 months
Re: [Crash-utility] [PATCH 2/2] arm64: make crash CONFIG_KASAN_HW_TAGS aware
by lijiang
Hi, Vinayak
在 2021年03月31日 00:00, crash-utility-request(a)redhat.com 写道:
> Date: Tue, 30 Mar 2021 19:22:35 +0530
> From: Vinayak Menon <vinayakm.list(a)gmail.com>
> To: crash-utility(a)redhat.com
> Subject: [Crash-utility] [PATCH 2/2] arm64: make crash
> CONFIG_KASAN_HW_TAGS aware
> Message-ID:
> <1617112355-19837-2-git-send-email-vinayakm.list(a)gmail.com>
> Content-Type: text/plain; charset="US-ASCII"
>
> With CONFIG_KASAN_HW_TAGS enabled kvaddr can be tagged
> and this results in readmem, vtop etc. fail like below.
>
> "
> please wait... (gathering kmem slab cache data)
> crash: invalid kernel virtual address: f0ffff878000201c type: "kmem_cache objsize/object_size"
> crash: get_active_set: no tasks found?
> please wait... (gathering task table data)
> crash: invalid kernel virtual address: f1ffff87f51e3530 type: "xa_node shift"
> "
>
> Make the mask introduced for pointer authentication generic
> and use it in vtop and kvaddr validation.
>
> Signed-off-by: Vinayak Menon <vinayakm.list(a)gmail.com>
> ---
> arm64.c | 50 +++++++++++++++++++++++++++++++-------------------
> defs.h | 2 +-
> 2 files changed, 32 insertions(+), 20 deletions(-)
>
> diff --git a/arm64.c b/arm64.c
> index 5b59972..bb41cbb 100644
> --- a/arm64.c
> +++ b/arm64.c
> @@ -85,7 +85,8 @@ static int arm64_get_kvaddr_ranges(struct vaddr_range *);
> static void arm64_get_crash_notes(void);
> 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_is_kvaddr(ulong);
> +static void arm64_calc_KERNELTAGMASK(void);
>
>
> /*
> @@ -215,7 +216,7 @@ arm64_init(int when)
> machdep->pagemask = ~((ulonglong)machdep->pageoffset);
>
> arm64_calc_VA_BITS();
> - arm64_calc_KERNELPACMASK();
> + arm64_calc_KERNELTAGMASK();
> ms = machdep->machspec;
> if (ms->VA_BITS_ACTUAL) {
> ms->page_offset = ARM64_PAGE_OFFSET_ACTUAL;
> @@ -228,7 +229,7 @@ arm64_init(int when)
> machdep->kvbase = ARM64_VA_START;
> ms->userspace_top = ARM64_USERSPACE_TOP;
> }
> - machdep->is_kvaddr = generic_is_kvaddr;
> + machdep->is_kvaddr = arm64_is_kvaddr;
> machdep->kvtop = arm64_kvtop;
> if (machdep->flags & NEW_VMEMMAP) {
> struct syment *sp;
> @@ -477,7 +478,7 @@ arm64_init(int when)
> case LOG_ONLY:
> machdep->machspec = &arm64_machine_specific;
> arm64_calc_VA_BITS();
> - arm64_calc_KERNELPACMASK();
> + arm64_calc_KERNELTAGMASK();
> arm64_calc_phys_offset();
> machdep->machspec->page_offset = ARM64_PAGE_OFFSET;
> arm64_calc_physvirt_offset();
> @@ -608,7 +609,7 @@ arm64_dump_machdep_table(ulong arg)
> fprintf(fp, " dis_filter: arm64_dis_filter()\n");
> fprintf(fp, " cmd_mach: arm64_cmd_mach()\n");
> fprintf(fp, " get_smp_cpus: arm64_get_smp_cpus()\n");
> - fprintf(fp, " is_kvaddr: generic_is_kvaddr()\n");
> + fprintf(fp, " is_kvaddr: arm64_is_kvaddr()\n");
> fprintf(fp, " is_uvaddr: arm64_is_uvaddr()\n");
> fprintf(fp, " value_to_symbol: generic_machdep_value_to_symbol()\n");
> fprintf(fp, " init_kernel_pgd: arm64_init_kernel_pgd\n");
> @@ -668,9 +669,9 @@ arm64_dump_machdep_table(ulong arg)
> fprintf(fp, "%ld\n", ms->VA_BITS_ACTUAL);
> else
> fprintf(fp, "(unused)\n");
> - fprintf(fp, "CONFIG_ARM64_KERNELPACMASK: ");
> - if (ms->CONFIG_ARM64_KERNELPACMASK)
> - fprintf(fp, "%lx\n", ms->CONFIG_ARM64_KERNELPACMASK);
> + fprintf(fp, "CONFIG_ARM64_KERNELTAGMASK: ");
> + if (ms->CONFIG_ARM64_KERNELTAGMASK)
> + fprintf(fp, "%lx\n", ms->CONFIG_ARM64_KERNELTAGMASK);
> else
> fprintf(fp, "(unused)\n");
> fprintf(fp, " userspace_top: %016lx\n", ms->userspace_top);
> @@ -1208,6 +1209,9 @@ arm64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbos
> if (!IS_KVADDR(kvaddr))
> return FALSE;
>
> + if (kvaddr & (1UL << 63))
> + kvaddr |= machdep->machspec->CONFIG_ARM64_KERNELTAGMASK;
> +
> if (!vt->vmalloc_start) {
> *paddr = VTOP(kvaddr);
> return TRUE;
> @@ -1828,7 +1832,7 @@ arm64_is_kernel_exception_frame(struct bt_info *bt, ulong stkptr)
> if (INSTACK(regs->sp, bt) && INSTACK(regs->regs[29], bt) &&
> !(regs->pstate & (0xffffffff00000000ULL | PSR_MODE32_BIT)) &&
> is_kernel_text(regs->pc) &&
> - is_kernel_text(regs->regs[30] | ms->CONFIG_ARM64_KERNELPACMASK)) {
> + is_kernel_text(regs->regs[30] | ms->CONFIG_ARM64_KERNELTAGMASK)) {
> switch (regs->pstate & PSR_MODE_MASK)
> {
> case PSR_MODE_EL1t:
> @@ -2198,8 +2202,8 @@ arm64_unwind_frame(struct bt_info *bt, struct arm64_stackframe *frame)
> frame->sp = fp + 0x10;
> frame->fp = GET_STACK_ULONG(fp);
> frame->pc = GET_STACK_ULONG(fp + 8);
> - if (is_kernel_text(frame->pc | ms->CONFIG_ARM64_KERNELPACMASK))
> - frame->pc |= ms->CONFIG_ARM64_KERNELPACMASK;
> + if (is_kernel_text(frame->pc | ms->CONFIG_ARM64_KERNELTAGMASK))
> + frame->pc |= ms->CONFIG_ARM64_KERNELTAGMASK;
>
> if ((frame->fp == 0) && (frame->pc == 0))
> return FALSE;
> @@ -2869,8 +2873,8 @@ arm64_print_text_symbols(struct bt_info *bt, struct arm64_stackframe *frame, FIL
> for (i = (start - bt->stackbase)/sizeof(ulong); i < LONGS_PER_STACK; i++) {
> up = (ulong *)(&bt->stackbuf[i*sizeof(ulong)]);
> val = *up;
> - if (is_kernel_text(val | ms->CONFIG_ARM64_KERNELPACMASK)) {
> - val |= ms->CONFIG_ARM64_KERNELPACMASK;
> + if (is_kernel_text(val | ms->CONFIG_ARM64_KERNELTAGMASK)) {
> + val |= ms->CONFIG_ARM64_KERNELTAGMASK;
> name = closest_symbol(val);
> fprintf(ofp, " %s[%s] %s at %lx",
> bt->flags & BT_ERROR_MASK ?
> @@ -3205,8 +3209,8 @@ arm64_print_exception_frame(struct bt_info *bt, ulong pt_regs, int mode, FILE *o
> rows = 4;
> } else {
> LR = regs->regs[30];
> - if (is_kernel_text (LR | ms->CONFIG_ARM64_KERNELPACMASK))
> - LR |= ms->CONFIG_ARM64_KERNELPACMASK;
> + if (is_kernel_text (LR | ms->CONFIG_ARM64_KERNELTAGMASK))
> + LR |= ms->CONFIG_ARM64_KERNELTAGMASK;
> SP = regs->sp;
> top_reg = 29;
> is_64_bit = TRUE;
> @@ -4102,6 +4106,14 @@ arm64_calc_virtual_memory_ranges(void)
> }
>
> static int
> +arm64_is_kvaddr(ulong addr)
> +{
> + if (addr & (1UL << 63))
Here, the bit-63 indicates that the addr contains the TAG MASK, which means
the TAG is enabled, right? Or could you please describe more details about
this?
Other changes are good to me.
Thanks.
Lianbo
> + addr |= machdep->machspec->CONFIG_ARM64_KERNELTAGMASK;
> + return generic_is_kvaddr(addr);
> +}
> +
> +static int
> arm64_is_uvaddr(ulong addr, struct task_context *tc)
> {
> return (addr < machdep->machspec->userspace_top);
> @@ -4129,21 +4141,21 @@ arm64_swp_offset(ulong pte)
> return pte;
> }
>
> -static void arm64_calc_KERNELPACMASK(void)
> +static void arm64_calc_KERNELTAGMASK(void)
> {
> ulong value = 0;
> char *string;
>
> - if ((string = pc->read_vmcoreinfo("NUMBER(KERNELPACMASK)"))) {
> + if ((string = pc->read_vmcoreinfo("NUMBER(KERNELTAGMASK)"))) {
> value = htol(string, QUIET, NULL);
> free(string);
> } else if (machdep->machspec->tag_mask) {
> value = machdep->machspec->tag_mask;
> }
>
> - machdep->machspec->CONFIG_ARM64_KERNELPACMASK = value;
> + machdep->machspec->CONFIG_ARM64_KERNELTAGMASK = value;
> if (CRASHDEBUG(1))
> - fprintf(fp, "CONFIG_ARM64_KERNELPACMASK: %lx\n", value);
> + fprintf(fp, "CONFIG_ARM64_KERNELTAGMASK: %lx\n", value);
> }
>
> #endif /* ARM64 */
> diff --git a/defs.h b/defs.h
> index d406f5f..770c335 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -3329,7 +3329,7 @@ struct machine_specific {
> ulong VA_BITS_ACTUAL;
> ulong CONFIG_ARM64_VA_BITS;
> ulong VA_START;
> - ulong CONFIG_ARM64_KERNELPACMASK;
> + ulong CONFIG_ARM64_KERNELTAGMASK;
> ulong physvirt_offset;
> ulong tag_mask;
> };
3 years, 4 months
[ANNOUNCE] crash-7.3.0 is available
by HAGIO KAZUHITO(萩尾 一仁)
Download from: https://crash-utility.github.io/
or
https://github.com/crash-utility/crash/releases
The github master branch serves as a development branch that will contain
all patches that are queued for the next release:
$ git clone git://github.com/crash-utility/crash.git
Changelog:
- Add support for new lockless righbuffer that Linux 5.10 introduced.
Without the two patches, crash fails during session initialization
or "log" command fails with the error message:
crash: cannot determine length of symbol: log_end
(john.ogness(a)linutronix.de, nborisov(a)suse.com, k-hagio-ab(a)nec.com)
- Add support for VC exception stack on x86_64 Linux 5.10 and later
kernels that contain commit 02772fb9b68e ("x86/sev-es: Allocate and
map an IST stack for #VC handler").
(amakhalov(a)vmware.com)
- Fix regression for raw RAM dumpfiles. Commit f42db6a33f0e ("Support
core files with "unusual" layout") increased the minimal file size
from MIN_NETDUMP_ELF_HEADER_SIZE to SAFE_NETDUMP_ELF_HEADER_SIZE
which can lead to crash rejecting raw RAM dumpfiles. Without the
patch, the crash fails to start a session with the error message:
/var/tmp/ramdump_elf_XXXXXX: ELF header read: No such file or directory
crash: malformed ELF file: /var/tmp/ramdump_elf_XXXXXX
(zhaoqianli(a)xiaomi.com)
- Update mapping symbol filter in arm64_verify_symbol() to support the
long form of mapping symbols, e.g. "$x.<any...>". Without the
patch, the "dis" command cannot completely parse out the disassembly
of a function that has mapping symbols in the long form and misses
the tail part of the function.
(zhaoqianli(a)xiaomi.com)
- Move extensins/Makefile's ping check to recipe script. Without this
patch, in an environment where ping to github.com does not work,
"make clean" at the top-level crash directory always takes about 10
seconds unnecessarily.
(k-hagio-ab(a)nec.com)
- Fix for a segmentation fault when analyzing arm64 kernels that are
configured with CONFIG_IKCONFIG and have a strange entry that does
not contain the delimiter "=", such as "CONFIG_SECU+[some hex data]".
Without the patch, in the add_ikconfig_entry() function, strtok_r()
interprets it as consisting of a single token and the val variable
is set to NULL, and then strdup() crashes.
(liuyun01(a)kylinos.cn)
- Fix a couple of issues that were detected by valgrind.
(d.hatayama(a)fujitsu.com)
- Add ability to un-set scope. The ability can come in very useful
when running automated pykdump scripts and needing scope to be
cleared between script runs.
(jpittman(a)redhat.com)
- Fix "sys [-t]|mod -S" after "mod -t" when crash runs with -s option.
Without the patch, the "sys [-t]" and "mod -S" options after "mod -t"
option fail with the error message:
sys: invalid structure member offset: tnt_false
FILE: kernel.c LINE: 11203 FUNCTION: show_kernel_taints_v4_10()
(k-hagio-ab(a)nec.com)
- Fix for "dev -d" option on Linux 5.11-rc1 and later kernels that
contains commit 0d02129e76edf91cf04fabf1efbc3a9a1f1d729a ("block:
merge struct block_device and struct hd_struct"). Without the patch,
the option fails with the error message:
dev: invalid structure member offset: hd_struct_dev
(k-hagio-ab(a)nec.com)
- Fix for "kmem -v" option on Linux 5.11-rc1 and later kernels that
contain commit 96e2db456135db0cf2476b6890f1e8b2fdcf21eb ("mm/vmalloc:
rework the drain logic"). Without the patch, the option will display
nothing or fail with the error message:
kmem: invalid kernel virtual address: <address> type: "vmlist addr"
(k-hagio-ab(a)nec.com)
- Add the base address of module to "mod" command output. Currently
the command shows the address of the module struct, but it is
inconvenient to know the address range of the module, so extend to
show the base adddress.
(yeyunfeng(a)huawei.com, k-hagio-ab(a)nec.com)
- Increase the value of __PHYSICAL_MASK_SHIFT_XEN to 52. The former
value of __PHYSICAL_MASK_SHIFT_XEN in crash (40) is smaller than the
kernel (52) since kernel commit 6f0e8bf167 (xen: support 52 bit
physical addresses in pv guests). This can cause x86_64_pud_offset()
to lose the most significant bits of pgd_pte, leading to a failed
xen_m2p() translation, resulting in crash failing with an error
message like this:
crash: read error: physical address: ffffffffffffffff type: "pud page"
(jbohac(a)suse.cz)
- Change log level print in older kernels. In older kernels that have
the variable-length-record log_buf, the log level and the log
flags/facility are not separated. Since the log level is only the
last three bits, and the flags/facility and level are separated in
5.10 and later kernels, only print those last three bits when using
'log -m'.
(jpittman(a)redhat.com)
- Reduce crash build log. The verbose output of tar command when
extracting the GDB source files occupies more than the half of crash
build log. It is not so helpful and makes the build log longer
needlessly especially on CI build test without the patch.
(k-hagio-ab(a)nec.com)
- Fix for "bt" command on Linux 5.12-rc1 and later x86_64 kernels that
contain commit 951c2a51ae75 ("x86/irq/64: Adjust the per CPU irq
stack pointer by 8"). Without the patch, the "bt" command and some
of its options that read irq stack fail with the error message:
bt: read of stack at <address> failed".
(k-hagio-ab(a)nec.com)
- Add valgrind support for the crash's custom memory allocator. This
helps detecting various memory errors on the crash's custom memory
allocator.
(d.hatayama(a)fujitsu.com)
- Fix for a couple of invalid read/write issues detected by valgrind.
(d.hatayama(a)fujitsu.com)
- Fix "struct" command to print member array of list_heads correctly.
Without the patch, due to the way that an array of list_head entries
are printed, parsing of them fails and the command does not print
anything:
crash> struct blk_mq_ctx.rq_completed ffffc447ffc0f740
crash>
(jpittman(a)redhat.com)
- Do not pass through 'sy' command to GDB. The GDB 'symbol-file'
command is prohibited in the crash utility, but an abbreviation of
it, the 'sy' is not prohibited. This can 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
Discard symbol table from `/path/to/vmlinux'? (y or n) Please answer y or n.
Discard symbol table from `/path/to/vmlinux'? (y or n) No symbol file now.
crash> sys
double free or corruption (!prev)
Aborted (core dumped)
(lijiang(a)redhat.com)
- Refine zram related code for crash gcore command to support it.
(d.hatayama(a)fujitsu.com)
- Fix for the failure of 'set scope' command. Without the patch,
some commands such as 'sys' may cause subsequent 'set scope'
commands to fail.
(lijiang(a)redhat.com)
- Fix for offset print for function pointers that return pointers.
In the show_member_offset() function, when trying to handle function
pointers, the case for "(*" is handled. However, if the function
pointer returns a pointer or a pointer to a pointer, then the
condition is unhandled. This results in the offset not being
printed without the patch, for example:
crash> struct -o offload_callbacks
struct offload_callbacks {
struct sk_buff *(*gso_segment)(struct sk_buff *, netdev_features_t);
struct sk_buff **(*gro_receive)(struct sk_buff **, struct sk_buff *);
[16] int (*gro_complete)(struct sk_buff *, int);
}
(jpittman(a)redhat.com)
- Change functions within extensions/echo.c to be static and document
the issue in code comments, for extensions developers who takes
echo.c as reference, to avoid the issue that symbols in extension
modules are overwritten by former loaded one if it's the same name.
(ltao(a)redhat.com)
- Fix for 'bt' command and options on Linux 5.8-rc1 and later x86_64
kernels that contain merge commit 076f14be7fc9. The merged patches
changed the name of exception functions that have been used by the
crash utility to check the exception frame. Without the patch, the
command and options cannot display it.
(k-hagio-ab(a)nec.com)
- Fix for xen kernels that contain commit edcb5cf84f05
("x86/paravirt/xen: Remove xen_patch()"). Withouth the patch,
crash fails with an error message like this:
crash: seek error: physical address: 83640e000 type: "pud page"
(john.p.donnelly(a)oracle.com, k-hagio-ab(a)nec.com)
- Remove extensions/trace.c file, as the extension module moved to
the separate repository from the crash repository.
(k-hagio-ab(a)nec.com)
- Fix for uvtop conversion on ARM with LPAE. Without the patch,
arm_uvtop() calls arm_lpae_vtop() with the LPAE and it can use
LPAE_VTOP() also for a user virtual address. As a result, commands
that use uvtop conversion such as "ps -a", "gcore" fail as readmem()
for a uvaddr returns a seek error:
ps: cannot access user stack address: <address>
(k-hagio-ab(a)nec.com)
- Handle 1GB block for VM_L3_4K on arm64 architecture. Without the
patch, "vtop" command cannot display the block as a 1GB hugepage.
(johan.erlandsson(a)sony.com)
- Implement initial support for the MIP64 architecture.
(tangyouling(a)loongson.cn, chenhuacai(a)loongson.cn)
- Fix for HZ calculation using cfq_slice_async on Linux 4.8 and later
kernels that contain commit 9a7f38c42c2b ("cfq-iosched: Convert from
jiffies to nanoseconds"). Without the patch, the HZ calculation
results in a wrong and big value for machde->hz and crash can shows
a wrong uptime and timestamps in "log -T".
(martin.moore(a)hpe.com)
- Fix for HZ calculation on Linux 4.8 and later kernels that contain
commit 9a7f38c42c2b ("cfq-iosched: Convert from jiffies to
nanoseconds"). Without the patch, the HZ value can be set to a
hardcorded wrong value.
(k-hagio-ab(a)nec.com)
3 years, 4 months
[PATCHv4] crash-utility/arm64: store phy_offset and memstart_addr separately
by Pingfan Liu
Crash encounters a bug like the following:
...
SECTION_SIZE_BITS: 30
CONFIG_ARM64_VA_BITS: 52
VA_BITS_ACTUAL: 48
(calculated) VA_BITS: 48
PAGE_OFFSET: ffff000000000000
VA_START: ffff800000000000
modules: ffff800008000000 - ffff80000fffffff
vmalloc: ffff800010000000 - ffffffdfdffeffff
kernel image: ffff800010000000 - ffff800012750000
vmemmap: ffffffdfffe00000 - ffffffffffffffff
<readmem: ffff800011c53bc8, KVADDR, "nr_irqs", 4, (FOE), b47bdc>
<read_kdump: addr: ffff800011c53bc8 paddr: eb453bc8 cnt: 4>
read_netdump: addr: ffff800011c53bc8 paddr: eb453bc8 cnt: 4 offset: 1c73bc8
irq_stack_ptr:
type: 1, TYPE_CODE_PTR
target_typecode: 8, TYPE_CODE_INT
target_length: 8
length: 8
GNU_GET_DATATYPE[thread_union]: returned via gdb_error_hook
<readmem: ffff000b779c0050, KVADDR, "IRQ stack pointer", 8, (ROE), 3a37bea0>
<read_kdump: addr: ffff000b779c0050 paddr: fff1000bf79c0050 cnt: 8>
read_netdump: READ_ERROR: offset not found for paddr: fff1000bf79c0050
crash: read error: kernel virtual address: ffff000b779c0050 type: "IRQ stack pointer"
<readmem: ffff000b77a60050, KVADDR, "IRQ stack pointer", 8, (ROE), 3a37bea8>
<read_kdump: addr: ffff000b77a60050 paddr: fff1000bf7a60050 cnt: 8>
read_netdump: READ_ERROR: offset not found for paddr: fff1000bf7a60050
...
Apparently, for a normal system, the 'paddr: fff1000bf79c0050' is
unreasonable.
This bug connects 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 phys_offset. If
using memstart_addr to calculate the real paddr, the unreasonable paddr
will be got.
Furthermore, in crash utility, PTOV() needs memstart_addr to calculate
VA from PA, while getting PFN offset in a dumpfile, phys_offset is
required.
To serve the different purpose, using phys_offset_nominal and
phys_offset to store them.
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: Bhupesh Sharma <bhupesh.sharma(a)linaro.org>
To: crash-utility(a)redhat.com
---
v3 -> v4:
use _PAGE_OFFSET(va) to define MEMSTART_ADDR_OFFSET
and use the formula "#define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)"
for arm64_VTOP()
v2 -> v3:
rename ms->memstart_addr as ms->phys_offset_nominal ( I keep the name
as phys_offset* since it is in accordance with other platform
conventions)
---
arm64.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
defs.h | 3 +++
2 files changed, 43 insertions(+), 5 deletions(-)
diff --git a/arm64.c b/arm64.c
index 4787fa6..84addde 100644
--- a/arm64.c
+++ b/arm64.c
@@ -23,6 +23,10 @@
#include <sys/ioctl.h>
#define NOT_IMPLEMENTED(X) error((X), "%s: function not implemented\n", __func__)
+/*
+ * _PAGE_OFFSET() refers to arch/arm64/include/asm/memory.h
+ */
+#define _PAGE_OFFSET(va) (-1UL << (va))
static struct machine_specific arm64_machine_specific = { 0 };
static int arm64_verify_symbol(const char *, ulong, char);
@@ -687,6 +691,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, " phys_offset_nominal: %lx\n", ms->phys_offset_nominal);
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 +992,12 @@ arm64_calc_physvirt_offset(void)
ulong physvirt_offset;
struct syment *sp;
- ms->physvirt_offset = ms->phys_offset - ms->page_offset;
+ /*
+ * source arch/arm64/include/asm/memory.h
+ * #define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)
+ * the part "addr & ~PAGE_OFFSET" is done in arm64_VTOP()
+ */
+ ms->physvirt_offset = ms->phys_offset_nominal;
if ((sp = kernel_symbol_search("physvirt_offset")) &&
machdep->machspec->kimage_voffset) {
@@ -1002,6 +1012,8 @@ arm64_calc_physvirt_offset(void)
static void
arm64_calc_phys_offset(void)
{
+#define MEMSTART_ADDR_OFFSET _PAGE_OFFSET(48) - _PAGE_OFFSET(52)
+
struct machine_specific *ms = machdep->machspec;
ulong phys_offset;
@@ -1028,7 +1040,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->phys_offset_nominal = htol(string, QUIET, NULL);
+ if (ms->phys_offset_nominal < 0)
+ ms->phys_offset = ms->phys_offset_nominal + MEMSTART_ADDR_OFFSET;
+ else
+ ms->phys_offset = ms->phys_offset_nominal;
free(string);
return;
}
@@ -1080,7 +1096,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->phys_offset_nominal = phys_offset;
+ if ((long)phys_offset < 0)
+ ms->phys_offset = phys_offset + MEMSTART_ADDR_OFFSET;
+ else
+ ms->phys_offset = phys_offset;
} else {
error(WARNING,
"phys_offset cannot be determined from the dumpfile.\n");
@@ -1180,8 +1207,16 @@ arm64_VTOP(ulong addr)
return addr - machdep->machspec->kimage_voffset;
}
- if (addr >= machdep->machspec->page_offset)
- return addr + machdep->machspec->physvirt_offset;
+ if (addr >= machdep->machspec->page_offset) {
+ ulong paddr;
+
+ /*
+ * #define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)
+ */
+ paddr = addr & ~ _PAGE_OFFSET(machdep->machspec->CONFIG_ARM64_VA_BITS);
+ paddr += machdep->machspec->physvirt_offset;
+ return paddr;
+ }
else if (machdep->machspec->kimage_voffset)
return addr - machdep->machspec->kimage_voffset;
else /* no randomness */
diff --git a/defs.h b/defs.h
index f9c711c..0a152f1 100644
--- a/defs.h
+++ b/defs.h
@@ -3289,7 +3289,10 @@ struct machine_specific {
ulong vmemmap_end;
ulong modules_vaddr;
ulong modules_end;
+ /* real physical offset */
ulong phys_offset;
+ /* read from kernel symbol memstart_addr */
+ long phys_offset_nominal;
ulong __exception_text_start;
ulong __exception_text_end;
struct arm64_pt_regs *panic_task_regs;
--
2.29.2
3 years, 4 months
crash does not work with last fedora kernels?
by Vasily Averin
It looks like Fedora kernels uses gcc11 and generates debuginfo in DWARF 5 format.
[root@localhost ~]# rpm -q crash
crash-7.2.9-5.fc35.x86_64
[root@localhost ~]# uname -a
Linux localhost.localdomain 5.11.12-300.fc34.x86_64 #1 SMP Wed Apr 7 16:31:13 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
[root@localhost ~]# crash -1
Dwarf Error: wrong version in compilation unit header (is 5, should be 2, 3, or 4) [in module /usr/lib/debug/usr/lib/modules/5.11.12-300.fc34.x86_64/vmlinux]
crash: gdb_session_init: pulling in debug data by accessing init_mm.mmap
Dwarf Error: wrong version in compilation unit header (is 5, should be 2, 3, or 4) [in module /usr/lib/debug/usr/lib/modules/5.11.12-300.fc34.x86_64/vmlinux]
crash: /usr/lib/debug/lib/modules/5.11.12-300.fc34.x86_64/vmlinux: no debugging data available
[root@localhost ~]# ls -al /usr/lib/debug/lib/modules/5.11.12-300.fc34.x86_64/vmlinux
-rwxr-xr-x. 1 root root 679679112 Apr 7 20:14 /usr/lib/debug/lib/modules/5.11.12-300.fc34.x86_64/vmlinux
[root@localhost ~]# rpm -qf /usr/lib/debug/lib/modules/5.11.12-300.fc34.x86_64/vmlinux
kernel-debuginfo-5.11.12-300.fc34.x86_64
NB: last fc35 does not work too.
Thank you,
Vasily Averin
3 years, 4 months