diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.9.21/0014-KVM-nVMX-Fix-handling-of-lmsw-instruction.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.9.21/0014-KVM-nVMX-Fix-handling-of-lmsw-instruction.patch | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.9.21/0014-KVM-nVMX-Fix-handling-of-lmsw-instruction.patch b/common/recipes-kernel/linux/linux-yocto-4.9.21/0014-KVM-nVMX-Fix-handling-of-lmsw-instruction.patch new file mode 100644 index 00000000..43b1f38e --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.9.21/0014-KVM-nVMX-Fix-handling-of-lmsw-instruction.patch @@ -0,0 +1,63 @@ +From 2c5329f428b85d1167abdd3206bdac08a02ae082 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20H=2E=20Sch=C3=B6nherr?= <jschoenh@amazon.de> +Date: Sat, 20 May 2017 13:22:56 +0200 +Subject: [PATCH 14/93] KVM: nVMX: Fix handling of lmsw instruction +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[ Upstream commit e1d39b17e044e8ae819827810d87d809ba5f58c0 ] + +The decision whether or not to exit from L2 to L1 on an lmsw instruction is +based on bogus values: instead of using the information encoded within the +exit qualification, it uses the data also used for the mov-to-cr +instruction, which boils down to using whatever is in %eax at that point. + +Use the correct values instead. + +Without this fix, an L1 may not get notified when a 32-bit Linux L2 +switches its secondary CPUs to protected mode; the L1 is only notified on +the next modification of CR0. This short time window poses a problem, when +there is some other reason to exit to L1 in between. Then, L2 will be +resumed in real mode and chaos ensues. + +Signed-off-by: Jan H. Schönherr <jschoenh@amazon.de> +Reviewed-by: Wanpeng Li <wanpeng.li@hotmail.com> +Signed-off-by: Paolo Bonzini <pbonzini@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 | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index 27f505d..8d842d9 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -7910,11 +7910,13 @@ static bool nested_vmx_exit_handled_cr(struct kvm_vcpu *vcpu, + { + unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); + int cr = exit_qualification & 15; +- int reg = (exit_qualification >> 8) & 15; +- unsigned long val = kvm_register_readl(vcpu, reg); ++ int reg; ++ unsigned long val; + + switch ((exit_qualification >> 4) & 3) { + case 0: /* mov to cr */ ++ reg = (exit_qualification >> 8) & 15; ++ val = kvm_register_readl(vcpu, reg); + switch (cr) { + case 0: + if (vmcs12->cr0_guest_host_mask & +@@ -7969,6 +7971,7 @@ static bool nested_vmx_exit_handled_cr(struct kvm_vcpu *vcpu, + * lmsw can change bits 1..3 of cr0, and only set bit 0 of + * cr0. Other attempted changes are ignored, with no exit. + */ ++ val = (exit_qualification >> LMSW_SOURCE_DATA_SHIFT) & 0x0f; + if (vmcs12->cr0_guest_host_mask & 0xe & + (val ^ vmcs12->cr0_read_shadow)) + return true; +-- +2.7.4 + |