History

iommu/vt-d: Fix general protection fault in aux_detach_device()

The aux-domain attach/detach are not tracked, some data structures might be used after free. This causes general protection faults when multiple subdevices are created and assigned to a same guest machine: | general protection fault, probably for non-canonical address 0xdead000000000100: 0000 [#1] SMP NOPTI | RIP: 0010:intel_iommu_aux_detach_device+0x12a/0x1f0 | [...] | Call Trace: | iommu_aux_detach_device+0x24/0x70 | vfio_mdev_detach_domain+0x3b/0x60 | ? vfio_mdev_set_domain+0x50/0x50 | iommu_group_for_each_dev+0x4f/0x80 | vfio_iommu_detach_group.isra.0+0x22/0x30 | vfio_iommu_type1_detach_group.cold+0x71/0x211 | ? find_exported_symbol_in_section+0x4a/0xd0 | ? each_symbol_section+0x28/0x50 | __vfio_group_unset_container+0x4d/0x150 | vfio_group_try_dissolve_container+0x25/0x30 | vfio_group_put_external_user+0x13/0x20 | kvm_vfio_group_put_external_user+0x27/0x40 [kvm] | kvm_vfio_destroy+0x45/0xb0 [kvm] | kvm_put_kvm+0x1bb/0x2e0 [kvm] | kvm_vm_release+0x22/0x30 [kvm] | __fput+0xcc/0x260 | ____fput+0xe/0x10 | task_work_run+0x8f/0xb0 | do_exit+0x358/0xaf0 | ? wake_up_state+0x10/0x20 | ? signal_wake_up_state+0x1a/0x30 | do_group_exit+0x47/0xb0 | __x64_sys_exit_group+0x18/0x20 | do_syscall_64+0x57/0x1d0 | entry_SYSCALL_64_after_hwframe+0x44/0xa9 Fix the crash by tracking the subdevices when attaching and detaching aux-domains.

Liu Yi L committed 5 years ago

Commit 18abda71 parent 9ad9f452 files · +82 −29Browse files

Showing the changes to include/linux (1 of 2 files). Show all

Unified · Split

include/linux/intel-iommu.h+11−5
@@ -533,11 +533,10 @@ struct dmar_domain { · 532 unmodified lines
533533 /* Domain ids per IOMMU. Use u16 since
534534 * domain ids are 16 bit wide according
535535 * to VT-d spec, section 9.3 */
536− unsigned int auxd_refcnt; /* Refcount of auxiliary attaching */
537536
538537 bool has_iotlb_device;
539538 struct list_head devices; /* all devices' list */
540− struct list_head auxd; /* link to device's auxiliary list */
539+ struct list_head subdevices; /* all subdevices' list */
541540 struct iova_domain iovad; /* iova's that belong to this domain */
542541
543542 struct dma_pte *pgd; /* virtual address */
@@ -610,14 +609,21 @@ struct intel_iommu { · 66 unmodified lines
610609 struct dmar_drhd_unit *drhd;
611610 };
612611
612+/* Per subdevice private data */
613+struct subdev_domain_info {
614+ struct list_head link_phys; /* link to phys device siblings */
615+ struct list_head link_domain; /* link to domain siblings */
616+ struct device *pdev; /* physical device derived from */
617+ struct dmar_domain *domain; /* aux-domain */
618+ int users; /* user count */
619+};
620+
613621 /* PCI domain-device relationship */
614622 struct device_domain_info {
615623 struct list_head link; /* link to domain siblings */
616624 struct list_head global; /* link to global list */
617625 struct list_head table; /* link to pasid table */
618− struct list_head auxiliary_domains; /* auxiliary domains
619− * attached to this device
620− */
626+ struct list_head subdevices; /* subdevices sibling */
621627 u32 segment; /* PCI segment number */
622628 u8 bus; /* PCI bus number */
623629 u8 devfn; /* PCI devfn number */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t