[xen-unstable] vmx realmode: Support privileged EFLAGS updates in emulated realmode.

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

[xen-unstable] vmx realmode: Support privileged EFLAGS updates in emulated realmode.

Xen patchbot-unstable
# HG changeset patch
# User Keir Fraser <[hidden email]>
# Date 1195991102 0
# Node ID a194083696d5dbd9b7509d35924e48aa05678607
# Parent  368bcf480772fb32b22fa9cb0bffcd10f0ed2c25
vmx realmode: Support privileged EFLAGS updates in emulated realmode.
Also tweak debug tracing to be much less noisy. We can emulates tens
of thousands of instructions in rombios now.
Signed-off-by: Keir Fraser <[hidden email]>
---
 xen/arch/x86/hvm/vmx/realmode.c |   47 ++++++++++++++++++++++++++++++----------
 xen/arch/x86/x86_emulate.c      |   11 +++------
 2 files changed, 40 insertions(+), 18 deletions(-)

diff -r 368bcf480772 -r a194083696d5 xen/arch/x86/hvm/vmx/realmode.c
--- a/xen/arch/x86/hvm/vmx/realmode.c Sun Nov 25 11:43:53 2007 +0000
+++ b/xen/arch/x86/hvm/vmx/realmode.c Sun Nov 25 11:45:02 2007 +0000
@@ -168,6 +168,14 @@ realmode_write_segment(
     struct realmode_emulate_ctxt *rm_ctxt =
         container_of(ctxt, struct realmode_emulate_ctxt, ctxt);
     memcpy(&rm_ctxt->seg_reg[seg], reg, sizeof(struct segment_register));
+
+    if ( seg == x86_seg_ss )
+    {
+        u32 intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
+        intr_shadow ^= VMX_INTR_SHADOW_MOV_SS;
+        __vmwrite(GUEST_INTERRUPTIBILITY_INFO, intr_shadow);
+    }
+
     return X86EMUL_OKAY;
 }
 
@@ -231,6 +239,20 @@ realmode_read_cr(
         break;
     default:
         return X86EMUL_UNHANDLEABLE;
+    }
+
+    return X86EMUL_OKAY;
+}
+
+static int realmode_write_rflags(
+    unsigned long val,
+    struct x86_emulate_ctxt *ctxt)
+{
+    if ( (val & X86_EFLAGS_IF) && !(ctxt->regs->eflags & X86_EFLAGS_IF) )
+    {
+        u32 intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
+        intr_shadow ^= VMX_INTR_SHADOW_STI;
+        __vmwrite(GUEST_INTERRUPTIBILITY_INFO, intr_shadow);
     }
 
     return X86EMUL_OKAY;
@@ -245,7 +267,8 @@ static struct x86_emulate_ops realmode_e
     .write_segment = realmode_write_segment,
     .read_io       = realmode_read_io,
     .write_io      = realmode_write_io,
-    .read_cr       = realmode_read_cr
+    .read_cr       = realmode_read_cr,
+    .write_rflags  = realmode_write_rflags
 };
 
 int vmx_realmode(struct cpu_user_regs *regs)
@@ -277,26 +300,22 @@ int vmx_realmode(struct cpu_user_regs *r
                  rm_ctxt.insn_buf, addr, sizeof(rm_ctxt.insn_buf)))
             ? sizeof(rm_ctxt.insn_buf) : 0;
 
-        gdprintk(XENLOG_DEBUG,
-                 "RM %04x:%08lx: %02x %02x %02x %02x %02x %02x\n",
-                 rm_ctxt.seg_reg[x86_seg_cs].sel, regs->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]);
-
         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_DEBUG,
+                     "RM %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]);
             gdprintk(XENLOG_ERR, "Emulation failed\n");
             rc = -EINVAL;
             break;
@@ -317,6 +336,12 @@ int vmx_realmode_io_complete(void)
     if ( !curr->arch.hvm_vmx.real_mode_io_in_progress )
         return 0;
 
+#if 0
+    gdprintk(XENLOG_DEBUG, "RM I/O %d %c bytes=%d addr=%lx data=%lx\n",
+             p->type, p->dir ? 'R' : 'W',
+             (int)p->size, (long)p->addr, (long)p->data);
+#endif
+
     curr->arch.hvm_vmx.real_mode_io_in_progress = 0;
     if ( p->dir == IOREQ_READ )
     {
diff -r 368bcf480772 -r a194083696d5 xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c Sun Nov 25 11:43:53 2007 +0000
+++ b/xen/arch/x86/x86_emulate.c Sun Nov 25 11:45:02 2007 +0000
@@ -2253,16 +2253,13 @@ x86_emulate(
         break;
 
     case 0xfa: /* cli */
-        generate_exception_if(!mode_iopl(), EXC_GP);
-        fail_if(ops->write_rflags == NULL);
-        if ( (rc = ops->write_rflags(_regs.eflags & ~EFLG_IF, ctxt)) != 0 )
-            goto done;
-        break;
-
     case 0xfb: /* sti */
         generate_exception_if(!mode_iopl(), EXC_GP);
         fail_if(ops->write_rflags == NULL);
-        if ( (rc = ops->write_rflags(_regs.eflags | EFLG_IF, ctxt)) != 0 )
+        _regs.eflags &= ~EFLG_IF;
+        if ( b == 0xfb ) /* sti */
+            _regs.eflags |= EFLG_IF;
+        if ( (rc = ops->write_rflags(_regs.eflags, ctxt)) != 0 )
             goto done;
         break;
 

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