----- Original Message ----- > On Tue, Oct 17, 2017 at 03:44:36PM -0400, Dave Anderson wrote: > > > > Thanks Takahiro, much appreciated. Queued for crash-7.2.1: > > > > https://github.com/crash-utility/crash/commit/2b93c036edf2a5cc21a06a14f377cd9b365f858a > > Oops, I've made small changes, nothing essential but some sort of > clean-ups/readability improvements with deleting incomplete fixes > against "bt -o." Hmmm, except it's kind of difficult to pick through the patch below for the changes, given that it's a combination of your original patch plus the new changes. So I can't apply it to get a clean view of the new changes. I do see that it's mostly the stacksize and stackframe related updates, but would it be possible for you to make a patch that can be applied to the github sources? Thanks, Dave > > Thanks, > -Takahiro AKASHI > ===8<=== > >From 826147807e2f2e00155b41b8ab97d3083bb0e607 Mon Sep 17 00:00:00 2001 > From: AKASHI Takahiro <takahiro.akashi@xxxxxxxxxx> > Date: Thu, 12 Oct 2017 10:46:34 +0900 > Subject: [PATCH v2] arm64: backtrace for v4.14 > > --- > arm64.c | 212 > +++++++++++++++++++++++++++++++++++++++++++++++----------------- > defs.h | 3 + > task.c | 2 + > 3 files changed, 161 insertions(+), 56 deletions(-) > > diff --git a/arm64.c b/arm64.c > index 20c5d34..80cb476 100644 > --- a/arm64.c > +++ b/arm64.c > @@ -72,6 +72,7 @@ static void arm64_cmd_mach(void); > static void arm64_display_machine_stats(void); > static int arm64_get_smp_cpus(void); > static void arm64_clear_machdep_cache(void); > +static int arm64_on_process_stack(struct bt_info *, ulong); > static int arm64_in_alternate_stack(int, ulong); > static int arm64_on_irq_stack(int, ulong); > static void arm64_set_irq_stack(struct bt_info *); > @@ -611,6 +612,7 @@ arm64_dump_machdep_table(ulong arg) > fprintf(fp, " exp_entry2_end: %lx\n", ms->exp_entry2_end); > fprintf(fp, " panic_task_regs: %lx\n", (ulong)ms->panic_task_regs); > fprintf(fp, " user_eframe_offset: %ld\n", ms->user_eframe_offset); > + fprintf(fp, " kern_eframe_offset: %ld\n", ms->kern_eframe_offset); > fprintf(fp, " PTE_PROT_NONE: %lx\n", ms->PTE_PROT_NONE); > fprintf(fp, " PTE_FILE: "); > if (ms->PTE_FILE) > @@ -1336,31 +1338,64 @@ arm64_irq_stack_init(void) > req = &request; > struct machine_specific *ms = machdep->machspec; > > - if (!symbol_exists("irq_stack") || > - !(sp = per_cpu_symbol_search("irq_stack")) || > - !get_symbol_type("irq_stack", NULL, req) || > - (req->typecode != TYPE_CODE_ARRAY) || > - (req->target_typecode != TYPE_CODE_INT)) > - return; > + if (!(ms->irq_stacks = (ulong *)malloc((size_t)(kt->cpus > + * sizeof(ulong))))) > + error(FATAL, "cannot malloc irq_stack addresses\n"); > > - if (CRASHDEBUG(1)) { > - fprintf(fp, "irq_stack: \n"); > - fprintf(fp, " type: %s\n", > - (req->typecode == TYPE_CODE_ARRAY) ? "TYPE_CODE_ARRAY" : "other"); > - fprintf(fp, " target_typecode: %s\n", > - req->target_typecode == TYPE_CODE_INT ? "TYPE_CODE_INT" : "other"); > - fprintf(fp, " target_length: %ld\n", req->target_length); > - fprintf(fp, " length: %ld\n", req->length); > - } > + if (symbol_exists("irq_stack") && > + (sp = per_cpu_symbol_search("irq_stack")) && > + get_symbol_type("irq_stack", NULL, req)) { > + /* before v4.14 or CONFIG_VMAP_STACK disabled */ > + if (CRASHDEBUG(1)) { > + fprintf(fp, "irq_stack: \n"); > + fprintf(fp, " type: %s\n", > + (req->typecode == TYPE_CODE_ARRAY) ? > + "TYPE_CODE_ARRAY" : "other"); > + fprintf(fp, " target_typecode: %s\n", > + req->target_typecode == TYPE_CODE_INT ? > + "TYPE_CODE_INT" : "other"); > + fprintf(fp, " target_length: %ld\n", > + req->target_length); > + fprintf(fp, " length: %ld\n", req->length); > + } > > - ms->irq_stack_size = req->length; > - if (!(ms->irq_stacks = (ulong *)malloc((size_t)(kt->cpus * > sizeof(ulong))))) > - error(FATAL, "cannot malloc irq_stack addresses\n"); > + ms->irq_stack_size = req->length; > + > + for (i = 0; i < kt->cpus; i++) > + ms->irq_stacks[i] = kt->__per_cpu_offset[i] + sp->value; > + > + machdep->flags |= IRQ_STACKS; > + } else if (symbol_exists("irq_stack_ptr") && > + (sp = per_cpu_symbol_search("irq_stack_ptr")) && > + get_symbol_type("irq_stack_ptr", NULL, req)) { > + /* v4.14 and later with CONFIG_VMAP_STACK enabled */ > + if (CRASHDEBUG(1)) { > + fprintf(fp, "irq_stack_ptr: \n"); > + fprintf(fp, " type: %x, %s\n", > + (int)req->typecode, > + (req->typecode == TYPE_CODE_PTR) ? > + "TYPE_CODE_PTR" : "other"); > + fprintf(fp, " target_typecode: %x, %s\n", > + (int)req->target_typecode, > + req->target_typecode == TYPE_CODE_INT ? > + "TYPE_CODE_INT" : "other"); > + fprintf(fp, " target_length: %ld\n", > + req->target_length); > + fprintf(fp, " length: %ld\n", req->length); > + } > + > + ms->irq_stack_size = ARM64_IRQ_STACK_SIZE; > > - for (i = 0; i < kt->cpus; i++) > - ms->irq_stacks[i] = kt->__per_cpu_offset[i] + sp->value; > + for (i = 0; i < kt->cpus; i++) { > + ulong p; > > - machdep->flags |= IRQ_STACKS; > + p = kt->__per_cpu_offset[i] + sp->value; > + readmem(p, KVADDR, &(ms->irq_stacks[i]), sizeof(ulong), > + "IRQ stack pointer", RETURN_ON_ERROR); > + } > + > + machdep->flags |= IRQ_STACKS; > + } > } > > /* > @@ -1379,10 +1414,13 @@ arm64_stackframe_init(void) > MEMBER_OFFSET_INIT(elf_prstatus_pr_pid, "elf_prstatus", "pr_pid"); > MEMBER_OFFSET_INIT(elf_prstatus_pr_reg, "elf_prstatus", "pr_reg"); > > - if (MEMBER_EXISTS("pt_regs", "stackframe")) > + if (MEMBER_EXISTS("pt_regs", "stackframe")) { > machdep->machspec->user_eframe_offset = SIZE(pt_regs); > - else > + machdep->machspec->kern_eframe_offset = SIZE(pt_regs) - 16; > + } else { > machdep->machspec->user_eframe_offset = SIZE(pt_regs) + 16; > + machdep->machspec->kern_eframe_offset = SIZE(pt_regs); > + } > > machdep->machspec->__exception_text_start = > symbol_value("__exception_text_start"); > @@ -1472,6 +1510,7 @@ arm64_stackframe_init(void) > #define USER_MODE (2) > > #define USER_EFRAME_OFFSET (machdep->machspec->user_eframe_offset) > +#define KERN_EFRAME_OFFSET (machdep->machspec->kern_eframe_offset) > > /* > * PSR bits > @@ -1747,14 +1786,23 @@ arm64_display_full_frame(struct bt_info *bt, ulong > sp) > ulong words, addr; > char buf[BUFSIZE]; > > - if (bt->frameptr == sp) > + if (bt->frameptr >= sp) > return; > > - if (!INSTACK(sp, bt) || !INSTACK(bt->frameptr, bt)) { > - if (sp == 0) > - sp = bt->stacktop - USER_EFRAME_OFFSET; > - else > - return; > + if (INSTACK(bt->frameptr, bt)) { > + if (INSTACK(sp, bt)) { > + /* normal case */; > + } else { > + if (sp == 0) > + /* interrupt in user mode */ > + sp = bt->stacktop - USER_EFRAME_OFFSET; > + else > + /* interrupt in kernel mode */ > + sp = bt->stacktop; > + } > + } else { > + /* This is a transition case from irq to process stack. */ > + return; > } > > words = (sp - bt->frameptr) / sizeof(ulong); > @@ -1860,6 +1908,38 @@ arm64_unwind_frame(struct bt_info *bt, struct > arm64_stackframe *frame) > if ((frame->fp == 0) && (frame->pc == 0)) > return FALSE; > > + if (!(machdep->flags & IRQ_STACKS)) > + return TRUE; > + > + if (machdep->flags & UNW_4_14) { > + if ((bt->flags & BT_IRQSTACK) && > + !arm64_on_irq_stack(bt->tc->processor, frame->fp)) { > + if (arm64_on_process_stack(bt, frame->fp)) { > + arm64_set_process_stack(bt); > + > + frame->sp = frame->fp - KERN_EFRAME_OFFSET; > + /* > + * for switch_stack > + * fp still points to irq stack > + */ > + bt->bptr = fp; > + /* > + * for display_full_frame > + * sp points to process stack > + * > + * If we want to see pt_regs, > + * comment out the below. > + * bt->frameptr = frame->sp; > + */ > + } else { > + /* irq -> user */ > + return FALSE; > + } > + } > + > + return TRUE; > + } > + > /* > * The kernel's manner of determining the end of the IRQ stack: > * > @@ -1872,29 +1952,27 @@ arm64_unwind_frame(struct bt_info *bt, struct > arm64_stackframe *frame) > * irq_stack_ptr = IRQ_STACK_PTR(raw_smp_processor_id()); > * orig_sp = IRQ_STACK_TO_TASK_STACK(irq_stack_ptr); (pt_regs pointer on > process stack) > */ > - if (machdep->flags & IRQ_STACKS) { > - ms = machdep->machspec; > - irq_stack_ptr = ms->irq_stacks[bt->tc->processor] + ms->irq_stack_size - > 16; > - > - if (frame->sp == irq_stack_ptr) { > - orig_sp = GET_STACK_ULONG(irq_stack_ptr - 8); > - arm64_set_process_stack(bt); > - if (INSTACK(orig_sp, bt) && (INSTACK(frame->fp, bt) || (frame->fp == 0))) > { > - ptregs = (struct arm64_pt_regs > *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(orig_sp))]; > - frame->sp = orig_sp; > - frame->pc = ptregs->pc; > - bt->bptr = fp; > - if (CRASHDEBUG(1)) > - error(INFO, > - "arm64_unwind_frame: switch stacks: fp: %lx sp: %lx pc: %lx\n", > - frame->fp, frame->sp, frame->pc); > - } else { > - error(WARNING, > - "arm64_unwind_frame: on IRQ stack: oriq_sp: %lx%s fp: %lx%s\n", > - orig_sp, INSTACK(orig_sp, bt) ? "" : " (?)", > - frame->fp, INSTACK(frame->fp, bt) ? "" : " (?)"); > - return FALSE; > - } > + ms = machdep->machspec; > + irq_stack_ptr = ms->irq_stacks[bt->tc->processor] + ms->irq_stack_size - > 16; > + > + if (frame->sp == irq_stack_ptr) { > + orig_sp = GET_STACK_ULONG(irq_stack_ptr - 8); > + arm64_set_process_stack(bt); > + if (INSTACK(orig_sp, bt) && (INSTACK(frame->fp, bt) || (frame->fp == 0))) > { > + ptregs = (struct arm64_pt_regs > *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(orig_sp))]; > + frame->sp = orig_sp; > + frame->pc = ptregs->pc; > + bt->bptr = fp; > + if (CRASHDEBUG(1)) > + error(INFO, > + "arm64_unwind_frame: switch stacks: fp: %lx sp: %lx pc: %lx\n", > + frame->fp, frame->sp, frame->pc); > + } else { > + error(WARNING, > + "arm64_unwind_frame: on IRQ stack: oriq_sp: %lx%s fp: %lx%s\n", > + orig_sp, INSTACK(orig_sp, bt) ? "" : " (?)", > + frame->fp, INSTACK(frame->fp, bt) ? "" : " (?)"); > + return FALSE; > } > } > > @@ -2211,6 +2289,11 @@ arm64_back_trace_cmd(struct bt_info *bt) > FILE *ofp; > > if (bt->flags & BT_OPT_BACK_TRACE) { > + if (machdep->flags & UNW_4_14) { > + error(WARNING, "\"-o\" is no longer supported for this version of kernel. > Please use bt\n"); > + return; > + } > + > arm64_back_trace_cmd_v2(bt); > return; > } > @@ -2272,7 +2355,7 @@ arm64_back_trace_cmd(struct bt_info *bt) > goto complete_user; > > if (DUMPFILE() && is_task_active(bt->task)) { > - exception_frame = stackframe.fp - SIZE(pt_regs); > + exception_frame = stackframe.fp - KERN_EFRAME_OFFSET; > if (arm64_is_kernel_exception_frame(bt, exception_frame)) > arm64_print_exception_frame(bt, exception_frame, > KERNEL_MODE, ofp); > @@ -2304,11 +2387,12 @@ arm64_back_trace_cmd(struct bt_info *bt) > if (arm64_in_exception_text(bt->instptr) && INSTACK(stackframe.fp, bt)) { > if (!(bt->flags & BT_IRQSTACK) || > (((stackframe.sp + SIZE(pt_regs)) < bt->stacktop))) > - exception_frame = stackframe.fp - SIZE(pt_regs); > + exception_frame = stackframe.fp > + - KERN_EFRAME_OFFSET; > } > > if ((bt->flags & BT_IRQSTACK) && > - !arm64_on_irq_stack(bt->tc->processor, stackframe.sp)) { > + !arm64_on_irq_stack(bt->tc->processor, stackframe.fp)) { > bt->flags &= ~BT_IRQSTACK; > if (arm64_switch_stack(bt, &stackframe, ofp) == USER_MODE) > break; > @@ -2669,7 +2753,9 @@ arm64_switch_stack(struct bt_info *bt, struct > arm64_stackframe *frame, FILE *ofp > if (frame->fp == 0) > return USER_MODE; > > - arm64_print_exception_frame(bt, frame->sp, KERNEL_MODE, ofp); > + if (!(machdep->flags & UNW_4_14)) > + arm64_print_exception_frame(bt, frame->sp, KERNEL_MODE, ofp); > + > return KERNEL_MODE; > } > > @@ -3362,6 +3448,20 @@ arm64_clear_machdep_cache(void) { > return; > } > > +static int > +arm64_on_process_stack(struct bt_info *bt, ulong stkptr) > +{ > + ulong stackbase, stacktop; > + > + stackbase = GET_STACKBASE(bt->task); > + stacktop = GET_STACKTOP(bt->task); > + > + if ((stkptr >= stackbase) && (stkptr < stacktop)) > + return TRUE; > + > + return FALSE; > +} > + > static int > arm64_on_irq_stack(int cpu, ulong stkptr) > { > diff --git a/defs.h b/defs.h > index 7768895..a694a66 100644 > --- a/defs.h > +++ b/defs.h > @@ -3038,6 +3038,7 @@ typedef signed int s32; > #define ARM64_VMEMMAP_END (ARM64_VMEMMAP_VADDR + GIGABYTES(8UL) - 1) > > #define ARM64_STACK_SIZE (16384) > +#define ARM64_IRQ_STACK_SIZE ARM64_STACK_SIZE > > #define _SECTION_SIZE_BITS 30 > #define _MAX_PHYSMEM_BITS 40 > @@ -3117,6 +3118,8 @@ struct machine_specific { > ulong kimage_text; > ulong kimage_end; > ulong user_eframe_offset; > + /* for v4.14 or later */ > + ulong kern_eframe_offset; > }; > > struct arm64_stackframe { > diff --git a/task.c b/task.c > index 2b12af0..23c2b7b 100644 > --- a/task.c > +++ b/task.c > @@ -6750,6 +6750,8 @@ panic_search(void) > fd->keyword_array[0] = FOREACH_BT; > if (machine_type("S390X")) > fd->flags |= FOREACH_o_FLAG; > + else if (machine_type("ARM64") && (machdep->flags & UNW_4_14)) > + fd->flags |= FOREACH_t_FLAG; > else > fd->flags |= (FOREACH_t_FLAG|FOREACH_o_FLAG); > > -- > 2.14.1 > > -- > Crash-utility mailing list > Crash-utility@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/crash-utility > -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility