stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] KVM: x86: inject exceptions produced by x86_decode_insn
@ 2017-11-10  9:49 Paolo Bonzini
  2017-11-10 21:42 ` Radim Krčmář
  2017-11-13  7:15 ` Wanpeng Li
  0 siblings, 2 replies; 3+ messages in thread
From: Paolo Bonzini @ 2017-11-10  9:49 UTC (permalink / raw)
  To: linux-kernel, kvm; +Cc: yfu, Eduardo Habkost, stable

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>
---
 arch/x86/kvm/x86.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 34c85aa2e2d1..6dbed9022797 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5722,6 +5722,8 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
 			if (reexecute_instruction(vcpu, cr2, write_fault_to_spt,
 						emulation_type))
 				return EMULATE_DONE;
+			if (ctxt->have_exception && inject_emulated_exception(vcpu))
+				return EMULATE_DONE;
 			if (emulation_type & EMULTYPE_SKIP)
 				return EMULATE_FAIL;
 			return handle_emulation_failure(vcpu);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] KVM: x86: inject exceptions produced by x86_decode_insn
  2017-11-10  9:49 [PATCH] KVM: x86: inject exceptions produced by x86_decode_insn Paolo Bonzini
@ 2017-11-10 21:42 ` Radim Krčmář
  2017-11-13  7:15 ` Wanpeng Li
  1 sibling, 0 replies; 3+ messages in thread
From: Radim Krčmář @ 2017-11-10 21:42 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: linux-kernel, kvm, yfu, Eduardo Habkost, stable

2017-11-10 10:49+0100, Paolo Bonzini:
> 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>
> ---

Applied, thanks.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] KVM: x86: inject exceptions produced by x86_decode_insn
  2017-11-10  9:49 [PATCH] KVM: x86: inject exceptions produced by x86_decode_insn Paolo Bonzini
  2017-11-10 21:42 ` Radim Krčmář
@ 2017-11-13  7:15 ` Wanpeng Li
  1 sibling, 0 replies; 3+ messages in thread
From: Wanpeng Li @ 2017-11-13  7:15 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: linux-kernel@vger.kernel.org, kvm, yfu, Eduardo Habkost,
	# v3 . 10+

2017-11-10 17:49 GMT+08:00 Paolo Bonzini <pbonzini@redhat.com>:
> 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.

I found the only place which can set ctxt->have_exception is in the
function x86_emulate_insn(), and x86_decode_insn() will not set
ctxt->have_exception even if kvm_fetch_guest_virt() returns
X86_EMUL_PROPAGATE_FAULT.

Regards,
Wanpeng Li

>
> 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>
> ---
>  arch/x86/kvm/x86.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 34c85aa2e2d1..6dbed9022797 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -5722,6 +5722,8 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
>                         if (reexecute_instruction(vcpu, cr2, write_fault_to_spt,
>                                                 emulation_type))
>                                 return EMULATE_DONE;
> +                       if (ctxt->have_exception && inject_emulated_exception(vcpu))
> +                               return EMULATE_DONE;
>                         if (emulation_type & EMULTYPE_SKIP)
>                                 return EMULATE_FAIL;
>                         return handle_emulation_failure(vcpu);
> --
> 1.8.3.1
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-11-13  7:15 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-11-10  9:49 [PATCH] KVM: x86: inject exceptions produced by x86_decode_insn Paolo Bonzini
2017-11-10 21:42 ` Radim Krčmář
2017-11-13  7:15 ` Wanpeng Li

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).