Skip to content

Commit 13e457e

Browse files
anadavbonzini
authored andcommitted
KVM: x86: Emulator does not decode clflush well
Currently, all group15 instructions are decoded as clflush (e.g., mfence, xsave). In addition, the clflush instruction requires no prefix (66/f2/f3) would exist. If prefix exists it may encode a different instruction (e.g., clflushopt). Creating a group for clflush, and different group for each prefix. This has been the case forever, but the next patch needs the cflush group in order to fix a bug introduced in 3.17. Fixes: 41061cd Cc: [email protected] Signed-off-by: Nadav Amit <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent a430c91 commit 13e457e

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

arch/x86/kvm/emulate.c

+17-3
Original file line numberDiff line numberDiff line change
@@ -3462,6 +3462,12 @@ static int em_bswap(struct x86_emulate_ctxt *ctxt)
34623462
return X86EMUL_CONTINUE;
34633463
}
34643464

3465+
static int em_clflush(struct x86_emulate_ctxt *ctxt)
3466+
{
3467+
/* emulating clflush regardless of cpuid */
3468+
return X86EMUL_CONTINUE;
3469+
}
3470+
34653471
static bool valid_cr(int nr)
34663472
{
34673473
switch (nr) {
@@ -3800,6 +3806,16 @@ static const struct opcode group11[] = {
38003806
X7(D(Undefined)),
38013807
};
38023808

3809+
static const struct gprefix pfx_0f_ae_7 = {
3810+
I(0, em_clflush), N, N, N,
3811+
};
3812+
3813+
static const struct group_dual group15 = { {
3814+
N, N, N, N, N, N, N, GP(0, &pfx_0f_ae_7),
3815+
}, {
3816+
N, N, N, N, N, N, N, N,
3817+
} };
3818+
38033819
static const struct gprefix pfx_0f_6f_0f_7f = {
38043820
I(Mmx, em_mov), I(Sse | Aligned, em_mov), N, I(Sse | Unaligned, em_mov),
38053821
};
@@ -4063,7 +4079,7 @@ static const struct opcode twobyte_table[256] = {
40634079
F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
40644080
F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd),
40654081
F(DstMem | SrcReg | Src2CL | ModRM, em_shrd),
4066-
D(ModRM), F(DstReg | SrcMem | ModRM, em_imul),
4082+
GD(0, &group15), F(DstReg | SrcMem | ModRM, em_imul),
40674083
/* 0xB0 - 0xB7 */
40684084
I2bv(DstMem | SrcReg | ModRM | Lock | PageTable, em_cmpxchg),
40694085
I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg),
@@ -4993,8 +5009,6 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
49935009
case 0x90 ... 0x9f: /* setcc r/m8 */
49945010
ctxt->dst.val = test_cc(ctxt->b, ctxt->eflags);
49955011
break;
4996-
case 0xae: /* clflush */
4997-
break;
49985012
case 0xb6 ... 0xb7: /* movzx */
49995013
ctxt->dst.bytes = ctxt->op_bytes;
50005014
ctxt->dst.val = (ctxt->src.bytes == 1) ? (u8) ctxt->src.val

0 commit comments

Comments
 (0)