aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSheng Yang <sheng@linux.intel.com>2009-01-05 21:03:03 -0500
committerAvi Kivity <avi@redhat.com>2009-02-14 19:47:36 -0500
commitba4cef31d5a397b64ba6d3ff713ce06c62f0c597 (patch)
tree50a0c4cbcad5d543dd9572c5911cc288b88c3c56 /arch
parentad8ba2cd44d4d39fb3fe55d5dcc565b19fc3a7fb (diff)
KVM: Fix racy in kvm_free_assigned_irq
In the past, kvm_get_kvm() and kvm_put_kvm() was called in assigned device irq handler and interrupt_work, in order to prevent cancel_work_sync() in kvm_free_assigned_irq got a illegal state when waiting for interrupt_work done. But it's tricky and still got two problems: 1. A bug ignored two conditions that cancel_work_sync() would return true result in a additional kvm_put_kvm(). 2. If interrupt type is MSI, we would got a window between cancel_work_sync() and free_irq(), which interrupt would be injected again... This patch discard the reference count used for irq handler and interrupt_work, and ensure the legal state by moving the free function at the very beginning of kvm_destroy_vm(). And the patch fix the second bug by disable irq before cancel_work_sync(), which may result in nested disable of irq but OK for we are going to free it. Signed-off-by: Sheng Yang <sheng@linux.intel.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/x86.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b0fc079f1bee..fc3e329f6ade 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4129,11 +4129,11 @@ static void kvm_free_vcpus(struct kvm *kvm)
4129 4129
4130void kvm_arch_sync_events(struct kvm *kvm) 4130void kvm_arch_sync_events(struct kvm *kvm)
4131{ 4131{
4132 kvm_free_all_assigned_devices(kvm);
4132} 4133}
4133 4134
4134void kvm_arch_destroy_vm(struct kvm *kvm) 4135void kvm_arch_destroy_vm(struct kvm *kvm)
4135{ 4136{
4136 kvm_free_all_assigned_devices(kvm);
4137 kvm_iommu_unmap_guest(kvm); 4137 kvm_iommu_unmap_guest(kvm);
4138 kvm_free_pit(kvm); 4138 kvm_free_pit(kvm);
4139 kfree(kvm->arch.vpic); 4139 kfree(kvm->arch.vpic);