aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/emulate.c
diff options
context:
space:
mode:
authorWei Yongjun <yjwei@cn.fujitsu.com>2010-08-16 21:17:30 -0400
committerAvi Kivity <avi@redhat.com>2010-10-24 04:51:06 -0400
commit31be40b3985f09c0c89b9e28a8206df32adba842 (patch)
treee111e9c112a62f5c9225c51b17dd062ad4f7e47e /arch/x86/kvm/emulate.c
parent646bab55a278ceb1cf43b1f80d3dd468be62a421 (diff)
KVM: x86 emulator: put register operand write back to a function
Introduce function write_register_operand() to write back the register operand. Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r--arch/x86/kvm/emulate.c55
1 files changed, 23 insertions, 32 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index f6b124fcc3fd..003713041ce6 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1020,6 +1020,25 @@ exception:
1020 return X86EMUL_PROPAGATE_FAULT; 1020 return X86EMUL_PROPAGATE_FAULT;
1021} 1021}
1022 1022
1023static void write_register_operand(struct operand *op)
1024{
1025 /* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */
1026 switch (op->bytes) {
1027 case 1:
1028 *(u8 *)op->addr.reg = (u8)op->val;
1029 break;
1030 case 2:
1031 *(u16 *)op->addr.reg = (u16)op->val;
1032 break;
1033 case 4:
1034 *op->addr.reg = (u32)op->val;
1035 break; /* 64b: zero-extend */
1036 case 8:
1037 *op->addr.reg = op->val;
1038 break;
1039 }
1040}
1041
1023static inline int writeback(struct x86_emulate_ctxt *ctxt, 1042static inline int writeback(struct x86_emulate_ctxt *ctxt,
1024 struct x86_emulate_ops *ops) 1043 struct x86_emulate_ops *ops)
1025{ 1044{
@@ -1029,23 +1048,7 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt,
1029 1048
1030 switch (c->dst.type) { 1049 switch (c->dst.type) {
1031 case OP_REG: 1050 case OP_REG:
1032 /* The 4-byte case *is* correct: 1051 write_register_operand(&c->dst);
1033 * in 64-bit mode we zero-extend.
1034 */
1035 switch (c->dst.bytes) {
1036 case 1:
1037 *(u8 *)c->dst.addr.reg = (u8)c->dst.val;
1038 break;
1039 case 2:
1040 *(u16 *)c->dst.addr.reg = (u16)c->dst.val;
1041 break;
1042 case 4:
1043 *c->dst.addr.reg = (u32)c->dst.val;
1044 break; /* 64b: zero-ext */
1045 case 8:
1046 *c->dst.addr.reg = c->dst.val;
1047 break;
1048 }
1049 break; 1052 break;
1050 case OP_MEM: 1053 case OP_MEM:
1051 if (c->lock_prefix) 1054 if (c->lock_prefix)
@@ -2970,25 +2973,13 @@ special_insn:
2970 case 0x86 ... 0x87: /* xchg */ 2973 case 0x86 ... 0x87: /* xchg */
2971 xchg: 2974 xchg:
2972 /* Write back the register source. */ 2975 /* Write back the register source. */
2973 switch (c->dst.bytes) { 2976 c->src.val = c->dst.val;
2974 case 1: 2977 write_register_operand(&c->src);
2975 *(u8 *) c->src.addr.reg = (u8) c->dst.val;
2976 break;
2977 case 2:
2978 *(u16 *) c->src.addr.reg = (u16) c->dst.val;
2979 break;
2980 case 4:
2981 *c->src.addr.reg = (u32) c->dst.val;
2982 break; /* 64b reg: zero-extend */
2983 case 8:
2984 *c->src.addr.reg = c->dst.val;
2985 break;
2986 }
2987 /* 2978 /*
2988 * Write back the memory destination with implicit LOCK 2979 * Write back the memory destination with implicit LOCK
2989 * prefix. 2980 * prefix.
2990 */ 2981 */
2991 c->dst.val = c->src.val; 2982 c->dst.val = c->src.orig_val;
2992 c->lock_prefix = 1; 2983 c->lock_prefix = 1;
2993 break; 2984 break;
2994 case 0x88 ... 0x8b: /* mov */ 2985 case 0x88 ... 0x8b: /* mov */