OSDN Git Service

KVM: x86: inject exceptions produced by x86_decode_insn
authorPaolo Bonzini <pbonzini@redhat.com>
Fri, 10 Nov 2017 09:49:38 +0000 (10:49 +0100)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 17 Nov 2017 12:20:16 +0000 (13:20 +0100)
commit6ea6e84309ca7e0e850b3083e6b09344ee15c290
treeb09493040739e5ee1546e9a18dcc5d43ca752ce3
parentfab0aa3b776f0a3af1db1f50e04f1884015f9082
KVM: x86: inject exceptions produced by x86_decode_insn

Sometimes, a processor might execute an instruction while another
processor is updating the page tables for that instruction's code page,
but before the TLB shootdown completes.  The interesting case happens
if the page is in the TLB.

In general, the processor will succeed in executing the instruction and
nothing bad happens.  However, what if the instruction is an MMIO access?
If *that* happens, KVM invokes the emulator, and the emulator gets the
updated page tables.  If the update side had marked the code page as non
present, the page table walk then will fail and so will x86_decode_insn.

Unfortunately, even though kvm_fetch_guest_virt is correctly returning
X86EMUL_PROPAGATE_FAULT, x86_decode_insn's caller treats the failure as
a fatal error if the instruction cannot simply be reexecuted (as is the
case for MMIO).  And this in fact happened sometimes when rebooting
Windows 2012r2 guests.  Just checking ctxt->have_exception and injecting
the exception if true is enough to fix the case.

Thanks to Eduardo Habkost for helping in the debugging of this issue.

Reported-by: Yanan Fu <yfu@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
arch/x86/kvm/x86.c