summaryrefslogtreecommitdiff
path: root/virt
diff options
context:
space:
mode:
authorJim Mattson <jmattson@google.com>2016-07-08 15:36:06 -0700
committerBen Hutchings <ben@decadent.org.uk>2016-11-20 01:01:26 +0000
commitc848310491586221cf5f5bf5c5c627e3b78b1757 (patch)
tree1d47f4b52929ae99959dfa59180cbf28a23347cb /virt
parentbcad1c3975a8b59d2695c5f1dc85aba24330a51f (diff)
downloadlinux-c848310491586221cf5f5bf5c5c627e3b78b1757.tar.gz
linux-c848310491586221cf5f5bf5c5c627e3b78b1757.tar.bz2
linux-c848310491586221cf5f5bf5c5c627e3b78b1757.zip
KVM: nVMX: Fix memory corruption when using VMCS shadowing
commit 2f1fe81123f59271bddda673b60116bde9660385 upstream. When freeing the nested resources of a vcpu, there is an assumption that the vcpu's vmcs01 is the current VMCS on the CPU that executes nested_release_vmcs12(). If this assumption is violated, the vcpu's vmcs01 may be made active on multiple CPUs at the same time, in violation of Intel's specification. Moreover, since the vcpu's vmcs01 is not VMCLEARed on every CPU on which it is active, it can linger in a CPU's VMCS cache after it has been freed and potentially repurposed. Subsequent eviction from the CPU's VMCS cache on a capacity miss can result in memory corruption. It is not sufficient for vmx_free_vcpu() to call vmx_load_vmcs01(). If the vcpu in question was last loaded on a different CPU, it must be migrated to the current CPU before calling vmx_load_vmcs01(). Signed-off-by: Jim Mattson <jmattson@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> [bwh: Backported to 3.2: vcpu_load() returns void] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/kvm_main.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 8b0617a648d1..375e0539597c 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -156,6 +156,7 @@ void vcpu_load(struct kvm_vcpu *vcpu)
kvm_arch_vcpu_load(vcpu, cpu);
put_cpu();
}
+EXPORT_SYMBOL_GPL(vcpu_load);
void vcpu_put(struct kvm_vcpu *vcpu)
{
@@ -165,6 +166,7 @@ void vcpu_put(struct kvm_vcpu *vcpu)
preempt_enable();
mutex_unlock(&vcpu->mutex);
}
+EXPORT_SYMBOL_GPL(vcpu_put);
static void ack_flush(void *_completed)
{