Linux USB
 help / color / mirror / Atom feed
From: Mathias Nyman <mathias.nyman@linux.intel.com>
To: <gregkh@linuxfoundation.org>
Cc: <linux-usb@vger.kernel.org>,
	Wesley Cheng <wesley.cheng@oss.qualcomm.com>,
	Mathias Nyman <mathias.nyman@intel.com>
Subject: [PATCH 07/14] usb: xhci: sideband: fix ring sg table for sub-page TRB segments
Date: Fri,  9 Oct 2026 12:58:27 +0300	[thread overview]
Message-ID: <20261009095834.561578-8-mathias.nyman@linux.intel.com> (raw)
In-Reply-To: <20261009095834.561578-1-mathias.nyman@linux.intel.com>

From: Wesley Cheng <wesley.cheng@oss.qualcomm.com>

xhci_ring_to_sgtable() populated its sg_table via dma_get_sgtable()
per segment and sg_alloc_table_from_pages(), both of which only
operate at whole PAGE_SIZE granularity. Since TRB_SEGMENT_SIZE (4096)
can be smaller than PAGE_SIZE, multiple ring segments can share the
same physical page on larger-PAGE_SIZE kernels (16K/64K), which these
helpers cannot correctly represent.

Build the sg_table directly instead: allocate one sg entry per ring
segment with sg_alloc_table(), and fill each entry explicitly with
sg_set_page() using the segment's own page (resolved via
is_vmalloc_addr()/vmalloc_to_page() or virt_to_page()),
TRB_SEGMENT_SIZE as the length, and offset_in_page() for the exact
intra-page offset. This guarantees each segment gets its own sg
entry regardless of page sharing.

Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Wesley Cheng <wesley.cheng@oss.qualcomm.com>
Signed-off-by: Mathias Nyman <mathias.nyman@intel.com>
---
 drivers/usb/host/xhci-sideband.c | 57 ++++++++++----------------------
 1 file changed, 18 insertions(+), 39 deletions(-)

diff --git a/drivers/usb/host/xhci-sideband.c b/drivers/usb/host/xhci-sideband.c
index a5deeee4d5dc..beb637407e47 100644
--- a/drivers/usb/host/xhci-sideband.c
+++ b/drivers/usb/host/xhci-sideband.c
@@ -9,57 +9,42 @@
  */
 
 #include <linux/usb/xhci-sideband.h>
-#include <linux/dma-direct.h>
 
 #include "xhci.h"
 
 /* sideband internal helpers */
 static struct sg_table *
