aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorNadav Amit <namit@cs.technion.ac.il>2014-10-13 06:04:13 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-10-24 07:30:36 -0400
commit13e457e0eebf0a0c82c38ceb890d93eb826d62a6 (patch)
treef0ab042f6b4b419ec6cda09f0f199764636fda25 /arch/x86/kvm
parenta430c9166312e1aa3d80bce32374233bdbfeba32 (diff)
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: 41061cdb98a0bec464278b4db8e894a3121671f5 Cc: stable@vger.kernel.org Signed-off-by: Nadav Amit <namit@cs.technion.ac.il> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/emulate.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index eb3b1c46f995..97da5034d812 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -3462,6 +3462,12 @@ static int em_bswap(struct x86_emulate_ctxt *ctxt)
3462 return X86EMUL_CONTINUE; 3462 return X86EMUL_CONTINUE;
3463} 3463}
3464 3464
3465static int em_clflush(struct x86_emulate_ctxt *ctxt)
3466{
3467 /* emulating clflush regardless of cpuid */
3468 return X86EMUL_CONTINUE;
3469}
3470
3465static bool valid_cr(int nr) 3471static bool valid_cr(int nr)
3466{ 3472{
3467 switch (nr) { 3473 switch (nr) {
@@ -3800,6 +3806,16 @@ static const struct opcode group11[] = {
3800 X7(D(Undefined)), 3806 X7(D(Undefined)),
3801}; 3807};
3802 3808
3809static const struct gprefix pfx_0f_ae_7 = {
3810 I(0, em_clflush), N, N, N,
3811};
3812
3813static 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
3803static const struct gprefix pfx_0f_6f_0f_7f = { 3819static const struct gprefix pfx_0f_6f_0f_7f = {
3804 I(Mmx, em_mov), I(Sse | Aligned, em_mov), N, I(Sse | Unaligned, em_mov), 3820 I(Mmx, em_mov), I(Sse | Aligned, em_mov), N, I(Sse | Unaligned, em_mov),
3805}; 3821};
@@ -4063,7 +4079,7 @@ static const struct opcode twobyte_table[256] = {
4063 F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts), 4079 F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
4064 F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd), 4080 F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd),
4065 F(DstMem | SrcReg | Src2CL | ModRM, em_shrd), 4081 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),
4067 /* 0xB0 - 0xB7 */ 4083 /* 0xB0 - 0xB7 */
4068 I2bv(DstMem | SrcReg | ModRM | Lock | PageTable, em_cmpxchg), 4084 I2bv(DstMem | SrcReg | ModRM | Lock | PageTable, em_cmpxchg),
4069 I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg), 4085 I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg),
@@ -4993,8 +5009,6 @@ twobyte_insn:
4993 case 0x90 ... 0x9f: /* setcc r/m8 */ 5009 case 0x90 ... 0x9f: /* setcc r/m8 */
4994 ctxt->dst.val = test_cc(ctxt->b, ctxt->eflags); 5010 ctxt->dst.val = test_cc(ctxt->b, ctxt->eflags);
4995 break; 5011 break;
4996 case 0xae: /* clflush */
4997 break;
4998 case 0xb6 ... 0xb7: /* movzx */ 5012 case 0xb6 ... 0xb7: /* movzx */
4999 ctxt->dst.bytes = ctxt->op_bytes; 5013 ctxt->dst.bytes = ctxt->op_bytes;
5000 ctxt->dst.val = (ctxt->src.bytes == 1) ? (u8) ctxt->src.val 5014 ctxt->dst.val = (ctxt->src.bytes == 1) ? (u8) ctxt->src.val