Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'iommu-fixes-v5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu

Pull iommu fixes from Joerg Roedel:

- Fix a sleeping-while-atomic issue in the AMD IOMMU code

- Disable lazy IOTLB flush for untrusted devices in the Intel VT-d
driver

- Fix status code definitions for Intel VT-d

- Fix IO Page Fault issue in Tegra IOMMU driver

* tag 'iommu-fixes-v5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
iommu/vt-d: Fix status code for Allocate/Free PASID command
iommu: Don't use lazy flush for untrusted device
iommu/tegra-smmu: Fix mc errors on tegra124-nyan
iommu/amd: Fix sleeping in atomic in increase_address_space()

+87 -14
+6 -4
drivers/iommu/amd/io_pgtable.c
··· 182 182 bool ret = true; 183 183 u64 *pte; 184 184 185 + pte = (void *)get_zeroed_page(gfp); 186 + if (!pte) 187 + return false; 188 + 185 189 spin_lock_irqsave(&domain->lock, flags); 186 190 187 191 if (address <= PM_LEVEL_SIZE(domain->iop.mode)) ··· 193 189 194 190 ret = false; 195 191 if (WARN_ON_ONCE(domain->iop.mode == PAGE_MODE_6_LEVEL)) 196 - goto out; 197 - 198 - pte = (void *)get_zeroed_page(gfp); 199 - if (!pte) 200 192 goto out; 201 193 202 194 *pte = PM_LEVEL_PDE(domain->iop.mode, iommu_virt_to_phys(domain->iop.root)); ··· 208 208 */ 209 209 amd_iommu_domain_set_pgtable(domain, pte, domain->iop.mode); 210 210 211 + pte = NULL; 211 212 ret = true; 212 213 213 214 out: 214 215 spin_unlock_irqrestore(&domain->lock, flags); 216 + free_page((unsigned long)pte); 215 217 216 218 return ret; 217 219 }
+8 -7
drivers/iommu/dma-iommu.c
··· 311 311 domain->ops->flush_iotlb_all(domain); 312 312 } 313 313 314 + static bool dev_is_untrusted(struct device *dev) 315 + { 316 + return dev_is_pci(dev) && to_pci_dev(dev)->untrusted; 317 + } 318 + 314 319 /** 315 320 * iommu_dma_init_domain - Initialise a DMA mapping domain 316 321 * @domain: IOMMU domain previously prepared by iommu_get_dma_cookie() ··· 370 365 371 366 init_iova_domain(iovad, 1UL << order, base_pfn); 372 367 373 - if (!cookie->fq_domain && !iommu_domain_get_attr(domain, 374 - DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE, &attr) && attr) { 368 + if (!cookie->fq_domain && (!dev || !dev_is_untrusted(dev)) && 369 + !iommu_domain_get_attr(domain, DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE, &attr) && 370 + attr) { 375 371 if (init_iova_flush_queue(iovad, iommu_dma_flush_iotlb_all, 376 372 iommu_dma_entry_dtor)) 377 373 pr_warn("iova flush queue initialization failed\n"); ··· 512 506 if (unlikely(is_swiotlb_buffer(phys))) 513 507 swiotlb_tbl_unmap_single(dev, phys, size, 514 508 iova_align(iovad, size), dir, attrs); 515 - } 516 - 517 - static bool dev_is_untrusted(struct device *dev) 518 - { 519 - return dev_is_pci(dev) && to_pci_dev(dev)->untrusted; 520 509 } 521 510 522 511 static dma_addr_t __iommu_dma_map(struct device *dev, phys_addr_t phys,
+2 -2
drivers/iommu/intel/pasid.h
··· 30 30 #define VCMD_VRSP_IP 0x1 31 31 #define VCMD_VRSP_SC(e) (((e) >> 1) & 0x3) 32 32 #define VCMD_VRSP_SC_SUCCESS 0 33 - #define VCMD_VRSP_SC_NO_PASID_AVAIL 1 34 - #define VCMD_VRSP_SC_INVALID_PASID 1 33 + #define VCMD_VRSP_SC_NO_PASID_AVAIL 2 34 + #define VCMD_VRSP_SC_INVALID_PASID 2 35 35 #define VCMD_VRSP_RESULT_PASID(e) (((e) >> 8) & 0xfffff) 36 36 #define VCMD_CMD_OPERAND(e) ((e) << 8) 37 37 /*
+71 -1
drivers/iommu/tegra-smmu.c
··· 798 798 return SMMU_PFN_PHYS(pfn) + SMMU_OFFSET_IN_PAGE(iova); 799 799 } 800 800 801 + static struct tegra_smmu *tegra_smmu_find(struct device_node *np) 802 + { 803 + struct platform_device *pdev; 804 + struct tegra_mc *mc; 805 + 806 + pdev = of_find_device_by_node(np); 807 + if (!pdev) 808 + return NULL; 809 + 810 + mc = platform_get_drvdata(pdev); 811 + if (!mc) 812 + return NULL; 813 + 814 + return mc->smmu; 815 + } 816 + 817 + static int tegra_smmu_configure(struct tegra_smmu *smmu, struct device *dev, 818 + struct of_phandle_args *args) 819 + { 820 + const struct iommu_ops *ops = smmu->iommu.ops; 821 + int err; 822 + 823 + err = iommu_fwspec_init(dev, &dev->of_node->fwnode, ops); 824 + if (err < 0) { 825 + dev_err(dev, "failed to initialize fwspec: %d\n", err); 826 + return err; 827 + } 828 + 829 + err = ops->of_xlate(dev, args); 830 + if (err < 0) { 831 + dev_err(dev, "failed to parse SW group ID: %d\n", err); 832 + iommu_fwspec_free(dev); 833 + return err; 834 + } 835 + 836 + return 0; 837 + } 838 + 801 839 static struct iommu_device *tegra_smmu_probe_device(struct device *dev) 802 840 { 803 - struct tegra_smmu *smmu = dev_iommu_priv_get(dev); 841 + struct device_node *np = dev->of_node; 842 + struct tegra_smmu *smmu = NULL; 843 + struct of_phandle_args args; 844 + unsigned int index = 0; 845 + int err; 804 846 847 + while (of_parse_phandle_with_args(np, "iommus", "#iommu-cells", index, 848 + &args) == 0) { 849 + smmu = tegra_smmu_find(args.np); 850 + if (smmu) { 851 + err = tegra_smmu_configure(smmu, dev, &args); 852 + of_node_put(args.np); 853 + 854 + if (err < 0) 855 + return ERR_PTR(err); 856 + 857 + break; 858 + } 859 + 860 + of_node_put(args.np); 861 + index++; 862 + } 863 + 864 + smmu = dev_iommu_priv_get(dev); 805 865 if (!smmu) 806 866 return ERR_PTR(-ENODEV); 807 867 ··· 1087 1027 smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL); 1088 1028 if (!smmu) 1089 1029 return ERR_PTR(-ENOMEM); 1030 + 1031 + /* 1032 + * This is a bit of a hack. Ideally we'd want to simply return this 1033 + * value. However the IOMMU registration process will attempt to add 1034 + * all devices to the IOMMU when bus_set_iommu() is called. In order 1035 + * not to rely on global variables to track the IOMMU instance, we 1036 + * set it here so that it can be looked up from the .probe_device() 1037 + * callback via the IOMMU device's .drvdata field. 1038 + */ 1039 + mc->smmu = smmu; 1090 1040 1091 1041 size = BITS_TO_LONGS(soc->num_asids) * sizeof(long); 1092 1042