public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
From: Mauro Carvalho Chehab <mchehab@s-opensource.com>
To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Linux Media Mailing List <linux-media@vger.kernel.org>,
	Linux Doc Mailing List <linux-doc@vger.kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Mauro Carvalho Chehab <mchehab@infradead.org>,
	John Youn <johnyoun@synopsys.com>,
	linux-usb@vger.kernel.org, linux-rpi-kernel@lists.infradead.org,
	Jonathan Corbet <corbet@lwn.net>,
	Mauro Carvalho Chehab <mchehab@kernel.org>,
	David Mosberger <davidm@egauge.net>,
	Oliver Neukum <oneukum@suse.com>, Roger Quadros <rogerq@ti.com>,
	Jaejoong Kim <climbbb.kim@gmail.com>,
	Wolfram Sang <wsa-dev@sang-engineering.com>
Subject: Re: [PATCH 22/22] usb: document that URB transfer_buffer should be aligned
Date: Thu, 30 Mar 2017 07:51:49 -0300	[thread overview]
Message-ID: <20170330075149.334d88a8@vento.lan> (raw)
In-Reply-To: <1832248.RT1uOmH7Wy@avalon>

Em Thu, 30 Mar 2017 12:38:42 +0300
Laurent Pinchart <laurent.pinchart@ideasonboard.com> escreveu:

> Hi Mauro,
> 
> On Wednesday 29 Mar 2017 22:06:33 Mauro Carvalho Chehab wrote:
> > Em Thu, 30 Mar 2017 01:15:27 +0300 Laurent Pinchart escreveu:  
> > > On Wednesday 29 Mar 2017 15:54:21 Mauro Carvalho Chehab wrote:  
> > > > Several host controllers, commonly found on ARM, like dwc2,
> > > > require buffers that are CPU-word aligned for they to work.
> > > > 
> > > > Failing to do that will cause random troubles at the caller
> > > > drivers, causing them to fail.
> > > > 
> > > > Document it.
> > > > 
> > > > Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
> > > > ---
> > > > 
> > > >  Documentation/driver-api/usb/URB.rst | 18 ++++++++++++++++++
> > > >  drivers/usb/core/message.c           | 15 +++++++++++++++
> > > >  include/linux/usb.h                  | 18 ++++++++++++++++++
> > > >  3 files changed, 51 insertions(+)
> > > > 
> > > > diff --git a/Documentation/driver-api/usb/URB.rst
> > > > b/Documentation/driver-api/usb/URB.rst index d9ea6a3996e7..b83b557e9891
> > > > 100644
> > > > --- a/Documentation/driver-api/usb/URB.rst
> > > > +++ b/Documentation/driver-api/usb/URB.rst
> > > > @@ -274,6 +274,24 @@ If you specify your own start frame, make sure it's
> > > > several frames in advance of the current frame.  You might want this
> > > > model
> > > > if you're synchronizing ISO data with some other event stream.
> > > > 
> > > > +.. note::
> > > > +
> > > > +   Several host drivers require that the ``transfer_buffer`` to be
> > > > aligned
> > > > +   with the CPU word size (e. g. DWORD for 32 bits, QDWORD for 64
> > > > bits).  
> > > 
> > > Is it the CPU word size or the DMA transfer size ? I assume the latter,
> > > and I wouldn't be surprised if the alignment requirement was 32-bit on at
> > > least some of the 64-bit platforms.  
> > 
> > Yeah, it is actually the DMA transfer size. Yet, worse case scenario is that
> > the DMA transfer size to be 64 bits on 64 bits CPU.
> >   
> > > > +   It is up to USB drivers should ensure that they'll only pass buffers
> > > > +   with such alignments.
> > > > +
> > > > +   Please also notice that, due to such restriction, the host driver  
> > > 
> > > s/notice/note/ (and below as well) ?  
> > 
> > OK.
> >   
> > > > +   may also override PAD bytes at the end of the ``transfer_buffer``,
> > > > up to the
> > > > +   size of the CPU word.  
> > > 
> > > "May" is quite weak here. If some host controller drivers require buffers
> > > to be aligned, then it's an API requirement, and all buffers must be
> > > aligned. I'm not even sure I would mention that some host drivers require
> > > it, I think we should just state that the API requires buffers to be
> > > aligned.  
> > 
> > What I'm trying to say here is that, on a 32-bits system, if the driver do
> > a USB_DIR_IN transfer using some code similar to:
> > 
> > 	size = 4;
> > 	buffer = kmalloc(size, GFP_KERNEL);
> > 
> > 	usb_control_msg(udev, pipe, req, type, val, idx, buffer + 2, 2,   
> timeout);
> > 	usb_control_msg(udev, pipe, req, type, val, idx, buffer, size,   
> timeout);
> > 
> > Drivers like dwc2 will mess with the buffer.
> > 
> > The first transfer will actually work, due to a workaround inside the
> > driver that will create a temporary DWORD-aligned buffer, avoiding it
> > to go past the buffer.
> > 
> > However, the second transfer will destroy the data received from the
> > first usb_control_msg(), as it will write 4 bytes at the buffer.
> > 
> > Not all drivers would do that, though.
> > 
> > Please notice that, as kmalloc will always return a CPU-aligned buffer,
> > if the client do something like:
> > 
> > 	size = 2;
> > 	buffer = kmalloc(size, GFP_KERNEL);
> > 
> > 	usb_control_msg(udev, pipe, req, type, val, idx, buffer, 2, timeout);
> > 
> > What happens there is that the DMA engine will still write 4 bytes at
> > the buffer, but the 2 bytes that go past the end of buffer will be
> > written on a memory that will never be used.  
> 
> I understand that, but stating that host controller drivers "may" do this 
> won't help much. If they *may*, all USB device drivers *must* align buffers 
> correctly. That's the part that needs to be documented. Let's not confuse 
> developers by only stating that something may happened, let's be clear and 
> tell what they must do.

