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: Restructure code for clarit

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] vmx realmode: Restructure code for clarity and better treatment of
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 24 Jan 2008 07:10:14 -0800
Delivery-date: Thu, 24 Jan 2008 07:11:20 -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 1201184953 0
# Node ID db620f1c9d3077e732440d1088e608b6d5530daa
# Parent  05e36e506c09438c0df10371116f9d2083a2f37e
vmx realmode: Restructure code for clarity and better treatment of
VM_ENTRY_INTR_INFO. Also add more sanity checking.
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/hvm/vmx/realmode.c |  178 ++++++++++++++++++++++++----------------
 1 files changed, 111 insertions(+), 67 deletions(-)

diff -r 05e36e506c09 -r db620f1c9d30 xen/arch/x86/hvm/vmx/realmode.c
--- a/xen/arch/x86/hvm/vmx/realmode.c   Wed Jan 23 18:12:37 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/realmode.c   Thu Jan 24 14:29:13 2008 +0000
@@ -41,6 +41,8 @@ struct realmode_emulate_ctxt {
 
     uint8_t exn_vector;
     uint8_t exn_insn_len;
+
+    uint32_t intr_shadow;
 };
 
 static void realmode_deliver_exception(
@@ -502,13 +504,108 @@ static struct x86_emulate_ops realmode_e
     .load_fpu_ctxt = realmode_load_fpu_ctxt
 };
 
