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.

Reply via email to