Ok, rewrote the entire text. Please see if the new version
works better.

> 
> > > > +   Please notice that ancillary routines that transfer URBs, like
> > > > +   usb_control_msg() also have such restriction.
> > > > +
> > > > +   Such word alignment condition is normally ensured if the buffer is
> > > > +   allocated with kmalloc(), but this may not be the case if the driver
> > > > +   allocates a bigger buffer and point to a random place inside it.
> > > > +
> > > > 
> > > >  How to start interrupt (INT) transfers?
> > > >  =======================================
> > > > 
> > > > diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
> > > > index 4c38ea41ae96..1662a4446475 100644
> > > > --- a/drivers/usb/core/message.c
> > > > +++ b/drivers/usb/core/message.c
> > > > @@ -128,6 +128,21 @@ static int usb_internal_control_msg(struct
> > > > usb_device
> > > > *usb_dev, * make sure your disconnect() method can wait for it to
> > > > complete.
> > > > Since you * don't have a handle on the URB used, you can't cancel the
> > > > request. *
> > > > + * .. note::
> > > > + *
> > > > + *   Several host drivers require that the @data buffer to be aligned
> > > > + *   with the CPU word size (e. g. DWORD for 32 bits, QDWORD for 64
> > > > bits).
> > > > + *   It is up to USB drivers should ensure that they'll only pass
> > > > buffers
> > > > + *   with such alignments.
> > > > + *
> > > > + *   Please also notice that, due to such restriction, the host driver
> > > > + *   may also override PAD bytes at the end of the @data buffer, up to
> > > > the
> > > > + *   size of the CPU word.
> > > > + *
> > > > + *   Such word alignment condition is normally ensured if the buffer is
> > > > + *   allocated with kmalloc(), but this may not be the case if the
> > > > driver
> > > > + *   allocates a bigger buffer and point to a random place inside it.
> > > > + *
> > > > 
> > > >   * Return: If successful, the number of bytes transferred. Otherwise, a
> > > > 
> > > > negative * error number.
> > > > 
> > > >   */
> > > > 
> > > > diff --git a/include/linux/usb.h b/include/linux/usb.h
> > > > index 7e68259360de..8b5ad6624708 100644
> > > > --- a/include/linux/usb.h
> > > > +++ b/include/linux/usb.h
> > > > @@ -1373,6 +1373,24 @@ typedef void (*usb_complete_t)(struct urb *);
> > > > 
> > > >   * capable, assign NULL to it, so that usbmon knows not to use the
> > > >   value.
> > > >   * The setup_packet must always be set, so it cannot be located in
> > > >   highmem.
> > > > 
> > > > *
> > > > + * .. note::
> > > > + *
> > > > + *   Several host drivers require that the @transfer_buffer to be
> > > > aligned
> > > > + *   with the CPU word size (e. g. DWORD for 32 bits, QDWORD for 64
> > > > bits).
> > > > + *   It is up to USB drivers should ensure that they'll only pass
> > > > buffers
> > > > + *   with such alignments.
> > > > + *
> > > > + *   Please also notice that, due to such restriction, the host driver
> > > > + *   may also override PAD bytes at the end of the @transfer_buffer, up
> > > > to
> > > > the + *   size of the CPU word.
> > > > + *
> > > > + *   Please notice that ancillary routines that start URB transfers,
> > > > like
> > > > + *   usb_control_msg() also have such restriction.
> > > > + *
> > > > + *   Such word alignment condition is normally ensured if the buffer is
> > > > + *   allocated with kmalloc(), but this may not be the case if the
> > > > driver
> > > > + *   allocates a bigger buffer and point to a random place inside it.
> > > > + *  
> > > 
> > > Couldn't we avoid three copies of the same text ? The chance they will get
> > > out-of-sync is quite high.  
> > 
> > IMHO, it is better to document it at those 3 parts, as this issue
> > cause buffer overflows, which is pretty serious, as it corrupts data.
> > 
> > The URB.rst file contains a quick overview of the URB data transfers,
> > and it is likely where a kernel newbie would read first. Experienced
> > programmers will look at urb.h.
> > 
> > usb_control_msg() is a different function, that one might not be
> > expecting to have the same issues.  
> 
> If you add the complete explanation to URB.rst, you can then reference it from 
> the functions' kerneldoc instead of copying it.

True, but URB.txt has a note saying that the document may not be
fully updated, implying that urb.h header is the main reference.

So, I stand that the best here is to have this warning duplicated,
as this is a pretty serious issue and will require people to review
all USB drivers.

Thanks,
Mauro

  reply	other threads:[~2017-03-30 10:51 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-29 18:54 [PATCH 01/22] driver-api/basics.rst: add device table header Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 02/22] docs-rst: convert usb docbooks to ReST Mauro Carvalho Chehab
2017-03-30  7:48   ` Markus Heiser
2017-03-30  8:21     ` Jani Nikula
2017-03-30  9:20       ` Markus Heiser
2017-03-30 10:12         ` Mauro Carvalho Chehab
2017-03-30 11:17           ` Markus Heiser
2017-03-30 11:35             ` Markus Heiser
2017-03-30 12:10             ` Mauro Carvalho Chehab
2017-03-31 14:46         ` Jonathan Corbet
2017-03-29 18:54 ` [PATCH 03/22] usb.rst: Enrich its ReST representation Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 04/22] gadget.rst: Enrich its ReST representation and add kernel-doc tag Mauro Carvalho Chehab
2017-03-30  7:01   ` Jani Nikula
2017-03-30  7:04     ` Jani Nikula
2017-03-30  9:29       ` Mauro Carvalho Chehab
2017-03-30  8:45     ` Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 05/22] writing_usb_driver.rst: Enrich its ReST representation Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 06/22] writing_musb_glue_layer.rst: " Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 07/22] usb/anchors.txt: convert to ReST and add to driver-api book Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 08/22] usb/bulk-streams.txt: " Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 09/22] usb/callbacks.txt: " Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 10/22] usb/power-management.txt: " Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 11/22] usb/dma.txt: " Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 12/22] error-codes.rst: " Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 13/22] usb/hotplug.txt: " Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 14/22] usb/persist.txt: " Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 15/22] usb/URB.txt: convert to ReST and update it Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 16/22] usb/gadget.rst: remove unused kernel-doc tags Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 17/22] usb.rst: get rid of some Sphinx errors Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 18/22] usb: get rid of some ReST doc build errors Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 19/22] usb: composite.h: fix two warnings when building docs Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 20/22] usb: gadget.h: be consistent at kernel doc macros Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 21/22] docs-rst: fix usb cross-references Mauro Carvalho Chehab
2017-03-29 18:54 ` [PATCH 22/22] usb: document that URB transfer_buffer should be aligned Mauro Carvalho Chehab
2017-03-29 22:15   ` Laurent Pinchart
2017-03-30  1:06     ` Mauro Carvalho Chehab
2017-03-30  9:38       ` Laurent Pinchart
2017-03-30 10:51         ` Mauro Carvalho Chehab [this message]
2017-03-30  8:11     ` Oliver Neukum
2017-03-30  9:34       ` Laurent Pinchart
2017-03-30 10:28         ` Mauro Carvalho Chehab
2017-03-30 11:07           ` David Laight
2017-03-30 12:05           ` Laurent Pinchart
2017-03-30 12:37             ` Mauro Carvalho Chehab
2017-03-30 12:56           ` Oliver Neukum
2017-03-30 14:26             ` Alan Stern
2017-03-30 15:45               ` Mauro Carvalho Chehab
2017-03-30 15:55                 ` Alan Stern
2017-03-30 20:16                   ` Laurent Pinchart
2017-03-30 20:57                   ` Oliver Neukum
2017-03-31 14:07                     ` Alan Stern
2017-03-31  1:26 ` [PATCH 01/22] driver-api/basics.rst: add device table header kbuild test robot

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=20170330075149.334d88a8@vento.lan \
    --to=mchehab@s-opensource.com \
    --cc=climbbb.kim@gmail.com \
    --cc=corbet@lwn.net \
    --cc=davidm@egauge.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=johnyoun@synopsys.com \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=linux-rpi-kernel@lists.infradead.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mchehab@infradead.org \
    --cc=mchehab@kernel.org \
    --cc=oneukum@suse.com \
    --cc=rogerq@ti.com \
    --cc=wsa-dev@sang-engineering.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox