b13680
From: Nadav Amit <namit@cs.technion.ac.il>
b13680
Date: Fri, 24 Oct 2014 17:07:22 +0200
b13680
Subject: [PATCH] KVM: x86: Emulator does not decode clflush well
b13680
b13680
Currently, all group15 instructions are decoded as clflush (e.g., mfence,
b13680
xsave).  In addition, the clflush instruction requires no prefix (66/f2/f3)
b13680
would exist. If prefix exists it may encode a different instruction (e.g.,
b13680
clflushopt).
b13680
b13680
Creating a group for clflush, and different group for each prefix.
b13680
b13680
This has been the case forever, but the next patch needs the cflush group
b13680
in order to fix a bug introduced in 3.17.
b13680
b13680
Fixes: 41061cdb98a0bec464278b4db8e894a3121671f5
b13680
Cc: stable@vger.kernel.org
b13680
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
b13680
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
b13680
---
b13680
 arch/x86/kvm/emulate.c | 20 +++++++++++++++++---
b13680
 1 file changed, 17 insertions(+), 3 deletions(-)
b13680
b13680
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
b13680
index 5669ed12f9ee..d1a19289d11a 100644
b13680
--- a/arch/x86/kvm/emulate.c
b13680
+++ b/arch/x86/kvm/emulate.c
b13680
@@ -3458,6 +3458,12 @@ static int em_bswap(struct x86_emulate_ctxt *ctxt)
b13680
 	return X86EMUL_CONTINUE;
b13680
 }
b13680
 
b13680
+static int em_clflush(struct x86_emulate_ctxt *ctxt)
b13680
+{
b13680
+	/* emulating clflush regardless of cpuid */
b13680
+	return X86EMUL_CONTINUE;
b13680
+}
b13680
+
b13680
 static bool valid_cr(int nr)
b13680
 {
b13680
 	switch (nr) {
b13680
@@ -3790,6 +3796,16 @@ static const struct opcode group11[] = {
b13680
 	X7(D(Undefined)),
b13680
 };
b13680
 
b13680
+static const struct gprefix pfx_0f_ae_7 = {
b13680
+	I(0, em_clflush), N, N, N,
b13680
+};
b13680
+
b13680
+static const struct group_dual group15 = { {
b13680
+	N, N, N, N, N, N, N, GP(0, &pfx_0f_ae_7),
b13680
+}, {
b13680
+	N, N, N, N, N, N, N, N,
b13680
+} };
b13680
+
b13680
 static const struct gprefix pfx_0f_6f_0f_7f = {
b13680
 	I(Mmx, em_mov), I(Sse | Aligned, em_mov), N, I(Sse | Unaligned, em_mov),
b13680
 };
b13680
@@ -4049,7 +4065,7 @@ static const struct opcode twobyte_table[256] = {
b13680
 	F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
b13680
 	F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd),
b13680
 	F(DstMem | SrcReg | Src2CL | ModRM, em_shrd),
b13680
-	D(ModRM), F(DstReg | SrcMem | ModRM, em_imul),
b13680
+	GD(0, &group15), F(DstReg | SrcMem | ModRM, em_imul),
b13680
 	/* 0xB0 - 0xB7 */
b13680
 	I2bv(DstMem | SrcReg | ModRM | Lock | PageTable, em_cmpxchg),
b13680
 	I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg),
b13680
@@ -4976,8 +4992,6 @@ twobyte_insn:
b13680
 	case 0x90 ... 0x9f:     /* setcc r/m8 */
b13680
 		ctxt->dst.val = test_cc(ctxt->b, ctxt->eflags);
b13680
 		break;
b13680
-	case 0xae:              /* clflush */
b13680
-		break;
b13680
 	case 0xb6 ... 0xb7:	/* movzx */
b13680
 		ctxt->dst.bytes = ctxt->op_bytes;
b13680
 		ctxt->dst.val = (ctxt->src.bytes == 1) ? (u8) ctxt->src.val
b13680
-- 
b13680
1.9.3
b13680