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/2b93c036edf2a5cc21a06a14f37...
>
> 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(a)linaro.org>
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