[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 21/38] arm: dump guest s1 walk on data abort which is not a stage 2 issue.
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- xen/arch/arm/traps.c | 75 +++++++++++++++++++++++++++++++++++--- xen/include/asm-arm/processor.h | 1 + 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 40bb375..35907ee 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -28,6 +28,7 @@ #include <xen/errno.h> #include <xen/hypercall.h> #include <xen/softirq.h> +#include <xen/domain_page.h> #include <public/xen.h> #include <asm/regs.h> #include <asm/cpregs.h> @@ -528,6 +529,62 @@ static void do_cp15_64(struct cpu_user_regs *regs, } +void dump_guest_s1_walk(struct domain *d, uint32_t addr) +{ + uint32_t ttbcr = READ_CP32(TTBCR); + uint32_t ttbr0 = READ_CP32(TTBR0); + paddr_t paddr; + uint32_t offset; + uint32_t *first = NULL, *second = NULL; + + printk("dom%d VA %#010"PRIx32"\n", d->domain_id, addr); + printk(" TTBCR: %#010"PRIx32"\n", ttbcr); + printk(" TTBR0: %#010"PRIx32" = %#"PRIpaddr"\n", + ttbr0, p2m_lookup(d, ttbr0 & PAGE_MASK)); + + if ( ttbcr & TTBCR_EAE ) + { + printk("Cannot handle LPAE guest PT walk\n"); + return; + } + if ( (ttbcr & TTBCR_N_MASK) != 0 ) + { + printk("Cannot handle TTBR1 guest walks\n"); + return; + } + + paddr = p2m_lookup(d, ttbr0 & PAGE_MASK); + if ( paddr == INVALID_PADDR ) + { + printk("Failed TTBR0 maddr lookup\n"); + goto done; + } + first = map_domain_page(paddr>>PAGE_SHIFT); + + offset = addr >> (12+10); + printk("1ST[%#03"PRIx32"] (%#"PRIpaddr") = %#010"PRIx32"\n", + offset, paddr, first[offset]); + if ( !(first[offset] & 0x1) || + !(first[offset] & 0x2) ) + goto done; + + paddr = p2m_lookup(d, first[offset] & PAGE_MASK); + + if ( paddr == INVALID_PADDR ) + { + printk("Failed L1 entry maddr lookup\n"); + goto done; + } + second = map_domain_page(paddr>>PAGE_SHIFT); + offset = (addr >> 12) & 0x3FF; + printk("2ND[%#03"PRIx32"] (%#"PRIpaddr") = %#010"PRIx32"\n", + offset, paddr, second[offset]); + +done: + if (second) unmap_domain_page(second); + if (first) unmap_domain_page(first); +} + static void do_trap_data_abort_guest(struct cpu_user_regs *regs, struct hsr_dabt dabt) { @@ -535,11 +592,12 @@ static void do_trap_data_abort_guest(struct cpu_user_regs *regs, int level = -1; mmio_info_t info; + info.dabt = dabt; + info.gva = READ_CP32(HDFAR); + if (dabt.s1ptw) goto bad_data_abort; - info.dabt = dabt; - info.gva = READ_CP32(HDFAR); info.gpa = gva_to_ipa(info.gva); if (handle_mmio(&info)) @@ -553,18 +611,23 @@ bad_data_abort: msg = decode_fsc( dabt.dfsc, &level); printk("Guest data abort: %s%s%s\n" - " gva=%"PRIx32" gpa=%"PRIpaddr"\n", + " gva=%"PRIx32"\n", msg, dabt.s1ptw ? " S2 during S1" : "", fsc_level_str(level), - info.gva, info.gpa); - if (dabt.valid) + info.gva); + if ( !dabt.s1ptw ) + printk(" gpa=%"PRIpaddr"\n", info.gpa); + if ( dabt.valid ) printk(" size=%d sign=%d write=%d reg=%d\n", dabt.size, dabt.sign, dabt.write, dabt.reg); else printk(" instruction syndrome invalid\n"); printk(" eat=%d cm=%d s1ptw=%d dfsc=%d\n", dabt.eat, dabt.cache, dabt.s1ptw, dabt.dfsc); - + if ( !dabt.s1ptw ) + dump_p2m_lookup(current->domain, info.gpa); + else + dump_guest_s1_walk(current->domain, info.gva); show_execution_state(regs); panic("Unhandled guest data abort\n"); } diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h index ec6fb48..81924a4 100644 --- a/xen/include/asm-arm/processor.h +++ b/xen/include/asm-arm/processor.h @@ -25,6 +25,7 @@ #define PSR_JAZELLE (1<<24) /* Jazelle Mode */ /* TTBCR Translation Table Base Control Register */ +#define TTBCR_EAE 0x80000000 #define TTBCR_N_MASK 0x07 #define TTBCR_N_16KB 0x00 #define TTBCR_N_8KB 0x01 -- 1.7.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |