提交 6550e1f1 编写于 作者: G Gleb Natapov 提交者: Avi Kivity

KVM: x86 emulator: add decoding of CMPXCHG8B dst operand

Decode CMPXCHG8B destination operand in decoding stage. Fixes regression
introduced by "If LOCK prefix is used dest arg should be memory" commit.
This commit relies on dst operand be decoded at the beginning of an
instruction emulation.
Signed-off-by: NGleb Natapov <gleb@redhat.com>
Signed-off-by: NAvi Kivity <avi@redhat.com>
上级 482ac18a
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#define DstMem (3<<1) /* Memory operand. */ #define DstMem (3<<1) /* Memory operand. */
#define DstAcc (4<<1) /* Destination Accumulator */ #define DstAcc (4<<1) /* Destination Accumulator */
#define DstDI (5<<1) /* Destination is in ES:(E)DI */ #define DstDI (5<<1) /* Destination is in ES:(E)DI */
#define DstMem64 (6<<1) /* 64bit memory operand */
#define DstMask (7<<1) #define DstMask (7<<1)
/* Source operand type. */ /* Source operand type. */
#define SrcNone (0<<4) /* No source operand. */ #define SrcNone (0<<4) /* No source operand. */
...@@ -360,7 +361,7 @@ static u32 group_table[] = { ...@@ -360,7 +361,7 @@ static u32 group_table[] = {
DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM | Lock, DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM | Lock,
DstMem | SrcImmByte | ModRM | Lock, DstMem | SrcImmByte | ModRM | Lock, DstMem | SrcImmByte | ModRM | Lock, DstMem | SrcImmByte | ModRM | Lock,
[Group9*8] = [Group9*8] =
0, ImplicitOps | ModRM | Lock, 0, 0, 0, 0, 0, 0, 0, DstMem64 | ModRM | Lock, 0, 0, 0, 0, 0, 0,
}; };
static u32 group2_table[] = { static u32 group2_table[] = {
...@@ -1205,6 +1206,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) ...@@ -1205,6 +1206,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
c->twobyte && (c->b == 0xb6 || c->b == 0xb7)); c->twobyte && (c->b == 0xb6 || c->b == 0xb7));
break; break;
case DstMem: case DstMem:
case DstMem64:
if ((c->d & ModRM) && c->modrm_mod == 3) { if ((c->d & ModRM) && c->modrm_mod == 3) {
c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
c->dst.type = OP_REG; c->dst.type = OP_REG;
...@@ -1214,7 +1216,10 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) ...@@ -1214,7 +1216,10 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
} }
c->dst.type = OP_MEM; c->dst.type = OP_MEM;
c->dst.ptr = (unsigned long *)c->modrm_ea; c->dst.ptr = (unsigned long *)c->modrm_ea;
c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; if ((c->d & DstMask) == DstMem64)
c->dst.bytes = 8;
else
c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
c->dst.val = 0; c->dst.val = 0;
if (c->d & BitOp) { if (c->d & BitOp) {
unsigned long mask = ~(c->dst.bytes * 8 - 1); unsigned long mask = ~(c->dst.bytes * 8 - 1);
...@@ -1706,12 +1711,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, ...@@ -1706,12 +1711,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops) struct x86_emulate_ops *ops)
{ {
struct decode_cache *c = &ctxt->decode; struct decode_cache *c = &ctxt->decode;
u64 old, new; u64 old = c->dst.orig_val;
int rc;
rc = ops->read_emulated(c->modrm_ea, &old, 8, ctxt->vcpu);
if (rc != X86EMUL_CONTINUE)
return rc;
if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) || if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) ||
((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) { ((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) {
...@@ -1719,15 +1719,12 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, ...@@ -1719,15 +1719,12 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
c->regs[VCPU_REGS_RAX] = (u32) (old >> 0); c->regs[VCPU_REGS_RAX] = (u32) (old >> 0);
c->regs[VCPU_REGS_RDX] = (u32) (old >> 32); c->regs[VCPU_REGS_RDX] = (u32) (old >> 32);
ctxt->eflags &= ~EFLG_ZF; ctxt->eflags &= ~EFLG_ZF;
} else { } else {
new = ((u64)c->regs[VCPU_REGS_RCX] << 32) | c->dst.val = ((u64)c->regs[VCPU_REGS_RCX] << 32) |
(u32) c->regs[VCPU_REGS_RBX]; (u32) c->regs[VCPU_REGS_RBX];
rc = ops->cmpxchg_emulated(c->modrm_ea, &old, &new, 8, ctxt->vcpu);
if (rc != X86EMUL_CONTINUE)
return rc;
ctxt->eflags |= EFLG_ZF; ctxt->eflags |= EFLG_ZF;
c->lock_prefix = 1;
} }
return X86EMUL_CONTINUE; return X86EMUL_CONTINUE;
} }
...@@ -3245,7 +3242,6 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) ...@@ -3245,7 +3242,6 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
rc = emulate_grp9(ctxt, ops); rc = emulate_grp9(ctxt, ops);
if (rc != X86EMUL_CONTINUE) if (rc != X86EMUL_CONTINUE)
goto done; goto done;
c->dst.type = OP_NONE;
break; break;
} }
goto writeback; goto writeback;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册