WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] vmx realmode: Plumb through I/O port acce

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] vmx realmode: Plumb through I/O port accesses in emulated realmode.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sun, 25 Nov 2007 10:30:08 -0800
Delivery-date: Sun, 25 Nov 2007 10:30:23 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1195991033 0
# Node ID 368bcf480772fb32b22fa9cb0bffcd10f0ed2c25
# Parent  ce3e5e859d66455ab31b8db8f286933e455b4f7c
vmx realmode: Plumb through I/O port accesses in emulated realmode.
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/hvm/io.c              |    6 ++-
 xen/arch/x86/hvm/vmx/realmode.c    |   62 ++++++++++++++++++++++++++++++++++---
 xen/arch/x86/hvm/vmx/vmx.c         |    1 
 xen/arch/x86/x86_emulate.c         |   34 +++++++++++++++++---
 xen/include/asm-x86/hvm/vcpu.h     |    3 +
 xen/include/asm-x86/hvm/vmx/vmcs.h |    4 ++
 xen/include/asm-x86/hvm/vmx/vmx.h  |    1 
 7 files changed, 102 insertions(+), 9 deletions(-)

diff -r ce3e5e859d66 -r 368bcf480772 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c     Sun Nov 25 09:23:02 2007 +0000
+++ b/xen/arch/x86/hvm/io.c     Sun Nov 25 11:43:53 2007 +0000
@@ -841,12 +841,16 @@ void hvm_io_assist(void)
     if ( p->state != STATE_IORESP_READY )
     {
         gdprintk(XENLOG_ERR, "Unexpected HVM iorequest state %d.\n", p->state);
-        domain_crash_synchronous();
+        domain_crash(v->domain);
+        goto out;
     }
 
     rmb(); /* see IORESP_READY /then/ read contents of ioreq */
 
     p->state = STATE_IOREQ_NONE;
