[xen-unstable] x86_emulate: Emulate LMSW and SMSW.

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

[xen-unstable] x86_emulate: Emulate LMSW and SMSW.

Xen patchbot-unstable
# HG changeset patch
# User Keir Fraser <[hidden email]>
# Date 1196099694 0
# Node ID f676c0dacbb95c69ad5a3e18ed0ea242a52366f7
# Parent  4deb65519d9b2ff75a25631e9724593de5672bc9
x86_emulate: Emulate LMSW and SMSW.
Signed-off-by: Keir Fraser <[hidden email]>
---
 xen/arch/x86/x86_emulate.c |   31 ++++++++++++++++++++++++++++---
 1 files changed, 28 insertions(+), 3 deletions(-)

diff -r 4deb65519d9b -r f676c0dacbb9 xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c Mon Nov 26 16:57:57 2007 +0000
+++ b/xen/arch/x86/x86_emulate.c Mon Nov 26 17:54:54 2007 +0000
@@ -2666,6 +2666,7 @@ x86_emulate(
     {
     case 0x01: /* Grp7 */ {
         struct segment_register reg;
+        unsigned long base, limit, cr0, cr0w;
 
         switch ( modrm_reg & 7 )
         {
@@ -2691,16 +2692,40 @@ x86_emulate(
             fail_if(ops->write_segment == NULL);
             memset(&reg, 0, sizeof(reg));
             if ( (rc = ops->read(ea.mem.seg, ea.mem.off+0,
-                                 (unsigned long *)&reg.limit, 2, ctxt)) ||
+                                 &limit, 2, ctxt)) ||
                  (rc = ops->read(ea.mem.seg, ea.mem.off+2,
-                                 (unsigned long *)&reg.base,
-                                 mode_64bit() ? 8 : 4, ctxt)) )
+                                 &base, mode_64bit() ? 8 : 4, ctxt)) )
                 goto done;
+            reg.base = base;
+            reg.limit = limit;
             if ( op_bytes == 2 )
                 reg.base &= 0xffffff;
             if ( (rc = ops->write_segment((modrm_reg & 1) ?
                                           x86_seg_idtr : x86_seg_gdtr,
                                           &reg, ctxt)) )
+                goto done;
+            break;
+        case 4: /* smsw */
+            dst = ea;
+            dst.bytes = 2;
+            fail_if(ops->read_cr == NULL);
+            if ( (rc = ops->read_cr(0, &dst.val, ctxt)) )
+                goto done;
+            d |= Mov; /* force writeback */
+            break;
+        case 6: /* lmsw */
+            fail_if(ops->read_cr == NULL);
+            fail_if(ops->write_cr == NULL);
+            if ( (rc = ops->read_cr(0, &cr0, ctxt)) )
+                goto done;
+            if ( ea.type == OP_REG )
+                cr0w = *ea.reg;
+            else if ( (rc = ops->read(ea.mem.seg, ea.mem.off,
+                                      &cr0w, 2, ctxt)) )
+                goto done;
+            cr0 &= 0xffff0000;
+            cr0 |= (uint16_t)cr0w;
+            if ( (rc = ops->write_cr(0, cr0, ctxt)) )
                 goto done;
             break;
         default:

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