public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
From: Boris Brezillon <boris.brezillon@free-electrons.com>
To: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Cyrille Pitchen <cyrille.pitchen@wedev4u.fr>,
	Marek Vasut <marek.vasut@gmail.com>,
	MTD Maling List <linux-mtd@lists.infradead.org>,
	Brian Norris <computersforpeace@gmail.com>,
	David Woodhouse <dwmw2@infradead.org>,
	Richard Weinberger <richard@nod.at>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Linux-Renesas <linux-renesas-soc@vger.kernel.org>,
	Mark Brown <broonie@kernel.org>
Subject: Re: [PATCH] mtd: spi-nor: fix DMA unsafe buffer issue in spi_nor_read_sfdp()
Date: Thu, 7 Sep 2017 13:37:56 +0200	[thread overview]
Message-ID: <20170907133756.6c1f02f6@bbrezillon> (raw)
In-Reply-To: <CAMuHMdXKpheF5whZi2Ot2Pm8t3Lu+ramNV==sXBo87u_HerZxQ@mail.gmail.com>

On Thu, 7 Sep 2017 10:00:50 +0200
Geert Uytterhoeven <geert@linux-m68k.org> wrote:

> Hi Cyrille,
> 
> On Wed, Sep 6, 2017 at 11:45 PM, 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>
> > Signed-off-by: Cyrille Pitchen <cyrille.pitchen@wedev4u.fr>  
> 
> While this patch got rid of the warning, it does not fix the SPI FLASH
> identification
> issue:
> 
>     m25p80 spi0.0: s25fl512s (0 Kbytes)
>     3 ofpart partitions found on MTD device spi0.0
>     Creating 3 MTD partitions on "spi0.0":
>     0x000000000000-0x000000040000 : "loader"
>     mtd: partition "loader" is out of reach -- disabled
>     0x000000040000-0x000000080000 : "system"
>     mtd: partition "system" is out of reach -- disabled
>     0x000000080000-0x000004000000 : "user"
>     mtd: partition "user" is out of reach -- disabled
> 
> I noticed there's still one direct call to spi_nor_read_sfdp() left in
> spi_nor_parse_sfdp().
> I tried changing that to spi_nor_read_sfdp_dma_unsafe(), but that didn't help.
> 
> > --- 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;
> > +}
> > +
> >  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;
> >  
> 
> Instead of having buffers on the stack, passing them around through multiple
> call levels, and then kmalloc()ing a buffer, what about using the helpers in
> <linux/spi/spi.h> instead, which take care of the issue through the
> static bounce
> buffer or kmalloc() themselves?

Are you referring to spi_write_then_read()? If this is the case, I'm not
sure we can use this because m25p80_read/write() can have more than 2
transfers.

  reply	other threads:[~2017-09-07 11:38 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
2017-09-07  8:00 ` Geert Uytterhoeven
2017-09-07 11:37   ` Boris Brezillon [this message]
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=20170907133756.6c1f02f6@bbrezillon \
    --to=boris.brezillon@free-electrons.com \
    --cc=broonie@kernel.org \
    --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=linux-renesas-soc@vger.kernel.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