Commit 13e457e0eebf0a0c82c38ceb890d93eb826d62a6
Committed by
Paolo Bonzini
1 parent
a430c91663
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
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>
Showing 1 changed file with 17 additions and 3 deletions Side-by-side Diff
arch/x86/kvm/emulate.c
... | ... | @@ -3462,6 +3462,12 @@ |
3462 | 3462 | return X86EMUL_CONTINUE; |
3463 | 3463 | } |
3464 | 3464 | |
3465 | +static int em_clflush(struct x86_emulate_ctxt *ctxt) | |
3466 | +{ | |
3467 | + /* emulating clflush regardless of cpuid */ | |
3468 | + return X86EMUL_CONTINUE; | |
3469 | +} | |
3470 | + | |
3465 | 3471 | static bool valid_cr(int nr) |
3466 | 3472 | { |
3467 | 3473 | switch (nr) { |
... | ... | @@ -3800,6 +3806,16 @@ |
3800 | 3806 | X7(D(Undefined)), |
3801 | 3807 | }; |
3802 | 3808 | |
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 | + | |
3803 | 3819 | static const struct gprefix pfx_0f_6f_0f_7f = { |
3804 | 3820 | I(Mmx, em_mov), I(Sse | Aligned, em_mov), N, I(Sse | Unaligned, em_mov), |
3805 | 3821 | }; |
... | ... | @@ -4063,7 +4079,7 @@ |
4063 | 4079 | F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts), |
4064 | 4080 | F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd), |
4065 | 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 | 4083 | /* 0xB0 - 0xB7 */ |
4068 | 4084 | I2bv(DstMem | SrcReg | ModRM | Lock | PageTable, em_cmpxchg), |
4069 | 4085 | I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg), |
... | ... | @@ -4992,8 +5008,6 @@ |
4992 | 5008 | break; |
4993 | 5009 | case 0x90 ... 0x9f: /* setcc r/m8 */ |
4994 | 5010 | ctxt->dst.val = test_cc(ctxt->b, ctxt->eflags); |
4995 | - break; | |
4996 | - case 0xae: /* clflush */ | |
4997 | 5011 | break; |
4998 | 5012 | case 0xb6 ... 0xb7: /* movzx */ |
4999 | 5013 | ctxt->dst.bytes = ctxt->op_bytes; |