From: Boris Brezillon <boris.brezillon@free-electrons.com>
To: Cyrille Pitchen <cyrille.pitchen@wedev4u.fr>
Cc: marek.vasut@gmail.com, linux-mtd@lists.infradead.org,
geert@linux-m68k.org, computersforpeace@gmail.com,
dwmw2@infradead.org, richard@nod.at,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] mtd: spi-nor: fix DMA unsafe buffer issue in spi_nor_read_sfdp()
Date: Thu, 7 Sep 2017 09:07:02 +0200 [thread overview]
Message-ID: <20170907090702.257d30a2@bbrezillon> (raw)
In-Reply-To: <20170906214502.26748-1-cyrille.pitchen@wedev4u.fr>
On Wed, 6 Sep 2017 23:45:02 +0200
Cyrille Pitchen <cyrille.pitchen@wedev4u.fr> wrote:
> spi_nor_read_sfdp() calls nor->read() to read the SFDP data.
> When the m25p80 driver is used (pretty common case), nor->read() is then
> implemented by the m25p80_read() function, which is likely to initialize a
> 'struct spi_transfer' from its buf argument before appending this
> structure inside the 'struct spi_message' argument of spi_sync().
>
> Besides the SPI sub-system states that both .tx_buf and .rx_buf members of
> 'struct spi_transfer' must point into dma-safe memory. However, two of the
> three calls of spi_nor_read_sfdp() were given pointers to stack allocated
> memory as buf argument, hence not in a dma-safe area.
> Hopefully, the third and last call of spi_nor_read_sfdp() was already
> given a kmalloc'ed buffer argument, hence dma-safe.
>
> So this patch fixes this issue by introducing a
> spi_nor_read_sfdp_dma_unsafe() function which simply wraps the existing
> spi_nor_read_sfdp() function and uses some kmalloc'ed memory as a bounce
> buffer.
>
> Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Missing
Fixes: f384b352cbf0310f ("mtd: spi-nor: parse Serial Flash Discoverable Parameters (SFDP) tables")
> Signed-off-by: Cyrille Pitchen <cyrille.pitchen@wedev4u.fr>
> ---
>
> Compiled but not tested yet!
>
> drivers/mtd/spi-nor/spi-nor.c | 36 +++++++++++++++++++++++++++++++++---
> 1 file changed, 33 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index cf1d4a15e10a..05254dd6a4a0 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -1784,7 +1784,7 @@ spi_nor_set_pp_settings(struct spi_nor_pp_command *pp,
> * @nor: pointer to a 'struct spi_nor'
> * @addr: offset in the SFDP area to start reading data from
> * @len: number of bytes to read
> - * @buf: buffer where the SFDP data are copied into
> + * @buf: buffer where the SFDP data are copied into (dma-safe memory)
> *
> * Whatever the actual numbers of bytes for address and dummy cycles are
> * for (Fast) Read commands, the Read SFDP (5Ah) instruction is always
> @@ -1829,6 +1829,36 @@ static int spi_nor_read_sfdp(struct spi_nor *nor, u32 addr,
> return ret;
> }
>
> +/**
> + * spi_nor_read_sfdp_dma_unsafe() - read Serial Flash Discoverable Parameters.
> + * @nor: pointer to a 'struct spi_nor'
> + * @addr: offset in the SFDP area to start reading data from
> + * @len: number of bytes to read
> + * @buf: buffer where the SFDP data are copied into
> + *
> + * Wrap spi_nor_read_sfdp() using a kmalloc'ed bounce buffer as @buf is now not
> + * guaranteed to be dma-safe.
> + *
> + * Return: -ENOMEM if kmalloc() fails, the return code of spi_nor_read_sfdp()
> + * otherwise.
> + */
> +static int spi_nor_read_sfdp_dma_unsafe(struct spi_nor *nor, u32 addr,
> + size_t len, void *buf)
> +{
> + void *dma_safe_buf;
> + int ret;
> +
> + dma_safe_buf = kmalloc(len, GFP_KERNEL);
> + if (!dma_safe_buf)
> + return -ENOMEM;
> +
> + ret = spi_nor_read_sfdp(nor, addr, len, dma_safe_buf);
> + memcpy(buf, dma_safe_buf, len);
> + kfree(dma_safe_buf);
> +
> + return ret;
> +}
Hm, do we really need to add this function? I would just kmalloc the bfpt
and header objects in spi_nor_parse_bfpt(), which would avoid the extra
heap-to-stack copy and also simplify this patch.
I understand that you want to generically address the problem, but AFAICT
this patch is not doing that since the user has to explicitly call
spi_nor_read_sfdp_dma_unsafe(), and I'm not even sure
spi_nor_read_sfdp_dma_unsafe() can/will be re-used in the generic solution
you envision.
Let's try to keep the fix as simple as possible and think about a better
approach afterwards.
> +
> struct sfdp_parameter_header {
> u8 id_lsb;
> u8 minor;
> @@ -2101,7 +2131,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
> bfpt_header->length * sizeof(u32));
> addr = SFDP_PARAM_HEADER_PTP(bfpt_header);
> memset(&bfpt, 0, sizeof(bfpt));
> - err = spi_nor_read_sfdp(nor, addr, len, &bfpt);
> + err = spi_nor_read_sfdp_dma_unsafe(nor, addr, len, &bfpt);
> if (err < 0)
> return err;
>
> @@ -2243,7 +2273,7 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor,
> int i, err;
>
> /* Get the SFDP header. */
> - err = spi_nor_read_sfdp(nor, 0, sizeof(header), &header);
> + err = spi_nor_read_sfdp_dma_unsafe(nor, 0, sizeof(header), &header);
> if (err < 0)
> return err;
>
next prev parent reply other threads:[~2017-09-07 7:07 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-06 21:45 [PATCH] mtd: spi-nor: fix DMA unsafe buffer issue in spi_nor_read_sfdp() Cyrille Pitchen
2017-09-06 22:50 ` Cyrille Pitchen
2017-09-07 7:12 ` Boris Brezillon
2017-09-07 7:07 ` Boris Brezillon [this message]
2017-09-07 8:00 ` Geert Uytterhoeven
2017-09-07 11:37 ` Boris Brezillon
2017-09-07 11:44 ` Geert Uytterhoeven
2017-09-07 18:54 ` [DEBUG] mtd: spi-nor: dump DWORDs of the Basic Flash Parameter Table Cyrille Pitchen
2017-09-07 19:28 ` Cyrille Pitchen
2017-09-11 8:58 ` Geert Uytterhoeven
2017-09-12 13:12 ` Boris Brezillon
[not found] ` <CAMuHMdXu4zWRev4nTnAfnAqwrZwDRwF3cuC_qEYr96q=C6osZw@mail.gmail.com>
2017-09-13 13:33 ` Boris Brezillon
2017-09-14 16:44 ` Cyrille Pitchen
2017-09-19 20:11 ` Boris Brezillon
2017-09-10 9:03 ` [PATCH] mtd: spi-nor: fix DMA unsafe buffer issue in spi_nor_read_sfdp() Boris Brezillon
2017-09-19 20:12 ` Boris Brezillon
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=20170907090702.257d30a2@bbrezillon \
--to=boris.brezillon@free-electrons.com \
--cc=computersforpeace@gmail.com \
--cc=cyrille.pitchen@wedev4u.fr \
--cc=dwmw2@infradead.org \
--cc=geert@linux-m68k.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=marek.vasut@gmail.com \
--cc=richard@nod.at \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox