aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorTakuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>2011-11-22 01:20:47 -0500
committerAvi Kivity <avi@redhat.com>2011-12-27 04:17:31 -0500
commite940b5c20f89282fe826c5e2237932ab280497cf (patch)
tree94ae1350f5260033039764f0ac5f106765136536 /arch
parente1e210b0a7f7b4d14577bdc76719963f7facc0e7 (diff)
KVM: x86 emulator: Use opcode::execute for CMPXCHG
CMPXCHG: 0F B0, 0F B1 Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/emulate.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 906c5eb34aa7..799000d8bf8b 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1832,6 +1832,24 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt)
1832 return rc; 1832 return rc;
1833} 1833}
1834 1834
1835static int em_cmpxchg(struct x86_emulate_ctxt *ctxt)
1836{
1837 /* Save real source value, then compare EAX against destination. */
1838 ctxt->src.orig_val = ctxt->src.val;
1839 ctxt->src.val = ctxt->regs[VCPU_REGS_RAX];
1840 emulate_2op_SrcV(ctxt, "cmp");
1841
1842 if (ctxt->eflags & EFLG_ZF) {
1843 /* Success: write back to memory. */
1844 ctxt->dst.val = ctxt->src.orig_val;
1845 } else {
1846 /* Failure: write the value we saw to EAX. */
1847 ctxt->dst.type = OP_REG;
1848 ctxt->dst.addr.reg = (unsigned long *)&ctxt->regs[VCPU_REGS_RAX];
1849 }
1850 return X86EMUL_CONTINUE;
1851}
1852
1835static int em_lseg(struct x86_emulate_ctxt *ctxt) 1853static int em_lseg(struct x86_emulate_ctxt *ctxt)
1836{ 1854{
1837 int seg = ctxt->src2.val; 1855 int seg = ctxt->src2.val;
@@ -3400,7 +3418,7 @@ static struct opcode twobyte_table[256] = {
3400 D(DstMem | SrcReg | Src2CL | ModRM), 3418 D(DstMem | SrcReg | Src2CL | ModRM),
3401 D(ModRM), I(DstReg | SrcMem | ModRM, em_imul), 3419 D(ModRM), I(DstReg | SrcMem | ModRM, em_imul),
3402 /* 0xB0 - 0xB7 */ 3420 /* 0xB0 - 0xB7 */
3403 D2bv(DstMem | SrcReg | ModRM | Lock | PageTable), 3421 I2bv(DstMem | SrcReg | ModRM | Lock | PageTable, em_cmpxchg),
3404 I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg), 3422 I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg),
3405 I(DstMem | SrcReg | ModRM | BitOp | Lock, em_btr), 3423 I(DstMem | SrcReg | ModRM | BitOp | Lock, em_btr),
3406 I(DstReg | SrcMemFAddr | ModRM | Src2FS, em_lseg), 3424 I(DstReg | SrcMemFAddr | ModRM | Src2FS, em_lseg),
@@ -4153,23 +4171,6 @@ twobyte_insn:
4153 break; 4171 break;
4154 case 0xae: /* clflush */ 4172 case 0xae: /* clflush */
4155 break; 4173 break;
4156 case 0xb0 ... 0xb1: /* cmpxchg */
4157 /*
4158 * Save real source value, then compare EAX against
4159 * destination.
4160 */
4161 ctxt->src.orig_val = ctxt->src.val;
4162 ctxt->src.val = ctxt->regs[VCPU_REGS_RAX];
4163 emulate_2op_SrcV(ctxt, "cmp");
4164 if (ctxt->eflags & EFLG_ZF) {
4165 /* Success: write back to memory. */
4166 ctxt->dst.val = ctxt->src.orig_val;
4167 } else {
4168 /* Failure: write the value we saw to EAX. */
4169 ctxt->dst.type = OP_REG;
4170 ctxt->dst.addr.reg = (unsigned long *)&ctxt->regs[VCPU_REGS_RAX];
4171 }
4172 break;
4173 case 0xb6 ... 0xb7: /* movzx */ 4174 case 0xb6 ... 0xb7: /* movzx */
4174 ctxt->dst.bytes = ctxt->op_bytes; 4175 ctxt->dst.bytes = ctxt->op_bytes;
4175 ctxt->dst.val = (ctxt->d & ByteOp) ? (u8) ctxt->src.val 4176 ctxt->dst.val = (ctxt->d & ByteOp) ? (u8) ctxt->src.val