Stage 1 input addresses are effectively 64-bit in SMMUv3 anyway, so
really all that's involved is letting io-pgtable know the appropriate
upper bound for T0SZ.

Signed-off-by: Robin Murphy <[email protected]>
---

v3: Fix IDR5.VAX being a 2-bit field, and slight reorganisation of the
    stage 1 IAS logic. Since constraining to VA_BITS turns out to be an
    SMMUv3-specific behaviour, and would introduce an undesirable arm64
    dependency to io-pgtable, I ended up leaving it here.

 drivers/iommu/arm-smmu-v3.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index e0d46661c153..b0e23d6bd1ef 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -92,6 +92,8 @@
 #define IDR5_OAS_44_BIT                        4
 #define IDR5_OAS_48_BIT                        5
 #define IDR5_OAS_52_BIT                        6
+#define IDR5_VAX                       GENMASK(11, 10)
+#define IDR5_VAX_52_BIT                        1
 
 #define ARM_SMMU_CR0                   0x20
 #define CR0_CMDQEN                     (1 << 3)
@@ -551,6 +553,7 @@ struct arm_smmu_device {
 #define ARM_SMMU_FEAT_STALLS           (1 << 11)
 #define ARM_SMMU_FEAT_HYP              (1 << 12)
 #define ARM_SMMU_FEAT_STALL_FORCE      (1 << 13)
+#define ARM_SMMU_FEAT_VAX              (1 << 14)
        u32                             features;
 
 #define ARM_SMMU_OPT_SKIP_PREFETCH     (1 << 0)
@@ -1591,7 +1594,8 @@ static int arm_smmu_domain_finalise(struct iommu_domain 
*domain)
 
        switch (smmu_domain->stage) {
        case ARM_SMMU_DOMAIN_S1:
-               ias = VA_BITS;
+               ias = (smmu->features & ARM_SMMU_FEAT_VAX) ? 52 : 48;
+               ias = min_t(unsigned long, ias, VA_BITS);
                oas = smmu->ias;
                fmt = ARM_64_LPAE_S1;
                finalise_stage_fn = arm_smmu_domain_finalise_s1;
@@ -2634,6 +2638,10 @@ static int arm_smmu_device_hw_probe(struct 
arm_smmu_device *smmu)
        if (reg & IDR5_GRAN4K)
                smmu->pgsize_bitmap |= SZ_4K | SZ_2M | SZ_1G;
 
+       /* Input address size */
+       if (FIELD_GET(IDR5_VAX, reg) == IDR5_VAX_52_BIT)
+               smmu->features |= ARM_SMMU_FEAT_VAX;
+
        /* Output address size */
        switch (FIELD_GET(IDR5_OAS, reg)) {
        case IDR5_OAS_32_BIT:
-- 
2.16.1.dirty

_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to