linux-usb.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH for 4.14] xhci: add xhci_get_virt_ep() helper
@ 2021-07-26  9:11 Schmid, Carsten
  2021-07-26  9:19 ` Greg KH (gregkh@linuxfoundation.org)
  2021-07-26 10:05 ` Greg KH (gregkh@linuxfoundation.org)
  0 siblings, 2 replies; 10+ messages in thread
From: Schmid, Carsten @ 2021-07-26  9:11 UTC (permalink / raw)
  To: Greg KH (gregkh@linuxfoundation.org); +Cc: USB list, Mathias Nyman

From 804d2db49c8db94ff4652f13826a2c74dac33941 Mon Sep 17 00:00:00 2001
From: Mathias Nyman <mathias.nyman@linux.intel.com>
Date: Fri, 29 Jan 2021 15:00:22 +0200
Subject: [PATCH] xhci: add xhci_get_virt_ep() helper

[commit b1adc42d440df3233255e313a45ab7e9b2b74096 upstream]

In several event handlers we need to find the right endpoint
structure from slot_id and ep_index in the event.

Add a helper for this, check that slot_id and ep_index are valid.

Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20210129130044.206855-6-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Carsten Schmid <carsten_schmid@mentor.com>
---
Rationale:
From mail thread " Possible race in 4.14 xhci stack"
Searched for fix that Mathias Nyman mentioned.
Fix didn't apply on 4.14 directly, needed some small adaption.
Result provided here.
@Greg: Patch is for 4.14, not tested if applies on other kernels.
---
 drivers/usb/host/xhci-ring.c | 58 ++++++++++++++++++++++++++++--------
 drivers/usb/host/xhci.h      |  3 +-
 2 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 9828c1eff9a5..ce5deac93418 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -444,6 +444,26 @@ static void ring_doorbell_for_active_rings(struct xhci_hcd *xhci,
 }
 }

+static struct xhci_virt_ep *xhci_get_virt_ep(struct xhci_hcd *xhci,
+     unsigned int slot_id,
+     unsigned int ep_index)
+{
+if (slot_id == 0 || slot_id >= MAX_HC_SLOTS) {
+xhci_warn(xhci, "Invalid slot_id %u\n", slot_id);
+return NULL;
+}
+if (ep_index >= EP_CTX_PER_DEV) {
+xhci_warn(xhci, "Invalid endpoint index %u\n", ep_index);
+return NULL;
+}
+if (!xhci->devs[slot_id]) {
+xhci_warn(xhci, "No xhci virt device for slot_id %u\n", slot_id);
+return NULL;
+}
+
+return &xhci->devs[slot_id]->eps[ep_index];
+}
+
 /* Get the right ring for the given slot_id, ep_index and stream_id.
  * If the endpoint supports streams, boundary check the URB's stream ID.
  * If the endpoint doesn't support streams, return the singular endpoint ring.
@@ -454,7 +474,10 @@ struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci,
 {
 struct xhci_virt_ep *ep;

-ep = &xhci->devs[slot_id]->eps[ep_index];
+ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
+if (!ep)
+return NULL;
+
 /* Common case: no streams */
 if (!(ep->ep_state & EP_HAS_STREAMS))
 return ep->ring;
@@ -724,11 +747,14 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
 memset(&deq_state, 0, sizeof(deq_state));
 ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));

+ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
+if (!ep)
+return;
+
 vdev = xhci->devs[slot_id];
 ep_ctx = xhci_get_ep_ctx(xhci, vdev->out_ctx, ep_index);
 trace_xhci_handle_cmd_stop_ep(ep_ctx);

-ep = &xhci->devs[slot_id]->eps[ep_index];
 last_unlinked_td = list_last_entry(&ep->cancelled_td_list,
 struct xhci_td, cancelled_td_list);

@@ -1052,9 +1078,11 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,

 ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
 stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb->generic.field[2]));
-dev = xhci->devs[slot_id];
-ep = &dev->eps[ep_index];
+ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
+if (!ep)
+return;

+dev = xhci->devs[slot_id];
 ep_ring = xhci_stream_id_to_ring(dev, ep_index, stream_id);
 if (!ep_ring) {
 xhci_warn(xhci, "WARN Set TR deq ptr command for freed stream ID %u\n",
@@ -1127,9 +1155,9 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
 }

 cleanup:
-dev->eps[ep_index].ep_state &= ~SET_DEQ_PENDING;
-dev->eps[ep_index].queued_deq_seg = NULL;
-dev->eps[ep_index].queued_deq_ptr = NULL;
+ep->ep_state &= ~SET_DEQ_PENDING;
+ep->queued_deq_seg = NULL;
+ep->queued_deq_ptr = NULL;
 /* Restart any rings with pending URBs */
 ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
 }
