diff options
author | Sheng Yang <sheng@linux.intel.com> | 2009-01-06 10:03:03 +0800 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-02-15 02:47:36 +0200 |
commit | ba4cef31d5a397b64ba6d3ff713ce06c62f0c597 (patch) | |
tree | 50a0c4cbcad5d543dd9572c5911cc288b88c3c56 /arch/x86/kvm/x86.c | |
parent | ad8ba2cd44d4d39fb3fe55d5dcc565b19fc3a7fb (diff) | |
download | lwn-ba4cef31d5a397b64ba6d3ff713ce06c62f0c597.tar.gz lwn-ba4cef31d5a397b64ba6d3ff713ce06c62f0c597.zip |
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/x86/kvm/x86.c')
-rw-r--r-- | arch/x86/kvm/x86.c | 2 |
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) void kvm_arch_sync_events(struct kvm *kvm) { + kvm_free_all_assigned_devices(kvm); } void kvm_arch_destroy_vm(struct kvm *kvm) { - kvm_free_all_assigned_devices(kvm); kvm_iommu_unmap_guest(kvm); kvm_free_pit(kvm); kfree(kvm->arch.vpic); |