1
From: Alex Williamson <alex.williamson@redhat.com>
2
Date: Tue, 17 Apr 2012 21:46:44 -0600
3
Subject: [PATCH] KVM: lock slots_lock around device assignment
5
commit 21a1416a1c945c5aeaeaf791b63c64926018eb77 upstream.
7
As pointed out by Jason Baron, when assigning a device to a guest
8
we first set the iommu domain pointer, which enables mapping
9
and unmapping of memory slots to the iommu. This leaves a window
10
where this path is enabled, but we haven't synchronized the iommu
11
mappings to the existing memory slots. Thus a slot being removed
12
at that point could send us down unexpected code paths removing
13
non-existent pinnings and iommu mappings. Take the slots_lock
14
around creating the iommu domain and initial mappings as well as
15
around iommu teardown to avoid this race.
17
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
18
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
20
virt/kvm/iommu.c | 23 +++++++++++++++--------
21
1 file changed, 15 insertions(+), 8 deletions(-)
23
diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c
24
index fec1723..e9fff98 100644
25
--- a/virt/kvm/iommu.c
26
+++ b/virt/kvm/iommu.c
27
@@ -240,9 +240,13 @@ int kvm_iommu_map_guest(struct kvm *kvm)
31
+ mutex_lock(&kvm->slots_lock);
33
kvm->arch.iommu_domain = iommu_domain_alloc(&pci_bus_type);
34
- if (!kvm->arch.iommu_domain)
36
+ if (!kvm->arch.iommu_domain) {
41
if (!allow_unsafe_assigned_interrupts &&
42
!iommu_domain_has_cap(kvm->arch.iommu_domain,
43
@@ -253,17 +257,16 @@ int kvm_iommu_map_guest(struct kvm *kvm)
44
" module option.\n", __func__);
45
iommu_domain_free(kvm->arch.iommu_domain);
46
kvm->arch.iommu_domain = NULL;
52
r = kvm_iommu_map_memslots(kvm);
57
+ kvm_iommu_unmap_memslots(kvm);
60
- kvm_iommu_unmap_memslots(kvm);
62
+ mutex_unlock(&kvm->slots_lock);
66
@@ -340,7 +343,11 @@ int kvm_iommu_unmap_guest(struct kvm *kvm)
70
+ mutex_lock(&kvm->slots_lock);
71
kvm_iommu_unmap_memslots(kvm);
72
+ kvm->arch.iommu_domain = NULL;
73
+ mutex_unlock(&kvm->slots_lock);
75
iommu_domain_free(domain);