All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rob Herring <robh+dt@kernel.org>
To: Robin Murphy <robin.murphy@arm.com>
Cc: "Frank Rowand" <frowand.list@gmail.com>,
	"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"Christoph Hellwig" <hch@lst.de>,
	"Marek Szyprowski" <m.szyprowski@samsung.com>,
	"Stefan Wahren" <stefan.wahren@i2se.com>,
	"Andreas Färber" <afaerber@suse.de>,
	"Hans Verkuil" <hverkuil@xs4all.nl>,
	"Johan Hovold" <johan@kernel.org>
Subject: Re: [PATCH 1/2] of: Fix DMA mask generation
Date: Mon, 14 Aug 2017 16:09:52 -0500	[thread overview]
Message-ID: <CAL_JsqJHYC0Pg404es8YJfownj7qwHpkfq6u9yx72hdqiDewKQ@mail.gmail.com> (raw)
In-Reply-To: <0819179085df6c41c70e83a2c5c138b95c0386b3.1502468875.git.robin.murphy@arm.com>

On Fri, Aug 11, 2017 at 11:29 AM, Robin Murphy <robin.murphy@arm.com> wrote:
> Historically, DMA masks have suffered some ambiguity between whether
> they represent the range of physical memory a device can access, or the
> address bits a device is capable of driving, particularly since on many
> platforms the two are equivalent. Whilst there are some stragglers left
> (dma_max_pfn(), I'm looking at you...), the majority of DMA code has
> been cleaned up to follow the latter definition, not least since it is
> the only one which makes sense once IOMMUs are involved.
>
> In this respect, of_dma_configure() has always done the wrong thing in
> how it generates initial masks based on "dma-ranges". Although rounding
> down did not affect the TI Keystone platform where dma_addr + size is
> already a power of two, in any other case it results in a mask which is
> at best unnecessarily constrained and at worst unusable.
>
> BCM2837 illustrates the problem nicely, where we have a DMA base of 3GB
> and a size of 1GB - 16MB, giving dma_addr + size = 0xff000000 and a
> resultant mask of 0x7fffffff, which is then insufficient to even cover
> the necessary offset, effectively making all DMA addresses out-of-range.
> This has been hidden until now (mostly because we don't yet prevent
> drivers from simply overwriting this initial mask later upon probe), but
> due to recent changes elsewhere now shows up as USB being broken on
> Raspberry Pi 3.
>
> Make it right by rounding up instead of down, such that the mask
> correctly correctly describes all possisble bits the device needs to
> emit.
>
> Fixes: 9a6d7298b083 ("of: Calculate device DMA masks based on DT dma-range size")
> Reported-by: Stefan Wahren <stefan.wahren@i2se.com>
> Reported-by: Andreas Färber <afaerber@suse.de>
> Reported-by: Hans Verkuil <hverkuil@xs4all.nl>
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
>
> Either of these patches alone should be sufficient to un-break RPi3,
> and they apply independently, so I'm quite happy for one to go in as a
> fix now and the other to wait for 4.14.

Acked-by: Rob Herring <robh@kernel.org>

>
> Robin.
>
>  drivers/of/device.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index 28c38c756f92..e0a28ea341fe 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -89,6 +89,7 @@ int of_dma_configure(struct device *dev, struct device_node *np)
>         bool coherent;
>         unsigned long offset;
>         const struct iommu_ops *iommu;
> +       u64 mask;
>
>         /*
>          * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
> @@ -134,10 +135,9 @@ int of_dma_configure(struct device *dev, struct device_node *np)
>          * Limit coherent and dma mask based on size and default mask
>          * set by the driver.
>          */
> -       dev->coherent_dma_mask = min(dev->coherent_dma_mask,
> -                                    DMA_BIT_MASK(ilog2(dma_addr + size)));
> -       *dev->dma_mask = min((*dev->dma_mask),
> -                            DMA_BIT_MASK(ilog2(dma_addr + size)));
> +       mask = DMA_BIT_MASK(ilog2(dma_addr + size - 1) + 1);
> +       dev->coherent_dma_mask &= mask;
> +       *dev->dma_mask &= mask;
>
>         coherent = of_dma_is_coherent(np);
>         dev_dbg(dev, "device is%sdma coherent\n",
> --
> 2.13.4.dirty
>

WARNING: multiple messages have this Message-ID (diff)
From: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
To: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
Cc: "Frank Rowand"
	<frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	"devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org"
	<devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
	"linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org"
	<linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org>,
	"linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org"
	<linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
	"Christoph Hellwig" <hch-jcswGhMUV9g@public.gmane.org>,
	"Marek Szyprowski"
	<m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>,
	"Stefan Wahren" <stefan.wahren-eS4NqCHxEME@public.gmane.org>,
	"Andreas Färber" <afaerber-l3A5Bk7waGM@public.gmane.org>,
	"Hans Verkuil" <hverkuil-qWit8jRvyhVmR6Xm/wNWPw@public.gmane.org>,
	"Johan Hovold" <johan-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Subject: Re: [PATCH 1/2] of: Fix DMA mask generation
Date: Mon, 14 Aug 2017 16:09:52 -0500	[thread overview]
Message-ID: <CAL_JsqJHYC0Pg404es8YJfownj7qwHpkfq6u9yx72hdqiDewKQ@mail.gmail.com> (raw)
In-Reply-To: <0819179085df6c41c70e83a2c5c138b95c0386b3.1502468875.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>

On Fri, Aug 11, 2017 at 11:29 AM, Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org> wrote:
> Historically, DMA masks have suffered some ambiguity between whether
> they represent the range of physical memory a device can access, or the
> address bits a device is capable of driving, particularly since on many
> platforms the two are equivalent. Whilst there are some stragglers left
> (dma_max_pfn(), I'm looking at you...), the majority of DMA code has
> been cleaned up to follow the latter definition, not least since it is
> the only one which makes sense once IOMMUs are involved.
>
> In this respect, of_dma_configure() has always done the wrong thing in
> how it generates initial masks based on "dma-ranges". Although rounding
> down did not affect the TI Keystone platform where dma_addr + size is
> already a power of two, in any other case it results in a mask which is
> at best unnecessarily constrained and at worst unusable.
>
> BCM2837 illustrates the problem nicely, where we have a DMA base of 3GB
> and a size of 1GB - 16MB, giving dma_addr + size = 0xff000000 and a
> resultant mask of 0x7fffffff, which is then insufficient to even cover
> the necessary offset, effectively making all DMA addresses out-of-range.
> This has been hidden until now (mostly because we don't yet prevent
> drivers from simply overwriting this initial mask later upon probe), but
> due to recent changes elsewhere now shows up as USB being broken on
> Raspberry Pi 3.
>
> Make it right by rounding up instead of down, such that the mask
> correctly correctly describes all possisble bits the device needs to
> emit.
>
> Fixes: 9a6d7298b083 ("of: Calculate device DMA masks based on DT dma-range size")
> Reported-by: Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org>
> Reported-by: Andreas Färber <afaerber-l3A5Bk7waGM@public.gmane.org>
> Reported-by: Hans Verkuil <hverkuil-qWit8jRvyhVmR6Xm/wNWPw@public.gmane.org>
> Signed-off-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
> ---
>
> Either of these patches alone should be sufficient to un-break RPi3,
> and they apply independently, so I'm quite happy for one to go in as a
> fix now and the other to wait for 4.14.

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

>
> Robin.
>
>  drivers/of/device.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index 28c38c756f92..e0a28ea341fe 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -89,6 +89,7 @@ int of_dma_configure(struct device *dev, struct device_node *np)
>         bool coherent;
>         unsigned long offset;
>         const struct iommu_ops *iommu;
> +       u64 mask;
>
>         /*
>          * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
> @@ -134,10 +135,9 @@ int of_dma_configure(struct device *dev, struct device_node *np)
>          * Limit coherent and dma mask based on size and default mask
>          * set by the driver.
>          */
> -       dev->coherent_dma_mask = min(dev->coherent_dma_mask,
> -                                    DMA_BIT_MASK(ilog2(dma_addr + size)));
> -       *dev->dma_mask = min((*dev->dma_mask),
> -                            DMA_BIT_MASK(ilog2(dma_addr + size)));
> +       mask = DMA_BIT_MASK(ilog2(dma_addr + size - 1) + 1);
> +       dev->coherent_dma_mask &= mask;
> +       *dev->dma_mask &= mask;
>
>         coherent = of_dma_is_coherent(np);
>         dev_dbg(dev, "device is%sdma coherent\n",
> --
> 2.13.4.dirty
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

WARNING: multiple messages have this Message-ID (diff)
From: robh+dt@kernel.org (Rob Herring)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/2] of: Fix DMA mask generation
Date: Mon, 14 Aug 2017 16:09:52 -0500	[thread overview]
Message-ID: <CAL_JsqJHYC0Pg404es8YJfownj7qwHpkfq6u9yx72hdqiDewKQ@mail.gmail.com> (raw)
In-Reply-To: <0819179085df6c41c70e83a2c5c138b95c0386b3.1502468875.git.robin.murphy@arm.com>

On Fri, Aug 11, 2017 at 11:29 AM, Robin Murphy <robin.murphy@arm.com> wrote:
> Historically, DMA masks have suffered some ambiguity between whether
> they represent the range of physical memory a device can access, or the
> address bits a device is capable of driving, particularly since on many
> platforms the two are equivalent. Whilst there are some stragglers left
> (dma_max_pfn(), I'm looking at you...), the majority of DMA code has
> been cleaned up to follow the latter definition, not least since it is
> the only one which makes sense once IOMMUs are involved.
>
> In this respect, of_dma_configure() has always done the wrong thing in
> how it generates initial masks based on "dma-ranges". Although rounding
> down did not affect the TI Keystone platform where dma_addr + size is
> already a power of two, in any other case it results in a mask which is
> at best unnecessarily constrained and at worst unusable.
>
> BCM2837 illustrates the problem nicely, where we have a DMA base of 3GB
> and a size of 1GB - 16MB, giving dma_addr + size = 0xff000000 and a
> resultant mask of 0x7fffffff, which is then insufficient to even cover
> the necessary offset, effectively making all DMA addresses out-of-range.
> This has been hidden until now (mostly because we don't yet prevent
> drivers from simply overwriting this initial mask later upon probe), but
> due to recent changes elsewhere now shows up as USB being broken on
> Raspberry Pi 3.
>
> Make it right by rounding up instead of down, such that the mask
> correctly correctly describes all possisble bits the device needs to
> emit.
>
> Fixes: 9a6d7298b083 ("of: Calculate device DMA masks based on DT dma-range size")
> Reported-by: Stefan Wahren <stefan.wahren@i2se.com>
> Reported-by: Andreas F?rber <afaerber@suse.de>
> Reported-by: Hans Verkuil <hverkuil@xs4all.nl>
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
>
> Either of these patches alone should be sufficient to un-break RPi3,
> and they apply independently, so I'm quite happy for one to go in as a
> fix now and the other to wait for 4.14.

Acked-by: Rob Herring <robh@kernel.org>

>
> Robin.
>
>  drivers/of/device.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index 28c38c756f92..e0a28ea341fe 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -89,6 +89,7 @@ int of_dma_configure(struct device *dev, struct device_node *np)
>         bool coherent;
>         unsigned long offset;
>         const struct iommu_ops *iommu;
> +       u64 mask;
>
>         /*
>          * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
> @@ -134,10 +135,9 @@ int of_dma_configure(struct device *dev, struct device_node *np)
>          * Limit coherent and dma mask based on size and default mask
>          * set by the driver.
>          */
> -       dev->coherent_dma_mask = min(dev->coherent_dma_mask,
> -                                    DMA_BIT_MASK(ilog2(dma_addr + size)));
> -       *dev->dma_mask = min((*dev->dma_mask),
> -                            DMA_BIT_MASK(ilog2(dma_addr + size)));
> +       mask = DMA_BIT_MASK(ilog2(dma_addr + size - 1) + 1);
> +       dev->coherent_dma_mask &= mask;
> +       *dev->dma_mask &= mask;
>
>         coherent = of_dma_is_coherent(np);
>         dev_dbg(dev, "device is%sdma coherent\n",
> --
> 2.13.4.dirty
>

  parent reply	other threads:[~2017-08-14 21:10 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-11 16:29 [PATCH 1/2] of: Fix DMA mask generation Robin Murphy
2017-08-11 16:29 ` Robin Murphy
2017-08-11 16:29 ` Robin Murphy
2017-08-11 16:29 ` [PATCH 2/2] of: Restrict DMA configuration Robin Murphy
2017-08-11 16:29   ` Robin Murphy
2017-08-11 18:01   ` Christoph Hellwig
2017-08-11 18:01     ` Christoph Hellwig
2017-08-11 18:01     ` Christoph Hellwig
2017-08-14 20:08   ` Rob Herring
2017-08-14 20:08     ` Rob Herring
2017-08-14 20:08     ` Rob Herring
2017-08-15 10:18     ` Robin Murphy
2017-08-15 10:18       ` Robin Murphy
2017-08-15 10:18       ` Robin Murphy
2017-08-15 14:19       ` Rob Herring
2017-08-15 14:19         ` Rob Herring
2017-08-15 14:19         ` Rob Herring
2017-08-25 14:54         ` Christoph Hellwig
2017-08-25 14:54           ` Christoph Hellwig
2017-08-11 17:56 ` [PATCH 1/2] of: Fix DMA mask generation Christoph Hellwig
2017-08-11 17:56   ` Christoph Hellwig
2017-08-14 21:09 ` Rob Herring [this message]
2017-08-14 21:09   ` Rob Herring
2017-08-14 21:09   ` Rob Herring
2017-08-17  8:24   ` Christoph Hellwig
2017-08-17  8:24     ` Christoph Hellwig

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAL_JsqJHYC0Pg404es8YJfownj7qwHpkfq6u9yx72hdqiDewKQ@mail.gmail.com \
    --to=robh+dt@kernel.org \
    --cc=afaerber@suse.de \
    --cc=devicetree@vger.kernel.org \
    --cc=frowand.list@gmail.com \
    --cc=hch@lst.de \
    --cc=hverkuil@xs4all.nl \
    --cc=johan@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=robin.murphy@arm.com \
    --cc=stefan.wahren@i2se.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.