Skip to content

Commit 309a15c

Browse files
rmurphy-armwilldeacon
authored andcommitted
iommu/arm-smmu-v3: Document MMU-700 erratum 2812531
To work around MMU-700 erratum 2812531 we need to ensure that certain sequences of commands cannot be issued without an intervening sync. In practice this falls out of our current command-batching machinery anyway - each batch only contains a single type of invalidation command, and ends with a sync. The only exception is when a batch is sufficiently large to need issuing across multiple command queue slots, wherein the earlier slots will not contain a sync and thus may in theory interleave with another batch being issued in parallel to create an affected sequence across the slot boundary. Since MMU-700 supports range invalidate commands and thus we will prefer to use them (which also happens to avoid conditions for other errata), I'm not entirely sure it's even possible for a single high-level invalidate call to generate a batch of more than 63 commands, but for the sake of robustness and documentation, wire up an option to enforce that a sync is always inserted for every slot issued. The other aspect is that the relative order of DVM commands cannot be controlled, so DVM cannot be used. Again that is already the status quo, but since we have at least defined ARM_SMMU_FEAT_BTM, we can explicitly disable it for documentation purposes even if it's not wired up anywhere yet. Signed-off-by: Robin Murphy <[email protected]> Reviewed-by: Nicolin Chen <[email protected]> Link: https://lore.kernel.org/r/330221cdfd0003cd51b6c04e7ff3566741ad8374.1683731256.git.robin.murphy@arm.com Signed-off-by: Will Deacon <[email protected]>
1 parent f322e8a commit 309a15c

File tree

3 files changed

+15
-0
lines changed

3 files changed

+15
-0
lines changed

Documentation/arm64/silicon-errata.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ stable kernels.
142142
+----------------+-----------------+-----------------+-----------------------------+
143143
| ARM | MMU-600 | #1076982 | N/A |
144144
+----------------+-----------------+-----------------+-----------------------------+
145+
| ARM | MMU-700 | #2812531 | N/A |
146+
+----------------+-----------------+-----------------+-----------------------------+
145147
+----------------+-----------------+-----------------+-----------------------------+
146148
| Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_845719 |
147149
+----------------+-----------------+-----------------+-----------------------------+

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,12 @@ static void arm_smmu_cmdq_batch_add(struct arm_smmu_device *smmu,
894894
{
895895
int index;
896896

897+
if (cmds->num == CMDQ_BATCH_ENTRIES - 1 &&
898+
(smmu->options & ARM_SMMU_OPT_CMDQ_FORCE_SYNC)) {
899+
arm_smmu_cmdq_issue_cmdlist(smmu, cmds->cmds, cmds->num, true);
900+
cmds->num = 0;
901+
}
902+
897903
if (cmds->num == CMDQ_BATCH_ENTRIES) {
898904
arm_smmu_cmdq_issue_cmdlist(smmu, cmds->cmds, cmds->num, false);
899905
cmds->num = 0;
@@ -3431,6 +3437,7 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
34313437

34323438
#define IIDR_IMPLEMENTER_ARM 0x43b
34333439
#define IIDR_PRODUCTID_ARM_MMU_600 0x483
3440+
#define IIDR_PRODUCTID_ARM_MMU_700 0x487
34343441

34353442
static void arm_smmu_device_iidr_probe(struct arm_smmu_device *smmu)
34363443
{
@@ -3451,6 +3458,11 @@ static void arm_smmu_device_iidr_probe(struct arm_smmu_device *smmu)
34513458
if (variant == 0 && revision <= 2)
34523459
smmu->features &= ~ARM_SMMU_FEAT_SEV;
34533460
break;
3461+
case IIDR_PRODUCTID_ARM_MMU_700:
3462+
/* Arm erratum 2812531 */
3463+
smmu->features &= ~ARM_SMMU_FEAT_BTM;
3464+
smmu->options |= ARM_SMMU_OPT_CMDQ_FORCE_SYNC;
3465+
break;
34543466
}
34553467
break;
34563468
}

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,7 @@ struct arm_smmu_device {
650650
#define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0)
651651
#define ARM_SMMU_OPT_PAGE0_REGS_ONLY (1 << 1)
652652
#define ARM_SMMU_OPT_MSIPOLL (1 << 2)
653+
#define ARM_SMMU_OPT_CMDQ_FORCE_SYNC (1 << 3)
653654
u32 options;
654655

655656
struct arm_smmu_cmdq cmdq;

0 commit comments

Comments
 (0)