[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 06/17] xen: arm: improve register dump output for 64-bit guest (and more generally too)



Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
 xen/arch/arm/traps.c         |  171 +++++++++++++++++++++++++++--------------
 xen/include/asm-arm/cpregs.h |    1 +
 2 files changed, 113 insertions(+), 59 deletions(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index db00c68..3d33fba 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -241,7 +241,7 @@ void panic_PAR(uint64_t par)
 
     msg = decode_fsc( (par&PAR_FSC_MASK) >> PAR_FSC_SHIFT, &level);
 
-    printk("PAR: %010"PRIx64": %s stage %d%s%s\n",
+    printk("PAR: %016"PRIx64": %s stage %d%s%s\n",
            par, msg,
            stage,
            second_in_first ? " during second stage lookup" : "",
@@ -299,33 +299,60 @@ static void inject_undef_exception(struct cpu_user_regs 
*regs,
 }
 
 struct reg_ctxt {
-    uint32_t sctlr, tcr;
-    uint64_t ttbr0, ttbr1;
+    /* Guest-side state */
+    uint32_t sctlr_el1, tcr_el1;
+    uint64_t ttbr0_el1, ttbr1_el1;
 #ifdef CONFIG_ARM_32
+    uint32_t dfsr, ifsr;
     uint32_t dfar, ifar;
 #else
+    uint32_t esr_el1;
     uint64_t far;
+    uint32_t ifsr32_el2;
 #endif
+
+    /* Hypervisor-side state */
+    uint64_t vttbr_el2;
 };
 
+static const char *mode_string(uint32_t cpsr)
+{
+    uint32_t mode;
+    static const char *mode_strings[] = {
+       [PSR_MODE_USR] = "32-bit Guest USR",
+       [PSR_MODE_FIQ] = "32-bit Guest FIQ",
+       [PSR_MODE_IRQ] = "32-bit Guest IRQ",
+       [PSR_MODE_SVC] = "32-bit Guest SVC",
+       [PSR_MODE_MON] = "32-bit Monitor",
+       [PSR_MODE_ABT] = "32-bit Guest ABT",
+       [PSR_MODE_HYP] = "Hypervisor",
+       [PSR_MODE_UND] = "32-bit Guest UND",
+       [PSR_MODE_SYS] = "32-bit Guest SYS",
+#ifdef CONFIG_ARM_64
+       [PSR_MODE_EL3h] = "64-bit EL3h (Monitor, handler)",
+       [PSR_MODE_EL3t] = "64-bit EL3t (Monitor, thread)",
+       [PSR_MODE_EL2h] = "64-bit EL2h (Hypervisor, handler)",
+       [PSR_MODE_EL2t] = "64-bit EL2t (Hypervisor, thread)",
+       [PSR_MODE_EL1h] = "64-bit EL1h (Guest Kernel, handler)",
+       [PSR_MODE_EL1t] = "64-bit EL1t (Guest Kernel, thread)",
+       [PSR_MODE_EL0t] = "64-bit EL0t (Guest User)",
+#endif
+    };
+    mode = cpsr & PSR_MODE_MASK;
+
+    if ( mode > ARRAY_SIZE(mode_strings) )
+        return "Unknown";
+    return mode_strings[mode] ? : "Unknown";
+}
+
 static void show_registers_32(struct cpu_user_regs *regs,
                               struct reg_ctxt *ctxt,
                               int guest_mode,
                               const struct vcpu *v)
 {
-    static const char *mode_strings[] = {
-       [PSR_MODE_USR] = "USR",
-       [PSR_MODE_FIQ] = "FIQ",
-       [PSR_MODE_IRQ] = "IRQ",
-       [PSR_MODE_SVC] = "SVC",
-       [PSR_MODE_MON] = "MON",
-       [PSR_MODE_ABT] = "ABT",
-       [PSR_MODE_HYP] = "HYP",
-       [PSR_MODE_UND] = "UND",
-       [PSR_MODE_SYS] = "SYS"
-    };
 
 #ifdef CONFIG_ARM_64
+    BUG_ON( ! (regs->cpsr & PSR_MODE_BIT) );
     printk("PC:     %08"PRIx32"\n", regs->pc32);
 #else
     printk("PC:     %08"PRIx32, regs->pc);
@@ -333,9 +360,8 @@ static void show_registers_32(struct cpu_user_regs *regs,
         print_symbol(" %s", regs->pc);
     printk("\n");
 #endif
-    printk("CPSR:   %08"PRIx32" MODE:%s%s\n", regs->cpsr,
-           guest_mode ? "32-bit Guest " : "Hypervisor",
-           guest_mode ? mode_strings[regs->cpsr & PSR_MODE_MASK] : "");
+    printk("CPSR:   %08"PRIx32" MODE:%s\n", regs->cpsr,
+           mode_string(regs->cpsr));
     printk("     R0: %08"PRIx32" R1: %08"PRIx32" R2: %08"PRIx32" R3: 
%08"PRIx32"\n",
            regs->r0, regs->r1, regs->r2, regs->r3);
     printk("     R4: %08"PRIx32" R5: %08"PRIx32" R6: %08"PRIx32" R7: 
%08"PRIx32"\n",
@@ -376,15 +402,19 @@ static void show_registers_32(struct cpu_user_regs *regs,
 
     if ( guest_mode )
     {
-        printk("TTBR0 %010"PRIx64" TTBR1 %010"PRIx64" TCR %08"PRIx32"\n",
-               ctxt->ttbr0, ctxt->ttbr1, ctxt->tcr);
-        printk("SCTLR %08"PRIx32"\n", ctxt->sctlr);
-        printk("IFAR %08"PRIx32" DFAR %08"PRIx32"\n",
+        printk("     SCTLR: %08"PRIx32"\n", ctxt->sctlr_el1);
+        printk("       TCR: %08"PRIx32"\n", ctxt->tcr_el1);
+        printk("     TTBR0: %016"PRIx64"\n", ctxt->ttbr0_el1);
+        printk("     TTBR1: %016"PRIx64"\n", ctxt->ttbr1_el1);
+        printk("      IFAR: %08"PRIx32", IFSR: %08"PRIx32"\n"
+               "      DFAR: %08"PRIx32", DFSR: %08"PRIx32"\n",
 #ifdef CONFIG_ARM_64
                (uint32_t)(ctxt->far >> 32),
-               (uint32_t)(ctxt->far & 0xffffffff)
+               ctxt->ifsr32_el2,
+               (uint32_t)(ctxt->far & 0xffffffff),
+               ctxt->esr_el1
 #else
-               ctxt->ifar, ctxt->dfar
+               ctxt->ifar, ctxt->ifsr, ctxt->dfar, ctxt->dfsr
 #endif
             );
         printk("\n");
@@ -397,13 +427,25 @@ static void show_registers_64(struct cpu_user_regs *regs,
                               int guest_mode,
                               const struct vcpu *v)
 {
+
+    BUG_ON( (regs->cpsr & PSR_MODE_BIT) );
+
     printk("PC:     %016"PRIx64, regs->pc);
     if ( !guest_mode )
         print_symbol(" %s", regs->pc);
     printk("\n");
-    printk("SP:     %08"PRIx64"\n", regs->sp);
+    printk("LR:     %016"PRIx64"\n", regs->lr);
+    if ( guest_mode )
+    {
+        printk("SP_EL0: %016"PRIx64"\n", regs->sp_el0);
+        printk("SP_EL1: %016"PRIx64"\n", regs->sp_el1);
+    }
+    else
+    {
+        printk("SP:     %016"PRIx64"\n", regs->sp);
+    }
     printk("CPSR:   %08"PRIx32" MODE:%s\n", regs->cpsr,
-           guest_mode ? "64-bit Guest" : "Hypervisor");
+           mode_string(regs->cpsr));
     printk("     X0: %016"PRIx64"  X1: %016"PRIx64"  X2: %016"PRIx64"\n",
            regs->x0, regs->x1, regs->x2);
     printk("     X3: %016"PRIx64"  X4: %016"PRIx64"  X5: %016"PRIx64"\n",
@@ -422,17 +464,20 @@ static void show_registers_64(struct cpu_user_regs *regs,
            regs->x21, regs->x22, regs->x23);
     printk("    X24: %016"PRIx64" X25: %016"PRIx64" X26: %016"PRIx64"\n",
            regs->x24, regs->x25, regs->x26);
-    printk("    X27: %016"PRIx64" X28: %016"PRIx64" X29: %016"PRIx64"\n",
-           regs->x27, regs->x28, regs->lr);
+    printk("    X27: %016"PRIx64" X28: %016"PRIx64"  FP: %016"PRIx64"\n",
+           regs->x27, regs->x28, regs->fp);
     printk("\n");
 
     if ( guest_mode )
     {
-        printk("SCTLR_EL1: %08"PRIx32"\n", ctxt->sctlr);
-        printk("  TCR_EL1: %08"PRIx32"\n", ctxt->tcr);
-        printk("TTBR0_EL1: %010"PRIx64"\n", ctxt->ttbr0);
-        printk("TTBR1_EL1: %010"PRIx64"\n", ctxt->ttbr1);
-        printk("  FAR_EL1: %010"PRIx64"\n", ctxt->far);
+        printk("   ELR_EL1: %016"PRIx64"\n", regs->elr_el1);
+        printk("   ESR_EL1: %08"PRIx32"\n", ctxt->esr_el1);
+        printk("   FAR_EL1: %016"PRIx64"\n", ctxt->far);
+        printk("\n");
+        printk(" SCTLR_EL1: %08"PRIx32"\n", ctxt->sctlr_el1);
+        printk("   TCR_EL1: %08"PRIx32"\n", ctxt->tcr_el1);
+        printk(" TTBR0_EL1: %016"PRIx64"\n", ctxt->ttbr0_el1);
+        printk(" TTBR1_EL1: %016"PRIx64"\n", ctxt->ttbr1_el1);
         printk("\n");
     }
 }
@@ -464,60 +509,68 @@ static void _show_registers(struct cpu_user_regs *regs,
         show_registers_32(regs, ctxt, guest_mode, v);
 #endif
     }
-
-#ifdef CONFIG_ARM_32
-    printk("HTTBR %"PRIx64"\n", READ_CP64(HTTBR));
-    printk("HDFAR %"PRIx32"\n", READ_CP32(HDFAR));
-    printk("HIFAR %"PRIx32"\n", READ_CP32(HIFAR));
-    printk("HPFAR %"PRIx32"\n", READ_CP32(HPFAR));
-    printk("HCR %08"PRIx32"\n", READ_CP32(HCR));
-    printk("HSR   %"PRIx32"\n", READ_CP32(HSR));
-    printk("VTTBR %010"PRIx64"\n", READ_CP64(VTTBR));
+    printk("  VTCR_EL2: %08"PRIx32"\n", READ_SYSREG32(VTCR_EL2));
+    printk(" VTTBR_EL2: %016"PRIx64"\n", ctxt->vttbr_el2);
     printk("\n");
 
-    printk("DFSR %"PRIx32" DFAR %"PRIx32"\n", READ_CP32(DFSR), 
READ_CP32(DFAR));
-    printk("IFSR %"PRIx32" IFAR %"PRIx32"\n", READ_CP32(IFSR), 
READ_CP32(IFAR));
+    printk(" SCTLR_EL2: %08"PRIx32"\n", READ_SYSREG32(SCTLR_EL2));
+    printk("   HCR_EL2: %016"PRIregister"\n", READ_SYSREG(HCR_EL2));
+    printk(" TTBR0_EL2: %016"PRIx64"\n", READ_SYSREG64(TTBR0_EL2));
     printk("\n");
+    printk("   ESR_EL2: %08"PRIx32"\n", READ_SYSREG32(ESR_EL2));
+    printk(" HPFAR_EL2: %016"PRIregister"\n", READ_SYSREG(HPFAR_EL2));
+
+#ifdef CONFIG_ARM_32
+    printk("     HDFAR: %08"PRIx32"\n", READ_CP32(HDFAR));
+    printk("     HIFAR: %08"PRIx32"\n", READ_CP32(HIFAR));
 #else
-    printk("TTBR0_EL2: %"PRIx64"\n", READ_SYSREG64(TTBR0_EL2));
-    printk("  FAR_EL2: %"PRIx64"\n", READ_SYSREG64(FAR_EL2));
-    printk("HPFAR_EL2: %"PRIx64"\n", READ_SYSREG64(HPFAR_EL2));
-    printk("  HCR_EL2: %"PRIx64"\n", READ_SYSREG64(HCR_EL2));
-    printk("  ESR_EL2: %"PRIx64"\n", READ_SYSREG64(ESR_EL2));
-    printk("VTTBR_EL2: %"PRIx64"\n", READ_SYSREG64(VTTBR_EL2));
-    printk("\n");
+    printk("   FAR_EL2: %016"PRIx64"\n", READ_SYSREG64(FAR_EL2));
 #endif
+    printk("\n");
 }
 
 void show_registers(struct cpu_user_regs *regs)
 {
     struct reg_ctxt ctxt;
-    ctxt.sctlr = READ_SYSREG(SCTLR_EL1);
-    ctxt.tcr = READ_SYSREG(TCR_EL1);
-    ctxt.ttbr0 = READ_SYSREG64(TTBR0_EL1);
-    ctxt.ttbr1 = READ_SYSREG64(TTBR1_EL1);
+    ctxt.sctlr_el1 = READ_SYSREG(SCTLR_EL1);
+    ctxt.tcr_el1 = READ_SYSREG(TCR_EL1);
+    ctxt.ttbr0_el1 = READ_SYSREG64(TTBR0_EL1);
+    ctxt.ttbr1_el1 = READ_SYSREG64(TTBR1_EL1);
 #ifdef CONFIG_ARM_32
     ctxt.dfar = READ_CP32(DFAR);
     ctxt.ifar = READ_CP32(IFAR);
+    ctxt.dfsr = READ_CP32(DFSR);
+    ctxt.ifsr = READ_CP32(IFSR);
 #else
     ctxt.far = READ_SYSREG(FAR_EL1);
+    ctxt.esr_el1 = READ_SYSREG(ESR_EL1);
+    ctxt.ifsr32_el2 = READ_SYSREG(IFSR32_EL2);
 #endif
+    ctxt.vttbr_el2 = READ_SYSREG64(VTTBR_EL2);
+
     _show_registers(regs, &ctxt, guest_mode(regs), current);
 }
 
 void vcpu_show_registers(const struct vcpu *v)
 {
     struct reg_ctxt ctxt;
-    ctxt.sctlr = v->arch.sctlr;
-    ctxt.tcr = v->arch.ttbcr;
-    ctxt.ttbr0 = v->arch.ttbr0;
-    ctxt.ttbr1 = v->arch.ttbr1;
+    ctxt.sctlr_el1 = v->arch.sctlr;
+    ctxt.tcr_el1 = v->arch.ttbcr;
+    ctxt.ttbr0_el1 = v->arch.ttbr0;
+    ctxt.ttbr1_el1 = v->arch.ttbr1;
 #ifdef CONFIG_ARM_32
     ctxt.dfar = v->arch.dfar;
     ctxt.ifar = v->arch.ifar;
+    ctxt.dfsr = v->arch.dfsr;
+    ctxt.ifsr = v->arch.ifsr;
 #else
     ctxt.far = v->arch.far;
+    ctxt.esr_el1 = v->arch.esr;
+    ctxt.ifsr32_el2 = v->arch.ifsr;
 #endif
+
+    ctxt.vttbr_el2 = v->domain->arch.vttbr;
+
     _show_registers(&v->arch.cpu_info->guest_cpu_user_regs, &ctxt, 1, v);
 }
 
@@ -957,7 +1010,7 @@ void dump_guest_s1_walk(struct domain *d, vaddr_t addr)
 
     printk("dom%d VA 0x%08"PRIvaddr"\n", d->domain_id, addr);
     printk("    TTBCR: 0x%08"PRIx32"\n", ttbcr);
-    printk("    TTBR0: 0x%010"PRIx64" = 0x%"PRIpaddr"\n",
+    printk("    TTBR0: 0x%016"PRIx64" = 0x%"PRIpaddr"\n",
            ttbr0, p2m_lookup(d, ttbr0 & PAGE_MASK));
 
     if ( ttbcr & TTBCR_EAE )
diff --git a/xen/include/asm-arm/cpregs.h b/xen/include/asm-arm/cpregs.h
index 122dd1a..2960492 100644
--- a/xen/include/asm-arm/cpregs.h
+++ b/xen/include/asm-arm/cpregs.h
@@ -259,6 +259,7 @@
 #define DACR32_EL2              DACR
 #define ESR_EL2                 HSR
 #define HCR_EL2                 HCR
+#define HPFAR_EL2               HPFAR
 #define ID_AFR0_EL1             ID_AFR0
 #define ID_DFR0_EL1             ID_DFR0
 #define ID_ISAR0_EL1            ID_ISAR0
-- 
1.7.2.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.