+static void realmode_emulate_one(struct realmode_emulate_ctxt *rm_ctxt)
+{
+    struct cpu_user_regs *regs = rm_ctxt->ctxt.regs;
+    struct vcpu *curr = current;
+    u32 new_intr_shadow;
+    int rc, io_completed;
+
+    rm_ctxt->insn_buf_eip = regs->eip;
+    (void)hvm_copy_from_guest_phys(
+        rm_ctxt->insn_buf,
+        (uint32_t)(rm_ctxt->seg_reg[x86_seg_cs].base + regs->eip),
+        sizeof(rm_ctxt->insn_buf));
+
+    rm_ctxt->flag_word = 0;
+
+    io_completed = curr->arch.hvm_vmx.real_mode_io_completed;
+    if ( curr->arch.hvm_vmx.real_mode_io_in_progress )
+    {
+        gdprintk(XENLOG_ERR, "I/O in progress before insn is emulated.\n");
+        goto fail;
+    }
+
+    rc = x86_emulate(&rm_ctxt->ctxt, &realmode_emulator_ops);
+
+    if ( curr->arch.hvm_vmx.real_mode_io_completed )
+    {
+        gdprintk(XENLOG_ERR, "I/O completion after insn is emulated.\n");
+        goto fail;
+    }
+
+    if ( io_completed && curr->arch.hvm_vmx.real_mode_io_in_progress )
+    {
+        gdprintk(XENLOG_ERR, "Multiple I/O transactions in a single insn.\n");
+        goto fail;
+    }
+
+    if ( rc == X86EMUL_UNHANDLEABLE )
+    {
+        gdprintk(XENLOG_ERR, "Failed to emulate insn.\n");
+        goto fail;
+    }
+
+    if ( rc == X86EMUL_RETRY )
+        return;
+
+    if ( curr->arch.hvm_vmx.real_mode_io_in_progress &&
+         (get_ioreq(curr)->vp_ioreq.dir == IOREQ_READ) )
+    {
+        gdprintk(XENLOG_ERR, "I/O read in progress but insn is retired.\n");
+        goto fail;
+    }
+
+    new_intr_shadow = rm_ctxt->intr_shadow;
+
+    /* MOV-SS instruction toggles MOV-SS shadow, else we just clear it. */
+    if ( rm_ctxt->flags.mov_ss )
+        new_intr_shadow ^= VMX_INTR_SHADOW_MOV_SS;
+    else
+        new_intr_shadow &= ~VMX_INTR_SHADOW_MOV_SS;
+
+    /* STI instruction toggles STI shadow, else we just clear it. */
+    if ( rm_ctxt->flags.sti )
+        new_intr_shadow ^= VMX_INTR_SHADOW_STI;
+    else
+        new_intr_shadow &= ~VMX_INTR_SHADOW_STI;
+
+    /* Update interrupt shadow information in VMCS only if it changes. */
+    if ( rm_ctxt->intr_shadow != new_intr_shadow )
+    {
+        rm_ctxt->intr_shadow = new_intr_shadow;
+        __vmwrite(GUEST_INTERRUPTIBILITY_INFO, rm_ctxt->intr_shadow);
+    }
+
+    if ( rc == X86EMUL_EXCEPTION )
+    {
+        realmode_deliver_exception(
+            rm_ctxt->exn_vector, rm_ctxt->exn_insn_len, rm_ctxt);
+    }
+    else if ( rm_ctxt->flags.hlt && !hvm_local_events_need_delivery(curr) )
+    {
+        hvm_hlt(regs->eflags);
+    }
+
+    return;
+
+ fail:
+    gdprintk(XENLOG_ERR,
+             "Real-mode emulation failed @ %04x:%08lx: "
+             "%02x %02x %02x %02x %02x %02x\n",
+             rm_ctxt->seg_reg[x86_seg_cs].sel, rm_ctxt->insn_buf_eip,
+             rm_ctxt->insn_buf[0], rm_ctxt->insn_buf[1],
+             rm_ctxt->insn_buf[2], rm_ctxt->insn_buf[3],
+             rm_ctxt->insn_buf[4], rm_ctxt->insn_buf[5]);
+    domain_crash_synchronous();
+}
+
 void vmx_realmode(struct cpu_user_regs *regs)
 {
     struct vcpu *curr = current;
     struct realmode_emulate_ctxt rm_ctxt;
     unsigned long intr_info;
-    int i, rc;
-    u32 intr_shadow, new_intr_shadow;
+    int i;
 
     rm_ctxt.ctxt.regs = regs;
 
@@ -520,77 +617,24 @@ void vmx_realmode(struct cpu_user_regs *
     rm_ctxt.ctxt.sp_size =
         rm_ctxt.seg_reg[x86_seg_ss].attr.fields.db ? 32 : 16;
 
+    rm_ctxt.intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
+
+    if ( curr->arch.hvm_vmx.real_mode_io_in_progress ||
+         curr->arch.hvm_vmx.real_mode_io_completed )
+        realmode_emulate_one(&rm_ctxt);
+
     intr_info = __vmread(VM_ENTRY_INTR_INFO);
-    intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
-    new_intr_shadow = intr_shadow;
+    if ( intr_info & INTR_INFO_VALID_MASK )
+    {
+        realmode_deliver_exception((uint8_t)intr_info, 0, &rm_ctxt);
+        __vmwrite(VM_ENTRY_INTR_INFO, 0);
+    }
 
     while ( !(curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE) &&
             !softirq_pending(smp_processor_id()) &&
             !hvm_local_events_need_delivery(curr) &&
             !curr->arch.hvm_vmx.real_mode_io_in_progress )
-    {
-        if ( (intr_info & INTR_INFO_VALID_MASK) &&
-             !curr->arch.hvm_vmx.real_mode_io_completed )
-        {
-            realmode_deliver_exception((uint8_t)intr_info, 0, &rm_ctxt);
-            __vmwrite(VM_ENTRY_INTR_INFO, 0);
-            intr_info = 0;
-        }
-
-        rm_ctxt.insn_buf_eip = regs->eip;
-        (void)hvm_copy_from_guest_phys(
-            rm_ctxt.insn_buf,
-            (uint32_t)(rm_ctxt.seg_reg[x86_seg_cs].base + regs->eip),
-            sizeof(rm_ctxt.insn_buf));
-
-        rm_ctxt.flag_word = 0;
-
-        rc = x86_emulate(&rm_ctxt.ctxt, &realmode_emulator_ops);
-
-        if ( rc == X86EMUL_RETRY )
-            continue;
-
-        if ( rc == X86EMUL_UNHANDLEABLE )
-        {
-            gdprintk(XENLOG_ERR,
-                     "Real-mode emulation failed @ %04x:%08lx: "
-                     "%02x %02x %02x %02x %02x %02x\n",
-                     rm_ctxt.seg_reg[x86_seg_cs].sel, rm_ctxt.insn_buf_eip,
-                     rm_ctxt.insn_buf[0], rm_ctxt.insn_buf[1],
-                     rm_ctxt.insn_buf[2], rm_ctxt.insn_buf[3],
-                     rm_ctxt.insn_buf[4], rm_ctxt.insn_buf[5]);
-            domain_crash_synchronous();
-        }
-
-        /* MOV-SS instruction toggles MOV-SS shadow, else we just clear it. */
-        if ( rm_ctxt.flags.mov_ss )
-            new_intr_shadow ^= VMX_INTR_SHADOW_MOV_SS;
-        else
-            new_intr_shadow &= ~VMX_INTR_SHADOW_MOV_SS;
-
-        /* STI instruction toggles STI shadow, else we just clear it. */
-        if ( rm_ctxt.flags.sti )
-            new_intr_shadow ^= VMX_INTR_SHADOW_STI;
-        else
-            new_intr_shadow &= ~VMX_INTR_SHADOW_STI;
-
-        /* Update interrupt shadow information in VMCS only if it changes. */
-        if ( intr_shadow != new_intr_shadow )
-        {
-            intr_shadow = new_intr_shadow;
-            __vmwrite(GUEST_INTERRUPTIBILITY_INFO, intr_shadow);
-        }
-
-        if ( rc == X86EMUL_EXCEPTION )
-        {
-            realmode_deliver_exception(
-                rm_ctxt.exn_vector, rm_ctxt.exn_insn_len, &rm_ctxt);
-        }
-        else if ( rm_ctxt.flags.hlt && !hvm_local_events_need_delivery(curr) )
-        {
-            hvm_hlt(regs->eflags);
-        }
-    }
+        realmode_emulate_one(&rm_ctxt);
 
     /*
      * Cannot enter protected mode with bogus selector RPLs and DPLs. Hence we

_______________________________________________
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: Restructure code for clarity and better treatment of, Xen patchbot-unstable <=