aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/emulate.c24
1 files changed, 10 insertions, 14 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 48de4b890055..b8ce53861f68 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -52,6 +52,7 @@
52#define DstMem (3<<1) /* Memory operand. */ 52#define DstMem (3<<1) /* Memory operand. */
53#define DstAcc (4<<1) /* Destination Accumulator */ 53#define DstAcc (4<<1) /* Destination Accumulator */
54#define DstDI (5<<1) /* Destination is in ES:(E)DI */ 54#define DstDI (5<<1) /* Destination is in ES:(E)DI */
55#define DstMem64 (6<<1) /* 64bit memory operand */
55#define DstMask (7<<1) 56#define DstMask (7<<1)
56/* Source operand type. */ 57/* Source operand type. */
57#define SrcNone (0<<4) /* No source operand. */ 58#define SrcNone (0<<4) /* No source operand. */
@@ -360,7 +361,7 @@ static u32 group_table[] = {
360 DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM | Lock, 361 DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM | Lock,
361 DstMem | SrcImmByte | ModRM | Lock, DstMem | SrcImmByte | ModRM | Lock, 362 DstMem | SrcImmByte | ModRM | Lock, DstMem | SrcImmByte | ModRM | Lock,
362 [Group9*8] = 363 [Group9*8] =
363 0, ImplicitOps | ModRM | Lock, 0, 0, 0, 0, 0, 0, 364 0, DstMem64 | ModRM | Lock, 0, 0, 0, 0, 0, 0,
364}; 365};
365 366
366static u32 group2_table[] = { 367static u32 group2_table[] = {
@@ -1205,6 +1206,7 @@ done_prefixes:
1205 c->twobyte && (c->b == 0xb6 || c->b == 0xb7)); 1206 c->twobyte && (c->b == 0xb6 || c->b == 0xb7));
1206 break; 1207 break;
1207 case DstMem: 1208 case DstMem:
1209 case DstMem64:
1208 if ((c->d & ModRM) && c->modrm_mod == 3) { 1210 if ((c->d & ModRM) && c->modrm_mod == 3) {
1209 c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; 1211 c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
1210 c->dst.type = OP_REG; 1212 c->dst.type = OP_REG;
@@ -1214,7 +1216,10 @@ done_prefixes:
1214 } 1216 }
1215 c->dst.type = OP_MEM; 1217 c->dst.type = OP_MEM;
1216 c->dst.ptr = (unsigned long *)c->modrm_ea; 1218 c->dst.ptr = (unsigned long *)c->modrm_ea;
1217 c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; 1219 if ((c->d & DstMask) == DstMem64)
1220 c->dst.bytes = 8;
1221 else
1222 c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
1218 c->dst.val = 0; 1223 c->dst.val = 0;
1219 if (c->d & BitOp) { 1224 if (c->d & BitOp) {
1220 unsigned long mask = ~(c->dst.bytes * 8 - 1); 1225 unsigned long mask = ~(c->dst.bytes * 8 - 1);
@@ -1706,12 +1711,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
1706 struct x86_emulate_ops *ops) 1711 struct x86_emulate_ops *ops)
1707{ 1712{
1708 struct decode_cache *c = &ctxt->decode; 1713 struct decode_cache *c = &ctxt->decode;
1709 u64 old, new; 1714 u64 old = c->dst.orig_val;
1710 int rc;
1711
1712 rc = ops->read_emulated(c->modrm_ea, &old, 8, ctxt->vcpu);
1713 if (rc != X86EMUL_CONTINUE)
1714 return rc;
1715 1715
1716 if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) || 1716 if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) ||
1717 ((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) { 1717 ((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) {
@@ -1719,15 +1719,12 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
1719 c->regs[VCPU_REGS_RAX] = (u32) (old >> 0); 1719 c->regs[VCPU_REGS_RAX] = (u32) (old >> 0);
1720 c->regs[VCPU_REGS_RDX] = (u32) (old >> 32); 1720 c->regs[VCPU_REGS_RDX] = (u32) (old >> 32);
1721 ctxt->eflags &= ~EFLG_ZF; 1721 ctxt->eflags &= ~EFLG_ZF;
1722
1723 } else { 1722 } else {
1724 new = ((u64)c->regs[VCPU_REGS_RCX] << 32) | 1723 c->dst.val = ((u64)c->regs[VCPU_REGS_RCX] << 32) |
1725 (u32) c->regs[VCPU_REGS_RBX]; 1724 (u32) c->regs[VCPU_REGS_RBX];
1726 1725
1727 rc = ops->cmpxchg_emulated(c->modrm_ea, &old, &new, 8, ctxt->vcpu);
1728 if (rc != X86EMUL_CONTINUE)
1729 return rc;
1730 ctxt->eflags |= EFLG_ZF; 1726 ctxt->eflags |= EFLG_ZF;
1727 c->lock_prefix = 1;
1731 } 1728 }
1732 return X86EMUL_CONTINUE; 1729 return X86EMUL_CONTINUE;
1733} 1730}
@@ -3245,7 +3242,6 @@ twobyte_insn:
3245 rc = emulate_grp9(ctxt, ops); 3242 rc = emulate_grp9(ctxt, ops);
3246 if (rc != X86EMUL_CONTINUE) 3243 if (rc != X86EMUL_CONTINUE)
3247 goto done; 3244 goto done;
3248 c->dst.type = OP_NONE;
3249 break; 3245 break;
3250 } 3246 }
3251 goto writeback; 3247 goto writeback;