@@ -1138,10 +1166,15 @@ static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
 union xhci_trb *trb, u32 cmd_comp_code)
 {
 struct xhci_virt_device *vdev;
+struct xhci_virt_ep *ep;
 struct xhci_ep_ctx *ep_ctx;
 unsigned int ep_index;

 ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
+ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
+if (!ep)
+return;
+
 vdev = xhci->devs[slot_id];
 ep_ctx = xhci_get_ep_ctx(xhci, vdev->out_ctx, ep_index);
 trace_xhci_handle_cmd_reset_ep(ep_ctx);
@@ -1171,7 +1204,7 @@ static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
 xhci_ring_cmd_db(xhci);
 } else {
 /* Clear our internal halted state */
-xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_HALTED;
+ep->ep_state &= ~EP_HALTED;
 }
 }

@@ -2347,14 +2380,13 @@ static int handle_tx_event(struct xhci_hcd *xhci,
 trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len));
 ep_trb_dma = le64_to_cpu(event->buffer);

-xdev = xhci->devs[slot_id];
-if (!xdev) {
-xhci_err(xhci, "ERROR Transfer event pointed to bad slot %u\n",
- slot_id);
+ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
+if (!ep) {
+xhci_err(xhci, "ERROR Invalid Transfer event\n");
 goto err_out;
 }

-ep = &xdev->eps[ep_index];
+xdev = xhci->devs[slot_id];
 ep_ring = xhci_dma_to_transfer_ring(ep, ep_trb_dma);
 ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);

diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 723cb31f592b..2b818dd12a8d 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -991,6 +991,7 @@ struct xhci_interval_bw_table {
 unsigned intss_bw_out;
 };

