summaryrefslogtreecommitdiff
path: root/drivers/thunderbolt
AgeCommit message (Collapse)Author
29 hoursMerge branch 'usb-next' of ↵Mark Brown
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git # Conflicts: # drivers/thunderbolt/tb.c
29 hoursMerge branch 'modules-next' of ↵Mark Brown
https://git.kernel.org/pub/scm/linux/kernel/git/modules/linux.git # Conflicts: # drivers/gpu/drm/clients/drm_fbdev_helper.c # drivers/gpu/drm/xe/xe_guc_log.c
29 hoursMerge branch 'linux-next' of ↵Mark Brown
https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
30 hoursMerge branch 'fixes' of ↵Mark Brown
https://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.git
3 daysdrivers: Replace __MODULE_STRING() with __stringify()Petr Pavlu
__MODULE_STRING() has been an alias for __stringify() since "[PATCH] MODULE_PARM support for older modules" [1] in 2002-12. That change also moved it to the graveyard section at the end of linux/module.h Replace the remaining uses of __MODULE_STRING() with __stringify() in preparation for its removal. Link: https://git.kernel.org/tglx/history/c/136839a1b4 [1] Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Acked-by: Andi Shyti <andi.shyti@kernel.org> Acked-by: Ian Abbott <abbotti@mev.co.uk> Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Acked-by: Mika Westerberg <westeri@kernel.org> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
5 daysMerge branch 'acpi-driver' into linux-nextRafael J. Wysocki
* acpi-driver: ACPI: bus: Drop acpi_get_first_physical_node() efi/dev-path-parser: Switch to use acpi_bus_get_primary_device() ALSA: hda: tas2781: Switch to use acpi_bus_get_primary_device() ALSA: hda: cs35l41: Switch to use acpi_bus_get_primary_device() iommu/arm-smmu-v3: Switch to use acpi_bus_get_primary_device() ACPI: Add stub for acpi_find_child_device() ACPI: bus: Provide !ACPI stub for acpi_device_uid() ALSA: hda: aw88399: Switch to use acpi_bus_get_primary_device() ASoC: loongson: Switch to use acpi_bus_get_primary_device() ASoC: intel: boards: Switch to use acpi_bus_get_primary_device() ASoC: amd: acp3x-es83xx: Switch to use acpi_bus_get_primary_device() ASoC: amd: acp-es8336: Switch to use acpi_bus_get_primary_device() thunderbolt: Switch to use acpi_bus_get_primary_device() platform/x86: apple-gmux: Switch to use acpi_bus_get_primary_device() platform/x86: x86-android-tablets: Use acpi_bus_get_primary_device() platform/x86: serdev_helpers: Switch to use acpi_bus_get_primary_device() platform/x86: yogabook: Switch to use acpi_bus_get_primary_device() ACPI: amba: Switch to use acpi_bus_get_primary_device() ACPI: bus: Use acpi/acpi_bus.h without CONFIG_ACPI
8 daysMerge tag 'thunderbolt-for-v7.3-rc7' of ↵Greg Kroah-Hartman
ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt into usb-next Mika writes: thunderbolt: Fix for v7.3-rc7 This incluces a single fix to make the runtime PM completion complete devices that are actually part of the domain. Needed for firmware connection manager based systems. This has been in linux-next for few days with no reported issues. * tag 'thunderbolt-for-v7.3-rc7' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt: thunderbolt: Do not RPM complete unrelated subtrees on unplug
11 daysMerge tag 'thunderbolt-for-v7.4-rc1' of ↵Greg Kroah-Hartman
ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt into usb-next Mika writes: thunderbolt: Changes for v7.4 merge window This includes following USB4/Thunderbolt changes for the v7.4 merge window: - Add quirk for ASMedia controller. - Add device links for Apple machines with Intel Ice Lake and Titan Ridge controllers. - Thunderbolt networking improvements. - USB4STREAM improvements. - Add support for extended error counters. - Minor fixes and cleanups. All these have been in linux-next with no reported issues. * tag 'thunderbolt-for-v7.4-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt: (24 commits) thunderbolt: stream: Make read return framing error to the userspace thunderbolt: Extract per-lane extended error counters in software margining thunderbolt: Fix sideband register access in usb4_port_sw_margin_errors() thunderbolt: Add extended error counter support for software lane margining thunderbolt: Define number of dwords for hardware margining results thunderbolt: Make software margining error counter configurable thunderbolt: stream: Improve CLOSE handling on write side thunderbolt: stream: Check the Rx ring before task starts sleeping thunderbolt: stream: Do not hold the lock while busy polling thunderbolt: Add tb_ring_poll_pending() thunderbolt: Write descriptors in tb_ring_poll() thunderbolt: stream: Use polling with RX ring thunderbolt: Use shadow copy for ring interrupt mask thunderbolt: Clean up ring interrupt register indexing thunderbolt: Do not WARN about already disabled interrupt on polled rings thunderbolt: Fix typo "forwared" in comment thunderbolt: Add device links for Apple systems with Ice Lake thunderbolt: Add device links for Apple machines with Titan Ridge thunderbolt: Move tb_apple_add_links() to pci.c net: thunderbolt: Update ring indices only after all frames are queued ...
12 daysthunderbolt: Do not RPM complete unrelated subtrees on unplugJonathan Gopel
When a Thunderbolt device is unplugged, that switch and every switch subsequent to it on the bus device list is `complete()`d, not just its child devices. In the case of multiple domains, it may cause, eg, an attempt to `complete()` the uninitialized domain 1 root switch RPM completion on unplug of a switch from domain 0 (though ordering is not guaranteed numerically sorted). I initially noticed this issue on a Dell XPS9720 when the system would seem to sporadically not wake after unplugging a Thunderbolt dock. I tried multiple kernel versions including v7.2.7 and v7.3-rc4 to see if that resolved the issue, but the issue persisted. Eventually I found that I could consistently generate a kernel Oops reporting a page fault at 0xffff_ffff_ffff_fff8 on unplug from one side of the laptop and went bug hunting. I became suspicious of the `bus_for_each_dev()` walk that I ultimately ended up changing. To confirm this issue, I did an eBPF trace of `bus_for_each_dev()`, `complete_rpm()`, and `complete()` while unplugging in a variety of situations and found that an unplug from domain 0 tries to `complete_rpm()` domain 1's switch, whose RPM completion is not initialized and thus is holding a null wait-list pointer, triggering the page fault. Here are the key sections of that eBPF trace. Note that HEAD denotes the completion's own wait-list HEAD: ``` RESCAN_ENTER domain=0 COMPLETE rescan_domain=0 target=0-1 target_domain=0 route=0x1 parent=0-0 unplugged=1 COMPLETION done=0 head=HEAD next=HEAD prev=HEAD BUS_WALK domain=0 start=0-1 callback=complete_rpm CALLBACK_ENTER rescan_domain=0 dev=1-0 parent=domain1 is_switch=1 COMPLETE rescan_domain=0 target=1-0 target_domain=1 route=0x0 parent=domain1 unplugged=0 COMPLETION done=0 head=HEAD next=0 prev=0 complete+5 complete_rpm+43 bus_for_each_dev+133 icm_free_unplugged_children+250 icm_rescan_work+42 ``` This patch gates the `complete()` on an additional condition - that the Thunderbolt domain matches the domain of the device that was unplugged. I only have a single system with multiple Thunderbolt domains - the Dell XPS9720. I am consistently able to reproduce the Oops on that system. Since running with this patch, I have not seen the Oops reoccur. I have also tested it on a Thinkpad X1-Gen12, and that system boots and runs well with it, but it only has a single Thunderbolt domain, so it does not exercise the multi-domain failure case. Fixes: 4f7c2e0d8765 ("thunderbolt: Make sure device runtime resume completes before taking domain lock") Cc: stable@vger.kernel.org Signed-off-by: Jonathan Gopel <jgopel@gmail.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-10-01Merge tag 'thunderbolt-for-v7.3-rc6' of ↵Greg Kroah-Hartman
ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt into usb-linus Mika writes: thunderbolt: Fixes for v7.3-rc6 This includes following USB4/Thunderbolt fixes: - Fix XDomain property parser to reject oversized properties responses. - Revert a quirk that causes deadlock at shutdown. - Fix USB4STREAM to announce FMODE_NOWAIT. - Add a quirk that disables CL states for Anker Prime TB5 dock to avoid link instability. All these have been in linux-next with no reported issues. * tag 'thunderbolt-for-v7.3-rc6' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt: thunderbolt: Disable CL states for the Anker Prime TB5 dock thunderbolt: stream: Announce support for FMODE_NOWAIT Revert "thunderbolt: Add quirk to reset host interface on DMA path teardown for AMD USB4 routers" thunderbolt: Reject oversized XDomain properties responses
2026-09-28thunderbolt: Disable CL states for the Anker Prime TB5 dockKurt Lieber
The Anker Prime TB5 dock identifies itself in the DROM as 01ea:83b5. Its router config space is an Intel Barlow Ridge 80G hub (8087:5786). The upstream lane adapter advertises CL0s, CL1, and CL2. With CLx left enabled, TMU uni-directional LowRes setup fails with -ENOTCONN, the USB3 and DisplayPort tunnels are aborted, and the router reconnects in a loop. Loading thunderbolt with clx=0 keeps the link up on this machine. Match the DROM id together with the Barlow Ridge hub id and disable CL states for this dock only. QUIRK_NO_CLX takes the same early-out as the module parameter, without disabling CLx for every other router. Closes: https://lore.kernel.org/linux-usb/SJ0PR15MB4696D491504DB667AA8E0617A3812@SJ0PR15MB4696.namprd15.prod.outlook.com/ Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Kurt Lieber <kurt@lieber.org> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-24thunderbolt: stream: Announce support for FMODE_NOWAITMika Westerberg
Commit 42bc6935339b ("thunderbolt: stream: Support IOCB_NOWAIT in non-blocking I/O as well") added support for IOCB_NOWAIT but forgot to actually announce it as part of the file->f_mode. Add this now so users such as io_uring can actually take advantage of IOCB_NOWAIT. Fixes: 42bc6935339b ("thunderbolt: stream: Support IOCB_NOWAIT in non-blocking I/O as well") Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-24thunderbolt: stream: Make read return framing error to the userspaceMika Westerberg
If any of the frames are corrupted during the receive we currently log a warning and pass them to the userspace without it knowing they were corrupted. Make the driver behave better and return an error (-EIO) to the userspace in that case. For the CLOSE packet, payload does not matter so we handle it the usual way. Reviewed-by: Ivy Lopez <skunkolee@gmail.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-24thunderbolt: Extract per-lane extended error counters in software marginingAnurag
USB4 defines two error counter formats for software margining: - Standard counters (USB4 v1): 4-bit per-lane values in DW0. - Extended counters (USB4 v2): 16-bit per-lane values split across DW0 (lower 4 bits) and DW1-DW3 (upper 12 bits). The existing debugfs logic only reads DW0 when checking for errors, which works correctly for standard error counters but only captures the lower 4 bits, missing the 12 MSBs if extended error counter is supported. Read and combine the full counter values from all result dwords before evaluating whether errors occurred on any lane. When running software margining with "all lanes", determine which Rx lanes are actually active and only check those: - ASYM_RX: RX0, RX1, RX2 - ASYM_TX: RX0 - Symmetric: RX0, RX1 Refactor the error counter extraction into a helper function to improve readability. Signed-off-by: Anurag <anurag@intel.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-24thunderbolt: Fix sideband register access in usb4_port_sw_margin_errors()Anurag
The READ_SW_MARGIN_ERR (RDSW) completion payload is returned in the USB4 sideband data window, but the location differs between standard and extended error counters. Standard error counters are returned in USB4_SB_METADATA and fit within a single dword. Extended error counters require 4 dwords and are returned in USB4_SB_DATA. Add conditional logic to select the appropriate register based on the dwords parameter that corresponds with error counter type. Co-developed-by: Rene Sapiens <rene.sapiens@linux.intel.com> Signed-off-by: Rene Sapiens <rene.sapiens@linux.intel.com> Signed-off-by: Anurag <anurag@intel.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-24thunderbolt: Add extended error counter support for software lane marginingRene Sapiens
Add support for software margining extended error counters. Increase the results buffer size to accommodate the new dwords used for extended error counters for RX0, RX1 and RX2. Signed-off-by: Rene Sapiens <rene.sapiens@linux.intel.com> Co-developed-by: Anurag <anurag@intel.com> Signed-off-by: Anurag <anurag@intel.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-24thunderbolt: Define number of dwords for hardware margining resultsRene Sapiens
Use a defined size for hardware margining results in preparation for the software margining extended error counters which requires a larger buffer size. Signed-off-by: Rene Sapiens <rene.sapiens@linux.intel.com> Co-developed-by: Anurag <anurag@intel.com> Signed-off-by: Anurag <anurag@intel.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-24thunderbolt: Make software margining error counter configurableAnurag
The debugfs software margining run path currently initializes the request with USB4_MARGIN_SW_ERROR_COUNTER_CLEAR, which implicitly clears/enables counters every time software margining is started. On some host-router/firmware implementations that enforce PHY interface for USB4 (PIPE) margining control, CLEAR and START are distinct operations. - CLEAR resets error counters without starting margining - START begins margin testing and error counting Make the error counter operation configurable through debugfs error_counter control instead of hardcoding CLEAR. Additionally, only execute the software margining sampling loop when the selected operation is START; for CLEAR or STOP operations, execute the counter operation and return immediately. Example to CLEAR error counter: cd /sys/kernel/debug/thunderbolt/<ROUTER_ID>/<PORT>/margining echo clear > error_counter Example to START error counter: cd /sys/kernel/debug/thunderbolt/<ROUTER_ID>/<PORT>/margining echo start > error_counter After configuring error counter run software margining for changes to take effect: echo 1 > run This aligns the debugfs behavior with the USB4 v2/PIPE expectation and lets users explicitly choose between CLEAR/START/STOP. Co-developed-by: Rene Sapiens <rene.sapiens@linux.intel.com> Signed-off-by: Rene Sapiens <rene.sapiens@linux.intel.com> Signed-off-by: Anurag <anurag@intel.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-24thunderbolt: stream: Improve CLOSE handling on write sideMika Westerberg
If there is only a writer in the stream (i.e the other side just reads and this side just writes) then if the other side is closed the CLOSE packet does is never picked up from the writers RX ring because we do not complete the RX poll. Currently we do that only when something is actually reading the stream. To make this work on write-only stream, complete the RX poll also during ->write_iter(), and then make the stream return -EPIPE to the writer. While there make sdev->closed to use READ/WRITE_ONCE() analogous to other flags. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-22thunderbolt: Switch to use acpi_bus_get_primary_device()Rafael J. Wysocki
Replace acpi_get_first_physical_node() that is slated for removal with acpi_bus_get_primary_device() that takes a reference to the device it is about to return. This addresses a potential use-after-free that may occur if the device returned by acpi_get_first_physical_node() is removed right after dropping its ACPI companion's physical_node_lock in that function. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com> Link: https://patch.msgid.link/1941270.atdPhlSkOF@rafael.j.wysocki
2026-09-16Revert "thunderbolt: Add quirk to reset host interface on DMA path teardown ↵Mario Limonciello
for AMD USB4 routers" This commit has caused a deadlock at shutdown. A proper fix with another approach will be coming later. Revert commit f1de1fc5f632cdeae1f5c2984572ab710d4dfcaa for now. Reported-by: juan.martinez@amd.com Closes: https://lore.kernel.org/linux-usb/20260825214237.4179813-1-juan.martinez@amd.com/ Cc: Sanath S <Sanath.S@amd.com> Cc: Basavaraj Natikar <Basavaraj.Natikar@amd.com> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-14thunderbolt: stream: Check the Rx ring before task starts sleepingMika Westerberg
In interrupt mode when tb_ring_poll_complete() is called it is possible that a frame was completed right before the ring interrupt was unmasked in which case there will be no interrupt and the task starts sleeping. Avoid this and check if there is anything completed prior putting the task to sleep. The same can happen with poll() so check the ring there too before reporting that there is nothing to read. Assisted-by: LLM Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-14thunderbolt: stream: Do not hold the lock while busy pollingMika Westerberg
When in busy poll mode with a reader and writer, and there is nothing completed on the rings both sides keep taking and releasing the lock from each other and this can cause stalls. Avoid this by calling the new API function tb_ring_poll_pending() that only returns true if there is anything available in which case they can take the lock and know there is now work to do. Reported-by: Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com> Assisted-by: LLM Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-14thunderbolt: Add tb_ring_poll_pending()Mika Westerberg
This helper can be used to figure out whether tb_ring_poll() has a frame to be returned. This can be used without the caller needing to take its own lock. Assisted-by: LLM Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-14thunderbolt: Write descriptors in tb_ring_poll()Mika Westerberg
When the ring is not in interrupt mode, it depends on something enqueuing new frames to write the descriptors from ring->queue to the hardware, and that can take a long time. Since we know that we just released one slot, we can push the next frame directly from tb_ring_poll(). Reported-by: Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com> Assisted-by: LLM Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-14thunderbolt: Reject oversized XDomain properties responsesDaehyeon Ko
tb_xdp_properties_request() allocates room for 45 data dwords in its 252-byte response buffer. The XDomain length field is six bits wide, however, and a malicious peer can set it to 63. After the fixed response fields are subtracted, the driver treats this as 48 data dwords. Commit 322e93448d90 ("thunderbolt: Clamp XDomain response data copy to allocation size") only bounds the copy against data_len. If data_len is at least 48, memcpy() reads 192 bytes from the 180-byte res->data array, causing a 12-byte heap out-of-bounds read. Commit 4db2bd2ed478 ("thunderbolt: Limit XDomain response copy to actual frame size") limits the earlier copy but does not constrain this header-derived length. Reject response data lengths that exceed the allocated source buffer before copying them into the assembled property block. Fixes: d1ff70241a27 ("thunderbolt: Add support for XDomain discovery protocol") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Daehyeon Ko <4ncienth@gmail.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-10thunderbolt: stream: Use polling with RX ringMika Westerberg
The ring API already supports polling so that once there is anything in the RX ring, it will mask the ring interrupt and call the ->start_poll callback. This is the same mechanism that the USB4/Thunderbolt networking driver already uses. We can do the same for the USB4STREAM driver and poll any RX frames while they are available, until we re-enable the ring interrupt again. This provides better latency when the stream is in "normal" (non-busy-polling) mode. Assisted-by: LLM Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-10thunderbolt: Use shadow copy for ring interrupt maskMika Westerberg
Each time we mask or unmask ring interrupt we do a read-modify-write and that is not without a cost when on a hot path. We can get rid of that read by making a shadow copy of the interrupt mask register and using that in place of a register read. Assisted-by: LLM Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-10thunderbolt: Clean up ring interrupt register indexingMika Westerberg
nhi_mask_interrupt() and nhi_clear_interrupt() take "ring" as parameter but in fact it is not an actual ring but a byte offset to the interrupt register. Make this less confusing and name the paramers what it really is and calculate the offset where it is actually needed. In addition ring_interrupt_active() has two variables called "index" with different meanings, and the second one shadows the first one open-coding ring_interrupt_index() as well. Drop that and rename the remaining what they actually hold. While there, make the mask variable u32 and use BIT() to avoid signed shifting. No functional changes intended. Assisted-by: LLM Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-10thunderbolt: Do not WARN about already disabled interrupt on polled ringsMika Westerberg
With ->start_poll it is possible that the ring is actually already disabled before tb_ring_stop() is called. This is expected behaviour so there is no point warning about that. Assisted-by: LLM Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-09Merge tag 'thunderbolt-for-v7.3-rc3' of ↵Greg Kroah-Hartman
ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt into usb-linus Mika writes: thunderbolt: Fixes for v7.3-rc3 This includes following USB4/Thunderbolt fixes: - Fix various issues around asynchronous DisplayPort tunnel activation when there is no graphics driver doing doing the capability exchange. - Fix potential NULL pointer dereference when XDomain connection is removed. - Fix use-after-free when control channel request is canceled. - Fix lockdep false positive. - Revert a commit that causes XDomain properties ping-pong. All these have been in linux-next with no reported issues. * tag 'thunderbolt-for-v7.3-rc3' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt: Revert "thunderbolt: xdomain: Notify peers after enumeration" thunderbolt: Use separate lock class for each ring thunderbolt: Fix KASAN reported use-after-free when request is canceled thunderbolt: Fix NULL dereference in tb_remove_work() thunderbolt: Tear down inactive DP tunnels when the domain is stopped thunderbolt: Mark discovered tunnels as active thunderbolt: Don't access a DP tunnel after its DPRX read was canceled thunderbolt: Fix domain reference leak when DPRX read is canceled thunderbolt: Make the DP tunnel activation callback mandatory thunderbolt: Hold a router reference for each allocated HopID
2026-09-08thunderbolt: Add device links for Apple systems with Ice LakeAtharva Tiwari
Ice Lake Thunderbolt NHI that are on some Macs. The NHI and its associated PCIe Root Ports all sit directly on the Root Complex with no upstream port. Identify the tunneled PCIe Root Ports by their PCI IDs and create device links back to the NHI so that PCIe tunnels can be re-established after sleep. Co-developed-by: Andre Eikmeyer <andre@negmaster.com> Signed-off-by: Andre Eikmeyer <andre@negmaster.com> Signed-off-by: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-08thunderbolt: Add device links for Apple machines with Titan RidgeAtharva Tiwari
Add device links for Apple machines with the Titan Ridge thunderbolt controller. Signed-off-by: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-08thunderbolt: Move tb_apple_add_links() to pci.cAtharva Tiwari
Due to historical reasons the software connection manager in tb.c directly sets up the device link between the tunneled PCIe ports and the NHI. Now as we are starting to support non-PCIe host interfaces as well we are trying to keep the connection manager implementation agnostic of the underlying host interface. For this reason move the device link creation into pci.c and expose it through a new NHI operation that the host interface code calls when it sets up the connection manager. Suggested-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-07thunderbolt: Allow batching of descriptorsMika Westerberg
The hardware allows queueing descriptors ahead of updating producer/consumer fields. This way it is possible to avoid unnecessary register writes on hot-paths such as when transferring networking packets. For this reason introduce an API that allows Thunderbolt service drivers to opt-in for this and take advantage of batching. Assisted-by: LLM Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-04treewide: refresh kmalloc_obj() conversionsKees Cook
This is another run of the Coccinelle script for converting kmalloc() family of allocations to kmalloc_obj() via the existing rules in scripts/coccinelle/api/kmalloc_objs.cocci This catches both the set of kmalloc() uses added since the first kmalloc_obj() conversions in v7.0 and adds a large group missed in the first pass due to Coccinelle not interacting well with the cleanup.h scoped_...() family of macros[1]. I worked around this with spatch's "--macro-file" argument to a file with all the scoped_...() macros mapped to Coccinelle's YACFE_ITERATOR[2] as that was the closest viable control flow indicator I could find. Build tested allmodconfig on x86, arm64, arm, loongarch, mips, powerpc, riscv, and s390 with no new warnings. Link: https://lore.kernel.org/lkml/202609021314.8A9C0B8@keescook/ [1] Link: https://github.com/coccinelle/coccinelle/blob/master/standard.h [2] Signed-off-by: Kees Cook <kees+treewide@kernel.org>
2026-09-04Revert "thunderbolt: xdomain: Notify peers after enumeration"Mika Westerberg
This reverts commit e027dba038f0008df9bc9575f5c3e803e90636c6. Alan noticed that this causes the peers send change properties to each other continuously. Reported-by: Borzeszkowski, Alan <alan.borzeszkowski@intel.com> Cc: Milo Chen <cmh79479@gmail.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-04thunderbolt: Use separate lock class for each ringMika Westerberg
When connected to another host and then unplugging cable lockdep triggers following: ====================================================== WARNING: possible circular locking dependency detected 7.1.0-rc2+ #1775 Tainted: G U ------------------------------------------------------ kworker/u16:6/312 is trying to acquire lock: ffff8881179c70a8 ((work_completion)(&ring->work)){+.+.}-{0:0}, at: __flush_work+0x3cf/0xd10 but task is already holding lock: ffff8881a8b810b0 (&net->connection_lock){+.+.}-{4:4}, at: tbnet_tear_down+0x110/0x720 [thunderbolt_net] which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&net->connection_lock){+.+.}-{4:4}: __mutex_lock+0x19a/0x2490 mutex_lock_nested+0x1b/0x30 tbnet_handle_packet+0x74c/0xd70 [thunderbolt_net] tb_xdomain_handle_request+0x37c/0x4b0 [thunderbolt] tb_domain_event_cb+0xc9/0x140 [thunderbolt] tb_ctl_handle_event+0xd6/0x2c0 [thunderbolt] tb_ctl_rx_callback+0x22c/0xa10 [thunderbolt] ring_work+0x715/0xcb0 [thunderbolt] process_one_work+0x902/0x1790 worker_thread+0x5cd/0xfe0 kthread+0x339/0x420 ret_from_fork+0x79a/0x9d0 ret_from_fork_asm+0x1a/0x30 -> #0 ((work_completion)(&ring->work)){+.+.}-{0:0}: __lock_acquire+0x1592/0x2640 lock_acquire+0x1a3/0x300 __flush_work+0x3e9/0xd10 flush_work+0x21/0x30 tb_ring_stop+0x240/0x840 [thunderbolt] tbnet_tear_down+0x2ff/0x720 [thunderbolt_net] tbnet_stop+0x47/0x1a0 [thunderbolt_net] __dev_close_many+0x19e/0x4e0 netif_close_many+0x1e8/0x640 unregister_netdevice_many_notify+0x6d3/0x22d0 unregister_netdevice_queue+0x2b9/0x3a0 unregister_netdev+0x1c/0x70 tbnet_remove+0x52/0xb0 [thunderbolt_net] tb_service_remove+0x8a/0xe0 [thunderbolt] device_remove+0xc5/0x190 device_release_driver_internal+0x3db/0x590 device_release_driver+0x12/0x20 bus_remove_device+0x2c1/0x580 device_del+0x3d9/0x9f0 device_unregister+0x17/0xc0 unregister_service+0x46/0x60 [thunderbolt] device_for_each_child_reverse+0xfa/0x180 tb_xdomain_unregister+0x57/0xe0 [thunderbolt] unregister_unplugged_xdomain+0x101/0x1a0 [thunderbolt] bus_for_each_dev+0x111/0x1a0 tb_domain_unregister_unplugged_xdomains+0x98/0xe0 [thunderbolt] tb_handle_hotplug+0xc3/0x2bb0 [thunderbolt] process_one_work+0x902/0x1790 worker_thread+0x5cd/0xfe0 kthread+0x339/0x420 ret_from_fork+0x79a/0x9d0 ret_from_fork_asm+0x1a/0x30 other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&net->connection_lock); lock((work_completion)(&ring->work)); lock(&net->connection_lock); lock((work_completion)(&ring->work)); This in fact is false positive because they involve unrelated rings (and unrelated work structures). In the first one it is ring 0 which is used for control traffic and in the second it is dealing with another ring used for the high-speed traffic. Fix this by using separate lock class for each ring worker. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-04thunderbolt: Fix KASAN reported use-after-free when request is canceledMika Westerberg
Alan reported that when doing stress testing sometimes KASAN notices use-after-free during control channel operation (stripped down keeping the relevant parts): BUG: KASAN: slab-use-after-free in tb_cfg_request_sync+0x240/0x250 [thunderbolt] Read of size 24 at addr ffff88811067f290 by task kworker/u40:2/1760 <TASK> tb_cfg_request_sync+0x240/0x250 [thunderbolt] tb_cfg_read_raw+0x367/0x510 [thunderbolt] tb_cfg_read+0xec/0x240 [thunderbolt] tb_port_get_link_generation+0x258/0x420 [thunderbolt] tb_usb3_consumed_bandwidth+0x1c1/0x2c0 [thunderbolt] tb_tunnel_consumed_bandwidth+0xfd/0x910 [thunderbolt] tb_available_bandwidth+0x5f2/0xeb0 [thunderbolt] tb_recalc_estimated_bandwidth+0x2a0/0x1bc0 [thunderbolt] tb_handle_dp_bandwidth_request+0x1897/0x5e20 [thunderbolt] process_one_work+0x675/0x1230 worker_thread+0x5e6/0xf70 kthread+0x365/0x470 ret_from_fork+0x54d/0x710 ret_from_fork_asm+0x1a/0x30 </TASK> Allocated by task 1760: __kmalloc_cache_noprof+0x1ee/0x550 tb_cfg_read_raw+0x1d3/0x510 [thunderbolt] tb_cfg_read+0xec/0x240 [thunderbolt] tb_port_get_link_generation+0x258/0x420 [thunderbolt] tb_usb3_consumed_bandwidth+0x1c1/0x2c0 [thunderbolt] tb_tunnel_consumed_bandwidth+0xfd/0x910 [thunderbolt] tb_available_bandwidth+0x5f2/0xeb0 [thunderbolt] tb_recalc_estimated_bandwidth+0x2a0/0x1bc0 [thunderbolt] tb_handle_dp_bandwidth_request+0x1897/0x5e20 [thunderbolt] process_one_work+0x675/0x1230 worker_thread+0x5e6/0xf70 kthread+0x365/0x470 ret_from_fork+0x54d/0x710 ret_from_fork_asm+0x1a/0x30 Freed by task 926: kfree+0x18f/0x4a0 tb_cfg_request_put+0xb7/0xe0 [thunderbolt] tb_cfg_request_work+0x82/0x120 [thunderbolt] process_one_work+0x675/0x1230 worker_thread+0x5e6/0xf70 kthread+0x365/0x470 ret_from_fork+0x54d/0x710 ret_from_fork_asm+0x1a/0x30 Second to last potentially related work creation: __queue_work+0x575/0xd00 queue_work_on+0x77/0x80 tb_cfg_request_cancel+0xc7/0x260 [thunderbolt] tb_cfg_request_sync+0x1f6/0x250 [thunderbolt] tb_cfg_read_raw+0x367/0x510 [thunderbolt] tb_cfg_read+0xec/0x240 [thunderbolt] tb_port_get_link_generation+0x258/0x420 [thunderbolt] tb_usb3_consumed_bandwidth+0x1c1/0x2c0 [thunderbolt] tb_tunnel_consumed_bandwidth+0xfd/0x910 [thunderbolt] tb_available_bandwidth+0x5f2/0xeb0 [thunderbolt] tb_recalc_estimated_bandwidth+0x2a0/0x1bc0 [thunderbolt] tb_handle_dp_bandwidth_request+0x1897/0x5e20 [thunderbolt] process_one_work+0x675/0x1230 worker_thread+0x5e6/0xf70 kthread+0x365/0x470 ret_from_fork+0x54d/0x710 ret_from_fork_asm+0x1a/0x30 The last stack trace is helpful because it shows that we are cancelling a request and looking at tb_cfg_request_cancel() what might happen is that tb_cfg_request_work() completes right before tb_cfg_request_cancel() starts and because of this it will call schedule_work() queueing the same work to run again. However, it is already removed from the request_queue and reference count is dropped so when tb_cfg_request_work() triggers again it will access memory that is already released. Fix this so that we first make sure a cancelled request is not handed away from tb_cfg_request_find() or scheduled to run. Then instead of relying on the worker to clean up the request we will do it in tb_cfg_request_cancel() after the work is canceled from running. Make tb_cfg_request_dequeue() release the request only if it was actually removed from the queue. Reported-by: Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com> Fixes: d7f781bfdbf4 ("thunderbolt: Rework control channel to be more reliable") Cc: stable@vger.kernel.org Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-02thunderbolt: Fix NULL dereference in tb_remove_work()Fedor Pchelkin
There is a slight race between tb_remove_work() and tb_domain_remove() which leads to dereferencing a NULL tb->root_switch pointer inside tb_free_unplugged_xdomains(): Thread A Thread B tb_remove_work() tb_domain_remove() mutex_lock(&tb->lock) tb_stop() /* doesn't cancel a running callback */ cancel_delayed_work(&tcm->remove_work) ... tb_switch_remove(tb->root_switch) tb->root_switch = NULL mutex_unlock(&tb->lock) mutex_lock(&tb->lock) ... /* without checking ->root_switch */ tb_free_unplugged_xdomains(tb->root_switch) mutex_unlock(&tb->lock) Commit a8937f35cf39 ("thunderbolt: Remove XDomain from the bus without holding tb->lock") doesn't seem right to move tb_free_unplugged_xdomains() out of the &tb->lock section and the check for tb->root_switch, in particular. It states: For this reason separate removing the XDomain from the topology data structures (where we need the lock) from unregistering the device from the bus (where remove callbacks of the drivers are being called). tb_free_unplugged_xdomains() belongs to the former group of functions requiring the lock. And it also calls tb_xdomain_remove() which should only be called with &tb->lock held. Found by Linux Verification Center (linuxtesting.org) with Svace static analysis tool. Fixes: a8937f35cf39 ("thunderbolt: Remove XDomain from the bus without holding tb->lock") Cc: stable@vger.kernel.org Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-01thunderbolt: Tear down inactive DP tunnels when the domain is stoppedSven Peter
tb_stop() only tears down DMA tunnels so a DP tunnel that is still waiting for dprx_work to complete keeps that work queued while the routers are removed and the control channel is stopped. The work only stops once the DPRX timeout has passed and because it requeues itself until then the flush_workqueue() in tb_domain_remove() won't wait for its final run. The callback then runs against a domain that is already torn down. A reference to that domain is kept so the completion waiting for that domain to disappear in unbind will block until the timeout is eventually reached. Tear down DP tunnels that are not active yet as well which also cancels that work. Tunnels for displays that are already alive are untouched and keep working. Fixes: d6d458d42e1e ("thunderbolt: Handle DisplayPort tunnel activation asynchronously") Cc: stable@vger.kernel.org Signed-off-by: Sven Peter <sven@kernel.org> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-01thunderbolt: Mark discovered tunnels as activeSven Peter
Discovered tunnels that have been activated by whatever was running before us stay in TB_TUNNEL_INACTIVE until hibernation restore such that anything depending on tb_tunnel_is_active() skips them. Mark them active during discovery instead. These now also emit TUNNEL_EVENT=activated uevents during discovery. Fixes: d6d458d42e1e ("thunderbolt: Handle DisplayPort tunnel activation asynchronously") Cc: stable@vger.kernel.org Signed-off-by: Sven Peter <sven@kernel.org> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-01thunderbolt: Don't access a DP tunnel after its DPRX read was canceledSven Peter
tb_dp_dprx_work() checks ->dprx_canceled before it takes tb->lock so it misses a tb_dp_dprx_stop() that could not cancel the already running work. It then polls the DPRX capabilities and runs the callback for a tunnel that has already been torn down while the domain is suspending or going away. This can be hit by cancelling the DPRX read from outside the ordered tb->wq: During suspend tb_disconnect_and_release_dp() does just this and with a later patch tb_stop() will do it as well. The latter in combination with the Apple NHI where the DPRX read never completed is how I hit this. Check the flag with tb->lock held instead and check it again in tb_dp_tunnel_active() because the callback runs after the lock has been dropped again. Also clear the flag in tb_dp_dprx_start() so that it only ever describes the work that is currently in flight. Fixes: d6d458d42e1e ("thunderbolt: Handle DisplayPort tunnel activation asynchronously") Cc: stable@vger.kernel.org Signed-off-by: Sven Peter <sven@kernel.org> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-01thunderbolt: Fix domain reference leak when DPRX read is canceledSven Peter
tb_tunnel_one_dp() takes a domain reference which is only dropped once tb_dp_tunnel_active() has run on the work queue. If that work is cancelled that reference is leaked. Since commit f5cc545f5969 ("thunderbolt: Wait for tb_domain_release() to complete when driver is removed") instead of just leaking memory this now also blocks in the completion wait forever when unbinding the driver. This can be triggered whenever a DP tunnel is torn down before the DPRX read has completed, e.g. by unplugging within the timeout, and then unbinding the driver. That reference only exists to keep the domain around while the DPRX work is scheduled so let the work itself own it: take it in tb_dp_dprx_start() and drop it in both places that end the work. Get/put are then paired inside the same file and it doesn't matter anymore if the callback ever runs. Fixes: d6d458d42e1e ("thunderbolt: Handle DisplayPort tunnel activation asynchronously") Cc: stable@vger.kernel.org Signed-off-by: Sven Peter <sven@kernel.org> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-01thunderbolt: Make the DP tunnel activation callback mandatorySven Peter
tb_tunnel_alloc_dp() takes an optional callback which is run from dprx_work once the DPRX capabilities read has completed. Without that callback tb_dp_dprx_start() reads the capabilities synchronously and never queues the work. It however always takes a tunnel reference which is only dropped by dprx_work itself or by tb_dp_dprx_stop() when cancel_delayed_work() actually canceled that work. That reference is thus leaked for every tunnel without a callback. The only tunnels without one are those from tb_tunnel_discover_dp(), which are activated again when restoring from hibernation. Pass the callback to tb_tunnel_discover_dp() as well and drop the synchronous path such that the DPRX capabilities are always read from dprx_work. Hibernation restore then also no longer blocks for up to 12 seconds while waiting for that read to complete. Also fix up the KUnit tests. Fixes: d6d458d42e1e ("thunderbolt: Handle DisplayPort tunnel activation asynchronously") Cc: stable@vger.kernel.org Signed-off-by: Sven Peter <sven@kernel.org> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-09-01thunderbolt: Hold a router reference for each allocated HopIDSven Peter
tb_stop() drops the reference to all DP tunnels but does not deactivate them, thus nothing cancels a dprx_work still in flight (which holds its own tunnel reference) and the tunnel can outlive tb_switch_remove(). The HopID releases in tb_path_free() then operate on freed IDAs and trigger warnings like ida_free called for id=8 which is not allocated. This can be triggered by unbinding the driver while a DP tunnel is still waiting for the DPRX capabilities read to finish. On the Apple NHI unplugging the cable runs into just that reliably because the read can never finish right now and because the unplug powers down the entire USB4 complex and removes the NHI device. Take a router reference whenever an input or output HopID is allocated and drop it again after the HopID is released. This keeps the ports and their HopID IDAs alive for as long as they are used. The KUnit tests allocate routers without ever registering their devices so initialize the embedded struct device there as well and drop its initial reference when the test is finished. Fixes: d6d458d42e1e ("thunderbolt: Handle DisplayPort tunnel activation asynchronously") Cc: stable@vger.kernel.org Signed-off-by: Sven Peter <sven@kernel.org> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-08-31thunderbolt: dma_test: Tear down DMA paths before stopping the ringsHaotian Zhang
dma_test_stop_rings() stops the RX and TX rings before calling tb_xdomain_disable_paths(). tb_ring_stop() zeroes the ring's descriptor base and the cancellation callbacks unmap and free the frame buffers, so by the time __tb_path_deactivate_hop() polls the hop's 'pending' bit any data still in flight has nowhere to drain to; on ASMedia ASM4242-class host routers the bit never clears and every teardown burns the full 500 ms timeout. This is the same defect as the one in tbnet_tear_down(), fixed as CVE-2026-74691 ("net: thunderbolt: Tear down DMA paths before stopping the rings"). Move the tb_xdomain_disable_paths() call before the tb_ring_stop() calls in dma_test_stop_rings(), so in-flight data drains while the rings are still active, and only then stop the rings and free the frame buffers. Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-08-31thunderbolt: Require complete DROM entry headersPengpeng Hou
tb_drom_parse_entries() checks for one byte remaining before reading a DROM entry header, but the header occupies two bytes. It also accepts a declared length of one byte. A one-byte tail consequently makes the parser read entry->len outside the DROM. A one-byte generic string entry reaches the subtype parser and underflows its payload-length calculation. Require a complete entry header before reading it and require the declared entry length to cover that header. Use subtraction-based bounds checks so the firmware-provided length cannot overflow the DROM extent calculation. While at it, use the actual const type instead of void * to make it clear we only read these. Assisted-by: Codex:gpt-5 Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-08-31thunderbolt: Stop waiting on a path pending bit that never clearsFan Ye
__tb_path_deactivate_hop() waits up to 500 ms for a hop's pending bit to read back clear. On an ASMedia ASM4242 host router the host interface adapter latches it once enough frames have gone through the DMA ring and never clears it again: the teardown finds it already set, seconds after the last frame and with the path still up. USB4 v2 table 8-23 has the field read only and zero unless packets belonging to the path are waiting to be dequeued, so the wait is right and this adapter is not. Make the wait a per-adapter length and quirk those routers to zero, which leaves the loop reading the bit exactly once. A hop that does drain still says so on that read, and one that does not answers -ETIMEDOUT without burning the timeout: bringing the interface down takes 6 ms where it took 506. Assisted-by: Claude:claude-opus-5 Signed-off-by: Fan Ye <fy15309206903@gmail.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
2026-08-19Merge tag 'thunderbolt-for-v7.3-rc1' of ↵Greg Kroah-Hartman
ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt into usb-next Mika writes: thunderbolt: Changes for v7.3 merge window This includes following USB4/Thunderbolt changes for the v7.3 merge window: - Assert Downstream Port Reset for Thunderbolt 3 devices during shutdown to avoid unnecessary delays over warm reset. - Tidy up Thunderbolt service ->probe callbacks. - USB4STREAM improvements. - AMD host interface quirk to fix Tx ring hang on teardown of a DMA tunnel. - Minor fixes and cleanups. All these have been in linux-next with no reported issues. * tag 'thunderbolt-for-v7.3-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt: thunderbolt: Clamp DMA tunnel credits to what a hop register can hold thunderbolt: Use min() for the DMA path credit cap thunderbolt: debugfs: Replace get_zeroed_page() with kzalloc() thunderbolt: Add quirk to reset host interface on DMA path teardown for AMD USB4 routers thunderbolt: stream: Add support for busy polling thunderbolt: Make interrupt optional for rings thunderbolt: stream: Support IOCB_NOWAIT in non-blocking I/O as well thunderbolt: stream: Fix possible short reads/writes thunderbolt: stream: Restore consumer if copying from iter fails thunderbolt: Remove redundant dev_err_probe() docs: admin-guide: thunderbolt: Fix sentence structure thunderbolt: xdomain: Notify peers after enumeration thunderbolt: Drop comma after device id array terminator thunderbolt: Assert that a service driver has a probe callback thunderbolt: Stop passing matched device ID to .probe() thunderbolt: Assert downstream port reset on shutdown