summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-10-15ext4: drain writeback before removing extents on the iomap pathZhang Yi
Because the iomap infrastructure does not always create an ifs to manage sub-folio state when folio size is larger than blocksize, invalidating a partial dirty folio during punch hole may fail to clear the dirty state of the affected range. As a result, writeback of that folio may observe a hole. At writeback submit time, ext4_map_blocks() already handles this case and will not allocate blocks. However, when punch hole races with writeback, the following scenario can cause I/O completion to encounter a hole. punch hole writeback ---------- --------- ext4_punch_hole() ext4_truncate_page_cache_block_range() iomap_invalidate_folio() [partial folio] iomap_clear_range_dirty() -- no ifs, sub-block dirty bits NOT cleared ext4_iomap_writepages() iomap_writepages() ext4_iomap_writeback_submit() ext4_iomap_map_writeback_range() ext4_map_blocks(IO_SUBMIT) -> extent exists, not a hole submit_io() -> bio in flight down_write(&i_data_sem) ext4_es_remove_extent() ext4_ext_remove_space() -> extent removed, hole inserted up_write(&i_data_sem) [ transaction commits, freed blocks released to buddy ] [ allocator reuses freed blocks for another inode ] [bio completes] ext4_iomap_finish_ioend() ext4_convert_unwritten_extents() ext4_map_blocks(IO_CONVERT_EXT) -> returns 0 (hole found) [bio writes to reallocated blocks ] -> silent data corruption If the bio completes after the freed blocks have been reallocated to another inode, it silently overwrites them and causes data corruption. Therefore, on the iomap path, drain writeback in ext4_punch_hole() after partial zeroing and before starting the freeing transaction, so any bio in flight on a partial folio completes against blocks still owned by this inode before extent removal. Once extent removal begins, the ES hole insert and the existing IO_SUBMIT short-circuit prevent further bio submission. This is a workaround. The proper fix is for the iomap infrastructure to always maintain an ifs when folio size is larger than blocksize, so that partial invalidate reliably clears sub-block dirty bits and no draining is needed. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-19-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15ext4: implement partial block zero range path using iomapZhang Yi
Introduce a new iomap_ops instance, ext4_iomap_zero_ops, along with ext4_block_iomap_zero_range() to implement block zeroing via the iomap infrastructure for ext4. ext4_block_iomap_zero_range() calls iomap_zero_range() with ext4_iomap_zero_begin() as the callback. The callback locates the range and populates the iomap mapping. If the range is mapped, iomap_zero_iter() in the iomap core zeros the partial block directly. If the range is an unwritten extent within EOF, the callback collects a dirty folio batch via iomap_fill_dirty_folios() so that iomap_zero_iter() can zero those folios directly, bypassing a separate slow flush operation that would otherwise be needed to convert the unwritten extent. Note that ext4_iomap_zero_begin() can race with concurrent writeback: after it queries an unwritten extent, writeback may convert it to written and complete on the folio before iomap_fill_dirty_folios() scans the range. The empty batch then makes iomap_zero_iter() skip zeroing, leaving stale on-disk data. zero_range writeback ---------------------- ---------------------- ext4_block_zero_range() iomap_zero_range() iomap_iter() ext4_iomap_zero_begin() ext4_iomap_map_blocks() -> extent is UNWRITTEN ext4_convert_unwritten_extents_endio() -> extent is converted to WRITTEN -> folio is clean iomap_fill_dirty_folios() filemap_get_folios_dirty() -> folio is clean, not added to batch ext4_set_iomap() -> IOMAP_UNWRITTEN iomap_zero_iter() __iomap_get_folio() -> NULL (empty batch) iomap_iter_advance_full() <-- zeroing skipped [later read returns stale on-disk data] <-- CORRUPTION Therefore, we retry the extent lookup when iomap_fill_dirty_folios() adds nothing and the i_es_seq cookie captured at the first lookup has advanced, indicating the race actually occurred. Other important constraints: Zeroing out under an active journal handle can cause deadlock, as the lock/handle ordering is inconsistent with the iomap writeback path. Therefore, ext4_block_iomap_zero_range() must not be called under an active handle. In addition, for post-EOF zeroing, the caller cannot rely on data=ordered mode to persist the zeroed data before i_disksize is updated. Subsequent patches will address this by deferring i_disksize update to i_size until after the zeroed data has been written back. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-18-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15ext4: implement mmap path using iomapZhang Yi
Introduce ext4_iomap_page_mkwrite() to implement the mmap iomap path for ext4. The heavy lifting is delegated to iomap_page_mkwrite(), which only requires ext4_iomap_buffered_write_ops and ext4_iomap_buffered_da_write_ops to allocate and map blocks. Note that the lock ordering between folio lock and transaction start in this path is reversed compared to the buffer_head buffered write path. The lock ordering documentation in super.c has been updated accordingly. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Reviewed-by: Jan Kara <jack@suse.cz> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-17-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15ext4: implement writeback path using iomapZhang Yi
Add the iomap writeback path for ext4 buffered I/O. This introduces: - ext4_iomap_writepages(): the main writeback entry point. - ext4_writeback_ops: a new iomap_writeback_ops instance to handle block mapping and I/O submission. - A new end I/O work handler ext4_iomap_finish_ioend() is added for converting unwritten extents, updating file size, and handling DATA_ERR_ABORT after I/O completion. Core implementation details: - ->writeback_range() callback Calls ext4_iomap_map_writeback_range() to map and allocate blocks using the enhanced ext4_map_blocks(). ext4_map_blocks() now starts its own transaction internally when it needs to allocate blocks. For performance, when a block range is not yet allocated, it allocates based on the writeback length and delalloc extent length (ext4_map_blocks() will trim the allocated length), rather than allocating a single folio at a time. The folio is then added to an iomap_ioend instance. - ->writeback_submit() callback Registers ext4_iomap_end_bio() as the end bio callback. This callback schedules a worker to handle: - Unwritten extent conversion. - i_disksize update after data is written back. - Journal abort on writeback I/O failure. - The new end I/O work handler ext4_iomap_finish_ioend() This reuses i_rsv_conversion_work and i_rsv_conversion_list, which are now used in the buffer_head writeback path for memory saving, because an inode can never go through both buffer_head and iomap paths. Those are not initialized in this patch but will be when the iomap path is formally enabled later. Key changes and considerations: - Append write and unwritten extents Since data=ordered mode is not used to prevent stale data exposure during append writebacks, new blocks are always allocated as unwritten extents (i.e. always enable dioread_nolock), and i_disksize update is postponed until I/O completion. Additionally, the deadlock that the reserve handle was expected to resolve does not occur anymore. Therefore, the end I/O worker can start a normal journal handle instead of a reserve handle when converting unwritten extents. - Lock ordering The ->writeback_range() callback runs under the folio lock, requiring the journal handle to be started under that same lock. This reverses the order compared to the buffer_head writeback path. The lock ordering documentation in super.c has been updated accordingly. - Don't cache writes The iomap infrastructure sets the BIO_COMPLETE_IN_TASK flag when submitting I/O, so the ioend will be processed in task context. However, if a private defer worker is to be started, this flag must be cleared explicitly to avoid double deferral. In the future, all private defer work should be moved to the generic bio complete in task framework. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-16-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15ext4: rework handle credit accounting for unwritten extent conversionZhang Yi
While converting the buffered I/O path to iomap, we noticed that the writeback completion can hand over an ioend which was merged across an arbitrary number of extents because iomap_ioend_try_merge() doesn't limit the length of the merged ioends, while ext4_convert_unwritten_extents() converts all of them with the handle provided by the caller, and callers calculate the credits of that handle without knowing the exact number of extents. Converting more extents than that within one transaction can exhaust its credits. Prepare for the iomap path nevertheless by making the conversion loop check the remaining credits before each extent with ext4_journal_ensure_credits(), so that the transaction is extended, or restarted once it is full, as needed. Also estimate the credits with ext4_meta_trans_blocks(..., alloc_extents = 0), since no data blocks are allocated here, and manage an internally started transaction as a whole instead of starting and stopping one for each extent. The buffer_head writeback path is safe, as it passes a handle whose credits are reserved by ext4_meta_trans_blocks(inode, bpf, bpf, 0), which is enough to convert one extent per block of a folio, so the reservation is sufficient and the handle is never restarted there. This also helps the fallocate path, where ext4_alloc_file_blocks() sizes the handle for the conversion with ext4_chunk_trans_blocks() as well, i.e. for a single extent only, while a concurrent modification of the extent tree can make the conversion cover more extents than the handle has credits for. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-15-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15ext4: implement buffered write path using iomapZhang Yi
Introduce two new iomap_ops instances for ext4 buffered writes: - ext4_iomap_buffered_da_write_ops: for delayed allocation mode, using ext4_da_map_blocks() to map delalloc extents. - ext4_iomap_buffered_write_ops: for non-delayed allocation mode, using ext4_map_blocks() to directly allocate blocks. Also add ext4_iomap_valid() for the iomap infrastructure to check extent validity. This is useful for the iomap buffered write path because it does not hold the folio lock between mapping the inode extent and copying data. So it can race with writeback, which may modify or stale the extent type. Key changes and considerations: - Unwritten extents for new blocks (dioread_nolock always on) Since data=ordered mode is not used to prevent stale data exposure in the non-delayed allocation path, new blocks are always allocated as unwritten extents. - Short write and write failure handling a. Delalloc path: On short write or failure, the stale delalloc range must be dropped and its space reservation released. Otherwise, a clean folio may cover leftover delalloc extents, causing inaccurate space reservation accounting. b. Non-delalloc path: No cleanup of allocated blocks is needed on short write since leaving the preallocated blocks behind doesn't cause any real issue. These blocks are visible to users and are not permanently leaked. - Adjust the call frequency of ext4_nonda_switch() so that it is no longer called once per folio in the buffer_head path, but instead once per write. For code simplicity, ext4_iomap_buffered_da_write_ops will be shared with the later page-fault path. Since ext4_nonda_switch() -> try_to_writeback_inodes_sb() synchronously waits for writeback, which could lead to deadlock under the same folio lock acquired by iomap_page_mkwrite(), we can no longer call ext4_nonda_switch() inside ext4_iomap_buffered_da_write_ops. This may increase the probability of a writeback-time allocation failure, but the expected real-world impact is small, so it can be implemented this way for now. - Lock ordering reversal The folio lock and transaction start ordering is reversed compared to the buffer_head buffered write path. To handle this, the journal handle must be stopped in iomap_begin() callbacks. The lock ordering documentation in super.c has been updated accordingly. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-14-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15ext4: do not use data=ordered mode for inodes using buffered iomap pathZhang Yi
The data=ordered mode introduces two fundamental conflicts with the iomap buffered write path, leading to potential deadlocks. 1) Lock ordering conflict In the iomap writeback path, each folio is processed sequentially: the folio lock is acquired first, followed by starting a transaction to create block mappings. In data=ordered mode, writeback triggered by the journal commit process may attempt to acquire a folio lock that is already held by iomap background writeback process. Meanwhile, iomap, under that same folio lock, may start a new transaction to map other blocks on this folio and wait for the currently committing transaction to finish, resulting in a deadlock. Trans N commit background writeback(via iomap) journal_submit_data_buffers() ext4_journal_submit_inode_data_buffers() iomap_writepages() iomap_writepages() folio_lock() folio_lock() -- wait iomap_writeback_folio() iomap_writeback_range() ext4_journal_start() start new transaction -- wait for trans N commit, DEADLOCK ext4_map_blocks() Currently, in the buffer_head writeback path, this is handled by starting the transaction before taking any folio locks for writeback. 2) Partial folio submission not supported When block size < folio size, a folio may contain both mapped and unmapped blocks. In data=ordered mode, a deadlock can occur if the journal waits (pure JI_WAIT_DATA) for such a folio to be written back while background writeback has already started on it (with the writeback flag set). The problem is that mapping the remaining delalloc blocks can deadlock because the writeback flag is not cleared until the entire folio is processed and committed. T0: Assume we have a folio contains four blocks, from front to back, they are A, B, C, D. The block B and C are holes, and the last block D is written in delalloc mode (the block is not allocated yet). T1: The background writeback process starts to write back data, set writeback flag on the folio, allocates block D, and adds it to transaction N's order list of jbd2 in pure JI_WAIT_DATA mode. T2: This folio completes the writeback and clears the writeback flag. T3: Before transaction N commit, we buffered write block A to C. T4: Transaction N commit and folio writeback are running concurrently. Trans N commit background writeback(via iomap) iomap_writeback_folio() folio_start_writeback() -- set writeback flag jbd2_journal_finish_inode_data_buffers() __filemap_fdatawait_range() -- wait writeback flag to clear iomap_writeback_range() ext4_journal_start() start new transaction -- wait for trans N commit, DEADLOCK ext4_map_block() (B, C) Currently, in the buffer_head writeback path, this is handled by: 1. Partial folio submission — already-allocated buffers can be submitted first. The writeback flag is cleared after I/O completes, preventing block allocation while the writeback flag is set. 2. Allocation order — the transaction is started first, then blocks are allocated, the writeback flag is set, and finally the allocated buffers submission begins. To support data=ordered mode, the iomap core would need two invasive changes: - Acquire the transaction handle before locking any folio for writeback. - Support partial folio submission. Both changes are complicated and risk performance regressions. Therefore, we must avoid using data=ordered mode when converting to the iomap path. Currently, data=ordered mode is used in three scenarios: - Append write - Post-EOF partial block truncate-up followed by append write - Online defragmentation We can address the first two without data=ordered mode: - For append write: always allocate unwritten blocks (i.e. always enable dioread_nolock), preserving the behavior of current extent-type inodes. - For post-EOF truncate-up + append write: postpone updating i_disksize until after the zeroed partial block has been written back. Online defragmentation does not yet support iomap; this can be resolved separately in the future. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-13-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15ext4: pass out extent seq counter when mapping da blocksZhang Yi
The iomap buffered write path does not hold the folio lock between mapping the inode extent and copying data. Therefore, it can race with writeback that modifies the extent type (e.g., from unwritten to written). This can lead to data corruption on partial writes, as iomap_block_needs_zeroing() may return a false positive based on a stale extent. The iomap infrastructure uses the sequence counter stored in the inode to detect such stale mappings. Commit 07c440e8da8f ("ext4: pass out extent seq counter when mapping blocks") added the m_seq field to ext4_map_blocks to pass out extent sequence numbers, but it missed two callsites within ext4_da_map_blocks(). These callsites are on the delayed allocation path, which is needed in the iomap buffered write path. Pass out the sequence counter to ensure stale mappings can be detected. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-12-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15ext4: implement buffered read path using iomapZhang Yi
Implement the iomap read path for ext4 by introducing a new ext4_iomap_buffered_read_ops instance. This provides the read_folio() and readahead() callbacks for ext4_iomap_aops. The implementation introduces: - ext4_iomap_map_blocks(): Helper function to query extent mappings for a given read range using ext4_map_blocks() and convert the mapping information to iomap type - ext4_iomap_buffered_read_begin(): The iomap_begin callbacks that maps blocks, validates filesystem state, and populates the iomap. It returns -ERANGE for inline data which is not yet supported. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-11-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15ext4: add iomap address space operations for buffered I/OZhang Yi
Introduce initial support for iomap in the buffered I/O path for regular files on ext4. - Add a new inode state flag EXT4_STATE_BUFFERED_IOMAP to indicate the inode uses iomap instead of buffer_head for buffered I/O - Add helper ext4_inode_buffered_iomap() to check the flag - Add new address space operations ext4_iomap_aops with callbacks that will use generic iomap implementations - Add ext4_iomap_aops to ext4_set_aops() when the flag is set The following callbacks(read_folio(), readahead(), writepages()) are provided as placeholders and will be implemented in later patches. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-10-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15ext4: skip block allocation for holes in the data submission pathZhang Yi
When ext4_map_blocks() is called from the data submission path and I/O end extent conversion path (EXT4_GET_BLOCKS_IO_SUBMIT), it should not allocate blocks if the lookup returns a hole. The writeback path can legitimately encounter dirty ranges that map to holes. For example, when a folio straddles i_size and the tail beyond i_size is dirtied via a mmap write. Allocating blocks for such ranges is wrong because there is no data to write back, the dirty bits should simply be discarded without submitting I/O. This prepares for the buffered iomap writeback conversion, mirrors the existing buffer_head writeback path, where mpage_add_bh_to_extent() skip unmapped buffers and ext4_bio_write_folio() clears their dirty bits. Since ext4_map_blocks() can now return zero for a hole, mpage_map_one_extent() must handle it as well. However, because those holes are already filtered out by mpage_add_bh_to_extent(), it only maps buffers that are delayed or unwritten, so a hole can never occur in normal operation. Add a WARN_ON_ONCE() and bail out with -EINVAL rather than proceeding with an invalid physical block number of zero. In the ioend extent conversion path, holes are also not expected because we should wait for folio writeback before punching hole. If one is encountered, it likely indicates a failure in the concurrency protection, so ext4_map_blocks() returns zero, and we keep warning and bail out with -EINVAL to surface the failure rather than continuing conversion on torn data. Atomic writes in ext4_convert_unwritten_extents_atomic() already bail out similarly. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-9-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15ext4: avoid unnecessary transaction in ext4_map_blocks() for unwritten extentsZhang Yi
When ext4_map_blocks() finds an unwritten extent in the extent cache and the caller is willing to accept unwritten extents without conversion, there is no need to start a journal transaction since no metadata update is required. This avoids unnecessary transaction overhead in the upcoming iomap writeback path when overwriting already-allocated unwritten extents. One thing to be careful about, as the comment in ext4_map_blocks() states, if the flags contain EXT4_GET_BLOCKS_CREATE, the function will mark @map as mapped. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-8-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15ext4: allow ext4_map_blocks() to start its own transaction handleZhang Yi
Make ext4_map_blocks() start its own transaction handle when the caller does not provide one. The handle is started after the lookup path confirms that allocation is actually needed, and is stopped at the unified out exit path. This avoids unnecessarily starting a handle for pure mapping queries. This prepares for the buffered iomap writeback conversion, which improves performance for fragile overwrite cases. Suggested-by: Jan Kara <jack@suse.cz> Link: https://lore.kernel.org/linux-ext4/i536qqwj5eyulec3r2ki2ycnelqdd4bkpat2drn7t72t6p622k@ktueynysgo3j/ Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-7-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15ext4: fix orig_mlen initialization in ext4_map_blocks()Zhang Yi
Save orig_mlen after clamping map->m_len to INT_MAX. Otherwise, the unclamped value may be passed below, bypassing its overflow protection. Fixes: 5bb12b1837c0 ("ext4: Add support for EXT4_GET_BLOCKS_QUERY_LEAF_BLOCKS") Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-6-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15ext4: recheck extent status tree before block allocationZhang Yi
After acquiring i_data_sem in write mode, recheck that the mapping found via the extent status tree or disk query has not changed. A racing truncate may have trimmed the extent between the earlier lookup and the write lock acquisition, since writeback does not hold i_rwsem or the folio locks covering the full extent. This could cause ext4_map_create_blocks() to allocate blocks beyond the truncated range, potentially leading to quota leaks in the upcomming iomap buffered writeback path, because the iomap writeback infrastructure caches extents beyond the folio range. Therefore, if we find a valid extent and the sequence number has changed, retry the entire lookup to obtain the correct trimmed mapping. Note that a retry only happens when i_es_seq has actually changed, which requires another thread to hold i_data_sem in write mode, so each retry implies real lock contention, and the writer yields on the rwsem slowpath rather than spinning. Moreover, the read-write lock also tries its best to guarantee fairness, so even though no retry limit is added here, livelock should not occur in theory. Also, the retry here mirrors the existing write_ops->iomap_valid() + IOMAP_F_STALE mechanism in iomap, which also rechecks the sequence number and retries without any upper bound, and has not shown livelock problems in practice. In addition, if ext4_map_query_blocks() fails, return the error immediately. Otherwise the following sequence number comparison would use a map->m_seq that may not have been updated, and silently continuing on an error is not advisable. Suggested-by: Jan Kara <jack@suse.cz> Link: https://lore.kernel.org/linux-ext4/b0781809-4759-4e12-be17-71555b764f48@gmail.com/ Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-5-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15ext4: set EXT4_MAP_NEW flag for delayed allocated blocksZhang Yi
Set EXT4_MAP_NEW in ext4_da_map_blocks() to properly indicate that a new delayed allocation block has been inserted, allowing callers to distinguish newly created delayed extents from existing ones. Currently, the buffer_head caller, ext4_da_get_block_prep(), does not consume this flag. It intercepts EXT4_MAP_DELAYED and returns early, and unconditionally calls set_buffer_new(bh) so EXT4_MAP_NEW is not used. The flag is prepared for the iomap buffered I/O path added later. Reported-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Link: https://lore.kernel.org/linux-ext4/cc05c17d-163e-4251-b2c9-aa3a6f9555d7@huaweicloud.com/ Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-4-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15ext4: factor out ext4_truncate_[up|down]()Zhang Yi
Refactor ext4_setattr() by introducing two helper functions, ext4_truncate_up() and ext4_truncate_down(), to handle size changes. The current ATTR_SIZE processing consolidates checks for both shrinking and non-shrinking cases, leading to cluttered code. Separating the truncation paths improves readability. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Reviewed-by: Jan Kara <jack@suse.cz> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-3-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15ext4: simplify size updating in ext4_setattr()Zhang Yi
The logic for updating the file size in ext4_setattr() is currently somewhat messy. By directly entering the error-handling path after failing to add an orphan inode, the unnecessary recovery process involving old_disksize and the file size can be avoided. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Tested-by: syzbot@syzkaller.appspotmail.com Link: https://patch.msgid.link/20261009103033.2920530-2-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-10-15Merge tag 'renesas-dts-for-v7.4-tag2' of ↵Alexandre Belloni
git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel into soc/dt Renesas DTS updates for v7.4 (take two) - Add PCIe support for the RZ/G3L SoC, - Add ADC DMA support for the RZ/T2H and RZ/N2H SoCs, - Add initial support for the RZ/G2M v3.0 SoC and the HopeRun HiHope RZ/G2M v3.0 board stack, - Add USB support for the RZ/G3E SoC and the RZ/G3E SMARC EVK board, - Add SPI (MSIOF) and I2C support for the R-Car X5H SoC, - Add support for various SolidRun boards based on RZ/G2L, RZ/G2LC, RZ/V2L, and RZ/G2UL, - Miscellaneous fixes and improvements. * tag 'renesas-dts-for-v7.4-tag2' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel: (34 commits) arm64: dts: renesas: Add support for solidrun rzg2ul som on hb-ripple arm64: dts: renesas: Add support for solidrun hb-ripple with rzg2lc som arm64: dts: renesas: Add support for solidrun hb-ripple with rzv2l som arm64: dts: renesas: Add support for solidrun hb-ripple with rzg2l som arm64: dts: renesas: rzg2l(c)/rzv2l hb-iiot: Add dsi panel dt overlay arm64: dts: renesas: Add support for solidrun rzg2lc som and hb-iiot evb arm64: dts: renesas: Add support for solidrun rzv2l som and hb-iiot evb arm64: dts: renesas: Add support for solidrun rzg2l som and hb-iiot evb dt-bindings: soc: renesas: Add various SolidRun RZ/G2 based boards arm64: dts: renesas: r8a779h0: Add PCIe Application/Local register reset arm64: dts: renesas: r8a779g0: Add PCIe Application/Local register reset arm64: dts: renesas: r8a779f0: Add PCIe Application/Local register reset arm64: dts: renesas: r8a78000: Add I2C nodes arm64: dts: renesas: r8a78000: Add MSIOF nodes dt-bindings: clock: renesas,r8a78000-cpg: Add MSIOF clocks arm64: dts: renesas: r9a09g047e57-smarc: Enable USB2.0 support arm64: dts: renesas: r9a09g047: Add USB2.0 support arm64: dts: renesas: r9a08g046: Add USB2.0 placeholder nodes arm64: dts: renesas: Add HiHope RZ/G2M v3.0 SoC sub board support arm64: dts: renesas: Add HiHope RZ/G2M v3.0 SoC main board support ... Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2026-10-15dt-bindings: mfd: mediatek: mt6397: describe the RTC's nvmem layoutRyan Brue
Four of the MT6397 RTC's alarm registers use only their low bits; the high byte of each is storage the clock and the alarm don't touch. MediaTek's documentation names them RTC_NEW_SPARE0 to RTC_NEW_SPARE3 and assigns the first to a fuel gauge, which is what a battery driver reads at boot so that the reported capacity does not jump across a reboot. They sit in the RTC's always-on domain, so the driver can offer them as a battery-backed nvmem provider. Allow a board to lay cells out over them. Assisted-by: LLM Signed-off-by: Ryan Brue <ryanbrue.dev@gmail.com> Reviewed-by: Rob Herring (Arm) <robh@kernel.org> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Link: https://patch.msgid.link/20260917-rbrue-suez-upstreaming-mt6397-rtc-nvmem-v1-1-558b8f95cfbc@gmail.com Signed-off-by: Lee Jones <lee@kernel.org>
2026-10-15Revert "platform/x86: thinkpad_acpi: Add X9-14 Gen 1 to non-standard ↵Huang Wei
thermal/fan quirk tables" This reverts commit bb0f3a5d6b9844b70ad696b9470762028f6d86ec. Lenovo's firmware team has verified that the X9-14 Gen 1 uses EC register offsets that are unique to this platform, rather than the shared non-standard ECFW layout of the models already covered by the quirk tables. Applying the generic quirk would make the driver read the wrong registers and report bogus temperatures. Lenovo is working on the correct solution based on an updated EC register specification. Link: https://lore.kernel.org/all/000acb24-7aef-4718-89ea-0dffd1ab34d9@app.fastmail.com/ Signed-off-by: Huang Wei <huangwei@kylinos.cn> Link: https://patch.msgid.link/20261013070740.789934-1-huangwei@kylinos.cn Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
2026-10-15ASoC: SOF/amd: Fixups for ACP7.B support and ASP carveoutMark Brown
Merge series from Vijendar Mukunda <Vijendar.Mukunda@amd.com>: A couple of additional fixups for the earlier series adding ACP7.B support and ASP carveout firmware loading.
2026-10-15platform/x86: msi-ec: Add MSI Creator Z16 A11UE EC firmwareAlexey Subbota
Add EC firmware version 1571EMS1.106 (MSI Creator Z16 A11UE) to the list of firmwares handled by CONF14. The EC register layout matches CONF14 field for field (verified against the out-of-tree msi-ec configuration for this firmware, where it is part of CONF_G2_10). Tested on a Creator Z16 A11UE with this driver built against 7.2.9: the module loads, charge_control_start_threshold and charge_control_end_threshold read the values set by the EC, and writing charge_control_end_threshold is applied and reads back. Assisted-by: LLM Signed-off-by: Alexey Subbota <subbota-job@yandex.ru> Link: https://patch.msgid.link/20261013212228.17349-1-subbota-job@yandex.ru Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
2026-10-15drm/panthor: Remove redundant drm_gem_create_mmap_offset() call from ↵Akash Goel
BO_MMAP_OFFSET ioctl This commit removes the call to drm_gem_create_mmap_offset() from the BO_MMAP_OFFSET ioctl handler. The call was redundant and didn't have any effect as file offset range is allocated unconditionally at the BO creation time. v2: - New patch Suggested-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Akash Goel <akash.goel@arm.com> Reviewed-by: Steven Price <steven.price@arm.com> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com> Link: https://patch.msgid.link/20261013125433.26432-2-akash.goel@arm.com
2026-10-15drm/panthor: Fix handling of NO_MMAP BOsAkash Goel
The BOs created with DRM_PANTHOR_BO_NO_MMAP flag are not supposed to be mmappable by the Userspace. But after the rework to support shrinker, it became possible to mmap NO_MMAP BOs. Userspace could second guess the file offset range, allocated unconditionally at the BO creation time, and create a CPU mapping. There may not be any adverse effect of such a CPU mapping though. This commit adds a check in the mmap callback of Panthor driver to fail the mmap() attempts on BOs created with NO_MMAP flag. The check covers private BOs as well as the prime exported BOs that are mmapped using prime fd. v2: - Fix breakage of mmap() on exported BOs that didn't have BO_MMAP_OFFSET ioctl invoked for them. Fixes: 68cbf96b1e9b ("drm/panthor: Part ways with drm_gem_shmem_object") Suggested-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Akash Goel <akash.goel@arm.com> Reviewed-by: Steven Price <steven.price@arm.com> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com> Link: https://patch.msgid.link/20261013125433.26432-1-akash.goel@arm.com
2026-10-15Revert "nvme-pci: clamp max_hw_sectors based on DMA optimized limitation"Christoph Hellwig
This turns down to cause up to 15% performance regressions on standard large transfer workloads. Revert it and hope the IOVA allocator can eventually be fixed to remove the need for the original workaround. This reverts commit 3710e2b056cb92ad816e4d79fa54a6a5b6ad8cbd. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Keith Busch <kbusch@kernel.org>
2026-10-15Merge branch 'bnxt_en-fix-sw-uso-padding'Paolo Abeni
Joe Damato says: ==================== bnxt_en: Fix SW USO padding As a followup to Eric's fix a51d233ccd48 ("bnxt_en: fix DMA mapping length for padded small packets") which fixes padding for normal TX, this series fixes padding for SW USO. There are two cases I try to address: 1. The last segment could be shorter than BNXT_MIN_PKT_SIZE. So, add an extra BD if needed to pad to that minimum. 2. The gso_size is so small that every segment would be shorter than BNXT_MIN_PKT_SIZE (under 10 bytes with IPv4). This seems exceedingly unlikely, but just in case, it is handled by clearing the GSO features for these skbs so the stack segments them. Patch 1 is a small refactor to move code into a helper that patch 2 uses to avoid duplicating code. I ran v1 on a bnxt machine and re-ran the uso.py test and it passed, but the existing uso.py test doesn't test this specific case, so running the test was more of a regression test. There were no functional changes to v2. Note that I did not see this issue in production and it should not be possible for QUIC to hit this case on either ipv4 or ipv6 because QUIC packets are at least 21 bytes. AFAIU, only ipv4 segments with less than 10 bytes of UDP payload can trigger this. As such, I was asked to send this to net-next. v1: https://lore.kernel.org/netdev/20261008191114.3736826-1-joe@dama.to/ ==================== Link: https://patch.msgid.link/20261009215426.2377946-1-joe@dama.to Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15bnxt_en: Pad short SW USO segments to BNXT_MIN_PKT_SIZEJoe Damato
Each SW USO segment is hdr_len + seg_payload bytes. With IPv4, hdr_len is 42 bytes, so a segment carrying less than 10 bytes of UDP payload is sent shorter than BNXT_MIN_PKT_SIZE. This happens with a short last segment (e.g. gso_size 1400 and 1405 bytes of payload) or with a gso_size below 10 bytes. Fix the short last segment in bnxt_sw_udp_gso_xmit(): zero the pad bytes after the header in the segment's inline header slot and add a pad BD pointing at them after the payload BDs. Only the last segment can need padding, and its pad BD fits within the existing bound in bds_needed and BNXT_SW_USO_MAX_DESCS, since payload BDs are at most num_segs + nr_frags. If gso_size itself is too small, every segment would need a pad BD, exceeding the descriptor bound. This case is unlikely, so bnxt_features_check() clears GSO features for these skbs and the stack segments them instead; bnxt_start_xmit() then pads each segment. Reviewed-by: Michael Chan <michael.chan@broadcom.com> Signed-off-by: Joe Damato <joe@dama.to> Link: https://patch.msgid.link/20261009215426.2377946-3-joe@dama.to Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15bnxt_en: Add helper to fill SW USO payload BDsJoe Damato
Move the code that fills a payload BD and its software ring entry in bnxt_sw_udp_gso_xmit() into a helper, bnxt_sw_gso_data_bd(). No functional change. A following patch uses the helper to add a pad BD to short SW USO segments. Reviewed-by: Michael Chan <michael.chan@broadcom.com> Signed-off-by: Joe Damato <joe@dama.to> Link: https://patch.msgid.link/20261009215426.2377946-2-joe@dama.to Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15spi: npcm-fiu: limit UMA data_size to the 16-byte staging bufferWeibin Liu
npcm_fiu_uma_read() and npcm_fiu_uma_write() use a 16-byte on-stack staging buffer (u32 data_reg[4]) and move data_size bytes to or from it. data_size comes straight from op->data.nbytes, which is supplied by the SPI MEM operation and is not bounded by the driver: npcm_fiu_exec_op() only validates op->addr.nbytes, and no adjust_op_size callback truncates the transfer to the controller FIFO size. A SPI MEM operation with addr.nbytes == 0 and data.nbytes > 16 therefore overflows data_reg[] on the kernel stack (write path) or reads past it (read path), corrupting the stack. Reject data_size larger than the staging buffer in both UMA helpers by returning -EOPNOTSUPP, so spi_mem falls back to the generic SPI message path. The chunked path in npcm_fiu_manualwrite() always passes at most CHUNK_SIZE bytes, so it is unaffected. Fixes: ace55c411b11 ("spi: npcm-fiu: add NPCM FIU controller driver") Cc: stable@vger.kernel.org # 5.4+ Reviewed-by: Guanglei Zhu <zhugl3@xiaopeng.com> Signed-off-by: Weibin Liu <liuwb@xiaopeng.com> Link: https://patch.msgid.link/20261015-npcm-fiu-uma-datasize-v1-1-7dee91cadee6@xiaopeng.com Signed-off-by: Mark Brown <broonie@kernel.org>
2026-10-15RDMA/rxe: bound the WQE opcode before indexing rxe_wr_opcode_info[]Youngsung Ahn
wr_opcode_mask() indexes the global rxe_wr_opcode_info[] array with a caller-supplied opcode and no bounds check. For a user QP the WQE comes from an mmap'd SQ ring, so wqe->wr.opcode is an attacker-controlled __u32 read back by the requester (req_next_wqe() -> rxe_requester()); rxe_post_send() takes the qp->is_user branch and never runs validate_send_wr(), whose only opcode check is itself !wr_opcode_mask() (it indexes before it checks). rxe_wr_opcode_info[] has entries only up to IB_WR_REG_MR, so an out-of-range opcode reads out of bounds and the result is used as a mask and dereferenced; observed as a KASAN global-out-of-bounds "Read of size 4" and a wild-pointer oops. Return a zero mask for an out-of-range opcode, matching how validate_send_wr() already treats a zero mask (an invalid WR), so no path indexes the array out of bounds. Fixes: 8700e3e7c485 ("Soft RoCE driver") Signed-off-by: Youngsung Ahn <ays511.kr@gmail.com> Link: https://patch.msgid.link/20261002164552.294749-1-ays511.kr@gmail.com Signed-off-by: Leon Romanovsky <leon@kernel.org>
2026-10-15RDMA/rxe: Fix out-of-range unsigned-to-signed conversion for RDMA message in ↵Honggang LI
2GiB size When RDMA READ request for 2GiB in single WR, res->read.resid is u32 0x80000000, which is INT_MIN (-2147483648). payload = min_t(int, res->read.resid, mtu); The `min_t` function will return -2147483648 for payload. The wrong size is propagated through call chain, `read_reply` -> `prepare_ack_packet` -> `rxe_init_packet` -> `alloc_skb` . `alloc_skb` failed because of invalid size. The passive side failed to emit response packet for RDMA READ request. After fixed it, the active side of RDMA READ failed with error code "IB_WC_LOC_PROT_ERR". When RDMA_READ_RESPONSE_FIRST packet recived by the active side, `do_read` call `copy_data`. dma->resid is u32 0x80000000. int resid = dma->resid; This conversion set resid to -2147483648. `copy_data` abort as length greater than resid. RDMA SEND and WRITE 2GiB message works too, after fixed these two bugs. Fixes: 8700e3e7c485 ("Soft RoCE driver") Signed-off-by: Honggang LI <honggangli@163.com> Link: https://patch.msgid.link/20261002142250.657151-1-honggangli@163.com Signed-off-by: Leon Romanovsky <leon@kernel.org>
2026-10-15RDMA/rxe: validate inline sge_offset in finish_packet() before indexing ↵Youngsung Ahn
inline_data[] For a user QP, rxe_post_send() takes the qp->is_user branch and never runs init_send_wqe(), so dma.length/resid/num_sge/cur_sge/sge_offset all come straight from the mmap'd SQ ring. In the inline send path finish_packet() uses sge_offset directly as an index: u8 *tmp = &wqe->dma.inline_data[wqe->dma.sge_offset]; memcpy(payload_addr(pkt), tmp, payload); inline_data is a flex array whose capacity is qp->sq.max_inline, but sge_offset is a u32 from user space, so the source pointer is displaced arbitrarily past the WQE and the memcpy reads out of bounds. commit 126c757e4cd4 ("RDMA/rxe: Validate num_sge/cur_sge before indexing wqe->dma.sge[]") added num_sge/cur_sge checks on the send path but not sge_offset, the third attacker-controlled index in the same struct. Read sge_offset once with READ_ONCE() and bound it (and the payload that follows it) by qp->sq.max_inline before indexing, so the value that is validated is the value that is used. Fixes: 8700e3e7c485 ("Soft RoCE driver") Signed-off-by: Youngsung Ahn <ays511.kr@gmail.com> Link: https://patch.msgid.link/20261001152433.3259573-1-ays511.kr@gmail.com Signed-off-by: Leon Romanovsky <leon@kernel.org>
2026-10-15RDMA/rxe: bound the ODP page index against the umem in rxe_check_pagefault()Youngsung Ahn
An ODP MR has a page array, map.pfn_list[]. Its size is computed from the umem start address. But rxe_check_pagefault() builds the index into that array from an iova that is relative to the same start, while the access itself was range-checked against the MR's iova (ibmr.iova). Those two bases do not have to match. reg_mr only requires that start and hca_va have the same page offset, so a user can register an MR with hca_va = start + N*PAGE. The difference then becomes an index skew of (hca_va - start) >> PAGE_SHIFT. Nothing compares the result with the size of pfn_list[], so the read goes past the end of the array. An unprivileged local user can reach this with a single RDMA operation on a self-connected rxe QP. KASAN reports a slab-out-of-bounds read. If the out-of-bounds qword happens to look like a writable HMM pfn, rxe then copies the payload into a page the user never registered. Reject an index that falls outside the umem and take the fault path instead. That path rejects the out-of-range access in ib_umem_odp_map_dma_and_lock(), which does check the umem range. The other users of pfn_list[], __rxe_odp_mr_copy() and the atomic helpers, run only after a successful map, so this single check covers them too. Fixes: 2fae67ab63db ("RDMA/rxe: Add support for Send/Recv/Write/Read with ODP") Signed-off-by: Youngsung Ahn <ays511.kr@gmail.com> Link: https://patch.msgid.link/20261004153246.2951263-1-ays511.kr@gmail.com Signed-off-by: Leon Romanovsky <leon@kernel.org>
2026-10-15RDMA/rxe: reject IB_WR_REG_MR from user QPs in rxe_reg_fast_mr()Youngsung Ahn
IB_WR_REG_MR is documented as kernel-only ("can not be issued by userspace"), but nothing enforces it. rxe_wr_opcode_info[IB_WR_REG_MR] sets WR_LOCAL_OP_MASK for IB_QPT_RC, a QP type userspace can create, so a user QP that writes opcode = IB_WR_REG_MR into its mmap'd SQ ring reaches rxe_do_local_ops() -> rxe_reg_fast_mr(). That function then trusts the ring-supplied fields: struct rxe_mr *mr = to_rmr(wqe->wr.wr.reg.mr); ... if (unlikely(mr->state != RXE_MR_STATE_FREE)) /* deref */ ... mr->access = access; /* write */ For a user QP wqe->wr.wr.reg.mr is a fully attacker-chosen pointer, so this is an arbitrary-kernel-address dereference (arbitrary read confirmed, oops). No existing check distinguishes a user QP on this path. Reject IB_WR_REG_MR for user QPs before dereferencing the supplied pointer. Fixes: 8700e3e7c485 ("Soft RoCE driver") Signed-off-by: Youngsung Ahn <ays511.kr@gmail.com> Link: https://patch.msgid.link/20261001152426.3259522-1-ays511.kr@gmail.com Signed-off-by: Leon Romanovsky <leon@kernel.org>
2026-10-15dt-bindings: bus: Add HiSilicon local busRob Herring (Arm)
Add a schema for hisilicon,hisi-localbus which is already in use for a long time. Link: https://patch.msgid.link/20261005205310.2079198-1-robh@kernel.org Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
2026-10-15RDMA/rxe: refuse to destroy a QP with type 2 MWs still boundYoungsung Ahn
Binding a type 2 memory window takes a reference on the QP: rxe_do_bind_mw() does rxe_get(qp) and stores it in mw->qp. That reference is released only when the window is invalidated (rxe_do_invalidate_mw() on IB_WR_LOCAL_INV) or the window itself is destroyed (rxe_mw_cleanup()). rxe_qp_chk_destroy() does not account for those references -- it only refuses when qp->mcg_num is non-zero. So an unprivileged user can bind a type 2 MW to a QP and then destroy the QP while the binding is still live. __rxe_cleanup() cannot drop the QP refcount to zero (the MW still holds a reference), hits its -ETIMEDOUT path, and frees the QP anyway; mw->qp is left dangling. When the MW is later invalidated or deallocated, rxe_mw_cleanup()/rxe_do_invalidate_mw() do rxe_put(mw->qp) on the freed struct rxe_qp -- a use-after-free write (refcount_dec, and complete()/list work if it reaches zero) reachable from userspace. IB_WR_BIND_MW is a local operation, so no peer is required. Track the number of type 2 MWs bound to a QP and refuse to destroy the QP while that count is non-zero, returning -EBUSY exactly as the existing multicast-attachment check does. The window must be invalidated or deallocated, which drops the reference and the count, before the QP can be destroyed. Fixes: 8700e3e7c485 ("Soft RoCE driver") Signed-off-by: Youngsung Ahn <ays511.kr@gmail.com> Link: https://patch.msgid.link/20260930182223.2511145-1-ays511.kr@gmail.com Signed-off-by: Leon Romanovsky <leon@kernel.org>
2026-10-15dt-bindings: gpu: img,powervr-rogue: add spacemit,k1-gpu and spacemit,k3-gpuBaihui Liang
Add compatible strings for the IMG GPUs in SpacemiT K1 and K3 SoCs: - K1: IMG BXE-2-32 (adds a dedicated entry for a single core clock and power domain). - K3: IMG BXM-4-64 (shares the same configuration and entry as the T-Head TH1520). Signed-off-by: Baihui Liang <liangbaihui@linux.spacemit.com> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> Link: https://patch.msgid.link/20261015-spacemit-gpu-binding-v1-1-a7a23c7e7788@linux.spacemit.com Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
2026-10-15platform/x86/intel/tpmi: Describe the device creation policy on the functionKuppuswamy Sathyanarayanan
The comment explaining the error policy of tpmi_create_devices() sits inside the loop, between the call and the check it describes. Move it above the function, where it describes the policy as a whole. Also split the check into its two cases, skipping unsupported features and failing on any other error, so that each reads on its own. No functional change intended. Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com> Suggested-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Link: https://patch.msgid.link/20261013192935.2243291-21-sathyanarayanan.kuppuswamy@linux.intel.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
2026-10-15platform/x86/intel/tpmi: Declare the loop counters in their loopsKuppuswamy Sathyanarayanan
Declare the loop counters in the for statements that use them, so that they are scoped to their loops. In tpmi_create_device() this also replaces the tmp cursor, which moved in step with the counter, with res[i]. While at it, use post-increment in all of them, as the other loops in the file already do. No functional change intended. Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Link: https://patch.msgid.link/20261013192935.2243291-20-sathyanarayanan.kuppuswamy@linux.intel.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
2026-10-15platform/x86/intel/tpmi: Use DEFINE_RES_MEM() for the feature resourcesKuppuswamy Sathyanarayanan
tpmi_create_device() fills in each feature resource field by field, deriving the end from the start and setting IORESOURCE_MEM by hand. That is what DEFINE_RES_MEM() exists for, so use it. The resources come from kzalloc_flex(), so the fields the macro sets that the open coded version left alone, name and desc, were already zero. No functional change intended. Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Link: https://patch.msgid.link/20261013192935.2243291-19-sathyanarayanan.kuppuswamy@linux.intel.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
2026-10-15platform/x86/intel/tpmi: Use scnprintf() to build the debugfs namesKuppuswamy Sathyanarayanan
The kernel has both snprintf() and scnprintf() for formatting into a fixed size buffer. The preference is to settle on scnprintf() and stop adding snprintf() users, so that only one of the two remains in use. Convert the two callers in tpmi_dbgfs_register(). Neither of them looks at the return value, so the difference in what the two functions return does not matter here. No functional change intended. Suggested-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com> Link: https://patch.msgid.link/20261013192935.2243291-18-sathyanarayanan.kuppuswamy@linux.intel.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
2026-10-15platform/x86/intel/tpmi: Use DEFINE_SHOW_STORE_ATTRIBUTE() for mem_writeKuppuswamy Sathyanarayanan
The mem_write debugfs file open handler and file_operations are written out by hand, which is what DEFINE_SHOW_STORE_ATTRIBUTE() exists for. Use it, and rename the write callback to mem_write_write() to match the name the macro derives. The other two files in this driver already come from DEFINE_SHOW_ATTRIBUTE(), so this also gives mem_write the .owner = THIS_MODULE that the open coded file_operations was missing. Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Link: https://patch.msgid.link/20261013192935.2243291-17-sathyanarayanan.kuppuswamy@linux.intel.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
2026-10-15platform/x86/intel/tpmi: Build the TPMI control words in one expressionKuppuswamy Sathyanarayanan
Both mailbox words in tpmi_read_feature_status() are assembled as an assignment followed by an or-assign of a second field, even though neither value is used in between. Build each of them in a single expression, so that a word and the fields it is made of read as one thing. The two comments on the command word described one value between them, so fold them together as well. No functional change intended. Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Link: https://patch.msgid.link/20261013192935.2243291-16-sathyanarayanan.kuppuswamy@linux.intel.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
2026-10-15platform/x86/intel/tpmi: Use scope based cleanup in the memory dumpKuppuswamy Sathyanarayanan
tpmi_mem_dump_show() frees its dump buffer and drops tpmi_dev_lock by hand at the end of the function, so the ioremap() failure in the middle of the loop cannot just return. It breaks out with an error stashed in ret, which is the only reason ret exists. Attach the buffer to __free(kfree) at its allocation and take the mutex with guard(), then return the error directly from the loop. mem_write() in this file already does both, so this makes the two debugfs paths consistent. No functional change intended. Suggested-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Link: https://patch.msgid.link/20261013192935.2243291-15-sathyanarayanan.kuppuswamy@linux.intel.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
2026-10-15platform/x86/intel/tpmi: Use guard() for tpmi_dev_lock in the status readKuppuswamy Sathyanarayanan
tpmi_read_feature_status() takes tpmi_dev_lock explicitly and unwinds through an err_unlock label, which is what forced the two error paths before the mailbox command is issued to be gotos rather than returns. Take the mutex with guard() and return directly from those two paths. The done_proc label stays, because the paths that reach it have already handed the mailbox to the hardware and still owe it the CPL write before dropping the lock. That is unchanged: the two early failures never wrote CPL before either. No functional change intended. Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com> Suggested-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Link: https://patch.msgid.link/20261013192935.2243291-14-sathyanarayanan.kuppuswamy@linux.intel.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
2026-10-15platform/x86/intel/tpmi: Turn TPMI_GET_SINGLE_ENTRY_SIZE() into a functionKuppuswamy Sathyanarayanan
The macro computing a feature instance size has a few problems. Its comment says the hardware reports the size in u32 units, but the conversion to bytes is spelled as a shift by 2, so the comment and the code have to be read together to see that they agree. Its body is a single conditional expression wrapped in a statement expression that it never needed. And it evaluates its argument twice. Make it a plain static function, tpmi_get_single_entry_size(), which fixes all three: the conversion becomes a multiply by sizeof(u32), there is nothing left to wrap, and the argument is evaluated once and type checked. No functional change intended. Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com> Suggested-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Link: https://patch.msgid.link/20261013192935.2243291-13-sathyanarayanan.kuppuswamy@linux.intel.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
2026-10-15platform/x86/intel/tpmi: Include the headers tpmi_common.c relies onKuppuswamy Sathyanarayanan
tpmi_common.c uses a number of interfaces whose headers it never includes directly and only gets by chance through other headers: BIT_ULL(), GENMASK_ULL() bits.h __packed compiler_attributes.h EXPORT_SYMBOL_NS_GPL() export.h DEFINE_IDA() idr.h IORESOURCE_MEM ioport.h DEFINE_MUTEX(), mutex_lock() mutex.h seq_printf(), seq_hex_dump() seq_file.h kmalloc(), kzalloc_flex() slab.h USEC_PER_MSEC, USEC_PER_SEC time64.h uXX types.h Include them, so that the file does not break when an unrelated header stops pulling them in. Drop io.h while at it, as iopoll.h already includes it, and sort the block alphabetically: debugfs.h and cleanup.h were the wrong way round. No functional change intended. Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com> Suggested-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Link: https://patch.msgid.link/20261013192935.2243291-12-sathyanarayanan.kuppuswamy@linux.intel.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
2026-10-15platform/x86/intel/tpmi: Split off the PCI VSEC enumerationKuppuswamy Sathyanarayanan
Everything the TPMI driver does once the PFS table has been located is independent of how the TPMI MMIO region was discovered, from walking the PFS to creating the per feature devices. Only the entry point is VSEC specific and it is now reduced to filling in the arguments of intel_tpmi_init(). Move the enumeration independent code to a new intel-tpmi_common module and leave the auxiliary driver binding to the "intel_vsec.tpmi" device created by the Intel VSEC driver in vsec_tpmi.c. The code is moved as is, apart from a stray blank line and a typo in a comment that are fixed in passing. tpmi_common.h exposes what an enumeration method needs, which is intel_tpmi_init(), intel_tpmi_deinit() and struct intel_tpmi_info. The structure is a complete type because the enumeration method allocates it and is expected to extend it with its own data. The PFS, TPMI_INFO and feature state layouts stay private to tpmi_common.c, only the hardware parsing touches them. CONFIG_INTEL_TPMI_COMMON is a hidden symbol selected by the enumeration method, in the same way as CONFIG_INTEL_TPMI_POWER_DOMAINS. The TPMI client API is now exported by intel-tpmi_common, so the client drivers depend on that module instead of intel-vsec_tpmi. That is what allows a second, non PCI enumeration method to be added later without the client drivers knowing which one is loaded. No functional change. Co-developed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Link: https://patch.msgid.link/20261013192935.2243291-11-sathyanarayanan.kuppuswamy@linux.intel.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
2026-10-15platform/x86/intel/tpmi: Split out enumeration independent init and exitKuppuswamy Sathyanarayanan
Once the two devices and the MMIO resources are known, the rest of what the init path does is independent of how the TPMI instance was found. Turn that part into intel_tpmi_init(), taking them as arguments, and add intel_tpmi_deinit() for what removal has to undo. The auxiliary bus and intel_vsec_device handling stays in tpmi_probe() and tpmi_remove(). intel_tpmi_info is allocated by the caller instead of by intel_tpmi_init(), so that an enumeration method can embed it in its own state and get back to that with container_of(). The TPMI_CORE_INIT and TPMI_CORE_EXIT notifications now pass the struct device of the TPMI instance instead of its auxiliary device, so that the generic code does not have to know about the auxiliary bus. No in tree notifier callback looks at that argument and one that needs the auxiliary device can use to_auxiliary_dev(). The driver data is set with dev_set_drvdata() on the same device that auxiliary_set_drvdata() used, so tpmi_remove() still finds it. No functional change. Co-developed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Link: https://patch.msgid.link/20261013192935.2243291-10-sathyanarayanan.kuppuswamy@linux.intel.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>