]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.18.86/kvm-x86-inject-exceptions-produced-by-x86_decode_insn.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.18.86 / kvm-x86-inject-exceptions-produced-by-x86_decode_insn.patch
1 From 6ea6e84309ca7e0e850b3083e6b09344ee15c290 Mon Sep 17 00:00:00 2001
2 From: Paolo Bonzini <pbonzini@redhat.com>
3 Date: Fri, 10 Nov 2017 10:49:38 +0100
4 Subject: KVM: x86: inject exceptions produced by x86_decode_insn
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 From: Paolo Bonzini <pbonzini@redhat.com>
10
11 commit 6ea6e84309ca7e0e850b3083e6b09344ee15c290 upstream.
12
13 Sometimes, a processor might execute an instruction while another
14 processor is updating the page tables for that instruction's code page,
15 but before the TLB shootdown completes. The interesting case happens
16 if the page is in the TLB.
17
18 In general, the processor will succeed in executing the instruction and
19 nothing bad happens. However, what if the instruction is an MMIO access?
20 If *that* happens, KVM invokes the emulator, and the emulator gets the
21 updated page tables. If the update side had marked the code page as non
22 present, the page table walk then will fail and so will x86_decode_insn.
23
24 Unfortunately, even though kvm_fetch_guest_virt is correctly returning
25 X86EMUL_PROPAGATE_FAULT, x86_decode_insn's caller treats the failure as
26 a fatal error if the instruction cannot simply be reexecuted (as is the
27 case for MMIO). And this in fact happened sometimes when rebooting
28 Windows 2012r2 guests. Just checking ctxt->have_exception and injecting
29 the exception if true is enough to fix the case.
30
31 Thanks to Eduardo Habkost for helping in the debugging of this issue.
32
33 Reported-by: Yanan Fu <yfu@redhat.com>
34 Cc: Eduardo Habkost <ehabkost@redhat.com>
35 Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
36 Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
37 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
38
39 ---
40 arch/x86/kvm/x86.c | 2 ++
41 1 file changed, 2 insertions(+)
42
43 --- a/arch/x86/kvm/x86.c
44 +++ b/arch/x86/kvm/x86.c
45 @@ -5372,6 +5372,8 @@ int x86_emulate_instruction(struct kvm_v
46 if (reexecute_instruction(vcpu, cr2, write_fault_to_spt,
47 emulation_type))
48 return EMULATE_DONE;
49 + if (ctxt->have_exception && inject_emulated_exception(vcpu))
50 + return EMULATE_DONE;
51 if (emulation_type & EMULTYPE_SKIP)
52 return EMULATE_FAIL;
53 return handle_emulation_failure(vcpu);