+#define EP_CTX_PER_DEV31

 struct xhci_virt_device {
 struct usb_device*udev;
@@ -1005,7 +1006,7 @@ struct xhci_virt_device {
 struct xhci_container_ctx       *out_ctx;
 /* Used for addressing devices and configuration changes */
 struct xhci_container_ctx       *in_ctx;
-struct xhci_virt_epeps[31];
+struct xhci_virt_epeps[EP_CTX_PER_DEV];
 u8fake_port;
 u8real_port;
 struct xhci_interval_bw_table*bw_table;
--
2.17.1
-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH for 4.14] xhci: add xhci_get_virt_ep() helper
  2021-07-26  9:11 [PATCH for 4.14] xhci: add xhci_get_virt_ep() helper Schmid, Carsten
@ 2021-07-26  9:19 ` Greg KH (gregkh@linuxfoundation.org)
  2021-07-26  9:32   ` Schmid, Carsten
  2021-07-26 10:05 ` Greg KH (gregkh@linuxfoundation.org)
  1 sibling, 1 reply; 10+ messages in thread
From: Greg KH (gregkh@linuxfoundation.org) @ 2021-07-26  9:19 UTC (permalink / raw)
  To: Schmid, Carsten; +Cc: USB list, Mathias Nyman

On Mon, Jul 26, 2021 at 09:11:30AM +0000, Schmid, Carsten wrote:
> From 804d2db49c8db94ff4652f13826a2c74dac33941 Mon Sep 17 00:00:00 2001
> From: Mathias Nyman <mathias.nyman@linux.intel.com>
> Date: Fri, 29 Jan 2021 15:00:22 +0200
> Subject: [PATCH] xhci: add xhci_get_virt_ep() helper
> 
> [commit b1adc42d440df3233255e313a45ab7e9b2b74096 upstream]
> 
> In several event handlers we need to find the right endpoint
> structure from slot_id and ep_index in the event.
> 
> Add a helper for this, check that slot_id and ep_index are valid.
> 
> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
> Link: https://lore.kernel.org/r/20210129130044.206855-6-mathias.nyman@linux.intel.com
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Carsten Schmid <carsten_schmid@mentor.com>
> ---
> Rationale:
> From mail thread " Possible race in 4.14 xhci stack"
> Searched for fix that Mathias Nyman mentioned.
> Fix didn't apply on 4.14 directly, needed some small adaption.
> Result provided here.
> @Greg: Patch is for 4.14, not tested if applies on other kernels.

I can not just apply this to 4.14, it also needs to go into 4.19 and 5.4
and 5.10 as you can not upgrade to a newer kernel and get a regression,
right?

Can you also provide patches for those kernels as well so that I can
take this one?

And also, you forgot to cc: the stable@vger.kernel.org mailing list :(

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH for 4.14] xhci: add xhci_get_virt_ep() helper
  2021-07-26  9:19 ` Greg KH (gregkh@linuxfoundation.org)
@ 2021-07-26  9:32   ` Schmid, Carsten
  0 siblings, 0 replies; 10+ messages in thread
From: Schmid, Carsten @ 2021-07-26  9:32 UTC (permalink / raw)
  To: Greg KH (gregkh@linuxfoundation.org); +Cc: USB list, Mathias Nyman

Hi Greg,

> -----Original Message-----
> From: Greg KH (gregkh@linuxfoundation.org) <gregkh@linuxfoundation.org>
> Sent: Montag, 26. Juli 2021 11:20
>
>> @Greg: Patch is for 4.14, not tested if applies on other kernels.
> I can not just apply this to 4.14, it also needs to go into 4.19 and 5.4 and 5.10 as you can not upgrade to a newer kernel and get a regression, right?
Aaah, didn't have that in mind. Sorry.

> Can you also provide patches for those kernels as well so that I can take this one?
I'll try to do so 😊

> And also, you forgot to cc: the stable@vger.kernel.org mailing list :(
I really need to have more practice 😉

thanks,
Carsten
-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH for 4.14] xhci: add xhci_get_virt_ep() helper
  2021-07-26  9:11 [PATCH for 4.14] xhci: add xhci_get_virt_ep() helper Schmid, Carsten
  2021-07-26  9:19 ` Greg KH (gregkh@linuxfoundation.org)
@ 2021-07-26 10:05 ` Greg KH (gregkh@linuxfoundation.org)
  2021-07-26 10:13   ` Schmid, Carsten
  1 sibling, 1 reply; 10+ messages in thread
From: Greg KH (gregkh@linuxfoundation.org) @ 2021-07-26 10:05 UTC (permalink / raw)
  To: Schmid, Carsten; +Cc: USB list, Mathias Nyman

On Mon, Jul 26, 2021 at 09:11:30AM +0000, Schmid, Carsten wrote:
> From 804d2db49c8db94ff4652f13826a2c74dac33941 Mon Sep 17 00:00:00 2001
> From: Mathias Nyman <mathias.nyman@linux.intel.com>
> Date: Fri, 29 Jan 2021 15:00:22 +0200
> Subject: [PATCH] xhci: add xhci_get_virt_ep() helper
> 
> [commit b1adc42d440df3233255e313a45ab7e9b2b74096 upstream]
> 
> In several event handlers we need to find the right endpoint
> structure from slot_id and ep_index in the event.
> 
> Add a helper for this, check that slot_id and ep_index are valid.
> 
> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
> Link: https://lore.kernel.org/r/20210129130044.206855-6-mathias.nyman@linux.intel.com
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Carsten Schmid <carsten_schmid@mentor.com>
> ---
> Rationale:
> From mail thread " Possible race in 4.14 xhci stack"
> Searched for fix that Mathias Nyman mentioned.
> Fix didn't apply on 4.14 directly, needed some small adaption.
> Result provided here.
> @Greg: Patch is for 4.14, not tested if applies on other kernels.
> ---
>  drivers/usb/host/xhci-ring.c | 58 ++++++++++++++++++++++++++++--------
>  drivers/usb/host/xhci.h      |  3 +-
>  2 files changed, 47 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
> index 9828c1eff9a5..ce5deac93418 100644
> --- a/drivers/usb/host/xhci-ring.c
> +++ b/drivers/usb/host/xhci-ring.c
> @@ -444,6 +444,26 @@ static void ring_doorbell_for_active_rings(struct xhci_hcd *xhci,
>  }
>  }
> 
> +static struct xhci_virt_ep *xhci_get_virt_ep(struct xhci_hcd *xhci,
> +     unsigned int slot_id,
> +     unsigned int ep_index)
> +{
> +if (slot_id == 0 || slot_id >= MAX_HC_SLOTS) {
> +xhci_warn(xhci, "Invalid slot_id %u\n", slot_id);
> +return NULL;
> +}
> +if (ep_index >= EP_CTX_PER_DEV) {
> +xhci_warn(xhci, "Invalid endpoint index %u\n", ep_index);
> +return NULL;
> +}
> +if (!xhci->devs[slot_id]) {
> +xhci_warn(xhci, "No xhci virt device for slot_id %u\n", slot_id);
> +return NULL;
> +}
> +
> +return &xhci->devs[slot_id]->eps[ep_index];
> +}
> +

