usb: xhci: Fix slot_id resource race conflict

xHC controller may immediately reuse a slot_id after it's disabled,
giving it to a new enumerating device before the xhci driver freed
all resources related to the disabled device.

In such a scenario, device-A with slot_id equal to 1 is disconnecting
while device-B is enumerating, device-B will fail to enumerate in the
follow sequence.

1.[device-A] send disable slot command
2.[device-B] send enable slot command
3.[device-A] disable slot command completed and wakeup waiting thread
4.[device-B] enable slot command completed with slot_id equal to 1 and
wakeup waiting thread
5.[device-B] driver checks that slot_id is still in use (by device-A) in
xhci_alloc_virt_device, and fail to enumerate due to this
conflict
6.[device-A] xhci->devs[slot_id] set to NULL in xhci_free_virt_device

To fix driver's slot_id resources conflict, clear xhci->devs[slot_id] and
xhci->dcbba->dev_context_ptrs[slot_id] pointers in the interrupt context
when disable slot command completes successfully. Simultaneously, adjust
function xhci_free_virt_device to accurately handle device release.

[minor smatch warning and commit message fix -Mathias]

Cc: stable@vger.kernel.org
Fixes: 7faac1953ed1 ("xhci: avoid race between disable slot command and host runtime suspend")
Signed-off-by: Weitao Wang <WeitaoWang-oc@zhaoxin.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20250819125844.2042452-2-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by Weitao Wang and committed by Greg Kroah-Hartman 2eb03376 309b6341

