| Age | Commit message (Collapse) | Author |
|
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
# Conflicts:
# drivers/thunderbolt/tb.c
|
|
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
|
|
https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
|
|
https://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.git
|
|
__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>
|
|
* 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
|
|
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
|
|
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
...
|
|
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>
|
|
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
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
__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>
|
|
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
|