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>, Umang Jain <uajain@igalia.com>,
	Mathias Nyman <mathias.nyman@linux.intel.com>
Subject: [PATCH 01/14] early: usb: xhci-dbc: Handle out of bounds xhci-xdbc capability
Date: Fri,  9 Oct 2026 12:58:21 +0300	[thread overview]
Message-ID: <20261009095834.561578-2-mathias.nyman@linux.intel.com> (raw)
In-Reply-To: <20261009095834.561578-1-mathias.nyman@linux.intel.com>

From: Umang Jain <uajain@igalia.com>

Currently, the early xhci-dbc assumes that the entire PCIe memory IO
can be entirely mapped  within the fixed boot time mappings
dictated by NR_FIX_BTMAPS. This patch handles the case where the PCIe
memory IO size can be larger than the fixed boot time mappings and
query the xhci debug extended capability in xdbc_map_pci_mmio().

This commit ensures that the xHCI debug capability can still be queried
when the PCIe memory IO space exceeds the fixmap size. In this scenario,
the base address is mapped uptil fixmap size and debug capabilities are
queried thereafter. Iterating over the entire PCIe BAR address size is
left for future improvement as and when, such a case arises.

Additionally, this brings the need to track the early_ioremap() mapped
size separately hence, introduce additional struct member xhci_base_length
in struct xdbc_state.

Signed-off-by: Umang Jain <uajain@igalia.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/early/xhci-dbc.c | 81 ++++++++++++++++++++++++++++++++----
 drivers/usb/early/xhci-dbc.h |  1 +
 2 files changed, 74 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/early/xhci-dbc.c b/drivers/usb/early/xhci-dbc.c
index 41118bba9197..f2ed8e52cc56 100644
--- a/drivers/usb/early/xhci-dbc.c
+++ b/drivers/usb/early/xhci-dbc.c
@@ -35,10 +35,23 @@ static bool early_console_keep;
 static inline void xdbc_trace(const char *fmt, ...) { }
 #endif /* XDBC_TRACE */
 
+/* Size of xHCI debug capability structure as per section 7.6.8 of xHCI spec. */
+#define XDBC_MAPPING_SIZE	64
+
+enum xdbc_capability_flags {
+	XDBC_CAP_FLAG_NONE		= 0,
+	XDBC_CAP_FLAG_LEGACY		= 1 << 0,
+	XDBC_CAP_FLAG_PROTOCOL		= 1 << 1,
+	XDBC_CAP_FLAG_DEBUG		= 1 << 2,
+};
+
 static void __iomem * __init xdbc_map_pci_mmio(u32 bus, u32 dev, u32 func)
 {
-	u64 val64, sz64, mask64;
+	u64 val64, sz64, mask64, fixmap_size;
+	enum xdbc_capability_flags cap_flags = XDBC_CAP_FLAG_NONE;
+	bool found_all_caps = false;
 	void __iomem *base;
+	int offset;
 	u32 val, sz;
 	u8 byte;
 
@@ -85,7 +98,59 @@ static void __iomem * __init xdbc_map_pci_mmio(u32 bus, u32 dev, u32 func)
 
 	xdbc.xhci_start = val64;
 	xdbc.xhci_length = sz64;
-	base = early_ioremap(val64, sz64);
+
+	fixmap_size = NR_FIX_BTMAPS << PAGE_SHIFT;
+	if (sz64 < fixmap_size) {
+		xdbc.xhci_base_length = sz64;
+		return early_ioremap(val64, sz64);
+	}
+
+	/*
+	 * Base address size is greater than fixed size boot time mappings
+	 * hence, map maximum allowed fixmap size from base address and
+	 * determine if the required extended capabilities lies within the
+	 * fixmap.
+	 */
+	base = early_ioremap(val64, fixmap_size);
+	if (!base)
+		return NULL;
+
+	offset = xhci_find_next_ext_cap(base, 0, 0);
+
+	while (offset < fixmap_size) {
+		val = readl(base + offset);
+		switch (XHCI_EXT_CAPS_ID(val)) {
+		case XHCI_EXT_CAPS_DEBUG:
+			if (offset + XDBC_MAPPING_SIZE < fixmap_size)
+				cap_flags |= XDBC_CAP_FLAG_DEBUG;
+			break;
+		case XHCI_EXT_CAPS_PROTOCOL:
+			cap_flags |= XDBC_CAP_FLAG_PROTOCOL;
+			break;
+		case XHCI_EXT_CAPS_LEGACY:
+			cap_flags |= XDBC_CAP_FLAG_LEGACY;
+			break;
+		}
+
+		if ((cap_flags & XDBC_CAP_FLAG_DEBUG) &&
+		    (cap_flags & XDBC_CAP_FLAG_PROTOCOL) &&
+		    (cap_flags & XDBC_CAP_FLAG_LEGACY)) {
+			found_all_caps = true;
+			break;
+		}
+
+		offset = xhci_find_next_ext_cap(base, offset, 0);
+		if (!offset)
+			break;
+	}
+
+	if (found_all_caps) {
+		xdbc.xhci_base_length = fixmap_size;
+	} else {
+		early_iounmap(base, fixmap_size);
+		xdbc.xhci_base_length = 0;
+		base = NULL;
+	}
 
 	return base;
 }
@@ -643,9 +708,9 @@ int __init early_xdbc_parse_parameter(char *s, int keep_early)
 	offset = xhci_find_next_ext_cap(xdbc.xhci_base, 0, XHCI_EXT_CAPS_DEBUG);
 	if (!offset) {
 		pr_notice("xhci host doesn't support debug capability\n");
-		early_iounmap(xdbc.xhci_base, xdbc.xhci_length);
+		early_iounmap(xdbc.xhci_base, xdbc.xhci_base_length);
 		xdbc.xhci_base = NULL;
-		xdbc.xhci_length = 0;
+		xdbc.xhci_base_length = 0;
 
 		return -ENODEV;
 	}
@@ -682,9 +747,9 @@ int __init early_xdbc_setup_hardware(void)
 		xdbc.table_base = NULL;
 		xdbc.out_buf = NULL;
 
-		early_iounmap(xdbc.xhci_base, xdbc.xhci_length);
+		early_iounmap(xdbc.xhci_base, xdbc.xhci_base_length);
 		xdbc.xhci_base = NULL;
-		xdbc.xhci_length = 0;
+		xdbc.xhci_base_length = 0;
 	}
 
 	return ret;
@@ -987,7 +1052,7 @@ static int __init xdbc_init(void)
 	}
 
 	raw_spin_lock_irqsave(&xdbc.lock, flags);
-	early_iounmap(xdbc.xhci_base, xdbc.xhci_length);
+	early_iounmap(xdbc.xhci_base, xdbc.xhci_base_length);
 	xdbc.xhci_base = base;
 	offset = xhci_find_next_ext_cap(xdbc.xhci_base, 0, XHCI_EXT_CAPS_DEBUG);
 	xdbc.xdbc_reg = (struct xdbc_regs __iomem *)(xdbc.xhci_base + offset);
@@ -1004,7 +1069,7 @@ static int __init xdbc_init(void)
 	memblock_phys_free(xdbc.table_dma, PAGE_SIZE);
 	memblock_phys_free(xdbc.out_dma, PAGE_SIZE);
 	writel(0, &xdbc.xdbc_reg->control);
-	early_iounmap(xdbc.xhci_base, xdbc.xhci_length);
+	early_iounmap(xdbc.xhci_base, xdbc.xhci_base_length);
 
 	return ret;
 }
diff --git a/drivers/usb/early/xhci-dbc.h b/drivers/usb/early/xhci-dbc.h
index 8b4d71de45fc..e2aefb796084 100644
--- a/drivers/usb/early/xhci-dbc.h
+++ b/drivers/usb/early/xhci-dbc.h
@@ -144,6 +144,7 @@ struct xdbc_state {
 	u32			dev;
 	u32			func;
 	void __iomem		*xhci_base;
+	size_t			xhci_base_length;
 	u64			xhci_start;
 	size_t			xhci_length;
 	int			port_number;
-- 
2.43.0


  reply	other threads:[~2026-10-09  9:58 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 ` Mathias Nyman [this message]
2026-10-09 10:11   ` [PATCH 01/14] early: usb: xhci-dbc: Handle out of bounds xhci-xdbc capability 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 ` [PATCH 07/14] usb: xhci: sideband: fix ring sg table for sub-page TRB segments Mathias Nyman
2026-10-09 10:15   ` 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-2-mathias.nyman@linux.intel.com \
    --to=mathias.nyman@linux.intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=uajain@igalia.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