From bdae8efb7f3aa3d367b84bbcb953e5ab4e5251fe Mon Sep 17 00:00:00 2001 From: "Li, Fei1" Date: Fri, 10 May 2019 19:15:43 +0800 Subject: [PATCH] hv: instr_emul: fix movzx return memory opsize wrong There're some instructions which not support bit 0(w bit) flag but which memory opcode size is fixed and the memory opcode size is not equal to the register opcode size. In our code, there is movzx (which opcode is 0F B7) which memory opcode size is fixed to 16 bits. So add a flag VIE_OP_F_WORD_OP to indicate a instruction which memory opcode size is fixed to 16 bits. Tracked-On: #1337 Signed-off-by: Li, Fei1 Reviewed-by: Yin Fengwei --- hypervisor/arch/x86/guest/instr_emul.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/hypervisor/arch/x86/guest/instr_emul.c b/hypervisor/arch/x86/guest/instr_emul.c index 270f7fa19..1c5c479c9 100644 --- a/hypervisor/arch/x86/guest/instr_emul.c +++ b/hypervisor/arch/x86/guest/instr_emul.c @@ -96,6 +96,7 @@ * FOR NON-64-BIT MODES, Vol 2, Intel SDM. */ #define VIE_OP_F_BYTE_OP (1U << 5U) /* 8-bit operands. */ +#define VIE_OP_F_WORD_OP (1U << 6U) /* 16-bit operands. */ static const struct instr_emul_vie_op two_byte_opcodes[256] = { [0xB6] = { @@ -104,6 +105,7 @@ static const struct instr_emul_vie_op two_byte_opcodes[256] = { }, [0xB7] = { .op_type = VIE_OP_TYPE_MOVZX, + .op_flags = VIE_OP_F_WORD_OP, }, [0xBA] = { .op_type = VIE_OP_TYPE_BITTEST, @@ -2398,8 +2400,13 @@ int32_t decode_instruction(struct acrn_vcpu *vcpu) if (retval >= 0) { /* return the Memory Operand byte size */ - retval = ((emul_ctxt->vie.op.op_flags & VIE_OP_F_BYTE_OP) != 0U) ? - 1 : (int32_t)emul_ctxt->vie.opsize; + if ((emul_ctxt->vie.op.op_flags & VIE_OP_F_BYTE_OP) != 0U) { + retval = 1; + } else if ((emul_ctxt->vie.op.op_flags & VIE_OP_F_WORD_OP) != 0U) { + retval = 2; + } else { + retval = (int32_t)emul_ctxt->vie.opsize; + } } } }