diff options
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.patch | 90 |
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 + |