Merge tag 'iommu-updates-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull iommu updates from Joerg Roedel:
- SMMU Updates from Will Deacon:
- SMMUv3:
- Support stalling faults for platform devices
- Decrease defaults sizes for the event and PRI queues
- SMMUv2:
- Support for a new '->probe_finalize' hook, needed by Nvidia
- Even more Qualcomm compatible strings
- Avoid Adreno TTBR1 quirk for DB820C platform
- Intel VT-d updates from Lu Baolu:
- Convert Intel IOMMU to use sva_lib helpers in iommu core
- ftrace and debugfs supports for page fault handling
- Support asynchronous nested capabilities
- Various misc cleanups
- Support for new VIOT ACPI table to make the VirtIO IOMMU
available on x86
- Add the amd_iommu=force_enable command line option to enable
the IOMMU on platforms where they are known to cause problems
- Support for version 2 of the Rockchip IOMMU
- Various smaller fixes, cleanups and refactorings
* tag 'iommu-updates-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: (66 commits)
iommu/virtio: Enable x86 support
iommu/dma: Pass address limit rather than size to iommu_setup_dma_ops()
ACPI: Add driver for the VIOT table
ACPI: Move IOMMU setup code out of IORT
ACPI: arm64: Move DMA setup operations out of IORT
iommu/vt-d: Fix dereference of pointer info before it is null checked
iommu: Update "iommu.strict" documentation
iommu/arm-smmu: Check smmu->impl pointer before dereferencing
iommu/arm-smmu-v3: Remove unnecessary oom message
iommu/arm-smmu: Fix arm_smmu_device refcount leak in address translation
iommu/arm-smmu: Fix arm_smmu_device refcount leak when arm_smmu_rpm_get fails
iommu/vt-d: Fix linker error on 32-bit
iommu/vt-d: No need to typecast
iommu/vt-d: Define counter explicitly as unsigned int
iommu/vt-d: Remove unnecessary braces
iommu/vt-d: Removed unused iommu_count in dmar domain
iommu/vt-d: Use bitfields for DMAR capabilities
iommu/vt-d: Use DEVICE_ATTR_RO macro
iommu/vt-d: Fix out-bounds-warning in intel/svm.c
iommu/vt-d: Add PRQ handling latency sampling
...
This commit is contained in:
@@ -31,7 +31,6 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_iommu.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
@@ -74,7 +73,7 @@ static bool using_legacy_binding, using_generic_binding;
|
||||
static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu)
|
||||
{
|
||||
if (pm_runtime_enabled(smmu->dev))
|
||||
return pm_runtime_get_sync(smmu->dev);
|
||||
return pm_runtime_resume_and_get(smmu->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1276,6 +1275,7 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain,
|
||||
u64 phys;
|
||||
unsigned long va, flags;
|
||||
int ret, idx = cfg->cbndx;
|
||||
phys_addr_t addr = 0;
|
||||
|
||||
ret = arm_smmu_rpm_get(smmu);
|
||||
if (ret < 0)
|
||||
@@ -1295,6 +1295,7 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain,
|
||||
dev_err(dev,
|
||||
"iova to phys timed out on %pad. Falling back to software table walk.\n",
|
||||
&iova);
|
||||
arm_smmu_rpm_put(smmu);
|
||||
return ops->iova_to_phys(ops, iova);
|
||||
}
|
||||
|
||||
@@ -1303,12 +1304,14 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain,
|
||||
if (phys & ARM_SMMU_CB_PAR_F) {
|
||||
dev_err(dev, "translation fault!\n");
|
||||
dev_err(dev, "PAR = 0x%llx\n", phys);
|
||||
return 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
addr = (phys & GENMASK_ULL(39, 12)) | (iova & 0xfff);
|
||||
out:
|
||||
arm_smmu_rpm_put(smmu);
|
||||
|
||||
return (phys & GENMASK_ULL(39, 12)) | (iova & 0xfff);
|
||||
return addr;
|
||||
}
|
||||
|
||||
static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
|
||||
@@ -1455,6 +1458,18 @@ static void arm_smmu_release_device(struct device *dev)
|
||||
iommu_fwspec_free(dev);
|
||||
}
|
||||
|
||||
static void arm_smmu_probe_finalize(struct device *dev)
|
||||
{
|
||||
struct arm_smmu_master_cfg *cfg;
|
||||
struct arm_smmu_device *smmu;
|
||||
|
||||
cfg = dev_iommu_priv_get(dev);
|
||||
smmu = cfg->smmu;
|
||||
|
||||
if (smmu->impl && smmu->impl->probe_finalize)
|
||||
smmu->impl->probe_finalize(smmu, dev);
|
||||
}
|
||||
|
||||
static struct iommu_group *arm_smmu_device_group(struct device *dev)
|
||||
{
|
||||
struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
|
||||
@@ -1574,6 +1589,7 @@ static struct iommu_ops arm_smmu_ops = {
|
||||
.iova_to_phys = arm_smmu_iova_to_phys,
|
||||
.probe_device = arm_smmu_probe_device,
|
||||
.release_device = arm_smmu_release_device,
|
||||
.probe_finalize = arm_smmu_probe_finalize,
|
||||
.device_group = arm_smmu_device_group,
|
||||
.enable_nesting = arm_smmu_enable_nesting,
|
||||
.set_pgtable_quirks = arm_smmu_set_pgtable_quirks,
|
||||
@@ -2169,7 +2185,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
|
||||
err = iommu_device_register(&smmu->iommu, &arm_smmu_ops, dev);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to register iommu\n");
|
||||
return err;
|
||||
goto err_sysfs_remove;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, smmu);
|
||||
@@ -2192,10 +2208,19 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
|
||||
* any device which might need it, so we want the bus ops in place
|
||||
* ready to handle default domain setup as soon as any SMMU exists.
|
||||
*/
|
||||
if (!using_legacy_binding)
|
||||
return arm_smmu_bus_init(&arm_smmu_ops);
|
||||
if (!using_legacy_binding) {
|
||||
err = arm_smmu_bus_init(&arm_smmu_ops);
|
||||
if (err)
|
||||
goto err_unregister_device;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister_device:
|
||||
iommu_device_unregister(&smmu->iommu);
|
||||
err_sysfs_remove:
|
||||
iommu_device_sysfs_remove(&smmu->iommu);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int arm_smmu_device_remove(struct platform_device *pdev)
|
||||
|
||||
Reference in New Issue
Block a user