hulk inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I913T5 CVE: NA
---------------------------------------------------
The commit 8544c8e14fec ("iommu/arm-smmu-v3: Add a SYNC command to avoid broken page table prefetch") use particular cpu cap to identify the problem with smmu, which is not suitable. So, using the smmu registers to identify the problem.
Signed-off-by: Zhang Zekun zhangzekun11@huawei.com --- Documentation/arm64/silicon-errata.rst | 2 ++ arch/arm64/Kconfig | 12 +++++++++ arch/arm64/configs/openeuler_defconfig | 1 + drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 28 +++++++++++++++++++++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 5 ++++ 5 files changed, 48 insertions(+)
diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst index a9441bfebb0d..af12c363a699 100644 --- a/Documentation/arm64/silicon-errata.rst +++ b/Documentation/arm64/silicon-errata.rst @@ -156,6 +156,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Hisilicon | LINXICORE9100 | #162100125 | HISILICON_ERRATUM_162100125 | +----------------+-----------------+-----------------+-----------------------------+ +| Hisilicon | SMMUv3 | #162100602 | HISILICON_ERRATUM_162100602 | ++----------------+-----------------+-----------------+-----------------------------+ | Hisilicon | HIP09 | #162102203 | HISILICON_ERRATUM_162102203 | +----------------+-----------------+-----------------+-----------------------------+ | Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 99fa1b145f32..a1eab2b7d5b3 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -836,6 +836,18 @@ config HISILICON_ERRATUM_162102203
If unsure, say N.
+config HISILICON_ERRATUM_162100602 + bool "Hisilicon erratum 162100602" + depends on ARM_SMMU_V3 && ARCH_HISI + default y + help + SMMU pagetable prefetch features may prefetch and use a invalid PTE even + the PTE is valid at that time. This will cause the device trigger fake + pagefaults. If the SMMU works in terminate mode, transactions which occur + fake pagefaults will be aborted, and could result in unexpected errors. + + If unsure, say Y. + config QCOM_FALKOR_ERRATUM_1003 bool "Falkor E1003: Incorrect translation due to ASID change" default y diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index e53161823f78..e7ecdd8a12eb 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -404,6 +404,7 @@ CONFIG_HISILICON_ERRATUM_1980005=y CONFIG_HISILICON_ERRATUM_162100801=y CONFIG_HISILICON_ERRATUM_162100125=y CONFIG_HISILICON_ERRATUM_162102203=y +CONFIG_HISILICON_ERRATUM_162100602=y CONFIG_QCOM_FALKOR_ERRATUM_1003=y CONFIG_QCOM_FALKOR_ERRATUM_1009=y CONFIG_QCOM_QDF2400_ERRATUM_0065=y diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index a55c2dab72f8..dd099725c72c 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2941,6 +2941,23 @@ static void arm_smmu_iotlb_sync(struct iommu_domain *domain, gather->pgsize, true, smmu_domain); }
+#ifdef CONFIG_HISILICON_ERRATUM_162100602 +static void arm_smmu_iotlb_sync_map(struct iommu_domain *domain, + unsigned long iova, size_t size) +{ + struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); + size_t granule_size; + + if (!(smmu_domain->smmu->options | ARM_SMMU_OPT_SYNC_MAP)) + return; + + granule_size = 1 << __ffs(smmu_domain->domain.pgsize_bitmap); + + /* Add a SYNC command to sync io-pgtale to avoid errors in pgtable prefetch*/ + arm_smmu_tlb_inv_range_domain(iova, granule_size, granule_size, true, smmu_domain); +} +#endif + static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) { @@ -3970,6 +3987,9 @@ static struct iommu_ops arm_smmu_ops = { .unmap = arm_smmu_unmap, .flush_iotlb_all = arm_smmu_flush_iotlb_all, .iotlb_sync = arm_smmu_iotlb_sync, +#ifdef CONFIG_HISILICON_ERRATUM_162100602 + .iotlb_sync_map = arm_smmu_iotlb_sync_map, +#endif .iova_to_phys = arm_smmu_iova_to_phys, .probe_device = arm_smmu_probe_device, .release_device = arm_smmu_release_device, @@ -5126,6 +5146,14 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu) smmu->oas = 48; }
+#ifdef CONFIG_HISILICON_ERRATUM_162100602 + /* IIDR */ + reg = readl_relaxed(smmu->base + ARM_SMMU_IIDR); + if (FIELD_GET(IIDR_VARIANT, reg) == 0x3 && + FIELD_GET(IIDR_REVISON, reg) == 0x2) + smmu->options |= ARM_SMMU_OPT_SYNC_MAP; +#endif + if (arm_smmu_ops.pgsize_bitmap == -1UL) arm_smmu_ops.pgsize_bitmap = smmu->pgsize_bitmap; else diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h index 919473d2217b..776d326de105 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h @@ -80,6 +80,10 @@ #define IDR5_VAX GENMASK(11, 10) #define IDR5_VAX_52_BIT 1
+#define ARM_SMMU_IIDR 0x18 +#define IIDR_VARIANT GENMASK(19, 16) +#define IIDR_REVISON GENMASK(15, 12) + #define ARM_SMMU_CR0 0x20 #define CR0_ATSCHK (1 << 4) #define CR0_CMDQEN (1 << 3) @@ -712,6 +716,7 @@ struct arm_smmu_device { #define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0) #define ARM_SMMU_OPT_PAGE0_REGS_ONLY (1 << 1) #define ARM_SMMU_OPT_MSIPOLL (1 << 2) +#define ARM_SMMU_OPT_SYNC_MAP (1 << 3) u32 options;
union {