diff options
author | Tim Deegan <Tim.Deegan@xensource.com> | 2007-02-20 15:37:03 +0000 |
---|---|---|
committer | Tim Deegan <Tim.Deegan@xensource.com> | 2007-02-20 15:37:03 +0000 |
commit | 621bd0c079569d4b1f2046a46386836888ae4e4f (patch) | |
tree | f1f43a1700261c835620890d6c054dbb5923bc34 /xen/arch/x86/hvm/io.c | |
parent | 25fc3fb4645e8d079f8e3648ec40fa08088b30fd (diff) | |
download | xen-621bd0c079569d4b1f2046a46386836888ae4e4f.tar.gz xen-621bd0c079569d4b1f2046a46386836888ae4e4f.tar.bz2 xen-621bd0c079569d4b1f2046a46386836888ae4e4f.zip |
[XEN] Get rid of gva_to_gpa translation
It didn't have any sensible error checking. Make all callers
use gva_to_gfn translation and check the result. MMIO and PIO
callers inject pagefaults to the guest iof the non-IO address is
not mapped.
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
Diffstat (limited to 'xen/arch/x86/hvm/io.c')
-rw-r--r-- | xen/arch/x86/hvm/io.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c index 8d369b3b49..43d1343d5f 100644 --- a/xen/arch/x86/hvm/io.c +++ b/xen/arch/x86/hvm/io.c @@ -371,7 +371,20 @@ static void hvm_pio_assist(struct cpu_user_regs *regs, ioreq_t *p, { unsigned long addr = pio_opp->addr; if ( hvm_paging_enabled(current) ) - (void)hvm_copy_to_guest_virt(addr, &p->data, p->size); + { + int rv = hvm_copy_to_guest_virt(addr, &p->data, p->size); + if ( rv != 0 ) + { + /* Failed on the page-spanning copy. Inject PF into + * the guest for the address where we failed. */ + addr += p->size - rv; + gdprintk(XENLOG_DEBUG, "Pagefault writing non-io side " + "of a page-spanning PIO: va=%#lx\n", addr); + hvm_inject_exception(TRAP_page_fault, + PFEC_write_access, addr); + return; + } + } else (void)hvm_copy_to_guest_phys(addr, &p->data, p->size); } @@ -489,7 +502,20 @@ static void hvm_mmio_assist(struct cpu_user_regs *regs, ioreq_t *p, unsigned long addr = mmio_opp->addr; if (hvm_paging_enabled(current)) - (void)hvm_copy_to_guest_virt(addr, &p->data, p->size); + { + int rv = hvm_copy_to_guest_virt(addr, &p->data, p->size); + if ( rv != 0 ) + { + /* Failed on the page-spanning copy. Inject PF into + * the guest for the address where we failed. */ + addr += p->size - rv; + gdprintk(XENLOG_DEBUG, "Pagefault writing non-io side of " + "a page-spanning MMIO: va=%#lx\n", addr); + hvm_inject_exception(TRAP_page_fault, + PFEC_write_access, addr); + return; + } + } else (void)hvm_copy_to_guest_phys(addr, &p->data, p->size); } |