aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/amd_iommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/amd_iommu.c')
-rw-r--r--arch/x86/kernel/amd_iommu.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 2b1e77c714ff..9aa135d4453f 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -1077,29 +1077,38 @@ static void __attach_device(struct amd_iommu *iommu,
1077 struct protection_domain *domain, 1077 struct protection_domain *domain,
1078 u16 devid) 1078 u16 devid)
1079{ 1079{
1080 unsigned long flags; 1080 u64 pte_root;
1081 u64 pte_root = virt_to_phys(domain->pt_root);
1082 1081
1083 domain->dev_cnt += 1; 1082 /* lock domain */
1083 spin_lock(&domain->lock);
1084
1085 pte_root = virt_to_phys(domain->pt_root);
1084 1086
1085 pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK) 1087 pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK)
1086 << DEV_ENTRY_MODE_SHIFT; 1088 << DEV_ENTRY_MODE_SHIFT;
1087 pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV; 1089 pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV;
1088 1090
1089 write_lock_irqsave(&amd_iommu_devtable_lock, flags);
1090 amd_iommu_dev_table[devid].data[2] = domain->id; 1091 amd_iommu_dev_table[devid].data[2] = domain->id;
1091 amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root); 1092 amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root);
1092 amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root); 1093 amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root);
1093 1094
1094 amd_iommu_pd_table[devid] = domain; 1095 amd_iommu_pd_table[devid] = domain;
1095 write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); 1096
1097 domain->dev_cnt += 1;
1098
1099 /* ready */
1100 spin_unlock(&domain->lock);
1096} 1101}
1097 1102
1098static void attach_device(struct amd_iommu *iommu, 1103static void attach_device(struct amd_iommu *iommu,
1099 struct protection_domain *domain, 1104 struct protection_domain *domain,
1100 u16 devid) 1105 u16 devid)
1101{ 1106{
1107 unsigned long flags;
1108
1109 write_lock_irqsave(&amd_iommu_devtable_lock, flags);
1102 __attach_device(iommu, domain, devid); 1110 __attach_device(iommu, domain, devid);
1111 write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
1103 1112
1104 /* 1113 /*
1105 * We might boot into a crash-kernel here. The crashed kernel 1114 * We might boot into a crash-kernel here. The crashed kernel