From: Dmitry Voytik <dmitry.voy...@huawei.com> Dump stack in the following cases: * exception in EL2. We can determine the stack size * unhandled exceptions in EL1/0. We can't determine the stack size thus we just print 512 bytes.
For EL2 exceptions the debug output will be like this: FATAL: Unhandled HYP exception: synchronous abort from EL2 pc: 00000000fc00469c lr: 00000000fc004688 spsr: 200003c9 EL2 sp: 00000000fc015e30 esr: 25 1 0000044 x0: ffffffff00000000 x1: 0000000000000001 x2: 00000000fc00bd14 x3: ffffff80ffffffc8 x4: 00000000fc010000 x5: 0000000000000004 x6: ffffffc000afe000 x7: 00000000ffffe188 x8: 0000000000005d25 x9: 0000000000000001 x10: ffffffc035766a40 x11: ffffffbdc2d23f80 x12: 0000000000000862 x13: 0000007f92bd7cb0 x14: 0000007f92a67bc8 x15: 0000000000005798 x16: ffffffc0000a2794 x17: 0000000000412288 x18: 0000000000000000 x19: 0000000001930047 x20: 0000000000000004 x21: 0000000000000001 x22: 0000000000000001 x23: 00000000fc015eb8 x24: 00000000000001c0 x25: 0000000000000000 x26: ffffffc000afe6d8 x27: ffffffc035470000 x28: ffffffc034e08000 x29: 00000000fc015e30 Hypervisor stack before exception (0x00000000fc015e30 - 0x00000000fc016000): 5e20: fc015e90 00000000 fc00a298 00000000 5e40: fc015f00 00000000 fc015000 00000000 00559cb8 ffffffc0 00b69000 ffffffc0 5e60: 00b00000 ffffffc0 000001c0 00000000 0000001e 00000000 fc015cf5 00000000 5e80: fc015e90 00000000 0000001e 001e0100 fc015ee0 00000000 fc00a3b0 00000000 5ea0: fc015f00 00000000 fc00b478 00000000 fc015ee0 00000000 fc015f08 00000000 5ec0: 93930047 00000000 200001c5 00000000 00310820 ffffffc0 34e0bbc0 ffffffc0 5ee0: 00000000 00000000 fc009c54 00000000 00040000 00000000 00b00ea0 ffffffc0 5f00: 00000001 00000000 00000f00 ffffff80 00000004 00000000 00000040 00000000 5f20: 00b00ee0 ffffffc0 00559cc0 ffffffc0 00000004 00000000 00afe000 ffffffc0 5f40: ffffe188 00000000 00005d25 00000000 00000001 00000000 35766a40 ffffffc0 5f60: c2d23f80 ffffffbd 00000862 00000000 92bd7cb0 0000007f 92a67bc8 0000007f 5f80: 00005798 00000000 000a2794 ffffffc0 00412288 00000000 00000000 00000000 5fa0: 00040000 00000000 00b00ea0 ffffffc0 00559cb8 ffffffc0 00b69000 ffffffc0 5fc0: 00b00000 ffffffc0 000001c0 00000000 00000000 00000000 00afe6d8 ffffffc0 5fe0: 35470000 ffffffc0 34e08000 ffffffc0 34e0bbc0 ffffffc0 003107fc ffffffc0 6000: 8008a800 Signed-off-by: Dmitry Voytik <dmitry.voy...@huawei.com> [Jan: replace PERCPU_STACK_END with sizeof expression] Signed-off-by: Jan Kiszka <jan.kis...@siemens.com> --- hypervisor/arch/arm64/traps.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/hypervisor/arch/arm64/traps.c b/hypervisor/arch/arm64/traps.c index 26bdc2e..de48f01 100644 --- a/hypervisor/arch/arm64/traps.c +++ b/hypervisor/arch/arm64/traps.c @@ -43,6 +43,38 @@ static void dump_regs(struct trap_context *ctx) panic_printk("\n"); } +/* TODO: move this function to an arch-independent code if other architectures + * will need it. + */ +static void dump_mem(unsigned long start, unsigned long stop) +{ + unsigned long caddr = start & ~0x1f; + + if (stop <= start) + return; + printk("(0x%016lx - 0x%016lx):", start, stop); + for (;;) { + printk("\n%04lx: ", caddr & 0xffe0); + do { + if (caddr >= start) + printk("%08x ", *(unsigned int *)caddr); + else + printk(" ", *(unsigned int *)caddr); + caddr += 4; + } while ((caddr & 0x1f) && caddr < stop); + if (caddr >= stop) + break; + } + printk("\n"); +} + +static void dump_hyp_stack(const struct trap_context *ctx) +{ + panic_printk("Hypervisor stack before exception "); + dump_mem(ctx->sp, (unsigned long)this_cpu_data()->stack + + sizeof(this_cpu_data()->stack)); +} + static void fill_trap_context(struct trap_context *ctx, struct registers *regs) { arm_read_sysreg(SPSR_EL2, ctx->spsr); @@ -52,7 +84,10 @@ static void fill_trap_context(struct trap_context *ctx, struct registers *regs) case 1: arm_read_sysreg(SP_EL1, ctx->sp); break; case 2: - arm_read_sysreg(SP_EL2, ctx->sp); break; + /* SP_EL2 is not accessible in EL2. To obtain SP value before + * the excepton we can use the regs parameter. regs is located + * on the stack (see handle_vmexit in exception.S) */ + ctx->sp = (u64)(regs) + 16 * 16; break; default: ctx->sp = 0; break; /* should never happen */ } @@ -91,6 +126,7 @@ static void arch_dump_exit(struct registers *regs, const char *reason) fill_trap_context(&ctx, regs); panic_printk("\nFATAL: Unhandled HYP exception: %s\n", reason); dump_regs(&ctx); + dump_hyp_stack(&ctx); } struct registers *arch_handle_exit(struct per_cpu *cpu_data, -- 2.1.4 -- You received this message because you are subscribed to the Google Groups "Jailhouse" group. To unsubscribe from this group and stop receiving emails from it, send an email to jailhouse-dev+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.