From 1943cf7a91d2536d23e606e9964ee22d83026b8a Mon Sep 17 00:00:00 2001
From: Nitin A Kamble <nitin.a.kamble@intel.com>
Date: Tue, 30 Oct 2007 19:35:56 -0800
Subject: [PATCH] Implement emulation of instructions: xchg
        xchg ax, r16
        xchg eax, r32
        xchg rax, r64
 opcodes: 0x90 ... 0x97

Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
---
 drivers/kvm/x86_emulate.c |   34 ++++++++++++++++++++++++++++++++--
 1 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 0f6ded5..ac35619 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -132,8 +132,11 @@ static u16 opcode_table[256] = {
 	ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov,
 	ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
 	0, ModRM | DstReg, 0, DstMem | SrcNone | ModRM | Mov,
-	/* 0x90 - 0x9F */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps, ImplicitOps, 0, 0,
+	/* 0x90 - 0x97 */
+	ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
+	ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
+	/* 0x98 - 0x9F */
+	0, 0, 0, 0, ImplicitOps, ImplicitOps, 0, 0,
 	/* 0xA0 - 0xA7 */
 	ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs,
 	ByteOp | DstMem | SrcReg | Mov | MemAbs, DstMem | SrcReg | Mov | MemAbs,
@@ -1370,6 +1373,33 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 		if (rc != 0)
 			goto done;
 		break;
+	case 0x90 ... 0x97: /* xchg ax, r16 / xchg eax, r32 / xchg rax, r64 */
+		c->src.ptr = &c->regs[c->b & 0x7];
+		c->dst.ptr = &c->regs[VCPU_REGS_RAX];
+		switch (c->op_bytes) {
+		case 2:
+			c->dst.val = *(u16 *) c->dst.ptr;
+			c->src.val = *(u16 *) c->src.ptr;
+			*(u16 *) c->dst.ptr = (u16) c->src.val;
+			*(u16 *) c->src.ptr = (u16) c->dst.val;
+		break;
+		case 4:
+			c->dst.val = *(u32 *) c->dst.ptr;
+			c->src.val = *(u32 *) c->src.ptr;
+			*(u32 *) c->dst.ptr = (u32) c->src.val;
+			*(u32 *) c->src.ptr = (u32) c->dst.val;
+		break;
+		case 8:
+			c->dst.val = *(u64 *) c->dst.ptr;
+			c->src.val = *(u64 *) c->src.ptr;
+			*(u64 *) c->dst.ptr = (u64) c->src.val;
+			*(u64 *) c->src.ptr = (u64) c->dst.val;
+		break;
+		default:
+			goto cannot_emulate;
+		}
+		c->dst.type = OP_NONE;  /* Disable writeback. */
+		break;
 	case 0xa0 ... 0xa1:	/* mov */
 		c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
 		c->dst.val = c->src.val;
-- 
1.5.2.2

