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-3-4fe9ac0ba2b7@pengutronix.de>
Date: Thu, 07 Mar 2024 16:22:05 +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 3/3] usb: dwc3: gadget: check the whole started queue for
 missed requests in complete

The function dwc3_gadget_endpoint_trbs_complete will be called with the
interrupt event. This event is only representing the interrupt reason of
the exact trb that had IOC enabled. In the current approach the function
dwc3_gadget_ep_cleanup_completed_requests will give back and complete
the requests with the corresponding trb status and therefor will
correctly return the missed requests that are already finished.

Since inbetween those complete functioncalls of the properly
finished and the missed trbs, a missed transfer could get new
trbs enqueued with the updatecmd, this will just lead to more missed
trbs.

To break the cascading scenario this patch is checking all trbs from the
started list for any trb that has the missed trb status before even
calling the complete handler but stopping the transfer instead.

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

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index f22b68a0b2dac..ca87f4d988d41 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -3563,6 +3563,21 @@ static void dwc3_gadget_endpoint_frame_from_event(struct dwc3_ep *dep,
 	dep->frame_number = event->parameters;
 }
 
+static int dwc3_gadget_ep_check_missed_requests(struct dwc3_ep *dep)
+{
+	struct dwc3_request	*req;
+	struct dwc3_request	*tmp;
+
+	list_for_each_entry_safe(req, tmp, &dep->started_list, list) {
+		struct dwc3_trb *trb = req->trb;
+
+		if (DWC3_TRB_SIZE_TRBSTS(trb->size) == DWC3_TRBSTS_MISSED_ISOC)
+			return -EXDEV;
+	}
+
+	return 0;
+}
+
 static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep,
 		const struct dwc3_event_depevt *event, int status)
 {
@@ -3584,7 +3599,7 @@ static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep,
 		transfer_in_flight = trb->ctrl & DWC3_TRB_CTRL_HWO;
 	}
 
-	if (status == -EXDEV || !transfer_in_flight)
+	if (status == -EXDEV || !transfer_in_flight || dwc3_gadget_ep_check_missed_requests(dep))
 		dwc3_stop_active_transfer(dep, true, true);
 
 	dwc3_gadget_ep_cleanup_completed_requests(dep, event, status);

-- 
2.39.2


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