From patchwork Wed Apr 5 13:52:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauro Carvalho Chehab X-Patchwork-Id: 40628 X-Patchwork-Delegate: mchehab@kernel.org Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cvlOD-00044m-Uo; Wed, 05 Apr 2017 13:54:25 +0000 X-tubIT-Incoming-IP: 209.132.180.67 Received: from vger.kernel.org ([209.132.180.67]) by mail.tu-berlin.de (exim-4.84_2/mailfrontend-8) with esmtp id 1cvlOB-0006g2-ls; Wed, 05 Apr 2017 15:54:25 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754609AbdDENx7 (ORCPT + 1 other); Wed, 5 Apr 2017 09:53:59 -0400 Received: from ec2-52-27-115-49.us-west-2.compute.amazonaws.com ([52.27.115.49]:40274 "EHLO osg.samsung.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754594AbdDENwq (ORCPT ); Wed, 5 Apr 2017 09:52:46 -0400 Received: from localhost (localhost [127.0.0.1]) by osg.samsung.com (Postfix) with ESMTP id 8D12EA05F0; Wed, 5 Apr 2017 13:53:10 +0000 (UTC) X-Virus-Scanned: amavisd-new at osg.samsung.com Received: from osg.samsung.com ([127.0.0.1]) by localhost (s-opensource.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Qa1KBswA6Xou; Wed, 5 Apr 2017 13:53:09 +0000 (UTC) Received: from smtp.s-opensource.com (177.133.87.34.dynamic.adsl.gvt.net.br [177.133.87.34]) by osg.samsung.com (Postfix) with ESMTPSA id C2B29A05EE; Wed, 5 Apr 2017 13:53:08 +0000 (UTC) Received: from mchehab by smtp.s-opensource.com with local (Exim 4.87) (envelope-from ) id 1cvlMX-0001Tt-OJ; Wed, 05 Apr 2017 10:52:41 -0300 From: Mauro Carvalho Chehab To: Linux Media Mailing List , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , Mauro Carvalho Chehab , Jonathan Corbet , Greg Kroah-Hartman , David Mosberger , Jaejoong Kim , Oliver Neukum , Roger Quadros , Wolfram Sang , linux-usb@vger.kernel.org Subject: [PATCH v3] usb: document that URB transfer_buffer should be aligned Date: Wed, 5 Apr 2017 10:52:40 -0300 Message-Id: <2ed1abe0e72e0e19ea8b1478f5438f2e24480731.1491399808.git.mchehab@s-opensource.com> X-Mailer: git-send-email 2.9.3 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-PMX-Version: 6.0.0.2142326, Antispam-Engine: 2.7.2.2107409, Antispam-Data: 2017.4.5.134518 X-PMX-Spam: Gauge=IIIIIIII, Probability=8%, Report=' MULTIPLE_RCPTS 0.1, HTML_00_01 0.05, HTML_00_10 0.05, BODY_SIZE_4000_4999 0, BODY_SIZE_5000_LESS 0, BODY_SIZE_7000_LESS 0, FROM_NAME_PHRASE 0, INFO_TLD 0, LEGITIMATE_SIGNS 0, MULTIPLE_REAL_RCPTS 0, URI_WITH_PATH_ONLY 0, __ANY_URI 0, __CC_NAME 0, __CC_NAME_DIFF_FROM_ACC 0, __CC_REAL_NAMES 0, __CP_URI_IN_BODY 0, __FROM_DOMAIN_IN_ANY_CC2 0, __FROM_DOMAIN_IN_RCPT 0, __HAS_CC_HDR 0, __HAS_FROM 0, __HAS_LIST_ID 0, __HAS_MSGID 0, __HAS_X_MAILER 0, __HAS_X_MAILING_LIST 0, __HTTPS_URI 0, __MIME_TEXT_ONLY 0, __MIME_TEXT_P 0, __MIME_TEXT_P1 0, __MULTIPLE_RCPTS_CC_X2 0, __MULTIPLE_URI_TEXT 0, __NO_HTML_TAG_RAW 0, __SANE_MSGID 0, __SUBJ_ALPHA_END 0, __TO_MALFORMED_2 0, __TO_NAME 0, __TO_NAME_DIFF_FROM_ACC 0, __TO_REAL_NAMES 0, __URI_IN_BODY 0, __URI_NOT_IMG 0, __URI_NO_WWW 0, __URI_NS , __URI_WITH_PATH 0' 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 buffer overflows at the caller drivers, with could cause data corruption. Such data corruption was found, in practice, with the uvcdriver. Document it. Signed-off-by: Mauro Carvalho Chehab --- Note: this patch is based on my previous patch series with converts URB.txt to ReST: Subject: [PATCH v2 00/21] Convert USB documentation to ReST format Date: Wed, 5 Apr 2017 10:22:54 -0300 https://marc.info/?l=linux-doc&m=149139868231095&w=2 This patch, together with the ones above can be found on this tree: https://git.linuxtv.org/mchehab/experimental.git/log/?h=usb-docs-v2 Documentation/driver-api/usb/URB.rst | 12 ++++++++++++ drivers/usb/core/message.c | 15 +++++++++++++++ include/linux/usb.h | 12 ++++++++++++ 3 files changed, 39 insertions(+) diff --git a/Documentation/driver-api/usb/URB.rst b/Documentation/driver-api/usb/URB.rst index 61a54da9fce9..8d3f362fbe82 100644 --- a/Documentation/driver-api/usb/URB.rst +++ b/Documentation/driver-api/usb/URB.rst @@ -271,6 +271,18 @@ 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. + .. warning:: + + Several host drivers have a 32-bits or 64-bits DMA transfer word size, + with usually matches the CPU word. Due to such restriction, you should + warrant that the @transfer_buffer is DWORD aligned, on 32 bits system, or + QDWORD aligned, on 64 bits system. You should also ensure that the + buffer has enough space for PAD bits. + + This condition is satisfied if you pass a buffer directly allocated by + 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..5739d4422343 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1373,6 +1373,18 @@ 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. * + * .. warning:: + * + * Several host drivers have a 32-bits or 64-bits DMA transfer word size, + * with usually matches the CPU word. Due to such restriction, you should + * warrant that the @transfer_buffer is DWORD aligned, on 32 bits system, or + * QDWORD aligned, on 64 bits system. You should also ensure that the + * buffer has enough space for PAD bits. + * + * This condition is satisfied if you pass a buffer directly allocated by + * kmalloc(), but this may not be the case if the driver allocates a bigger + * buffer and point to a random place inside it. + * * Initialization: * * All URBs submitted must initialize the dev, pipe, transfer_flags (may be