Skip to contentSkip to conversation

usb: xhci: fix ERST max field conversion

PATCH In review Youngjoon Lee 2 participants 2 messages Aug 27

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 usb: xhci: fix ERST max field conversion

Commit 6d45e9556d4a ("usb: xhci: standardize multi bit-field macros") converted the ERST maximum calculation from BIT() to a left shift. These operations are not equivalent because the HCS_ERST_MAX field contains an exponent.

On an MT8173 xHCI controller where HCS_ERST_MAX is zero, the new calculation produces zero event ring segments. This reaches dma_alloc_coherent() with a zero size, triggers a page allocator warning, and prevents xHCI from probing with -ENOMEM.

Preserve the original calculation by applying BIT() to the value extracted with FIELD_GET().

This restores the USB 2.0 and USB 3.0 root hubs on MT8173. A USB webcam and both USB 2.0 and USB 3.0 hubs enumerate successfully, and the previous ERST allocation failure is no longer present.

Fixes 6d45e9556d4a ("usb: xhci: standardize multi bit-field macros")
---
 drivers/usb/host/xhci-mem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/host/xhci-mem.c +1 -1
index 7a21ac81f9c8..af8d4b74c4ba 100644
@@ -2301,7 +2301,7 @@ xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigned int segs, gfp_t flags)
 	if (!segs)
 		segs = ERST_DEFAULT_SEGS;
 
-	max_segs = FIELD_GET(HCS_ERST_MAX, xhci->hcs_params2) << 2;
+	max_segs = BIT(FIELD_GET(HCS_ERST_MAX, xhci->hcs_params2));
 	segs = min(segs, max_segs);
 
 	ir = kzalloc_node(sizeof(*ir), flags, dev_to_node(dev));
Signature · 1 line
2.55.0
#1 lore raw
Quoted 13 lines · Youngjoon Lee

Commit 6d45e9556d4a ("usb: xhci: standardize multi bit-field macros") converted the ERST maximum calculation from BIT() to a left shift. These operations are not equivalent because the HCS_ERST_MAX field contains an exponent.

On an MT8173 xHCI controller where HCS_ERST_MAX is zero, the new calculation produces zero event ring segments. This reaches dma_alloc_coherent() with a zero size, triggers a page allocator warning, and prevents xHCI from probing with -ENOMEM.

Preserve the original calculation by applying BIT() to the value extracted with FIELD_GET().

Quoted 6 lines

This restores the USB 2.0 and USB 3.0 root hubs on MT8173. A USB webcam and both USB 2.0 and USB 3.0 hubs enumerate successfully, and the previous ERST allocation failure is no longer present.

Fixes 6d45e9556d4a ("usb: xhci: standardize multi bit-field macros")

Thanks for the report and patch.

This issue has already been addressed in:

https://lore.kernel.org/linux-usb/[email protected]/

-Niklas