All of lore.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: 53+ 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   ` 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 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.