From mboxrd@z Thu Jan 1 00:00:00 1970 From: Stefano Stabellini Subject: Re: [PATCH v2 10/12] xen/iommu: smmu: Check for duplicate stream IDs when registering master devices Date: Tue, 27 Jan 2015 16:30:29 +0000 Message-ID: References: <1421418247-30068-1-git-send-email-julien.grall@linaro.org> <1421418247-30068-11-git-send-email-julien.grall@linaro.org> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1YG92S-0007ew-UI for xen-devel@lists.xenproject.org; Tue, 27 Jan 2015 16:30:53 +0000 In-Reply-To: <1421418247-30068-11-git-send-email-julien.grall@linaro.org> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Julien Grall Cc: ian.campbell@citrix.com, tim@xen.org, Andreas Herrmann , stefano.stabellini@citrix.com, Andreas Herrmann , xen-devel@lists.xenproject.org List-Id: xen-devel@lists.xenproject.org On Fri, 16 Jan 2015, Julien Grall wrote: > From: Andreas Herrmann > > If DT information lists one stream ID twice for the master devices of > an SMMU this can cause a multi match when stream ID matching is used. > For stream ID indexing this might trigger an overwrite of an S2CR that > is already in use. > > So better check for duplicates when DT information is parsed. > > Taken from the linux ML: > http://lists.infradead.org/pipermail/linux-arm-kernel/2014-January/226099.html > > Cc: Andreas Herrmann > Signed-off-by: Andreas Herrmann > Signed-off-by: Julien Grall Why didn't you just take a more recent version of the Linux smmu driver? > xen/drivers/passthrough/arm/smmu.c | 25 +++++++++++++++++++++++-- > 1 file changed, 23 insertions(+), 2 deletions(-) > > diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c > index 6cd47b7..bfc1069 100644 > --- a/xen/drivers/passthrough/arm/smmu.c > +++ b/xen/drivers/passthrough/arm/smmu.c > @@ -51,6 +51,9 @@ > /* Maximum number of stream IDs assigned to a single device */ > #define MAX_MASTER_STREAMIDS MAX_PHANDLE_ARGS > > +/* Maximum stream ID */ > +#define ARM_SMMU_MAX_STREAMID (SZ_64K - 1) > + > /* Maximum number of context banks per SMMU */ > #define ARM_SMMU_MAX_CBS 128 > > @@ -519,7 +522,8 @@ static int insert_smmu_master(struct arm_smmu_device *smmu, > > static int register_smmu_master(struct arm_smmu_device *smmu, > struct device *dev, > - struct of_phandle_args *masterspec) > + struct of_phandle_args *masterspec, > + unsigned long *smmu_sids) > { > int i; > struct arm_smmu_master *master; > @@ -556,6 +560,12 @@ static int register_smmu_master(struct arm_smmu_device *smmu, > masterspec->np->name, smmu->num_mapping_groups); > return -ERANGE; > } > + > + if (test_and_set_bit(streamid, smmu_sids)) { > + dev_err(dev, "duplicate stream ID (%d)\n", streamid); > + return -EEXIST; > + } > + > master->cfg.streamids[i] = streamid; > } > return insert_smmu_master(smmu, master); > @@ -1977,6 +1987,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) > struct device *dev = &pdev->dev; > struct rb_node *node; > struct of_phandle_args masterspec; > + unsigned long *smmu_sids; > int num_irqs, i, err; > > smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL); > @@ -2035,20 +2046,30 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) > if (err) > return err; > > + smmu_sids = kzalloc(BITS_TO_LONGS(ARM_SMMU_MAX_STREAMID) * > + sizeof(long), GFP_KERNEL); > + if (!smmu_sids) { > + dev_err(dev, > + "failed to allocate bitmap for stream ID tracking\n"); > + return -ENOMEM; > + } > + > i = 0; > smmu->masters = RB_ROOT; > while (!of_parse_phandle_with_args(dev->of_node, "mmu-masters", > "#stream-id-cells", i, > &masterspec)) { > - err = register_smmu_master(smmu, dev, &masterspec); > + err = register_smmu_master(smmu, dev, &masterspec, smmu_sids); > if (err) { > dev_err(dev, "failed to add master %s\n", > masterspec.np->name); > + kfree(smmu_sids); > goto out_put_masters; > } > > i++; > } > + kfree(smmu_sids); > dev_notice(dev, "registered %d master devices\n", i); > > parse_driver_options(smmu); > -- > 2.1.4 >