aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86_emulate.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2008-05-05 07:58:26 -0400
committerAvi Kivity <avi@qumranet.com>2008-05-18 07:34:14 -0400
commit107d6d2efa9eb8c48d050936d8019230ac6b24cd (patch)
treefc1d94a18e3f909e31c900ac698811831ed0abb2 /arch/x86/kvm/x86_emulate.c
parentf26a3988917913b3d11b2bd741601a2c64ab9204 (diff)
KVM: x86 emulator: fix writes to registers with modrm encodings
A register destination encoded with a mod=3 encoding left dst.ptr NULL. Normally we don't trap writes to registers, but in the case of smsw, we do. Fix by pointing dst.ptr at the destination register. Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/x86/kvm/x86_emulate.c')
-rw-r--r--arch/x86/kvm/x86_emulate.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c
index f2a696d6a243..8a96320ab071 100644
--- a/arch/x86/kvm/x86_emulate.c
+++ b/arch/x86/kvm/x86_emulate.c
@@ -677,8 +677,9 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
677 c->use_modrm_ea = 1; 677 c->use_modrm_ea = 1;
678 678
679 if (c->modrm_mod == 3) { 679 if (c->modrm_mod == 3) {
680 c->modrm_val = *(unsigned long *) 680 c->modrm_ptr = decode_register(c->modrm_rm,
681 decode_register(c->modrm_rm, c->regs, c->d & ByteOp); 681 c->regs, c->d & ByteOp);
682 c->modrm_val = *(unsigned long *)c->modrm_ptr;
682 return rc; 683 return rc;
683 } 684 }
684 685
@@ -1005,6 +1006,7 @@ done_prefixes:
1005 if ((c->d & ModRM) && c->modrm_mod == 3) { 1006 if ((c->d & ModRM) && c->modrm_mod == 3) {
1006 c->src.type = OP_REG; 1007 c->src.type = OP_REG;
1007 c->src.val = c->modrm_val; 1008 c->src.val = c->modrm_val;
1009 c->src.ptr = c->modrm_ptr;
1008 break; 1010 break;
1009 } 1011 }
1010 c->src.type = OP_MEM; 1012 c->src.type = OP_MEM;
@@ -1049,6 +1051,7 @@ done_prefixes:
1049 if ((c->d & ModRM) && c->modrm_mod == 3) { 1051 if ((c->d & ModRM) && c->modrm_mod == 3) {
1050 c->dst.type = OP_REG; 1052 c->dst.type = OP_REG;
1051 c->dst.val = c->dst.orig_val = c->modrm_val; 1053 c->dst.val = c->dst.orig_val = c->modrm_val;
1054 c->dst.ptr = c->modrm_ptr;
1052 break; 1055 break;
1053 } 1056 }
1054 c->dst.type = OP_MEM; 1057 c->dst.type = OP_MEM;