Commit ed9aad21 authored by Nadav Amit's avatar Nadav Amit Committed by Paolo Bonzini

KVM: x86: MOVNTI emulation min opsize is not respected

Commit 3b32004a ("KVM: x86: movnti minimum op size of 32-bit is not kept")
did not fully fix the minimum operand size of MONTI emulation. Still, MOVNTI
may be mistakenly performed using 16-bit opsize.

This patch add No16 flag to mark an instruction does not support 16-bits
operand size.
Signed-off-by: default avatarNadav Amit <namit@cs.technion.ac.il>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 7f187922
...@@ -167,6 +167,7 @@ ...@@ -167,6 +167,7 @@
#define NoBigReal ((u64)1 << 50) /* No big real mode */ #define NoBigReal ((u64)1 << 50) /* No big real mode */
#define PrivUD ((u64)1 << 51) /* #UD instead of #GP on CPL > 0 */ #define PrivUD ((u64)1 << 51) /* #UD instead of #GP on CPL > 0 */
#define NearBranch ((u64)1 << 52) /* Near branches */ #define NearBranch ((u64)1 << 52) /* Near branches */
#define No16 ((u64)1 << 53) /* No 16 bit operand */
#define DstXacc (DstAccLo | SrcAccHi | SrcWrite) #define DstXacc (DstAccLo | SrcAccHi | SrcWrite)
...@@ -4134,7 +4135,7 @@ static const struct opcode twobyte_table[256] = { ...@@ -4134,7 +4135,7 @@ static const struct opcode twobyte_table[256] = {
D(DstReg | SrcMem8 | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), D(DstReg | SrcMem8 | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov),
/* 0xC0 - 0xC7 */ /* 0xC0 - 0xC7 */
F2bv(DstMem | SrcReg | ModRM | SrcWrite | Lock, em_xadd), F2bv(DstMem | SrcReg | ModRM | SrcWrite | Lock, em_xadd),
N, D(DstMem | SrcReg | ModRM | Mov), N, I(DstMem | SrcReg | ModRM | No16 | Mov, em_mov),
N, N, N, GD(0, &group9), N, N, N, GD(0, &group9),
/* 0xC8 - 0xCF */ /* 0xC8 - 0xCF */
X8(I(DstReg, em_bswap)), X8(I(DstReg, em_bswap)),
...@@ -4571,7 +4572,8 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) ...@@ -4571,7 +4572,8 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
return EMULATION_FAILED; return EMULATION_FAILED;
if (unlikely(ctxt->d & if (unlikely(ctxt->d &
(NotImpl|Stack|Op3264|Sse|Mmx|Intercept|CheckPerm|NearBranch))) { (NotImpl|Stack|Op3264|Sse|Mmx|Intercept|CheckPerm|NearBranch|
No16))) {
/* /*
* These are copied unconditionally here, and checked unconditionally * These are copied unconditionally here, and checked unconditionally
* in x86_emulate_insn. * in x86_emulate_insn.
...@@ -4596,6 +4598,9 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) ...@@ -4596,6 +4598,9 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
ctxt->op_bytes = 4; ctxt->op_bytes = 4;
} }
if ((ctxt->d & No16) && ctxt->op_bytes == 2)
ctxt->op_bytes = 4;
if (ctxt->d & Sse) if (ctxt->d & Sse)
ctxt->op_bytes = 16; ctxt->op_bytes = 16;
else if (ctxt->d & Mmx) else if (ctxt->d & Mmx)
...@@ -5061,11 +5066,6 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) ...@@ -5061,11 +5066,6 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
ctxt->dst.val = (ctxt->src.bytes == 1) ? (s8) ctxt->src.val : ctxt->dst.val = (ctxt->src.bytes == 1) ? (s8) ctxt->src.val :
(s16) ctxt->src.val; (s16) ctxt->src.val;
break; break;
case 0xc3: /* movnti */
ctxt->dst.bytes = ctxt->op_bytes;
ctxt->dst.val = (ctxt->op_bytes == 8) ? (u64) ctxt->src.val :
(u32) ctxt->src.val;
break;
default: default:
goto cannot_emulate; goto cannot_emulate;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment