aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJean-Philippe Brucker <jean-philippe.brucker@arm.com>2019-04-17 14:24:45 -0400
committerWill Deacon <will.deacon@arm.com>2019-04-23 07:23:12 -0400
commit8be39a1a04c1491a6a408c1549dfd4e191f3a287 (patch)
tree874cf25a725b9176c8de2450d991e7442d683479 /drivers
parentbcecaee434733d98a9e7a45834f7439b64142eb3 (diff)
iommu/arm-smmu-v3: Add a master->domain pointer
As we're going to track domain-master links more closely for ATS and CD invalidation, add pointer to the attached domain in struct arm_smmu_master. As a result, arm_smmu_strtab_ent is redundant and can be removed. Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/iommu/arm-smmu-v3.c92
1 files changed, 45 insertions, 47 deletions
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 25ba546cae7f..7b425483f4b6 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -505,19 +505,6 @@ struct arm_smmu_s2_cfg {
505 u64 vtcr; 505 u64 vtcr;
506}; 506};
507 507
508struct arm_smmu_strtab_ent {
509 /*
510 * An STE is "assigned" if the master emitting the corresponding SID
511 * is attached to a domain. The behaviour of an unassigned STE is
512 * determined by the disable_bypass parameter, whereas an assigned
513 * STE behaves according to s1_cfg/s2_cfg, which themselves are
514 * configured according to the domain type.
515 */
516 bool assigned;
517 struct arm_smmu_s1_cfg *s1_cfg;
518 struct arm_smmu_s2_cfg *s2_cfg;
519};
520
521struct arm_smmu_strtab_cfg { 508struct arm_smmu_strtab_cfg {
522 __le64 *strtab; 509 __le64 *strtab;
523 dma_addr_t strtab_dma; 510 dma_addr_t strtab_dma;
@@ -593,7 +580,7 @@ struct arm_smmu_device {
593/* SMMU private data for each master */ 580/* SMMU private data for each master */
594struct arm_smmu_master { 581struct arm_smmu_master {
595 struct arm_smmu_device *smmu; 582 struct arm_smmu_device *smmu;
596 struct arm_smmu_strtab_ent ste; 583 struct arm_smmu_domain *domain;
597 u32 *sids; 584 u32 *sids;
598 unsigned int num_sids; 585 unsigned int num_sids;
599}; 586};
@@ -1087,8 +1074,8 @@ static void arm_smmu_sync_ste_for_sid(struct arm_smmu_device *smmu, u32 sid)
1087 arm_smmu_cmdq_issue_sync(smmu); 1074 arm_smmu_cmdq_issue_sync(smmu);
1088} 1075}
1089 1076
1090static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid, 1077static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
1091 __le64 *dst, struct arm_smmu_strtab_ent *ste) 1078 __le64 *dst)
1092{ 1079{
1093 /* 1080 /*
1094 * This is hideously complicated, but we only really care about 1081 * This is hideously complicated, but we only really care about
@@ -1108,6 +1095,10 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid,
1108 */ 1095 */
1109 u64 val = le64_to_cpu(dst[0]); 1096 u64 val = le64_to_cpu(dst[0]);
1110 bool ste_live = false; 1097 bool ste_live = false;
1098 struct arm_smmu_device *smmu = NULL;
1099 struct arm_smmu_s1_cfg *s1_cfg = NULL;
1100 struct arm_smmu_s2_cfg *s2_cfg = NULL;
1101 struct arm_smmu_domain *smmu_domain = NULL;
1111 struct arm_smmu_cmdq_ent prefetch_cmd = { 1102 struct arm_smmu_cmdq_ent prefetch_cmd = {
1112 .opcode = CMDQ_OP_PREFETCH_CFG, 1103 .opcode = CMDQ_OP_PREFETCH_CFG,
1113 .prefetch = { 1104 .prefetch = {
@@ -1115,6 +1106,25 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid,
1115 }, 1106 },
1116 }; 1107 };
1117 1108
1109 if (master) {
1110 smmu_domain = master->domain;
1111 smmu = master->smmu;
1112 }
1113
1114 if (smmu_domain) {
1115 switch (smmu_domain->stage) {
1116 case ARM_SMMU_DOMAIN_S1:
1117 s1_cfg = &smmu_domain->s1_cfg;
1118 break;
1119 case ARM_SMMU_DOMAIN_S2:
1120 case ARM_SMMU_DOMAIN_NESTED:
1121 s2_cfg = &smmu_domain->s2_cfg;
1122 break;
1123 default:
1124 break;
1125 }
1126 }
1127
1118 if (val & STRTAB_STE_0_V) { 1128 if (val & STRTAB_STE_0_V) {
1119 switch (FIELD_GET(STRTAB_STE_0_CFG, val)) { 1129 switch (FIELD_GET(STRTAB_STE_0_CFG, val)) {
1120 case STRTAB_STE_0_CFG_BYPASS: 1130 case STRTAB_STE_0_CFG_BYPASS:
@@ -1135,8 +1145,8 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid,
1135 val = STRTAB_STE_0_V; 1145 val = STRTAB_STE_0_V;
1136 1146
1137 /* Bypass/fault */ 1147 /* Bypass/fault */
1138 if (!ste->assigned || !(ste->s1_cfg || ste->s2_cfg)) { 1148 if (!smmu_domain || !(s1_cfg || s2_cfg)) {
1139 if (!ste->assigned && disable_bypass) 1149 if (!smmu_domain && disable_bypass)
1140 val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_ABORT); 1150 val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_ABORT);
1141 else 1151 else
1142 val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_BYPASS); 1152 val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_BYPASS);
@@ -1154,7 +1164,7 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid,
1154 return; 1164 return;
1155 } 1165 }
1156 1166
1157 if (ste->s1_cfg) { 1167 if (s1_cfg) {
1158 BUG_ON(ste_live); 1168 BUG_ON(ste_live);
1159 dst[1] = cpu_to_le64( 1169 dst[1] = cpu_to_le64(
1160 FIELD_PREP(STRTAB_STE_1_S1CIR, STRTAB_STE_1_S1C_CACHE_WBRA) | 1170 FIELD_PREP(STRTAB_STE_1_S1CIR, STRTAB_STE_1_S1C_CACHE_WBRA) |
@@ -1169,22 +1179,22 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid,
1169 !(smmu->features & ARM_SMMU_FEAT_STALL_FORCE)) 1179 !(smmu->features & ARM_SMMU_FEAT_STALL_FORCE))
1170 dst[1] |= cpu_to_le64(STRTAB_STE_1_S1STALLD); 1180 dst[1] |= cpu_to_le64(STRTAB_STE_1_S1STALLD);
1171 1181
1172 val |= (ste->s1_cfg->cdptr_dma & STRTAB_STE_0_S1CTXPTR_MASK) | 1182 val |= (s1_cfg->cdptr_dma & STRTAB_STE_0_S1CTXPTR_MASK) |
1173 FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S1_TRANS); 1183 FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S1_TRANS);
1174 } 1184 }
1175 1185
1176 if (ste->s2_cfg) { 1186 if (s2_cfg) {
1177 BUG_ON(ste_live); 1187 BUG_ON(ste_live);
1178 dst[2] = cpu_to_le64( 1188 dst[2] = cpu_to_le64(
1179 FIELD_PREP(STRTAB_STE_2_S2VMID, ste->s2_cfg->vmid) | 1189 FIELD_PREP(STRTAB_STE_2_S2VMID, s2_cfg->vmid) |
1180 FIELD_PREP(STRTAB_STE_2_VTCR, ste->s2_cfg->vtcr) | 1190 FIELD_PREP(STRTAB_STE_2_VTCR, s2_cfg->vtcr) |
1181#ifdef __BIG_ENDIAN 1191#ifdef __BIG_ENDIAN
1182 STRTAB_STE_2_S2ENDI | 1192 STRTAB_STE_2_S2ENDI |
1183#endif 1193#endif
1184 STRTAB_STE_2_S2PTW | STRTAB_STE_2_S2AA64 | 1194 STRTAB_STE_2_S2PTW | STRTAB_STE_2_S2AA64 |
1185 STRTAB_STE_2_S2R); 1195 STRTAB_STE_2_S2R);
1186 1196
1187 dst[3] = cpu_to_le64(ste->s2_cfg->vttbr & STRTAB_STE_3_S2TTB_MASK); 1197 dst[3] = cpu_to_le64(s2_cfg->vttbr & STRTAB_STE_3_S2TTB_MASK);
1188 1198
1189 val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S2_TRANS); 1199 val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S2_TRANS);
1190 } 1200 }
@@ -1201,10 +1211,9 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid,
1201static void arm_smmu_init_bypass_stes(u64 *strtab, unsigned int nent) 1211static void arm_smmu_init_bypass_stes(u64 *strtab, unsigned int nent)
1202{ 1212{
1203 unsigned int i; 1213 unsigned int i;
1204 struct arm_smmu_strtab_ent ste = { .assigned = false };
1205 1214
1206 for (i = 0; i < nent; ++i) { 1215 for (i = 0; i < nent; ++i) {
1207 arm_smmu_write_strtab_ent(NULL, -1, strtab, &ste); 1216 arm_smmu_write_strtab_ent(NULL, -1, strtab);
1208 strtab += STRTAB_STE_DWORDS; 1217 strtab += STRTAB_STE_DWORDS;
1209 } 1218 }
1210} 1219}
@@ -1706,13 +1715,16 @@ static void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master)
1706 if (j < i) 1715 if (j < i)
1707 continue; 1716 continue;
1708 1717
1709 arm_smmu_write_strtab_ent(smmu, sid, step, &master->ste); 1718 arm_smmu_write_strtab_ent(master, sid, step);
1710 } 1719 }
1711} 1720}
1712 1721
1713static void arm_smmu_detach_dev(struct arm_smmu_master *master) 1722static void arm_smmu_detach_dev(struct arm_smmu_master *master)
1714{ 1723{
1715 master->ste.assigned = false; 1724 if (!master->domain)
1725 return;
1726
1727 master->domain = NULL;
1716 arm_smmu_install_ste_for_dev(master); 1728 arm_smmu_install_ste_for_dev(master);
1717} 1729}
1718 1730
@@ -1723,18 +1735,14 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
1723 struct arm_smmu_device *smmu; 1735 struct arm_smmu_device *smmu;
1724 struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); 1736 struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
1725 struct arm_smmu_master *master; 1737 struct arm_smmu_master *master;
1726 struct arm_smmu_strtab_ent *ste;
1727 1738
1728 if (!fwspec) 1739 if (!fwspec)
1729 return -ENOENT; 1740 return -ENOENT;
1730 1741
1731 master = fwspec->iommu_priv; 1742 master = fwspec->iommu_priv;
1732 smmu = master->smmu; 1743 smmu = master->smmu;
1733 ste = &master->ste;
1734 1744
1735 /* Already attached to a different domain? */ 1745 arm_smmu_detach_dev(master);
1736 if (ste->assigned)
1737 arm_smmu_detach_dev(master);
1738 1746
1739 mutex_lock(&smmu_domain->init_mutex); 1747 mutex_lock(&smmu_domain->init_mutex);
1740 1748
@@ -1754,19 +1762,10 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
1754 goto out_unlock; 1762 goto out_unlock;
1755 } 1763 }
1756 1764
1757 ste->assigned = true; 1765 master->domain = smmu_domain;
1758 1766
1759 if (smmu_domain->stage == ARM_SMMU_DOMAIN_BYPASS) { 1767 if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1)
1760 ste->s1_cfg = NULL; 1768 arm_smmu_write_ctx_desc(smmu, &smmu_domain->s1_cfg);
1761 ste->s2_cfg = NULL;
1762 } else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
1763 ste->s1_cfg = &smmu_domain->s1_cfg;
1764 ste->s2_cfg = NULL;
1765 arm_smmu_write_ctx_desc(smmu, ste->s1_cfg);
1766 } else {
1767 ste->s1_cfg = NULL;
1768 ste->s2_cfg = &smmu_domain->s2_cfg;
1769 }
1770 1769
1771 arm_smmu_install_ste_for_dev(master); 1770 arm_smmu_install_ste_for_dev(master);
1772out_unlock: 1771out_unlock:
@@ -1921,8 +1920,7 @@ static void arm_smmu_remove_device(struct device *dev)
1921 1920
1922 master = fwspec->iommu_priv; 1921 master = fwspec->iommu_priv;
1923 smmu = master->smmu; 1922 smmu = master->smmu;
1924 if (master && master->ste.assigned) 1923 arm_smmu_detach_dev(master);
1925 arm_smmu_detach_dev(master);
1926 iommu_group_remove_device(dev); 1924 iommu_group_remove_device(dev);
1927 iommu_device_unlink(&smmu->iommu, dev); 1925 iommu_device_unlink(&smmu->iommu, dev);
1928 kfree(master); 1926 kfree(master);