hulk inclusion category: feature bugzilla: NA DTS: na CVE: NA
-------------------------------------
Extended SMMU_BYPASS_DEV to support SMMU default bypass for some CPU SoCs which the SMMU is not functional well in address translation mode.
The mainline kernel already has the .def_domain_type hook for iommu_ops, so if we update the kernel in the future, we can add the CPU SoC SMMU bypass code in the .def_domain_type hook, for now we just reuse the SMMU_BYPASS_DEV framwork.
After we add the hook, we set all the devices for such SoCs in pass through mode, no matter adding iommu.passthrough=off/on or not in the boot cmdline.
Signed-off-by: Hanjun Guo guohanjun@huawei.com Cc: Guo Hui guohui@uniontech.com Cc: Cheng Jian cj.chengjian@huawei.com Cc: Zhen Lei thunder.leizhen@huawei.com Cc: Xiuqi Xie xiexiuqi@huawei.com --- drivers/iommu/Kconfig | 14 +++++++++++--- drivers/iommu/arm-smmu.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 4f4132d..a608ac1 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -444,9 +444,17 @@ config QCOM_IOMMU Support for IOMMU on certain Qualcomm SoCs.
config SMMU_BYPASS_DEV - bool "SMMU bypass streams for some specific devices" + bool "SMMU bypass streams for some specific devices or CPU SoCs" help - according smmu.bypassdev cmdline, SMMU performs attribute - transformation only,with no address translation. + Using the smmu.bypassdev cmdline, to collect the devices that SMMU + performs attribute transformation only, with no address translation. + This function will be replaced by IORT RMR node, which will be + upstreamed in mainline. + Also extended this function to support SMMU bypass for some CPU SoCs + which the SMMU for some platform is not functional well. Since mainline + kernel already has the .def_domain_type hook for iommu_ops, so if we + update the kernel in the future, we can add the SMMU bypass code for + some CPU SoCs in the .def_domain_type hook, for now we just reuse the + dev bypass.
endif # IOMMU_SUPPORT diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 111c216..f948de8 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1608,6 +1608,31 @@ static void arm_smmu_put_resv_regions(struct device *dev, kfree(entry); }
+#ifdef CONFIG_SMMU_BYPASS_DEV + +#ifdef CONFIG_ARM64 +#include <asm/cputype.h> +static int phytium_smmu_def_domain_type(struct device *dev, unsigned int *type) +{ + u32 midr = read_cpuid_id(); + + if (((midr & MIDR_CPU_MODEL_MASK) == MIDR_PHYTIUM_FT2000PLUS) + || ((midr & MIDR_CPU_MODEL_MASK) == MIDR_PHYTIUM_FT2500)) { + *type = IOMMU_DOMAIN_IDENTITY; + return 0; + } + + return -EINVAL; +} +#else +static inline int phytium_smmu_def_domain_type(struct device *dev, unsigned int *type) +{ + return -EINVAL; +} +#endif + +#endif + static struct iommu_ops arm_smmu_ops = { .capable = arm_smmu_capable, .domain_alloc = arm_smmu_domain_alloc, @@ -1627,6 +1652,9 @@ static void arm_smmu_put_resv_regions(struct device *dev, .get_resv_regions = arm_smmu_get_resv_regions, .put_resv_regions = arm_smmu_put_resv_regions, .pgsize_bitmap = -1UL, /* Restricted during device attach */ +#ifdef CONFIG_SMMU_BYPASS_DEV + .device_domain_type = phytium_smmu_def_domain_type, +#endif };
static void arm_smmu_device_reset(struct arm_smmu_device *smmu)