arch/arm64/include/asm/pgtable.h | 32 + arch/loongarch/include/asm/pgtable.h | 1 + arch/powerpc/include/asm/book3s/64/pgtable.h | 7 + arch/s390/include/asm/pgtable.h | 38 + arch/x86/include/asm/pgtable.h | 52 + arch/x86/include/asm/pgtable_64.h | 2 + arch/x86/mm/pgtable.c | 18 +- fs/proc/task_mmu.c | 2212 +++++++++--------- include/asm-generic/pgtable_uffd.h | 15 + include/linux/leafops.h | 46 + include/linux/mm.h | 2 + include/linux/mm_inline.h | 32 + include/linux/pagewalk.h | 106 + include/linux/pgtable.h | 95 + mm/internal.h | 75 +- mm/memory.c | 22 + mm/pagewalk.c | 400 ++++ mm/pgtable-generic.c | 10 + 18 files changed, 2024 insertions(+), 1141 deletions(-)
Changelog:
rfc -> rfcv2:
- Add pte_hole functionality
- Fix pagemap issues
- Fix shmem in smap
- Testing with pagemap "testsuite"
[WARNING]
This is not yet fully complete, but before investing more time into it I would like
to know whether 1) this is heading into the right direction and 2) this is something
we are still interested in.
E.g: one of the things that still needs work is make the new API being able to
take other locks like i_mmap, since that one is needed for hugetlb to protect
WP vs pmd-sharing in pagemap_scan.
That is already a WIP, but I still need to make a small adjustments.
Another thing is to convert "make_uffd_wp_huge_pte" to normal non-hugetlb specific
code, and that is too a WIP thing.
Kudos go to David, who was the person suggesting the interface and
he gave me some ideas where to begin, besides providing feedback
on early stages (in case there is something stupid don't blame him, blame me)
Also, I would like to thank Vlastimil, who helped me running this
patchset quite a few times through Claude, to catch some fixes.
[/WARNING]
[TESTING]
So far, tools/mm/page-types.c reports the right outcome (compared to the old API),
and tools/testing/selftests/mm/pagemap_ioctl.c only reports 4 failing tests.
Although to be honest, I do not how much should I trust that one because if I
add a few delays in the userspace code, some tests that were failing before are not
now, so yeah.
localhost:~/workspace # ./page-types -p 1168
flags page-count MB symbolic-flags long-symbolic-flags
0x0000000000000800 1 0 ___________M_______________________________ mmap
0x0000000000000828 2 0 ___U_l_____M_______________________________ uptodate,lru,mmap
0x000000000000082c 1 0 __RU_l_____M_______________________________ referenced,uptodate,lru,mmap
0x0000000000004838 1 0 ___UDl_____M__b____________________________ uptodate,dirty,lru,mmap,swapbacked
0x000000000000086c 423 1 __RU_lA____M_______________________________ referenced,uptodate,lru,active,mmap
0x0000000000205828 29 0 ___U_l_____Ma_b______x_____________________ uptodate,lru,mmap,anonymous,swapbacked,ksm
0x000000000020586c 1 0 __RU_lA____Ma_b______x_____________________ referenced,uptodate,lru,active,mmap,anonymous,swapbacked,ksm
total 458 1
localhost:~/workspace # ./page-types_lab -p 1168
flags page-count MB symbolic-flags long-symbolic-flags
0x0000000000000804 1 0 __R________M_______________________________ referenced,mmap
0x0000000000000828 2 0 ___U_l_____M_______________________________ uptodate,lru,mmap
0x000000000000082c 1 0 __RU_l_____M_______________________________ referenced,uptodate,lru,mmap
0x0000000000004838 1 0 ___UDl_____M__b____________________________ uptodate,dirty,lru,mmap,swapbacked
0x000000000000086c 423 1 __RU_lA____M_______________________________ referenced,uptodate,lru,active,mmap
0x0000000000205828 29 0 ___U_l_____Ma_b______x_____________________ uptodate,lru,mmap,anonymous,swapbacked,ksm
0x000000000020586c 1 0 __RU_lA____Ma_b______x_____________________ referenced,uptodate,lru,active,mmap,anonymous,swapbacked,ksm
total 458 1
page-types being using the new API and page-types_lab the old one.
# ./pagemap_ioctl
TAP version 13
1..117
ok 1 sanity_tests_sd Zero range size is valid
ok 2 sanity_tests_sd output buffer must be specified with size
ok 3 sanity_tests_sd output buffer can be 0
ok 4 sanity_tests_sd output buffer can be 0
ok 5 sanity_tests_sd wrong flag specified
ok 6 sanity_tests_sd flag has extra bits specified
ok 7 sanity_tests_sd no selection mask is specified
ok 8 sanity_tests_sd no return mask is specified
ok 9 sanity_tests_sd wrong return mask specified
ok 10 sanity_tests_sd mixture of correct and wrong flag
ok 11 sanity_tests_sd PAGEMAP_BITS_ALL can be specified with PM_SCAN_WP_MATCHING | PM_SCAN_CHECK_WPASYNC
ok 12 sanity_tests_sd Clear area with larger vec size
ok 13 sanity_tests_sd Repeated pattern of written and non-written pages
ok 14 sanity_tests_sd Repeated pattern of written and non-written pages in parts 498 2 2
ok 15 sanity_tests_sd Repeated pattern of written and non-written pages max_pages
ok 16 sanity_tests_sd only get 2 written pages and clear them as well
ok 17 sanity_tests_sd Two regions
ok 18 sanity_tests_sd Smaller max_pages
ok 19 Smaller vec
ok 20 Walk_end: Same start and end address
ok 21 Walk_end: Same start and end with WP
ok 22 Walk_end: Same start and end with 0 output buffer
ok 23 Walk_end: Big vec
ok 24 Walk_end: vec of minimum length
ok 25 Walk_end: Max pages specified
ok 26 Walk_end: Half max pages
ok 27 Walk_end: 1 max page
ok 28 Walk_end: max pages
ok 29 Walk_end sparse: Big vec
ok 30 Walk_end sparse: vec of minimum length
ok 31 Walk_end sparse: Max pages specified
ok 32 Walk_end sparse: Max pages specified
ok 33 Walk_end sparse: Max pages specified
ok 34 Walk_endsparse : Half max pages
ok 35 Walk_end: 1 max page
ok 36 Page testing: all new pages must not be written (dirty)
ok 37 Page testing: all pages must be written (dirty)
ok 38 Page testing: all pages dirty other than first and the last one
ok 39 Page testing: PM_SCAN_WP_MATCHING | PM_SCAN_CHECK_WPASYNC
ok 40 Page testing: only middle page dirty
ok 41 Page testing: only two middle pages dirty
ok 42 Large Page testing: all new pages must not be written (dirty)
ok 43 Large Page testing: all pages must be written (dirty)
ok 44 Large Page testing: all pages dirty other than first and the last one
ok 45 Large Page testing: PM_SCAN_WP_MATCHING | PM_SCAN_CHECK_WPASYNC
ok 46 Large Page testing: only middle page dirty
ok 47 Large Page testing: only two middle pages dirty
ok 48 Huge page testing: all new pages must not be written (dirty)
ok 49 Huge page testing: all pages must be written (dirty)
ok 50 Huge page testing: all pages dirty other than first and the last one
ok 51 Huge page testing: PM_SCAN_WP_MATCHING | PM_SCAN_CHECK_WPASYNC
ok 52 Huge page testing: only middle page dirty
ok 53 Huge page testing: only two middle pages dirty
ok 54 Hugetlb shmem testing: all new pages must not be written (dirty)
ok 55 Hugetlb shmem testing: all pages must be written (dirty)
ok 56 Hugetlb shmem testing: all pages dirty other than first and the last one
ok 57 Hugetlb shmem testing: PM_SCAN_WP_MATCHING | PM_SCAN_CHECK_WPASYNC
ok 58 Hugetlb shmem testing: only middle page dirty
not ok 59 Hugetlb shmem testing: only two middle pages dirty
ok 60 Hugetlb mem testing: all new pages must not be written (dirty)
ok 61 Hugetlb mem testing: all pages must be written (dirty)
ok 62 Hugetlb mem testing: all pages dirty other than first and the last one
ok 63 Hugetlb mem testing: PM_SCAN_WP_MATCHING | PM_SCAN_CHECK_WPASYNC
ok 64 Hugetlb mem testing: only middle page dirty
not ok 65 Hugetlb mem testing: only two middle pages dirty
ok 66 Hugetlb shmem testing: all new pages must not be written (dirty)
ok 67 Hugetlb shmem testing: all pages must be written (dirty)
ok 68 Hugetlb shmem testing: all pages dirty other than first and the last one
ok 69 Hugetlb shmem testing: PM_SCAN_WP_MATCHING | PM_SCAN_CHECK_WPASYNC
ok 70 Hugetlb shmem testing: only middle page dirty
not ok 71 Hugetlb shmem testing: only two middle pages dirty
ok 72 File memory testing: all new pages must not be written (dirty)
ok 73 File memory testing: all pages must be written (dirty)
ok 74 File memory testing: all pages dirty other than first and the last one
ok 75 File memory testing: PM_SCAN_WP_MATCHING | PM_SCAN_CHECK_WPASYNC
ok 76 File memory testing: only middle page dirty
ok 77 File memory testing: only two middle pages dirty
ok 78 File anonymous memory testing: all new pages must not be written (dirty)
ok 79 File anonymous memory testing: all pages must be written (dirty)
ok 80 File anonymous memory testing: all pages dirty other than first and the last one
ok 81 File anonymous memory testing: PM_SCAN_WP_MATCHING | PM_SCAN_CHECK_WPASYNC
ok 82 File anonymous memory testing: only middle page dirty
ok 83 File anonymous memory testing: only two middle pages dirty
ok 84 hpage_unit_tests all new huge page must not be written (dirty)
ok 85 hpage_unit_tests all the huge page must not be written
ok 86 hpage_unit_tests all the huge page must be written and clear
ok 87 hpage_unit_tests only middle page written
not ok 88 hpage_unit_tests clear first half of huge page
ok 89 hpage_unit_tests clear first half of huge page with limited buffer
ok 90 hpage_unit_tests clear second half huge page
ok 91 hpage_unit_tests get half huge page
ok 92 hpage_unit_tests get half huge page
ok 93 Test test_simple
ok 94 mprotect_tests Both pages written
ok 95 mprotect_tests Both pages are not written (dirty)
ok 96 mprotect_tests Both pages written after remap and mprotect
ok 97 mprotect_tests Clear and make the pages written
ok 98 transact_test count 192
ok 99 transact_test count 0
ok 100 transact_test Extra pages 143 (0.3%), extra thread faults 143.
ok 101 sanity_tests WP op can be specified with !PAGE_IS_WRITTEN
ok 102 sanity_tests required_mask specified
ok 103 sanity_tests anyof_mask specified
ok 104 sanity_tests excluded_mask specified
ok 105 sanity_tests required_mask and anyof_mask specified
ok 106 sanity_tests Get sd and present pages with anyof_mask
ok 107 sanity_tests Get all the pages with required_mask
ok 108 sanity_tests Get sd and present pages with required_mask and anyof_mask
ok 109 sanity_tests Don't get sd pages
ok 110 sanity_tests Don't get present pages
ok 111 sanity_tests Find written present pages with return mask
ok 112 sanity_tests Memory mapped file
ok 113 sanity_tests Read/write to memory
ok 114 unmapped_region_tests Get status of pages
ok 115 userfaultfd_tests all new pages must not be written (dirty)
ok 116 zeropfn_tests all pages must have PFNZERO set
ok 117 zeropfn_tests all huge pages must have PFNZERO set
# Totals: pass:113 fail:4 xfail:0 xpass:0 skip:0 error:0
/proc/$$/numa_maps and /proc/$$/smaps have been tested too, comparing
the outcome with the old API.
[/TESTING]
In the LSFMM/BFP 2025, there was a general agreement that we 1) would like to have
a generic pagewalk API 2) that replaces the existing one with callbacks if possible
and 3) that HugeTLB can use without the need to special case it (e.g: not having to
depend on .hugetlb_entry callbacks)., which means having a lot of duplicated
code and also having a lot of special casing just because hugetlb lore.
pt_range_walk API tries to do that and replaces the old behaviour of "in
HugeTLB world everything reads as a PTE" and starts reading HugeTLB entries
the way they really are, that means interpreting them as PMD/PUD entries and
contiguous-PMD/PTE entries.
In order to achieve that, we need some infrastructure we did not really need until
know, in order to be able to read HugeTLB pages as PUD/PMD entries.
E.g: softleaf_from_pud had to be added and some other pud_* functions.
In a few words, this API goes through an address range and returns
whatever it is in there (swap/hwpoison/migration/marker entries, folios,
pfn and device entries, or nothing).
These are the internal return types the API uses:
PT_TYPE_NONE
PT_TYPE_FOLIO
PT_TYPE_MARKER
PT_TYPE_PFN
PT_TYPE_SWAP
PT_TYPE_MIGRATION
PT_TYPE_DEVICE
PT_TYPE_HWPOISON
The API also handles locking and batching itself, so the caller
does not really need to bother with that.
In order to handle contiguous-PMD mapped hugetlb pages, folio_pmd_batch,
which is an analogous of folio_pte_batch, has been implemented.
More information about the API can be found in patch #4.
This was tested on x86_64 and arm64, but as I said, it is still
incomplete, therefore the RFC, to gather some initial feedback before
investing more time into this.
For now, only the /proc/pid/(smaps|numa_maps|pagemap) have been replaced
to use this new API.
Thanks in advance
Oscar Salvador (7):
mm: Add softleaf_from_pud
mm: Add {pmd,pud}_huge_lock helper
mm: Implement folio_pmd_batch
mm: Implement pt_range_walk
mm: Make /proc/pid/smaps use the new generic pagewalk API
mm: Make /proc/pid/numa_maps use the new generic pagewalk API
mm: Make /proc/pid/pagemap use the new generic pagewalk API
arch/arm64/include/asm/pgtable.h | 32 +
arch/loongarch/include/asm/pgtable.h | 1 +
arch/powerpc/include/asm/book3s/64/pgtable.h | 7 +
arch/s390/include/asm/pgtable.h | 38 +
arch/x86/include/asm/pgtable.h | 52 +
arch/x86/include/asm/pgtable_64.h | 2 +
arch/x86/mm/pgtable.c | 18 +-
fs/proc/task_mmu.c | 2212 +++++++++---------
include/asm-generic/pgtable_uffd.h | 15 +
include/linux/leafops.h | 46 +
include/linux/mm.h | 2 +
include/linux/mm_inline.h | 32 +
include/linux/pagewalk.h | 106 +
include/linux/pgtable.h | 95 +
mm/internal.h | 75 +-
mm/memory.c | 22 +
mm/pagewalk.c | 400 ++++
mm/pgtable-generic.c | 10 +
18 files changed, 2024 insertions(+), 1141 deletions(-)
--
2.35.3
On Sun, Apr 26, 2026 at 02:57:12PM +0200, Oscar Salvador wrote: > Changelog: > rfc -> rfcv2: > - Add pte_hole functionality > - Fix pagemap issues > - Fix shmem in smap > - Testing with pagemap "testsuite" Please, hold on to for the review of this patchset. I have found a few issues while testing cont-pte/cont-pmd on arm64 that I have been fixing and I plan to send a rfcv3 by the end of the week, so we do not go over issues that have been already tackled. -- Oscar Salvador SUSE Labs
On Sun, 26 Apr 2026 14:57:12 +0200 Oscar Salvador <osalvador@suse.de> wrote: > Also, I would like to thank Vlastimil, who helped me running this > patchset quite a few times through Claude, to catch some fixes. Well dang, I wanted to do a Claude-vs-Sashiko cage match, but "Failed to apply". Again :( (https://sashiko.dev/#/patchset/20260426125719.24698-1-osalvador@suse.de). And indeed, there are a couple of little rejects against current -linus. Giving patch(1) the "-l" flag fixes those up, no probs. Roman, perhaps teach Sashiko to try that as a fallback?
syzbot ci has tested the following series
[v2] Implement a new generic pagewalk API
https://lore.kernel.org/all/20260426125719.24698-1-osalvador@suse.de
* [RFC PATCH v2 1/7] mm: Add softleaf_from_pud
* [RFC PATCH v2 2/7] mm: Add {pmd,pud}_huge_lock helper
* [RFC PATCH v2 3/7] mm: Implement folio_pmd_batch
* [RFC PATCH v2 4/7] mm: Implement pt_range_walk
* [RFC PATCH v2 5/7] mm: Make /proc/pid/smaps use the new generic pagewalk API
* [RFC PATCH v2 6/7] mm: Make /proc/pid/numa_maps use the new generic pagewalk API
* [RFC PATCH v2 7/7] mm: Make /proc/pid/pagemap use the new generic pagewalk API
and found the following issues:
* KASAN: slab-out-of-bounds Write in pagemap_read
* WARNING in __page_table_check_pmds_set
* WARNING in pt_range_walk
* WARNING: bad unlock balance in pt_range_walk
Full report is available here:
https://ci.syzbot.org/series/409219de-ca42-45a5-9204-0b315095160c
***
KASAN: slab-out-of-bounds Write in pagemap_read
tree: mm-new
URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/akpm/mm.git
base: 819bd270abf9de3b7f306e233054b85a07c47820
arch: amd64
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
config: https://ci.syzbot.org/builds/0361816f-57b2-43e4-aef2-186d8d35fdc9/config
syz repro: https://ci.syzbot.org/findings/7f740037-7398-46f2-aa01-a57caa186d06/syz_repro
==================================================================
BUG: KASAN: slab-out-of-bounds in add_to_pagemap fs/proc/task_mmu.c:1776 [inline]
BUG: KASAN: slab-out-of-bounds in pagemap_read_walk_range fs/proc/task_mmu.c:2949 [inline]
BUG: KASAN: slab-out-of-bounds in pagemap_read+0x1d60/0x2810 fs/proc/task_mmu.c:3092
Write of size 8 at addr ffff88816f1bd000 by task syz.1.18/5957
CPU: 1 UID: 0 PID: 5957 Comm: syz.1.18 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0xba/0x230 mm/kasan/report.c:482
kasan_report+0x117/0x150 mm/kasan/report.c:595
add_to_pagemap fs/proc/task_mmu.c:1776 [inline]
pagemap_read_walk_range fs/proc/task_mmu.c:2949 [inline]
pagemap_read+0x1d60/0x2810 fs/proc/task_mmu.c:3092
vfs_read+0x20c/0xa70 fs/read_write.c:572
ksys_pread64 fs/read_write.c:765 [inline]
__do_sys_pread64 fs/read_write.c:773 [inline]
__se_sys_pread64 fs/read_write.c:770 [inline]
__x64_sys_pread64+0x199/0x230 fs/read_write.c:770
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f340679cdd9
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f34075d2028 EFLAGS: 00000246 ORIG_RAX: 0000000000000011
RAX: ffffffffffffffda RBX: 00007f3406a15fa0 RCX: 00007f340679cdd9
RDX: 0000000000019020 RSI: 0000200000000200 RDI: 0000000000000003
RBP: 00007f3406832d69 R08: 0000000000000000 R09: 0000000000000000
R10: 0000001000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f3406a16038 R14: 00007f3406a15fa0 R15: 00007ffdb721f7e8
</TASK>
Allocated by task 5957:
kasan_save_stack mm/kasan/common.c:57 [inline]
kasan_save_track+0x3e/0x80 mm/kasan/common.c:78
poison_kmalloc_redzone mm/kasan/common.c:398 [inline]
__kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:415
kasan_kmalloc include/linux/kasan.h:263 [inline]
__kmalloc_cache_noprof+0x31c/0x660 mm/slub.c:5339
kmalloc_noprof include/linux/slab.h:962 [inline]
kmalloc_array_noprof include/linux/slab.h:1109 [inline]
pagemap_read+0x27d/0x2810 fs/proc/task_mmu.c:3033
vfs_read+0x20c/0xa70 fs/read_write.c:572
ksys_pread64 fs/read_write.c:765 [inline]
__do_sys_pread64 fs/read_write.c:773 [inline]
__se_sys_pread64 fs/read_write.c:770 [inline]
__x64_sys_pread64+0x199/0x230 fs/read_write.c:770
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The buggy address belongs to the object at ffff88816f1bc000
which belongs to the cache kmalloc-4k of size 4096
The buggy address is located 0 bytes to the right of
allocated 4096-byte region [ffff88816f1bc000, ffff88816f1bd000)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff88816f1b8000 pfn:0x16f1b8
head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0x57ff00000000240(workingset|head|node=1|zone=2|lastcpupid=0x7ff)
page_type: f5(slab)
raw: 057ff00000000240 ffff888100042140 ffff888160400a08 ffffea0005c6fe10
raw: ffff88816f1b8000 0000000000040003 00000000f5000000 0000000000000000
head: 057ff00000000240 ffff888100042140 ffff888160400a08 ffffea0005c6fe10
head: ffff88816f1b8000 0000000000040003 00000000f5000000 0000000000000000
head: 057ff00000000003 ffffea0005bc6e01 00000000ffffffff 00000000ffffffff
head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd2040(__GFP_IO|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 5715, tgid 5715 (rm), ts 50636400155, free_ts 46909302793
set_page_owner include/linux/page_owner.h:32 [inline]
post_alloc_hook+0x231/0x280 mm/page_alloc.c:1889
prep_new_page mm/page_alloc.c:1897 [inline]
get_page_from_freelist+0x24dc/0x2580 mm/page_alloc.c:3962
__alloc_frozen_pages_noprof+0x18d/0x380 mm/page_alloc.c:5250
alloc_slab_page mm/slub.c:3255 [inline]
allocate_slab+0x77/0x660 mm/slub.c:3444
new_slab mm/slub.c:3502 [inline]
refill_objects+0x331/0x3c0 mm/slub.c:7134
refill_sheaf mm/slub.c:2804 [inline]
__pcs_replace_empty_main+0x2b9/0x620 mm/slub.c:4578
alloc_from_pcs mm/slub.c:4681 [inline]
slab_alloc_node mm/slub.c:4815 [inline]
__do_kmalloc_node mm/slub.c:5218 [inline]
__kmalloc_noprof+0x474/0x760 mm/slub.c:5231
kmalloc_noprof include/linux/slab.h:966 [inline]
tomoyo_realpath_from_path+0xe3/0x5d0 security/tomoyo/realpath.c:251
tomoyo_get_realpath security/tomoyo/file.c:151 [inline]
tomoyo_path_perm+0x283/0x560 security/tomoyo/file.c:827
tomoyo_path_unlink+0xaa/0xf0 security/tomoyo/tomoyo.c:162
security_path_unlink+0x15f/0x330 security/security.c:1457
filename_unlinkat+0x349/0x610 fs/namei.c:5537
__do_sys_unlink fs/namei.c:5575 [inline]
__se_sys_unlink+0x2e/0x140 fs/namei.c:5572
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
page last free pid 5257 tgid 5257 stack trace:
reset_page_owner include/linux/page_owner.h:25 [inline]
__free_pages_prepare mm/page_alloc.c:1433 [inline]
__free_frozen_pages+0xc2b/0xdb0 mm/page_alloc.c:2978
__slab_free+0x263/0x2b0 mm/slub.c:5532
qlink_free mm/kasan/quarantine.c:163 [inline]
qlist_free_all+0x97/0x100 mm/kasan/quarantine.c:179
kasan_quarantine_reduce+0x148/0x160 mm/kasan/quarantine.c:286
__kasan_slab_alloc+0x22/0x80 mm/kasan/common.c:350
kasan_slab_alloc include/linux/kasan.h:253 [inline]
slab_post_alloc_hook mm/slub.c:4501 [inline]
slab_alloc_node mm/slub.c:4830 [inline]
kmem_cache_alloc_noprof+0x2bc/0x650 mm/slub.c:4837
alloc_filename fs/namei.c:142 [inline]
do_getname+0x2e/0x250 fs/namei.c:182
getname_flags fs/namei.c:225 [inline]
getname include/linux/fs.h:2512 [inline]
class_filename_constructor include/linux/fs.h:2539 [inline]
__do_sys_unlink fs/namei.c:5574 [inline]
__se_sys_unlink+0x1e/0x140 fs/namei.c:5572
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Memory state around the buggy address:
ffff88816f1bcf00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff88816f1bcf80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffff88816f1bd000: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
^
ffff88816f1bd080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff88816f1bd100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==================================================================
***
WARNING in __page_table_check_pmds_set
tree: mm-new
URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/akpm/mm.git
base: 819bd270abf9de3b7f306e233054b85a07c47820
arch: amd64
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
config: https://ci.syzbot.org/builds/0361816f-57b2-43e4-aef2-186d8d35fdc9/config
syz repro: https://ci.syzbot.org/findings/f8fe52b4-cef7-4d25-8e60-cbbb1a4f4df5/syz_repro
------------[ cut here ]------------
softleaf_cached_writable(entry)
WARNING: mm/page_table_check.c:227 at page_table_check_pmd_flags mm/page_table_check.c:227 [inline], CPU#1: syz.0.17/6022
WARNING: mm/page_table_check.c:227 at __page_table_check_pmds_set+0x18e/0x340 mm/page_table_check.c:240, CPU#1: syz.0.17/6022
Modules linked in:
CPU: 1 UID: 0 PID: 6022 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
RIP: 0010:page_table_check_pmd_flags mm/page_table_check.c:227 [inline]
RIP: 0010:__page_table_check_pmds_set+0x18e/0x340 mm/page_table_check.c:240
Code: 89 fe e8 85 44 89 ff 48 b8 00 00 00 00 00 00 00 94 4c 01 f8 48 c1 e8 3b 0f 94 c0 4d 39 e5 76 0f 84 c0 74 0b e8 83 3f 89 ff 90 <0f> 0b 90 eb 05 e8 78 3f 89 ff 31 ff 89 ee e8 af 43 89 ff 41 89 ef
RSP: 0018:ffffc90003ce7af8 EFLAGS: 00010293
RAX: ffffffff823c4d7d RBX: ffff888111416001 RCX: ffff88816cbd1d00
RDX: 0000000000000000 RSI: 6c00000000000000 RDI: 6c00000000000000
RBP: 0000000000000001 R08: 0000000000000001 R09: 0000000000000003
R10: 0000000000000002 R11: 0000000000000000 R12: c7fffffffffffffe
R13: dfffffffdc9bfe06 R14: ffff888111416008 R15: 6c00000000000000
FS: 00007ff0386af6c0(0000) GS:ffff8882a9466000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000555574a1a9e8 CR3: 00000001063c6000 CR4: 00000000000006f0
Call Trace:
<TASK>
page_table_check_pmds_set include/linux/page_table_check.h:92 [inline]
set_pmd_at arch/x86/include/asm/pgtable.h:1234 [inline]
make_uffd_wp_pmd fs/proc/task_mmu.c:1903 [inline]
pagemap_scan_walk fs/proc/task_mmu.c:2631 [inline]
do_pagemap_scan fs/proc/task_mmu.c:2785 [inline]
do_pagemap_cmd+0x3bd8/0x4310 fs/proc/task_mmu.c:3131
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7ff03779cdd9
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ff0386af028 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007ff037a16090 RCX: 00007ff03779cdd9
RDX: 00002000000001c0 RSI: 00000000c0606610 RDI: 0000000000000003
RBP: 00007ff037832d69 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007ff037a16128 R14: 00007ff037a16090 R15: 00007ffd47ec5488
</TASK>
***
WARNING in pt_range_walk
tree: mm-new
URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/akpm/mm.git
base: 819bd270abf9de3b7f306e233054b85a07c47820
arch: amd64
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
config: https://ci.syzbot.org/builds/0361816f-57b2-43e4-aef2-186d8d35fdc9/config
syz repro: https://ci.syzbot.org/findings/02bfe437-a81f-4510-9fff-4b769eb9a0a4/syz_repro
------------[ cut here ]------------
next_addr < vma->vm_start || next_addr >= vma->vm_end
WARNING: mm/pagewalk.c:1052 at pt_range_walk+0x14e/0x35a0 mm/pagewalk.c:1052, CPU#1: syz.2.19/6013
Modules linked in:
CPU: 1 UID: 0 PID: 6013 Comm: syz.2.19 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
RIP: 0010:pt_range_walk+0x14e/0x35a0 mm/pagewalk.c:1052
Code: 74 08 48 89 df e8 12 1a 15 00 49 89 de 48 8b 1b 48 8b 7c 24 10 48 89 de e8 6f a5 aa ff 48 39 5c 24 10 73 13 e8 03 a3 aa ff 90 <0f> 0b 90 b8 01 00 00 00 e9 88 2b 00 00 49 8d 5e 08 48 89 d8 48 c1
RSP: 0018:ffffc90003d37920 EFLAGS: 00010293
RAX: ffffffff821b11f0 RBX: 0000200000800000 RCX: ffff8881134f5700
RDX: 0000000000000000 RSI: 0000200000800000 RDI: 0000200000800000
RBP: ffffc90003d37b30 R08: 00000000000000ff R09: 1ffff1102dc8b830
R10: dffffc0000000000 R11: ffffed102dc8b831 R12: ffff8881709b1800
R13: dffffc0000000000 R14: ffff8881709b1800 R15: 0000200000800000
FS: 00007f33141ff6c0(0000) GS:ffff8882a9466000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f331344f0d1 CR3: 000000017150e000 CR4: 00000000000006f0
Call Trace:
<TASK>
pagemap_scan_walk fs/proc/task_mmu.c:2463 [inline]
do_pagemap_scan fs/proc/task_mmu.c:2785 [inline]
do_pagemap_cmd+0x3924/0x4310 fs/proc/task_mmu.c:3131
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f331339cdd9
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f33141ff028 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007f3313615fa0 RCX: 00007f331339cdd9
RDX: 0000200000000140 RSI: 00000000c0606610 RDI: 0000000000000003
RBP: 00007f3313432d69 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f3313616038 R14: 00007f3313615fa0 R15: 00007fff980e14d8
</TASK>
***
WARNING: bad unlock balance in pt_range_walk
tree: mm-new
URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/akpm/mm.git
base: 819bd270abf9de3b7f306e233054b85a07c47820
arch: amd64
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
config: https://ci.syzbot.org/builds/0361816f-57b2-43e4-aef2-186d8d35fdc9/config
syz repro: https://ci.syzbot.org/findings/1e53935d-6673-468b-905d-88da8f1e39f3/syz_repro
loop1: detected capacity change from 0 to 4096
=====================================
WARNING: bad unlock balance detected!
syzkaller #0 Not tainted
-------------------------------------
syz.1.18/5968 is trying to release lock (ptlock_ptr(ptdesc)) at:
[<ffffffff821aeb0a>] spin_unlock include/linux/spinlock.h:389 [inline]
[<ffffffff821aeb0a>] pt_range_walk+0x25a/0x35a0 mm/pagewalk.c:1058
but there are no more locks to release!
other info that might help us debug this:
1 lock held by syz.1.18/5968:
#0: ffff8881626b0340 (&mm->mmap_lock){++++}-{4:4}, at: mmap_read_lock_killable include/linux/mmap_lock.h:601 [inline]
#0: ffff8881626b0340 (&mm->mmap_lock){++++}-{4:4}, at: do_pagemap_scan fs/proc/task_mmu.c:2746 [inline]
#0: ffff8881626b0340 (&mm->mmap_lock){++++}-{4:4}, at: do_pagemap_cmd+0x618/0x4310 fs/proc/task_mmu.c:3131
stack backtrace:
CPU: 1 UID: 0 PID: 5968 Comm: syz.1.18 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
print_unlock_imbalance_bug+0xdc/0xf0 kernel/locking/lockdep.c:5298
__lock_release kernel/locking/lockdep.c:5537 [inline]
lock_release+0x248/0x3d0 kernel/locking/lockdep.c:5889
__raw_spin_unlock include/linux/spinlock_api_smp.h:167 [inline]
_raw_spin_unlock+0x16/0x50 kernel/locking/spinlock.c:186
spin_unlock include/linux/spinlock.h:389 [inline]
pt_range_walk+0x25a/0x35a0 mm/pagewalk.c:1058
pagemap_scan_walk fs/proc/task_mmu.c:2463 [inline]
do_pagemap_scan fs/proc/task_mmu.c:2785 [inline]
do_pagemap_cmd+0x3924/0x4310 fs/proc/task_mmu.c:3131
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f0ce439cdd9
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f0ce5214028 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007f0ce4615fa0 RCX: 00007f0ce439cdd9
RDX: 0000200000000140 RSI: 00000000c0606610 RDI: 0000000000000004
RBP: 00007f0ce4432d69 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f0ce4616038 R14: 00007f0ce4615fa0 R15: 00007fffbeb73768
</TASK>
***
If these findings have caused you to resend the series or submit a
separate fix, please add the following tag to your commit message:
Tested-by: syzbot@syzkaller.appspotmail.com
---
This report is generated by a bot. It may contain errors.
syzbot ci engineers can be reached at syzkaller@googlegroups.com.
To test a patch for this bug, please reply with `#syz test`
(should be on a separate line).
The patch should be attached to the email.
Note: arguments like custom git repos and branches are not supported.
© 2016 - 2026 Red Hat, Inc.