diff options
author | Yisheng Xie <xieyisheng1@huawei.com> | 2017-09-21 08:36:07 -0400 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2017-10-20 11:55:04 -0400 |
commit | 9cff86fd2b960f9bedc67771c24a73d7dc32048d (patch) | |
tree | 4e53fee65a0f6215f89f2124d083da0471d0757c /drivers | |
parent | 74f55d34414c866dbf3a69e28a2f963abe61ca58 (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.c | 15 |
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 | ||