git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git]
/
virt
/
kvm
/
iommu.c
diff --git
a/virt/kvm/iommu.c
b/virt/kvm/iommu.c
index
a195c07
..
5dbb35d
100644
(file)
--- a/
virt/kvm/iommu.c
+++ b/
virt/kvm/iommu.c
@@
-101,6
+101,10
@@
int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
while ((gfn << PAGE_SHIFT) & (page_size - 1))
page_size >>= 1;
while ((gfn << PAGE_SHIFT) & (page_size - 1))
page_size >>= 1;
+ /* Make sure hva is aligned to the page size we want to map */
+ while (gfn_to_hva_memslot(slot, gfn) & (page_size - 1))
+ page_size >>= 1;
+
/*
* Pin all pages we are about to map in memory. This is
* important because we unmap and unpin in 4kb steps later.
/*
* Pin all pages we are about to map in memory. This is
* important because we unmap and unpin in 4kb steps later.
@@
-239,9
+243,13
@@
int kvm_iommu_map_guest(struct kvm *kvm)
return -ENODEV;
}
return -ENODEV;
}
+ mutex_lock(&kvm->slots_lock);
+
kvm->arch.iommu_domain = iommu_domain_alloc(&pci_bus_type);
kvm->arch.iommu_domain = iommu_domain_alloc(&pci_bus_type);
- if (!kvm->arch.iommu_domain)
- return -ENOMEM;
+ if (!kvm->arch.iommu_domain) {
+ r = -ENOMEM;
+ goto out_unlock;
+ }
if (!allow_unsafe_assigned_interrupts &&
!iommu_domain_has_cap(kvm->arch.iommu_domain,
if (!allow_unsafe_assigned_interrupts &&
!iommu_domain_has_cap(kvm->arch.iommu_domain,
@@
-252,17
+260,16
@@
int kvm_iommu_map_guest(struct kvm *kvm)
" module option.\n", __func__);
iommu_domain_free(kvm->arch.iommu_domain);
kvm->arch.iommu_domain = NULL;
" module option.\n", __func__);
iommu_domain_free(kvm->arch.iommu_domain);
kvm->arch.iommu_domain = NULL;
- return -EPERM;
+ r = -EPERM;
+ goto out_unlock;
}
r = kvm_iommu_map_memslots(kvm);
if (r)
}
r = kvm_iommu_map_memslots(kvm);
if (r)
- goto out_unmap;
-
- return 0;
+ kvm_iommu_unmap_memslots(kvm);
-out_un
map
:
-
kvm_iommu_unmap_memslots(kvm
);
+out_un
lock
:
+
mutex_unlock(&kvm->slots_lock
);
return r;
}
return r;
}
@@
-309,6
+316,11
@@
static void kvm_iommu_put_pages(struct kvm *kvm,
}
}
}
}
+void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
+{
+ kvm_iommu_put_pages(kvm, slot->base_gfn, slot->npages);
+}
+
static int kvm_iommu_unmap_memslots(struct kvm *kvm)
{
int i, idx;
static int kvm_iommu_unmap_memslots(struct kvm *kvm)
{
int i, idx;
@@
-317,10
+329,9
@@
static int kvm_iommu_unmap_memslots(struct kvm *kvm)
idx = srcu_read_lock(&kvm->srcu);
slots = kvm_memslots(kvm);
idx = srcu_read_lock(&kvm->srcu);
slots = kvm_memslots(kvm);
- for (i = 0; i < slots->nmemslots; i++) {
- kvm_iommu_put_pages(kvm, slots->memslots[i].base_gfn,
- slots->memslots[i].npages);
- }
+ for (i = 0; i < slots->nmemslots; i++)
+ kvm_iommu_unmap_pages(kvm, &slots->memslots[i]);
+
srcu_read_unlock(&kvm->srcu, idx);
return 0;
srcu_read_unlock(&kvm->srcu, idx);
return 0;
@@
-334,7
+345,11
@@
int kvm_iommu_unmap_guest(struct kvm *kvm)
if (!domain)
return 0;
if (!domain)
return 0;
+ mutex_lock(&kvm->slots_lock);
kvm_iommu_unmap_memslots(kvm);
kvm_iommu_unmap_memslots(kvm);
+ kvm->arch.iommu_domain = NULL;
+ mutex_unlock(&kvm->slots_lock);
+
iommu_domain_free(domain);
return 0;
}
iommu_domain_free(domain);
return 0;
}