PAGEMAP_SCAN already reports PAGE_IS_WRITTEN from the inverted uffd PTE bit, targeting the UFFDIO_WRITEPROTECT workflow. UFFDIO_RWPROTECT reuses the same PTE bit as a marker for read-write protection, but "has been written" and "has been accessed" are distinct semantic signals — they happen to share one PTE bit today only because the two implementations share infrastructure. Give RWP its own pagemap category so the UAPI does not conflate them: PAGE_IS_WRITTEN reported on VM_UFFD_WP VMAs, !pte_uffd(pte) PAGE_IS_ACCESSED reported on VM_UFFD_RWP VMAs, !pte_uffd(pte) Both still read the same PTE bit today, but each is scoped to the VMA whose registered mode makes the bit meaningful. If a future implementation moves RWP to a separate PTE bit, only PAGE_IS_ACCESSED switches over. This is a UAPI narrowing. Outside VM_UFFD_WP VMAs the uffd bit is always clear, so PAGEMAP_SCAN used to flag PAGE_IS_WRITTEN on every present PTE there — a meaningless duplicate of PAGE_IS_PRESENT. Now PAGE_IS_WRITTEN fires only inside VM_UFFD_WP VMAs. pagemap_hugetlb_category() now takes the vma like its PTE/PMD peers.
Showing the changes to Documentation/admin-guide (1 of 4 files). Show all
Unified · Split
| @@ -19,8 +19,11 @@ There are four components to pagemap: · 18 unmodified lines | |||
| 19 | * Bit 55 pte is soft-dirty (see | 19 | * Bit 55 pte is soft-dirty (see |
| 20 | Documentation/admin-guide/mm/soft-dirty.rst) | 20 | Documentation/admin-guide/mm/soft-dirty.rst) |
| 21 | * Bit 56 page exclusively mapped (since 4.2) | 21 | * Bit 56 page exclusively mapped (since 4.2) |
| 22 | * Bit 57 pte is uffd-wp write-protected (since 5.13) (see | 22 | * Bit 57 pte is tracked by userfaultfd (since 5.13) — in a |
| 23 | Documentation/admin-guide/mm/userfaultfd.rst) | 23 | ``VM_UFFD_WP`` VMA this indicates a write-protected PTE; in a |
| 24 | ``VM_UFFD_RWP`` VMA it indicates an RWP-protected PTE. WP and | ||
| 25 | RWP are mutually exclusive per VMA, so the meaning is | ||
| 26 | unambiguous. See Documentation/admin-guide/mm/userfaultfd.rst. | ||
| 24 | * Bit 58 pte is a guard region (since 6.15) (see madvise (2) man page) | 27 | * Bit 58 pte is a guard region (since 6.15) (see madvise (2) man page) |
| 25 | * Bits 59-60 zero | 28 | * Bits 59-60 zero |
| 26 | * Bit 61 page is file-page or shared-anon (since 3.5) | 29 | * Bit 61 page is file-page or shared-anon (since 3.5) |
| @@ -244,7 +247,8 @@ in this IOCTL: · 217 unmodified lines | |||
| 244 | Following flags about pages are currently supported: | 247 | Following flags about pages are currently supported: |
| 245 | 248 | ||
| 246 | - ``PAGE_IS_WPALLOWED`` - Page has async-write-protection enabled | 249 | - ``PAGE_IS_WPALLOWED`` - Page has async-write-protection enabled |
| 247 | - ``PAGE_IS_WRITTEN`` - Page has been written to from the time it was write protected | 250 | - ``PAGE_IS_WRITTEN`` - Page in a ``UFFDIO_REGISTER_MODE_WP`` VMA has been |
| 251 | written to since it was write-protected. Only reported inside such VMAs. | ||
| 248 | - ``PAGE_IS_FILE`` - Page is file backed | 252 | - ``PAGE_IS_FILE`` - Page is file backed |
| 249 | - ``PAGE_IS_PRESENT`` - Page is present in the memory | 253 | - ``PAGE_IS_PRESENT`` - Page is present in the memory |
| 250 | - ``PAGE_IS_SWAPPED`` - Page is in swapped | 254 | - ``PAGE_IS_SWAPPED`` - Page is in swapped |
| @@ -252,6 +256,9 @@ Following flags about pages are currently supported: · 1 unmodified line | |||
| 252 | - ``PAGE_IS_HUGE`` - Page is PMD-mapped THP or Hugetlb backed | 256 | - ``PAGE_IS_HUGE`` - Page is PMD-mapped THP or Hugetlb backed |
| 253 | - ``PAGE_IS_SOFT_DIRTY`` - Page is soft-dirty | 257 | - ``PAGE_IS_SOFT_DIRTY`` - Page is soft-dirty |
| 254 | - ``PAGE_IS_GUARD`` - Page is a part of a guard region | 258 | - ``PAGE_IS_GUARD`` - Page is a part of a guard region |
| 259 | - ``PAGE_IS_ACCESSED`` - Page in a ``UFFDIO_REGISTER_MODE_RWP`` VMA has been | ||
| 260 | accessed since RWP was applied. Only reported inside such VMAs. See | ||
| 261 | Documentation/admin-guide/mm/userfaultfd.rst for the RWP workflow. | ||
| 255 | 262 | ||
| 256 | The ``struct pm_scan_arg`` is used as the argument of the IOCTL. | 263 | The ``struct pm_scan_arg`` is used as the argument of the IOCTL. |
| 257 | 264 | ||