Message ID | 7775719c50c56b801e69d952e4ce255b8da1481c.1615312254.git.rahul.singh@arm.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | xen/arm: smmuv1: Fix stream match conflict issue | expand |
Hi Rahul, On 09/03/2021 18:19, Rahul Singh wrote: > Backport commit 21174240e4f4439bb8ed6c116cdbdc03eba2126e > "iommu/arm-smmu: Handle stream IDs more dynamically" from the Linux > ernel. > > This patch is the preparatory work to fix the stream match conflict > when two devices have the same stream-id. > > Original commit message: > > Rather than assuming fixed worst-case values for stream IDs and SMR > masks, keep track of whatever implemented bits the hardware actually > reports. This also obviates the slightly questionable validation of SMR > fields in isolation - rather than aborting the whole SMMU probe for a > hardware configuration which is still architecturally valid, we can > simply refuse masters later if they try to claim an unrepresentable ID > or mask (which almost certainly implies a DT error anyway). For single backported and verbatim commit, it is common to keep the origin tags (I usually indent them) to show who is the original author of the patch. Since 7936671da9fbf645d6bb207608f7b81c27f992de from Wei Chen as an example. Cheers,
Hello Julien > On 16 Mar 2021, at 3:16 pm, Julien Grall <julien@xen.org> wrote: > > Hi Rahul, > > On 09/03/2021 18:19, Rahul Singh wrote: >> Backport commit 21174240e4f4439bb8ed6c116cdbdc03eba2126e >> "iommu/arm-smmu: Handle stream IDs more dynamically" from the Linux >> ernel. >> This patch is the preparatory work to fix the stream match conflict >> when two devices have the same stream-id. >> Original commit message: >> Rather than assuming fixed worst-case values for stream IDs and SMR >> masks, keep track of whatever implemented bits the hardware actually >> reports. This also obviates the slightly questionable validation of SMR >> fields in isolation - rather than aborting the whole SMMU probe for a >> hardware configuration which is still architecturally valid, we can >> simply refuse masters later if they try to claim an unrepresentable ID >> or mask (which almost certainly implies a DT error anyway). > > For single backported and verbatim commit, it is common to keep the origin tags (I usually indent them) to show who is the original author of the patch. > > Since 7936671da9fbf645d6bb207608f7b81c27f992de from Wei Chen as an example. Thanks for reviewing the series. I will add the origin tags in the next version. Regards, Rahul > > Cheers, > > -- > Julien Grall
diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c index 3e8aa37866..adfab8ee84 100644 --- a/xen/drivers/passthrough/arm/smmu.c +++ b/xen/drivers/passthrough/arm/smmu.c @@ -440,9 +440,7 @@ static struct iommu_group *iommu_group_get(struct device *dev) #define ARM_SMMU_GR0_SMR(n) (0x800 + ((n) << 2)) #define SMR_VALID (1U << 31) #define SMR_MASK_SHIFT 16 -#define SMR_MASK_MASK 0x7fff #define SMR_ID_SHIFT 0 -#define SMR_ID_MASK 0x7fff #define ARM_SMMU_GR0_S2CR(n) (0xc00 + ((n) << 2)) #define S2CR_CBNDX_SHIFT 0 @@ -632,6 +630,8 @@ struct arm_smmu_device { atomic_t irptndx; u32 num_mapping_groups; + u16 streamid_mask; + u16 smr_mask_mask; DECLARE_BITMAP(smr_map, ARM_SMMU_MAX_SMRS); unsigned long s1_input_size; @@ -2140,39 +2140,40 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) dev_notice(smmu->dev, "\tcoherent table walk\n"); } + /* Max. number of entries we have for stream matching/indexing */ + size = 1 << ((id >> ID0_NUMSIDB_SHIFT) & ID0_NUMSIDB_MASK); + smmu->streamid_mask = size - 1; if (id & ID0_SMS) { - u32 smr, sid, mask; + u32 smr; smmu->features |= ARM_SMMU_FEAT_STREAM_MATCH; - smmu->num_mapping_groups = (id >> ID0_NUMSMRG_SHIFT) & - ID0_NUMSMRG_MASK; - if (smmu->num_mapping_groups == 0) { + size = (id >> ID0_NUMSMRG_SHIFT) & ID0_NUMSMRG_MASK; + if (size == 0) { dev_err(smmu->dev, "stream-matching supported, but no SMRs present!\n"); return -ENODEV; } - smr = SMR_MASK_MASK << SMR_MASK_SHIFT; - smr |= (SMR_ID_MASK << SMR_ID_SHIFT); + /* + * SMR.ID bits may not be preserved if the corresponding MASK + * bits are set, so check each one separately. We can reject + * masters later if they try to claim IDs outside these masks. + */ + smr = smmu->streamid_mask << SMR_ID_SHIFT; writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(0)); smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(0)); + smmu->streamid_mask = smr >> SMR_ID_SHIFT; - mask = (smr >> SMR_MASK_SHIFT) & SMR_MASK_MASK; - sid = (smr >> SMR_ID_SHIFT) & SMR_ID_MASK; - if ((mask & sid) != sid) { - dev_err(smmu->dev, - "SMR mask bits (0x%x) insufficient for ID field (0x%x)\n", - mask, sid); - return -ENODEV; - } + smr = smmu->streamid_mask << SMR_MASK_SHIFT; + writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(0)); + smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(0)); + smmu->smr_mask_mask = smr >> SMR_MASK_SHIFT; dev_notice(smmu->dev, - "\tstream matching with %u register groups, mask 0x%x\n", - smmu->num_mapping_groups, mask); - } else { - smmu->num_mapping_groups = (id >> ID0_NUMSIDB_SHIFT) & - ID0_NUMSIDB_MASK; + "\tstream matching with %lu register groups, mask 0x%x", + size, smmu->smr_mask_mask); } + smmu->num_mapping_groups = size; /* ID1 */ id = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID1);
Backport commit 21174240e4f4439bb8ed6c116cdbdc03eba2126e "iommu/arm-smmu: Handle stream IDs more dynamically" from the Linux ernel. This patch is the preparatory work to fix the stream match conflict when two devices have the same stream-id. Original commit message: Rather than assuming fixed worst-case values for stream IDs and SMR masks, keep track of whatever implemented bits the hardware actually reports. This also obviates the slightly questionable validation of SMR fields in isolation - rather than aborting the whole SMMU probe for a hardware configuration which is still architecturally valid, we can simply refuse masters later if they try to claim an unrepresentable ID or mask (which almost certainly implies a DT error anyway). Signed-off-by: Rahul Singh <rahul.singh@arm.com> --- xen/drivers/passthrough/arm/smmu.c | 43 +++++++++++++++--------------- 1 file changed, 22 insertions(+), 21 deletions(-)