lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240307-dwc3-gadget-complete-irq-v1-1-4fe9ac0ba2b7@pengutronix.de>
Date: Thu, 07 Mar 2024 16:22:03 +0100
From: Michael Grzeschik <m.grzeschik@...gutronix.de>
To: Thinh Nguyen <Thinh.Nguyen@...opsys.com>, 
 Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Cc: linux-usb@...r.kernel.org, linux-kernel@...r.kernel.org, 
 Michael Grzeschik <m.grzeschik@...gutronix.de>
Subject: [PATCH 1/3] usb: dwc3: gadget: reclaim the whole started list when
 request was missed

On EXDEV/Missed status interrupt, the handler has to stop the running
transfer and ensure that every request complete call will not run kick
on the current transfer. This is achieved by calling
dwc3_stop_active_transfer early before cleaning up the started request
list.

If the current transfer was stopped we can not keep all requests in the
hardware and have to reclaim them all. Since the requests could have
no_interrupt bit the cleanup on an stopped pipeline has to remove every
request and may not stop on the one that has the IOC bit set.

To ensure that the dwc3_gadget_ep_cleanup_completed_request will
iterate over every request in that case, we skip the stop condition
in reclaim_completed_trb if the current transfer was stopped by checking
for DWC3_EP_END_TRANSFER_PENDING bit set.

Signed-off-by: Michael Grzeschik <m.grzeschik@...gutronix.de>
---
 drivers/usb/dwc3/gadget.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 40c52dbc28d3b..b9fce7b1dcdec 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -3404,7 +3404,8 @@ static int dwc3_gadget_ep_reclaim_completed_trb(struct dwc3_ep *dep,
 	    DWC3_TRB_SIZE_TRBSTS(trb->size) == DWC3_TRBSTS_MISSED_ISOC)
 		return 1;
 
-	if ((trb->ctrl & DWC3_TRB_CTRL_IOC) ||
+	if (((trb->ctrl & DWC3_TRB_CTRL_IOC) &&
+		 !(dep->flags & DWC3_EP_END_TRANSFER_PENDING)) ||
 	    (trb->ctrl & DWC3_TRB_CTRL_LST))
 		return 1;
 
@@ -3568,6 +3569,9 @@ static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep,
 	struct dwc3		*dwc = dep->dwc;
 	bool			no_started_trb = true;
 
+	if (status == -EXDEV)
+		dwc3_stop_active_transfer(dep, true, true);
+
 	dwc3_gadget_ep_cleanup_completed_requests(dep, event, status);
 
 	if (dep->flags & DWC3_EP_END_TRANSFER_PENDING)
@@ -3578,7 +3582,7 @@ static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep,
 
 	if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
 		list_empty(&dep->started_list) &&
-		(list_empty(&dep->pending_list) || status == -EXDEV))
+		(list_empty(&dep->pending_list)))
 		dwc3_stop_active_transfer(dep, true, true);
 	else if (dwc3_gadget_ep_should_continue(dep))
 		if (__dwc3_gadget_kick_transfer(dep) == 0)

-- 
2.39.2


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