intel-iommu: Unlink domain from iommu
When we remove a device, we unlink the iommu from the domain, but we never do the reverse unlinking of the domain from the iommu. This means that we never clear iommu->domain_ids, eventually leading to resource exhaustion if we repeatedly bind and unbind a device to a driver. Also free empty domains to avoid a resource leak. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Acked-by: Donald Dutile <ddutile@redhat.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> Cc: stable@kernel.org
This commit is contained in:
parent
7a6610139a
commit
a97590e56d
|
@ -3260,9 +3260,15 @@ static int device_notifier(struct notifier_block *nb,
|
|||
if (!domain)
|
||||
return 0;
|
||||
|
||||
if (action == BUS_NOTIFY_UNBOUND_DRIVER && !iommu_pass_through)
|
||||
if (action == BUS_NOTIFY_UNBOUND_DRIVER && !iommu_pass_through) {
|
||||
domain_remove_one_dev_info(domain, pdev);
|
||||
|
||||
if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) &&
|
||||
!(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) &&
|
||||
list_empty(&domain->devices))
|
||||
domain_exit(domain);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3411,6 +3417,11 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain,
|
|||
domain->iommu_count--;
|
||||
domain_update_iommu_cap(domain);
|
||||
spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags);
|
||||
|
||||
spin_lock_irqsave(&iommu->lock, tmp_flags);
|
||||
clear_bit(domain->id, iommu->domain_ids);
|
||||
iommu->domains[domain->id] = NULL;
|
||||
spin_unlock_irqrestore(&iommu->lock, tmp_flags);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&device_domain_lock, flags);
|
||||
|
|
Loading…
Reference in a new issue