diff options
-rw-r--r-- | virt/kvm/iommu.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c index 62a9caf0563c..78c80f67f535 100644 --- a/virt/kvm/iommu.c +++ b/virt/kvm/iommu.c | |||
@@ -30,6 +30,12 @@ | |||
30 | #include <linux/iommu.h> | 30 | #include <linux/iommu.h> |
31 | #include <linux/intel-iommu.h> | 31 | #include <linux/intel-iommu.h> |
32 | 32 | ||
33 | static int allow_unsafe_assigned_interrupts; | ||
34 | module_param_named(allow_unsafe_assigned_interrupts, | ||
35 | allow_unsafe_assigned_interrupts, bool, S_IRUGO | S_IWUSR); | ||
36 | MODULE_PARM_DESC(allow_unsafe_assigned_interrupts, | ||
37 | "Enable device assignment on platforms without interrupt remapping support."); | ||
38 | |||
33 | static int kvm_iommu_unmap_memslots(struct kvm *kvm); | 39 | static int kvm_iommu_unmap_memslots(struct kvm *kvm); |
34 | static void kvm_iommu_put_pages(struct kvm *kvm, | 40 | static void kvm_iommu_put_pages(struct kvm *kvm, |
35 | gfn_t base_gfn, unsigned long npages); | 41 | gfn_t base_gfn, unsigned long npages); |
@@ -231,6 +237,18 @@ int kvm_iommu_map_guest(struct kvm *kvm) | |||
231 | if (!kvm->arch.iommu_domain) | 237 | if (!kvm->arch.iommu_domain) |
232 | return -ENOMEM; | 238 | return -ENOMEM; |
233 | 239 | ||
240 | if (!allow_unsafe_assigned_interrupts && | ||
241 | !iommu_domain_has_cap(kvm->arch.iommu_domain, | ||
242 | IOMMU_CAP_INTR_REMAP)) { | ||
243 | printk(KERN_WARNING "%s: No interrupt remapping support," | ||
244 | " disallowing device assignment." | ||
245 | " Re-enble with \"allow_unsafe_assigned_interrupts=1\"" | ||
246 | " module option.\n", __func__); | ||
247 | iommu_domain_free(kvm->arch.iommu_domain); | ||
248 | kvm->arch.iommu_domain = NULL; | ||
249 | return -EPERM; | ||
250 | } | ||
251 | |||
234 | r = kvm_iommu_map_memslots(kvm); | 252 | r = kvm_iommu_map_memslots(kvm); |
235 | if (r) | 253 | if (r) |
236 | goto out_unmap; | 254 | goto out_unmap; |