FAILED: patch "[PATCH] usb: gadget: udc: renesas_usb3: Fix a race in" failed to apply to 4.9-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.9-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From e752dbc59e1241b13b8c4f7b6eb582862e7668fe Mon Sep 17 00:00:00 2001
From: Yoshihiro Shimoda <[email protected]>
Date: Mon, 24 May 2021 15:01:55 +0900
Subject: [PATCH] usb: gadget: udc: renesas_usb3: Fix a race in
usb3_start_pipen()
The usb3_start_pipen() is called by renesas_usb3_ep_queue() and usb3_request_done_pipen() so that usb3_start_pipen() is possible to cause a race when getting usb3_first_req like below:
renesas_usb3_ep_queue()
spin_lock_irqsave()
list_add_tail()
spin_unlock_irqrestore()
usb3_start_pipen()
usb3_first_req = usb3_get_request() --- [1]
--- interrupt ---
usb3_irq_dma_int()
usb3_request_done_pipen()
usb3_get_request()
usb3_start_pipen()
usb3_first_req = usb3_get_request()
...
(the req is possible to be finished in the interrupt)
The usb3_first_req [1] above may have been finished after the interrupt ended so that this driver caused to start a transfer wrongly. To fix this issue, getting/checking the usb3_first_req are under spin_lock_irqsave() in the same section.
drivers/usb/gadget/udc/renesas_usb3.c +3 -2
@@ -1488,7 +1488,7 @@ static void usb3_start_pipen(struct renesas_usb3_ep *usb3_ep, struct renesas_usb3_request *usb3_req) {struct renesas_usb3 *usb3 =usb3_ep_to_usb3 (usb3_ep); -struct renesas_usb3_request *usb3_req_first =usb3_get_request (usb3_ep); +struct renesas_usb3_request *usb3_req_first;unsigned long flags;int ret = -EAGAIN ;u32 enable_bits =0 ;
@@ -1496,7 +1496,8 @@ static void usb3_start_pipen(struct renesas_usb3_ep *usb3_ep,spin_lock_irqsave (&usb3->lock, flags);if (usb3_ep->halt || usb3_ep->started) goto out; -if (usb3_req != usb3_req_first) + usb3_req_first =__usb3_get_request (usb3_ep); +if (!usb3_req_first || usb3_req != usb3_req_first) goto out;if (usb3_pn_change (usb3, usb3_ep->num) <0 )