diff options
author | Avi Kivity <avi@qumranet.com> | 2008-05-05 14:58:26 +0300 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-05-18 14:34:14 +0300 |
commit | 107d6d2efa9eb8c48d050936d8019230ac6b24cd (patch) | |
tree | fc1d94a18e3f909e31c900ac698811831ed0abb2 | |
parent | f26a3988917913b3d11b2bd741601a2c64ab9204 (diff) | |
download | op-kernel-dev-107d6d2efa9eb8c48d050936d8019230ac6b24cd.zip op-kernel-dev-107d6d2efa9eb8c48d050936d8019230ac6b24cd.tar.gz |
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>
-rw-r--r-- | arch/x86/kvm/x86_emulate.c | 7 | ||||
-rw-r--r-- | include/asm-x86/kvm_x86_emulate.h | 1 |
2 files changed, 6 insertions, 2 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index f2a696d..8a96320 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, c->use_modrm_ea = 1; if (c->modrm_mod == 3) { - c->modrm_val = *(unsigned long *) - decode_register(c->modrm_rm, c->regs, c->d & ByteOp); + c->modrm_ptr = decode_register(c->modrm_rm, + c->regs, c->d & ByteOp); + c->modrm_val = *(unsigned long *)c->modrm_ptr; return rc; } @@ -1005,6 +1006,7 @@ done_prefixes: if ((c->d & ModRM) && c->modrm_mod == 3) { c->src.type = OP_REG; c->src.val = c->modrm_val; + c->src.ptr = c->modrm_ptr; break; } c->src.type = OP_MEM; @@ -1049,6 +1051,7 @@ done_prefixes: if ((c->d & ModRM) && c->modrm_mod == 3) { c->dst.type = OP_REG; c->dst.val = c->dst.orig_val = c->modrm_val; + c->dst.ptr = c->modrm_ptr; break; } c->dst.type = OP_MEM; diff --git a/include/asm-x86/kvm_x86_emulate.h b/include/asm-x86/kvm_x86_emulate.h index d6337f94..b877bbd 100644 --- a/include/asm-x86/kvm_x86_emulate.h +++ b/include/asm-x86/kvm_x86_emulate.h @@ -135,6 +135,7 @@ struct decode_cache { u8 modrm_rm; u8 use_modrm_ea; unsigned long modrm_ea; + void *modrm_ptr; unsigned long modrm_val; struct fetch_cache fetch; }; |