From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1032344Ab2I1U7E (ORCPT ); Fri, 28 Sep 2012 16:59:04 -0400 Received: from out1-smtp.messagingengine.com ([66.111.4.25]:49586 "EHLO out1-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1422943Ab2I1Ur7 (ORCPT ); Fri, 28 Sep 2012 16:47:59 -0400 X-Sasl-enc: 70k7IKxDc5qzg3uL3YsEo3mkAReTmSCFaS8aoj1LY4DH 1348865278 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Greg Kroah-Hartman , alan@lxorguk.ukuu.org.uk, Pavankumar Kondeti , Alan Stern Subject: [ 073/127] EHCI: Update qTD next pointer in QH overlay region during unlink Date: Fri, 28 Sep 2012 13:34:06 -0700 Message-Id: <20120928203054.421141164@linuxfoundation.org> X-Mailer: git-send-email 1.7.12.1.428.g652398a In-Reply-To: <20120928203045.835238916@linuxfoundation.org> References: <20120928203045.835238916@linuxfoundation.org> User-Agent: quilt/0.60-2.1.2 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.0-stable review patch. If anyone has any objections, please let me know. ------------------ From: Pavankumar Kondeti commit 3d037774b42ed677f699b1dce7d548d55f4e4c2b upstream. There is a possibility of QH overlay region having reference to a stale qTD pointer during unlink. Consider an endpoint having two pending qTD before unlink process begins. The endpoint's QH queue looks like this. qTD1 --> qTD2 --> Dummy To unlink qTD2, QH is removed from asynchronous list and Asynchronous Advance Doorbell is programmed. The qTD1's next qTD pointer is set to qTD2'2 next qTD pointer and qTD2 is retired upon controller's doorbell interrupt. If QH's current qTD pointer points to qTD1, transfer overlay region still have reference to qTD2. But qtD2 is just unlinked and freed. This may cause EHCI system error. Fix this by updating qTD next pointer in QH overlay region with the qTD next pointer of the current qTD. Signed-off-by: Pavankumar Kondeti Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-q.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -130,9 +130,17 @@ qh_refresh (struct ehci_hcd *ehci, struc else { qtd = list_entry (qh->qtd_list.next, struct ehci_qtd, qtd_list); - /* first qtd may already be partially processed */ - if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) + /* + * first qtd may already be partially processed. + * If we come here during unlink, the QH overlay region + * might have reference to the just unlinked qtd. The + * qtd is updated in qh_completions(). Update the QH + * overlay here. + */ + if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) { + qh->hw->hw_qtd_next = qtd->hw_next; qtd = NULL; + } } if (qtd)