x86/amd-iommu: Align locking between attach_device and detach_device
authorJoerg Roedel <joerg.roedel@amd.com>
Tue, 1 Sep 2009 10:07:08 +0000 (12:07 +0200)
committerJoerg Roedel <joerg.roedel@amd.com>
Thu, 3 Sep 2009 14:15:44 +0000 (16:15 +0200)
This patch makes the locking behavior between the functions
attach_device and __attach_device consistent with the
locking behavior between detach_device and __detach_device.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
arch/x86/kernel/amd_iommu.c

index 2b1e77c..9aa135d 100644 (file)
@@ -1077,29 +1077,38 @@ static void __attach_device(struct amd_iommu *iommu,
                            struct protection_domain *domain,
                            u16 devid)
 {
-       unsigned long flags;
-       u64 pte_root = virt_to_phys(domain->pt_root);
+       u64 pte_root;
 
-       domain->dev_cnt += 1;
+       /* lock domain */
+       spin_lock(&domain->lock);
+
+       pte_root = virt_to_phys(domain->pt_root);
 
        pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK)
                    << DEV_ENTRY_MODE_SHIFT;
        pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV;
 
-       write_lock_irqsave(&amd_iommu_devtable_lock, flags);
        amd_iommu_dev_table[devid].data[2] = domain->id;
        amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root);
        amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root);
 
        amd_iommu_pd_table[devid] = domain;
-       write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
+
+       domain->dev_cnt += 1;
+
+       /* ready */
+       spin_unlock(&domain->lock);
 }
 
 static void attach_device(struct amd_iommu *iommu,
                          struct protection_domain *domain,
                          u16 devid)
 {
+       unsigned long flags;
+
+       write_lock_irqsave(&amd_iommu_devtable_lock, flags);
        __attach_device(iommu, domain, devid);
+       write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
 
        /*
         * We might boot into a crash-kernel here. The crashed kernel