diff options
author | Avi Kivity <avi@qumranet.com> | 2007-06-05 05:17:03 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2007-07-16 05:05:45 -0400 |
commit | 7b53aa56508479507c6e5667bb252ca7c2cd19cf (patch) | |
tree | d2020d70e6578f0d6405cba3f3b5a1ccdc62a581 /drivers/kvm/kvm_main.c | |
parent | 313899477f7578d37e82ead1af10f794a6da3c90 (diff) |
KVM: Fix vcpu freeing for guest smp
A vcpu can pin up to four mmu shadow pages, which means the freeing
loop will never terminate. Fix by first unpinning shadow pages on
all vcpus, then freeing shadow pages.
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r-- | drivers/kvm/kvm_main.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index 3c3231d8dabf..3ff8ee56279c 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -381,6 +381,16 @@ static void free_pio_guest_pages(struct kvm_vcpu *vcpu) | |||
381 | } | 381 | } |
382 | } | 382 | } |
383 | 383 | ||
384 | static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu) | ||
385 | { | ||
386 | if (!vcpu->vmcs) | ||
387 | return; | ||
388 | |||
389 | vcpu_load(vcpu); | ||
390 | kvm_mmu_unload(vcpu); | ||
391 | vcpu_put(vcpu); | ||
392 | } | ||
393 | |||
384 | static void kvm_free_vcpu(struct kvm_vcpu *vcpu) | 394 | static void kvm_free_vcpu(struct kvm_vcpu *vcpu) |
385 | { | 395 | { |
386 | if (!vcpu->vmcs) | 396 | if (!vcpu->vmcs) |
@@ -401,6 +411,11 @@ static void kvm_free_vcpus(struct kvm *kvm) | |||
401 | { | 411 | { |
402 | unsigned int i; | 412 | unsigned int i; |
403 | 413 | ||
414 | /* | ||
415 | * Unpin any mmu pages first. | ||
416 | */ | ||
417 | for (i = 0; i < KVM_MAX_VCPUS; ++i) | ||
418 | kvm_unload_vcpu_mmu(&kvm->vcpus[i]); | ||
404 | for (i = 0; i < KVM_MAX_VCPUS; ++i) | 419 | for (i = 0; i < KVM_MAX_VCPUS; ++i) |
405 | kvm_free_vcpu(&kvm->vcpus[i]); | 420 | kvm_free_vcpu(&kvm->vcpus[i]); |
406 | } | 421 | } |