Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp449448ybi; Fri, 7 Jun 2019 10:40:40 -0700 (PDT) X-Google-Smtp-Source: APXvYqzTWT9ujDqTZ6GCMuP4PgS6M+PVMloyG+n5qBgYK2xZ21QAverb3e4ZBYSaDojar8zWpE4D X-Received: by 2002:a17:902:222:: with SMTP id 31mr1762199plc.55.1559929240256; Fri, 07 Jun 2019 10:40:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559929240; cv=none; d=google.com; s=arc-20160816; b=kJOhD6PECaewh6Q1iZtrdmqs9j6ePtOB59G/Yi//Gx8Y8DLi+oQLqzw/pCKKWMcxRI 34x2+KwE8y7yisgFJlvW0Py0CHuuuD1Gk6nxshI/22YSYfAJd9sIg/Tw7ixFXlCYaDi2 QAsxhm/8CiYxSAy8xoYs/ZEoicPRPzvKXUNiI+MEmHHKxzbr9STRkn0WrZKtf9oMdFgh 6rSevW0Z8HdvXhGVG3Dql3G1hYhE9x/R1PHEbYeNNPRB0P+Mhy0BxRcfCc7NKV+IKHxd 06LWAhFDDDXi0Uy1NdBzkIQ3eVb65U79O09f/9UeJlmZVD67Fi3+uwj9ASPj64ZODC82 K0pQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=tm/psORJRMmyoIVTxvb56S7ysidNHXZO3kjgkSi/GIU=; b=kb+2PzgjWbwEgiYbNBYcYLO2r5afVHCMa96z3un8qfZINPtIMthvFjAhG/L+gNedSN mFh3yjcRpez+saaZkANbvTkTRrEWO6LadsJZHagaRKHzJ4MQuKCVoMQGRHeC2YgWZOuT 9ILYmuUbDDHL43EMkashBsD8wdoG14zJaMo8499/prVErHipML0n0MOKreo5oVWotjCy VtQS8fmPIHrPP7O+1Pv+f7QVCrJHY6nQFLm/J2IOVSu1NDKrl7Pb4JB+5Y21NZRSFy8Z fqMEsNIjmi+DQXBUaqn5Uoz89Q9SUczlM08L+QTTcsmgfo2OCO2Xs+qPE8l9K9tuP7TY ug5A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=S8vBlVUv; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 65si2574330plb.39.2019.06.07.10.40.23; Fri, 07 Jun 2019 10:40:40 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=S8vBlVUv; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730215AbfFGPlF (ORCPT + 99 others); Fri, 7 Jun 2019 11:41:05 -0400 Received: from mail.kernel.org ([198.145.29.99]:50656 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730198AbfFGPlE (ORCPT ); Fri, 7 Jun 2019 11:41:04 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 1F6B02146E; Fri, 7 Jun 2019 15:41:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559922063; bh=qxZ9rMqJ8eG6DGpDo67Bytw4sJ6TMxqP6+C9DYjK+XY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=S8vBlVUvJDYblG8Yf9SaFwUUf9GaQrOFGoPtTmvdQ9+nOjwBd0Jwi69vd9E9nGOhF fVfu8YVslITTczbcshUF5o4FlX1fosNyMBBLj73QsRXh88O8+qqXYBi9nQDlawfIr5 k4w+0rdczlMqVB5kIhVy4fSPAGYGJqFbV8hD0IvE= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Henry Lin , Mathias Nyman Subject: [PATCH 4.14 23/69] xhci: update bounce buffer with correct sg num Date: Fri, 7 Jun 2019 17:39:04 +0200 Message-Id: <20190607153851.228812132@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190607153848.271562617@linuxfoundation.org> References: <20190607153848.271562617@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Henry Lin commit 597c56e372dab2c7f79b8d700aad3a5deebf9d1b upstream. This change fixes a data corruption issue occurred on USB hard disk for the case that bounce buffer is used during transferring data. While updating data between sg list and bounce buffer, current implementation passes mapped sg number (urb->num_mapped_sgs) to sg_pcopy_from_buffer() and sg_pcopy_to_buffer(). This causes data not get copied if target buffer is located in the elements after mapped sg elements. This change passes sg number for full list to fix issue. Besides, for copying data from bounce buffer, calling dma_unmap_single() on the bounce buffer before copying data to sg list can avoid cache issue. Fixes: f9c589e142d0 ("xhci: TD-fragment, align the unsplittable case with a bounce buffer") Cc: # v4.8+ Signed-off-by: Henry Lin Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -667,6 +667,7 @@ static void xhci_unmap_td_bounce_buffer( struct device *dev = xhci_to_hcd(xhci)->self.controller; struct xhci_segment *seg = td->bounce_seg; struct urb *urb = td->urb; + size_t len; if (!ring || !seg || !urb) return; @@ -677,11 +678,14 @@ static void xhci_unmap_td_bounce_buffer( return; } - /* for in tranfers we need to copy the data from bounce to sg */ - sg_pcopy_from_buffer(urb->sg, urb->num_mapped_sgs, seg->bounce_buf, - seg->bounce_len, seg->bounce_offs); dma_unmap_single(dev, seg->bounce_dma, ring->bounce_buf_len, DMA_FROM_DEVICE); + /* for in tranfers we need to copy the data from bounce to sg */ + len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, seg->bounce_buf, + seg->bounce_len, seg->bounce_offs); + if (len != seg->bounce_len) + xhci_warn(xhci, "WARN Wrong bounce buffer read length: %ld != %d\n", + len, seg->bounce_len); seg->bounce_len = 0; seg->bounce_offs = 0; } @@ -3186,6 +3190,7 @@ static int xhci_align_td(struct xhci_hcd unsigned int unalign; unsigned int max_pkt; u32 new_buff_len; + size_t len; max_pkt = usb_endpoint_maxp(&urb->ep->desc); unalign = (enqd_len + *trb_buff_len) % max_pkt; @@ -3216,8 +3221,12 @@ static int xhci_align_td(struct xhci_hcd /* create a max max_pkt sized bounce buffer pointed to by last trb */ if (usb_urb_dir_out(urb)) { - sg_pcopy_to_buffer(urb->sg, urb->num_mapped_sgs, + len = sg_pcopy_to_buffer(urb->sg, urb->num_sgs, seg->bounce_buf, new_buff_len, enqd_len); + if (len != seg->bounce_len) + xhci_warn(xhci, + "WARN Wrong bounce buffer write length: %ld != %d\n", + len, seg->bounce_len); seg->bounce_dma = dma_map_single(dev, seg->bounce_buf, max_pkt, DMA_TO_DEVICE); } else {