Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751221AbdHWWrY (ORCPT ); Wed, 23 Aug 2017 18:47:24 -0400 Received: from mail.ispras.ru ([83.149.199.45]:50340 "EHLO mail.ispras.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751085AbdHWWrX (ORCPT ); Wed, 23 Aug 2017 18:47:23 -0400 From: Alexey Khoroshilov To: Felipe Balbi , Greg Kroah-Hartman Cc: Alexey Khoroshilov , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, ldv-project@linuxtesting.org Subject: [PATCH] usb: gadget: pch_udc: add checks for dma mapping errors Date: Thu, 24 Aug 2017 01:47:08 +0300 Message-Id: <1503528428-16901-1-git-send-email-khoroshilov@ispras.ru> X-Mailer: git-send-email 2.7.4 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2008 Lines: 60 There are no checks for dma mapping errors in pch_udc. Tha patch adds the checks and error handling code. Compile tested only. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/usb/gadget/udc/pch_udc.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index 84dcbcd756f0..a305f8392082 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c @@ -1767,7 +1767,7 @@ static struct usb_request *pch_udc_alloc_request(struct usb_ep *usbep, req->req.dma = DMA_ADDR_INVALID; req->dma = DMA_ADDR_INVALID; INIT_LIST_HEAD(&req->queue); - if (!ep->dev->dma_addr) + if (ep->dev->dma_addr != DMA_ADDR_INVALID) return &req->req; /* ep0 in requests are allocated from data pool here */ dma_desc = dma_pool_alloc(ep->dev->data_requests, gfp, @@ -1879,6 +1879,13 @@ static int pch_udc_pcd_queue(struct usb_ep *usbep, struct usb_request *usbreq, usbreq->length, DMA_FROM_DEVICE); } + if (dma_mapping_error(&dev->pdev->dev, req->dma)) { + req->dma = DMA_ADDR_INVALID; + retval = -ENOMEM; + if ((unsigned long)(usbreq->buf) & 0x03) + kfree(req->buf); + goto probe_end; + } req->dma_mapped = 1; } if (usbreq->length > 0) { @@ -2961,6 +2968,10 @@ static int init_dma_pools(struct pch_udc_dev *dev) dev->dma_addr = dma_map_single(&dev->pdev->dev, ep0out_buf, UDC_EP0OUT_BUFF_SIZE * 4, DMA_FROM_DEVICE); + if (dma_mapping_error(&dev->pdev->dev, dev->dma_addr)) { + dev->dma_addr = DMA_ADDR_INVALID; + return -ENOMEM; + } return 0; } @@ -3038,7 +3049,7 @@ static void pch_udc_remove(struct pci_dev *pdev) dma_pool_destroy(dev->stp_requests); } - if (dev->dma_addr) + if (dev->dma_addr != DMA_ADDR_INVALID) dma_unmap_single(&dev->pdev->dev, dev->dma_addr, UDC_EP0OUT_BUFF_SIZE * 4, DMA_FROM_DEVICE); -- 2.7.4