]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
iommu/arm-smmu-v3: Work around MMU-600 erratum 1076982
authorRobin Murphy <robin.murphy@arm.com>
Wed, 2 Aug 2023 17:20:57 +0000 (17:20 +0000)
committerStefan Bader <stefan.bader@canonical.com>
Mon, 30 Oct 2023 10:59:51 +0000 (11:59 +0100)
BugLink: https://bugs.launchpad.net/bugs/2038236
commit f322e8af35c7f23a8c08b595c38d6c855b2d836f upstream

MMU-600 versions prior to r1p0 fail to correctly generate a WFE wakeup
event when the command queue transitions fom full to non-full. We can
easily work around this by simply hiding the SEV capability such that we
fall back to polling for space in the queue - since MMU-600 implements
MSIs we wouldn't expect to need SEV for sync completion either, so this
should have little to no impact.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Link: https://lore.kernel.org/r/08adbe3d01024d8382a478325f73b56851f76e49.1683731256.git.robin.murphy@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Easwar Hariharan <eahariha@linux.microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
Documentation/arm64/silicon-errata.rst
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h

index ef138bb82570c640580c626216c8514750ec65d4..6fa41cafdaefdcf74bda5b92fddb2e5ee044a47c 100644 (file)
@@ -143,6 +143,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | MMU-500         | #841119,826419  | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | MMU-600         | #1076982        | N/A                         |
++----------------+-----------------+-----------------+-----------------------------+
 +----------------+-----------------+-----------------+-----------------------------+
 | Broadcom       | Brahma-B53      | N/A             | ARM64_ERRATUM_845719        |
 +----------------+-----------------+-----------------+-----------------------------+
index f2425b0f0cd6252ba284576a5c77d45c05dbe401..829bf305b8f561459962f6d4c2f8af4989181dca 100644 (file)
@@ -3413,6 +3413,33 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
        return 0;
 }
 
+#define IIDR_IMPLEMENTER_ARM           0x43b
+#define IIDR_PRODUCTID_ARM_MMU_600     0x483
+
+static void arm_smmu_device_iidr_probe(struct arm_smmu_device *smmu)
+{
+       u32 reg;
+       unsigned int implementer, productid, variant, revision;
+
+       reg = readl_relaxed(smmu->base + ARM_SMMU_IIDR);
+       implementer = FIELD_GET(IIDR_IMPLEMENTER, reg);
+       productid = FIELD_GET(IIDR_PRODUCTID, reg);
+       variant = FIELD_GET(IIDR_VARIANT, reg);
+       revision = FIELD_GET(IIDR_REVISION, reg);
+
+       switch (implementer) {
+       case IIDR_IMPLEMENTER_ARM:
+               switch (productid) {
+               case IIDR_PRODUCTID_ARM_MMU_600:
+                       /* Arm erratum 1076982 */
+                       if (variant == 0 && revision <= 2)
+                               smmu->features &= ~ARM_SMMU_FEAT_SEV;
+                       break;
+               }
+               break;
+       }
+}
+
 static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
 {
        u32 reg;
@@ -3619,6 +3646,8 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
 
        smmu->ias = max(smmu->ias, smmu->oas);
 
+       arm_smmu_device_iidr_probe(smmu);
+
        if (arm_smmu_sva_supported(smmu))
                smmu->features |= ARM_SMMU_FEAT_SVA;
 
index 8d772ea8a58367b690e91b2a7fbea251b11b93c2..47ca623e2d15ae4221420dfd07b5ad0ec4e0e60f 100644 (file)
 #define IDR5_VAX                       GENMASK(11, 10)
 #define IDR5_VAX_52_BIT                        1
 
+#define ARM_SMMU_IIDR                  0x18
+#define IIDR_PRODUCTID                 GENMASK(31, 20)
+#define IIDR_VARIANT                   GENMASK(19, 16)
+#define IIDR_REVISION                  GENMASK(15, 12)
+#define IIDR_IMPLEMENTER               GENMASK(11, 0)
+
 #define ARM_SMMU_CR0                   0x20
 #define CR0_ATSCHK                     (1 << 4)
 #define CR0_CMDQEN                     (1 << 3)