aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.9.21/0084-KVM-VMX-raise-internal-error-for-exception-during-in.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.9.21/0084-KVM-VMX-raise-internal-error-for-exception-during-in.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.9.21/0084-KVM-VMX-raise-internal-error-for-exception-during-in.patch90
1 files changed, 90 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.9.21/0084-KVM-VMX-raise-internal-error-for-exception-during-in.patch b/common/recipes-kernel/linux/linux-yocto-4.9.21/0084-KVM-VMX-raise-internal-error-for-exception-during-in.patch
new file mode 100644
index 00000000..a2280307
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.9.21/0084-KVM-VMX-raise-internal-error-for-exception-during-in.patch
@@ -0,0 +1,90 @@
+From 075696ba348a4c1eb20a641157f84f8b81220510 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <sean.j.christopherson@intel.com>
+Date: Fri, 23 Mar 2018 09:34:00 -0700
+Subject: [PATCH 84/93] KVM: VMX: raise internal error for exception during
+ invalid protected mode state
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+[ Upstream commit add5ff7a216ee545a214013f26d1ef2f44a9c9f8 ]
+
+Exit to userspace with KVM_INTERNAL_ERROR_EMULATION if we encounter
+an exception in Protected Mode while emulating guest due to invalid
+guest state. Unlike Big RM, KVM doesn't support emulating exceptions
+in PM, i.e. PM exceptions are always injected via the VMCS. Because
+we will never do VMRESUME due to emulation_required, the exception is
+never realized and we'll keep emulating the faulting instruction over
+and over until we receive a signal.
+
+Exit to userspace iff there is a pending exception, i.e. don't exit
+simply on a requested event. The purpose of this check and exit is to
+aid in debugging a guest that is in all likelihood already doomed.
+Invalid guest state in PM is extremely limited in normal operation,
+e.g. it generally only occurs for a few instructions early in BIOS,
+and any exception at this time is all but guaranteed to be fatal.
+Non-vectored interrupts, e.g. INIT, SIPI and SMI, can be cleanly
+handled/emulated, while checking for vectored interrupts, e.g. INTR
+and NMI, without hitting false positives would add a fair amount of
+complexity for almost no benefit (getting hit by lightning seems
+more likely than encountering this specific scenario).
+
+Add a WARN_ON_ONCE to vmx_queue_exception() if we try to inject an
+exception via the VMCS and emulation_required is true.
+
+Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
+Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/vmx.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index 7b4739c..9307c0d 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -2555,6 +2555,8 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
+ return;
+ }
+
++ WARN_ON_ONCE(vmx->emulation_required);
++
+ if (kvm_exception_is_soft(nr)) {
+ vmcs_write32(VM_ENTRY_INSTRUCTION_LEN,
+ vmx->vcpu.arch.event_exit_inst_len);
+@@ -6405,12 +6407,12 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
+ goto out;
+ }
+
+- if (err != EMULATE_DONE) {
+- vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
+- vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
+- vcpu->run->internal.ndata = 0;
+- return 0;
+- }
++ if (err != EMULATE_DONE)
++ goto emulation_error;
++
++ if (vmx->emulation_required && !vmx->rmode.vm86_active &&
++ vcpu->arch.exception.pending)
++ goto emulation_error;
+
+ if (vcpu->arch.halt_request) {
+ vcpu->arch.halt_request = 0;
+@@ -6426,6 +6428,12 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
+
+ out:
+ return ret;
++
++emulation_error:
++ vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
++ vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
++ vcpu->run->internal.ndata = 0;
++ return 0;
+ }
+
+ static int __grow_ple_window(int val)
+--
+2.7.4
+