Also, the patch is corrupted and can not be applied, even if I wanted to
:(

So can you fix that up when you resend all of the other versions too?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH for 4.14] xhci: add xhci_get_virt_ep() helper
  2021-07-26 10:05 ` Greg KH (gregkh@linuxfoundation.org)
@ 2021-07-26 10:13   ` Schmid, Carsten
  2021-07-26 10:16     ` Greg KH (gregkh@linuxfoundation.org)
  0 siblings, 1 reply; 10+ messages in thread
From: Schmid, Carsten @ 2021-07-26 10:13 UTC (permalink / raw)
  To: Greg KH (gregkh@linuxfoundation.org), Merz, Thomas
  Cc: USB list, Mathias Nyman, Hardinge, Charles

Hi Greg,

> Also, the patch is corrupted and can not be applied, even if I wanted to :(
> So can you fix that up when you resend all of the other versions too?

I've seen that and already sent a mail to IT regarding this.
We had to "upgrade" to O365 Outlook, and I selected "plain text" to send but ....
Still fighting with that.

May I attach the patches as a file, generated with "git format-patch" meanwhile?
I fear that I'm not allowed to use "git send-mail".

Thanks,
Carsten
-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH for 4.14] xhci: add xhci_get_virt_ep() helper
  2021-07-26 10:13   ` Schmid, Carsten
@ 2021-07-26 10:16     ` Greg KH (gregkh@linuxfoundation.org)
  2021-07-26 12:22       ` Schmid, Carsten
  0 siblings, 1 reply; 10+ messages in thread
From: Greg KH (gregkh@linuxfoundation.org) @ 2021-07-26 10:16 UTC (permalink / raw)
  To: Schmid, Carsten; +Cc: Merz, Thomas, USB list, Mathias Nyman, Hardinge, Charles

On Mon, Jul 26, 2021 at 10:13:35AM +0000, Schmid, Carsten wrote:
> Hi Greg,
> 
> > Also, the patch is corrupted and can not be applied, even if I wanted to :(
> > So can you fix that up when you resend all of the other versions too?
> 
> I've seen that and already sent a mail to IT regarding this.
> We had to "upgrade" to O365 Outlook, and I selected "plain text" to send but ....
> Still fighting with that.
> 
> May I attach the patches as a file, generated with "git format-patch" meanwhile?
> I fear that I'm not allowed to use "git send-mail".

For backports for the stable tree, yes, I can handle attachments just
fine, you are not the only company with that problem :)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH for 4.14] xhci: add xhci_get_virt_ep() helper
  2021-07-26 10:16     ` Greg KH (gregkh@linuxfoundation.org)
@ 2021-07-26 12:22       ` Schmid, Carsten
  2021-07-26 12:26         ` Felipe Balbi
  2021-07-26 12:59         ` Greg KH (gregkh@linuxfoundation.org)
  0 siblings, 2 replies; 10+ messages in thread
From: Schmid, Carsten @ 2021-07-26 12:22 UTC (permalink / raw)
  To: Greg KH (gregkh@linuxfoundation.org); +Cc: USB list, Mathias Nyman, stable

[-- Attachment #1: Type: text/plain, Size: 834 bytes --]

Hi Greg,

>>
>> May I attach the patches as a file, generated with "git format-patch" meanwhile?
>> I fear that I'm not allowed to use "git send-mail".
>
> For backports for the stable tree, yes, I can handle attachments just fine, you are not the only company with that problem :)
>
please find the patches attached.
0001-xhci-add-xhci_get_virt_sp-helper.patch.4 for 4.14 and 4.19
0001-xhci-add-xhci_get_virt_sp-helper.patch.5 for 5.4 and 5.10

Applied and compiled, not tested.
Added Cc: stable@vger.kernel.org in both patches.

Thanks,
Carsten
-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

