STRTAB_STE_1_S1STALLD | STRTAB_STE_1_STRW |
                                    STRTAB_STE_1_EATS);
                used_bits[2] |= cpu_to_le64(STRTAB_STE_2_S2VMID);
+
+               /*
+                * See 13.5 Summary of attribute/permission configuration fields
+                * for the SHCFG behavior.
+                */
+               if (FIELD_GET(STRTAB_STE_1_S1DSS, le64_to_cpu(ent[1])) ==
+                   STRTAB_STE_1_S1DSS_BYPASS)
+                       used_bits[1] |= cpu_to_le64(STRTAB_STE_1_SHCFG);
        }
 
        /* S2 translates */
 
 VISIBLE_IF_KUNIT
 void arm_smmu_make_cdtable_ste(struct arm_smmu_ste *target,
-                              struct arm_smmu_master *master, bool ats_enabled)
+                              struct arm_smmu_master *master, bool ats_enabled,
+                              unsigned int s1dss)
 {
        struct arm_smmu_ctx_desc_cfg *cd_table = &master->cd_table;
        struct arm_smmu_device *smmu = master->smmu;
                FIELD_PREP(STRTAB_STE_0_S1CDMAX, cd_table->s1cdmax));
 
        target->data[1] = cpu_to_le64(
-               FIELD_PREP(STRTAB_STE_1_S1DSS, STRTAB_STE_1_S1DSS_SSID0) |
+               FIELD_PREP(STRTAB_STE_1_S1DSS, s1dss) |
                FIELD_PREP(STRTAB_STE_1_S1CIR, STRTAB_STE_1_S1C_CACHE_WBRA) |
                FIELD_PREP(STRTAB_STE_1_S1COR, STRTAB_STE_1_S1C_CACHE_WBRA) |
                FIELD_PREP(STRTAB_STE_1_S1CSH, ARM_SMMU_SH_ISH) |
                FIELD_PREP(STRTAB_STE_1_EATS,
                           ats_enabled ? STRTAB_STE_1_EATS_TRANS : 0));
 
+       if ((smmu->features & ARM_SMMU_FEAT_ATTR_TYPES_OVR) &&
+           s1dss == STRTAB_STE_1_S1DSS_BYPASS)
+               target->data[1] |= cpu_to_le64(FIELD_PREP(
+                       STRTAB_STE_1_SHCFG, STRTAB_STE_1_SHCFG_INCOMING));
+
        if (smmu->features & ARM_SMMU_FEAT_E2H) {
                /*
                 * To support BTM the streamworld needs to match the
        /* Inputs */
        struct iommu_domain *old_domain;
        struct arm_smmu_master *master;
+       bool cd_needs_ats;
        ioasid_t ssid;
        /* Resulting state */
        bool ats_enabled;
         */
        lockdep_assert_held(&arm_smmu_asid_lock);
 
-       if (smmu_domain) {
+       if (smmu_domain || state->cd_needs_ats) {
                /*
                 * The SMMU does not support enabling ATS with bypass/abort.
                 * When the STE is in bypass (STE.Config[2:0] == 0b100), ATS
                 * tables.
                 */
                state->ats_enabled = arm_smmu_ats_supported(master);
+       }
 
+       if (smmu_domain) {
                master_domain = kzalloc(sizeof(*master_domain), GFP_KERNEL);
                if (!master_domain)
                        return -ENOMEM;
                arm_smmu_make_s1_cd(&target_cd, master, smmu_domain);
                arm_smmu_write_cd_entry(master, IOMMU_NO_PASID, cdptr,
                                        &target_cd);
-               arm_smmu_make_cdtable_ste(&target, master, state.ats_enabled);
+               arm_smmu_make_cdtable_ste(&target, master, state.ats_enabled,
+                                         STRTAB_STE_1_S1DSS_SSID0);
                arm_smmu_install_ste_for_dev(master, &target);
                break;
        }
        mutex_unlock(&arm_smmu_asid_lock);
 }
 
-static int arm_smmu_attach_dev_ste(struct iommu_domain *domain,
-                                  struct device *dev, struct arm_smmu_ste *ste)
+static void arm_smmu_attach_dev_ste(struct iommu_domain *domain,
+                                   struct device *dev,
+                                   struct arm_smmu_ste *ste,
+                                   unsigned int s1dss)
 {
        struct arm_smmu_master *master = dev_iommu_priv_get(dev);
        struct arm_smmu_attach_state state = {
                .ssid = IOMMU_NO_PASID,
        };
 
-       if (arm_smmu_ssids_in_use(&master->cd_table))
-               return -EBUSY;
-
        /*
         * Do not allow any ASID to be changed while are working on the STE,
         * otherwise we could miss invalidations.
         */
        mutex_lock(&arm_smmu_asid_lock);
 
-       arm_smmu_attach_prepare(&state, domain);
+       /*
+        * If the CD table is not in use we can use the provided STE, otherwise
+        * we use a cdtable STE with the provided S1DSS.
+        */
+       if (arm_smmu_ssids_in_use(&master->cd_table)) {
+               /*
+                * If a CD table has to be present then we need to run with ATS
+                * on even though the RID will fail ATS queries with UR. This is
+                * because we have no idea what the PASID's need.
+                */
+               state.cd_needs_ats = true;
+               arm_smmu_attach_prepare(&state, domain);
+               arm_smmu_make_cdtable_ste(ste, master, state.ats_enabled, s1dss);
+       } else {
+               arm_smmu_attach_prepare(&state, domain);
+       }
        arm_smmu_install_ste_for_dev(master, ste);
        arm_smmu_attach_commit(&state);
        mutex_unlock(&arm_smmu_asid_lock);
         * descriptor from arm_smmu_share_asid().
         */
        arm_smmu_clear_cd(master, IOMMU_NO_PASID);
-       return 0;
 }
 
 static int arm_smmu_attach_dev_identity(struct iommu_domain *domain,
        struct arm_smmu_master *master = dev_iommu_priv_get(dev);
 
        arm_smmu_make_bypass_ste(master->smmu, &ste);
-       return arm_smmu_attach_dev_ste(domain, dev, &ste);
+       arm_smmu_attach_dev_ste(domain, dev, &ste, STRTAB_STE_1_S1DSS_BYPASS);
+       return 0;
 }
 
 static const struct iommu_domain_ops arm_smmu_identity_ops = {
        struct arm_smmu_ste ste;
 
        arm_smmu_make_abort_ste(&ste);
-       return arm_smmu_attach_dev_ste(domain, dev, &ste);
+       arm_smmu_attach_dev_ste(domain, dev, &ste,
+                               STRTAB_STE_1_S1DSS_TERMINATE);
+       return 0;
 }
 
 static const struct iommu_domain_ops arm_smmu_blocked_ops = {