From: Jiri Slaby Date: Mon, 14 Jun 2010 15:17:32 +0000 (+0200) Subject: intel-iommu: Fix double lock in get_domain_for_dev() X-Git-Tag: v2.6.35-rc4~64^2~1 X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=00dfff77e7184140dc45724c7232e99302f6bf97;p=~shefty%2Frdma-dev.git intel-iommu: Fix double lock in get_domain_for_dev() stanse found the following double lock. In get_domain_for_dev: spin_lock_irqsave(&device_domain_lock, flags); domain_exit(domain); domain_remove_dev_info(domain); spin_lock_irqsave(&device_domain_lock, flags); spin_unlock_irqrestore(&device_domain_lock, flags); spin_unlock_irqrestore(&device_domain_lock, flags); This happens when the domain is created by another CPU at the same time as this function is creating one, and the other CPU wins the race to attach it to the device in question, so we have to destroy our own newly-created one. Signed-off-by: David Woodhouse --- diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 3bd30557ce2..bf8fd913d06 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -1874,14 +1874,15 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) } } if (found) { + spin_unlock_irqrestore(&device_domain_lock, flags); free_devinfo_mem(info); domain_exit(domain); domain = found; } else { list_add(&info->link, &domain->devices); list_add(&info->global, &device_domain_list); + spin_unlock_irqrestore(&device_domain_lock, flags); } - spin_unlock_irqrestore(&device_domain_lock, flags); } found_domain: