forked from luck/tmp_suning_uos_patched
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>
This commit is contained in:
parent
f26a398891
commit
107d6d2efa
@ -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 @@ 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;
|
||||
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user