diff options
author | Alex Williamson <alex.williamson@redhat.com> | 2011-07-14 15:27:03 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-07-24 04:50:42 -0400 |
commit | 3f68b0318bbbd61bf08478ab99a149f0d9e5156e (patch) | |
tree | 5caa009c012cee6b61de36f1aa643c9443684423 | |
parent | 4f0226482d20f104e943ee9e6f1218b573953f63 (diff) |
KVM: IOMMU: Disable device assignment without interrupt remapping
IOMMU interrupt remapping support provides a further layer of
isolation for device assignment by preventing arbitrary interrupt
block DMA writes by a malicious guest from reaching the host. By
default, we should require that the platform provides interrupt
remapping support, with an opt-in mechanism for existing behavior.
Both AMD IOMMU and Intel VT-d2 hardware support interrupt
remapping, however we currently only have software support on
the Intel side. Users wishing to re-enable device assignment
when interrupt remapping is not supported on the platform can
use the "allow_unsafe_assigned_interrupts=1" module option.
[avi: break long lines]
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
-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; |