aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoman Kagan <rkagan@virtuozzo.com>2018-07-19 14:59:07 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2018-07-20 12:07:22 -0400
commit63aff65573d73eb8dda4732ad4ef222dd35e4862 (patch)
treee156a616d972a9a7e060d7174b432c2d87f4a563
parent0a06d4256674c4e041945b52044941995fee237d (diff)
kvm: x86: vmx: fix vpid leak
VPID for the nested vcpu is allocated at vmx_create_vcpu whenever nested vmx is turned on with the module parameter. However, it's only freed if the L1 guest has executed VMXON which is not a given. As a result, on a system with nested==on every creation+deletion of an L1 vcpu without running an L2 guest results in leaking one vpid. Since the total number of vpids is limited to 64k, they can eventually get exhausted, preventing L2 from starting. Delay allocation of the L2 vpid until VMXON emulation, thus matching its freeing. Fixes: 5c614b3583e7b6dab0c86356fa36c2bcbb8322a0 Cc: stable@vger.kernel.org Signed-off-by: Roman Kagan <rkagan@virtuozzo.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/kvm/vmx.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 548bef5359e6..5d8e317c2b04 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -7893,6 +7893,8 @@ static int enter_vmx_operation(struct kvm_vcpu *vcpu)
7893 HRTIMER_MODE_REL_PINNED); 7893 HRTIMER_MODE_REL_PINNED);
7894 vmx->nested.preemption_timer.function = vmx_preemption_timer_fn; 7894 vmx->nested.preemption_timer.function = vmx_preemption_timer_fn;
7895 7895
7896 vmx->nested.vpid02 = allocate_vpid();
7897
7896 vmx->nested.vmxon = true; 7898 vmx->nested.vmxon = true;
7897 return 0; 7899 return 0;
7898 7900
@@ -10369,11 +10371,9 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
10369 goto free_vmcs; 10371 goto free_vmcs;
10370 } 10372 }
10371 10373
10372 if (nested) { 10374 if (nested)
10373 nested_vmx_setup_ctls_msrs(&vmx->nested.msrs, 10375 nested_vmx_setup_ctls_msrs(&vmx->nested.msrs,
10374 kvm_vcpu_apicv_active(&vmx->vcpu)); 10376 kvm_vcpu_apicv_active(&vmx->vcpu));
10375 vmx->nested.vpid02 = allocate_vpid();
10376 }
10377 10377
10378 vmx->nested.posted_intr_nv = -1; 10378 vmx->nested.posted_intr_nv = -1;
10379 vmx->nested.current_vmptr = -1ull; 10379 vmx->nested.current_vmptr = -1ull;
@@ -10390,7 +10390,6 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
10390 return &vmx->vcpu; 10390 return &vmx->vcpu;
10391 10391
10392free_vmcs: 10392free_vmcs:
10393 free_vpid(vmx->nested.vpid02);
10394 free_loaded_vmcs(vmx->loaded_vmcs); 10393 free_loaded_vmcs(vmx->loaded_vmcs);
10395free_msrs: 10394free_msrs:
10396 kfree(vmx->guest_msrs); 10395 kfree(vmx->guest_msrs);