Message ID | 20190809160047.8319-80-alazar@bitdefender.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | VM introspection | expand |
On 09/08/19 18:00, Adalbert Lazăr wrote: > From: Mihai Donțu <mdontu@bitdefender.com> > > This is needed in order to be able to support guest code that uses movsd to > write into pages that are marked for write tracking. > > Signed-off-by: Mihai Donțu <mdontu@bitdefender.com> > Signed-off-by: Adalbert Lazăr <alazar@bitdefender.com> > --- > arch/x86/kvm/emulate.c | 32 +++++++++++++++++++++++++++----- > 1 file changed, 27 insertions(+), 5 deletions(-) > > diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c > index 34431cf31f74..9d38f892beea 100644 > --- a/arch/x86/kvm/emulate.c > +++ b/arch/x86/kvm/emulate.c > @@ -1177,6 +1177,27 @@ static int em_fnstsw(struct x86_emulate_ctxt *ctxt) > return X86EMUL_CONTINUE; > } > > +static u8 simd_prefix_to_bytes(const struct x86_emulate_ctxt *ctxt, > + int simd_prefix) > +{ > + u8 bytes; > + > + switch (ctxt->b) { > + case 0x11: > + /* movsd xmm, m64 */ > + /* movups xmm, m128 */ > + if (simd_prefix == 0xf2) { > + bytes = 8; > + break; > + } > + /* fallthrough */ > + default: > + bytes = 16; > + break; > + } > + return bytes; > +} > + > static void decode_register_operand(struct x86_emulate_ctxt *ctxt, > struct operand *op) > { > @@ -1187,7 +1208,7 @@ static void decode_register_operand(struct x86_emulate_ctxt *ctxt, > > if (ctxt->d & Sse) { > op->type = OP_XMM; > - op->bytes = 16; > + op->bytes = ctxt->op_bytes; > op->addr.xmm = reg; > read_sse_reg(ctxt, &op->vec_val, reg); > return; > @@ -1238,7 +1259,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, > ctxt->d & ByteOp); > if (ctxt->d & Sse) { > op->type = OP_XMM; > - op->bytes = 16; > + op->bytes = ctxt->op_bytes; > op->addr.xmm = ctxt->modrm_rm; > read_sse_reg(ctxt, &op->vec_val, ctxt->modrm_rm); > return rc; > @@ -4529,7 +4550,7 @@ static const struct gprefix pfx_0f_2b = { > }; > > static const struct gprefix pfx_0f_10_0f_11 = { > - I(Unaligned, em_mov), I(Unaligned, em_mov), N, N, > + I(Unaligned, em_mov), I(Unaligned, em_mov), I(Unaligned, em_mov), N, > }; > > static const struct gprefix pfx_0f_28_0f_29 = { > @@ -5097,7 +5118,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) > { > int rc = X86EMUL_CONTINUE; > int mode = ctxt->mode; > - int def_op_bytes, def_ad_bytes, goffset, simd_prefix; > + int def_op_bytes, def_ad_bytes, goffset, simd_prefix = 0; > bool op_prefix = false; > bool has_seg_override = false; > struct opcode opcode; > @@ -5320,7 +5341,8 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) > ctxt->op_bytes = 4; > > if (ctxt->d & Sse) > - ctxt->op_bytes = 16; > + ctxt->op_bytes = simd_prefix_to_bytes(ctxt, > + simd_prefix); > else if (ctxt->d & Mmx) > ctxt->op_bytes = 8; > } > Please submit all these emulator patches as a separate series, complete with testcases for kvm-unit-tests. Paolo
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 34431cf31f74..9d38f892beea 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1177,6 +1177,27 @@ static int em_fnstsw(struct x86_emulate_ctxt *ctxt) return X86EMUL_CONTINUE; } +static u8 simd_prefix_to_bytes(const struct x86_emulate_ctxt *ctxt, + int simd_prefix) +{ + u8 bytes; + + switch (ctxt->b) { + case 0x11: + /* movsd xmm, m64 */ + /* movups xmm, m128 */ + if (simd_prefix == 0xf2) { + bytes = 8; + break; + } + /* fallthrough */ + default: + bytes = 16; + break; + } + return bytes; +} + static void decode_register_operand(struct x86_emulate_ctxt *ctxt, struct operand *op) { @@ -1187,7 +1208,7 @@ static void decode_register_operand(struct x86_emulate_ctxt *ctxt, if (ctxt->d & Sse) { op->type = OP_XMM; - op->bytes = 16; + op->bytes = ctxt->op_bytes; op->addr.xmm = reg; read_sse_reg(ctxt, &op->vec_val, reg); return; @@ -1238,7 +1259,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, ctxt->d & ByteOp); if (ctxt->d & Sse) { op->type = OP_XMM; - op->bytes = 16; + op->bytes = ctxt->op_bytes; op->addr.xmm = ctxt->modrm_rm; read_sse_reg(ctxt, &op->vec_val, ctxt->modrm_rm); return rc; @@ -4529,7 +4550,7 @@ static const struct gprefix pfx_0f_2b = { }; static const struct gprefix pfx_0f_10_0f_11 = { - I(Unaligned, em_mov), I(Unaligned, em_mov), N, N, + I(Unaligned, em_mov), I(Unaligned, em_mov), I(Unaligned, em_mov), N, }; static const struct gprefix pfx_0f_28_0f_29 = { @@ -5097,7 +5118,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) { int rc = X86EMUL_CONTINUE; int mode = ctxt->mode; - int def_op_bytes, def_ad_bytes, goffset, simd_prefix; + int def_op_bytes, def_ad_bytes, goffset, simd_prefix = 0; bool op_prefix = false; bool has_seg_override = false; struct opcode opcode; @@ -5320,7 +5341,8 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) ctxt->op_bytes = 4; if (ctxt->d & Sse) - ctxt->op_bytes = 16; + ctxt->op_bytes = simd_prefix_to_bytes(ctxt, + simd_prefix); else if (ctxt->d & Mmx) ctxt->op_bytes = 8; }