This is a note to let you know that I've just added the patch titled usb: dwc3: gadget: Prevent EP queuing while stopping transfers to the 5.10-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: usb-dwc3-gadget-prevent-ep-queuing-while-stopping-transfers.patch and it can be found in the queue-5.10 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From f09ddcfcb8c569675066337adac2ac205113471f Mon Sep 17 00:00:00 2001 From: Wesley Cheng <wcheng@xxxxxxxxxxxxxx> Date: Thu, 11 Mar 2021 15:59:02 -0800 Subject: usb: dwc3: gadget: Prevent EP queuing while stopping transfers From: Wesley Cheng <wcheng@xxxxxxxxxxxxxx> commit f09ddcfcb8c569675066337adac2ac205113471f upstream. In the situations where the DWC3 gadget stops active transfers, once calling the dwc3_gadget_giveback(), there is a chance where a function driver can queue a new USB request in between the time where the dwc3 lock has been released and re-aquired. This occurs after we've already issued an ENDXFER command. When the stop active transfers continues to remove USB requests from all dep lists, the newly added request will also be removed, while controller still has an active TRB for it. This can lead to the controller accessing an unmapped memory address. Fix this by ensuring parameters to prevent EP queuing are set before calling the stop active transfers API. Fixes: ae7e86108b12 ("usb: dwc3: Stop active transfers before halting the controller") Signed-off-by: Wesley Cheng <wcheng@xxxxxxxxxxxxxx> Link: https://lore.kernel.org/r/1615507142-23097-1-git-send-email-wcheng@xxxxxxxxxxxxxx Cc: stable <stable@xxxxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/usb/dwc3/gadget.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -783,8 +783,6 @@ static int __dwc3_gadget_ep_disable(stru trace_dwc3_gadget_ep_disable(dep); - dwc3_remove_requests(dwc, dep); - /* make sure HW endpoint isn't stalled */ if (dep->flags & DWC3_EP_STALL) __dwc3_gadget_ep_set_halt(dep, 0, false); @@ -803,6 +801,8 @@ static int __dwc3_gadget_ep_disable(stru dep->endpoint.desc = NULL; } + dwc3_remove_requests(dwc, dep); + return 0; } @@ -1617,7 +1617,7 @@ static int __dwc3_gadget_ep_queue(struct { struct dwc3 *dwc = dep->dwc; - if (!dep->endpoint.desc || !dwc->pullups_connected) { + if (!dep->endpoint.desc || !dwc->pullups_connected || !dwc->connected) { dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n", dep->name); return -ESHUTDOWN; @@ -2150,6 +2150,7 @@ static int dwc3_gadget_pullup(struct usb if (!is_on) { u32 count; + dwc->connected = false; /* * In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a * Section 4.1.8 Table 4-7, it states that for a device-initiated @@ -2174,7 +2175,6 @@ static int dwc3_gadget_pullup(struct usb dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) % dwc->ev_buf->length; } - dwc->connected = false; } else { __dwc3_gadget_start(dwc); } @@ -3267,8 +3267,6 @@ static void dwc3_gadget_reset_interrupt( { u32 reg; - dwc->connected = true; - /* * WORKAROUND: DWC3 revisions <1.88a have an issue which * would cause a missing Disconnect Event if there's a @@ -3308,6 +3306,7 @@ static void dwc3_gadget_reset_interrupt( * transfers." */ dwc3_stop_active_transfers(dwc); + dwc->connected = true; reg = dwc3_readl(dwc->regs, DWC3_DCTL); reg &= ~DWC3_DCTL_TSTCTRL_MASK; Patches currently in stable-queue which might be from wcheng@xxxxxxxxxxxxxx are queue-5.10/usb-dwc3-gadget-prevent-ep-queuing-while-stopping-transfers.patch queue-5.10/usb-dwc3-gadget-allow-runtime-suspend-if-udc-unbinded.patch