aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorYisheng Xie <xieyisheng1@huawei.com>2017-09-21 08:36:07 -0400
committerWill Deacon <will.deacon@arm.com>2017-10-20 11:55:04 -0400
commit9cff86fd2b960f9bedc67771c24a73d7dc32048d (patch)
tree4e53fee65a0f6215f89f2124d083da0471d0757c /drivers
parent74f55d34414c866dbf3a69e28a2f963abe61ca58 (diff)
iommu/arm-smmu-v3: Avoid ILLEGAL setting of STE.S1STALLD and CD.S
According to Spec, it is ILLEGAL to set STE.S1STALLD if STALL_MODEL is not 0b00, which means we should not disable stall mode if stall or terminate mode is not configuable. Meanwhile, it is also ILLEGAL when STALL_MODEL==0b10 && CD.S==0 which means if stall mode is force we should always set CD.S. As Jean-Philippe's suggestion, this patch introduce a feature bit ARM_SMMU_FEAT_STALL_FORCE, which means smmu only supports stall force. Therefore, we can avoid the ILLEGAL setting of STE.S1STALLD.by checking ARM_SMMU_FEAT_STALL_FORCE. This patch keeps the ARM_SMMU_FEAT_STALLS as the meaning of stall supported (force or configuable) to easy to expand the future function, i.e. we can only use ARM_SMMU_FEAT_STALLS to check whether we should register fault handle or enable master can_stall, etc to supporte platform SVM. The feature bit, STE.S1STALLD and CD.S setting will be like: STALL_MODEL FEATURE S1STALLD CD.S 0b00 ARM_SMMU_FEAT_STALLS 0b1 0b0 0b01 !ARM_SMMU_FEAT_STALLS && !ARM_SMMU_FEAT_STALL_FORCE 0b0 0b0 0b10 ARM_SMMU_FEAT_STALLS && ARM_SMMU_FEAT_STALL_FORCE 0b0 0b1 after apply this patch. Signed-off-by: Yisheng Xie <xieyisheng1@huawei.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/iommu/arm-smmu-v3.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 80532d9ecaaf..159117e2c5ad 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -316,6 +316,7 @@
316#define ARM64_TCR_TBI0_MASK 0x1UL 316#define ARM64_TCR_TBI0_MASK 0x1UL
317 317
318#define CTXDESC_CD_0_AA64 (1UL << 41) 318#define CTXDESC_CD_0_AA64 (1UL << 41)
319#define CTXDESC_CD_0_S (1UL << 44)
319#define CTXDESC_CD_0_R (1UL << 45) 320#define CTXDESC_CD_0_R (1UL << 45)
320#define CTXDESC_CD_0_A (1UL << 46) 321#define CTXDESC_CD_0_A (1UL << 46)
321#define CTXDESC_CD_0_ASET_SHIFT 47 322#define CTXDESC_CD_0_ASET_SHIFT 47
@@ -595,6 +596,7 @@ struct arm_smmu_device {
595#define ARM_SMMU_FEAT_TRANS_S2 (1 << 10) 596#define ARM_SMMU_FEAT_TRANS_S2 (1 << 10)
596#define ARM_SMMU_FEAT_STALLS (1 << 11) 597#define ARM_SMMU_FEAT_STALLS (1 << 11)
597#define ARM_SMMU_FEAT_HYP (1 << 12) 598#define ARM_SMMU_FEAT_HYP (1 << 12)
599#define ARM_SMMU_FEAT_STALL_FORCE (1 << 13)
598 u32 features; 600 u32 features;
599 601
600#define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0) 602#define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0)
@@ -987,6 +989,11 @@ static void arm_smmu_write_ctx_desc(struct arm_smmu_device *smmu,
987 CTXDESC_CD_0_R | CTXDESC_CD_0_A | CTXDESC_CD_0_ASET_PRIVATE | 989 CTXDESC_CD_0_R | CTXDESC_CD_0_A | CTXDESC_CD_0_ASET_PRIVATE |
988 CTXDESC_CD_0_AA64 | (u64)cfg->cd.asid << CTXDESC_CD_0_ASID_SHIFT | 990 CTXDESC_CD_0_AA64 | (u64)cfg->cd.asid << CTXDESC_CD_0_ASID_SHIFT |
989 CTXDESC_CD_0_V; 991 CTXDESC_CD_0_V;
992
993 /* STALL_MODEL==0b10 && CD.S==0 is ILLEGAL */
994 if (smmu->features & ARM_SMMU_FEAT_STALL_FORCE)
995 val |= CTXDESC_CD_0_S;
996
990 cfg->cdptr[0] = cpu_to_le64(val); 997 cfg->cdptr[0] = cpu_to_le64(val);
991 998
992 val = cfg->cd.ttbr & CTXDESC_CD_1_TTB0_MASK << CTXDESC_CD_1_TTB0_SHIFT; 999 val = cfg->cd.ttbr & CTXDESC_CD_1_TTB0_MASK << CTXDESC_CD_1_TTB0_SHIFT;
@@ -1107,7 +1114,8 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid,
1107#endif 1114#endif
1108 STRTAB_STE_1_STRW_NSEL1 << STRTAB_STE_1_STRW_SHIFT); 1115 STRTAB_STE_1_STRW_NSEL1 << STRTAB_STE_1_STRW_SHIFT);
1109 1116
1110 if (smmu->features & ARM_SMMU_FEAT_STALLS) 1117 if (smmu->features & ARM_SMMU_FEAT_STALLS &&
1118 !(smmu->features & ARM_SMMU_FEAT_STALL_FORCE))
1111 dst[1] |= cpu_to_le64(STRTAB_STE_1_S1STALLD); 1119 dst[1] |= cpu_to_le64(STRTAB_STE_1_S1STALLD);
1112 1120
1113 val |= (ste->s1_cfg->cdptr_dma & STRTAB_STE_0_S1CTXPTR_MASK 1121 val |= (ste->s1_cfg->cdptr_dma & STRTAB_STE_0_S1CTXPTR_MASK
@@ -2531,9 +2539,10 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
2531 coherent ? "true" : "false"); 2539 coherent ? "true" : "false");
2532 2540
2533 switch (reg & IDR0_STALL_MODEL_MASK << IDR0_STALL_MODEL_SHIFT) { 2541 switch (reg & IDR0_STALL_MODEL_MASK << IDR0_STALL_MODEL_SHIFT) {
2534 case IDR0_STALL_MODEL_STALL:
2535 /* Fallthrough */
2536 case IDR0_STALL_MODEL_FORCE: 2542 case IDR0_STALL_MODEL_FORCE:
2543 smmu->features |= ARM_SMMU_FEAT_STALL_FORCE;
2544 /* Fallthrough */
2545 case IDR0_STALL_MODEL_STALL:
2537 smmu->features |= ARM_SMMU_FEAT_STALLS; 2546 smmu->features |= ARM_SMMU_FEAT_STALLS;
2538 } 2547 }
2539 2548