2021-12-31 11:30:02 +08:00
|
|
|
From e43071b6ceaa4fe20c65befe1b5685b68dc9f33f Mon Sep 17 00:00:00 2001
|
|
|
|
|
From: Jialong Chen <chenjialong@huawei.com>
|
|
|
|
|
Date: Wed, 5 Jun 2019 21:25:34 +0800
|
|
|
|
|
Subject: [PATCH] crash: add SDEI stack resolution
|
|
|
|
|
reason: The kernel adds NMI dog detection, and the NMI interrupt stack uses a separate SDEI stack.
|
|
|
|
|
When the NMI dog is called, the kernel stack will switch to the sdei stack.
|
|
|
|
|
If the crash reads the stack data, the stack data cannot be parsed normally.
|
|
|
|
|
|
|
|
|
|
normal call trace as follows:
|
|
|
|
|
PID: 55429 TASK: ffff802772e3ae80 CPU: 19 COMMAND: "insmod"
|
|
|
|
|
#0 [ffff00000d4e3c70] __crash_kexec at ffff0000081b4ac0
|
|
|
|
|
#1 [ffff00000d4e3e00] panic at ffff0000080ebd0c
|
|
|
|
|
#2 [ffff00000d4e3ee0] nmi_panic at ffff0000080eb864
|
|
|
|
|
#3 [ffff00000d4e3f00] watchdog_hardlockup_check at ffff0000081ecd6c
|
|
|
|
|
#4 [ffff00000d4e3f40] sdei_watchdog_callback at ffff0000080a411c
|
|
|
|
|
#5 [ffff00000d4e3f60] sdei_event_handler at ffff0000087971ec
|
|
|
|
|
#6 [ffff00000d4e3f90] __sdei_handler at ffff000008995964
|
|
|
|
|
#7 [ffff00000d4e3ff0] __sdei_asm_handler at ffff0000080862dc
|
|
|
|
|
--- <IRQ stack> ---
|
|
|
|
|
#8 [ffff0000ccad3b70] __delay at ffff000008973658
|
|
|
|
|
#9 [ffff0000ccad3ba0] __const_udelay at ffff0000089735e8
|
|
|
|
|
#10 [ffff0000ccad3bb0] init_module at ffff0000009c6038 [test]
|
|
|
|
|
#11 [ffff0000ccad3bd0] do_one_initcall at ffff000008084ae0
|
|
|
|
|
#12 [ffff0000ccad3c60] do_init_module at ffff0000081b1418
|
|
|
|
|
#13 [ffff0000ccad3c90] load_module at ffff0000081afc54
|
|
|
|
|
#14 [ffff0000ccad3d80] __se_sys_finit_module at ffff0000081b0134
|
|
|
|
|
#15 [ffff0000ccad3e40] __arm64_sys_finit_module at ffff0000081b01a0
|
|
|
|
|
#16 [ffff0000ccad3e60] el0_svc_common at ffff000008097b44
|
|
|
|
|
#17 [ffff0000ccad3ea0] el0_svc_handler at ffff000008097c34
|
|
|
|
|
#18 [ffff0000ccad3ff0] el0_svc at ffff000008084144
|
|
|
|
|
|
|
|
|
|
Signed-off-by: Jialong Chen <chenjialong@huawei.com>
|
|
|
|
|
---
|
2023-01-29 14:30:19 +08:00
|
|
|
arm64.c | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
|
2022-02-08 11:23:34 +08:00
|
|
|
defs.h | 3 +
|
2023-01-29 14:30:19 +08:00
|
|
|
2 files changed, 212 insertions(+), 4 deletions(-)
|
2021-12-31 11:30:02 +08:00
|
|
|
|
|
|
|
|
diff --git a/arm64.c b/arm64.c
|
2023-01-29 14:30:19 +08:00
|
|
|
index c3e26a3..d293e6c 100644
|
2021-12-31 11:30:02 +08:00
|
|
|
--- a/arm64.c
|
|
|
|
|
+++ b/arm64.c
|
2023-01-29 14:30:19 +08:00
|
|
|
@@ -93,6 +93,11 @@ static void arm64_calc_VA_BITS(void);
|
2021-12-31 11:30:02 +08:00
|
|
|
static int arm64_is_uvaddr(ulong, struct task_context *);
|
|
|
|
|
static void arm64_calc_KERNELPACMASK(void);
|
|
|
|
|
|
|
|
|
|
+static int arm64_in_sdei_normal_stack(int cpu, ulong stkptr);
|
|
|
|
|
+static void arm64_set_sdei_normal_stack(struct bt_info *bt);
|
|
|
|
|
+static void arm64_sdei_stack_init(void);
|
|
|
|
|
+static int arm64_in_kdump_text_on_sdei_stack(struct bt_info *bt);
|
2023-01-29 14:30:19 +08:00
|
|
|
+
|
|
|
|
|
struct kernel_range {
|
|
|
|
|
unsigned long modules_vaddr, modules_end;
|
|
|
|
|
unsigned long vmalloc_start_addr, vmalloc_end;
|
|
|
|
|
@@ -520,6 +525,7 @@ arm64_init(int when)
|
2021-12-31 11:30:02 +08:00
|
|
|
arm64_irq_stack_init();
|
2023-01-29 14:30:19 +08:00
|
|
|
arm64_overflow_stack_init();
|
2021-12-31 11:30:02 +08:00
|
|
|
arm64_stackframe_init();
|
|
|
|
|
+ arm64_sdei_stack_init();
|
|
|
|
|
break;
|
|
|
|
|
|
2023-01-29 14:30:19 +08:00
|
|
|
case POST_INIT:
|
|
|
|
|
@@ -2174,6 +2180,70 @@ arm64_irq_stack_init(void)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-31 11:30:02 +08:00
|
|
|
+/*
|
|
|
|
|
+ * Gather IRQ stack values.
|
|
|
|
|
+ */
|
|
|
|
|
+static void
|
|
|
|
|
+arm64_sdei_stack_init(void)
|
|
|
|
|
+{
|
|
|
|
|
+ int i;
|
|
|
|
|
+ struct syment *sp;
|
|
|
|
|
+ struct gnu_request request, *req;
|
|
|
|
|
+ struct machine_specific *ms = machdep->machspec;
|
|
|
|
|
+ ulong p, sz;
|
|
|
|
|
+ req = &request;
|
|
|
|
|
+
|
|
|
|
|
+ if (symbol_exists("sdei_stack_normal_ptr") &&
|
|
|
|
|
+ (sp = per_cpu_symbol_search("sdei_stack_normal_ptr")) &&
|
|
|
|
|
+ get_symbol_type("sdei_stack_normal_ptr", NULL, req)) {
|
|
|
|
|
+ /* v4.14 and later with CONFIG_VMAP_STACK enabled */
|
|
|
|
|
+ if (CRASHDEBUG(1)) {
|
|
|
|
|
+ fprintf(fp, "sdei_stack_normal_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);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!(ms->sdei_stacks = (ulong *)malloc((size_t)(kt->cpus * sizeof(ulong)))))
|
|
|
|
|
+ error(FATAL, "cannot malloc irq_stack addresses\n");
|
|
|
|
|
+
|
|
|
|
|
+ /*
|
|
|
|
|
+ * Determining the IRQ_STACK_SIZE is tricky, but for now
|
|
|
|
|
+ * 4.14 kernel has:
|
|
|
|
|
+ *
|
|
|
|
|
+ * #define IRQ_STACK_SIZE THREAD_SIZE
|
|
|
|
|
+ *
|
|
|
|
|
+ * and finding a solid usage of THREAD_SIZE is hard, but:
|
|
|
|
|
+ *
|
|
|
|
|
+ * union thread_union {
|
|
|
|
|
+ * ...
|
|
|
|
|
+ * unsigned long stack[THREAD_SIZE/sizeof(long)];
|
|
|
|
|
+ * };
|
|
|
|
|
+ */
|
|
|
|
|
+ if (MEMBER_EXISTS("thread_union", "stack")) {
|
|
|
|
|
+ if ((sz = MEMBER_SIZE("thread_union", "stack")) > 0)
|
|
|
|
|
+ ms->sdei_stack_size = sz;
|
|
|
|
|
+ } else
|
|
|
|
|
+ ms->sdei_stack_size = ARM64_IRQ_STACK_SIZE;
|
|
|
|
|
+
|
|
|
|
|
+ machdep->flags |= IRQ_STACKS;
|
|
|
|
|
+
|
|
|
|
|
+ for (i = 0; i < kt->cpus; i++) {
|
|
|
|
|
+ p = kt->__per_cpu_offset[i] + sp->value;
|
|
|
|
|
+ readmem(p, KVADDR, &(ms->sdei_stacks[i]), sizeof(ulong),
|
|
|
|
|
+ "SDEI stack pointer", RETURN_ON_ERROR);
|
|
|
|
|
+ }
|
2023-01-29 14:30:19 +08:00
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
/*
|
|
|
|
|
* Gather Overflow stack values.
|
|
|
|
|
*
|
|
|
|
|
@@ -2736,7 +2806,7 @@ arm64_unwind_frame(struct bt_info *bt, struct arm64_stackframe *frame)
|
2021-12-31 11:30:02 +08:00
|
|
|
{
|
|
|
|
|
unsigned long high, low, fp;
|
|
|
|
|
unsigned long stack_mask;
|
|
|
|
|
- unsigned long irq_stack_ptr, orig_sp;
|
|
|
|
|
+ unsigned long irq_stack_ptr, orig_sp, sdei_stack_ptr;
|
|
|
|
|
struct arm64_pt_regs *ptregs;
|
|
|
|
|
struct machine_specific *ms = machdep->machspec;
|
|
|
|
|
|
2023-01-29 14:30:19 +08:00
|
|
|
@@ -2765,7 +2835,8 @@ arm64_unwind_frame(struct bt_info *bt, struct arm64_stackframe *frame)
|
|
|
|
|
if (((bt->flags & BT_IRQSTACK) &&
|
|
|
|
|
!arm64_on_irq_stack(bt->tc->processor, frame->fp)) ||
|
|
|
|
|
((bt->flags & BT_OVERFLOW_STACK) &&
|
|
|
|
|
- !arm64_on_overflow_stack(bt->tc->processor, frame->fp))) {
|
|
|
|
|
+ !arm64_on_overflow_stack(bt->tc->processor, frame->fp)) &&
|
|
|
|
|
+ !arm64_in_sdei_normal_stack(bt->tc->processor, frame->fp)) {
|
2021-12-31 11:30:02 +08:00
|
|
|
if (arm64_on_process_stack(bt, frame->fp)) {
|
|
|
|
|
arm64_set_process_stack(bt);
|
|
|
|
|
|
2023-01-29 14:30:19 +08:00
|
|
|
@@ -2805,6 +2876,7 @@ arm64_unwind_frame(struct bt_info *bt, struct arm64_stackframe *frame)
|
2021-12-31 11:30:02 +08:00
|
|
|
* orig_sp = IRQ_STACK_TO_TASK_STACK(irq_stack_ptr); (pt_regs pointer on process stack)
|
|
|
|
|
*/
|
|
|
|
|
irq_stack_ptr = ms->irq_stacks[bt->tc->processor] + ms->irq_stack_size - 16;
|
|
|
|
|
+ sdei_stack_ptr = ms->sdei_stacks[bt->tc->processor] + ms->sdei_stack_size - 16;
|
|
|
|
|
|
|
|
|
|
if (frame->sp == irq_stack_ptr) {
|
|
|
|
|
orig_sp = GET_STACK_ULONG(irq_stack_ptr - 8);
|
2023-01-29 14:30:19 +08:00
|
|
|
@@ -2825,6 +2897,25 @@ arm64_unwind_frame(struct bt_info *bt, struct arm64_stackframe *frame)
|
2021-12-31 11:30:02 +08:00
|
|
|
frame->fp, INSTACK(frame->fp, bt) ? "" : " (?)");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
+ } else if (frame->sp == sdei_stack_ptr) {
|
|
|
|
|
+ orig_sp = GET_STACK_ULONG(sdei_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;
|
2023-01-29 14:30:19 +08:00
|
|
|
@@ -3164,6 +3255,10 @@ arm64_back_trace_cmd(struct bt_info *bt)
|
2021-12-31 11:30:02 +08:00
|
|
|
arm64_set_irq_stack(bt);
|
|
|
|
|
bt->flags |= BT_IRQSTACK;
|
|
|
|
|
}
|
|
|
|
|
+ if (arm64_in_sdei_normal_stack(bt->tc->processor, bt->bptr)) {
|
|
|
|
|
+ arm64_set_sdei_normal_stack(bt);
|
|
|
|
|
+ bt->flags |= BT_IRQSTACK;
|
|
|
|
|
+ }
|
|
|
|
|
stackframe.fp = GET_STACK_ULONG(bt->bptr - 8);
|
|
|
|
|
stackframe.pc = GET_STACK_ULONG(bt->bptr);
|
|
|
|
|
stackframe.sp = bt->bptr + 8;
|
2023-01-29 14:30:19 +08:00
|
|
|
@@ -3173,6 +3268,10 @@ arm64_back_trace_cmd(struct bt_info *bt)
|
2021-12-31 11:30:02 +08:00
|
|
|
arm64_set_irq_stack(bt);
|
|
|
|
|
bt->flags |= BT_IRQSTACK;
|
|
|
|
|
}
|
2023-01-29 14:30:19 +08:00
|
|
|
+ if (arm64_in_sdei_normal_stack(bt->tc->processor, bt->bptr)) {
|
2021-12-31 11:30:02 +08:00
|
|
|
+ arm64_set_sdei_normal_stack(bt);
|
|
|
|
|
+ bt->flags |= BT_IRQSTACK;
|
|
|
|
|
+ }
|
|
|
|
|
stackframe.fp = GET_STACK_ULONG(bt->hp->esp - 8);
|
|
|
|
|
stackframe.pc = bt->hp->eip ?
|
|
|
|
|
bt->hp->eip : GET_STACK_ULONG(bt->hp->esp);
|
2023-01-29 14:30:19 +08:00
|
|
|
@@ -3186,6 +3285,10 @@ arm64_back_trace_cmd(struct bt_info *bt)
|
|
|
|
|
arm64_set_overflow_stack(bt);
|
|
|
|
|
bt->flags |= BT_OVERFLOW_STACK;
|
2021-12-31 11:30:02 +08:00
|
|
|
}
|
2023-01-29 14:30:19 +08:00
|
|
|
+ if (arm64_in_sdei_normal_stack(bt->tc->processor, bt->bptr)) {
|
2021-12-31 11:30:02 +08:00
|
|
|
+ arm64_set_sdei_normal_stack(bt);
|
|
|
|
|
+ bt->flags |= BT_IRQSTACK;
|
|
|
|
|
+ }
|
|
|
|
|
stackframe.sp = bt->stkptr;
|
|
|
|
|
stackframe.pc = bt->instptr;
|
|
|
|
|
stackframe.fp = bt->frameptr;
|
2023-01-29 14:30:19 +08:00
|
|
|
@@ -3249,7 +3352,8 @@ arm64_back_trace_cmd(struct bt_info *bt)
|
2021-12-31 11:30:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((bt->flags & BT_IRQSTACK) &&
|
|
|
|
|
- !arm64_on_irq_stack(bt->tc->processor, stackframe.fp)) {
|
2023-01-29 14:30:19 +08:00
|
|
|
+ !arm64_on_irq_stack(bt->tc->processor, stackframe.fp) &&
|
|
|
|
|
+ !arm64_in_sdei_normal_stack(bt->tc->processor, stackframe.fp)) {
|
2021-12-31 11:30:02 +08:00
|
|
|
bt->flags &= ~BT_IRQSTACK;
|
|
|
|
|
if (arm64_switch_stack(bt, &stackframe, ofp) == USER_MODE)
|
|
|
|
|
break;
|
2023-01-29 14:30:19 +08:00
|
|
|
@@ -3537,6 +3641,81 @@ arm64_in_kdump_text(struct bt_info *bt, struct arm64_stackframe *frame)
|
|
|
|
|
return FALSE;
|
2021-12-31 11:30:02 +08:00
|
|
|
}
|
|
|
|
|
|
2023-01-29 14:30:19 +08:00
|
|
|
+static int
|
2021-12-31 11:30:02 +08:00
|
|
|
+arm64_in_kdump_text_on_sdei_stack(struct bt_info *bt)
|
|
|
|
|
+{
|
|
|
|
|
+ int cpu;
|
|
|
|
|
+ ulong stackbase;
|
|
|
|
|
+ char *stackbuf;
|
|
|
|
|
+ ulong *ptr, *start, *base;
|
|
|
|
|
+ struct machine_specific *ms;
|
|
|
|
|
+
|
|
|
|
|
+ if ((machdep->flags & (IRQ_STACKS|KDUMP_ENABLED)) != (IRQ_STACKS|KDUMP_ENABLED))
|
|
|
|
|
+ return FALSE;
|
|
|
|
|
+
|
|
|
|
|
+ ms = machdep->machspec;
|
2022-02-08 11:23:34 +08:00
|
|
|
+ if (!ms->sdei_stacks)
|
|
|
|
|
+ return FALSE;
|
2021-12-31 11:30:02 +08:00
|
|
|
+ cpu = bt->tc->processor;
|
|
|
|
|
+ stackbase = ms->sdei_stacks[cpu];
|
|
|
|
|
+ stackbuf = GETBUF(ms->sdei_stack_size);
|
|
|
|
|
+
|
|
|
|
|
+ if (!readmem(stackbase, KVADDR, stackbuf,
|
|
|
|
|
+ ms->sdei_stack_size, "IRQ stack contents", RETURN_ON_ERROR)) {
|
|
|
|
|
+ error(INFO, "read of IRQ stack at %lx failed\n", stackbase);
|
|
|
|
|
+ FREEBUF(stackbuf);
|
|
|
|
|
+ return FALSE;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ base = (ulong *)stackbuf;
|
|
|
|
|
+ start = (ulong *)(stackbuf + ms->sdei_stack_size);
|
|
|
|
|
+
|
|
|
|
|
+ for (ptr = start - 8; ptr >= base; ptr--) {
|
|
|
|
|
+ if (bt->flags & BT_OPT_BACK_TRACE) {
|
2023-01-29 14:30:19 +08:00
|
|
|
+ if ((*ptr > ms->crash_kexec_start) &&
|
2021-12-31 11:30:02 +08:00
|
|
|
+ (*ptr < ms->crash_kexec_end) &&
|
|
|
|
|
+ INSTACK(*(ptr - 1), bt)) {
|
|
|
|
|
+ bt->bptr = ((ulong)(ptr - 1) - (ulong)base) + stackbase;
|
|
|
|
|
+ if (CRASHDEBUG(1))
|
|
|
|
|
+ fprintf(fp, "%lx: %lx (crash_kexec on IRQ stack)\n",
|
|
|
|
|
+ bt->bptr, *ptr);
|
|
|
|
|
+ FREEBUF(stackbuf);
|
|
|
|
|
+ return TRUE;
|
|
|
|
|
+ }
|
2023-01-29 14:30:19 +08:00
|
|
|
+ if ((*ptr > ms->crash_save_cpu_start) &&
|
2021-12-31 11:30:02 +08:00
|
|
|
+ (*ptr < ms->crash_save_cpu_end) &&
|
|
|
|
|
+ INSTACK(*(ptr - 1), bt)) {
|
|
|
|
|
+ bt->bptr = ((ulong)(ptr - 1) - (ulong)base) + stackbase;
|
|
|
|
|
+ if (CRASHDEBUG(1))
|
|
|
|
|
+ fprintf(fp, "%lx: %lx (crash_save_cpu on IRQ stack)\n",
|
|
|
|
|
+ bt->bptr, *ptr);
|
|
|
|
|
+ FREEBUF(stackbuf);
|
|
|
|
|
+ return TRUE;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
2023-01-29 14:30:19 +08:00
|
|
|
+ if ((*ptr > ms->crash_kexec_start) && (*ptr < ms->crash_kexec_end)) {
|
2021-12-31 11:30:02 +08:00
|
|
|
+ bt->bptr = ((ulong)ptr - (ulong)base) + stackbase;
|
|
|
|
|
+ if (CRASHDEBUG(1))
|
|
|
|
|
+ fprintf(fp, "%lx: %lx (crash_kexec on IRQ stack)\n",
|
|
|
|
|
+ bt->bptr, *ptr);
|
|
|
|
|
+ FREEBUF(stackbuf);
|
|
|
|
|
+ return TRUE;
|
|
|
|
|
+ }
|
2023-01-29 14:30:19 +08:00
|
|
|
+ if ((*ptr > ms->crash_save_cpu_start) && (*ptr < ms->crash_save_cpu_end)) {
|
2021-12-31 11:30:02 +08:00
|
|
|
+ bt->bptr = ((ulong)ptr - (ulong)base) + stackbase;
|
|
|
|
|
+ if (CRASHDEBUG(1))
|
|
|
|
|
+ fprintf(fp, "%lx: %lx (crash_save_cpu on IRQ stack)\n",
|
|
|
|
|
+ bt->bptr, *ptr);
|
|
|
|
|
+ FREEBUF(stackbuf);
|
|
|
|
|
+ return TRUE;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ FREEBUF(stackbuf);
|
|
|
|
|
+ return FALSE;
|
|
|
|
|
+}
|
|
|
|
|
+
|
2023-01-29 14:30:19 +08:00
|
|
|
static int
|
2021-12-31 11:30:02 +08:00
|
|
|
arm64_in_kdump_text_on_irq_stack(struct bt_info *bt)
|
|
|
|
|
{
|
2023-01-29 14:30:19 +08:00
|
|
|
@@ -3727,7 +3906,8 @@ try_kernel:
|
2021-12-31 11:30:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (arm64_in_kdump_text(bt, frame) ||
|
2023-01-29 14:30:19 +08:00
|
|
|
- arm64_in_kdump_text_on_irq_stack(bt)) {
|
2021-12-31 11:30:02 +08:00
|
|
|
+ arm64_in_kdump_text_on_irq_stack(bt) ||
|
2023-01-29 14:30:19 +08:00
|
|
|
+ arm64_in_kdump_text_on_sdei_stack(bt)) {
|
2021-12-31 11:30:02 +08:00
|
|
|
bt->flags |= BT_KDUMP_ADJUST;
|
2023-01-29 14:30:19 +08:00
|
|
|
if (skip && is_idle_thread(bt->task))
|
|
|
|
|
bt->flags |= BT_SKIP_IDLE;
|
|
|
|
|
@@ -4488,6 +4668,31 @@ arm64_on_overflow_stack(int cpu, ulong stkptr)
|
|
|
|
|
ms->overflow_stacks, ms->overflow_stack_size);
|
2021-12-31 11:30:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+static int
|
|
|
|
|
+arm64_in_sdei_normal_stack(int cpu, ulong stkptr)
|
|
|
|
|
+{
|
|
|
|
|
+ struct machine_specific *ms = machdep->machspec;
|
|
|
|
|
+
|
|
|
|
|
+ if (!ms->sdei_stack_size || (cpu >= kt->cpus))
|
|
|
|
|
+ return FALSE;
|
|
|
|
|
+
|
2023-01-29 14:30:19 +08:00
|
|
|
+ if ((stkptr > ms->sdei_stacks[cpu]) &&
|
2021-12-31 11:30:02 +08:00
|
|
|
+ (stkptr < (ms->sdei_stacks[cpu] + ms->sdei_stack_size)))
|
|
|
|
|
+ return TRUE;
|
|
|
|
|
+
|
|
|
|
|
+ return FALSE;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void
|
|
|
|
|
+arm64_set_sdei_normal_stack(struct bt_info *bt)
|
|
|
|
|
+{
|
|
|
|
|
+ struct machine_specific *ms = machdep->machspec;
|
|
|
|
|
+
|
|
|
|
|
+ bt->stackbase = ms->sdei_stacks[bt->tc->processor];
|
|
|
|
|
+ bt->stacktop = bt->stackbase + ms->sdei_stack_size;
|
|
|
|
|
+ alter_stackbuf(bt);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
static void
|
|
|
|
|
arm64_set_irq_stack(struct bt_info *bt)
|
|
|
|
|
{
|
|
|
|
|
diff --git a/defs.h b/defs.h
|
2023-01-29 14:30:19 +08:00
|
|
|
index afdcf6c..4885d55 100644
|
2021-12-31 11:30:02 +08:00
|
|
|
--- a/defs.h
|
|
|
|
|
+++ b/defs.h
|
2023-01-29 14:30:19 +08:00
|
|
|
@@ -3376,6 +3376,9 @@ struct machine_specific {
|
2021-12-31 11:30:02 +08:00
|
|
|
ulong irq_stack_size;
|
|
|
|
|
ulong *irq_stacks;
|
|
|
|
|
char *irq_stackbuf;
|
|
|
|
|
+ ulong sdei_stack_size;
|
|
|
|
|
+ ulong *sdei_stacks;
|
|
|
|
|
+ char *sdei_stackbuf;
|
|
|
|
|
ulong __irqentry_text_start;
|
|
|
|
|
ulong __irqentry_text_end;
|
2023-01-29 14:30:19 +08:00
|
|
|
ulong overflow_stack_size;
|
2021-12-31 11:30:02 +08:00
|
|
|
--
|
2023-01-29 14:30:19 +08:00
|
|
|
2.27.0
|
2021-12-31 11:30:02 +08:00
|
|
|
|