+
+    if ( v->arch.hvm_vcpu.io_complete && v->arch.hvm_vcpu.io_complete() )
+        goto out;
 
     switch ( p->type )
     {
diff -r ce3e5e859d66 -r 368bcf480772 xen/arch/x86/hvm/vmx/realmode.c
--- a/xen/arch/x86/hvm/vmx/realmode.c   Sun Nov 25 09:23:02 2007 +0000
+++ b/xen/arch/x86/hvm/vmx/realmode.c   Sun Nov 25 11:43:53 2007 +0000
@@ -178,7 +178,24 @@ realmode_read_io(
     unsigned long *val,
     struct x86_emulate_ctxt *ctxt)
 {
-    return X86EMUL_UNHANDLEABLE;
+    struct vcpu *curr = current;
+
+    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_pio_req(port, 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;
 }
 
 static int realmode_write_io(
@@ -187,7 +204,15 @@ static int realmode_write_io(
     unsigned long val,
     struct x86_emulate_ctxt *ctxt)
 {
-    return X86EMUL_UNHANDLEABLE;
+    struct vcpu *curr = current;
+
+    if ( curr->arch.hvm_vmx.real_mode_io_in_progress )
+        return X86EMUL_UNHANDLEABLE;
+
+    curr->arch.hvm_vmx.real_mode_io_in_progress = 1;
+    send_pio_req(port, 1, bytes, val, IOREQ_WRITE, 0, 0);
+
+    return X86EMUL_OKAY;
 }
 
 static int
@@ -259,8 +284,19 @@ int vmx_realmode(struct cpu_user_regs *r
                  rm_ctxt.insn_buf[2], rm_ctxt.insn_buf[3],
                  rm_ctxt.insn_buf[4], rm_ctxt.insn_buf[5]);
 
-        if ( x86_emulate(&rm_ctxt.ctxt, &realmode_emulator_ops) )
-        {            
+        rc = x86_emulate(&rm_ctxt.ctxt, &realmode_emulator_ops);
+
+        if ( curr->arch.hvm_vmx.real_mode_io_in_progress )
+        {
+            ioreq_t *p = &get_ioreq(curr)->vp_ioreq;
+            gdprintk(XENLOG_DEBUG, "RM I/O %d %c addr=%lx data=%lx\n",
+                     p->type, p->dir ? 'R' : 'W', p->addr, p->data);
+            rc = 0;
+            break;
+        }
+
+        if ( rc )
+        {
             gdprintk(XENLOG_ERR, "Emulation failed\n");
             rc = -EINVAL;
             break;
@@ -272,3 +308,21 @@ int vmx_realmode(struct cpu_user_regs *r
 
     return rc;
 }
+
+int vmx_realmode_io_complete(void)
+{
+    struct vcpu *curr = current;
+    ioreq_t *p = &get_ioreq(curr)->vp_ioreq;
+
+    if ( !curr->arch.hvm_vmx.real_mode_io_in_progress )
+        return 0;
+
+    curr->arch.hvm_vmx.real_mode_io_in_progress = 0;
+    if ( p->dir == IOREQ_READ )
+    {
+        curr->arch.hvm_vmx.real_mode_io_completed = 1;
+        curr->arch.hvm_vmx.real_mode_io_data = p->data;
+    }
+
+    return 1;
+}
diff -r ce3e5e859d66 -r 368bcf480772 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Sun Nov 25 09:23:02 2007 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Sun Nov 25 11:43:53 2007 +0000
@@ -95,6 +95,7 @@ static int vmx_vcpu_initialise(struct vc
 #ifndef VMXASSIST
     if ( v->vcpu_id == 0 )
         v->arch.guest_context.user_regs.eax = 1;
+    v->arch.hvm_vcpu.io_complete = vmx_realmode_io_complete;
 #endif
 
     return 0;
diff -r ce3e5e859d66 -r 368bcf480772 xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c        Sun Nov 25 09:23:02 2007 +0000
+++ b/xen/arch/x86/x86_emulate.c        Sun Nov 25 11:43:53 2007 +0000
@@ -264,6 +264,7 @@ struct operand {
 };
 
 /* EFLAGS bit definitions. */
+#define EFLG_VM (1<<17)
 #define EFLG_RF (1<<16)
 #define EFLG_OF (1<<11)
 #define EFLG_DF (1<<10)
@@ -478,10 +479,6 @@ do {                                    
 /* In future we will be able to generate arbitrary exceptions. */
 #define generate_exception_if(p, e) fail_if(p)
 
-/* To be done... */
-#define mode_ring0() (0)
-#define mode_iopl()  (0)
-
 /* Given byte has even parity (even number of 1s)? */
 static int even_parity(uint8_t v)
 {
@@ -678,6 +675,35 @@ test_cc(
     /* Odd condition identifiers (lsb == 1) have inverted sense. */
     return (!!rc ^ (condition & 1));
 }
+
+static int
+get_cpl(
+    struct x86_emulate_ctxt *ctxt,
+    struct x86_emulate_ops  *ops)
+{
+    struct segment_register reg;
+
+    if ( ctxt->regs->eflags & EFLG_VM )
+        return 3;
+
+    if ( (ops->read_segment == NULL) ||
+         ops->read_segment(x86_seg_ss, &reg, ctxt) )
+        return -1;
+
+    return reg.attr.fields.dpl;
+}
+
+static int
+_mode_iopl(
+    struct x86_emulate_ctxt *ctxt,
+    struct x86_emulate_ops  *ops)
+{
+    int cpl = get_cpl(ctxt, ops);
+    return ((cpl >= 0) && (cpl <= ((ctxt->regs->eflags >> 12) & 3)));
+}
+
+#define mode_ring0() (get_cpl(ctxt, ops) == 0)
+#define mode_iopl()  _mode_iopl(ctxt, ops)
 
 static int
 in_realmode(
diff -r ce3e5e859d66 -r 368bcf480772 xen/include/asm-x86/hvm/vcpu.h
--- a/xen/include/asm-x86/hvm/vcpu.h    Sun Nov 25 09:23:02 2007 +0000
+++ b/xen/include/asm-x86/hvm/vcpu.h    Sun Nov 25 11:43:53 2007 +0000
@@ -59,6 +59,9 @@ struct hvm_vcpu {
     bool_t              flag_dr_dirty;
     bool_t              debug_state_latch;
 
+    /* Callback function for I/O completion. */
+    int                 (*io_complete)(void);
+
     union {
         struct arch_vmx_struct vmx;
         struct arch_svm_struct svm;
diff -r ce3e5e859d66 -r 368bcf480772 xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Sun Nov 25 09:23:02 2007 +0000
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Sun Nov 25 11:43:53 2007 +0000
@@ -92,6 +92,10 @@ struct arch_vmx_struct {
     unsigned long        vmxassist_enabled:1;
     unsigned long        irqbase_mode:1;
     unsigned char        pm_irqbase[2];
+#else
+    bool_t               real_mode_io_in_progress;
+    bool_t               real_mode_io_completed;
+    unsigned long        real_mode_io_data;
 #endif
 };
 
diff -r ce3e5e859d66 -r 368bcf480772 xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Sun Nov 25 09:23:02 2007 +0000
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Sun Nov 25 11:43:53 2007 +0000
@@ -34,6 +34,7 @@ void set_guest_time(struct vcpu *v, u64 
 void set_guest_time(struct vcpu *v, u64 gtime);
 void vmx_vlapic_msr_changed(struct vcpu *v);
 int vmx_realmode(struct cpu_user_regs *regs);
+int vmx_realmode_io_complete(void);
 
 /*
  * Exit Reasons

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] vmx realmode: Plumb through I/O port accesses in emulated realmode., Xen patchbot-unstable <=