]> xenbits.xensource.com Git - people/vhanquez/xen.git/commitdiff
hvm: Fix lmsw handling
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 27 Jun 2008 16:29:51 +0000 (17:29 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 27 Jun 2008 16:29:51 +0000 (17:29 +0100)
The lmsw instruction can be used to set CR0_PE, but can never clear
it, once set.

Signed-off-by: Trolle Selander <trolle.selander@eu.citrix.com>
xen-unstable changeset:   17906:6b06639011744b6e22915fc1f97237a574e9305f
xen-unstable date:        Fri Jun 27 16:20:59 2008 +0100

x86: Emulation of LMSW must only affect CR0 bits 0-3.
Emulation of SMSW is only restricted to 16-bit operation on memory
operands.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen-unstable changeset:   17907:a9fff28d4f066442b65b3ff8ac916f1a50f7c64b
xen-unstable date:        Fri Jun 27 17:24:54 2008 +0100

xen/arch/x86/hvm/vmx/vmx.c
xen/arch/x86/x86_emulate.c

index 65404f9f9526e86b22a5455624f7336ffd0bf0ed..709b4203362a553383bf145a56d29375de89d334 100644 (file)
@@ -2229,8 +2229,8 @@ static int vmx_cr_access(unsigned long exit_qualification,
         break;
     case TYPE_LMSW:
         value = v->arch.hvm_vcpu.guest_cr[0];
-        value = (value & ~0xF) |
-            (((exit_qualification & LMSW_SOURCE_DATA) >> 16) & 0xF);
+        /* LMSW can: (1) set bits 0-3; (2) clear bits 1-3. */
+        value = (value & ~0xe) | ((exit_qualification >> 16) & 0xf);
         HVMTRACE_1D(LMSW, current, value);
         return vmx_set_cr0(value);
     default:
index 698554a5e8e34ed79ccfeff5d0596c91272374aa..cff508c5b3abf3e69bb04c2daddac64eff480f85 100644 (file)
@@ -3179,7 +3179,8 @@ x86_emulate(
                 goto done;
             break;
         case 4: /* smsw */
-            ea.bytes = 2;
+            if ( ea.type == OP_MEM )
+                ea.bytes = 2;
             dst = ea;
             fail_if(ops->read_cr == NULL);
             if ( (rc = ops->read_cr(0, &dst.val, ctxt)) )
@@ -3196,8 +3197,8 @@ x86_emulate(
             else if ( (rc = ops->read(ea.mem.seg, ea.mem.off,
                                       &cr0w, 2, ctxt)) )
                 goto done;
-            cr0 &= 0xffff0000;
-            cr0 |= (uint16_t)cr0w;
+            /* LMSW can: (1) set bits 0-3; (2) clear bits 1-3. */
+            cr0 = (cr0 & ~0xe) | (cr0w & 0xf);
             if ( (rc = ops->write_cr(0, cr0, ctxt)) )
                 goto done;
             break;