From: Keir Fraser Date: Fri, 27 Jun 2008 16:24:54 +0000 (+0100) Subject: x86: Emulation of LMSW must only affect CR0 bits 0-3. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14192^2~18 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=41d0fcff57ee5fdc920c977e3d95562fcbed8ca5;p=xen.git 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 --- diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index b486721962..a614ea5839 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -1523,8 +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]; - /* NB. LMSW can set, but never clear, PE. */ - value = (value & 0xFFFF0001) | ((exit_qualification >> 16) & 0xFFFF); + /* LMSW can: (1) set bits 0-3; (2) clear bits 1-3. */ + value = (value & ~0xe) | ((exit_qualification >> 16) & 0xf); HVMTRACE_LONG_1D(LMSW, current, value); return !hvm_set_cr0(value); default: diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c index 1e67c0f4d7..2cc9b40fff 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -3267,7 +3267,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)) ) @@ -3284,8 +3285,8 @@ x86_emulate( else if ( (rc = ops->read(ea.mem.seg, ea.mem.off, &cr0w, 2, ctxt)) ) goto done; - cr0 &= 0xffff0001; /* lmsw can set, but never clear, PE */ - 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;