iommu/arm-smmu-v3: Arm SMMU errata bits
Subsystems (3)
Robin Murphy
reviewercover iommu/arm-smmu-v3: Arm SMMU errata bits
Hi all,
Further to the discussion on the nesting series a while back, here's a mini-series to help us start taking more of an interest in SMMU errata. Patch #1 is more about the infrastucture than that erratum itself, but since I *had* already written it up (5 years ago!) I figured why not just build on it as-is. The rest is effectively just documentation at this point, but getting us ready for all the hitherto unmet conditions that IOMMUFD nesting is going to open up.
Thanks,
Robin.
Robin Murphy (4):
iommu/arm-smmu-v3: Work around MMU-600 erratum 1076982 iommu/arm-smmu-v3: Document MMU-700 erratum 2812531 iommu/arm-smmu-v3: Add explicit feature for nesting iommu/arm-smmu-v3: Document nesting-related errata
Documentation/arm64/silicon-errata.rst | 4 ++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 50 +++++++++++++++++++++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 8 ++++ 3 files changed, 62 insertions(+)
Signature · 1 line
2.39.2.101.g768bb238c484.dirty
Robin Murphy
reviewerPATCH 1/4 iommu/arm-smmu-v3: Work around MMU-600 erratum 1076982
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.
--- Documentation/arm64/silicon-errata.rst | 2 ++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 29 +++++++++++++++++++++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 6 +++++ 3 files changed, 37 insertions(+)
Documentation/arm64/silicon-errata.rst +2 -0
@@ -140,6 +140,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-500 | #841119,826419 | N/A | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | MMU-600 | #1076982 | N/A | ++----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ | Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_845719 | +----------------+-----------------+-----------------+-----------------------------+
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +29 -0
@@ -3432,6 +3432,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;
@@ -3633,6 +3660,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 ;
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +6 -0
@@ -69,6 +69,12 @@#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)
Signature · 1 line
2.39.2.101.g768bb238c484.dirty
Re: [PATCH 1/4] iommu/arm-smmu-v3: Work around MMU-600 erratum 1076982
Quoted 8 lines · Robin Murphy
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 <[email protected]>
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass) · line 3441
Quoted 4 lines
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +4
-0+static void arm_smmu_device_iidr_probe (struct arm_smmu_device *smmu) +{ +u32 reg; +unsigned int implementer, productid, variant, revision;
Just for curiosity -- what's the fashion behind the coding style here? Usually I follow a longer-to-shorter style, yet perhaps I can follow this one for further SMMU patches, if it matters.
Thanks
Nicolin
Robin Murphy
reviewerRe: [PATCH 1/4] iommu/arm-smmu-v3: Work around MMU-600 erratum 1076982
Quoted 9 lines · Nicolin Chen
Quoted 7 lines · Robin Murphy
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.
Quoted 3 lines
Quoted 1 line
Signed-off-by Robin Murphy <[email protected]>Reviewed-by Nicolin Chen <[email protected]>
Thanks!
Quoted 8 lines
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass) · line 3441
Quoted 4 lines
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +4
-0+static void arm_smmu_device_iidr_probe (struct arm_smmu_device *smmu) +{ +u32 reg; +unsigned int implementer, productid, variant, revision;Just for curiosity -- what's the fashion behind the coding style here? Usually I follow a longer-to-shorter style, yet perhaps I can follow this one for further SMMU patches, if it matters.
In the case of my code, it's usually some intuitive contextual order based on a hierarchy of the types and/or importance of variables within the logic of the function and relative to each other. I couldn't really explain it as a set of rules, it's just whatever feels most right :)
Cheers,
Robin.
Nicolin Chen
Tested-byRe: [PATCH 1/4] iommu/arm-smmu-v3: Work around MMU-600 erratum 1076982
In reply to Nicolin ChenQuoted 9 lines · Nicolin Chen
Quoted 7 lines · Robin Murphy
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.
Quoted 3 lines
Quoted 1 line
Signed-off-by Robin Murphy <[email protected]>Reviewed-by Nicolin Chen <[email protected]>
It happens that I have a simulation environment where the IIDR value hits the errata, i.e. the NESTING feature bit gets canceled by this patch. So,
Hopefully we can get this series merged soon.
Thanks!
Nic
Robin Murphy
reviewerPATCH 2/4 iommu/arm-smmu-v3: Document MMU-700 erratum 2812531
In reply to Robin MurphyTo 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.
--- Documentation/arm64/silicon-errata.rst | 2 ++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 12 ++++++++++++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 1 + 3 files changed, 15 insertions(+)
Documentation/arm64/silicon-errata.rst +2 -0
@@ -142,6 +142,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-600 | #1076982 | N/A | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | MMU-700 | #2812531 | N/A | ++----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ | Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_845719 | +----------------+-----------------+-----------------+-----------------------------+
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +12 -0
@@ -894,6 +894,12 @@ static void arm_smmu_cmdq_batch_add(struct arm_smmu_device *smmu, {int index; +if (cmds->num ==CMDQ_BATCH_ENTRIES -1 && + (smmu->options &ARM_SMMU_OPT_CMDQ_FORCE_SYNC )) { +arm_smmu_cmdq_issue_cmdlist (smmu, cmds->cmds, cmds->num, true); + cmds->num =0 ; + } +if (cmds->num ==CMDQ_BATCH_ENTRIES ) {arm_smmu_cmdq_issue_cmdlist (smmu, cmds->cmds, cmds->num, false); cmds->num =0 ;
@@ -3434,6 +3440,7 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)#define IIDR_IMPLEMENTER_ARM 0x43b#define IIDR_PRODUCTID_ARM_MMU_600 0x483 +#define IIDR_PRODUCTID_ARM_MMU_700 0x487static void arm_smmu_device_iidr_probe (struct arm_smmu_device *smmu) {
@@ -3454,6 +3461,11 @@ static void arm_smmu_device_iidr_probe(struct arm_smmu_device *smmu)if (variant ==0 && revision <=2 ) smmu->features &= ~ARM_SMMU_FEAT_SEV ;break ; +case IIDR_PRODUCTID_ARM_MMU_700 : +/* Arm erratum 2812531 */ + smmu->features &= ~ARM_SMMU_FEAT_BTM ; + smmu->options |=ARM_SMMU_OPT_CMDQ_FORCE_SYNC ; +break ; }break ; }
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +1 -0
@@ -650,6 +650,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_CMDQ_FORCE_SYNC (1 << 3)u32 options;struct arm_smmu_cmdq cmdq;
Signature · 1 line
2.39.2.101.g768bb238c484.dirty
Re: [PATCH 2/4] iommu/arm-smmu-v3: Document MMU-700 erratum 2812531
Quoted 4 lines · Robin Murphy
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,
Hmm. This doesn't apply to the user cache invalidation solution in my v2. A user cmdq could possibly mix different commands in a single batch if the driver isn't aware of such an errata. So, I think I'd need some twist when the host has a FORCE_SYNC flag in my v3.
Quoted 6 lines
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.
Quoted 6 lines
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.
Hmm. This can happen to a user space driver that does something insane like that. I'll need, again in the nesting patch, a line of code to limit the number of the commands when it calls the arm_smmu_cmdq_issue_cmdlist() for a user cache invalidation.
Quoted 7 lines
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]>
Thanks!
Re: [PATCH 2/4] iommu/arm-smmu-v3: Document MMU-700 erratum 2812531
Quoted 7 lines · Nicolin Chen
Quoted 4 lines · Robin Murphy
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,
Quoted 5 lines
Hmm. This doesn't apply to the user cache invalidation solution in my v2. A user cmdq could possibly mix different commands in a single batch if the driver isn't aware of such an errata. So, I think I'd need some twist when the host has a
FORCE_SYNCflag in my v3.
Just found that you unset the NESTING feature flag in PATCH-4 for this errata too. So, the solution in my v2 should be safe.
Thanks
Nicolin
Robin Murphy
reviewerRe: [PATCH 2/4] iommu/arm-smmu-v3: Document MMU-700 erratum 2812531
Quoted 8 lines · Nicolin Chen
Quoted 7 lines · Nicolin Chen
Quoted 4 lines · Robin Murphy
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,
Quoted 8 lines
Quoted 5 lines
Hmm. This doesn't apply to the user cache invalidation solution in my v2. A user cmdq could possibly mix different commands in a single batch if the driver isn't aware of such an errata. So, I think I'd need some twist when the host has a
FORCE_SYNCflag in my v3.Just found that you unset the NESTING feature flag in PATCH-4 for this errata too. So, the solution in my v2 should be safe.
For the short term at least - we will still need to come up with a more practical active mitigation sooner rather than later, since I imagine people are likely to be a bit miffed if nesting support lands in distros but still refuses to play at all on the newest shiniest hardware. Unfortunately all current versions of MMU-700 are affected (hence the unconditional nature of this patch), and some of those are going to found in production SoCs.
Thanks,
Robin.
Re: [PATCH 2/4] iommu/arm-smmu-v3: Document MMU-700 erratum 2812531
Quoted 18 lines · Robin Murphy
Quoted 8 lines · Nicolin Chen
Quoted 7 lines · Nicolin Chen
Quoted 4 lines · Robin Murphy
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,
Quoted 8 lines
Quoted 5 lines
Hmm. This doesn't apply to the user cache invalidation solution in my v2. A user cmdq could possibly mix different commands in a single batch if the driver isn't aware of such an errata. So, I think I'd need some twist when the host has a
FORCE_SYNCflag in my v3.Just found that you unset the NESTING feature flag in PATCH-4 for this errata too. So, the solution in my v2 should be safe.
Quoted 7 lines
For the short term at least - we will still need to come up with a more practical active mitigation sooner rather than later, since I imagine people are likely to be a bit miffed if nesting support lands in distros but still refuses to play at all on the newest shiniest hardware. Unfortunately all current versions of MMU-700 are affected (hence the unconditional nature of this patch), and some of those are going to found in production SoCs.
Okay. I will try adding a WAR function following the doc:
1. A Stage 1 Invalidation that is followed by a Stage 2 invalidation
2. A Configuration Invalidation that is followed by any TLB Invalidation
3. A Leaf invalidation that is followed by a Non-leaf invalidation
We don't need anything for (1) as a user CMDQ only has stage-1 invalidations. Adding a SYNC after every CFIG_CD(_ALL) should work for (2). Then for (3), need to check the leaf bit between two adjacent NH_VA/NH_VAA commands.
Thanks
Nic
Robin Murphy
reviewerPATCH 3/4 iommu/arm-smmu-v3: Add explicit feature for nesting
In reply to Robin MurphyIn certain cases we may want to refuse to allow nested translation even when both stages are implemented, so let's add an explicit feature for nesting support which we can control in its own right. For now this merely serves as documentation, but it means a nice convenient check will be ready and waiting for the future nesting code.
--- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 4 ++++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 1 + 2 files changed, 5 insertions(+)
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +4 -0
@@ -3672,6 +3672,10 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu) smmu->ias =max (smmu->ias, smmu->oas); +if ((smmu->features &ARM_SMMU_FEAT_TRANS_S1 ) && + (smmu->features &ARM_SMMU_FEAT_TRANS_S2 )) + smmu->features |=ARM_SMMU_FEAT_NESTING ; +arm_smmu_device_iidr_probe (smmu);if (arm_smmu_sva_supported (smmu))
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +1 -0
@@ -645,6 +645,7 @@ struct arm_smmu_device {#define ARM_SMMU_FEAT_BTM (1 << 16)#define ARM_SMMU_FEAT_SVA (1 << 17)#define ARM_SMMU_FEAT_E2H (1 << 18) +#define ARM_SMMU_FEAT_NESTING (1 << 19)u32 features;#define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0)
Signature · 1 line
2.39.2.101.g768bb238c484.dirty
Re: [PATCH 3/4] iommu/arm-smmu-v3: Add explicit feature for nesting
Quoted 7 lines · Robin Murphy
In certain cases we may want to refuse to allow nested translation even when both stages are implemented, so let's add an explicit feature for nesting support which we can control in its own right. For now this merely serves as documentation, but it means a nice convenient check will be ready and waiting for the future nesting code.
Signed-off-by Robin Murphy <[email protected]>
Robin Murphy
reviewerPATCH 4/4 iommu/arm-smmu-v3: Document nesting-related errata
In reply to Robin MurphyBoth MMU-600 and MMU-700 have similar errata around TLB invalidation while both stages of translation are active, which will need some consideration once nesting support is implemented. For now, though, it's very easy to make our implicit lack of nesting support explicit for those cases, so they're less likely to be missed in future.
--- Documentation/arm64/silicon-errata.rst | 4 ++-- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-)
Documentation/arm64/silicon-errata.rst +2 -2
@@ -140,9 +140,9 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-500 | #841119,826419 | N/A | +----------------+-----------------+-----------------+-----------------------------+ -| ARM | MMU-600 | #1076982 | N/A | +| ARM | MMU-600 | #1076982,1209401| N/A | +----------------+-----------------+-----------------+-----------------------------+ -| ARM | MMU-700 | #2812531 | N/A | +| ARM | MMU-700 | #2268618,2812531| N/A | +----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ | Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_845719 |
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +5 -0
@@ -3460,11 +3460,16 @@ static void arm_smmu_device_iidr_probe(struct arm_smmu_device *smmu)/* Arm erratum 1076982 */ if (variant ==0 && revision <=2 ) smmu->features &= ~ARM_SMMU_FEAT_SEV ; +/* Arm erratum 1209401 */ +if (variant <2 ) + smmu->features &= ~ARM_SMMU_FEAT_NESTING ;break ;case IIDR_PRODUCTID_ARM_MMU_700 :/* Arm erratum 2812531 */ smmu->features &= ~ARM_SMMU_FEAT_BTM ; smmu->options |=ARM_SMMU_OPT_CMDQ_FORCE_SYNC ; +/* Arm errata 2268618, 2812531 */ + smmu->features &= ~ARM_SMMU_FEAT_NESTING ;break ; }break ;
Signature · 1 line
2.39.2.101.g768bb238c484.dirty
Re: [PATCH 4/4] iommu/arm-smmu-v3: Document nesting-related errata
Quoted 8 lines · Robin Murphy
Both MMU-600 and MMU-700 have similar errata around TLB invalidation while both stages of translation are active, which will need some consideration once nesting support is implemented. For now, though, it's very easy to make our implicit lack of nesting support explicit for those cases, so they're less likely to be missed in future.
Signed-off-by Robin Murphy <[email protected]>
Quoted 9 lines · Robin Murphy
Further to the discussion on the nesting series a while back, here's a mini-series to help us start taking more of an interest in SMMU errata. Patch #1 is more about the infrastucture than that erratum itself, but since I *had* already written it up (5 years ago!) I figured why not just build on it as-is. The rest is effectively just documentation at this point, but getting us ready for all the hitherto unmet conditions that IOMMUFD nesting is going to open up.
[...]
Applied to will (for-joerg/arm-smmu/updates), thanks!
[1/4] iommu/arm-smmu-v3: Work around MMU-600 erratum 1076982
https://git.kernel.org/will/c/f322e8af35c7 [2/4] iommu/arm-smmu-v3: Document MMU-700 erratum 2812531 https://git.kernel.org/will/c/309a15cb16bb [3/4] iommu/arm-smmu-v3: Add explicit feature for nesting https://git.kernel.org/will/c/1d9777b9f3d5 [4/4] iommu/arm-smmu-v3: Document nesting-related errata https://git.kernel.org/will/c/0bfbfc526c70
Cheers,
Signature · 5 lines
Will https://fixes.arm64.dev https://next.arm64.dev https://will.arm64.dev