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: 94b037f2a451b3dc855f9f2c346e5049a361bd55 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;
 | 
			
		||||
    unsigned int max_psize;
 | 
			
		||||
    uint32_t state;
 | 
			
		||||
    uint32_t kick_active;
 | 
			
		||||
 | 
			
		||||
    /* streams */
 | 
			
		||||
    unsigned int max_pstreams;
 | 
			
		||||
@ -2131,6 +2132,9 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (epctx->kick_active) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    xhci_kick_epctx(epctx, streamid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2146,6 +2150,7 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
       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);
 | 
			
		||||
 | 
			
		||||
    epctx->kick_active++;
 | 
			
		||||
    while (1) {
 | 
			
		||||
        length = xhci_ring_chain_length(xhci, ring);
 | 
			
		||||
        if (length <= 0) {
 | 
			
		||||
@ -2253,6 +2259,7 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    epctx->kick_active--;
 | 
			
		||||
 | 
			
		||||
    ep = xhci_epid_to_usbep(epctx);
 | 
			
		||||
    if (ep) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user