[xen-unstable] vmx realmode: Detect and correctly plumb mmio accesses from emulated

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[xen-unstable] vmx realmode: Detect and correctly plumb mmio accesses from emulated

Xen patchbot-unstable
# HG changeset patch
# User Keir Fraser <[hidden email]>
# Date 1196025888 0
# Node ID bb961bda7eff2bec637a23990caa9cf1bdaf596a
# Parent  6d129d0933942ca2ff672c1f23cf26379c1db129
vmx realmode: Detect and correctly plumb mmio accesses from emulated
realmode. Also correctly handle debug output to I/O port 0xe9.
Signed-off-by: Keir Fraser <[hidden email]>
---
 xen/arch/x86/hvm/platform.c     |    6 +--
 xen/arch/x86/hvm/vmx/realmode.c |   63 ++++++++++++++++++++++++++++++++++++++--
 xen/include/asm-x86/hvm/io.h    |    7 +++-
 3 files changed, 69 insertions(+), 7 deletions(-)

diff -r 6d129d093394 -r bb961bda7eff xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c Sun Nov 25 18:07:33 2007 +0000
+++ b/xen/arch/x86/hvm/platform.c Sun Nov 25 21:24:48 2007 +0000
@@ -885,9 +885,9 @@ void send_pio_req(unsigned long port, un
     hvm_send_assist_req(v);
 }
 
-static void send_mmio_req(unsigned char type, unsigned long gpa,
-                          unsigned long count, int size, paddr_t value,
-                          int dir, int df, int value_is_ptr)
+void send_mmio_req(unsigned char type, unsigned long gpa,
+                   unsigned long count, int size, paddr_t value,
+                   int dir, int df, int value_is_ptr)
 {
     struct vcpu *v = current;
     vcpu_iodata_t *vio;
diff -r 6d129d093394 -r bb961bda7eff xen/arch/x86/hvm/vmx/realmode.c
--- a/xen/arch/x86/hvm/vmx/realmode.c Sun Nov 25 18:07:33 2007 +0000
+++ b/xen/arch/x86/hvm/vmx/realmode.c Sun Nov 25 21:24:48 2007 +0000
@@ -108,8 +108,39 @@ realmode_read(
     struct realmode_emulate_ctxt *rm_ctxt)
 {
     uint32_t addr = rm_ctxt->seg_reg[seg].base + offset;
+    int todo;
+
     *val = 0;
-    (void)hvm_copy_from_guest_phys(val, addr, bytes);
+    todo = hvm_copy_from_guest_phys(val, addr, bytes);
+
+    if ( todo )
+    {
+        struct vcpu *curr = current;
+
+        if ( todo != bytes )
+        {
+            gdprintk(XENLOG_WARNING, "RM: Partial read at %08x (%d/%d)\n",
+                     addr, todo, bytes);
+            return X86EMUL_UNHANDLEABLE;
+        }
+
+        if ( curr->arch.hvm_vmx.real_mode_io_in_progress )
+            return X86EMUL_UNHANDLEABLE;
+
+        if ( !curr->arch.hvm_vmx.real_mode_io_completed )
+        {
+            curr->arch.hvm_vmx.real_mode_io_in_progress = 1;
+            send_mmio_req(IOREQ_TYPE_COPY, addr, 1, bytes,
+                          0, IOREQ_READ, 0, 0);
+        }
+
+        if ( !curr->arch.hvm_vmx.real_mode_io_completed )
+            return X86EMUL_UNHANDLEABLE;
+
+        *val = curr->arch.hvm_vmx.real_mode_io_data;
+        curr->arch.hvm_vmx.real_mode_io_completed = 0;
+    }
+
     return X86EMUL_OKAY;
 }
 
@@ -161,7 +192,29 @@ realmode_emulate_write(
     struct realmode_emulate_ctxt *rm_ctxt =
         container_of(ctxt, struct realmode_emulate_ctxt, ctxt);
     uint32_t addr = rm_ctxt->seg_reg[seg].base + offset;
-    (void)hvm_copy_to_guest_phys(addr, &val, bytes);
+    int todo;
+
+    todo = hvm_copy_to_guest_phys(addr, &val, bytes);
+
+    if ( todo )
+    {
+        struct vcpu *curr = current;
+
+        if ( todo != bytes )
+        {
+            gdprintk(XENLOG_WARNING, "RM: Partial write at %08x (%d/%d)\n",
+                     addr, todo, bytes);
+            return X86EMUL_UNHANDLEABLE;
+        }
+
+        if ( curr->arch.hvm_vmx.real_mode_io_in_progress )
+            return X86EMUL_UNHANDLEABLE;
+
+        curr->arch.hvm_vmx.real_mode_io_in_progress = 1;
+        send_mmio_req(IOREQ_TYPE_COPY, addr, 1, bytes,
+                      val, IOREQ_WRITE, 0, 0);
+    }
+
     return X86EMUL_OKAY;
 }
 
@@ -243,6 +296,12 @@ static int realmode_write_io(
     struct x86_emulate_ctxt *ctxt)
 {
     struct vcpu *curr = current;
+
+    if ( port == 0xe9 )
+    {
+        hvm_print_line(curr, val);
+        return X86EMUL_OKAY;
+    }
 
     if ( curr->arch.hvm_vmx.real_mode_io_in_progress )
         return X86EMUL_UNHANDLEABLE;
diff -r 6d129d093394 -r bb961bda7eff xen/include/asm-x86/hvm/io.h
--- a/xen/include/asm-x86/hvm/io.h Sun Nov 25 18:07:33 2007 +0000
+++ b/xen/include/asm-x86/hvm/io.h Sun Nov 25 21:24:48 2007 +0000
@@ -149,8 +149,11 @@ static inline int register_buffered_io_h
     return register_io_handler(d, addr, size, action, HVM_BUFFERED_IO);
 }
 
-extern void send_pio_req(unsigned long port, unsigned long count, int size,
-                         paddr_t value, int dir, int df, int value_is_ptr);
+void send_mmio_req(unsigned char type, unsigned long gpa,
+                   unsigned long count, int size, paddr_t value,
+                   int dir, int df, int value_is_ptr);
+void send_pio_req(unsigned long port, unsigned long count, int size,
+                  paddr_t value, int dir, int df, int value_is_ptr);
 void send_timeoffset_req(unsigned long timeoff);
 void send_invalidate_req(void);
 extern void handle_mmio(unsigned long gpa);

_______________________________________________
Xen-changelog mailing list
[hidden email]
http://lists.xensource.com/xen-changelog