Re: [PATCH v4 13/13] iommu/arm-smmu-v3: Add support for PCI PASID
From: Will Deacon <will@kernel.org>
Date: 2020-01-14 12:45:50
Also in:
linux-acpi, linux-devicetree, linux-iommu, linux-pci
On Thu, Dec 19, 2019 at 05:30:33PM +0100, Jean-Philippe Brucker wrote:
Enable PASID for PCI devices that support it. Since the SSID tables are allocated by arm_smmu_attach_dev(), PASID has to be enabled early enough. arm_smmu_dev_feature_enable() would be too late, since by that time the
What is arm_smmu_dev_feature_enable()?
quoted hunk ↗ jump to hunk
main DMA domain has already been attached. Do it in add_device() instead. Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Jean-Philippe Brucker <redacted> --- drivers/iommu/arm-smmu-v3.c | 55 ++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-)diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index e62ca80f2f76..8e95ecad4c9a 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c@@ -2644,6 +2644,53 @@ static void arm_smmu_disable_ats(struct arm_smmu_master *master) atomic_dec(&smmu_domain->nr_ats_masters); } +static int arm_smmu_enable_pasid(struct arm_smmu_master *master) +{ + int ret; + int features; + int num_pasids; + struct pci_dev *pdev; + + if (!dev_is_pci(master->dev)) + return -ENODEV; + + pdev = to_pci_dev(master->dev); + + features = pci_pasid_features(pdev); + if (features < 0) + return features; + + num_pasids = pci_max_pasids(pdev); + if (num_pasids <= 0) + return num_pasids; + + ret = pci_enable_pasid(pdev, features); + if (ret) { + dev_err(&pdev->dev, "Failed to enable PASID\n"); + return ret; + } + + master->ssid_bits = min_t(u8, ilog2(num_pasids), + master->smmu->ssid_bits); + return 0; +} + +static void arm_smmu_disable_pasid(struct arm_smmu_master *master) +{ + struct pci_dev *pdev; + + if (!dev_is_pci(master->dev)) + return; + + pdev = to_pci_dev(master->dev); + + if (!pdev->pasid_enabled) + return; + + master->ssid_bits = 0; + pci_disable_pasid(pdev); +} + static void arm_smmu_detach_dev(struct arm_smmu_master *master) { unsigned long flags;@@ -2852,13 +2899,16 @@ static int arm_smmu_add_device(struct device *dev) master->ssid_bits = min(smmu->ssid_bits, fwspec->num_pasid_bits); + /* Note that PASID must be enabled before, and disabled after ATS */ + arm_smmu_enable_pasid(master);
Is that part of the PCIe specs? If so, please can you add a citation to the comment? Are there any other ordering requirements, i.e. with respect to enabling substreams at the SMMU? For example, can a speculative ATS request provide a PASID? Will _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel