NetBSD Problem Report #51199

From www@NetBSD.org  Mon May 30 21:27:44 2016
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(Client CN "mail.netbsd.org", Issuer "Postmaster NetBSD.org" (verified OK))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 3A63A7ABC4
	for <gnats-bugs@gnats.NetBSD.org>; Mon, 30 May 2016 21:27:44 +0000 (UTC)
Message-Id: <20160530212743.194617ABD1@mollari.NetBSD.org>
Date: Mon, 30 May 2016 21:27:43 +0000 (UTC)
From: webpages@sprow.co.uk
Reply-To: webpages@sprow.co.uk
To: gnats-bugs@NetBSD.org
Subject: XHCI driver flushes wrong memory during ring put
X-Send-Pr-Version: www-1.0

>Number:         51199
>Category:       kern
>Synopsis:       XHCI driver flushes wrong memory during ring put
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    kern-bug-people
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon May 30 21:30:00 +0000 2016
>Closed-Date:    Sat Jun 04 20:53:35 +0000 2016
>Last-Modified:  Sat Jun 04 20:53:35 +0000 2016
>Originator:     Sprow
>Release:        
>Organization:
>Environment:
>Description:
When putting a ring of TRBs into memory, xhci_ring_put() takes care to do it backwards to avoid confusing controllers. However, when the first TRB is written out (last) the offset passed to usb_syncmem() is the offset after the final TRB rather than the 0th TRB as required.

This is easiest to see when considering the initial call with just 1 TRB. ie. xr_ep = 0, and ntrbs = 1.
The function reduces to:

	ri = xr->xr_ep;
	ri++; /* <-- ie. 1, required since the for loop starts at 1 and post increments ri */

	/* Write any subsequent TRB first */
	for (i = 1; i < ntrbs; i++) { /* <-- ntrbs = 0, so this loop is skipped */
		usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * ri, XHCI_TRB_SIZE * 1,
		    BUS_DMASYNC_PREWRITE);
		ri++;
	}

	/* Write the first TRB last */
	i = 0;
	usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * ri, XHCI_TRB_SIZE * 1,
	    BUS_DMASYNC_PREWRITE); /* <-- oops, flushes the 1st TRB not the 0th */

	xr->xr_ep = ri;

obviously more complex cases (xr_ep != 0, ntrbs != 1) are similarly affected.
>How-To-Repeat:

>Fix:
--- xhci-1_46.c	2016-05-30 20:51:36 +0100
+++ xhci.c	2016-05-30 20:51:20 +0100
@@ -2559,7 +2559,7 @@
 	}

 	xhci_trb_put(&xr->xr_trb[xr->xr_ep], parameter, status, control);
-	usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * ri, XHCI_TRB_SIZE * 1,
+	usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * xr->xr_ep, XHCI_TRB_SIZE * 1,
 	    BUS_DMASYNC_PREWRITE);
 	xr->xr_cookies[xr->xr_ep] = cookie;

>Release-Note:

>Audit-Trail:
From: "Michael van Elst" <mlelstv@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/51199 CVS commit: src/sys/dev/usb
Date: Tue, 31 May 2016 09:22:11 +0000

 Module Name:	src
 Committed By:	mlelstv
 Date:		Tue May 31 09:22:11 UTC 2016

 Modified Files:
 	src/sys/dev/usb: xhci.c

 Log Message:
 Flush memory correctly during ring put.
 See PR 51199.

 From Sprow, ok skrll@.


 To generate a diff of this commit:
 cvs rdiff -u -r1.46 -r1.47 src/sys/dev/usb/xhci.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->closed
State-Changed-By: skrll@NetBSD.org
State-Changed-When: Sat, 04 Jun 2016 20:53:35 +0000
State-Changed-Why:
Fix committed


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.