diff options
-rw-r--r-- | arch/x86/kvm/emulate.c | 24 |
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 | ||
366 | static u32 group2_table[] = { | 367 | static 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; |