-xhci_ring_to_sgtable(struct xhci_sideband *sb, struct xhci_ring *ring)
+xhci_ring_to_sgtable(struct xhci_ring *ring)
 {
 	struct xhci_segment *seg;
 	struct sg_table	*sgt;
-	unsigned int n_pages;
-	struct page **pages;
-	struct device *dev;
-	size_t sz;
+	struct page *page;
 	int i;
 
-	dev = xhci_to_hcd(sb->xhci)->self.sysdev;
-	sz = ring->num_segs * TRB_SEGMENT_SIZE;
-	n_pages = PAGE_ALIGN(sz) >> PAGE_SHIFT;
-	pages = kvmalloc_objs(struct page *, n_pages);
-	if (!pages)
+	seg = ring->first_seg;
+	if (!seg)
 		return NULL;
 
 	sgt = kzalloc_obj(*sgt);
-	if (!sgt) {
-		kvfree(pages);
+	if (!sgt)
+		return NULL;
+
+	if (sg_alloc_table(sgt, ring->num_segs, GFP_KERNEL)) {
+		kfree(sgt);
 		return NULL;
 	}
 
-	seg = ring->first_seg;
-	if (!seg)
-		goto err;
-	/*
-	 * Rings can potentially have multiple segments, create an array that
-	 * carries page references to allocated segments.  Utilize the
-	 * sg_alloc_table_from_pages() to create the sg table, and to ensure
-	 * that page links are created.
-	 */
 	for (i = 0; i < ring->num_segs; i++) {
-		dma_get_sgtable(dev, sgt, seg->trbs, seg->dma,
-				TRB_SEGMENT_SIZE);
-		pages[i] = sg_page(sgt->sgl);
-		sg_free_table(sgt);
+		if (is_vmalloc_addr(seg->trbs))
+			page = vmalloc_to_page(seg->trbs);
+		else
+			page = virt_to_page(seg->trbs);
+
+		sg_set_page(&sgt->sgl[i], page, TRB_SEGMENT_SIZE,
+			    offset_in_page(seg->trbs));
 		seg = seg->next;
 	}
 
-	if (sg_alloc_table_from_pages(sgt, pages, n_pages, 0, sz, GFP_KERNEL))
-		goto err;
-
-	kvfree(pages);
-
 	/*
 	 * Save first segment dma address to sg dma_address field for the sideband
 	 * client to have access to the IOVA of the ring.
@@ -67,12 +52,6 @@ xhci_ring_to_sgtable(struct xhci_sideband *sb, struct xhci_ring *ring)
 	sg_dma_address(sgt->sgl) = ring->first_seg->dma;
 
 	return sgt;
-
-err:
-	kvfree(pages);
-	kfree(sgt);
-
-	return NULL;
 }
 
 /* Caller must hold sb->mutex */
@@ -254,7 +233,7 @@ xhci_sideband_get_endpoint_buffer(struct xhci_sideband *sb,
 	if (!ep || !ep->ring || !ep->sideband || ep->sideband != sb)
 		return NULL;
 
-	return xhci_ring_to_sgtable(sb, ep->ring);
+	return xhci_ring_to_sgtable(ep->ring);
 }
 EXPORT_SYMBOL_GPL(xhci_sideband_get_endpoint_buffer);
 
@@ -276,7 +255,7 @@ xhci_sideband_get_event_buffer(struct xhci_sideband *sb)
 	if (!sb || !sb->ir)
 		return NULL;
 
-	return xhci_ring_to_sgtable(sb, sb->ir->event_ring);
+	return xhci_ring_to_sgtable(sb->ir->event_ring);
 }
 EXPORT_SYMBOL_GPL(xhci_sideband_get_event_buffer);
 
-- 
2.43.0


  parent reply	other threads:[~2026-10-09  9:59 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-09  9:58 [PATCH 00/14] xhci features and fixes for usb-next Mathias Nyman
2026-10-09  9:58 ` [PATCH 01/14] early: usb: xhci-dbc: Handle out of bounds xhci-xdbc capability Mathias Nyman
2026-10-09 10:11   ` sashiko-bot
2026-10-09 14:52     ` Mathias Nyman
2026-10-09  9:58 ` [PATCH 02/14] usb: xhci: return an error if the host is not halted Mathias Nyman
2026-10-09 10:13   ` sashiko-bot
2026-10-09  9:58 ` [PATCH 03/14] usb: xhci: Unlock for command abort polling Mathias Nyman
2026-10-09 10:10   ` sashiko-bot
2026-10-09  9:58 ` [PATCH 04/14] usb: xhci: fix typos in comments Mathias Nyman
2026-10-09 10:02   ` sashiko-bot
2026-10-09  9:58 ` [PATCH 05/14] xhci: check device notification type before forwarding wake event Mathias Nyman
2026-10-09 10:10   ` sashiko-bot
2026-10-09  9:58 ` [PATCH 06/14] xhci: dbc: lock the minor IDR on registration failure Mathias Nyman
2026-10-09 10:13   ` sashiko-bot
2026-10-09 10:51     ` Greg KH
2026-10-09 10:52       ` Greg KH
2026-10-09 11:16         ` Mathias Nyman
2026-10-09 11:23           ` Greg KH
2026-10-09  9:58 ` Mathias Nyman [this message]
2026-10-09 10:15   ` [PATCH 07/14] usb: xhci: sideband: fix ring sg table for sub-page TRB segments sashiko-bot
2026-10-09 13:35     ` Mathias Nyman
2026-10-09  9:58 ` [PATCH 08/14] usb: xhci-pci: Add TUSB73x0 definitions Mathias Nyman
2026-10-09 10:07   ` sashiko-bot
2026-10-09 12:15     ` Mathias Nyman
2026-10-09  9:58 ` [PATCH 09/14] usb: xhci: Guarantee URB giveback on Ring Underrun/Overrun Mathias Nyman
2026-10-09 10:11   ` sashiko-bot
2026-10-09  9:58 ` [PATCH 10/14] usb: xhci: Don't set the skip flag on non-isoc endpoints Mathias Nyman
2026-10-09 10:16   ` sashiko-bot
2026-10-09 12:06     ` Mathias Nyman
2026-10-09  9:58 ` [PATCH 11/14] usb: xhci: Shorten the TD skipping loop Mathias Nyman
2026-10-09 10:06   ` sashiko-bot
2026-10-09  9:58 ` [PATCH 12/14] usb: xhci: Rework and improve the TD matching and skipping logic Mathias Nyman
2026-10-09 10:15   ` sashiko-bot
2026-10-09  9:58 ` [PATCH 13/14] usb: xhci: Fix bounce buffer overflow Mathias Nyman
2026-10-09 10:15   ` sashiko-bot
2026-10-09  9:58 ` [PATCH 14/14] xhci: Prevent invalid vdev dereference during sideband unregister Mathias Nyman
2026-10-09 10:12   ` sashiko-bot
2026-10-09 10:50 ` [PATCH 00/14] xhci features and fixes for usb-next Greg KH
2026-10-09 11:00   ` Mathias Nyman
2026-10-09 12:23     ` Michal Pecio

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261009095834.561578-8-mathias.nyman@linux.intel.com \
    --to=mathias.nyman@linux.intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mathias.nyman@intel.com \
    --cc=wesley.cheng@oss.qualcomm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox