From patchwork Wed Oct 24 16:31:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 193912 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 330052C0089 for ; Thu, 25 Oct 2012 05:39:10 +1100 (EST) Received: from localhost ([::1]:37877 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TR3r3-00012Y-Ju for incoming@patchwork.ozlabs.org; Wed, 24 Oct 2012 12:30:53 -0400 Received: from eggs.gnu.org ([208.118.235.92]:37078) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TR3qD-00086O-8k for qemu-devel@nongnu.org; Wed, 24 Oct 2012 12:30:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TR3qB-0002Hj-V9 for qemu-devel@nongnu.org; Wed, 24 Oct 2012 12:30:01 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53573) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TR3qB-0002HX-LJ for qemu-devel@nongnu.org; Wed, 24 Oct 2012 12:29:59 -0400 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q9OGTwWK027720 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 24 Oct 2012 12:29:59 -0400 Received: from shalem.localdomain.com (vpn1-6-4.ams2.redhat.com [10.36.6.4]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q9OGTa9m024595; Wed, 24 Oct 2012 12:29:57 -0400 From: Hans de Goede To: Gerd Hoffmann Date: Wed, 24 Oct 2012 18:31:16 +0200 Message-Id: <1351096280-9518-14-git-send-email-hdegoede@redhat.com> In-Reply-To: <1351096280-9518-1-git-send-email-hdegoede@redhat.com> References: <1351096280-9518-1-git-send-email-hdegoede@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: Hans de Goede , qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH 13/17] uhci: Detect guest td re-use X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org A td can be reused by the guest in a different queue, before we notice the original queue has been unlinked. So search for tds by addr only, detect guest td reuse, and cancel the original queue, this is necessary to keep our packet ids unique. Signed-off-by: Hans de Goede --- hw/usb/hcd-uhci.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index 0984bee..c4f2f98 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -319,28 +319,18 @@ static void uhci_async_cancel_all(UHCIState *s) } } -static UHCIAsync *uhci_async_find_td(UHCIState *s, uint32_t td_addr, - UHCI_TD *td) +static UHCIAsync *uhci_async_find_td(UHCIState *s, uint32_t td_addr) { - uint32_t token = uhci_queue_token(td); UHCIQueue *queue; UHCIAsync *async; QTAILQ_FOREACH(queue, &s->queues, next) { - if (queue->token == token) { - break; - } - } - if (queue == NULL) { - return NULL; - } - - QTAILQ_FOREACH(async, &queue->asyncs, next) { - if (async->td_addr == td_addr) { - return async; + QTAILQ_FOREACH(async, &queue->asyncs, next) { + if (async->td_addr == td_addr) { + return async; + } } } - return NULL; } @@ -805,11 +795,21 @@ out: static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr, UHCI_TD *td, uint32_t td_addr, uint32_t *int_mask) { - UHCIAsync *async; int len = 0, max_len; bool spd; bool queuing = (q != NULL); uint8_t pid = td->token & 0xff; + UHCIAsync *async = uhci_async_find_td(s, td_addr); + + if (async) { + if (uhci_queue_verify(async->queue, qh_addr, td, td_addr, queuing)) { + assert(q == NULL || q == async->queue); + q = async->queue; + } else { + uhci_queue_free(async->queue, "guest re-used pending td"); + async = NULL; + } + } if (q == NULL) { q = uhci_queue_find(s, td); @@ -831,7 +831,6 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr, return TD_RESULT_NEXT_QH; } - async = uhci_async_find_td(s, td_addr, td); if (async) { /* Already submitted */ async->queue->valid = 32;