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:
(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.