aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/io.c
diff options
context:
space:
mode:
authorTim Deegan <Tim.Deegan@xensource.com>2007-02-20 15:37:03 +0000
committerTim Deegan <Tim.Deegan@xensource.com>2007-02-20 15:37:03 +0000
commit621bd0c079569d4b1f2046a46386836888ae4e4f (patch)
treef1f43a1700261c835620890d6c054dbb5923bc34 /xen/arch/x86/hvm/io.c
parent25fc3fb4645e8d079f8e3648ec40fa08088b30fd (diff)
downloadxen-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.c30
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);
}