aboutsummaryrefslogtreecommitdiffstatshomepage
AgeCommit message (Collapse)AuthorFilesLines
2026-09-09arc: kernel: Fix clk reference leak in show_cpuinfo()blaze1-0/+1
In show_cpuinfo(), clk_get() acquires a reference to the CPU clock, but clk_put() is never called to release it. Since show_cpuinfo() is the seq_file show callback for /proc/cpuinfo, this causes a clock reference count leak every time /proc/cpuinfo is read. The frequency is extracted via clk_get_rate() into a local variable, so the clock reference can be safely released immediately after. Fix this by calling clk_put(cpu_clk) right after clk_get_rate(). Fixes: 98f2892607c5 ("ARC: [cpuinfo] Add clk info in /proc/cpuinfo") Signed-off-by: blaze <1466528493@qq.com> Signed-off-by: Vineet Gupta <vgupta@kernel.org>
2026-09-09arc: remove unused profile.h includesAnthony Iliopoulos1-1/+0
None of the code in these files uses declarations provided by profile.h. Remove the unnecessary header includes across the various files to clean up dependencies and reduce include bloat. Signed-off-by: Anthony Iliopoulos <ailiop@suse.com> Signed-off-by: Vineet Gupta <vgupta@kernel.org>
2026-09-09ARC: cleanup dead ARC_CANT_LLSC option in KconfigJulian Braha1-4/+0
Currently, the ARC_CANT_LLSC config option can never be enabled. It is also not referenced anywhere else. So let's remove this dead code. Note that I have only compile-tested these changes, because I do not have the hardware to runtime test. This dead code was found by kconfirm, a static analysis tool for Kconfig. Signed-off-by: Julian Braha <julianbraha@gmail.com> Signed-off-by: Vineet Gupta <vgupta@kernel.org>
2026-09-09nstree: check listing permission before taking a namespace referenceNorbert Szetei1-8/+2
legitimize_ns() takes a reference on the candidate namespace before may_list_ns() has decided whether the caller may see it. The __free(ns_put) cleanup on the denied path can drop the last reference to a mount namespace while we still hold the rcu read lock, and put_mnt_ns() may sleep there. This is the same problem commit 2ec2aff3c8e2 ("ns: make sure reference are dropped outside of rcu lock") fixed for the put_user() path. Neither ns_requested() nor may_list_ns() needs a reference, both only look at the namespace type and at the caller's own namespaces, so do the checks first and take the reference last. Splat: Voluntary context switch within RCU read-side critical section! WARNING: kernel/rcu/tree_plugin.h:332 at rcu_note_context_switch+0x238/0x2a0, CPU#5: a/3442 CPU: 5 UID: 1000 PID: 3442 Comm: a Not tainted 7.0.0-30-generic #30-Ubuntu PREEMPT(lazy) RIP: 0010:rcu_note_context_switch+0x238/0x2a0 Call Trace: <TASK> __schedule+0xcf/0x650 schedule+0x27/0x90 schedule_preempt_disabled+0x15/0x30 __mutex_lock.constprop.0+0x550/0xaf0 __mutex_lock_slowpath+0x13/0x20 mutex_lock+0x3b/0x50 exp_funnel_lock+0xb2/0x260 synchronize_rcu_expedited+0xe7/0x220 namespace_unlock+0x26a/0x320 put_mnt_ns+0xd3/0x120 mntns_put+0xe/0x20 do_listns+0x13e/0x560 __do_sys_listns+0x126/0x2d0 __x64_sys_listns+0x20/0x30 x64_sys_call+0x2366/0x2390 do_syscall_64+0x105/0x5a0 entry_SYSCALL_64_after_hwframe+0x76/0x7e </TASK> Fixes: 76b6f5dfb3fd ("nstree: add listns()") Signed-off-by: Norbert Szetei <norbert@doyensec.com> Link: https://patch.msgid.link/ABA32239-733B-438C-B95A-B13ED69FF0F3@doyensec.com Reviewed-by: Bradley Morgan <brads@mainlining.org> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-09-09Merge branch 'for-7.4-trivial' into for-linusPetr Mladek3-3/+3
2026-09-09exec: do_close_on_exec() before taking exec_update_lockJann Horn1-8/+14
do_close_on_exec() currently happens while holding the exec_update_lock, which is used in a lot of places that access process state to synchronize access checks. I recently added another such use of exec_update_lock, causing a regression. do_close_on_exec() can block waiting for a reply from a filesystem. That means a hung filesystem can block codepaths that use exec_update_lock; and it also means that a FUSE filesystem which attempts to inspect the calling process can deadlock. To avoid such problems, move do_close_on_exec() before the exec_update_lock is taken, but after the FD table has been copied if necessary. I have looked through all the calls between the old and new position of the do_close_on_exec() call; there seems to be no file descriptor table access in between. Reported-by: Benjamin Peterson <benjamin@locrian.net> Closes: https://lore.kernel.org/r/f5e8166a-88be-46c5-8939-1e5227ffe4c2@app.fastmail.com Fixes: 6650527444da ("proc: protect ptrace_may_access() with exec_update_lock (part 1)") Cc: stable@vger.kernel.org Signed-off-by: Jann Horn <jannh@google.com> Link: https://patch.msgid.link/20260907-cloexec-before-exec-update-lock-v1-1-8018c201a7df@google.com Tested-by: Benjamin Peterson <benjamin@locrian.net> Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-09-09x86/mm: Fix user-space data loss with MADV_FREE and THPVernon Yang1-1/+1
Some of users of Polars (a data analytics library) have lost production data from this bug. They seem to have just the right combination of huge pages, MADV_FREE and heavy reclaim pressure. pmd_modify() masks the old value with (_HPAGE_CHG_MASK & ~_PAGE_DIRTY), silently discarding the hardware dirty bit. The subsequent pmd_mksaveddirty() call is supposed to transfer _PAGE_DIRTY into _PAGE_SAVED_DIRTY when write-protecting, but the dirty bit was already stripped from the value, so there is nothing left to transfer. Contrast with pte_modify(), which keeps _PAGE_DIRTY_BITS in its mask, and pud_modify(), which keeps _HPAGE_CHG_MASK untouched: pmd_modify() is the odd one out. Any pmd_modify() on a writable, dirty PMD loses the dirty state. One visible consequence is data loss with MADV_FREE on PMD-mapped THP: memset(buf, 0x5A, size); // PMD-mapped THP, PMD dirty madvise(buf, size, MADV_FREE); // PMD cleaned but left writable, // folio marked lazyfree memset(buf, 0x5A, size); // hardware sets _PAGE_DIRTY again mprotect(buf, size, PROT_READ); // pmd_modify() drops the dirty bit mprotect(buf, size, PROT_READ|PROT_WRITE); // ... memory pressure ... Reclaim (e.g. under memcg pressure) then finds the lazyfree folio with no dirty bit set anywhere and frees it in __discard_anon_folio_pmd_locked(), even though the data was rewritten after MADV_FREE; subsequent reads fault in fresh zero pages. NUMA hinting alone can trigger the same loss, as do_huge_pmd_numa_page() restores the PMD through pmd_modify() as well. PMD-mapped file THPs are affected too: mprotect()/NUMA hinting dropping the dirty bit means rewritten data is never written back. Fix it by keeping _PAGE_DIRTY in the preserved mask, exactly like pte_modify() and pud_modify() do. The existing pmd_mksaveddirty()/pmd_clear_saveddirty() pair then performs the hardware-dirty <-> saved-dirty transition based on the write bit, preserving the shadow-stack encoding rules. Fixes: bb3aadf7d446 ("x86/mm: Start actually marking _PAGE_SAVED_DIRTY") Closes: https://lore.kernel.org/r/CAJxLxMUGu1-L+O_nAONOwOXnS=cNbNApCWqdthRjd76LThtSPg@mail.gmail.com/ Reported-by: Orson Peters <orsonpeters@gmail.com> Signed-off-by: Vernon Yang <yanglincheng@kylinos.cn> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Rick Edgecombe <rick.p.edgecombe@intel.com> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260903031608.1194238-1-vernon2gm@gmail.com
2026-09-09x86/mm/pat: Allocate split page tables as kernel page tablesLorenzo Stoakes (ARM)1-9/+16
A PTE is allocated directly without going through the standard page table allocation routines (such as pte_alloc_one_kernel()) when the CPA code splits a large page (__split_large_page()). This means the page table constructor is never called nor is the page table marked as a kernel page table. The former results in the folio associated with the page table not being marked as a page table (__pagetable_ctor() is never called thus neither is __folio_set_pgtable()) nor are statistics updated to reflect it (lruvec_stat_add_folio() is never called). The latter issue of failing to mark the page table as a kernel page table (ptdesc_set_kernel() is never called) is far more problematic. Since commit: 5ba2f0a15564 ("mm: introduce deferred freeing for kernel page tables") kernel page table freeing has been batched and since the subsequent commit: e37d5a2d60a3 ("iommu/sva: invalidate stale IOTLB entries for kernel address space") IOTLB cache entries for kernel page tables have been invalidated upon being freed. Since split page tables are freed without this invalidation, the IOTLB can contain stale entries for them. Resolve the issue by using the ordinary PTE allocation API at split time. This results in these kernel page tables invoking a page table constructor, and thus requires a page table destructor. Destructors are not always present, like for early allocated direct map page tables). Conditionally call pagetable_dtor_free() if the PG_table folio flag for the ptdesc is set, otherwise we free the page table via pagetable_free(). Regardless of which path is taken page tables marked as kernel page tables, which now includes split page tables, take the correct route through pagetable_free_kernel(). There is a user-visible side effect in that split page tables will appear in nr_page_table_pages in /proc/vmstat (as do other kernel page tables allocated after early boot), however this is a positive change. This issue started being markedly problematic after commit: 5ba2f0a15564 ("mm: introduce deferred freeing for kernel page tables") so choose this as the Fixes target. [ dhansen: rephrase in imperative mood ] Fixes: 5ba2f0a15564 ("mm: introduce deferred freeing for kernel page tables") Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Acked-by: Vishal Moola <vishal.moola@gmail.com> Tested-by: Atish Patra <atishp@meta.com> Tested-by: Nikunj A Dadhania <nikunj@amd.com> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260813-cpa-fixes-v2-4-39b4ff90f91d@kernel.org
2026-09-09x86/alternatives: Exclude text poking against change_page_attr()Pedro Falcato1-3/+36
From time to time, the following BUG can be observed in the x86 alternatives patching code [0]: > kernel BUG at arch/x86/kernel/alternative.c:2576! > Oops: invalid opcode: 0000 [#1] SMP NOPTI > CPU: 0 UID: 0 PID: 355 Comm: (udev-worker) Not tainted 7.1.3-1-default #1 PREEMPT(full) openSUSE Tumbleweed 8c1795b03ec64f997e57a8ad38b1161e3b98da64 > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS unknown 02/02/2022 > RIP: 0010:__text_poke+0x2aa/0x450 > Call Trace: > <TASK> > smp_text_poke_batch_finish+0x2a7/0x320 > __static_call_transform+0xb7/0x220 > arch_static_call_transform+0x5b/0xb0 > __static_call_init+0xe9/0x270 > static_call_module_notify+0x11f/0x150 > notifier_call_chain+0x61/0xe0 > blocking_notifier_call_chain_robust+0x63/0xc0 > load_module+0x1c92/0x20c0 > init_module_from_file+0xd8/0x140 > idempotent_init_module+0x100/0x2f0 > __x64_sys_finit_module+0x71/0xe0 > do_syscall_64+0xe1/0x610 > entry_SYSCALL_64_after_hwframe+0x76/0x7e which matches the following BUG_ON() in alternative.c: /* * If something went wrong, crash and burn since recovery paths are not * implemented. */ BUG_ON(!pages[0] || (cross_page_boundary && !pages[1])); This can happen if vmalloc_to_page() fails, for any reason. Such can happen if text poking races with CPA, which can possibly result in the collapsing of page tables (or breaking of PMD hugepages). It is not a problem for most users of vmalloc_to_page() (they solely own the vmalloc'd range) but, when CONFIG_ARCH_HAS_EXECMEM_ROX=y, various modules own a single execmem vmalloc range, and can call set_memory_*() in parallel on it. This can happen to race against __text_poke and cause havoc in vmalloc_to_page(). Fix it by excluding against CPA using the init_mm mmap read lock. [ dhansen: Fix up SoB ordering. The actual code flow here was: Pedro=>Lorenzo=>Mike=>Me which is reflected in the SoB chain now. I *believe* Mike simply picked up Lorenzo's update to Pedro's post from the Link ] Fixes: 64f6a4e10c05 ("x86: re-enable EXECMEM_ROX support") Reported-by: Jiri Slaby <jirislaby@kernel.org> Reported-by: Steffen Dirkwinkel <lists@steffen.cc> Signed-off-by: Pedro Falcato <pfalcato@suse.de> Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> Co-developed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Tested-by: Jiri Slaby <jirislaby@kernel.org> Tested-by: Atish Patra <atishp@meta.com> Tested-by: Nikunj A Dadhania <nikunj@amd.com> Cc: stable@vger.kernel.org Link: https://bugzilla.opensuse.org/show_bug.cgi?id=1271202 [0] Link: https://lore.kernel.org/linux-mm/555ea1d43a12c30a8f1eaf10c899b3790d728f33.camel@dirkwinkel.cc/ Link: https://patch.msgid.link/20260813-cpa-fixes-v2-3-39b4ff90f91d@kernel.org
2026-09-09x86/mm/pat: Acquire init_mm read lock on attribute changes to avoid UAFLorenzo Stoakes (ARM)1-2/+11
A previous commit protected against races between ptdump and CPA collapse, however one still exists between attribute changes and collapse as reported by Denis V. Lunev (linked). When an attribute change arises, a lockless page table walker obtains a PTE entry, which is later written to via set_pte_atomic(): ... -> change_page_attr_set_clr() -> __change_page_attr_set_clr() -> __change_page_attr() -> _lookup_address_cpa() -> lookup_address_in_pgd_attr() -> [ lockless page table walker ] -> set_pte_atomic() There is nothing preventing a concurrent CPA collapse which can free the PTE that was retrieved here, resulting in a use-after-free. With the mmap write lock taken on init_mm over CPA collapse, resolve this race by acquiring an mmap read lock on init_mm over __change_page_attr_set_clr(). This locks across the whole operation over which the walk and the PTE entry write occurs, solving the race. It is safe to do this here, as no spinlocks are held upon entry to __change_page_attr_set_clr(). However, the lock must not be held over an allocation, as allocation can trigger reclaim and shrinkers may call into CPA recursively, making deadlocks possible (init_mm -> ... -> fs_reclaim -> init_mm). A page table is allocated when a huge page needs to be split: -> change_page_attr_set_clr() -> __change_page_attr_set_clr() -> __change_page_attr() -> split_large_page() [ pagetable_alloc() ] -> __split_large_page() Avoid deadlocks by dropping the mmap lock across pagetable_alloc() in split_large_page() and track whether this is needed by adding a new 'init_mm_read_locked' flag to struct cpa_data. This is safe as __split_large_page() (called with locks re-established) revalidates that the page table entry is the same as it was prior to the locks being dropped and __change_page_attr() repeats the entire page table walk whenever a split occurs, so concurrent split and collapse are accounted for. Concurrent ptdump is also safe as the lock is only dropped over page table allocation during which time the page table has not yet been modified. The CPA_COLLAPSE flag is only set by set_memory_rox(), which exclusively operates upon vmalloc ranges, and on x86 only within the module mapping space. This is important, because some callers directly invoke __change_page_attr_set_clr(), bypassing this lock. However, none of these operate within the module mapping space. * cpa_process_alias() - a recursive helper called by __change_page_attr_set_clr(). * __set_memory_enc_pgtable() - operates on the direct mapping and (via __vmbus_establish_gpadl()) the vmalloc mapping space. * __set_pages_[n]p() - called by set_direct_map_[invalid, default, valid]_noflush(), __kernel_map_pages() - operates on the direct map. * kernel_[un]map_pages_in_pgd() - operates on EFI ranges. This work is based upon Denis V. Lunev's excellent analysis of the bug with gratitude. [ dhansen: move to imperative voice in changelog ] Fixes: 41d88484c71c ("x86/mm/pat: restore large ROX pages after fragmentation") Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Tested-by: Atish Patra <atishp@meta.com> Tested-by: Nikunj A Dadhania <nikunj@amd.com> Link: https://lore.kernel.org/all/20260626163213.2284080-1-den@openvz.org/ Cc:stable@vger.kernel.org Link: https://patch.msgid.link/20260813-cpa-fixes-v2-2-39b4ff90f91d@kernel.org
2026-09-09x86/mm/pat: Acquire init_mm write lock on collapse to avoid UAFLorenzo Stoakes (ARM)2-1/+16
x86 implements page attribute modification using its Change Page Attributes (CPA) mechanism. This tracks properties of ranges such as cache mode through x86 page attributes, and as part of that logic manipulates kernel page tables. Since commit: 41d88484c71c ("x86/mm/pat: restore large ROX pages after fragmentation") ranges of kernel page table entries can be collapsed into huge page table entries as part of this logic. As part of this collapse, it frees the page tables which the collapsed entries previously pointed to, and it does so without any relevant locks being held to preclude concurrent kernel page table walkers. The only way this code can be reached is if CPA_COLLAPSE is specified, and this is only set in set_memory_rox() via: set_memory_rox() -> change_page_attr_set_clr() -> cpa_flush() -> cpa_collapse_large_pages() Notable users of this are execmem and BPF when manipulating executable mappings. However, this is problematic for ptdump as it walks ranges it does not own and thus runs the risk of a use-after-free on page tables freed underneath it. In addition, concurrent CPA collapse operations are possible which can also cause races. Resolve the issue by acquiring the mmap write lock on init_mm across the whole operation. It is safe to acquire a sleeping lock as all the callers invoke set_memory_rox() from process context and in any case, change_page_attr_set_clr() calls vm_unmap_alias() which ultimately takes a mutex, disallowing atomic context here. Fixes: 41d88484c71c ("x86/mm/pat: restore large ROX pages after fragmentation") Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org> Reviewed-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Will Deacon <will@kernel.org> Reviewed-by: David Carlier <devnexen@gmail.com> Tested-by: Atish Patra <atishp@meta.com> Tested-by: Nikunj A Dadhania <nikunj@amd.com> Cc:stable@vger.kernel.org Link: https://patch.msgid.link/20260813-cpa-fixes-v2-1-39b4ff90f91d@kernel.org
2026-09-09swiotlb: use the adjusted address for the highmem page lookupDonggeun Yoo1-2/+2
swiotlb_bounce() reads the page frame number from the slot's recorded orig_addr, then advances orig_addr by tlb_offset to reach the address the caller asked about. The highmem branch mixes the two: the offset within the page comes from the adjusted address, the page from the value before it. Once the adjustment crosses a page boundary the pair no longer describes one location, and the whole copy lands one page below the intended one for a positive tlb_offset, one above for a negative one. DMA_FROM_DEVICE writes the device data over the wrong page and leaves the intended one stale, DMA_TO_DEVICE feeds the device from a page the mapping may not cover. Partial syncs through dma_sync_single_range_for_*() are what make tlb_offset non-zero. The branch test is picked the same way, so a slot recorded in lowmem can be adjusted into highmem and the lowmem path then hands a highmem address to phys_to_virt(). Take both from orig_addr once it is final and keep pfn in the branch that uses it. PhysHighMem() asks the question straight from the address, as dma-debug already does. Fixes: 5f89468e2f06 ("swiotlb: manipulate orig_addr when tlb_addr has offset") Cc: stable@vger.kernel.org Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com> Reviewed-by: Michael Kelley <mhklinux@outlook.com> Link: https://lore.kernel.org/r/20260905084210.148255-1-donggeunyoo.kernel@gmail.com Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
2026-09-09dma-coherent: report a failed reserved memory assignmentDonggeun Yoo1-2/+1
rmem_dma_device_init() drops the return value of dma_assign_coherent_memory() and always reports success. That call fails with -EBUSY when the device already has a coherent pool, and the file allows only "*one* such region of memory" per device. of_reserved_mem_device_init_by_idx() reads the zero as success. It logs "assigned reserved memory node" for a region that was not assigned and records the pairing, so of_reserved_mem_device_release() later runs rmem_dma_device_release() for it. That clears dev->dma_mem without looking at which region it was called for, dropping the pool the device did get and leaving it on ordinary memory. dma_declare_coherent_memory() checks the same call and releases the memory on failure, and rmem_swiotlb_device_init() propagates its own errors. Return the error here as well, so a device tree that assigns two pools to one device fails the probe instead of half working. Fixes: 7bfa5ab6fa1b ("drivers: dma-coherent: add initialization from device tree") Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com> Link: https://lore.kernel.org/r/20260905074727.108029-1-donggeunyoo.kernel@gmail.com Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
2026-09-08mm/folio: EXPORT_SYMBOL_FOR_KVM(lru_cache_drain_for_folio)Ackerley Tng1-0/+2
To simplify independent development in the KVM and MM subsystems, now export to KVM the lru_cache_drain_for_folio() which MM added in 7.3-rc1. Link: https://lore.kernel.org/lkml/bd6c9c74-e374-a9d3-ba1f-8b6f430894fc@google.com/T/#u Link: https://lore.kernel.org/02876cea-5727-2ca4-bead-73659ea6fec4@google.com Signed-off-by: Ackerley Tng <ackerleytng@google.com> Signed-off-by: Hugh Dickins <hughd@google.com> Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org> Suggested-by: David Hildenbrand <david@kernel.org> Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev> Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Sean Christopherson <seanjc@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2026-09-08mm/shrinker: fix bogus set_shrinker_bit() with cgroup.memory=nokmemJiayuan Chen1-0/+2
With cgroup.memory=nokmem, shrinker_memcg_alloc() bails out early and never allocates an id, so shrinker->id keeps the 0 it got from the kzalloc() in shrinker_alloc(). __list_lru_init() then copies that 0 into lru->shrinker_id, where it looks like a valid bit index. Nothing calls expand_shrinker_info() on nokmem either, so shrinker_nr_max stays 0 and every memcg ends up with an empty map (map_nr_max == 0). deferred_split_folio() hands a real memcg to __list_lru_add() regardless of whether the lru is memcg aware, so the first THP queued in a cgroup does set_shrinker_bit(memcg, nid, 0) and trips the bounds check: WARNING: mm/shrinker.c:212 at set_shrinker_bit+0x7d/0x90, CPU#126 Call Trace: <TASK> deferred_split_folio+0x18c/0x220 map_anon_folio_pmd_nopf+0xdd/0x130 map_anon_folio_pmd_pf+0x14/0xb0 do_huge_pmd_anonymous_page+0x1a1/0x620 __handle_mm_fault+0xea9/0x10d0 handle_mm_fault+0xe5/0x320 do_user_addr_fault+0x1cc/0x870 exc_page_fault+0x81/0x1b0 asm_exc_page_fault+0x27/0x30 </TASK> Harmless, the WARN_ON_ONCE() is what keeps the out of bounds unit[] read from happening, but the id should not look valid in the first place. Clear it before returning. Two other spots could paper over this: drop the id in __list_lru_init() when nokmem turns memcg_aware off, or make deferred_split_folio() pass NULL like list_lru_add_obj() does. Both leave shrinker->id lying around for the next caller, so fix it where the id is handed out. Link: https://lore.kernel.org/20260902073800.305481-1-jiayuan.chen@linux.dev Fixes: fafaeceb89a5 ("mm: switch deferred split shrinker to list_lru") Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev> Acked-by: Shakeel Butt <shakeel.butt@linux.dev> Cc: Usama Arif <usama.arif@linux.dev> Cc: Dave Chinner <david@fromorbit.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Kairui Song <kasong@tencent.com> Cc: Muchun Song <muchun.song@linux.dev> Cc: Roman Gushchin <roman.gushchin@linux.dev> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2026-09-08mm/vma: correctly unaccount on mmap_prepare() failureLorenzo Stoakes (ARM)1-2/+4
__mmap_setup() accounts memory for relevant mappings via: security_vm_enough_memory_mm() -> __vm_enough_memory() -> vm_acct_memory() If __mmap_setup() fails, this indicates that this accounting did not take place, and thus it's appropriate for __mmap_region() to jump to abort_munmap. However if call_mmap_prepare() fails, it also jumps there and any accounted memory is not correctly unaccounted. Fix this by handling each error separately. Link: https://lore.kernel.org/20260902-fix-unaccount-mmap_prepare-v1-1-ea070189fdfb@kernel.org Fixes: c84bf6dd2b83 ("mm: introduce new .mmap_prepare() file callback") Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> Cc: Jann Horn <jannh@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Pedro Falcato <pfalcato@suse.de> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2026-09-09opp: fix use after free in _update_opp_table_clk()Peter Griffin1-2/+4
dev_pm_opp_put_opp_table() frees the opp_table which is subsquently used by dev_err_probe(). This causes an Oops during boot on gs101-oriole. cpu cpu0: error 000000006b6b6b6b: Couldn't find clock Unable to handle kernel paging request at virtual address 006b6b6b6b6b6cd3 ... Hardware name: Oriole (DT) pstate: 00400005 (nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : _of_add_table_indexed+0x80/0xbb0 lr : _of_add_table_indexed+0x6c/0xbb0 ... Call trace: _of_add_table_indexed+0x80/0xbb0 (P) dev_pm_opp_of_cpumask_add_table+0x70/0x120 dt_cpufreq_probe+0x23c/0x480 platform_probe+0x64/0xb8 Fixes: 84f05af0975c9 ("opp: Use clk_get_optional() to avoid leaving opp_table->clk as an error pointer") Signed-off-by: Peter Griffin <peter.griffin@linaro.org> Reviewed-by: Tudor Ambarus <tudor.ambarus@linaro.org> [ Viresh: use return value of dev_err_probe() ] Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
2026-09-08io_uring/net: let io_recv_buf_select return the length of the buffer regionGabriel Krisman Bertazi1-4/+6
In preparation to using this field as an upper limit to truncation, return the size of the allocated region. Fixes: ae98dbf43d75 ("io_uring/kbuf: add support for incremental buffer consumption") Cc: stable@vger.kernel.org Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de> Link: https://patch.msgid.link/20260902230041.1320658-2-krisman@suse.de Signed-off-by: Jens Axboe <axboe@kernel.dk>
2026-09-08io_uring/rw: end write accounting from ->ki_completeJens Axboe1-10/+19
Commit b000145e9907 moved both the fsnotify calls and the write accounting out of the kiocb completion handler and into the io_req_rw_complete() task_work. However, only the fsnotify part actually needed to move as it may sleep. Ending the write accounting is just a percpu_up_read() on the superblock writers sem. Deferring it is a problem, because it makes dropping SB_FREEZE_WRITE protection depend on the ring owner getting to running task_work. But the task may be blocked in freeze_super(), causing it to never get to that: task io-wq worker -------------------------------------------------------------- io_write() io_kiocb_start_write() (takes sb_writers, hidden from lockdep by __sb_writers_release) write_iter() -> -EIOCBQUEUED ioctl(FS_IOC_SHUTDOWN) bdev_freeze() freeze_super() percpu_down_write() <- waits for the reader above io_write() kiocb_start_write() percpu_down_read() <- queued behind the writer <bio completes> io_complete_rw() queues io_req_rw_complete() <- never runs, task is in D state End the write from io_complete_rw() instead, and leave only the fsnotify calls in task_work. Reported-by: syzbot+2eb3d983669d3e49d4fa@syzkaller.appspotmail.com Cc: stable@vger.kernel.org Fixes: b000145e9907 ("io_uring/rw: defer fsnotify calls to task context") Signed-off-by: Jens Axboe <axboe@kernel.dk>
2026-09-08Merge branch 'net-macb-fix-two-probe-path-leaks'Jakub Kicinski1-0/+3
Nicolai Buchwitz says: ==================== net: macb: fix two probe path leaks Two independent leaks on macb probe paths, both noticed while reviewing the fixed-link unbind crash fix [1]. Patch 1 destroys the phylink instance when probe fails after macb_mii_init() has succeeded. Patch 2 drops the "mdio" child node reference on the success path of macb_mii_init(). [1] https://lore.kernel.org/netdev/20260902102836.2019355-1-vineeth.karumanchi@amd.com/ ==================== Link: https://patch.msgid.link/20260907210856.1673589-1-nb@tipi-net.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-08net: macb: put the "mdio" child node reference on successNicolai Buchwitz1-0/+2
macb_mii_init() holds the reference returned by of_get_child_by_name() for macb_mdiobus_register() and drops it only on the error paths, so every successful probe leaks a node reference. On a CM5, overlay removal after four bind cycles reports OF: ERROR: memory leak, expected refcount 1 instead of 5 Drop the reference after registration, where __mdiobus_register() has already taken its own for the lifetime of the bus. Fixes: 8a6631f1cece ("net: macb: avoid redundant lookup for "mdio" child node in MDIO setup") Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de> Link: https://patch.msgid.link/20260907210856.1673589-3-nb@tipi-net.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-08net: macb: destroy the phylink instance on the probe error pathNicolai Buchwitz1-0/+1
macb_mii_init() creates a phylink instance on both of its success paths, but the probe unwind frees the netdev without destroying it, so a failing macb_alloc_tieoff() or register_netdev() leaks the instance. Destroy it at err_out_unregister_mdio, which is only reachable once macb_mii_init() has succeeded, so bp->phylink is valid there. Fixes: 7897b071ac3b ("net: macb: convert to phylink") Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de> Link: https://patch.msgid.link/20260907210856.1673589-2-nb@tipi-net.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-08net: bridge: use option bits for CFM/MRP frame handlersZhiling Zou5-51/+35
CFM and MRP register a global br_frame_type whose hlist_node is linked into the per-bridge frame_type_list when the first MEP/MRP instance is created. Enabling the protocol on multiple bridges therefore inserts the same node into multiple lists. Unregistering it on one bridge then corrupts list state belonging to another. These handlers can only be installed once per bridge, and they are uncommon. Track their per-bridge enable state with net_bridge option bits, which already live on the Rx hot cache line, and dispatch the matching handler directly from the receive path. Check both bits together first as an unlikely case. Remove the generic frame_type_list and br_frame_type helpers, which have had no other users since CFM and MRP were added. That shrinks struct net_bridge by 8 bytes and drops the list walk from the fast path. When neither protocol is compiled in, BR_CFM_MRP_OPTS is 0 and the compiler prunes the branch. Fixes: 90c628dd47ff ("net: bridge: extend the process of special frames") Fixes: dc32cbb3dbd7 ("bridge: cfm: Kernel space implementation of CFM. CCM frame RX added.") Cc: stable@vger.kernel.org Reported-by: Vega <vega@nebusec.ai> Suggested-by: Nikolay Aleksandrov <razor@blackwall.org> Co-developed-by: Yilin Zhu <zylzyl2333@gmail.com> Signed-off-by: Yilin Zhu <zylzyl2333@gmail.com> Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai> Acked-by: Nikolay Aleksandrov <razor@blackwall.org> Link: https://patch.msgid.link/0345b9d5aa60ba416f6738ff1b87140f0a749cb8.1788417901.git.zhilinz@nebusec.ai Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-08net: openvswitch: fix use-after-free of the flow table mask arrayNorbert Szetei1-1/+3
tbl_mask_array_realloc() retires the old mask_array before it stops being reachable: old = ovsl_dereference(tbl->mask_array); if (old) { ... call_rcu(&old->rcu, mask_array_rcu_cb); } rcu_assign_pointer(tbl->mask_array, new); call_rcu() only waits for read-side critical sections already in flight. tbl->mask_array still points at old between the call_rcu() and the rcu_assign_pointer(), so a reader entering ovs_flow_tbl_lookup_stats() in that window picks up old in a fresh critical section that the pending grace period does not cover. tbl_mask_array_realloc() runs in process context under ovs_mutex, so the window is preemptible and can outlast the grace period. Then mask_array_rcu_cb() frees old before the swap runs: BUG: KASAN: slab-use-after-free in flow_lookup.constprop.0+0x2bf/0x2f0 Read of size 8 at addr ffff888020b3e018 by task poc/741 flow_lookup.constprop.0+0x2bf/0x2f0 ovs_flow_tbl_lookup_stats+0x4a3/0x5c0 ovs_dp_process_packet+0x19c/0x710 ovs_vport_receive+0x243/0x390 internal_dev_xmit+0x81/0x170 Freed by task 728: kfree+0x16a/0x4e0 rcu_core+0x853/0x1030 Publish the new array before retiring the old one. The kfree_rcu() that call_rcu() replaced ran after the swap. Fixes: eac87c413bf9 ("net: openvswitch: reorder masks array based on usage") Cc: stable@vger.kernel.org Signed-off-by: Norbert Szetei <norbert@doyensec.com> Reviewed-by: Ilya Maximets <i.maximets@ovn.org> Acked-by: Eelco Chaudron echaudro@redhat.com Link: https://patch.msgid.link/DE115F9C-2545-423E-A702-986FC952FD62@doyensec.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-08ipv6: null-check fib6_node before accessing in __ip6_del_rt_siblings()Naman Gulati1-3/+6
syzbot reported a null-ptr-deref in __ip6_del_rt_siblings() [0]. The stack trace hinted towards a null dereference of rt->fib6_node when fn->leaf is accessed in __ip6_del_rt_siblings(). With RTNL_FLAG_DOIT_UNLOCKED set, inet6_rtm_delroute() operations run concurrently without acquiring the RTNL lock. In ip6_route_del(), the route lookup happens under rcu_read_lock() without acquiring table->tb6_lock. Between ip6_route_del() looking up the route and __ip6_del_rt_siblings() acquiring table->tb6_lock, another thread can modify the routing table. For example, when an ECMP route is replaced via RTM_NEWROUTE with NLM_F_REPLACE, fib6_add_rt2node() unlinks all old siblings and sets iter->fib6_node = NULL. A reproducer was found that triggers this [1]. Add a check to ensure rt->fib6_node is non-null before accessing it. [0] KASAN: null-ptr-deref in range [0x0000000000000020-0x0000000000000027] RIP: 0010:__ip6_del_rt_siblings+0x31e/0x7c0 net/ipv6/route.c:4056 Call Trace: <TASK> ip6_route_del+0x1054/0x1110 net/ipv6/route.c:4232 inet6_rtm_delroute+0x5d7/0x6d0 net/ipv6/route.c:5669 rtnetlink_rcv_msg+0x802/0xc00 net/core/rtnetlink.c:7132 netlink_rcv_skb+0x226/0x4a0 net/netlink/af_netlink.c:2556 netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline] netlink_unicast+0x7f5/0x990 net/netlink/af_netlink.c:1345 netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1900 sock_sendmsg_nosec+0x13a/0x180 net/socket.c:800 __sock_sendmsg net/socket.c:815 [inline] ____sys_sendmsg+0x565/0x870 net/socket.c:2713 ___sys_sendmsg+0x2a5/0x360 net/socket.c:2767 __sys_sendmsg net/socket.c:2799 [inline] __do_sys_sendmsg net/socket.c:2804 [inline] __se_sys_sendmsg net/socket.c:2802 [inline] __x64_sys_sendmsg+0x1b7/0x290 net/socket.c:2802 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline] do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84 entry_SYSCALL_64_after_hwframe+0x77/0x7f </TASK> [1] https://gist.github.com/NamanGulati/0766a1159b6ca61928faaf87425ff899 Fixes: bd11ff421d36 ("ipv6: Get rid of RTNL for SIOCDELRT and RTM_DELROUTE.") Reported-by: syzbot+a73e5ee0fd534fed75bd@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/6a9b03f9.04649fcc.10325f.0003.GAE@google.com Signed-off-by: Naman Gulati <namangulati@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260904180645.706425-1-namangulati@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-08MAINTAINERS: Update the so_txtime selftest path in SOCKET TIMESTAMPINGKarl Mehltretter1-1/+1
Commit 5c6baef3885c ("selftests: drv-net: convert so_txtime to drv-net") moved the test to tools/testing/selftests/drivers/net/, but the SOCKET TIMESTAMPING entry still lists the old path and scripts/get_maintainer.pl --self-test=patterns reports it as matching nothing. Point the pattern at the new location. Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com> Reviewed-by: Jason Xing <kerneljasonxing@gmail.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/20260905100608.42539-1-kmehltretter@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-08ppp_async: drop the errored frame instead of resetting its headroomVlatko Kosturjak1-5/+2
ppp_receive_nonmp_frame() prepends a two-byte direction tag before running the pass/active BPF filters: *(__be16 *)skb_push(skb, 2) = htons(PPP_FILTER_INBOUND_TAG); Nothing on the receive path guarantees those two bytes of headroom. The frame-error path in ppp_async's process_input_packet() resets a reused skb's headroom to zero while claiming to restore it to a freshly allocated state - but a fresh skb from dev_alloc_skb() carries NET_SKB_PAD: err: if (skb) { /* make skb appear as freshly allocated */ skb_trim(skb, 0); skb_reserve(skb, - skb_headroom(skb)); } ap->rpkt still points at that skb, so the next frame is reassembled into it with no headroom at all. A peer that sends a bad-FCS frame followed by one beginning ff 03 then leaves a single byte of headroom by the time the filter tag is pushed, which lands one byte below skb->head: skbuff: skb_under_panic: len:49 put:2 head:ffff888003c10000 data:ffff888003c0ffff tail:0x30 end:0x640 dev:<NULL> kernel BUG at net/core/skbuff.c:214! RIP: 0010:skb_panic+0x13e/0x230 Call Trace: skb_push+0xbd/0x100 ppp_receive_nonmp_frame+0x48a/0x1d10 ppp_input+0x4e9/0x2f80 ppp_async_process+0x2a/0xe0 tasklet_action_common+0x20f/0x8a0 handle_softirqs+0x18e/0x590 Kernel panic - not syncing: Fatal exception in interrupt Zeroing the headroom violates the NET_SKB_PAD guarantee that dev_alloc_skb() gives the rest of the receive path. Besides the filter panic above, when CCP compression is enabled ppp_decompress_frame() hands skb->data - 2 to ->decompress()/->incomp(), which then reads out of bounds before skb->head for the same reason. Rather than restore the headroom, drop the errored frame - as ppp_synctty already does on its error path - and clear ap->rpkt so the next frame is reassembled into a fresh skb with proper headroom. This is simpler and fixes both the filter under-panic and the CCP out-of-bounds read. The original V1 of this patch made room in ppp_receive_nonmp_frame() with skb_cow_head(); Eric pointed out that fixing the root cause in the transport is the right approach. Found by fuzzing the PPP receive path with a mutating peer on a pty; it is an interesting (remote) DoS: root configures PPP, the peer supplies two crashing frames. The reproducer (repro-ppp-skb.c, unchanged from v1) panics in about a second, and returns cleanly with this applied. Fixes: 6722e78c9005 ("[PPP]: handle misaligned accesses") Suggested-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Vlatko Kosturjak <kost@linux.hr> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/apkR6ZU+tqP2C3Fl@griffin.linux.hr Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-08net: mana: Clear RDMA teardown and suspend state in mana_rdma_probe()Long Li1-1/+17
mana_rdma_remove() sets gd->rdma_teardown to stop mana_rdma_service_handle() from acting on servicing events, but nothing ever clears it. A hardware service reset (GDMA_EQE_HWC_RESET_REQUEST) goes through mana_gd_suspend() -> mana_rdma_remove() and mana_gd_resume() -> mana_rdma_probe(), so from the first reset onwards every GDMA_EQE_HWC_SOC_SERVICE event returns early and RDMA suspend/resume servicing is silently dropped for the life of the device. gd->is_suspended has the same problem: it is set when servicing removes the adev and is cleared only by a matching resume. A reset while RDMA is suspended re-adds the adev but leaves is_suspended set, so a later resume event calls add_adev() on top of a live gd->adev and leaks it. This is currently masked by the rdma_teardown bug. Clear both in mana_rdma_probe(). On the reset path mana_rdma_remove() has closed the gate and drained the service workqueue, so clear is_suspended first and re-open the gate with smp_store_release(), paired with smp_load_acquire() in the handler, so the handler cannot observe an open gate with a stale is_suspended. On the initial probe path the gate was never closed and both flags are already clear. This does not order gd->adev, which add_adev() publishes afterwards. A servicing event arriving in that window is still dropped, as it is in mainline today on the initial probe path; closing it needs probe and the handler to be serialized and is left to a separate change. Fixes: 505cc26bcae0 ("net: mana: Add support for auxiliary device servicing events") Signed-off-by: Long Li <longli@microsoft.com> Link: https://patch.msgid.link/20260902175153.3410560-1-longli@microsoft.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-08rust: allow `unknown_lints` in generated bindings for Rust < 1.88Miguel Ojeda2-2/+4
Starting with bindgen 0.73.2 [1], `#[allow(unnecessary_transmutes)]` are used, even when `--rust-target 1.85` is passed. However, the lint was introduced in Rust 1.88.0. Thus building with older Rust versions warns like: error: unknown lint: `unnecessary_transmutes` --> rust/uapi/uapi_generated.rs:26294:13 | 26294 | #[allow(unnecessary_transmutes)] | ^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D unknown-lints` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(unknown_lints)]` Thus allow `unknown_lints` in the generated bindings -- only when building with older Rust versions. I have asked upstream if this is intentional [1], i.e. if we are supposed to always allow unknown lints in case `bindgen` uses such attributes, or whether it is an oversight. [ Emilio said it wasn't intentional -- we will work around it for now on the kernel side. - Miguel ] Cc: stable@vger.kernel.org # Needed in 6.12.y and later (Rust is pinned in older LTSs). Cc: Emilio Cobos Álvarez <emilio@crisal.io> Link: https://github.com/rust-lang/rust-bindgen/pull/3455#issuecomment-5588526559 [1] Assisted-by: LLM Link: https://patch.msgid.link/20260908170539.345207-1-ojeda@kernel.org [ Removed the `cfg` for `allow(unnecessary_transmutes)` as suggested by Gary. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2026-09-08Bluetooth: btusb: Fix leaked runtime PM reference in btusb_resetJiajia Liu1-1/+3
btusb_reset calls usb_autopm_get_interface to resume the device before queuing a reset of it, but never calls the matching usb_autopm_put_interface. usb_queue_reset_device ends up in usb_reset_device(), and since btusb provides no pre_reset/post_reset callbacks the interface is merely unbound and rebound: the interface device object survives this cycle, and so does its PM usage count, which is not cleared when the driver is unbound. As a result every reset permanently leaks a PM usage reference, preventing the interface from being runtime suspended again until it is unbound. Set BTUSB_RESET flag before usb_queue_reset_device so that btusb_disconnect drops the reference. If the flag is already set, drop one reference. Fixes: c9209b269afd ("Bluetooth: btusb: Introduce generic USB reset") Assisted-by: Claude:qwen3.8-max Signed-off-by: Jiajia Liu <liujiajia@kylinos.cn> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-08Bluetooth: btusb: mediatek: Fix leaked runtime PM reference in resetJiajia Liu1-1/+13
MT7925 on HP Pro Mini 260 sometimes timed out during reloading driver and reset usb device. btusb_suspend is not called again after closing bluetooth interface. usbcore: registered new interface driver btusb Bluetooth: hci0: HW/SW Version: 0x00000000, Build Time: 20260605184935 Bluetooth: hci0: Execution of wmt command timed out Bluetooth: hci0: Failed to send wmt patch dwnld (-110) Bluetooth: hci0: Failed to set up firmware (-110) usb 3-10: reset high-speed USB device number 4 using xhci_hcd Bluetooth: hci0: HW/SW Version: 0x00000000, Build Time: 20260605184935 Bluetooth: hci0: Device setup in 1856545 usecs Bluetooth: hci0: AOSP extensions version v1.00 Bluetooth: hci0: AOSP quality report is supported Bluetooth: MGMT ver 1.23 btusb_mtk_reset calls usb_autopm_get_interface to resume the device before driving the hardware reset, but never calls the matching usb_autopm_put_interface. Every hardware reset therefore leaks a PM usage reference of the interface, preventing the device from being runtime suspended again until it is unbound. Add the BTUSB_RESET flag. It is set before usb_queue_reset_device and is cleared in btusb_disconnect, which drops the reference as well. If the flag is already set when a new reset is requested, drop one reference. Also clear BTMTK_HW_RESET_ACTIVE if usb_autopm_get_interface fails, otherwise no further reset could ever be attempted. Fixes: 25b6d7593a3a ("Bluetooth: btmtk: introduce btmtk reset work") Assisted-by: Claude:qwen3.8-max Signed-off-by: Jiajia Liu <liujiajia@kylinos.cn> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-08Bluetooth: btqcomsmd: destroy RPMsg endpoints before freeing hci_devXu Rao1-1/+5
The command and ACL RPMsg endpoints store struct btqcomsmd as their callback private data. The receive callbacks dereference btq->hdev without taking an hci_dev reference. The current teardown order frees the hci_dev before destroying the RPMsg endpoints in both the hci_register_dev() error path and the driver remove path. If WCNSS delivers data in that window, the endpoint callback can run with an already freed hci_dev and pass it to the Bluetooth core. For qcom_smd endpoints, rpmsg_destroy_ept() closes the channel and clears the callback under the channel recv_lock. The receive path holds the same lock while invoking the callback, so destroying the endpoints first both prevents new callbacks and serializes with any callback already running. Destroy the command and ACL endpoints before hci_free_dev(). Keep hci_unregister_dev() first during remove so the HCI core stops issuing operations before the transport endpoints are shut down. In the full registration-error cleanup path, return directly after freeing the hci_dev to avoid falling through to the partial-construction labels and destroying the endpoints twice. Fixes: 5052de8deff5 ("soc: qcom: smd: Transition client drivers from smd to rpmsg") Fixes: 9a39a927be01 ("Bluetooth: btqcomsmd: Fix a resource leak in error handling paths in the probe function") Cc: stable@vger.kernel.org Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Signed-off-by: Xu Rao <raoxu@uniontech.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-08Bluetooth: hci_sysfs: Fix NULL pointer dereference in device_del()Krystian Kaniewski1-2/+15
A NULL pointer dereference in klist_put() occurs when a child device (such as a BNEP network device in bnep_session) is concurrently being unregistered while hci_conn_del_sysfs() reparents child devices. This is caused by a race condition between hci_conn_del_sysfs() and concurrent child device unregistration (e.g. bnep_session calling unregister_netdev()). During device unregistration, device_del() snapshots a non-NULL parent pointer. Concurrently, hci_conn_del_sysfs() finds the child device using device_find_any_child() and calls device_move() to reparent it to NULL, which removes the node from its parent's klist and clears knode_parent. Subsequently, device_del() calls klist_del(&dev->p->knode_parent) using the stale parent snapshot, causing klist_put() to dereference knode_klist(n)->put on an already removed node, resulting in a NULL pointer dereference. This race was introduced by commit 27aabf27fd01 ("Bluetooth: fix use-after-free in device_for_each_child()"), which replaced device_find_child(..., __match_tty) with device_find_any_child() in hci_conn_del_sysfs(). That change was intended to avoid a use-after-free where conn->dev outlived its parent hdev->dev when child devices held references to conn->dev, because conn->dev only held a reference to hdev->dev while registered in sysfs. Fix the issue properly by taking an explicit reference to the parent device with get_device(&hdev->dev) in hci_conn_init_sysfs() and dropping it with put_device(parent) in bt_link_release() when the conn device is freed. This ensures that hdev->dev remains valid for the entire lifecycle of conn->dev, resolving the underlying use-after-free. With the parent reference held properly, restore the __match_tty filter in hci_conn_del_sysfs() so that device_move() is only invoked on persistent RFCOMM TTY devices as originally intended, eliminating the race condition with unregistering network devices. Fixes: 27aabf27fd01 ("Bluetooth: fix use-after-free in device_for_each_child()") Assisted-by: Gemini:gemini-3.7-flash syzbot Reported-by: syzbot+6df45dd3d03e1a9aca96@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=6df45dd3d03e1a9aca96 Link: https://syzkaller.appspot.com/ai_job?id=f1c0e740-db21-40af-a9ff-84db0fd8b8bd Signed-off-by: Krystian Kaniewski <krystianmkaniewski@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-08Bluetooth: btmtk: Declare MT7920 (MT7961 1a) Bluetooth firmwareIvan Hu2-0/+2
btmtk_fw_get_filename() constructs the firmware name at runtime, so for the MT7920 variant (dev_id 0x7961 with fw_flavor set) it requests "mediatek/BT_RAM_CODE_MT7961_1a_2_hdr.bin" without ever declaring it via MODULE_FIRMWARE(). Tools that select firmware from module metadata (e.g. "modinfo -F firmware") therefore omit this blob, so request_firmware() fails and Bluetooth does not initialise on MT7920, even though the file is present in linux-firmware. Declare it with MODULE_FIRMWARE(), as the mt76 driver already does for the corresponding MT7920 wifi firmware. Fixes: 1cb63d80fff6 ("Bluetooth: btusb: Add support Mediatek MT7920") Signed-off-by: Ivan Hu <ivan.hu@canonical.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-08Bluetooth: hci_sync: Fix not setting CE length properlyLuiz Augusto von Dentz1-2/+36
Both hci_le_set_def_rate_sync() and hci_le_conn_rate_request_sync() were leaving Min_CE_Length and Max_CE_Length set to 0x0000, but the connection event length recommended in requests by a Peripheral has a valid range of 0x0001 to 0x7CFF (Time = N * 125 us, Time Range: 0.125 ms to 3.999875 s), so 0x0000 cannot be used. Set both to the minimum valid value, which is safe since the Controller is not required to use these values: BLUETOOTH CORE SPECIFICATION Version 6.2 | Vol 4, Part E 7.8.157. LE Connection Rate Request command 7.8.158. LE Set Default Rate Parameters command The Min_CE_Length and Max_CE_Length parameters provide the Controller with the expected minimum and maximum length of the connection events. The Controller is not required to use these values. Fixes: 2f8784cfe8a9 ("Bluetooth: Add support for Shorter Connection Interval (SCI) feature") Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-08Bluetooth: btintel_pcie: fix tx_handle bounds off-by-oneKiran K1-1/+1
Valid indices into txq->urbd0s/tfds/bufs are 0..txq->count-1, so tfd_index == txq->count is already out of range. Change the guard in btintel_pcie_msix_tx_handle() from '> txq->count' to '>= txq->count'. This issue was reported by Claude Mythos. Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport") Signed-off-by: Kiran K <kiran.k@intel.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-08Bluetooth: btintel_pcie: validate packet_len before skb_put_dataKiran K1-1/+3
btintel_pcie_submit_rx_work() reads packet_len from rfh_hdr without checking if it exceeds the RX buffer size. An oversized packet_len can lead to an out-of-bounds read in skb_put_data(). Validate packet_len to ensure it is non-zero and does not exceed BTINTEL_PCIE_BUFFER_SIZE - sizeof(*rfh_hdr), logging an error when invalid. This issue was reported by Claude Mythos. It can be simulated either by using customized firmware configured to return an invalid packet_len or by modifying rfh_hdr->packet_len in the driver before calling btintel_pcie_submit_rx_work(). Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport") Signed-off-by: Kiran K <kiran.k@intel.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-08Bluetooth: btrtl: Don't leak return code when parsing firmware format v2Rong Zhang1-3/+2
When key_id from chip is zero, rtlbt_parse_firmware_v2() intentionally ignores all security headers. However, the implementation simply breaks from a switch statement and leaks uninitialized return code `rc' (if the first section is a security one) or the previous section's `rc'. Fix it by really skipping a loop with `continue'. For consistency and readability, also do the same for the default case. Fixes: 9a24ce5e29b1 ("Bluetooth: btrtl: Firmware format v2 support") Cc: stable@vger.kernel.org Signed-off-by: Rong Zhang <i@rong.moe> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-08Bluetooth: btusb: Fix UAF of btusb_data by rx_workLuiz Augusto von Dentz1-4/+10
btusb_close() and btusb_flush() cancel data->rx_work with the asynchronous cancel_delayed_work(), so if btusb_rx_work() is already running on another CPU it keeps running after the cancel returns. btusb_disconnect() calls hci_unregister_dev(), which invokes btusb_close(), and then frees the btusb_data. A still running btusb_rx_work() then dereferences the freed data: while ((skb = skb_dequeue(&data->acl_q))) data->recv_acl(data->hdev, skb); Use cancel_delayed_work_sync() instead. In btusb_close() the cancel also has to happen after btusb_stop_traffic(), otherwise an URB completion racing with the cancel can requeue the work right after it has been waited for. Fixes: 800fe5ec302e ("Bluetooth: btusb: Add support for queuing during polling interval") Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-08Bluetooth: Properly disable remote wakeup for MT7922/MT7925 on Ryzen platformRong Zhang2-14/+69
It is reported that a remote wakeup could cause MT7922/MT7925's btusb interface completely unresponsive. Resetting the xHCI root hub doesn't help at all, and recovering from such a state needs a power cycle. All reports seen to be relevant to Ryzen-based laptops. These NICs are usually used as OEM components thanks to some sort of reference designs. Their popularity on other platforms is unclear. While there is still a chance that the quirk may exist on other platforms, be cautious and only apply the quirk to direct children of Ryzen platforms's root hubs for the time being. In most cases the root hub is on the SoC or PCH, which needs the quirk. Unfortunately, this can't distinguish root hubs on PCIe add-in cards. Such roughness should be acceptable, as PCIe USB controller add-in cards are less commonly used nowadays. On the other hand, applying the quirk doesn't hurt any functionalities either, as the device can still be used as a wakeup source if desired. Theoretically, we could retrieve the root hub's PCI vendor ID with some hierarchy magic, but that's too intrusive... Meanwhile, though device_set_wakeup_capable(false) is the correct fix for other NICs with fake remote wakeup capabilities, doing so for MT7922/MT7925 effectively prevents it from being used as wakeup sources as per userspace requests. Hence, return -EBUSY on runtime suspend to prevent the interface from being autosuspended while it's still opened, which has the same effect as device_set_wakeup_capable(false), since disabling remote wakeup simply causes the USB core to gate runtime autosuspend as well due to needs_remote_wakeup == 1. The interface can be safely autosuspended as long as remote wakeup is disabled, i.e., after closing the HCI device. Specifically, the interface may still take the advantage of remote wakeup in order to wake up the system from sleep if userspace has enabled it as a wakeup source. Fixes: e31d761628ad ("Bluetooth: btmtk: Disable remote wakeup for MT7922/MT7925") Tested-by: Rafael Passos <rafael@rcpassos.me> Signed-off-by: Rong Zhang <i@rong.moe> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-09-08Merge tag 'nf-26-09-07' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nfJakub Kicinski10-507/+34
Pablo Neira Ayuso says: ==================== Netfilter/IPVS fixes for net The following patchset contains Netfilter/IPVS fixes for net: 1) Reject malformed messages in IPVS sync, from Kyle Zeng. 2) Fix possible stale infoleak in IPVS sync, also from Kyle Zeng. 3) Out-of-bound read in the SIP conntrack helper, from Joas Antonio dos Santos. 4) UaF on cttimeout module removal, from Chengfeng Ye. 5) Unregister nf_loggers before netns teardown to fix UaF, also from Chengfeng Ye. 6) Fix race in nfnetlink_log due to concurrent instance destruction, from Florian Westphal. 7) Remove arp_table 32bit compat interface, this is already off in many distributions, from Florian Westphal. 8) Set IP6T_F_PROTO flag is e->ipv6.proto is set on to deal with insufficient validation of xtables extensions when used from legacy ip6tables, from Florian. 9) Set on the NLM_F_DUMP_FILTERED flag when all is filtering out in ctnetlink, from Ilya Maximets. * tag 'nf-26-09-07' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: netfilter: report NLM_F_DUMP_FILTERED when all is filtered out netfilter: ip6_tables: set F_PROTO when proto value is nonzero netfilter: arp_tables: remove the 32bit compat interface netfilter: nfnetlink_log: cope with concurrent instance destruction netfilter: nf_log: unregister loggers before per-net teardown netfilter: cttimeout: prevent UAF during module unload netfilter: nf_conntrack_sip: fix OOB read in sip_skip_whitespace() ipvs: fix reversed sequence option serialization ipvs: reject invalid states in connection template sync records ==================== Link: https://patch.msgid.link/20260907171732.1407739-1-pablo@netfilter.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-08eth: ice: don't dereference pointers from TP_printk()Jakub Kicinski1-22/+42
After forwarding net-next during the v7.3 merge window we started seeing: TRACE EVENT ERROR: Event ice_tx_dim_work has double dereference in TP_printk: REC->q_vector->tx.tx_ring->q_index WARNING: kernel/trace/trace_events.c:420 at test_double_dereference.cold+0x39/0x4b this is due to extra checks added in tracing subsystem in commit b5cc230af5e5 ("tracing: Warn when an event dereferences a pointer in TP_printk()"). Printing happens long after the event was recorded, by which point the pointers may be invalid (the ring or the dim instance). Copy the eight scalars into the event instead. Fixes: 3089cf6d3caa ("ice: add tracepoints") Signed-off-by: Jakub Kicinski <kuba@kernel.org> Tested-by: Alexander Nowlin <alexander.nowlin@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2026-09-08ice: add missing xa_destroy for sched_node_idsJacob Keller3-6/+9
Commit 16dfa49406bc ("ice: Introduce new parameters in ice_sched_node") added a sched_node_ids xarray to the port info structure, but never called xa_destroy on it. Since xarrays can allocate internal memory, this can result in a memory leak even if every element in the xarray has been removed. The xarray is currently embedded in the port_info structure. This appears to have been done because its use is within functions that take the port_info as a primary argument. However, this complicates managing the lifecycle of the field. The port_info structure is allocated in ice_init_hw() using devm, and it is not released until the devm cleanup when the driver is unloaded. The ice_init_hw() function is called in many places, including devlink reload, and possibly during DDP load after updating the Tx scheduler layout. Adding a call of xa_destroy to the ice_deinit_hw() causes Sashiko to raise multiple concerns due to potential ordering issues and possible ways that port_info could be a dangling reference. To handle this, move the sched_node_ids out of port_info and into the hw structure. All users of the array already have a pointer to hw anyways, and there is only one sched_node_ids per adapter. While here, remove the overly verbose comment explaining the nature of the sched_node_ids xarray. Add the missing xa_destroy to the cleanup path and to ice_deinit_hw(), ensuring that we properly release the xarray memory. This was caught by Sashiko during development of unrelated code. Fixes: 16dfa49406bc ("ice: Introduce new parameters in ice_sched_node") Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel) Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2026-09-08idpf: account for VLAN header when parsing RSC packet headerJoshua Hay1-3/+7
While parsing the header of a Receive Side Coalesced (RSC) packet, check if a VLAN tag is present and adjust the header parsing accordingly. Otherwise, Rx TCP traffic is completely broken for any VLAN interface whose underlying interface has RSC (rx-gro-hw) enabled. We only need to worry about one VLAN header since Rx packets with multiple VLAN headers are not candidates for RSC. Fixes: 3a8845af66edb ("idpf: add RX splitq napi poll support") Signed-off-by: Joshua Hay <joshua.a.hay@intel.com> Reviewed-by: Emil Tantilov <emil.s.tantilov@intel.com> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Tested-by: Samuel Salin <Samuel.salin@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2026-09-08idpf: disable PTM on probe failure and on removeMyeonghun Pak1-0/+5
idpf_probe() enables PCIe Precision Time Measurement with pci_enable_ptm(), which takes a reference on the device and on every PTM-capable device up the path to the PTM Root. Neither the probe error path nor idpf_remove() drops that reference, so the PTM enable counts of this device and of its upstream path stay elevated with no bound driver, and the device's PTM control bits remain set. pcim_enable_device() only arranges for pci_disable_device() and does not undo the PTM enable. Add the matching pci_disable_ptm() to the common unwind path. pci_enable_ptm() failure is not fatal here, so guard the call with pcie_ptm_enabled(): pci_disable_ptm() decrements dev->ptm_enable_cnt unconditionally and then recurses upstream, so calling it after a failed enable would drive this device's count negative and wrongly decrement parents shared with other endpoints. This issue was identified during our ongoing static-analysis research while reviewing kernel code. Fixes: 8d5e12c5921c ("idpf: add initial PTP support") Co-developed-by: Ijae Kim <ae878000@gmail.com> Signed-off-by: Ijae Kim <ae878000@gmail.com> Signed-off-by: Myeonghun Pak <mhun512@gmail.com> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Tested-by: Samuel Salin <Samuel.salin@intel.com> [TN moved call due to commit 6b284aa2ddf3 ("idpf: refactor idpf to use libie_pci APIs")] Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2026-09-08idpf: disable DIM work before freeing q_vectorsMyeonghun Pak1-1/+23
idpf never drains the Tx/Rx DIM works before freeing the memory they live in. tx_dim and rx_dim are embedded in struct idpf_q_vector, they are queued from the NAPI poll via net_dim(), and idpf_vport_intr_rel() ends with kfree(rsrc->q_vectors). Nothing in the driver cancels them. idpf_tx_dim_work() and idpf_rx_dim_work() then run on freed memory: idpf_vport_intr_write_itr() writes the ITR register through q_vector->intr_reg.tx_itr / rx_itr, void __iomem pointers loaded out of the freed q_vector. No configuration is needed to get there -- IDPF_ITR_IS_DYNAMIC() is defined as (itr_mode) and idpf_vport_alloc() initialises both modes to IDPF_ITR_DYNAMIC. Draining after idpf_vport_intr_napi_dis_all() is not enough on its own. idpf_net_dim() is called from inside the "if (napi_complete_done(napi, work_done))" branch of the poll, and napi_complete_done() has already cleared NAPIF_STATE_SCHED by then. napi_disable_locked() waits only while (val & (NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC)), so napi_disable() can return while the poll tail is still queueing the work, and a plain cancel_work_sync() would be re-armed behind the drain. Use disable_work_sync(): schedule_work() on a work with a non-zero disable count is dropped by clear_pending_if_disabled() before __queue_work() is reached. Move idpf_init_dim() to idpf_vport_intr_alloc() so the works are initialised on every path that can reach the drain -- the three "goto intr_deinit" sites between idpf_vport_intr_init() and idpf_vport_intr_ena() get there without the enable side having run. Nothing re-enables them: rsrc->q_vectors is freed on every exit from idpf_vport_open() and on every idpf_vport_stop(), so the count dies with the object. It is a race, not a deterministic failure -- net_dim() only schedules once DIM_NEVENTS events have accumulated and the profile index changes. A KASAN ifup/ifdown loop under load is the way to see it. Fixes: c2d548cad150 ("idpf: add TX splitq napi poll support") Fixes: 3a8845af66ed ("idpf: add RX splitq napi poll support") Cc: <stable@vger.kernel.org> # see patch description, needs adjustments for <= 6.9 Co-developed-by: Ijae Kim <ae878000@gmail.com> Signed-off-by: Ijae Kim <ae878000@gmail.com> Signed-off-by: Myeonghun Pak <mhun512@gmail.com> Tested-by: Samuel Salin <Samuel.salin@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2026-09-08Merge branches 'for-next/ffa/fixes' and 'for-next/scmi/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linuxSudeep Holla4-7/+16
* 'for-next/ffa/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux: firmware: arm_ffa: Tear down driver during shutdown * 'for-next/scmi/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux: firmware: arm_scmi: Fix typo "upto" in comment clk: scpi: use PLATFORM_DEVID_NONE for scpi-cpufreq clk: scpi: register scpi-cpufreq once and clear on failure clk: scpi: bound-check DVFS index in scpi_dvfs_recalc_rate firmware: arm_scpi: reject DVFS OPP count above MAX_DVFS_OPPS firmware: arm_scpi: fix device_node leak in scpi_dev_domain_id
2026-09-08Merge tag 'x86_urgent_for_7.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tipLinus Torvalds2-7/+14
Pull x86 fixes from Dave Hansen: "These are fixes for some older AMD device topology and machine check issues. But, they are issues that are affecting real users and aren't just cleaning up AI drive-by reports. These is coming a wee bit later than the usual Sundays because of a late breaking issue with one of the patches which is now temporarily kicked out" * tag 'x86_urgent_for_7.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/MCE/AMD: Fix inverted interrupt enablement during storm handling x86/amd_node: Fix potential NULL pointer dereference x86/amd_node: Avoid divide by zero on virtualized systems
2026-09-08platform/x86: x86-android-tablets: fix gpio_secondary_fwnode_init() not workingHans de Goede1-2/+9
acpi_bus_find_device_by_name() call returns a pointer to the device object on the ACPI bus, aka the ACPI companion device. gpio_secondary_fwnode_init() then continues with setting the secondary fwnode on this device. But this is not the actual physical device for the GPIO controller (e.g. the GPIO controller platform bus device). This mismatch is causing GPIO lookups by secondary fwnode to not work. Modify gpio_secondary_fwnode_init() to instead set the secondary fwnode of the first physical device associated with the ACPI companion device. This fixes the GPIO lookups not working. Fixes: 1448c2d2ca5c ("platform/x86: x86-android-tablets: enable fwnode matching of GPIO chips") Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com> Link: https://patch.msgid.link/20260908185517.49047-1-johannes.goede@oss.qualcomm.com Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
2026-09-08mmc: spi: reset bytes_xfered before retrying CRC failuresXu Rao1-0/+1
mmc_spi_data_do() updates data->bytes_xfered after each block has been transferred successfully. If a later block in the same data request fails with a CRC error, data->bytes_xfered may therefore contain the number of bytes completed before the failing block. mmc_spi_request() has a private recovery path for such CRC failures. It sends STOP_TRANSMISSION, clears data->error and jumps back to crc_recover to issue the same command and data request again. However, it does not clear data->bytes_xfered before the retry. If the retry succeeds, the request is completed with the bytes from the failed attempt still included in data->bytes_xfered. For a multi-block request this can make the completed request report more bytes than were transferred by the successful retry, and can even exceed the request size when most blocks completed before the CRC error. This is most likely to be observed on MMC-over-SPI systems where long multi-block transfers occasionally hit a data CRC error but the mmc_spi-internal retry succeeds. The data itself is retried, but the completion accounting is not. Clear data->bytes_xfered together with data->error before repeating the request so the final completion reports only the bytes transferred by the successful attempt. Fixes: 061c6c847eeb ("mmc_spi: Recover from CRC errors for r/w operation over SPI.") Cc: stable@vger.kernel.org Signed-off-by: Xu Rao <raoxu@uniontech.com> Signed-off-by: Ulf Hansson <ulfh@kernel.org>