From 4e843f6a6dfe9c24e533426b047fcc28c39121d4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 3 Dec 2024 11:54:53 +0100 Subject: [PATCH] 5.10-stable patches added patches: usb-dwc3-gadget-fix-checking-for-number-of-trbs-left.patch usb-dwc3-gadget-fix-looping-of-queued-sg-entries.patch --- queue-5.10/series | 2 + ...fix-checking-for-number-of-trbs-left.patch | 53 +++++++++++++++++++ ...get-fix-looping-of-queued-sg-entries.patch | 49 +++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 queue-5.10/usb-dwc3-gadget-fix-checking-for-number-of-trbs-left.patch create mode 100644 queue-5.10/usb-dwc3-gadget-fix-looping-of-queued-sg-entries.patch diff --git a/queue-5.10/series b/queue-5.10/series index 93cadc63072..1e1057d9115 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -272,3 +272,5 @@ alsa-hda-realtek-update-alc225-depop-procedure.patch alsa-hda-realtek-set-pcbeep-to-default-value-for-alc274.patch alsa-hda-realtek-fix-internal-speaker-and-mic-boost-of-infinix-y4-max.patch alsa-hda-realtek-apply-quirk-for-medion-e15433.patch +usb-dwc3-gadget-fix-checking-for-number-of-trbs-left.patch +usb-dwc3-gadget-fix-looping-of-queued-sg-entries.patch diff --git a/queue-5.10/usb-dwc3-gadget-fix-checking-for-number-of-trbs-left.patch b/queue-5.10/usb-dwc3-gadget-fix-checking-for-number-of-trbs-left.patch new file mode 100644 index 00000000000..24ae728f111 --- /dev/null +++ b/queue-5.10/usb-dwc3-gadget-fix-checking-for-number-of-trbs-left.patch @@ -0,0 +1,53 @@ +From 02a6982b0ccfcdc39e20016f5fc9a1b7826a6ee7 Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Thu, 14 Nov 2024 01:02:12 +0000 +Subject: usb: dwc3: gadget: Fix checking for number of TRBs left + +From: Thinh Nguyen + +commit 02a6982b0ccfcdc39e20016f5fc9a1b7826a6ee7 upstream. + +The check whether the TRB ring is full or empty in dwc3_calc_trbs_left() +is insufficient. It assumes there are active TRBs if there's any request +in the started_list. However, that's not the case for requests with a +large SG list. + +That is, if we have a single usb request that requires more TRBs than +the total TRBs in the TRB ring, the queued TRBs will be available when +all the TRBs in the ring are completed. But the request is only +partially completed and remains in the started_list. With the current +logic, the TRB ring is empty, but dwc3_calc_trbs_left() returns 0. + +Fix this by additionally checking for the request->num_trbs for active +TRB count. + +Cc: stable@vger.kernel.org +Fixes: 51f1954ad853 ("usb: dwc3: gadget: Fix dwc3_calc_trbs_left()") +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/708dc62b56b77da1f704cc2ae9b6ddb1f2dbef1f.1731545781.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/gadget.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -953,11 +953,14 @@ static u32 dwc3_calc_trbs_left(struct dw + * pending to be processed by the driver. + */ + if (dep->trb_enqueue == dep->trb_dequeue) { ++ struct dwc3_request *req; ++ + /* +- * If there is any request remained in the started_list at +- * this point, that means there is no TRB available. ++ * If there is any request remained in the started_list with ++ * active TRBs at this point, then there is no TRB available. + */ +- if (!list_empty(&dep->started_list)) ++ req = next_request(&dep->started_list); ++ if (req && req->num_trbs) + return 0; + + return DWC3_TRB_NUM - 1; diff --git a/queue-5.10/usb-dwc3-gadget-fix-looping-of-queued-sg-entries.patch b/queue-5.10/usb-dwc3-gadget-fix-looping-of-queued-sg-entries.patch new file mode 100644 index 00000000000..e3dfbefc379 --- /dev/null +++ b/queue-5.10/usb-dwc3-gadget-fix-looping-of-queued-sg-entries.patch @@ -0,0 +1,49 @@ +From b7fc65f5141c24785dc8c19249ca4efcf71b3524 Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Thu, 14 Nov 2024 01:02:18 +0000 +Subject: usb: dwc3: gadget: Fix looping of queued SG entries + +From: Thinh Nguyen + +commit b7fc65f5141c24785dc8c19249ca4efcf71b3524 upstream. + +The dwc3_request->num_queued_sgs is decremented on completion. If a +partially completed request is handled, then the +dwc3_request->num_queued_sgs no longer reflects the total number of +num_queued_sgs (it would be cleared). + +Correctly check the number of request SG entries remained to be prepare +and queued. Failure to do this may cause null pointer dereference when +accessing non-existent SG entry. + +Cc: stable@vger.kernel.org +Fixes: c96e6725db9d ("usb: dwc3: gadget: Correct the logic for queuing sgs") +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/d07a7c4aa0fcf746cdca0515150dbe5c52000af7.1731545781.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/gadget.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -1188,8 +1188,8 @@ static int dwc3_prepare_trbs_sg(struct d + struct scatterlist *s; + int i; + unsigned int length = req->request.length; +- unsigned int remaining = req->request.num_mapped_sgs +- - req->num_queued_sgs; ++ unsigned int remaining = req->num_pending_sgs; ++ unsigned int num_queued_sgs = req->request.num_mapped_sgs - remaining; + unsigned int num_trbs = req->num_trbs; + bool needs_extra_trb = dwc3_needs_extra_trb(dep, req); + +@@ -1197,7 +1197,7 @@ static int dwc3_prepare_trbs_sg(struct d + * If we resume preparing the request, then get the remaining length of + * the request and resume where we left off. + */ +- for_each_sg(req->request.sg, s, req->num_queued_sgs, i) ++ for_each_sg(req->request.sg, s, num_queued_sgs, i) + length -= sg_dma_len(s); + + for_each_sg(sg, s, remaining, i) { -- 2.47.3