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-3.2-testing] vmx realmode: Restructure code for cla

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-3.2-testing] vmx realmode: Restructure code for clarity and better treatment of
From: "Xen patchbot-3.2-testing" <patchbot-3.2-testing@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 07 Feb 2008 01:20:30 -0800
Delivery-date: Thu, 07 Feb 2008 01:20:43 -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 1202291679 0
# Node ID 985bae80b6d7aa87e589e59b376f52a5000eaa64
# Parent  744ec35f1e3ab5aa6c5301c872c2f0685a46cd34
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-unstable changeset:   16869:db620f1c9d3077e732440d1088e608b6d5530daa
xen-unstable date:        Thu Jan 24 14:29:13 2008 +0000

vmx realmode: Multiple I/O reads to qemu in an instruction is not
allowed. But we do allow, for example, a read followed by a write
(e.g., MOVS within video RAM).
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
xen-unstable changeset:   16922:ed2ca78286a8c30ab68e37c7eccae6d1748f0d50
xen-unstable date:        Mon Jan 28 11:28:55 2008 +0000
---
 xen/arch/x86/hvm/vmx/realmode.c |  178 ++++++++++++++++++++++++----------------
 1 files changed, 111 insertions(+), 67 deletions(-)

diff -r 744ec35f1e3a -r 985bae80b6d7 xen/arch/x86/hvm/vmx/realmode.c
--- a/xen/arch/x86/hvm/vmx/realmode.c   Wed Feb 06 09:52:43 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/realmode.c   Wed Feb 06 09:54:39 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 ( rc == X86EMUL_UNHANDLEABLE )
+    {
+        gdprintk(XENLOG_ERR, "Failed to emulate insn.\n");
+        goto fail;
+    }
+
+    if ( rc == X86EMUL_RETRY )
+    {
+        BUG_ON(!curr->arch.hvm_vmx.real_mode_io_in_progress);
+        if ( !io_completed )
+            return;
+        gdprintk(XENLOG_ERR, "Multiple I/O reads in a single insn.\n");
+        goto fail;
+    }
+
+    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-3.2-testing] vmx realmode: Restructure code for clarity and better treatment of, Xen patchbot-3.2-testing <=