aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/x86_emulate
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-06-27 17:24:54 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-06-27 17:24:54 +0100
commit41d0fcff57ee5fdc920c977e3d95562fcbed8ca5 (patch)
treec496dac3e306b21d1f10feefc61a462b437675b2 /xen/arch/x86/x86_emulate
parent80982c971fc3d49622412a9b2cb038e004acef49 (diff)
downloadxen-41d0fcff57ee5fdc920c977e3d95562fcbed8ca5.tar.gz
xen-41d0fcff57ee5fdc920c977e3d95562fcbed8ca5.tar.bz2
xen-41d0fcff57ee5fdc920c977e3d95562fcbed8ca5.zip
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>
Diffstat (limited to 'xen/arch/x86/x86_emulate')
-rw-r--r--xen/arch/x86/x86_emulate/x86_emulate.c7
1 files changed, 4 insertions, 3 deletions
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;