Skip to content

Commit

Permalink
KVM: x86 emulator: fix writes to registers with modrm encodings
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
avikivity committed May 18, 2008
1 parent f26a398 commit 107d6d2
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 2 deletions.
7 changes: 5 additions & 2 deletions arch/x86/kvm/x86_emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -1005,6 +1006,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
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;
Expand Down Expand Up @@ -1049,6 +1051,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
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;
Expand Down
1 change: 1 addition & 0 deletions include/asm-x86/kvm_x86_emulate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down

0 comments on commit 107d6d2

Please sign in to comment.