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