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

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



At 13:20 +0100 on 29 Jul (1375104055), Ian Campbell wrote:
> Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

Acked-by: Tim Deegan <tim@xxxxxxx>

> ---
>  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

_______________________________________________
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®.