Преглед на файлове

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 <David.Woodhouse@intel.com>
Jiri Slaby преди 15 години
родител
ревизия
00dfff77e7
променени са 1 файла, в които са добавени 2 реда и са изтрити 1 реда
  1. 2 1
      drivers/pci/intel-iommu.c

+ 2 - 1
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) {
 		if (found) {
+			spin_unlock_irqrestore(&device_domain_lock, flags);
 			free_devinfo_mem(info);
 			free_devinfo_mem(info);
 			domain_exit(domain);
 			domain_exit(domain);
 			domain = found;
 			domain = found;
 		} else {
 		} else {
 			list_add(&info->link, &domain->devices);
 			list_add(&info->link, &domain->devices);
 			list_add(&info->global, &device_domain_list);
 			list_add(&info->global, &device_domain_list);
+			spin_unlock_irqrestore(&device_domain_lock, flags);
 		}
 		}
-		spin_unlock_irqrestore(&device_domain_lock, flags);
 	}
 	}
 
 
 found_domain:
 found_domain: