| @@ -163,38 +163,6 @@ static phys_addr_t root_entry_uctp(struct root_entry *re) · 162 unmodified lines |
| 163 | return re->hi & VTD_PAGE_MASK; | 163 | return re->hi & VTD_PAGE_MASK; |
| 164 | } | 164 | } |
| 165 | | 165 | |
| 166 | static inline void context_clear_pasid_enable(struct context_entry *context) | | |
| 167 | { | | |
| 168 | context->lo &= ~(1ULL << 11); | | |
| 169 | } | | |
| 170 | | | |
| 171 | static inline bool context_pasid_enabled(struct context_entry *context) | | |
| 172 | { | | |
| 173 | return !!(context->lo & (1ULL << 11)); | | |
| 174 | } | | |
| 175 | | | |
| 176 | static inline void context_set_copied(struct context_entry *context) | | |
| 177 | { | | |
| 178 | context->hi |= (1ull << 3); | | |
| 179 | } | | |
| 180 | | | |
| 181 | static inline bool context_copied(struct context_entry *context) | | |
| 182 | { | | |
| 183 | return !!(context->hi & (1ULL << 3)); | | |
| 184 | } | | |
| 185 | | | |
| 186 | static inline bool __context_present(struct context_entry *context) | | |
| 187 | { | | |
| 188 | return (context->lo & 1); | | |
| 189 | } | | |
| 190 | | | |
| 191 | bool context_present(struct context_entry *context) | | |
| 192 | { | | |
| 193 | return context_pasid_enabled(context) ? | | |
| 194 | __context_present(context) : | | |
| 195 | __context_present(context) && !context_copied(context); | | |
| 196 | } | | |
| 197 | | | |
| 198 | static inline void context_set_present(struct context_entry *context) | 166 | static inline void context_set_present(struct context_entry *context) |
| 199 | { | 167 | { |
| 200 | context->lo |= 1; | 168 | context->lo |= 1; |
| @@ -242,6 +210,26 @@ static inline void context_clear_entry(struct context_entry *context) · 41 unmodified lines |
| 242 | context->hi = 0; | 210 | context->hi = 0; |
| 243 | } | 211 | } |
| 244 | | 212 | |
| | 213 | static inline bool context_copied(struct intel_iommu *iommu, u8 bus, u8 devfn) |
| | 214 | { |
| | 215 | if (!iommu->copied_tables) |
| | 216 | return false; |
| | 217 | |
| | 218 | return test_bit(((long)bus << 8) | devfn, iommu->copied_tables); |
| | 219 | } |
| | 220 | |
| | 221 | static inline void |
| | 222 | set_context_copied(struct intel_iommu *iommu, u8 bus, u8 devfn) |
| | 223 | { |
| | 224 | set_bit(((long)bus << 8) | devfn, iommu->copied_tables); |
| | 225 | } |
| | 226 | |
| | 227 | static inline void |
| | 228 | clear_context_copied(struct intel_iommu *iommu, u8 bus, u8 devfn) |
| | 229 | { |
| | 230 | clear_bit(((long)bus << 8) | devfn, iommu->copied_tables); |
| | 231 | } |
| | 232 | |
| 245 | /* | 233 | /* |
| 246 | * This domain is a statically identity mapping domain. | 234 | * This domain is a statically identity mapping domain. |
| 247 | * 1. This domain creats a static 1:1 mapping to all usable memory. | 235 | * 1. This domain creats a static 1:1 mapping to all usable memory. |
| @@ -402,14 +390,36 @@ static inline int domain_pfn_supported(struct dmar_domain *domain, · 154 unmodified lines |
| 402 | return !(addr_width < BITS_PER_LONG && pfn >> addr_width); | 390 | return !(addr_width < BITS_PER_LONG && pfn >> addr_width); |
| 403 | } | 391 | } |
| 404 | | 392 | |
| | 393 | /* |
| | 394 | * Calculate the Supported Adjusted Guest Address Widths of an IOMMU. |
| | 395 | * Refer to 11.4.2 of the VT-d spec for the encoding of each bit of |
| | 396 | * the returned SAGAW. |
| | 397 | */ |
| | 398 | static unsigned long __iommu_calculate_sagaw(struct intel_iommu *iommu) |
| | 399 | { |
| | 400 | unsigned long fl_sagaw, sl_sagaw; |
| | 401 | |
| | 402 | fl_sagaw = BIT(2) | (cap_fl1gp_support(iommu->cap) ? BIT(3) : 0); |
| | 403 | sl_sagaw = cap_sagaw(iommu->cap); |
| | 404 | |
| | 405 | /* Second level only. */ |
| | 406 | if (!sm_supported(iommu) || !ecap_flts(iommu->ecap)) |
| | 407 | return sl_sagaw; |
| | 408 | |
| | 409 | /* First level only. */ |
| | 410 | if (!ecap_slts(iommu->ecap)) |
| | 411 | return fl_sagaw; |
| | 412 | |
| | 413 | return fl_sagaw & sl_sagaw; |
| | 414 | } |
| | 415 | |
| 405 | static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw) | 416 | static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw) |
| 406 | { | 417 | { |
| 407 | unsigned long sagaw; | 418 | unsigned long sagaw; |
| 408 | int agaw; | 419 | int agaw; |
| 409 | | 420 | |
| 410 | sagaw = cap_sagaw(iommu->cap); | 421 | sagaw = __iommu_calculate_sagaw(iommu); |
| 411 | for (agaw = width_to_agaw(max_gaw); | 422 | for (agaw = width_to_agaw(max_gaw); agaw >= 0; agaw--) { |
| 412 | agaw >= 0; agaw--) { | | |
| 413 | if (test_bit(agaw, &sagaw)) | 423 | if (test_bit(agaw, &sagaw)) |
| 414 | break; | 424 | break; |
| 415 | } | 425 | } |
| @@ -505,8 +515,9 @@ static int domain_update_device_node(struct dmar_domain *domain) · 89 unmodified lines |
| 505 | { | 515 | { |
| 506 | struct device_domain_info *info; | 516 | struct device_domain_info *info; |
| 507 | int nid = NUMA_NO_NODE; | 517 | int nid = NUMA_NO_NODE; |
| | 518 | unsigned long flags; |
| 508 | | 519 | |
| 509 | spin_lock(&domain->lock); | 520 | spin_lock_irqsave(&domain->lock, flags); |
| 510 | list_for_each_entry(info, &domain->devices, link) { | 521 | list_for_each_entry(info, &domain->devices, link) { |
| 511 | /* | 522 | /* |
| 512 | * There could possibly be multiple device numa nodes as devices | 523 | * There could possibly be multiple device numa nodes as devices |
| @@ -518,7 +529,7 @@ static int domain_update_device_node(struct dmar_domain *domain) · 5 unmodified lines |
| 518 | if (nid != NUMA_NO_NODE) | 529 | if (nid != NUMA_NO_NODE) |
| 519 | break; | 530 | break; |
| 520 | } | 531 | } |
| 521 | spin_unlock(&domain->lock); | 532 | spin_unlock_irqrestore(&domain->lock, flags); |
| 522 | | 533 | |
| 523 | return nid; | 534 | return nid; |
| 524 | } | 535 | } |
| @@ -578,6 +589,13 @@ struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus, · 53 unmodified lines |
| 578 | struct context_entry *context; | 589 | struct context_entry *context; |
| 579 | u64 *entry; | 590 | u64 *entry; |
| 580 | | 591 | |
| | 592 | /* |
| | 593 | * Except that the caller requested to allocate a new entry, |
| | 594 | * returning a copied context entry makes no sense. |
| | 595 | */ |
| | 596 | if (!alloc && context_copied(iommu, bus, devfn)) |
| | 597 | return NULL; |
| | 598 | |
| 581 | entry = &root->lo; | 599 | entry = &root->lo; |
| 582 | if (sm_supported(iommu)) { | 600 | if (sm_supported(iommu)) { |
| 583 | if (devfn >= 0x80) { | 601 | if (devfn >= 0x80) { |
| @@ -795,32 +813,11 @@ static void free_context_table(struct intel_iommu *iommu) · 211 unmodified lines |
| 795 | } | 813 | } |
| 796 | | 814 | |
| 797 | #ifdef CONFIG_DMAR_DEBUG | 815 | #ifdef CONFIG_DMAR_DEBUG |
| 798 | static void pgtable_walk(struct intel_iommu *iommu, unsigned long pfn, u8 bus, u8 devfn) | 816 | static void pgtable_walk(struct intel_iommu *iommu, unsigned long pfn, |
| | 817 | u8 bus, u8 devfn, struct dma_pte *parent, int level) |
| 799 | { | 818 | { |
| 800 | struct device_domain_info *info; | 819 | struct dma_pte *pte; |
| 801 | struct dma_pte *parent, *pte; | 820 | int offset; |
| 802 | struct dmar_domain *domain; | | |
| 803 | struct pci_dev *pdev; | | |
| 804 | int offset, level; | | |
| 805 | | | |
| 806 | pdev = pci_get_domain_bus_and_slot(iommu->segment, bus, devfn); | | |
| 807 | if (!pdev) | | |
| 808 | return; | | |
| 809 | | | |
| 810 | info = dev_iommu_priv_get(&pdev->dev); | | |
| 811 | if (!info || !info->domain) { | | |
| 812 | pr_info("device [%02x:%02x.%d] not probed\n", | | |
| 813 | bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); | | |
| 814 | return; | | |
| 815 | } | | |
| 816 | | | |
| 817 | domain = info->domain; | | |
| 818 | level = agaw_to_level(domain->agaw); | | |
| 819 | parent = domain->pgd; | | |
| 820 | if (!parent) { | | |
| 821 | pr_info("no page table setup\n"); | | |
| 822 | return; | | |
| 823 | } | | |
| 824 | | 821 | |
| 825 | while (1) { | 822 | while (1) { |
| 826 | offset = pfn_level_offset(pfn, level); | 823 | offset = pfn_level_offset(pfn, level); |
| @@ -847,9 +844,10 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id, · 20 unmodified lines |
| 847 | struct pasid_entry *entries, *pte; | 844 | struct pasid_entry *entries, *pte; |
| 848 | struct context_entry *ctx_entry; | 845 | struct context_entry *ctx_entry; |
| 849 | struct root_entry *rt_entry; | 846 | struct root_entry *rt_entry; |
| | 847 | int i, dir_index, index, level; |
| 850 | u8 devfn = source_id & 0xff; | 848 | u8 devfn = source_id & 0xff; |
| 851 | u8 bus = source_id >> 8; | 849 | u8 bus = source_id >> 8; |
| 852 | int i, dir_index, index; | 850 | struct dma_pte *pgtable; |
| 853 | | 851 | |
| 854 | pr_info("Dump %s table entries for IOVA 0x%llx\n", iommu->name, addr); | 852 | pr_info("Dump %s table entries for IOVA 0x%llx\n", iommu->name, addr); |
| 855 | | 853 | |
| @@ -877,8 +875,11 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id, · 21 unmodified lines |
| 877 | ctx_entry->hi, ctx_entry->lo); | 875 | ctx_entry->hi, ctx_entry->lo); |
| 878 | | 876 | |
| 879 | /* legacy mode does not require PASID entries */ | 877 | /* legacy mode does not require PASID entries */ |
| 880 | if (!sm_supported(iommu)) | 878 | if (!sm_supported(iommu)) { |
| | 879 | level = agaw_to_level(ctx_entry->hi & 7); |
| | 880 | pgtable = phys_to_virt(ctx_entry->lo & VTD_PAGE_MASK); |
| 881 | goto pgtable_walk; | 881 | goto pgtable_walk; |
| | 882 | } |
| 882 | | 883 | |
| 883 | /* get the pointer to pasid directory entry */ | 884 | /* get the pointer to pasid directory entry */ |
| 884 | dir = phys_to_virt(ctx_entry->lo & VTD_PAGE_MASK); | 885 | dir = phys_to_virt(ctx_entry->lo & VTD_PAGE_MASK); |
| @@ -905,8 +906,16 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id, · 20 unmodified lines |
| 905 | for (i = 0; i < ARRAY_SIZE(pte->val); i++) | 906 | for (i = 0; i < ARRAY_SIZE(pte->val); i++) |
| 906 | pr_info("pasid table entry[%d]: 0x%016llx\n", i, pte->val[i]); | 907 | pr_info("pasid table entry[%d]: 0x%016llx\n", i, pte->val[i]); |
| 907 | | 908 | |
| | 909 | if (pasid_pte_get_pgtt(pte) == PASID_ENTRY_PGTT_FL_ONLY) { |
| | 910 | level = pte->val[2] & BIT_ULL(2) ? 5 : 4; |
| | 911 | pgtable = phys_to_virt(pte->val[2] & VTD_PAGE_MASK); |
| | 912 | } else { |
| | 913 | level = agaw_to_level((pte->val[0] >> 2) & 0x7); |
| | 914 | pgtable = phys_to_virt(pte->val[0] & VTD_PAGE_MASK); |
| | 915 | } |
| | 916 | |
| 908 | pgtable_walk: | 917 | pgtable_walk: |
| 909 | pgtable_walk(iommu, addr >> VTD_PAGE_SHIFT, bus, devfn); | 918 | pgtable_walk(iommu, addr >> VTD_PAGE_SHIFT, bus, devfn, pgtable, level); |
| 910 | } | 919 | } |
| 911 | #endif | 920 | #endif |
| 912 | | 921 | |
| @@ -1345,19 +1354,20 @@ iommu_support_dev_iotlb(struct dmar_domain *domain, struct intel_iommu *iommu, · 432 unmodified lines |
| 1345 | u8 bus, u8 devfn) | 1354 | u8 bus, u8 devfn) |
| 1346 | { | 1355 | { |
| 1347 | struct device_domain_info *info; | 1356 | struct device_domain_info *info; |
| | 1357 | unsigned long flags; |
| 1348 | | 1358 | |
| 1349 | if (!iommu->qi) | 1359 | if (!iommu->qi) |
| 1350 | return NULL; | 1360 | return NULL; |
| 1351 | | 1361 | |
| 1352 | spin_lock(&domain->lock); | 1362 | spin_lock_irqsave(&domain->lock, flags); |
| 1353 | list_for_each_entry(info, &domain->devices, link) { | 1363 | list_for_each_entry(info, &domain->devices, link) { |
| 1354 | if (info->iommu == iommu && info->bus == bus && | 1364 | if (info->iommu == iommu && info->bus == bus && |
| 1355 | info->devfn == devfn) { | 1365 | info->devfn == devfn) { |
| 1356 | spin_unlock(&domain->lock); | 1366 | spin_unlock_irqrestore(&domain->lock, flags); |
| 1357 | return info->ats_supported ? info : NULL; | 1367 | return info->ats_supported ? info : NULL; |
| 1358 | } | 1368 | } |
| 1359 | } | 1369 | } |
| 1360 | spin_unlock(&domain->lock); | 1370 | spin_unlock_irqrestore(&domain->lock, flags); |
| 1361 | | 1371 | |
| 1362 | return NULL; | 1372 | return NULL; |
| 1363 | } | 1373 | } |
| @@ -1366,8 +1376,9 @@ static void domain_update_iotlb(struct dmar_domain *domain) · 2 unmodified lines |
| 1366 | { | 1376 | { |
| 1367 | struct device_domain_info *info; | 1377 | struct device_domain_info *info; |
| 1368 | bool has_iotlb_device = false; | 1378 | bool has_iotlb_device = false; |
| | 1379 | unsigned long flags; |
| 1369 | | 1380 | |
| 1370 | spin_lock(&domain->lock); | 1381 | spin_lock_irqsave(&domain->lock, flags); |
| 1371 | list_for_each_entry(info, &domain->devices, link) { | 1382 | list_for_each_entry(info, &domain->devices, link) { |
| 1372 | if (info->ats_enabled) { | 1383 | if (info->ats_enabled) { |
| 1373 | has_iotlb_device = true; | 1384 | has_iotlb_device = true; |
| @@ -1375,7 +1386,7 @@ static void domain_update_iotlb(struct dmar_domain *domain) · 1 unmodified line |
| 1375 | } | 1386 | } |
| 1376 | } | 1387 | } |
| 1377 | domain->has_iotlb_device = has_iotlb_device; | 1388 | domain->has_iotlb_device = has_iotlb_device; |
| 1378 | spin_unlock(&domain->lock); | 1389 | spin_unlock_irqrestore(&domain->lock, flags); |
| 1379 | } | 1390 | } |
| 1380 | | 1391 | |
| 1381 | static void iommu_enable_dev_iotlb(struct device_domain_info *info) | 1392 | static void iommu_enable_dev_iotlb(struct device_domain_info *info) |
| @@ -1467,14 +1478,15 @@ static void iommu_flush_dev_iotlb(struct dmar_domain *domain, · 85 unmodified lines |
| 1467 | u64 addr, unsigned mask) | 1478 | u64 addr, unsigned mask) |
| 1468 | { | 1479 | { |
| 1469 | struct device_domain_info *info; | 1480 | struct device_domain_info *info; |
| | 1481 | unsigned long flags; |
| 1470 | | 1482 | |
| 1471 | if (!domain->has_iotlb_device) | 1483 | if (!domain->has_iotlb_device) |
| 1472 | return; | 1484 | return; |
| 1473 | | 1485 | |
| 1474 | spin_lock(&domain->lock); | 1486 | spin_lock_irqsave(&domain->lock, flags); |
| 1475 | list_for_each_entry(info, &domain->devices, link) | 1487 | list_for_each_entry(info, &domain->devices, link) |
| 1476 | __iommu_flush_dev_iotlb(info, addr, mask); | 1488 | __iommu_flush_dev_iotlb(info, addr, mask); |
| 1477 | spin_unlock(&domain->lock); | 1489 | spin_unlock_irqrestore(&domain->lock, flags); |
| 1478 | } | 1490 | } |
| 1479 | | 1491 | |
| 1480 | static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, | 1492 | static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, |
| @@ -1688,6 +1700,11 @@ static void free_dmar_iommu(struct intel_iommu *iommu) · 207 unmodified lines |
| 1688 | iommu->domain_ids = NULL; | 1700 | iommu->domain_ids = NULL; |
| 1689 | } | 1701 | } |
| 1690 | | 1702 | |
| | 1703 | if (iommu->copied_tables) { |
| | 1704 | bitmap_free(iommu->copied_tables); |
| | 1705 | iommu->copied_tables = NULL; |
| | 1706 | } |
| | 1707 | |
| 1691 | /* free context mapping */ | 1708 | /* free context mapping */ |
| 1692 | free_context_table(iommu); | 1709 | free_context_table(iommu); |
| 1693 | | 1710 | |
| @@ -1913,7 +1930,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain, · 219 unmodified lines |
| 1913 | goto out_unlock; | 1930 | goto out_unlock; |
| 1914 | | 1931 | |
| 1915 | ret = 0; | 1932 | ret = 0; |
| 1916 | if (context_present(context)) | 1933 | if (context_present(context) && !context_copied(iommu, bus, devfn)) |
| 1917 | goto out_unlock; | 1934 | goto out_unlock; |
| 1918 | | 1935 | |
| 1919 | /* | 1936 | /* |
| @@ -1925,7 +1942,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain, · 5 unmodified lines |
| 1925 | * in-flight DMA will exist, and we don't need to worry anymore | 1942 | * in-flight DMA will exist, and we don't need to worry anymore |
| 1926 | * hereafter. | 1943 | * hereafter. |
| 1927 | */ | 1944 | */ |
| 1928 | if (context_copied(context)) { | 1945 | if (context_copied(iommu, bus, devfn)) { |
| 1929 | u16 did_old = context_domain_id(context); | 1946 | u16 did_old = context_domain_id(context); |
| 1930 | | 1947 | |
| 1931 | if (did_old < cap_ndoms(iommu->cap)) { | 1948 | if (did_old < cap_ndoms(iommu->cap)) { |
| @@ -1936,6 +1953,8 @@ static int domain_context_mapping_one(struct dmar_domain *domain, · 4 unmodified lines |
| 1936 | iommu->flush.flush_iotlb(iommu, did_old, 0, 0, | 1953 | iommu->flush.flush_iotlb(iommu, did_old, 0, 0, |
| 1937 | DMA_TLB_DSI_FLUSH); | 1954 | DMA_TLB_DSI_FLUSH); |
| 1938 | } | 1955 | } |
| | 1956 | |
| | 1957 | clear_context_copied(iommu, bus, devfn); |
| 1939 | } | 1958 | } |
| 1940 | | 1959 | |
| 1941 | context_clear_entry(context); | 1960 | context_clear_entry(context); |
| @@ -2429,6 +2448,7 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev) · 487 unmodified lines |
| 2429 | { | 2448 | { |
| 2430 | struct device_domain_info *info = dev_iommu_priv_get(dev); | 2449 | struct device_domain_info *info = dev_iommu_priv_get(dev); |
| 2431 | struct intel_iommu *iommu; | 2450 | struct intel_iommu *iommu; |
| | 2451 | unsigned long flags; |
| 2432 | u8 bus, devfn; | 2452 | u8 bus, devfn; |
| 2433 | int ret; | 2453 | int ret; |
| 2434 | | 2454 | |
| @@ -2440,9 +2460,9 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev) · 5 unmodified lines |
| 2440 | if (ret) | 2460 | if (ret) |
| 2441 | return ret; | 2461 | return ret; |
| 2442 | info->domain = domain; | 2462 | info->domain = domain; |
| 2443 | spin_lock(&domain->lock); | 2463 | spin_lock_irqsave(&domain->lock, flags); |
| 2444 | list_add(&info->link, &domain->devices); | 2464 | list_add(&info->link, &domain->devices); |
| 2445 | spin_unlock(&domain->lock); | 2465 | spin_unlock_irqrestore(&domain->lock, flags); |
| 2446 | | 2466 | |
| 2447 | /* PASID table is mandatory for a PCI device in scalable mode. */ | 2467 | /* PASID table is mandatory for a PCI device in scalable mode. */ |
| 2448 | if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) { | 2468 | if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) { |
| @@ -2684,32 +2704,14 @@ static int copy_context_table(struct intel_iommu *iommu, · 235 unmodified lines |
| 2684 | /* Now copy the context entry */ | 2704 | /* Now copy the context entry */ |
| 2685 | memcpy(&ce, old_ce + idx, sizeof(ce)); | 2705 | memcpy(&ce, old_ce + idx, sizeof(ce)); |
| 2686 | | 2706 | |
| 2687 | if (!__context_present(&ce)) | 2707 | if (!context_present(&ce)) |
| 2688 | continue; | 2708 | continue; |
| 2689 | | 2709 | |
| 2690 | did = context_domain_id(&ce); | 2710 | did = context_domain_id(&ce); |
| 2691 | if (did >= 0 && did < cap_ndoms(iommu->cap)) | 2711 | if (did >= 0 && did < cap_ndoms(iommu->cap)) |
| 2692 | set_bit(did, iommu->domain_ids); | 2712 | set_bit(did, iommu->domain_ids); |
| 2693 | | 2713 | |
| 2694 | /* | 2714 | set_context_copied(iommu, bus, devfn); |
| 2695 | * We need a marker for copied context entries. This | | |
| 2696 | * marker needs to work for the old format as well as | | |
| 2697 | * for extended context entries. | | |
| 2698 | * | | |
| 2699 | * Bit 67 of the context entry is used. In the old | | |
| 2700 | * format this bit is available to software, in the | | |
| 2701 | * extended format it is the PGE bit, but PGE is ignored | | |
| 2702 | * by HW if PASIDs are disabled (and thus still | | |
| 2703 | * available). | | |
| 2704 | * | | |
| 2705 | * So disable PASIDs first and then mark the entry | | |
| 2706 | * copied. This means that we don't copy PASID | | |
| 2707 | * translations from the old kernel, but this is fine as | | |
| 2708 | * faults there are not fatal. | | |
| 2709 | */ | | |
| 2710 | context_clear_pasid_enable(&ce); | | |
| 2711 | context_set_copied(&ce); | | |
| 2712 | | | |
| 2713 | new_ce[idx] = ce; | 2715 | new_ce[idx] = ce; |
| 2714 | } | 2716 | } |
| 2715 | | 2717 | |
| @@ -2735,8 +2737,8 @@ static int copy_translation_tables(struct intel_iommu *iommu) · 19 unmodified lines |
| 2735 | bool new_ext, ext; | 2737 | bool new_ext, ext; |
| 2736 | | 2738 | |
| 2737 | rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG); | 2739 | rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG); |
| 2738 | ext = !!(rtaddr_reg & DMA_RTADDR_RTT); | 2740 | ext = !!(rtaddr_reg & DMA_RTADDR_SMT); |
| 2739 | new_ext = !!ecap_ecs(iommu->ecap); | 2741 | new_ext = !!sm_supported(iommu); |
| 2740 | | 2742 | |
| 2741 | /* | 2743 | /* |
| 2742 | * The RTT bit can only be changed when translation is disabled, | 2744 | * The RTT bit can only be changed when translation is disabled, |
| @@ -2747,6 +2749,10 @@ static int copy_translation_tables(struct intel_iommu *iommu) · 4 unmodified lines |
| 2747 | if (new_ext != ext) | 2749 | if (new_ext != ext) |
| 2748 | return -EINVAL; | 2750 | return -EINVAL; |
| 2749 | | 2751 | |
| | 2752 | iommu->copied_tables = bitmap_zalloc(BIT_ULL(16), GFP_KERNEL); |
| | 2753 | if (!iommu->copied_tables) |
| | 2754 | return -ENOMEM; |
| | 2755 | |
| 2750 | old_rt_phys = rtaddr_reg & VTD_PAGE_MASK; | 2756 | old_rt_phys = rtaddr_reg & VTD_PAGE_MASK; |
| 2751 | if (!old_rt_phys) | 2757 | if (!old_rt_phys) |
| 2752 | return -EINVAL; | 2758 | return -EINVAL; |
| @@ -3013,13 +3019,7 @@ static int __init init_dmars(void) · 260 unmodified lines |
| 3013 | | 3019 | |
| 3014 | #ifdef CONFIG_INTEL_IOMMU_SVM | 3020 | #ifdef CONFIG_INTEL_IOMMU_SVM |
| 3015 | if (pasid_supported(iommu) && ecap_prs(iommu->ecap)) { | 3021 | if (pasid_supported(iommu) && ecap_prs(iommu->ecap)) { |
| 3016 | /* | | |
| 3017 | * Call dmar_alloc_hwirq() with dmar_global_lock held, | | |
| 3018 | * could cause possible lock race condition. | | |
| 3019 | */ | | |
| 3020 | up_write(&dmar_global_lock); | | |
| 3021 | ret = intel_svm_enable_prq(iommu); | 3022 | ret = intel_svm_enable_prq(iommu); |
| 3022 | down_write(&dmar_global_lock); | | |
| 3023 | if (ret) | 3023 | if (ret) |
| 3024 | goto free_iommu; | 3024 | goto free_iommu; |
| 3025 | } | 3025 | } |
| @@ -3932,7 +3932,6 @@ int __init intel_iommu_init(void) · 906 unmodified lines |
| 3932 | force_on = (!intel_iommu_tboot_noforce && tboot_force_iommu()) || | 3932 | force_on = (!intel_iommu_tboot_noforce && tboot_force_iommu()) || |
| 3933 | platform_optin_force_iommu(); | 3933 | platform_optin_force_iommu(); |
| 3934 | | 3934 | |
| 3935 | down_write(&dmar_global_lock); | | |
| 3936 | if (dmar_table_init()) { | 3935 | if (dmar_table_init()) { |
| 3937 | if (force_on) | 3936 | if (force_on) |
| 3938 | panic("tboot: Failed to initialize DMAR table\n"); | 3937 | panic("tboot: Failed to initialize DMAR table\n"); |
| @@ -3945,16 +3944,6 @@ int __init intel_iommu_init(void) · 6 unmodified lines |
| 3945 | goto out_free_dmar; | 3944 | goto out_free_dmar; |
| 3946 | } | 3945 | } |
| 3947 | | 3946 | |
| 3948 | up_write(&dmar_global_lock); | | |
| 3949 | | | |
| 3950 | /* | | |
| 3951 | * The bus notifier takes the dmar_global_lock, so lockdep will | | |
| 3952 | * complain later when we register it under the lock. | | |
| 3953 | */ | | |
| 3954 | dmar_register_bus_notifier(); | | |
| 3955 | | | |
| 3956 | down_write(&dmar_global_lock); | | |
| 3957 | | | |
| 3958 | if (!no_iommu) | 3947 | if (!no_iommu) |
| 3959 | intel_iommu_debugfs_init(); | 3948 | intel_iommu_debugfs_init(); |
| 3960 | | 3949 | |
| @@ -3999,11 +3988,9 @@ int __init intel_iommu_init(void) · 38 unmodified lines |
| 3999 | pr_err("Initialization failed\n"); | 3988 | pr_err("Initialization failed\n"); |
| 4000 | goto out_free_dmar; | 3989 | goto out_free_dmar; |
| 4001 | } | 3990 | } |
| 4002 | up_write(&dmar_global_lock); | | |
| 4003 | | 3991 | |
| 4004 | init_iommu_pm_ops(); | 3992 | init_iommu_pm_ops(); |
| 4005 | | 3993 | |
| 4006 | down_read(&dmar_global_lock); | | |
| 4007 | for_each_active_iommu(iommu, drhd) { | 3994 | for_each_active_iommu(iommu, drhd) { |
| 4008 | /* | 3995 | /* |
| 4009 | * The flush queue implementation does not perform | 3996 | * The flush queue implementation does not perform |
| @@ -4021,13 +4008,11 @@ int __init intel_iommu_init(void) · 11 unmodified lines |
| 4021 | "%s", iommu->name); | 4008 | "%s", iommu->name); |
| 4022 | iommu_device_register(&iommu->iommu, &intel_iommu_ops, NULL); | 4009 | iommu_device_register(&iommu->iommu, &intel_iommu_ops, NULL); |
| 4023 | } | 4010 | } |
| 4024 | up_read(&dmar_global_lock); | | |
| 4025 | | 4011 | |
| 4026 | bus_set_iommu(&pci_bus_type, &intel_iommu_ops); | 4012 | bus_set_iommu(&pci_bus_type, &intel_iommu_ops); |
| 4027 | if (si_domain && !hw_pass_through) | 4013 | if (si_domain && !hw_pass_through) |
| 4028 | register_memory_notifier(&intel_iommu_memory_nb); | 4014 | register_memory_notifier(&intel_iommu_memory_nb); |
| 4029 | | 4015 | |
| 4030 | down_read(&dmar_global_lock); | | |
| 4031 | if (probe_acpi_namespace_devices()) | 4016 | if (probe_acpi_namespace_devices()) |
| 4032 | pr_warn("ACPI name space devices didn't probe correctly\n"); | 4017 | pr_warn("ACPI name space devices didn't probe correctly\n"); |
| 4033 | | 4018 | |
| @@ -4038,17 +4023,15 @@ int __init intel_iommu_init(void) · 4 unmodified lines |
| 4038 | | 4023 | |
| 4039 | iommu_disable_protect_mem_regions(iommu); | 4024 | iommu_disable_protect_mem_regions(iommu); |
| 4040 | } | 4025 | } |
| 4041 | up_read(&dmar_global_lock); | | |
| 4042 | | | |
| 4043 | pr_info("Intel(R) Virtualization Technology for Directed I/O\n"); | | |
| 4044 | | 4026 | |
| 4045 | intel_iommu_enabled = 1; | 4027 | intel_iommu_enabled = 1; |
| | 4028 | dmar_register_bus_notifier(); |
| | 4029 | pr_info("Intel(R) Virtualization Technology for Directed I/O\n"); |
| 4046 | | 4030 | |
| 4047 | return 0; | 4031 | return 0; |
| 4048 | | 4032 | |
| 4049 | out_free_dmar: | 4033 | out_free_dmar: |
| 4050 | intel_iommu_free_dmars(); | 4034 | intel_iommu_free_dmars(); |
| 4051 | up_write(&dmar_global_lock); | | |
| 4052 | return ret; | 4035 | return ret; |
| 4053 | } | 4036 | } |
| 4054 | | 4037 | |
| @@ -4080,6 +4063,7 @@ static void dmar_remove_one_dev_info(struct device *dev) · 25 unmodified lines |
| 4080 | struct device_domain_info *info = dev_iommu_priv_get(dev); | 4063 | struct device_domain_info *info = dev_iommu_priv_get(dev); |
| 4081 | struct dmar_domain *domain = info->domain; | 4064 | struct dmar_domain *domain = info->domain; |
| 4082 | struct intel_iommu *iommu = info->iommu; | 4065 | struct intel_iommu *iommu = info->iommu; |
| | 4066 | unsigned long flags; |
| 4083 | | 4067 | |
| 4084 | if (!dev_is_real_dma_subdevice(info->dev)) { | 4068 | if (!dev_is_real_dma_subdevice(info->dev)) { |
| 4085 | if (dev_is_pci(info->dev) && sm_supported(iommu)) | 4069 | if (dev_is_pci(info->dev) && sm_supported(iommu)) |
| @@ -4091,9 +4075,9 @@ static void dmar_remove_one_dev_info(struct device *dev) · 5 unmodified lines |
| 4091 | intel_pasid_free_table(info->dev); | 4075 | intel_pasid_free_table(info->dev); |
| 4092 | } | 4076 | } |
| 4093 | | 4077 | |
| 4094 | spin_lock(&domain->lock); | 4078 | spin_lock_irqsave(&domain->lock, flags); |
| 4095 | list_del(&info->link); | 4079 | list_del(&info->link); |
| 4096 | spin_unlock(&domain->lock); | 4080 | spin_unlock_irqrestore(&domain->lock, flags); |
| 4097 | | 4081 | |
| 4098 | domain_detach_iommu(domain, iommu); | 4082 | domain_detach_iommu(domain, iommu); |
| 4099 | info->domain = NULL; | 4083 | info->domain = NULL; |
| @@ -4412,19 +4396,20 @@ static void domain_set_force_snooping(struct dmar_domain *domain) · 312 unmodified lines |
| 4412 | static bool intel_iommu_enforce_cache_coherency(struct iommu_domain *domain) | 4396 | static bool intel_iommu_enforce_cache_coherency(struct iommu_domain *domain) |
| 4413 | { | 4397 | { |
| 4414 | struct dmar_domain *dmar_domain = to_dmar_domain(domain); | 4398 | struct dmar_domain *dmar_domain = to_dmar_domain(domain); |
| | 4399 | unsigned long flags; |
| 4415 | | 4400 | |
| 4416 | if (dmar_domain->force_snooping) | 4401 | if (dmar_domain->force_snooping) |
| 4417 | return true; | 4402 | return true; |
| 4418 | | 4403 | |
| 4419 | spin_lock(&dmar_domain->lock); | 4404 | spin_lock_irqsave(&dmar_domain->lock, flags); |
| 4420 | if (!domain_support_force_snooping(dmar_domain)) { | 4405 | if (!domain_support_force_snooping(dmar_domain)) { |
| 4421 | spin_unlock(&dmar_domain->lock); | 4406 | spin_unlock_irqrestore(&dmar_domain->lock, flags); |
| 4422 | return false; | 4407 | return false; |
| 4423 | } | 4408 | } |
| 4424 | | 4409 | |
| 4425 | domain_set_force_snooping(dmar_domain); | 4410 | domain_set_force_snooping(dmar_domain); |
| 4426 | dmar_domain->force_snooping = true; | 4411 | dmar_domain->force_snooping = true; |
| 4427 | spin_unlock(&dmar_domain->lock); | 4412 | spin_unlock_irqrestore(&dmar_domain->lock, flags); |
| 4428 | | 4413 | |
| 4429 | return true; | 4414 | return true; |
| 4430 | } | 4415 | } |