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; |
