# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1214584191 -3600
# Node ID 2bd01fa8582aab848b97768a86b34e2adf395703
# Parent af0ee672efa35cb895ece0df2e1010104b9a2748
hvm: Fix lmsw handling
The lmsw instruction can be used to set CR0_PE, but can never clear
it, once set.
Signed-off-by: Trolle Selander <trolle.selander@xxxxxxxxxxxxx>
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@xxxxxxxxxx>
xen-unstable changeset: 17907:a9fff28d4f066442b65b3ff8ac916f1a50f7c64b
xen-unstable date: Fri Jun 27 17:24:54 2008 +0100
---
xen/arch/x86/hvm/vmx/vmx.c | 4 ++--
xen/arch/x86/x86_emulate.c | 7 ++++---
2 files changed, 6 insertions(+), 5 deletions(-)
diff -r af0ee672efa3 -r 2bd01fa8582a xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Fri Jun 27 17:04:41 2008 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c Fri Jun 27 17:29:51 2008 +0100
@@ -2229,8 +2229,8 @@ static int vmx_cr_access(unsigned long e
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:
diff -r af0ee672efa3 -r 2bd01fa8582a xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c Fri Jun 27 17:04:41 2008 +0100
+++ b/xen/arch/x86/x86_emulate.c Fri Jun 27 17:29:51 2008 +0100
@@ -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;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|