diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-06-27 17:24:54 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-06-27 17:24:54 +0100 |
commit | 41d0fcff57ee5fdc920c977e3d95562fcbed8ca5 (patch) | |
tree | c496dac3e306b21d1f10feefc61a462b437675b2 /xen/arch/x86/x86_emulate | |
parent | 80982c971fc3d49622412a9b2cb038e004acef49 (diff) | |
download | xen-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.c | 7 |
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; |