Extended the SMMU_BYPASS_DEV to support SMMU default bypass for some CPU SoCs which the SMMU is not functional well in address translation mode.
This is the version for 4.19 kernel. Guo Hui, if you didn't test patchset based on 1.0 LTS kernel, you can just apply this patch set instead.
Guo Hui (1): arm64: Add MIDR encoding for PHYTIUM CPUs
Hanjun Guo (3): arm64: phytium: using MIDR_PHYTIUM_FT2000PLUS instead of ARM_CPU_IMP_PHYTIUM iommu: dev_bypass: cleanup dev bypass code iommu: smmuv2: Using the SMMU_BYPASS_DEV to bypass SMMU for some SoCs
arch/arm64/include/asm/cputype.h | 5 +++++ arch/arm64/kernel/topology.c | 6 +++--- drivers/iommu/Kconfig | 14 +++++++++++--- drivers/iommu/arm-smmu-v3.c | 2 +- drivers/iommu/arm-smmu.c | 28 ++++++++++++++++++++++++++++ drivers/iommu/iommu.c | 13 ++++--------- drivers/usb/host/xhci-pci.c | 4 +++- 7 files changed, 55 insertions(+), 17 deletions(-)
-- 2.25.1
From: Guo Hui guohui@uniontech.com
uniontech inclusion category: feature bugzilla: NA CVE: NA
-------------------------------------
Adding the MIDR encodings for PHYTIUM 2000+ and 2500 CPUs.
Signed-off-by: Guo Hui guohui@uniontech.com 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 Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Cheng Jian cj.chengjian@huawei.com --- arch/arm64/include/asm/cputype.h | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index f33947af79d9..31ce4213126d 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -102,6 +102,9 @@ #define HISI_CPU_PART_TSV110 0xD01 #define HISI_CPU_PART_TSV200 0xD02
+#define PHYTIUM_CPU_PART_FTC662 0x662 +#define PHYTIUM_CPU_PART_FTC663 0x663 + #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72) @@ -123,6 +126,8 @@ #define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL) #define MIDR_HISI_TSV110 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV110) #define MIDR_HISI_TSV200 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV200) +#define MIDR_PHYTIUM_FT2000PLUS MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_FTC662) +#define MIDR_PHYTIUM_FT2500 MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_FTC663)
#ifndef __ASSEMBLY__
From: Hanjun Guo guohanjun@huawei.com
hulk inclusion category: feature bugzilla: NA CVE: NA
-------------------------------------
Update the code to using MIDR_PHYTIUM_FT2000PLUS, instead of ARM_CPU_IMP_PHYTIUM, which will distinguish FTC662 and FTC663.
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 Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Cheng Jian cj.chengjian@huawei.com --- arch/arm64/kernel/topology.c | 6 +++--- drivers/usb/host/xhci-pci.c | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c index 4c22fe0cd3c6..02d3e688d657 100644 --- a/arch/arm64/kernel/topology.c +++ b/arch/arm64/kernel/topology.c @@ -290,10 +290,10 @@ void store_cpu_topology(unsigned int cpuid) cpuid_topo->core_id = cpuid; cpuid_topo->package_id = cpu_to_node(cpuid);
- if (!(mpidr & MPIDR_MT_BITMASK) && - read_cpuid_implementor() == ARM_CPU_IMP_PHYTIUM) { + /* Some PHYTIUM FT2000PLUS platform firmware has no PPTT table */ + if ((read_cpuid_id() & MIDR_CPU_MODEL_MASK) == MIDR_PHYTIUM_FT2000PLUS + && cpu_to_node(cpuid) == NUMA_NO_NODE) { cpuid_topo->thread_id = 0; - cpuid_topo->core_id = cpuid; cpuid_topo->package_id = 0; }
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index b7b30da1894f..37874d58c805 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -329,8 +329,10 @@ static int xhci_pci_setup(struct usb_hcd *hcd) #include <asm/cputype.h> static void phytium_xhci_pci_workaround(struct pci_dev *dev) { + u32 midr = read_cpuid_id(); + /* Firmware bug, DMA mask is not reported by the firmware */ - if (read_cpuid_implementor() == ARM_CPU_IMP_PHYTIUM) + if ((midr & MIDR_CPU_MODEL_MASK) == MIDR_PHYTIUM_FT2000PLUS) dma_set_mask(&dev->dev, DMA_BIT_MASK(64)); } #else
From: Hanjun Guo guohanjun@huawei.com
hulk inclusion category: feature bugzilla: NA CVE: NA
-------------------------------------
The device bypass code can be cleanuped to be more readable.
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 Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Cheng Jian cj.chengjian@huawei.com --- drivers/iommu/arm-smmu-v3.c | 2 +- drivers/iommu/iommu.c | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 592ccae9771a..cc1db70646ad 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -3092,10 +3092,10 @@ static struct iommu_ops arm_smmu_ops = { .of_xlate = arm_smmu_of_xlate, .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 = arm_smmu_device_domain_type, #endif - .pgsize_bitmap = -1UL, /* Restricted during device attach */ };
/* Probing and initialisation functions */ diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index a5a27ba0048b..73e51b3d4d26 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1291,9 +1291,8 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev) const struct iommu_ops *ops = dev->bus->iommu_ops; struct iommu_group *group; int ret; -#ifdef CONFIG_SMMU_BYPASS_DEV unsigned int type = iommu_def_domain_type; -#endif + group = iommu_group_get(dev); if (group) return group; @@ -1317,17 +1316,13 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)
#ifdef CONFIG_SMMU_BYPASS_DEV /* direct allocate required default domain type for some specific devices. */ - if (ops->device_domain_type != NULL) { + if (ops->device_domain_type) { if (ops->device_domain_type(dev, &type)) type = iommu_def_domain_type; - } - + } +#endif dom = __iommu_domain_alloc(dev->bus, type); if (!dom && type != IOMMU_DOMAIN_DMA) { -#else - dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type); - if (!dom && iommu_def_domain_type != IOMMU_DOMAIN_DMA) { -#endif dev_warn(dev, "failed to allocate default IOMMU domain of type %u; falling back to IOMMU_DOMAIN_DMA", iommu_def_domain_type);
From: Hanjun Guo guohanjun@huawei.com
hulk inclusion category: feature bugzilla: 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 Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Cheng Jian cj.chengjian@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 4f4132d0fca4..a608ac136a97 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 111c2160e82a..f948de8af412 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 struct iommu_ops arm_smmu_ops = { .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)