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
					
				
			
		
					 1 changed files with 12 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue