Skip to content

Commit 7e7dfab

Browse files
Jiang Liujoergroedel
authored andcommitted
iommu/vt-d: Avoid caching stale domain_device_info when hot-removing PCI device
Function device_notifier() in intel-iommu.c only remove domain_device_info data structure associated with a PCI device when handling PCI device driver unbinding events. If a PCI device has never been bound to a PCI device driver, there won't be BUS_NOTIFY_UNBOUND_DRIVER event when hot-removing the PCI device. So associated domain_device_info data structure may get lost. On the other hand, if iommu_pass_through is enabled, function iommu_prepare_static_indentify_mapping() will create domain_device_info data structure for each PCIe to PCIe bridge and PCIe endpoint, no matter whether there are drivers associated with those PCIe devices or not. So those domain_device_info data structures will get lost when hot-removing the assocated PCIe devices if they have never bound to any PCI device driver. To be even worse, it's not only an memory leak issue, but also an caching of stale information bug because the memory are kept in device_domain_list and domain->devices lists. Fix the bug by trying to remove domain_device_info data structure when handling BUS_NOTIFY_DEL_DEVICE event. Signed-off-by: Jiang Liu <[email protected]> Signed-off-by: Joerg Roedel <[email protected]>
1 parent 816997d commit 7e7dfab

File tree

1 file changed

+9
-8
lines changed

1 file changed

+9
-8
lines changed

drivers/iommu/intel-iommu.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3603,18 +3603,19 @@ static int device_notifier(struct notifier_block *nb,
36033603
if (iommu_dummy(pdev))
36043604
return 0;
36053605

3606+
if (action != BUS_NOTIFY_UNBOUND_DRIVER &&
3607+
action != BUS_NOTIFY_DEL_DEVICE)
3608+
return 0;
3609+
36063610
domain = find_domain(pdev);
36073611
if (!domain)
36083612
return 0;
36093613

3610-
if (action == BUS_NOTIFY_UNBOUND_DRIVER) {
3611-
domain_remove_one_dev_info(domain, pdev);
3612-
3613-
if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) &&
3614-
!(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) &&
3615-
list_empty(&domain->devices))
3616-
domain_exit(domain);
3617-
}
3614+
domain_remove_one_dev_info(domain, pdev);
3615+
if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) &&
3616+
!(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) &&
3617+
list_empty(&domain->devices))
3618+
domain_exit(domain);
36183619

36193620
return 0;
36203621
}

0 commit comments

Comments
 (0)