From: Michael Brown Date: Mon, 19 Feb 2018 18:59:45 +0000 (+0000) Subject: [xhci] Consume event TRB before reporting completion to USB core X-Git-Tag: v1.20.1~118 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8dbb73a779e5b11ee2b65f9d2af6dd9bd8998608;p=thirdparty%2Fipxe.git [xhci] Consume event TRB before reporting completion to USB core Reporting a completion via usb_complete() will pass control outside the scope of xhci.c, and could potentially result in a further call to xhci_event_poll() before returning from usb_complete(). Since we currently update the event consumer counter only after calling usb_complete(), this can result in duplicate completions and consequent corruption of the submission TRB ring structures. Fix by updating the event ring consumer counter before passing control to usb_complete(). Reported-by: Andreas Hammarskjöld Tested-by: Andreas Hammarskjöld Signed-off-by: Michael Brown --- diff --git a/src/drivers/usb/xhci.c b/src/drivers/usb/xhci.c index 8bf3ca776..ecf8bf4d5 100644 --- a/src/drivers/usb/xhci.c +++ b/src/drivers/usb/xhci.c @@ -1711,6 +1711,9 @@ static void xhci_event_poll ( struct xhci_device *xhci ) { ( event->cons >> shift ) ) & XHCI_TRB_C ) ) break; + /* Consume this TRB */ + event->cons++; + /* Handle TRB */ type = ( trb->common.type & XHCI_TRB_TYPE_MASK ); switch ( type ) { @@ -1733,14 +1736,11 @@ static void xhci_event_poll ( struct xhci_device *xhci ) { default: DBGC ( xhci, "XHCI %s unrecognised event %#x\n:", - xhci->name, event->cons ); + xhci->name, ( event->cons - 1 ) ); DBGC_HDA ( xhci, virt_to_phys ( trb ), trb, sizeof ( *trb ) ); break; } - - /* Consume this TRB */ - event->cons++; } /* Update dequeue pointer if applicable */