+35 -23
+1 -2
drivers/usb/host/xhci-hub.c
··· 704 704 if (!xhci->devs[i]) 705 705 continue; 706 706 707 - retval = xhci_disable_slot(xhci, i); 708 - xhci_free_virt_device(xhci, i); 707 + retval = xhci_disable_and_free_slot(xhci, i); 709 708 if (retval) 710 709 xhci_err(xhci, "Failed to disable slot %d, %d. Enter test mode anyway\n", 711 710 i, retval);
+11 -11
drivers/usb/host/xhci-mem.c
··· 865 865 * will be manipulated by the configure endpoint, allocate device, or update 866 866 * hub functions while this function is removing the TT entries from the list. 867 867 */ 868 - void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) 868 + void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev, 869 + int slot_id) 869 870 { 870 - struct xhci_virt_device *dev; 871 871 int i; 872 872 int old_active_eps = 0; 873 873 874 874 /* Slot ID 0 is reserved */ 875 - if (slot_id == 0 || !xhci->devs[slot_id]) 875 + if (slot_id == 0 || !dev) 876 876 return; 877 877 878 - dev = xhci->devs[slot_id]; 879 - 880 - xhci->dcbaa->dev_context_ptrs[slot_id] = 0; 881 - if (!dev) 882 - return; 878 + /* If device ctx array still points to _this_ device, clear it */ 879 + if (dev->out_ctx && 880 + xhci->dcbaa->dev_context_ptrs[slot_id] == cpu_to_le64(dev->out_ctx->dma)) 881 + xhci->dcbaa->dev_context_ptrs[slot_id] = 0; 883 882 884 883 trace_xhci_free_virt_device(dev); 885 884 ··· 919 920 dev->udev->slot_id = 0; 920 921 if (dev->rhub_port && dev->rhub_port->slot_id == slot_id) 921 922 dev->rhub_port->slot_id = 0; 922 - kfree(xhci->devs[slot_id]); 923 - xhci->devs[slot_id] = NULL; 923 + if (xhci->devs[slot_id] == dev) 924 + xhci->devs[slot_id] = NULL; 925 + kfree(dev); 924 926 } 925 927 926 928 /* ··· 962 962 out: 963 963 /* we are now at a leaf device */ 964 964 xhci_debugfs_remove_slot(xhci, slot_id); 965 - xhci_free_virt_device(xhci, slot_id); 965 + xhci_free_virt_device(xhci, vdev, slot_id); 966 966 } 967 967 968 968 int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
+7 -2
drivers/usb/host/xhci-ring.c
··· 1592 1592 command->slot_id = 0; 1593 1593 } 1594 1594 1595 - static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id) 1595 + static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id, 1596 + u32 cmd_comp_code) 1596 1597 { 1597 1598 struct xhci_virt_device *virt_dev; 1598 1599 struct xhci_slot_ctx *slot_ctx; ··· 1608 1607 if (xhci->quirks & XHCI_EP_LIMIT_QUIRK) 1609 1608 /* Delete default control endpoint resources */ 1610 1609 xhci_free_device_endpoint_resources(xhci, virt_dev, true); 1610 + if (cmd_comp_code == COMP_SUCCESS) { 1611 + xhci->dcbaa->dev_context_ptrs[slot_id] = 0; 1612 + xhci->devs[slot_id] = NULL; 1613 + } 1611 1614 } 1612 1615 1613 1616 static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id) ··· 1861 1856 xhci_handle_cmd_enable_slot(slot_id, cmd, cmd_comp_code); 1862 1857 break; 1863 1858 case TRB_DISABLE_SLOT: 1864 - xhci_handle_cmd_disable_slot(xhci, slot_id); 1859 + xhci_handle_cmd_disable_slot(xhci, slot_id, cmd_comp_code); 1865 1860 break; 1866 1861 case TRB_CONFIG_EP: 1867 1862 if (!cmd->completion)
+14 -7
drivers/usb/host/xhci.c
··· 3932 3932 * Obtaining a new device slot to inform the xHCI host that 3933 3933 * the USB device has been reset. 3934 3934 */ 3935 - ret = xhci_disable_slot(xhci, udev->slot_id); 3936 - xhci_free_virt_device(xhci, udev->slot_id); 3935 + ret = xhci_disable_and_free_slot(xhci, udev->slot_id); 3937 3936 if (!ret) { 3938 3937 ret = xhci_alloc_dev(hcd, udev); 3939 3938 if (ret == 1) ··· 4089 4090 xhci_disable_slot(xhci, udev->slot_id); 4090 4091 4091 4092 spin_lock_irqsave(&xhci->lock, flags); 4092 - xhci_free_virt_device(xhci, udev->slot_id); 4093 + xhci_free_virt_device(xhci, virt_dev, udev->slot_id); 4093 4094 spin_unlock_irqrestore(&xhci->lock, flags); 4094 4095 4095 4096 } ··· 4136 4137 xhci_free_command(xhci, command); 4137 4138 4138 4139 return 0; 4140 + } 4141 + 4142 + int xhci_disable_and_free_slot(struct xhci_hcd *xhci, u32 slot_id) 4143 + { 4144 + struct xhci_virt_device *vdev = xhci->devs[slot_id]; 4145 + int ret; 4146 + 4147 + ret = xhci_disable_slot(xhci, slot_id); 4148 + xhci_free_virt_device(xhci, vdev, slot_id); 4149 + return ret; 4139 4150 } 4140 4151 4141 4152 /* ··· 4254 4245 return 1; 4255 4246 4256 4247 disable_slot: 4257 - xhci_disable_slot(xhci, udev->slot_id); 4258 - xhci_free_virt_device(xhci, udev->slot_id); 4248 + xhci_disable_and_free_slot(xhci, udev->slot_id); 4259 4249 4260 4250 return 0; 4261 4251 } ··· 4390 4382 dev_warn(&udev->dev, "Device not responding to setup %s.\n", act); 4391 4383 4392 4384 mutex_unlock(&xhci->mutex); 4393 - ret = xhci_disable_slot(xhci, udev->slot_id); 4394 - xhci_free_virt_device(xhci, udev->slot_id); 4385 + ret = xhci_disable_and_free_slot(xhci, udev->slot_id); 4395 4386 if (!ret) { 4396 4387 if (xhci_alloc_dev(hcd, udev) == 1) 4397 4388 xhci_setup_addressable_virt_dev(xhci, udev);
+2 -1
drivers/usb/host/xhci.h
··· 1791 1791 /* xHCI memory management */ 1792 1792 void xhci_mem_cleanup(struct xhci_hcd *xhci); 1793 1793 int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags); 1794 - void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id); 1794 + void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev, int slot_id); 1795 1795 int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device *udev, gfp_t flags); 1796 1796 int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev); 1797 1797 void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci, ··· 1888 1888 int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, 1889 1889 struct usb_tt *tt, gfp_t mem_flags); 1890 1890 int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id); 1891 + int xhci_disable_and_free_slot(struct xhci_hcd *xhci, u32 slot_id); 1891 1892 int xhci_ext_cap_init(struct xhci_hcd *xhci); 1892 1893 1893 1894 int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup);