diff options
3 files changed, 145 insertions, 0 deletions
diff --git a/queue-5.15/arm64-restrict-pagetable-teardown-to-avoid-false-warning.patch b/queue-5.15/arm64-restrict-pagetable-teardown-to-avoid-false-warning.patch new file mode 100644 index 0000000000..2ea4fe9d32 --- /dev/null +++ b/queue-5.15/arm64-restrict-pagetable-teardown-to-avoid-false-warning.patch @@ -0,0 +1,46 @@ +From 650768c512faba8070bf4cfbb28c95eb5cd203f3 Mon Sep 17 00:00:00 2001 +From: Dev Jain <dev.jain@arm.com> +Date: Tue, 27 May 2025 13:56:33 +0530 +Subject: arm64: Restrict pagetable teardown to avoid false warning + +From: Dev Jain <dev.jain@arm.com> + +commit 650768c512faba8070bf4cfbb28c95eb5cd203f3 upstream. + +Commit 9c006972c3fe ("arm64: mmu: drop pXd_present() checks from +pXd_free_pYd_table()") removes the pxd_present() checks because the +caller checks pxd_present(). But, in case of vmap_try_huge_pud(), the +caller only checks pud_present(); pud_free_pmd_page() recurses on each +pmd through pmd_free_pte_page(), wherein the pmd may be none. Thus it is +possible to hit a warning in the latter, since pmd_none => !pmd_table(). +Thus, add a pmd_present() check in pud_free_pmd_page(). + +This problem was found by code inspection. + +Fixes: 9c006972c3fe ("arm64: mmu: drop pXd_present() checks from pXd_free_pYd_table()") +Cc: stable@vger.kernel.org +Reported-by: Ryan Roberts <ryan.roberts@arm.com> +Acked-by: David Hildenbrand <david@redhat.com> +Signed-off-by: Dev Jain <dev.jain@arm.com> +Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> +Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com> +Reviewed-by: Ryan Roberts <ryan.roberts@arm.com> +Link: https://lore.kernel.org/r/20250527082633.61073-1-dev.jain@arm.com +Signed-off-by: Will Deacon <will@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + arch/arm64/mm/mmu.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/arm64/mm/mmu.c ++++ b/arch/arm64/mm/mmu.c +@@ -1466,7 +1466,8 @@ int pud_free_pmd_page(pud_t *pudp, unsig + next = addr; + end = addr + PUD_SIZE; + do { +- pmd_free_pte_page(pmdp, next); ++ if (pmd_present(READ_ONCE(*pmdp))) ++ pmd_free_pte_page(pmdp, next); + } while (pmdp++, next += PMD_SIZE, next != end); + + pud_clear(pudp); diff --git a/queue-5.15/btrfs-don-t-drop-extent_map-for-free-space-inode-on-write-error.patch b/queue-5.15/btrfs-don-t-drop-extent_map-for-free-space-inode-on-write-error.patch new file mode 100644 index 0000000000..c4d8d00352 --- /dev/null +++ b/queue-5.15/btrfs-don-t-drop-extent_map-for-free-space-inode-on-write-error.patch @@ -0,0 +1,97 @@ +From 5571e41ec6e56e35f34ae9f5b3a335ef510e0ade Mon Sep 17 00:00:00 2001 +From: Josef Bacik <josef@toxicpanda.com> +Date: Wed, 31 Jan 2024 14:27:25 -0500 +Subject: btrfs: don't drop extent_map for free space inode on write error + +From: Josef Bacik <josef@toxicpanda.com> + +commit 5571e41ec6e56e35f34ae9f5b3a335ef510e0ade upstream. + +While running the CI for an unrelated change I hit the following panic +with generic/648 on btrfs_holes_spacecache. + +assertion failed: block_start != EXTENT_MAP_HOLE, in fs/btrfs/extent_io.c:1385 +------------[ cut here ]------------ +kernel BUG at fs/btrfs/extent_io.c:1385! +invalid opcode: 0000 [#1] PREEMPT SMP NOPTI +CPU: 1 PID: 2695096 Comm: fsstress Kdump: loaded Tainted: G W 6.8.0-rc2+ #1 +RIP: 0010:__extent_writepage_io.constprop.0+0x4c1/0x5c0 +Call Trace: + <TASK> + extent_write_cache_pages+0x2ac/0x8f0 + extent_writepages+0x87/0x110 + do_writepages+0xd5/0x1f0 + filemap_fdatawrite_wbc+0x63/0x90 + __filemap_fdatawrite_range+0x5c/0x80 + btrfs_fdatawrite_range+0x1f/0x50 + btrfs_write_out_cache+0x507/0x560 + btrfs_write_dirty_block_groups+0x32a/0x420 + commit_cowonly_roots+0x21b/0x290 + btrfs_commit_transaction+0x813/0x1360 + btrfs_sync_file+0x51a/0x640 + __x64_sys_fdatasync+0x52/0x90 + do_syscall_64+0x9c/0x190 + entry_SYSCALL_64_after_hwframe+0x6e/0x76 + +This happens because we fail to write out the free space cache in one +instance, come back around and attempt to write it again. However on +the second pass through we go to call btrfs_get_extent() on the inode to +get the extent mapping. Because this is a new block group, and with the +free space inode we always search the commit root to avoid deadlocking +with the tree, we find nothing and return a EXTENT_MAP_HOLE for the +requested range. + +This happens because the first time we try to write the space cache out +we hit an error, and on an error we drop the extent mapping. This is +normal for normal files, but the free space cache inode is special. We +always expect the extent map to be correct. Thus the second time +through we end up with a bogus extent map. + +Since we're deprecating this feature, the most straightforward way to +fix this is to simply skip dropping the extent map range for this failed +range. + +I shortened the test by using error injection to stress the area to make +it easier to reproduce. With this patch in place we no longer panic +with my error injection test. + +CC: stable@vger.kernel.org # 4.14+ +Reviewed-by: Filipe Manana <fdmanana@suse.com> +Signed-off-by: Josef Bacik <josef@toxicpanda.com> +Signed-off-by: David Sterba <dsterba@suse.com> +[ Larry: backport to 5.15.y. Minor conflict resolved due to missing commit 4c0c8cfc8433 + btrfs: move btrfs_drop_extent_cache() to extent_map.c ] +Signed-off-by: Larry Bassel <larry.bassel@oracle.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + fs/btrfs/inode.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -3197,8 +3197,23 @@ out: + unwritten_start += logical_len; + clear_extent_uptodate(io_tree, unwritten_start, end, NULL); + +- /* Drop the cache for the part of the extent we didn't write. */ +- btrfs_drop_extent_cache(inode, unwritten_start, end, 0); ++ /* ++ * Drop extent maps for the part of the extent we didn't write. ++ * ++ * We have an exception here for the free_space_inode, this is ++ * because when we do btrfs_get_extent() on the free space inode ++ * we will search the commit root. If this is a new block group ++ * we won't find anything, and we will trip over the assert in ++ * writepage where we do ASSERT(em->block_start != ++ * EXTENT_MAP_HOLE). ++ * ++ * Theoretically we could also skip this for any NOCOW extent as ++ * we don't mess with the extent map tree in the NOCOW case, but ++ * for now simply skip this if we are the free space inode. ++ */ ++ if (!btrfs_is_free_space_inode(inode)) ++ btrfs_drop_extent_cache(inode, unwritten_start, ++ end, 0); + + /* + * If the ordered extent had an IOERR or something else went diff --git a/queue-5.15/series b/queue-5.15/series index d769a474c9..55370c2cdd 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -92,3 +92,5 @@ media-uvcvideo-rollback-non-processed-entities-on-error.patch s390-entry-fix-last-breaking-event-handling-in-case-of-stack-corruption.patch s390-add-std-gnu11-to-decompressor-and-purgatory-cflags.patch revert-ipv6-save-dontfrag-in-cork.patch +arm64-restrict-pagetable-teardown-to-avoid-false-warning.patch +btrfs-don-t-drop-extent_map-for-free-space-inode-on-write-error.patch |