[-- Attachment #2: 0001-xhci-add-xhci_get_virt_ep-helper.patch.4 --]
[-- Type: application/octet-stream, Size: 5993 bytes --]

From 849ad03a1e77eb123f5d8ddedbfcb08c8afdb77d Mon Sep 17 00:00:00 2001
From: Mathias Nyman <mathias.nyman@linux.intel.com>
Date: Fri, 29 Jan 2021 15:00:22 +0200
Subject: [PATCH] xhci: add xhci_get_virt_ep() helper

[commit b1adc42d440df3233255e313a45ab7e9b2b74096 upstream]

In several event handlers we need to find the right endpoint
structure from slot_id and ep_index in the event.

Add a helper for this, check that slot_id and ep_index are valid.

Cc: stable@vger.kernel.org
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20210129130044.206855-6-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Carsten Schmid <carsten_schmid@mentor.com>
---
 drivers/usb/host/xhci-ring.c | 58 ++++++++++++++++++++++++++++--------
 drivers/usb/host/xhci.h      |  3 +-
 2 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 748d4c69cb28..420ad7dc4fe8 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -444,6 +444,26 @@ static void ring_doorbell_for_active_rings(struct xhci_hcd *xhci,
 	}
 }
 
+static struct xhci_virt_ep *xhci_get_virt_ep(struct xhci_hcd *xhci,
+					     unsigned int slot_id,
+					     unsigned int ep_index)
+{
+	if (slot_id == 0 || slot_id >= MAX_HC_SLOTS) {
+		xhci_warn(xhci, "Invalid slot_id %u\n", slot_id);
+		return NULL;
+	}
+	if (ep_index >= EP_CTX_PER_DEV) {
+		xhci_warn(xhci, "Invalid endpoint index %u\n", ep_index);
+		return NULL;
+	}
+	if (!xhci->devs[slot_id]) {
+		xhci_warn(xhci, "No xhci virt device for slot_id %u\n", slot_id);
+		return NULL;
+	}
+
+	return &xhci->devs[slot_id]->eps[ep_index];
+}
+
 /* Get the right ring for the given slot_id, ep_index and stream_id.
  * If the endpoint supports streams, boundary check the URB's stream ID.
  * If the endpoint doesn't support streams, return the singular endpoint ring.
@@ -454,7 +474,10 @@ struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci,
 {
 	struct xhci_virt_ep *ep;
 
-	ep = &xhci->devs[slot_id]->eps[ep_index];
+	ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
+	if (!ep)
+		return NULL;
+
 	/* Common case: no streams */
 	if (!(ep->ep_state & EP_HAS_STREAMS))
 		return ep->ring;
@@ -729,11 +752,14 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
 	memset(&deq_state, 0, sizeof(deq_state));
 	ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
 
+	ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
+	if (!ep)
+		return;
+
 	vdev = xhci->devs[slot_id];
 	ep_ctx = xhci_get_ep_ctx(xhci, vdev->out_ctx, ep_index);
 	trace_xhci_handle_cmd_stop_ep(ep_ctx);
 
-	ep = &xhci->devs[slot_id]->eps[ep_index];
 	last_unlinked_td = list_last_entry(&ep->cancelled_td_list,
 			struct xhci_td, cancelled_td_list);
 
@@ -1057,9 +1083,11 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
 
 	ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
 	stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb->generic.field[2]));
-	dev = xhci->devs[slot_id];
-	ep = &dev->eps[ep_index];
+	ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
+	if (!ep)
+		return;
 
+	dev = xhci->devs[slot_id];
 	ep_ring = xhci_stream_id_to_ring(dev, ep_index, stream_id);
 	if (!ep_ring) {
 		xhci_warn(xhci, "WARN Set TR deq ptr command for freed stream ID %u\n",
@@ -1132,9 +1160,9 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
 	}
 
 cleanup:
-	dev->eps[ep_index].ep_state &= ~SET_DEQ_PENDING;
-	dev->eps[ep_index].queued_deq_seg = NULL;
-	dev->eps[ep_index].queued_deq_ptr = NULL;
+	ep->ep_state &= ~SET_DEQ_PENDING;
+	ep->queued_deq_seg = NULL;
+	ep->queued_deq_ptr = NULL;
 	/* Restart any rings with pending URBs */
 	ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
 }
@@ -1143,10 +1171,15 @@ static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
 		union xhci_trb *trb, u32 cmd_comp_code)
 {
 	struct xhci_virt_device *vdev;
+	struct xhci_virt_ep *ep;
 	struct xhci_ep_ctx *ep_ctx;
 	unsigned int ep_index;
 
 	ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
+	ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
+	if (!ep)
+		return;
+
 	vdev = xhci->devs[slot_id];
 	ep_ctx = xhci_get_ep_ctx(xhci, vdev->out_ctx, ep_index);
 	trace_xhci_handle_cmd_reset_ep(ep_ctx);
@@ -1176,7 +1209,7 @@ static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
 		xhci_ring_cmd_db(xhci);
 	} else {
 		/* Clear our internal halted state */
-		xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_HALTED;
+		ep->ep_state &= ~EP_HALTED;
 	}
 }
 
@@ -2352,14 +2385,13 @@ static int handle_tx_event(struct xhci_hcd *xhci,
 	trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len));
 	ep_trb_dma = le64_to_cpu(event->buffer);
 
-	xdev = xhci->devs[slot_id];
-	if (!xdev) {
-		xhci_err(xhci, "ERROR Transfer event pointed to bad slot %u\n",
-			 slot_id);
+	ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
+	if (!ep) {
+		xhci_err(xhci, "ERROR Invalid Transfer event\n");
 		goto err_out;
 	}
 
-	ep = &xdev->eps[ep_index];
+	xdev = xhci->devs[slot_id];
 	ep_ring = xhci_dma_to_transfer_ring(ep, ep_trb_dma);
 	ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
 
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 8b52a7773bc8..300506de0c7a 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -991,6 +991,7 @@ struct xhci_interval_bw_table {
 	unsigned int		ss_bw_out;
 };
 
+#define EP_CTX_PER_DEV		31
 
 struct xhci_virt_device {
 	struct usb_device		*udev;
@@ -1005,7 +1006,7 @@ struct xhci_virt_device {
 	struct xhci_container_ctx       *out_ctx;
 	/* Used for addressing devices and configuration changes */
 	struct xhci_container_ctx       *in_ctx;
-	struct xhci_virt_ep		eps[31];
+	struct xhci_virt_ep		eps[EP_CTX_PER_DEV];
 	u8				fake_port;
 	u8				real_port;
 	struct xhci_interval_bw_table	*bw_table;
-- 
2.17.1


[-- Attachment #3: 0001-xhci-add-xhci_get_virt_ep-helper.patch.5 --]
[-- Type: application/octet-stream, Size: 6090 bytes --]

From c57ecf1cd2fc7d4c35646f63f1cca6e52476664e Mon Sep 17 00:00:00 2001
From: Mathias Nyman <mathias.nyman@linux.intel.com>
Date: Fri, 29 Jan 2021 15:00:22 +0200
Subject: [PATCH] xhci: add xhci_get_virt_ep() helper

[commit b1adc42d440df3233255e313a45ab7e9b2b74096 upstream]

In several event handlers we need to find the right endpoint
structure from slot_id and ep_index in the event.

Add a helper for this, check that slot_id and ep_index are valid.

Cc: stable@vger.kernel.org
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20210129130044.206855-6-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Carsten Schmid <carsten_schmid@mentor.com>
---
 drivers/usb/host/xhci-ring.c | 58 ++++++++++++++++++++++++++++--------
 drivers/usb/host/xhci.h      |  3 +-
 2 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index f6b5010deb73..1228b3d92db0 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -440,6 +440,26 @@ void xhci_ring_doorbell_for_active_rings(struct xhci_hcd *xhci,
 	ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
 }
 
+static struct xhci_virt_ep *xhci_get_virt_ep(struct xhci_hcd *xhci,
+					     unsigned int slot_id,
+					     unsigned int ep_index)
+{
+	if (slot_id == 0 || slot_id >= MAX_HC_SLOTS) {
+		xhci_warn(xhci, "Invalid slot_id %u\n", slot_id);
+		return NULL;
+	}
+	if (ep_index >= EP_CTX_PER_DEV) {
+		xhci_warn(xhci, "Invalid endpoint index %u\n", ep_index);
+		return NULL;
+	}
+	if (!xhci->devs[slot_id]) {
+		xhci_warn(xhci, "No xhci virt device for slot_id %u\n", slot_id);
+		return NULL;
+	}
+
+	return &xhci->devs[slot_id]->eps[ep_index];
+}
+
 /* Get the right ring for the given slot_id, ep_index and stream_id.
  * If the endpoint supports streams, boundary check the URB's stream ID.
  * If the endpoint doesn't support streams, return the singular endpoint ring.
@@ -450,7 +470,10 @@ struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci,
 {
 	struct xhci_virt_ep *ep;
 
-	ep = &xhci->devs[slot_id]->eps[ep_index];
+	ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
+	if (!ep)
+		return NULL;
+
 	/* Common case: no streams */
 	if (!(ep->ep_state & EP_HAS_STREAMS))
 		return ep->ring;
@@ -743,11 +766,14 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
 	memset(&deq_state, 0, sizeof(deq_state));
 	ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
 
+	ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
+	if (!ep)
+		return;
+
 	vdev = xhci->devs[slot_id];
 	ep_ctx = xhci_get_ep_ctx(xhci, vdev->out_ctx, ep_index);
 	trace_xhci_handle_cmd_stop_ep(ep_ctx);
 
-	ep = &xhci->devs[slot_id]->eps[ep_index];
 	last_unlinked_td = list_last_entry(&ep->cancelled_td_list,
 			struct xhci_td, cancelled_td_list);
 
@@ -1068,9 +1094,11 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
 
 	ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
 	stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb->generic.field[2]));
-	dev = xhci->devs[slot_id];
-	ep = &dev->eps[ep_index];
+	ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
+	if (!ep)
+		return;
 
+	dev = xhci->devs[slot_id];
 	ep_ring = xhci_stream_id_to_ring(dev, ep_index, stream_id);
 	if (!ep_ring) {
 		xhci_warn(xhci, "WARN Set TR deq ptr command for freed stream ID %u\n",
@@ -1143,9 +1171,9 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
 	}
 
 cleanup:
-	dev->eps[ep_index].ep_state &= ~SET_DEQ_PENDING;
-	dev->eps[ep_index].queued_deq_seg = NULL;
-	dev->eps[ep_index].queued_deq_ptr = NULL;
+	ep->ep_state &= ~SET_DEQ_PENDING;
+	ep->queued_deq_seg = NULL;
+	ep->queued_deq_ptr = NULL;
 	/* Restart any rings with pending URBs */
 	ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
 }
@@ -1154,10 +1182,15 @@ static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
 		union xhci_trb *trb, u32 cmd_comp_code)
 {
 	struct xhci_virt_device *vdev;
+	struct xhci_virt_ep *ep;
 	struct xhci_ep_ctx *ep_ctx;
 	unsigned int ep_index;
 
 	ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
+	ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
+	if (!ep)
+		return;
+
 	vdev = xhci->devs[slot_id];
 	ep_ctx = xhci_get_ep_ctx(xhci, vdev->out_ctx, ep_index);
 	trace_xhci_handle_cmd_reset_ep(ep_ctx);
@@ -1187,7 +1220,7 @@ static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
 		xhci_ring_cmd_db(xhci);
 	} else {
 		/* Clear our internal halted state */
-		xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_HALTED;
+		ep->ep_state &= ~EP_HALTED;
 	}
 
 	/* if this was a soft reset, then restart */
@@ -2356,14 +2389,13 @@ static int handle_tx_event(struct xhci_hcd *xhci,
 	trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len));
 	ep_trb_dma = le64_to_cpu(event->buffer);
 
-	xdev = xhci->devs[slot_id];
-	if (!xdev) {
-		xhci_err(xhci, "ERROR Transfer event pointed to bad slot %u\n",
-			 slot_id);
+	ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
+	if (!ep) {
+		xhci_err(xhci, "ERROR Invalid Transfer event\n");
 		goto err_out;
 	}
 
-	ep = &xdev->eps[ep_index];
+	xdev = xhci->devs[slot_id];
 	ep_ring = xhci_dma_to_transfer_ring(ep, ep_trb_dma);
 	ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
 
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 8798ed031786..834f32fe9930 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -993,6 +993,7 @@ struct xhci_interval_bw_table {
 	unsigned int		ss_bw_out;
 };
 
+#define EP_CTX_PER_DEV		31
 
 struct xhci_virt_device {
 	struct usb_device		*udev;
@@ -1007,7 +1008,7 @@ struct xhci_virt_device {
 	struct xhci_container_ctx       *out_ctx;
 	/* Used for addressing devices and configuration changes */
 	struct xhci_container_ctx       *in_ctx;
-	struct xhci_virt_ep		eps[31];
+	struct xhci_virt_ep		eps[EP_CTX_PER_DEV];
 	u8				fake_port;
 	u8				real_port;
 	struct xhci_interval_bw_table	*bw_table;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH for 4.14] xhci: add xhci_get_virt_ep() helper
  2021-07-26 12:22       ` Schmid, Carsten
@ 2021-07-26 12:26         ` Felipe Balbi
  2021-07-26 12:51           ` Greg KH (gregkh@linuxfoundation.org)
  2021-07-26 12:59         ` Greg KH (gregkh@linuxfoundation.org)
  1 sibling, 1 reply; 10+ messages in thread
From: Felipe Balbi @ 2021-07-26 12:26 UTC (permalink / raw)
  To: Schmid, Carsten
  Cc: Greg KH (gregkh@linuxfoundation.org), USB list, Mathias Nyman, stable


Hi,

Schmid, Carsten <Carsten_Schmid@mentor.com> writes:
>>> May I attach the patches as a file, generated with "git format-patch" meanwhile?
>>> I fear that I'm not allowed to use "git send-mail".
>>
>> For backports for the stable tree, yes, I can handle attachments just fine, you are not the only company with that problem :)
>>
> please find the patches attached.
> 0001-xhci-add-xhci_get_virt_sp-helper.patch.4 for 4.14 and 4.19
> 0001-xhci-add-xhci_get_virt_sp-helper.patch.5 for 5.4 and 5.10
>
> Applied and compiled, not tested.
> Added Cc: stable@vger.kernel.org in both patches.

Unfortunately, attachments will not do. You need to send the patches
themselves as the email. The easiest way is to configure (and rely) on
`git send-email', then it will do the right thing for you.

-- 
balbi

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH for 4.14] xhci: add xhci_get_virt_ep() helper
  2021-07-26 12:26         ` Felipe Balbi
@ 2021-07-26 12:51           ` Greg KH (gregkh@linuxfoundation.org)
  0 siblings, 0 replies; 10+ messages in thread
From: Greg KH (gregkh@linuxfoundation.org) @ 2021-07-26 12:51 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: Schmid, Carsten, USB list, Mathias Nyman, stable

On Mon, Jul 26, 2021 at 03:26:59PM +0300, Felipe Balbi wrote:
> 
> Hi,
> 
> Schmid, Carsten <Carsten_Schmid@mentor.com> writes:
> >>> May I attach the patches as a file, generated with "git format-patch" meanwhile?
> >>> I fear that I'm not allowed to use "git send-mail".
> >>
> >> For backports for the stable tree, yes, I can handle attachments just fine, you are not the only company with that problem :)
> >>
> > please find the patches attached.
> > 0001-xhci-add-xhci_get_virt_sp-helper.patch.4 for 4.14 and 4.19
> > 0001-xhci-add-xhci_get_virt_sp-helper.patch.5 for 5.4 and 5.10
> >
> > Applied and compiled, not tested.
> > Added Cc: stable@vger.kernel.org in both patches.
> 
> Unfortunately, attachments will not do. You need to send the patches
> themselves as the email. The easiest way is to configure (and rely) on
> `git send-email', then it will do the right thing for you.

For stable patches, I can take these as attachments, especially given
just how b0rked mentor.com's email system currently is :(

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH for 4.14] xhci: add xhci_get_virt_ep() helper
  2021-07-26 12:22       ` Schmid, Carsten
  2021-07-26 12:26         ` Felipe Balbi
@ 2021-07-26 12:59         ` Greg KH (gregkh@linuxfoundation.org)
  1 sibling, 0 replies; 10+ messages in thread
From: Greg KH (gregkh@linuxfoundation.org) @ 2021-07-26 12:59 UTC (permalink / raw)
  To: Schmid, Carsten; +Cc: USB list, Mathias Nyman, stable

On Mon, Jul 26, 2021 at 12:22:00PM +0000, Schmid, Carsten wrote:
> Hi Greg,
> 
> >>
> >> May I attach the patches as a file, generated with "git format-patch" meanwhile?
> >> I fear that I'm not allowed to use "git send-mail".
> >
> > For backports for the stable tree, yes, I can handle attachments just fine, you are not the only company with that problem :)
> >
> please find the patches attached.
> 0001-xhci-add-xhci_get_virt_sp-helper.patch.4 for 4.14 and 4.19
> 0001-xhci-add-xhci_get_virt_sp-helper.patch.5 for 5.4 and 5.10
> 
> Applied and compiled, not tested.
> Added Cc: stable@vger.kernel.org in both patches.

Thanks for these, all now queued up.

greg k-h

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-07-26 12:59 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-26  9:11 [PATCH for 4.14] xhci: add xhci_get_virt_ep() helper Schmid, Carsten
2021-07-26  9:19 ` Greg KH (gregkh@linuxfoundation.org)
2021-07-26  9:32   ` Schmid, Carsten
2021-07-26 10:05 ` Greg KH (gregkh@linuxfoundation.org)
2021-07-26 10:13   ` Schmid, Carsten
2021-07-26 10:16     ` Greg KH (gregkh@linuxfoundation.org)
2021-07-26 12:22       ` Schmid, Carsten
2021-07-26 12:26         ` Felipe Balbi
2021-07-26 12:51           ` Greg KH (gregkh@linuxfoundation.org)
2021-07-26 12:59         ` Greg KH (gregkh@linuxfoundation.org)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).