XHCI: Rearrange RemoveEndpointForPipe to fix crashes and deadlocks.

* As we were clearing out the endpoint structures before detaching
   the xhci_endpoint from the Pipe, it was possible for SubmitRequest
   to be called while we were being destroyed and then use the half-
   torn-down endpoint, leading to crashes. Instead, we now call
   SetControllerCookie first, so that SubmitRequest will thus
   fail.

 * Lock the endpoint after calling StopEndpoint, for the same
   reasons that this is now the order of operations in CancelQueuedTransfers.

Probably fixes #15710, and maybe other issues.
This commit is contained in:
Augustin Cavalier 2020-02-17 14:33:54 -05:00
parent 41e5cf016e
commit 357adccf9f

View File

@ -1765,14 +1765,15 @@ XHCI::_RemoveEndpointForPipe(Pipe *pipe)
if (endpoint == NULL || endpoint->trbs == NULL)
return B_NO_INIT;
xhci_device *device = endpoint->device;
pipe->SetControllerCookie(NULL);
if (endpoint->id > 0) {
mutex_lock(&endpoint->lock);
xhci_device *device = endpoint->device;
uint8 epNumber = endpoint->id + 1;
StopEndpoint(true, epNumber, device->slot);
mutex_lock(&endpoint->lock);
// See comment in CancelQueuedTransfers.
xhci_td* td;
while ((td = endpoint->td_head) != NULL) {
@ -1791,7 +1792,6 @@ XHCI::_RemoveEndpointForPipe(Pipe *pipe)
else
EvaluateContext(device->input_ctx_addr, device->slot);
}
pipe->SetControllerCookie(NULL);
return B_OK;
}