xhci: guard xhci_kick_epctx against recursive calls
Track xhci_kick_epctx processing being active in a variable. Check the
variable before calling xhci_kick_epctx from xhci_kick_ep. Add an
assert to make sure we don't call recursively into xhci_kick_epctx.
Cc: 1653384@bugs.launchpad.net
Fixes: 94b037f2a4
Reported-by: Fabian Lesniak <fabian@lesniak-it.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 1486035372-3621-1-git-send-email-kraxel@redhat.com
Message-id: 1485790607-31399-5-git-send-email-kraxel@redhat.com
This commit is contained in:
parent
ddb603ab6c
commit
96d87bdda3
@ -390,6 +390,7 @@ struct XHCIEPContext {
|
|||||||
dma_addr_t pctx;
|
dma_addr_t pctx;
|
||||||
unsigned int max_psize;
|
unsigned int max_psize;
|
||||||
uint32_t state;
|
uint32_t state;
|
||||||
|
uint32_t kick_active;
|
||||||
|
|
||||||
/* streams */
|
/* streams */
|
||||||
unsigned int max_pstreams;
|
unsigned int max_pstreams;
|
||||||
@ -2131,6 +2132,9 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (epctx->kick_active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
xhci_kick_epctx(epctx, streamid);
|
xhci_kick_epctx(epctx, streamid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2146,6 +2150,7 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
trace_usb_xhci_ep_kick(epctx->slotid, epctx->epid, streamid);
|
trace_usb_xhci_ep_kick(epctx->slotid, epctx->epid, streamid);
|
||||||
|
assert(!epctx->kick_active);
|
||||||
|
|
||||||
/* If the device has been detached, but the guest has not noticed this
|
/* If the device has been detached, but the guest has not noticed this
|
||||||
yet the 2 above checks will succeed, but we must NOT continue */
|
yet the 2 above checks will succeed, but we must NOT continue */
|
||||||
@ -2217,6 +2222,7 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
|
|||||||
}
|
}
|
||||||
assert(ring->dequeue != 0);
|
assert(ring->dequeue != 0);
|
||||||
|
|
||||||
|
epctx->kick_active++;
|
||||||
while (1) {
|
while (1) {
|
||||||
length = xhci_ring_chain_length(xhci, ring);
|
length = xhci_ring_chain_length(xhci, ring);
|
||||||
if (length <= 0) {
|
if (length <= 0) {
|
||||||
@ -2253,6 +2259,7 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
epctx->kick_active--;
|
||||||
|
|
||||||
ep = xhci_epid_to_usbep(epctx);
|
ep = xhci_epid_to_usbep(epctx);
|
||||||
if (ep) {
|
if (ep) {
|
||||||
|
Loading…
Reference in New Issue
Block a user