[Skiboot] [PATCH 10/16] core: interrupt markers for stack traces
Nicholas Piggin
npiggin at gmail.com
Mon Apr 27 21:08:07 AEST 2020
Use magic marker in the exception stack frame that is used by the
unwinder to decode the interrupt type and NIA. The below example trace
comes from a modified skiboot that uses virtual memory, but any
interrupt type will appear similarly.
CPU 0000 Backtrace:
S: 0000000031c13580 R: 0000000030028210 .vm_dsi+0x360
S: 0000000031c13630 R: 000000003003b0dc .exception_entry+0x4fc
S: 0000000031c13830 R: 0000000030001f4c exception_entry_foo+0x4
--- Interrupt 0x300 at 000000003002431c ---
S: 0000000031c13b40 R: 000000003002430c .make_free.isra.0+0x110
S: 0000000031c13bd0 R: 0000000030025198 .mem_alloc+0x4a0
S: 0000000031c13c80 R: 0000000030028bac .__memalign+0x48
S: 0000000031c13d10 R: 0000000030028da4 .__zalloc+0x18
S: 0000000031c13d90 R: 000000003002fb34 .opal_init_msg+0x34
S: 0000000031c13e20 R: 00000000300234b4 .main_cpu_entry+0x61c
S: 0000000031c13f00 R: 00000000300031b8 boot_entry+0x1b0
--- OPAL boot ---
Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
---
asm/asm-offsets.c | 1 +
asm/head.S | 5 +++++
core/exceptions.c | 2 ++
core/stack.c | 11 +++++++++++
include/mem-map.h | 2 +-
include/stack.h | 6 ++++++
6 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/asm/asm-offsets.c b/asm/asm-offsets.c
index 2328d4d0f..7be0a1157 100644
--- a/asm/asm-offsets.c
+++ b/asm/asm-offsets.c
@@ -38,6 +38,7 @@ int main(void)
OFFSET(CPUTHREAD_STACK_BOT_TOK, cpu_thread, stack_bot_tok);
#endif
OFFSET(STACK_TYPE, stack_frame, type);
+ OFFSET(STACK_MAGIC, stack_frame, magic);
OFFSET(STACK_LOCALS, stack_frame, locals);
OFFSET(STACK_GPR0, stack_frame, gpr[0]);
OFFSET(STACK_GPR1, stack_frame, gpr[1]);
diff --git a/asm/head.S b/asm/head.S
index 450fb71f1..88b2bc12a 100644
--- a/asm/head.S
+++ b/asm/head.S
@@ -176,6 +176,7 @@ _exception:
mfspr %r3,SPR_SRR0
mfspr %r4,SPR_SRR1
std %r3,STACK_SRR0(%r1)
+ std %r3,16(%r1)
std %r4,STACK_SRR1(%r1)
mfspr %r3,SPR_DSISR
mfspr %r4,SPR_DAR
@@ -231,6 +232,8 @@ _exception:
stw %r4,STACK_XER(%r1)
std %r5,STACK_CTR(%r1)
std %r6,STACK_LR(%r1)
+ LOAD_IMM64(%r3,STACK_INT_MAGIC)
+ std %r3,STACK_MAGIC(%r1)
LOAD_IMM64(%r4, SKIBOOT_BASE)
LOAD_IMM32(%r5,__toc_start - __head)
LOAD_IMM32(%r6, exception_entry_foo - __head)
@@ -928,6 +931,8 @@ opal_entry:
/* Store token in CPU thread */
std %r0,CPUTHREAD_CUR_TOKEN(%r16)
+ LOAD_IMM64(%r12,STACK_INT_MAGIC)
+ std %r12,STACK_MAGIC(%r1)
/* Mark the stack frame */
li %r12,STACK_ENTRY_OPAL_API
std %r12,STACK_TYPE(%r1)
diff --git a/core/exceptions.c b/core/exceptions.c
index dacc02a28..fd069aa60 100644
--- a/core/exceptions.c
+++ b/core/exceptions.c
@@ -65,6 +65,8 @@ void exception_entry(struct stack_frame *stack)
nip = stack->srr0;
msr = stack->srr1;
}
+ stack->msr = msr;
+ stack->pc = nip;
if (!(msr & MSR_RI))
fatal = true;
diff --git a/core/stack.c b/core/stack.c
index 688ef7044..2df960b3e 100644
--- a/core/stack.c
+++ b/core/stack.c
@@ -35,6 +35,12 @@ static void __nomcount __backtrace_create(struct bt_entry *entries,
if (!fp || (unsigned long)fp > top_adj)
break;
eframe = (struct stack_frame *)fp;
+ if (eframe->magic == STACK_INT_MAGIC) {
+ entries->exception_type = eframe->type;
+ entries->exception_pc = eframe->pc;
+ } else {
+ entries->exception_type = 0;
+ }
entries->sp = (unsigned long)fp;
entries->pc = fp[2];
entries++;
@@ -99,6 +105,11 @@ void backtrace_print(struct bt_entry *entries, struct bt_metadata *metadata,
if (symbols)
l += snprintf_symbol(buf + l, max - l, entries->pc);
l += snprintf(buf + l, max - l, "\n");
+ if (entries->exception_type) {
+ l += snprintf(buf + l, max - l,
+ " --- Interrupt 0x%lx at %016lx ---\n",
+ entries->exception_type, entries->exception_pc);
+ }
entries++;
}
if (metadata->token <= OPAL_LAST)
diff --git a/include/mem-map.h b/include/mem-map.h
index b65401257..15ec09ea0 100644
--- a/include/mem-map.h
+++ b/include/mem-map.h
@@ -19,7 +19,7 @@
/* End of the exception region we copy from 0x0. 0x0-0x100 will have
* IPL data and is not actually for exception vectors.
*/
-#define EXCEPTION_VECTORS_END 0x2000
+#define EXCEPTION_VECTORS_END 0x3000
#define NACA_OFF 0x4000
diff --git a/include/stack.h b/include/stack.h
index bd4fa2f64..3e987ea81 100644
--- a/include/stack.h
+++ b/include/stack.h
@@ -45,6 +45,7 @@
#define STACK_WARNING_GAP 2048
#define STACK_CHECK_GUARD_BASE 0xdeadf00dbaad300
+#define STACK_INT_MAGIC 0xb1ab1af00ba1234ULL
#ifndef __ASSEMBLY__
@@ -72,6 +73,9 @@ struct stack_frame {
* one doubleword. */
uint64_t locals[1];
+ /* Interrupt entry magic value */
+ uint64_t magic;
+
/* Entry type */
uint64_t type;
@@ -104,6 +108,8 @@ struct stack_frame {
struct bt_entry {
unsigned long sp;
unsigned long pc;
+ unsigned long exception_type;
+ unsigned long exception_pc;
};
/* Backtrace metadata */
--
2.23.0
More information about the Skiboot
mailing list