hvm: Fix lmsw handling
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 27 Jun 2008 15:20:59 +0000 (16:20 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 27 Jun 2008 15:20:59 +0000 (16:20 +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/arch/x86/hvm/vmx/vmx.c
xen/arch/x86/x86_emulate/x86_emulate.c

index 5f048ab5501c56a00bf34553752803ff3a1fd321..b486721962057f2a6968306cadc3b6a206b358bc 100644 (file)
@@ -1523,7 +1523,8 @@ static int vmx_cr_access(unsigned long exit_qualification,
         break;
     case VMX_CONTROL_REG_ACCESS_TYPE_LMSW:
         value = v->arch.hvm_vcpu.guest_cr[0];
-        value = (value & ~0xFFFF) | ((exit_qualification >> 16) & 0xFFFF);
+        /* NB. LMSW can set, but never clear, PE. */
+        value = (value & 0xFFFF0001) | ((exit_qualification >> 16) & 0xFFFF);
         HVMTRACE_LONG_1D(LMSW, current, value);
         return !hvm_set_cr0(value);
     default:
index 33718f2e8550cae57b36f0f136e6d633c55a9931..1e67c0f4d70ccea3f9e1c21e2be94bad6fd675aa 100644 (file)
@@ -3284,7 +3284,7 @@ x86_emulate(
             else if ( (rc = ops->read(ea.mem.seg, ea.mem.off,
                                       &cr0w, 2, ctxt)) )
                 goto done;
-            cr0 &= 0xffff0000;
+            cr0 &= 0xffff0001; /* lmsw can set, but never clear, PE */
             cr0 |= (uint16_t)cr0w;
             if ( (rc = ops->write_cr(0, cr0, ctxt)) )
                 goto done;