提交 7b53aa56 编写于 作者: A Avi Kivity

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: NAvi Kivity <avi@qumranet.com>
上级 31389947
...@@ -381,6 +381,16 @@ static void free_pio_guest_pages(struct kvm_vcpu *vcpu) ...@@ -381,6 +381,16 @@ static void free_pio_guest_pages(struct kvm_vcpu *vcpu)
} }
} }
static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu)
{
if (!vcpu->vmcs)
return;
vcpu_load(vcpu);
kvm_mmu_unload(vcpu);
vcpu_put(vcpu);
}
static void kvm_free_vcpu(struct kvm_vcpu *vcpu) static void kvm_free_vcpu(struct kvm_vcpu *vcpu)
{ {
if (!vcpu->vmcs) if (!vcpu->vmcs)
...@@ -401,6 +411,11 @@ static void kvm_free_vcpus(struct kvm *kvm) ...@@ -401,6 +411,11 @@ static void kvm_free_vcpus(struct kvm *kvm)
{ {
unsigned int i; unsigned int i;
/*
* Unpin any mmu pages first.
*/
for (i = 0; i < KVM_MAX_VCPUS; ++i)
kvm_unload_vcpu_mmu(&kvm->vcpus[i]);
for (i = 0; i < KVM_MAX_VCPUS; ++i) for (i = 0; i < KVM_MAX_VCPUS; ++i)
kvm_free_vcpu(&kvm->vcpus[i]); kvm_free_vcpu(&kvm->vcpus[i]);
} }
......
...@@ -838,11 +838,12 @@ static void mmu_free_roots(struct kvm_vcpu *vcpu) ...@@ -838,11 +838,12 @@ static void mmu_free_roots(struct kvm_vcpu *vcpu)
int i; int i;
struct kvm_mmu_page *page; struct kvm_mmu_page *page;
if (!VALID_PAGE(vcpu->mmu.root_hpa))
return;
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
if (vcpu->mmu.shadow_root_level == PT64_ROOT_LEVEL) { if (vcpu->mmu.shadow_root_level == PT64_ROOT_LEVEL) {
hpa_t root = vcpu->mmu.root_hpa; hpa_t root = vcpu->mmu.root_hpa;
ASSERT(VALID_PAGE(root));
page = page_header(root); page = page_header(root);
--page->root_count; --page->root_count;
vcpu->mmu.root_hpa = INVALID_PAGE; vcpu->mmu.root_hpa = INVALID_PAGE;
...@@ -853,7 +854,6 @@ static void mmu_free_roots(struct kvm_vcpu *vcpu) ...@@ -853,7 +854,6 @@ static void mmu_free_roots(struct kvm_vcpu *vcpu)
hpa_t root = vcpu->mmu.pae_root[i]; hpa_t root = vcpu->mmu.pae_root[i];
if (root) { if (root) {
ASSERT(VALID_PAGE(root));
root &= PT64_BASE_ADDR_MASK; root &= PT64_BASE_ADDR_MASK;
page = page_header(root); page = page_header(root);
--page->root_count; --page->root_count;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册