[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] xen: arm: do not panic when failing to translate a guest address
# HG changeset patch # User Ian Campbell <ian.campbell@xxxxxxxxxx> # Date 1359031675 0 # Node ID a26b37fdfd3d4a124338073089fae52624912ce2 # Parent b6fd9302594bee36e31d20dc14b65fbd2819d2d0 xen: arm: do not panic when failing to translate a guest address The gva_to_{par,ipa} functions currently panic if the guest address cannot be translated. Often the input comes from the guest so panicing the host is a bit harsh! Change the API of those functions to allow them to return a failure and plumb it through where it is used. Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> Acked-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> Committed-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- diff -r b6fd9302594b -r a26b37fdfd3d xen/arch/arm/guestcopy.c --- a/xen/arch/arm/guestcopy.c Thu Jan 24 12:47:55 2013 +0000 +++ b/xen/arch/arm/guestcopy.c Thu Jan 24 12:47:55 2013 +0000 @@ -12,10 +12,16 @@ unsigned long raw_copy_to_guest(void *to while ( len ) { - paddr_t g = gvirt_to_maddr((uint32_t) to); - void *p = map_domain_page(g>>PAGE_SHIFT); + int rc; + paddr_t g; + void *p; unsigned size = min(len, (unsigned)PAGE_SIZE - offset); + rc = gvirt_to_maddr((uint32_t) to, &g); + if ( rc ) + return rc; + + p = map_domain_page(g>>PAGE_SHIFT); p += offset; memcpy(p, from, size); @@ -36,10 +42,16 @@ unsigned long raw_clear_guest(void *to, while ( len ) { - paddr_t g = gvirt_to_maddr((uint32_t) to); - void *p = map_domain_page(g>>PAGE_SHIFT); + int rc; + paddr_t g; + void *p; unsigned size = min(len, (unsigned)PAGE_SIZE - offset); + rc = gvirt_to_maddr((uint32_t) to, &g); + if ( rc ) + return rc; + + p = map_domain_page(g>>PAGE_SHIFT); p += offset; memset(p, 0x00, size); @@ -56,10 +68,16 @@ unsigned long raw_copy_from_guest(void * { while ( len ) { - paddr_t g = gvirt_to_maddr((uint32_t) from & PAGE_MASK); - void *p = map_domain_page(g>>PAGE_SHIFT); + int rc; + paddr_t g; + void *p; unsigned size = min(len, (unsigned)(PAGE_SIZE - ((unsigned)from & (~PAGE_MASK)))); + rc = gvirt_to_maddr((uint32_t) from & PAGE_MASK, &g); + if ( rc ) + return rc; + + p = map_domain_page(g>>PAGE_SHIFT); p += ((unsigned long)from & (~PAGE_MASK)); memcpy(to, p, size); diff -r b6fd9302594b -r a26b37fdfd3d xen/arch/arm/kernel.c --- a/xen/arch/arm/kernel.c Thu Jan 24 12:47:55 2013 +0000 +++ b/xen/arch/arm/kernel.c Thu Jan 24 12:47:55 2013 +0000 @@ -76,12 +76,22 @@ static void kernel_zimage_load(struct ke paddr, load_addr, load_addr + len); for ( offs = 0; offs < len; ) { - paddr_t s, l, ma = gvirt_to_maddr(load_addr + offs); - void *dst = map_domain_page(ma>>PAGE_SHIFT); + int rc; + paddr_t s, l, ma; + void *dst; s = offs & ~PAGE_MASK; l = min(PAGE_SIZE - s, len); + rc = gvirt_to_maddr(load_addr + offs, &ma); + if ( rc ) + { + panic("\nUnable to map translate guest address\n"); + return; + } + + dst = map_domain_page(ma>>PAGE_SHIFT); + copy_from_paddr(dst + s, paddr + offs, l, attr); unmap_domain_page(dst); diff -r b6fd9302594b -r a26b37fdfd3d xen/arch/arm/traps.c --- a/xen/arch/arm/traps.c Thu Jan 24 12:47:55 2013 +0000 +++ b/xen/arch/arm/traps.c Thu Jan 24 12:47:55 2013 +0000 @@ -200,32 +200,22 @@ static const char *fsc_level_str(int lev } } -void panic_PAR(uint64_t par, const char *when) +void panic_PAR(uint64_t par) { - if ( par & PAR_F ) - { - const char *msg; - int level = -1; - int stage = par & PAR_STAGE2 ? 2 : 1; - int second_in_first = !!(par & PAR_STAGE21); + const char *msg; + int level = -1; + int stage = par & PAR_STAGE2 ? 2 : 1; + int second_in_first = !!(par & PAR_STAGE21); - msg = decode_fsc( (par&PAR_FSC_MASK) >> PAR_FSC_SHIFT, &level); + msg = decode_fsc( (par&PAR_FSC_MASK) >> PAR_FSC_SHIFT, &level); - printk("PAR: %010"PRIx64": %s stage %d%s%s\n", - par, msg, - stage, - second_in_first ? " during second stage lookup" : "", - fsc_level_str(level)); - } - else - { - printk("PAR: %010"PRIx64": paddr:%010"PRIx64 - " attr %"PRIx64" sh %"PRIx64" %s\n", - par, par & PADDR_MASK, par >> PAR_MAIR_SHIFT, - (par & PAR_SH_MASK) >> PAR_SH_SHIFT, - (par & PAR_NS) ? "Non-Secure" : "Secure"); - } - panic("Error during %s-to-physical address translation\n", when); + printk("PAR: %010"PRIx64": %s stage %d%s%s\n", + par, msg, + stage, + second_in_first ? " during second stage lookup" : "", + fsc_level_str(level)); + + panic("Error during Hypervisor-to-physical address translation\n"); } struct reg_ctxt { @@ -721,7 +711,7 @@ static void do_trap_data_abort_guest(str struct hsr_dabt dabt) { const char *msg; - int level = -1; + int rc, level = -1; mmio_info_t info; info.dabt = dabt; @@ -730,7 +720,9 @@ static void do_trap_data_abort_guest(str if (dabt.s1ptw) goto bad_data_abort; - info.gpa = gva_to_ipa(info.gva); + rc = gva_to_ipa(info.gva, &info.gpa); + if ( rc == -EFAULT ) + goto bad_data_abort; if (handle_mmio(&info)) { @@ -742,6 +734,7 @@ bad_data_abort: msg = decode_fsc( dabt.dfsc, &level); + /* XXX inject a suitable fault into the guest */ printk("Guest data abort: %s%s%s\n" " gva=%"PRIx32"\n", msg, dabt.s1ptw ? " S2 during S1" : "", @@ -761,7 +754,7 @@ bad_data_abort: else dump_guest_s1_walk(current->domain, info.gva); show_execution_state(regs); - panic("Unhandled guest data abort\n"); + domain_crash_synchronous(); } asmlinkage void do_trap_hypervisor(struct cpu_user_regs *regs) diff -r b6fd9302594b -r a26b37fdfd3d xen/include/asm-arm/mm.h --- a/xen/include/asm-arm/mm.h Thu Jan 24 12:47:55 2013 +0000 +++ b/xen/include/asm-arm/mm.h Thu Jan 24 12:47:55 2013 +0000 @@ -192,10 +192,13 @@ static inline void *maddr_to_virt(paddr_ return (void *)(unsigned long) ma + XENHEAP_VIRT_START; } -static inline paddr_t gvirt_to_maddr(uint32_t va) +static inline int gvirt_to_maddr(uint32_t va, paddr_t *pa) { - uint64_t par = gva_to_par(va); - return (par & PADDR_MASK & PAGE_MASK) | ((unsigned long) va & ~PAGE_MASK); + uint64_t par = gva_to_ma_par(va); + if ( par & PAR_F ) + return -EFAULT; + *pa = (par & PADDR_MASK & PAGE_MASK) | ((unsigned long) va & ~PAGE_MASK); + return 0; } /* Convert between Xen-heap virtual addresses and machine addresses. */ diff -r b6fd9302594b -r a26b37fdfd3d xen/include/asm-arm/page.h --- a/xen/include/asm-arm/page.h Thu Jan 24 12:47:55 2013 +0000 +++ b/xen/include/asm-arm/page.h Thu Jan 24 12:47:55 2013 +0000 @@ -2,6 +2,7 @@ #define __ARM_PAGE_H__ #include <xen/config.h> +#include <xen/errno.h> #include <public/xen.h> #include <asm/processor.h> @@ -366,13 +367,13 @@ static inline uint64_t va_to_par(uint32_ if ( par & PAR_F ) { dump_hyp_walk(va); - panic_PAR(par, "Hypervisor"); + panic_PAR(par); } return par; } /* Ask the MMU to translate a Guest VA for us */ -static inline uint64_t __gva_to_par(uint32_t va) +static inline uint64_t gva_to_ma_par(uint32_t va) { uint64_t par, tmp; tmp = READ_CP64(PAR); @@ -382,15 +383,7 @@ static inline uint64_t __gva_to_par(uint WRITE_CP64(tmp, PAR); return par; } -static inline uint64_t gva_to_par(uint32_t va) -{ - uint64_t par = __gva_to_par(va); - /* It is not OK to call this with an invalid VA */ - /* XXX harsh for a guest address... */ - if ( par & PAR_F ) panic_PAR(par, "Guest"); - return par; -} -static inline uint64_t __gva_to_ipa(uint32_t va) +static inline uint64_t gva_to_ipa_par(uint32_t va) { uint64_t par, tmp; tmp = READ_CP64(PAR); @@ -400,14 +393,16 @@ static inline uint64_t __gva_to_ipa(uint WRITE_CP64(tmp, PAR); return par; } -static inline uint64_t gva_to_ipa(uint32_t va) + +static inline int gva_to_ipa(uint32_t va, paddr_t *paddr) { - uint64_t par = __gva_to_ipa(va); - /* It is not OK to call this with an invalid VA */ - /* XXX harsh for a guest address... */ - if ( par & PAR_F ) panic_PAR(par, "Guest"); - return (par & PADDR_MASK & PAGE_MASK) | ((unsigned long) va & ~PAGE_MASK); + uint64_t par = gva_to_ipa_par(va); + if ( par & PAR_F ) + return -EFAULT; + *paddr = (par & PADDR_MASK & PAGE_MASK) | ((unsigned long) va & ~PAGE_MASK); + return 0; } + /* Bits in the PAR returned by va_to_par */ #define PAR_FAULT 0x1 diff -r b6fd9302594b -r a26b37fdfd3d xen/include/asm-arm/processor.h --- a/xen/include/asm-arm/processor.h Thu Jan 24 12:47:55 2013 +0000 +++ b/xen/include/asm-arm/processor.h Thu Jan 24 12:47:55 2013 +0000 @@ -231,7 +231,7 @@ union hsr { #ifndef __ASSEMBLY__ extern uint32_t hyp_traps_vector[8]; -void panic_PAR(uint64_t par, const char *when); +void panic_PAR(uint64_t par); void show_execution_state(struct cpu_user_regs *regs); void show_registers(struct cpu_user_regs *regs); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |