Dave, On Wed, Oct 18, 2017 at 02:12:17PM -0400, Dave Anderson wrote: > > > ----- 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? Here is what you requested. Pls check. Thanks, -Takahiro AKASHI ===8<=== >From 7b99a1c2e688ba81e18541c21a7d0fa70504e5bc Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro <takahiro.akashi@xxxxxxxxxx> Date: Thu, 19 Oct 2017 10:18:22 +0900 Subject: [PATCH] arm64: bt: cleanup stuff --- arm64.c | 159 +++++++++++++++++++++++++++++++++------------------------------- defs.h | 3 ++ task.c | 2 + 3 files changed, 86 insertions(+), 78 deletions(-) diff --git a/arm64.c b/arm64.c index c75669b..1f742d4 100644 --- a/arm64.c +++ b/arm64.c @@ -612,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) @@ -1383,7 +1384,7 @@ arm64_irq_stack_init(void) if (!(ms->irq_stacks = (ulong *)malloc((size_t)(kt->cpus * sizeof(ulong))))) error(FATAL, "cannot malloc irq_stack addresses\n"); - ms->irq_stack_size = 16384; + ms->irq_stack_size = ARM64_IRQ_STACK_SIZE; machdep->flags |= IRQ_STACKS; for (i = 0; i < kt->cpus; i++) { @@ -1410,10 +1411,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"); @@ -1503,6 +1507,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 @@ -1778,7 +1783,7 @@ 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(bt->frameptr, bt)) { @@ -1793,7 +1798,7 @@ arm64_display_full_frame(struct bt_info *bt, ulong sp) sp = bt->stacktop; } } else { - /* IRQ exception frame */ + /* This is a transition case from irq to process stack. */ return; } @@ -1903,61 +1908,73 @@ arm64_unwind_frame(struct bt_info *bt, struct arm64_stackframe *frame) if (!(machdep->flags & IRQ_STACKS)) return TRUE; - /* - * The kernel's manner of determining the end of the IRQ stack: - * - * #define THREAD_SIZE 16384 - * #define THREAD_START_SP (THREAD_SIZE - 16) - * #define IRQ_STACK_START_SP THREAD_START_SP - * #define IRQ_STACK_PTR(cpu) ((unsigned long)per_cpu(irq_stack, cpu) + IRQ_STACK_START_SP) - * #define IRQ_STACK_TO_TASK_STACK(ptr) (*((unsigned long *)((ptr) - 0x08))) - * - * 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)) + 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 - SIZE(pt_regs) + 16; - /* for switch_stack */ - /* fp still points to irq stack */ + 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 */ - bt->frameptr = frame->sp; + /* + * 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; } } - } else { /* !UNW_4_14 */ - 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; - } + + return TRUE; + } + + /* + * The kernel's manner of determining the end of the IRQ stack: + * + * #define THREAD_SIZE 16384 + * #define THREAD_START_SP (THREAD_SIZE - 16) + * #define IRQ_STACK_START_SP THREAD_START_SP + * #define IRQ_STACK_PTR(cpu) ((unsigned long)per_cpu(irq_stack, cpu) + IRQ_STACK_START_SP) + * #define IRQ_STACK_TO_TASK_STACK(ptr) (*((unsigned long *)((ptr) - 0x08))) + * + * 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) + */ + 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; } - } /* UNW_4_14 */ + } return TRUE; } @@ -2147,17 +2164,10 @@ arm64_unwind_frame_v2(struct bt_info *bt, struct arm64_stackframe *frame, * We are on process stack. Just add a faked frame */ - if (!arm64_on_irq_stack(bt->tc->processor, ext_frame.fp)) { - if (MEMBER_EXISTS("pt_regs", "stackframe")) { - frame->sp = ext_frame.fp - - sizeof(struct arm64_pt_regs) - 16; - frame->fp = ext_frame.fp; - } else { - frame->sp = ext_frame.fp - - sizeof(struct arm64_pt_regs); - frame->fp = frame->sp; - } - } else { + if (!arm64_on_irq_stack(bt->tc->processor, ext_frame.fp)) + frame->sp = ext_frame.fp + - sizeof(struct arm64_pt_regs); + else { /* * FIXME: very exceptional case * We are already back on process stack, but @@ -2177,10 +2187,10 @@ arm64_unwind_frame_v2(struct bt_info *bt, struct arm64_stackframe *frame, * Really ugly */ frame->sp = frame->fp + 0x20; - frame->fp = frame->sp; fprintf(ofp, " (Next exception frame might be wrong)\n"); } + frame->fp = frame->sp; } else { /* We are on IRQ stack */ @@ -2190,15 +2200,9 @@ arm64_unwind_frame_v2(struct bt_info *bt, struct arm64_stackframe *frame, if (ext_frame.fp != irq_stack_ptr) { /* (2) Just add a faked frame */ - if (MEMBER_EXISTS("pt_regs", "stackframe")) { - frame->sp = ext_frame.fp - - sizeof(struct arm64_pt_regs); - frame->fp = ext_frame.fp; - } else { - frame->sp = ext_frame.fp - - sizeof(struct arm64_pt_regs) - 16; - frame->fp = frame->sp; - } + frame->sp = ext_frame.fp + - sizeof(struct arm64_pt_regs); + frame->fp = frame->sp; } else { /* * (3) @@ -2285,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; } @@ -2346,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); @@ -2377,13 +2386,9 @@ 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))) { - if (MEMBER_EXISTS("pt_regs", "stackframe")) - /* v4.14 or later */ - exception_frame = stackframe.fp - SIZE(pt_regs) + 16; - else - exception_frame = stackframe.fp - SIZE(pt_regs); - } + (((stackframe.sp + SIZE(pt_regs)) < bt->stacktop))) + exception_frame = stackframe.fp + - KERN_EFRAME_OFFSET; } if ((bt->flags & BT_IRQSTACK) && @@ -2503,8 +2508,6 @@ user_space: * otherwise show an exception frame. * Since exception entry code doesn't have a real * stackframe, we fake a dummy frame here. - * Note: Since we have a real stack frame in pt_regs, - * We no longer need a dummy frame on v4.14 or later. */ if (!arm64_in_exp_entry(stackframe.pc)) continue; 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