summaryrefslogtreecommitdiff
path: root/drivers
AgeCommit message (Collapse)AuthorFilesLines
2026-07-13Input: mms114 - fix endianness portability in I2C packet layoutDmitry Torokhov1-19/+33
The driver defines the I2C packet layout using C bitfields in struct mms114_touch. This is not portable as the layout of bitfields within a byte is compiler-dependent and varies with endianness. On Big Endian systems, the fields will be parsed incorrectly. Fix this by redefining struct mms114_touch with plain u8 fields and introducing bitwise macros to extract the values portably. Reported-by: sashiko-bot@kernel.org Assisted-by: Antigravity:gemini-3.5-flash Link: https://patch.msgid.link/20260704060115.353049-2-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2026-07-13Merge tag 'v7.2-rc3' into nextDmitry Torokhov7960-126433/+457731
Sync up with mainline to pull in stable fixes to avoid merge conflicts.
2026-07-14drm/i915/display: Fix NV12 ceiling division for bigjoiner caseVidya Srinivas1-20/+13
Commit 16df4cc63c58 ("drm/i915/display: Use ceiling division for NV12 UV surface offset calculation") computes the UV (chroma) surface start/size as ceiling(half of Y plane start/size) directly from the U16.16 fixed-point source rectangle: x = fp_16_16_to_int_ceil(fp_16_16_div2(src.x1)); For a single pipe the source coordinates are integers, so this is correct. (UV start = ceiling(half of Y plane start)). With bigjoiner + a plane scaler the picture changes. The pipe boundary is a fixed integer destination pixel, but the plane's position and the scaler ratio are arbitrary, so drm_rect_clip_scaled() maps the seam back to a *fractional* per-pipe source. For a 1280->2407 upscaled NV12 plane crossing the seam: master src: width = 1204 * 1280/2407 = 640.265899, x1 = 0 joiner src: width = 1203 * 1280/2407 = 639.734115, x1 = 640.265884 The luma path floors this to an integer (src.x1 >> 16 = 640), but the UV path takes ceiling(640.265884 / 2) = ceil(320.13) = 321. The Y plane then starts at column 640 while the UV plane starts at 321*2 = 642, pushing the chroma read one column past the 640-wide chroma surface on the joiner secondary: [CRTC:382:pipe C] PLANE ATS fault [CRTC:382:pipe C][PLANE:267:plane 1C] fault (CTL=0x81009400, ...) The spec "Y plane start" is the integer pixel the luma surface actually programs (640), not the pre-floor fixed-point value (640.27). Convert the Y plane start/size to integer first - matching skl_check_main_surface() - and then apply the ceiling. This is a no-op for the integer (non-joiner) case and yields the correct, in-bounds chroma offset for the fractional joiner seam: before fix after fix master 1B: x=0 w=321 x=0 w=320 -> [0, 320) slave 1C: x=321 w=320 x=320 w=320 -> [320, 640) The two halves now tile the 640-wide chroma plane exactly and the ATS fault is gone. Assisted-by: GitHub-Copilot:Claude-Opus-4.8 Fixes: 16df4cc63c58 ("drm/i915/display: Use ceiling division for NV12 UV surface offset calculation") Signed-off-by: Vidya Srinivas <vidya.srinivas@intel.com> Reviewed-by: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com> Signed-off-by: Uma Shankar <uma.shankar@intel.com> Link: https://patch.msgid.link/20260618181837.687302-1-vidya.srinivas@intel.com
2026-07-14Merge tag 'rust-io-7.3-rc1' of ↵Danilo Krummrich4-116/+92
git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core into drm-rust-next I/O type generalization and projection This series presents a major rework of I/O types, as a summary: - Make I/O regions typed. The existing untyped region still exists with a dynamically sized `Region` type. - Create I/O view types to represent subregion of a full I/O region mapped. A projection macro is added to allow safely create such subviews. - Split I/O traits, make I/O views play a central role, avoid duplicate monomorphization and less `unsafe` code. - Add a `SysMem` backend, and make `Coherent` implement `Io`. - Add copying methods (memcpy_{from,to}io and friends). This series generalize `Mmio` type from just an untyped region to typed representations (so `MmioRaw<T>` is `__iomem *T`). This allows us to remove the `IoKnownSize` trait; the information is sourced from just the pointer from the `KnownSize` trait instead. Building on top of that, `Mmio` and `ConfigSpace` have been converted to typed views of I/O regions rather than just a big chunk of untyped I/O memory. These changes made it possible to implement `Io` trait for `Coherent<T>`. Shared system memory, `SysMem` is also added to the series, given it similarity in implementation compared to `Coherent`. In fact, the series use `SysMem` to implement `Coherent`'s I/O methods. Built on these generalization, this series add `io_project!()`. `io_project!()` performs a safe way to project a bigger view to a small subviews, and some Nova code has been converted in this series to demonstrate cleanups possible with this addition. New `io_read!()`, `io_write!()` has been added that supersedes `dma_read!()`, `dma_write!()` macro. Although, they work for primitives only (to be exact, types that the backend is `IoCapable` of). One feature that was lost from the old `dma_read!()` and `dma_write!()` series was the ability to read/write a large structs. However, the semantics was unclear to begin with, as there was no guarantee about their atomicity even for structs that were small enough to fit in u32. Suggested-by: Danilo Krummrich <dakr@kernel.org> Link: https://rust-for-linux.zulipchat.com/#narrow/channel/288089-General/topic/Generic.20I.2FO.20backends/near/571198078 This is a stable tag for other trees to merge. Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-13Merge patch series "rust: I/O type generalization and projection"Danilo Krummrich4-116/+92
Gary Guo <gary@garyguo.net> says: This series presents a major rework of I/O types, as a summary: - Make I/O regions typed. The existing untyped region still exists with a dynamically sized `Region` type. - Create I/O view types to represent subregion of a full I/O region mapped. A projection macro is added to allow safely create such subviews. - Split I/O traits, make I/O views play a central role, avoid duplicate monomorphization and less `unsafe` code. - Add a `SysMem` backend, and make `Coherent` implement `Io`. - Add copying methods (memcpy_{from,to}io and friends). This series generalize `Mmio` type from just an untyped region to typed representations (so `MmioRaw<T>` is `__iomem *T`). This allows us to remove the `IoKnownSize` trait; the information is sourced from just the pointer from the `KnownSize` trait instead. Building on top of that, `Mmio` and `ConfigSpace` have been converted to typed views of I/O regions rather than just a big chunk of untyped I/O memory. These changes made it possible to implement `Io` trait for `Coherent<T>`. Shared system memory, `SysMem` is also added to the series, given it similarity in implementation compared to `Coherent`. In fact, the series use `SysMem` to implement `Coherent`'s I/O methods. Built on these generalization, this series add `io_project!()`. `io_project!()` performs a safe way to project a bigger view to a small subviews, and some Nova code has been converted in this series to demonstrate cleanups possible with this addition. New `io_read!()`, `io_write!()` has been added that supersedes `dma_read!()`, `dma_write!()` macro. Although, they work for primitives only (to be exact, types that the backend is `IoCapable` of). One feature that was lost from the old `dma_read!()` and `dma_write!()` series was the ability to read/write a large structs. However, the semantics was unclear to begin with, as there was no guarantee about their atomicity even for structs that were small enough to fit in u32. Suggested-by: Danilo Krummrich <dakr@kernel.org> Link: https://rust-for-linux.zulipchat.com/#narrow/channel/288089-General/topic/Generic.20I.2FO.20backends/near/571198078 Link: https://patch.msgid.link/20260706-io_projection-v6-0-72cd5d055d54@garyguo.net Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-13Merge patch series "ForLt/CovariantForLt split, auxiliary closure API and ↵Danilo Krummrich2-5/+4
DevresLt" Danilo Krummrich <dakr@kernel.org> says: The ForLt trait currently guarantees covariance, which allows safe lifetime shortening via cast_ref(). However, some types (e.g. those containing Mutex<&'bound T>) are invariant over their lifetime parameter and cannot safely use cast_ref(). This series splits ForLt into two traits: - ForLt: base trait for all lifetime-parameterized types, providing only the Of<'a> GAT. - CovariantForLt: unsafe subtrait that guarantees covariance, providing a safe cast_ref() method. For invariant types, a closure-based API (registration_data_with()) is added to the auxiliary subsystem. The closure's HRTB prevents the caller from choosing a concrete lifetime, which would be unsound for invariant types. On top of that, this series adds DevresLt<F: ForLt>, a thin wrapper around Devres<F::Of<'static>> that shortens the stored 'static lifetime back to the caller's borrow scope. DevresLt provides both closure-based access (access_with/try_access_with for ForLt types) and direct reference access (access/try_access for CovariantForLt types). Also implement ForLt and CovariantForLt for Bar, IoMem and ExclusiveIoMem, and update their into_devres() methods to return DevresLt. Provide convenience type aliases DevresBar, DevresIoMem and DevresExclusiveIoMem. Link: https://patch.msgid.link/20260626183630.2585057-1-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-13drm/xe/multi_queue: preempt primary on queue group suspendNiranjana Vishwanathapura3-17/+166
In a multi-queue group only the group's primary queue interfaces with GuC for scheduling; suspend/resume of secondary queues is handled internally and is not forwarded to GuC. As a result, suspending a secondary queue alone (e.g. on its preempt fence signalling) does not disable the primary's GuC context, so in-flight GPU work of the group is not actually preempted. Make a secondary queue suspend/resume like any other queue, driven by its own xe_guc_exec_queue.suspend_count, and additionally forward the suspend/resume to the primary so the GPU is actually preempted. The forward is gated on the secondary's own 0->1 / 1->0 suspend_count transition, so each group member contributes exactly one suspend reference to the primary: the primary keeps its GuC context disabled until every member that suspended it has resumed, including across the resume-all-queues-each-rebind-cycle behavior. group->suspend_lock makes the secondary transition and the primary forward atomic, and a member leaving while still suspended (queue teardown) drops its reference on the primary. v2: Add comment about suspend_wait() in drop_suspend() v3: Do not suspend a secondary if primary is killed, wait for primay suspend to complete before drop_suspend() Assisted-by: Github-Copilot:Claude-opus-4.8 Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Link: https://patch.msgid.link/20260713202317.2187787-14-niranjana.vishwanathapura@intel.com
2026-07-13drm/xe/guc: Add suspend refcount to exec queue opsThomas Hellström2-9/+28
With the lr.suspended flag a consumer already pairs its own suspend() and resume() correctly, and no current path issues overlapping suspends on the same queue. Add a reference count to the exec queue suspend operations, as a small self-contained building block for callers that can genuinely overlap. A queue stays suspended as long as any caller holds a suspend and only resumes once the last caller releases it, so each caller pairs its own suspend/resume without needing to know about the others. This is what the upcoming multi-queue support needs, where queues in a group share a primary and may be suspended concurrently. Assisted-by: GitHub_Copilot:claude-sonnet-4.6 Co-authored-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Link: https://patch.msgid.link/20260713202317.2187787-13-niranjana.vishwanathapura@intel.com
2026-07-13drm/xe/hw_engine_group: propagate suspend failures during mode switchNiranjana Vishwanathapura1-3/+82
The hw engine group fault-mode switch suspends all faulting LR queues but ignored the suspend()/suspend_wait() return value. A suspend() can fail (e.g. the queue is killed/banned/wedged), leaving the queue un-suspended, so silently continuing could later resume a queue that was never suspended. Propagate the failure instead: in xe_hw_engine_group_add_exec_queue() bail out if suspend() fails, and in xe_hw_engine_group_suspend_faulting_lr_jobs() undo the partial suspend via a new err_resume path that resumes the sibling queues already suspended in this call. Record per-queue success with lr.suspended so only queues that were actually suspended are waited on and resumed, and skip the cleanup resume() when suspend_wait() failed or the queue was reset/killed/banned/wedged (its suspend may not have completed, so resuming would trip the !suspend_pending assert in the resume path; teardown resolves its state instead). Gate the group resume worker (hw_engine_group_resume_lr_jobs_func()) on lr.suspended for the same reason, so it only resumes queues that were actually suspended. v2: Don't let a dying queue block the switch (Matt Brost) Assisted-by: Github-Copilot:Claude-opus-4.8 Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Link: https://patch.msgid.link/20260713202317.2187787-12-niranjana.vishwanathapura@intel.com
2026-07-13drm/xe/guc: add uninterruptible suspend wait for cross-process cleanupNiranjana Vishwanathapura3-0/+49
Add a suspend_wait_blocking() exec queue op: an uninterruptible variant of suspend_wait() for callers that must complete a suspend on behalf of a queue that may belong to a different process than the calling task (e.g. cleanup/undo paths). An interruptible suspend_wait() returns -ERESTARTSYS when the calling task is signalled, which would leave the other process's queue suspended forever - a cross-process DoS. The blocking variant waits uninterruptibly and, on a genuine GuC timeout, bans and tears down the queue like suspend_wait() (shared via guc_exec_queue_suspend_timeout_ban()). It deliberately does not handle VF recovery since a blocking caller cannot retry. Assisted-by: Github-Copilot:Claude-opus-4.8 Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Link: https://patch.msgid.link/20260713202317.2187787-11-niranjana.vishwanathapura@intel.com
2026-07-13drm/xe/guc: ban exec queue on suspend timeoutNiranjana Vishwanathapura1-4/+49
Harden guc_exec_queue_suspend_wait(): - In multi-queue mode the primary owns the group's GuC scheduling context, so wait on the primary's suspend to complete. - On timeout, ban the queue and trigger cleanup rather than leaving it suspended forever. Clearing suspend_pending via __suspend_fence_signal() lets a subsequent resume() proceed without tripping the !suspend_pending assert. A timeout on the primary wedges the whole group, so ban and tear down the entire group in the multi-queue case. The ban/cleanup is factored into guc_exec_queue_suspend_timeout_ban(). Add a note that on a signal (-ERESTARTSYS) the queue is not banned and the suspend is not confirmed complete, so callers must not resume() without re-confirming. Assisted-by: Github-Copilot:Claude-opus-4.8 Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Link: https://patch.msgid.link/20260713202317.2187787-10-niranjana.vishwanathapura@intel.com
2026-07-13drm/xe: only resume exec queues that were actually suspendedNiranjana Vishwanathapura3-1/+36
A consumer-issued suspend() can fail (e.g. the queue is killed, banned or wedged), leaving the queue un-suspended. The consumer must then not issue the matching resume(): resuming a queue that was never suspended is incorrect. Add an lr.suspended flag to struct xe_exec_queue that records whether a consumer suspend() succeeded and a matching resume() is still owed. Set it on a successful suspend() in the preempt-fence path, clear it on resume(), and only resume queues that have it set. In resume_and_reinstall_preempt_fences() also skip queues that have since been reset/killed/banned/wedged: such a queue's suspend may not have completed (suspend_pending can still be set, e.g. a preempt fence signalled with -ENOENT without waiting), so resuming it would trip the !suspend_pending assert in the backend. Leave it marked suspended and let teardown resolve its state. A queue is only ever suspended by a single consumer at a time (preempt-fence mode and hw engine group fault mode are mutually exclusive), so a single flag is sufficient. Assisted-by: Github-Copilot:Claude-opus-4.8 Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Link: https://patch.msgid.link/20260713202317.2187787-9-niranjana.vishwanathapura@intel.com
2026-07-13drm/i915/gt: use correct selftest config symbolPengpeng Hou1-1/+1
intel_engine_user.c checks CONFIG_DRM_I915_SELFTESTS before running the engine UABI isolation check. Kconfig defines DRM_I915_SELFTEST, without the trailing "S", and the rest of i915 uses CONFIG_DRM_I915_SELFTEST. Because CONFIG_DRM_I915_SELFTESTS is not backed by any Kconfig symbol, the IS_ENABLED() test is always false. Use the existing selftest symbol so the debug/selftest guarded path can be reached when selftests are enabled. This is a source-level fix. It does not claim dynamic hardware reproduction; the evidence is the Kconfig definition and the inconsistent guard in intel_engine_user.c. Fixes: 750e76b4f9f6 ("drm/i915/gt: Move the [class][inst] lookup for engines onto the GT") Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn> Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net> Link: https://lore.kernel.org/r/20260705080225.436-1-pengpeng@iscas.ac.cn (cherry picked from commit 14a2012a490258f3f93857bc4f1b203405964be7) Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
2026-07-13dm-verity: remove pointless nested "bio" declarationMikulas Patocka1-2/+0
Remove pointless declaration of "bio" and initialization using "dm_bio_from_per_bio_data". The variable "bio" is already declared and initialized in the upper block. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4.6
2026-07-13dm-table: fix spellingMikulas Patocka1-1/+1
Fix spelling: impementation -> implementation. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4.6
2026-07-13dm-ioctl: delete a useless conditionMikulas Patocka1-4/+0
The condition "remaining <= 0" can never be true. The variable remaining has type size_t, thus it can't be negative. It can't be zero because we made sure earlier that "remaining > sizeof(struct dm_target_spec)" and then we added "sizeof(struct dm_target_spec)" to "outptr" (this means that we subtraceted "sizeof(struct dm_target_spec)" from "remaining"). Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4.6
2026-07-13dm-integrity: fix wrong fallthrough in integrity_bio_waitMikulas Patocka1-1/+2
If dm_integrity_map_inline returned DM_MAPIO_KILL, the code would set status BLK_STS_IOERR and then incorrectly fall through and submit the bio. Luckily, dm_integrity_map_inline can't return DM_MAPIO_KILL at this point, so the bug is just theoretical. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4.6
2026-07-13dm-integrity: clean-up error handlingMikulas Patocka1-0/+1
Add "goto bad" to error handling. This commit doesn't fix any bug, just cleans up the code. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4.6
2026-07-13dm-integrity: fix error messageMikulas Patocka1-1/+1
Change "reading tags" to "writing tags" because the error is reported when writing fails. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4.6
2026-07-13drm/panel: novatek-nt37801: Use mipi_dsi_*_multi() functionsNicolás Antinori1-60/+46
Replace mipi_dsi_* functions with their non-deprecated mipi_dsi_*_multi counterparts. This change reduces error-checking boilerplate and improves readability. Signed-off-by: Nicolás Antinori <nico.antinori.7@gmail.com> Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://patch.msgid.link/20260706224414.1015766-1-nico.antinori.7@gmail.com
2026-07-13regcache: Mark cache dirty if selector register rewrite failsbui duc phuc1-0/+1
After a successful cache synchronization, regcache_sync() clears cache_dirty. If rewriting a selector register later fails, the cache and hardware become inconsistent while the cache still appears clean. Update cache_dirty to reflect the cache and hardware state when selector register rewriting fails. Signed-off-by: bui duc phuc <phucduc.bui@gmail.com> Link: https://patch.msgid.link/20260713050312.38729-3-phucduc.bui@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2026-07-13regcache: Preserve cache synchronization errors in regcache_sync()bui duc phuc1-11/+12
regcache_sync() currently stores the return value from both cache synchronization and selector register rewriting in the same variable. As a result, a successful selector register rewrite can overwrite an earlier cache synchronization error, causing regcache_sync() to return success even though synchronization failed. Track the two operations with separate return variables and preserve the cache synchronization error. Errors from rewriting selector registers are returned only if cache synchronization completed successfully. Signed-off-by: bui duc phuc <phucduc.bui@gmail.com> Link: https://patch.msgid.link/20260713050312.38729-2-phucduc.bui@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
2026-07-13iommufd: Reject DMABUF pages from the access pin pathPeiyang He1-0/+3
DMABUF pages are not supported for iommufd access pinning. iommufd_access_pin_pages() returns struct page pointers for in-kernel CPU access, but DMABUF-backed iopt_pages do not carry a userspace address that can be passed to the GUP path. iopt_pages_rw_access() already rejects IOPT_ADDRESS_DMABUF before doing CPU access. Apply the same rejection to iopt_area_add_access() before it takes pages->mutex and calls iopt_pages_fill_xarray(). Otherwise a DMABUF-backed iopt_pages can reach the hole-fill path, where pfn_reader_user_pin() interprets the union as uptr and calls pin_user_pages_fast()/pin_user_pages_remote(). This fix also avoids the lockdep warning reported from that path, where pages_dmabuf_mutex_key is held while gup_fast_fallback() may acquire mmap_lock. Link: https://patch.msgid.link/r/CD68F549BF3761B7+20260709050800.520607-1-peiyang_he@smail.nju.edu.cn Reported-by: Peiyang He <peiyang_he@smail.nju.edu.cn> Closes: https://lore.kernel.org/all/E8540D7D05768C91+8b2ef227-3368-494e-909d-7b28e1489dfb@smail.nju.edu.cn/ Fixes: 71db84a092c3 ("iommufd: Add DMABUF to iopt_pages") Cc: stable@vger.kernel.org Tested-by: Peiyang He <peiyang_he@smail.nju.edu.cn> Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
2026-07-13iommufd: Fix wrong hwpt passed to iommufd_auto_response_faults on replacePeiyang He1-1/+1
iommufd_hwpt_replace_device() calls: iommufd_auto_response_faults(hwpt, old_handle); passing the *new* hwpt together with the handle of the device's *old* domain. This should be a parameter mismatch: 1. Semantically, iommufd_auto_response_faults(x, handle) scans x->fault's deliver list and response xarray for groups matching "handle". A group is queued under the hwpt that was attached at fault-delivery time. old_handle is fetched *before* the domain switch, so its group lives on old->fault, not on the new hwpt->fault. 2. Historically, the first argument was "old". The routine was introduced by commit b7d8833677ba ("iommufd: Fault-capable hwpt attach/detach/replace") as __fault_domain_replace_dev() in fault.c, correctly calling iommufd_auto_response_faults(old, curr). Commit fb21b1568ada ("iommufd: Make attach_handle generic than fault specific") moved this into iommufd_hwpt_replace_device() in device.c and swapped it to "hwpt". This should be a refactor regression, not an intentional change. Fix this by passing "old" instead. Link: https://patch.msgid.link/r/9D652384339C69D5+20260710122952.885325-1-peiyang_he@smail.nju.edu.cn Fixes: fb21b1568ada ("iommufd: Make attach_handle generic than fault specific") Cc: stable@vger.kernel.org Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
2026-07-13drm/virtio: fix deadlock in display_info_cb by removing hotplug from dequeue ↵Ryosuke Yasuoka2-4/+4
worker A probe-time deadlock can occur between the dequeue worker and drm_client_register(). During probe, drm_client_register() holds clientlist_mutex and calls the fbdev hotplug callback, which triggers an atomic commit that ends up sleeping in virtio_gpu_queue_ctrl_sgs() waiting for virtqueue space. The dequeue worker that would free that space calls virtio_gpu_cmd_get_display_info_cb(), which invokes drm_kms_helper_hotplug_event() -> drm_client_dev_hotplug(), attempting to acquire the same clientlist_mutex. Since wake_up() is only called after the resp_cb loop, the probe thread is never woken and both threads deadlock. Fix this by removing the hotplug notification from virtio_gpu_cmd_get_display_info_cb(). The display data (outputs[i].info) is still updated synchronously in the callback. For the init path, drm_client_register() already fires an initial hotplug when the client is registered, which picks up the connector state updated by display_info_cb. For the runtime config_changed path, add a wait_event_timeout() in config_changed_work_func() so that display_info_cb updates the connector data before the hotplug notification is sent. Also replace drm_helper_hpd_irq_event() with drm_kms_helper_hotplug_event() since virtio-gpu never calls drm_kms_helper_poll_init() and thus drm_helper_hpd_irq_event() always returns false without doing anything. Fixes: 27655b9bb9f0 ("drm/client: Send hotplug event after registering a client") Closes: https://syzkaller.appspot.com/bug?id=d6dd6f86d3aaf7eebe7406e45c1c6e549453f224 Closes: https://syzkaller.appspot.com/bug?id=908bd910da5dd79b88de4cf7baf376cc873a922e Suggested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> Signed-off-by: Ryosuke Yasuoka <ryasuoka@redhat.com> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> Link: https://patch.msgid.link/20260713-virtiogpu_syzbot-v2-1-2958fa37d46d@redhat.com
2026-07-14media: em28xx: requeue buffers if start_streaming failsHans Verkuil1-2/+16
If start_streaming fails, then all queued buffers must be returned to vb2 in state QUEUED. Otherwise it will trigger a WARN_ON. Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org> Tested-by: Hans Verkuil <hverkuil+cisco@kernel.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2026-07-14media: em28xx: dev_info->pr_info since dev has been freedHans Verkuil1-1/+1
In em28xx_free_device() dev_info passed &dev->intf->dev, but that device can be freed already. Just use pr_info instead. Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org> Tested-by: Hans Verkuil <hverkuil+cisco@kernel.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2026-07-14media: em28xx: use vb2_video_unregister_deviceHans Verkuil1-6/+6
Use vb2_video_unregister_device instead of video_unregister_device to ensure any streaming is correctly stopped at unregister time. Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org> Tested-by: Hans Verkuil <hverkuil+cisco@kernel.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2026-07-14media: em28xx: drop 'users' fieldHans Verkuil2-12/+7
Drop the em28xx_v4l2 'users' field, use v4l2_fh_is_singular_file() instead. Assisted-by: Claude:claude-opus-4-7 Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org> Tested-by: Hans Verkuil <hverkuil+cisco@kernel.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2026-07-14media: em28xx: use v4l2_device release callbackHans Verkuil2-26/+41
The em28xx driver creates a lot of video devices, but life-time management is really bad. Instead use the struct v4l2_device release() callback to have a single place where memory can be freed once the last user has gone. Assisted-by: Claude:claude-opus-4-7 Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org> Tested-by: Hans Verkuil <hverkuil+cisco@kernel.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2026-07-14media: v4l2-async: Unregister sub-device if asc_list is emptyHans Verkuil1-3/+12
When my em28xx USB device that uses the i2c tvp5150 driver is disconnected, it crashes. The cause is that the tvp5150 i2c module uses v4l2_async, but the em28xx driver does not since it predates v4l2_async. In that corner case sd->asc_list is empty, so v4l2_async_unregister_subdev() never calls v4l2_device_unregister_subdev(). Modify the code so that, if sd->asc_list is empty, v4l2_device_unregister_subdev() is still called. Fixes: 28a1295795d8 ("media: v4l: async: Allow multiple connections between entities") Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org> Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com> Tested-by: Hans Verkuil <hverkuil+cisco@kernel.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2026-07-13drm/virtio: Don't detach GEM from a non-created contextJason Macnak1-6/+8
Applies the same treatment as commit 7cf6dd467e87 ("drm/virtio: Don't attach GEM to a non-created context in gem_object_open()") to virtio_gpu_gem_object_close() to avoid trying to detach a resource that was never attached due to a context never being created when context_init is supported. Fixes: 086b9f27f0ab ("drm/virtio: Don't create a context with default param if context_init is supported") Cc: <stable@vger.kernel.org> # v6.14+ Signed-off-by: Jason Macnak <natsu@google.com> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> Link: https://patch.msgid.link/20260625170828.3335431-1-natsu@google.com
2026-07-13soc: imx9: devm_kasprintf error handlingGriffin Kroah-Hartman1-0/+9
Add error handling to devm_kasprintf functions in imx9_soc_probe(). Assisted-by: gkh_clanker_2000 Cc: Frank Li <Frank.Li@nxp.com> Cc: Sascha Hauer <s.hauer@pengutronix.de> Cc: Pengutronix Kernel Team <kernel@pengutronix.de> Cc: Fabio Estevam <festevam@gmail.com> Cc: Peng Fan <peng.fan@nxp.com> Cc: Shawn Guo <shawnguo@kernel.org> Cc: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> Signed-off-by: Griffin Kroah-Hartman <griffin@kroah.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Frank Li <Frank.Li@nxp.com>
2026-07-13iommufd/selftest: Fix dmabuf leak in iommufd_test_dmabuf_get()yeeli1-1/+6
When dma_buf_export() succeeds but dma_buf_fd() fails (e.g. -EMFILE from fd exhaustion), the dmabuf is leaked with no dma_buf_put() called. Reproducer: exhaust fd table near RLIMIT_NOFILE, then repeatedly call IOMMU_TEST_OP_DMABUF_GET — htop shows unbounded memory growth. Fix by calling dma_buf_put(dmabuf) on error and returning directly. Fixes: d2041f1f11dd ("iommufd/selftest: Add some tests for the dmabuf flow") Link: https://patch.msgid.link/r/20260707030635.221577-1-seven.yi.lee@gmail.com Signed-off-by: yeeli <seven.yi.lee@gmail.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
2026-07-13Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdmaLinus Torvalds9-46/+84
Pull rdma fixes from Jason Gunthorpe: "More bug fixes, many found by tools: - Protect from a possible DOS with certain RMPP traffic patterns - Correct mac address comparison so CMA works properly on IB - Some crashes in irdma around memory registration - Uninitialized value in erdma and mana - Wrong order setting up a QP in SIW allowed a network packet to reach an unready QP struct - Catch math overflows in hns and irdma" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: RDMA/irdma: Prevent overflows in memory contiguity checks RDMA/siw: publish QP after initialization RDMA/hns: Fix potential integer overflow in mhop hem cleanup RDMA/core: Fix memory leak in __ib_create_cq() on invalid cqe RDMA/mana_ib: initialize err for empty send WR lists RDMA/erdma: initialize ret for empty receive WR lists RDMA/irdma: Prevent user-triggered null deref on QP create RDMA/irdma: Prevent rereg_mr for non-mem regions RDMA/cma: Fix hardware address comparison length in netevent callback RDMa/mlx5: Avoid frame overflow warning IB/mad: Drop unmatched RMPP responses before reassembly
2026-07-13firmware: qcom: scm: Add minidump SRAM supportMukesh Ojha1-0/+92
On most Qualcomm SoCs where minidump is supported, a word in always-on SRAM is shared between the operating system (OS) and boot firmware. Before DDR is initialized on the warm reset following a crash, firmware reads this word to decide if minidump is enabled and collect a minidump, and where to deliver it (USB upload to a host, or save to local storage). The OS is expected to select one of the destinations. The SRAM region is described by a 'sram' phandle on the SCM DT node. If the property is absent the feature is silently disabled, keeping existing SoCs unaffected. Expose a 'minidump_dest' module parameter (default: usb) so the user can select the destination. Only the string names "usb" or "storage" are accepted. Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com> Link: https://lore.kernel.org/r/20260624190830.3131112-6-mukesh.ojha@oss.qualcomm.com Signed-off-by: Bjorn Andersson <andersson@kernel.org>
2026-07-13firmware: qcom: scm: use dev_err_probe() for dload address failureMukesh Ojha1-1/+2
Replace the bare `return ret` after qcom_scm_find_dload_address() with dev_err_probe() to produce a consistent, deferred-probe-aware error message when the download-mode address cannot be resolved. Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com> Link: https://lore.kernel.org/r/20260624190830.3131112-5-mukesh.ojha@oss.qualcomm.com Signed-off-by: Bjorn Andersson <andersson@kernel.org>
2026-07-13firmware: qcom: scm: Fix missing smp_load_acquire()Mukesh Ojha1-11/+14
__scm is published in qcom_scm_probe() with smp_store_release() but qcom_scm_set_download_mode() reads it directly without smp_load_acquire(), creating a potential ordering violation where a CPU could observe a stale or partially initialised __scm pointer. Use smp_load_acquire() to acquire __scm in the qcom_scm_set_download_mode() function. Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com> Link: https://lore.kernel.org/r/20260624190830.3131112-4-mukesh.ojha@oss.qualcomm.com Signed-off-by: Bjorn Andersson <andersson@kernel.org>
2026-07-13drm/msm: Switch to generic PAS TZ APIsSumit Garg3-7/+9
Switch drm/msm client drivers over to generic PAS TZ APIs. Generic PAS TZ service allows to support multiple TZ implementation backends like QTEE based SCM PAS service, OP-TEE based PAS service and any further future TZ backend service. Acked-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Reviewed-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com> Tested-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com> # Lemans Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com> Link: https://lore.kernel.org/r/20260702115835.167602-9-sumit.garg@kernel.org Signed-off-by: Bjorn Andersson <andersson@kernel.org>
2026-07-13Bluetooth: hci_qca: Clear memdump state on invalid dump sizeRuoyu Wang1-0/+4
qca_controller_memdump() allocates qca->qca_memdump before processing the first dump packet. For a sequence-zero packet it then disables IBS, marks memdump collection active, and reads the advertised dump size. If the controller reports a zero dump size, the error path frees the local qca_memdump object and returns without clearing qca->qca_memdump or undoing the collection state. A later memdump work item initializes its local pointer from qca->qca_memdump and skips allocation when that pointer is non-NULL, so it can operate on freed memory. The stale collection and IBS-disabled flags can also leave waiters or later transmit handling blocked behind an aborted dump. Clear the saved pointer and memdump state before returning from the invalid-size path, matching the cleanup used when hci_devcd_init() fails. A static analysis checker reported the stale memdump state, and manual source review confirmed the invalid-size failure path. Fixes: 06d3fdfcdf5c ("Bluetooth: hci_qca: Add qcom devcoredump support") Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com> Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de> Reviewed-by: Zijun Hu <zijun.hu@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-07-13Bluetooth: btrtl: validate firmware patch boundsLaxman Acharya Padhya1-2/+3
rtlbt_parse_firmware() copies patch_length - 4 bytes before appending the firmware version. A malformed firmware patch shorter than the version field can make this subtraction underflow and turn the copy into an oversized read and write during Bluetooth setup. The existing patch_offset + patch_length check can also wrap on 32-bit architectures. Validate the patch length and range without arithmetic overflow before allocating or copying the patch. Fixes: db33c77dddc2 ("Bluetooth: btrtl: Create separate module for Realtek BT driver") Cc: stable@vger.kernel.org Signed-off-by: Laxman Acharya Padhya <acharyalaxman8848@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-07-13Bluetooth: qca: fix NVM tag length underflow in TLV parserXiang Mei1-1/+1
In the TLV_TYPE_NVM branch of qca_tlv_check_data() the tag loop bound is "while (idx < length - sizeof(struct tlv_type_nvm))". "length" is a signed int from the firmware TLV header and sizeof(struct tlv_type_nvm) is a size_t (12), so "length" is converted to size_t and any firmware-supplied "length" < 12 makes the subtraction wrap to a huge value. The loop body then reads a 12-byte struct tlv_type_nvm past the end of the short vmalloc'd firmware buffer (and the EDL_TAG_ID_* handlers can write past it). Rewrite the bound as "idx + sizeof(struct tlv_type_nvm) <= length"; both operands are non-negative, so it no longer underflows and a "length" too small for one record correctly skips the loop. BUG: KASAN: vmalloc-out-of-bounds in qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421) Read of size 2 at addr ffffc900000e5004 by task kworker/u9:0/52 Workqueue: hci0 hci_power_on Call Trace: ... kasan_report (mm/kasan/report.c:595) qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421 drivers/bluetooth/btqca.c:617) qca_uart_setup (drivers/bluetooth/btqca.c:948) qca_setup (drivers/bluetooth/hci_qca.c:2029) hci_uart_setup (drivers/bluetooth/hci_ldisc.c:438) hci_dev_open_sync (net/bluetooth/hci_sync.c:5227) hci_power_on (net/bluetooth/hci_core.c:920) process_one_work (kernel/workqueue.c:3322) worker_thread (kernel/workqueue.c:3486) kthread (kernel/kthread.c:436) ret_from_fork (arch/x86/kernel/process.c:158) ret_from_fork_asm (arch/x86/entry/entry_64.S:245) Fixes: 2e4edfa1e2bd ("Bluetooth: qca: add missing firmware sanity checks") Reported-by: Weiming Shi <bestswngs@gmail.com> Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Xiang Mei <xmei5@asu.edu> Reported-by: Weiming Shi <bestswngs@gmail.com> Reviewed-by: Johan Hovold <johan@kernel.org> Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-07-13wifi: carl9170: fix buffer overflow in rx_stream failover pathTristan Madani1-1/+3
The failover continuation in carl9170_rx_stream() copies the full tlen from the second USB transfer instead of capping at rx_failover_missing bytes. When both transfers are near maximum size, the total exceeds the 65535-byte failover SKB, triggering skb_over_panic. Limit the copy size to the missing byte count. Fixes: a84fab3cbfdc ("carl9170: 802.11 rx/tx processing and usb backend") Signed-off-by: Tristan Madani <tristan@talencesecurity.com> Acked-by: Christian Lamparter <chunkeey@gmail.com> Closes: https://syzkaller.appspot.com/bug?extid=5c1ca6ccaa1215781cac Link: https://patch.msgid.link/20260421134929.325662-4-tristmd@gmail.com [Fix checkpatch CHECK:PARENTHESIS_ALIGNMENT] Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
2026-07-13wifi: carl9170: fix OOB read from off-by-two in TX status handlerTristan Madani1-1/+1
The bounds check in carl9170_tx_process_status() uses `i > ((cmd->hdr.len / 2) + 1)` which is off by two, allowing 2 extra iterations past valid _tx_status entries when the firmware- controlled hdr.ext exceeds hdr.len/2. Fix by using the correct comparison `i >= (cmd->hdr.len / 2)`. Fixes: a84fab3cbfdc ("carl9170: 802.11 rx/tx processing and usb backend") Signed-off-by: Tristan Madani <tristan@talencesecurity.com> Acked-by: Christian Lamparter <chunkeey@gmail.com> Closes: https://syzkaller.appspot.com/bug?extid=5c1ca6ccaa1215781cac Link: https://patch.msgid.link/20260421134929.325662-3-tristmd@gmail.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
2026-07-13wifi: carl9170: bound memcpy length in cmd callback to prevent OOB readTristan Madani1-1/+2
When the firmware sends a command response with a length mismatch, carl9170_cmd_callback() logs the mismatch and calls carl9170_restart() but then falls through to memcpy(ar->readbuf, buffer + 4, len - 4). Since len comes from the firmware and can exceed ar->readlen, this copies more data than the readbuf was allocated for. Bound the memcpy to min(len - 4, ar->readlen) so that the response is still completed -- avoiding repeated restarts from queued garbage -- while preventing an overread past the response buffer. Fixes: a84fab3cbfdc ("carl9170: 802.11 rx/tx processing and usb backend") Signed-off-by: Tristan Madani <tristan@talencesecurity.com> Acked-by: Christian Lamparter <chunkeey@gmail.com> Closes: https://syzkaller.appspot.com/bug?extid=5c1ca6ccaa1215781cac Link: https://patch.msgid.link/20260421134929.325662-2-tristmd@gmail.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
2026-07-13wifi: ath6kl: fix OOB read from firmware IE lengths in connect eventTristan Madani1-0/+8
The firmware-controlled beacon_ie_len, assoc_req_len, and assoc_resp_len fields in ath6kl_wmi_connect_event_rx() are not validated against the buffer length. Their sum (up to 765) can exceed the actual WMI event data, causing out-of-bounds reads during IE parsing and state corruption of wmi->is_wmm_enabled. Add a check that the total IE length fits within the buffer. Fixes: bdcd81707973 ("Add ath6kl cleaned up driver") Signed-off-by: Tristan Madani <tristan@talencesecurity.com> Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com> Link: https://patch.msgid.link/20260421135009.348084-3-tristmd@gmail.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
2026-07-13wifi: ath6kl: fix OOB read from firmware num_msg in TX complete handlerTristan Madani1-0/+12
The firmware-controlled num_msg field (u8, 0-255) drives the loop in ath6kl_wmi_tx_complete_event_rx() without validation against the buffer length. This allows out-of-bounds reads of up to 1020 bytes past the WMI event buffer when the firmware sends an inflated num_msg. Add a check that the buffer is large enough to hold the fixed struct and the num_msg variable-length entries. Fixes: bdcd81707973 ("Add ath6kl cleaned up driver") Signed-off-by: Tristan Madani <tristan@talencesecurity.com> Link: https://patch.msgid.link/20260625232907.3620746-1-tristmd@gmail.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
2026-07-13wifi: ath6kl: fix OOB access from firmware ADDBA window sizeTristan Madani1-4/+6
aggr_recv_addba_req_evt() logs a debug message when the firmware-supplied win_sz is outside [AGGR_WIN_SZ_MIN, AGGR_WIN_SZ_MAX] but does not return. The out-of-range win_sz is then used in TID_WINDOW_SZ() to compute a kzalloc size and stored in rxtid->hold_q_sz, leading to zero-size or overflowed allocations and subsequent out-of-bounds access. Clean up any previously active aggregation session for the TID first, then return early when win_sz is out of the valid range, instead of proceeding with a broken allocation size. Fixes: bdcd81707973 ("Add ath6kl cleaned up driver") Cc: stable@vger.kernel.org Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com> Signed-off-by: Tristan Madani <tristan@talencesecurity.com> Link: https://patch.msgid.link/20260702005020.708717-1-tristmd@gmail.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
2026-07-13wifi: ath12k: fix NULL pointer dereference in rhash table destroyJose Ignacio Tornos Martinez2-2/+8
When unbinding the ath12k driver, kernel NULL pointer dereferences occur in irq_work_sync() called from rhashtable_destroy(). Two hash tables are affected: 1. ath12k_link_sta hash table in ath12k_base 2. ath12k_dp_link_peer hash table in ath12k_dp The issue happens because the destroy functions are called unconditionally in cleanup paths, but the hash tables are only initialized late in their respective init functions. If the device was never fully started or if the init functions failed before initializing the hash tables, the pointers will be NULL. The issues are always reproducible from a VM because the MSI addressing initialization is failing. Call trace for ath12k_link_sta_rhash_tbl_destroy: RIP: irq_work_sync+0x1e/0x70 rhashtable_destroy+0x12/0x60 ath12k_link_sta_rhash_tbl_destroy+0x19/0x40 [ath12k] ath12k_core_stop+0xe/0x80 [ath12k] ath12k_core_hw_group_cleanup+0x6b/0xb0 [ath12k] ath12k_pci_remove+0x60/0x110 [ath12k] Call trace for ath12k_dp_link_peer_rhash_tbl_destroy: RIP: irq_work_sync+0x1e/0x70 rhashtable_destroy+0x12/0x60 ath12k_dp_link_peer_rhash_tbl_destroy+0x29/0x50 [ath12k] ath12k_dp_cmn_device_deinit+0x21/0x140 [ath12k] ath12k_core_hw_group_cleanup+0x6b/0xb0 [ath12k] ath12k_pci_remove+0x60/0x110 [ath12k] Fix this by adding NULL checks before calling rhashtable_destroy() in both destroy functions. The NULL check approach was chosen because the rhashtable pointer serves as the initialization state indicator. The init can fail at various points, leaving some components uninitialized. Checking the pointer directly is simpler than adding separate state flags that would need synchronization. Fixes: 57ccca410237 ("wifi: ath12k: Add hash table for ath12k_link_sta in ath12k_base") Fixes: a88cf5f71adf ("wifi: ath12k: Add hash table for ath12k_dp_link_peer") Cc: stable@vger.kernel.org Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com> Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com> Link: https://patch.msgid.link/20260615112103.601982-1-jtornosm@redhat.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
2026-07-13wifi: ath12k: Fix low MLO RX throughput on WCN7850Yingying Tang8-7/+73
Commit [1] introduced a regression causing severely degraded MLO RX throughput on WCN7850. On WCN7850, there is only a single ar instance, but MLO uses two link IDs. ath12k_dp_peer->hw_links[] is indexed using ar->hw_link_id, which causes both MLO link IDs to be stored at the same index. As a result, an incorrect link ID is assigned to MSDUs in ath12k_dp_rx_deliver_msdu(), leading to severe MLO RX throughput loss. Different chipsets identify the per-MSDU link differently: - On QCN9274 / IPQ5332, the host owns multiple ar instances and the per-MSDU hw_link_id from the RX descriptor maps cleanly through dp_peer->hw_links[hw_link_id] to the IEEE link_id. - On single-ar chipsets like WCN7850 / QCC2072, there is only one ar instance for both MLO links, so dp_peer->hw_links[] has just one valid slot and cannot be used to distinguish the two links. To resolve the link, walk dp_peer->link_peers[] and match by rxcb->peer_id, which on the link_peer side identifies the link peer for the MSDU. Add a new hw_op set_rx_link_id() so each chipset resolves the link on the RX fast path using whatever signal it actually has, and let the op itself decide whether to populate rx_status::link_valid and rx_status::link_id: QCN9274 / IPQ5332 : always derive link_id from dp_peer->hw_links[rxcb->hw_link_id] and set link_valid. WCN7850 / QCC2072 : walk the link_peers[] of dp_peer to find the link_peer whose peer_id matches rxcb->peer_id, and set link_valid only when a match is found. Otherwise leave link_valid clear so that mac80211 can fall back to its own link resolution path (via addr2 / deflink). For WCN7850 / QCC2072, walking dp_peer->link_peers[] is bounded by the number of links actually populated, so introduce a link_peers_map bitmap (unsigned long) in struct ath12k_dp_peer that tracks populated slots and use for_each_set_bit() to iterate. Non-MLO clients hit one slot, current MLO clients hit two; the full ATH12K_NUM_MAX_LINKS array is never scanned. The bitmap is maintained with WRITE_ONCE() on the write side (under dp_hw->peer_lock) paired with READ_ONCE() on both the lockless RX read side and the write-side RMW for KCSAN correctness. Also guard the dp_peer dereference in ath12k_mac_peer_cleanup_all() with a NULL check, since peer->dp_peer can be NULL for self-peers or peers not yet fully assigned, the pre-existing rcu_assign_pointer() call there had the same latent issue. This restores the correct link ID on WCN7850 without changing the QCN9274 / IPQ5332 data path, which keeps its O(1) hw_links[] indexing. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Fixes: 11157e0910fd ("wifi: ath12k: Use ath12k_dp_peer in per packet Tx & Rx paths") # [1] Signed-off-by: Yingying Tang <yingying.tang@oss.qualcomm.com> Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com> Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com> Link: https://patch.msgid.link/20260610053315.2249912-1-yingying.tang@oss.qualcomm.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>