11ad1335dSMike Rapoport=============================
21ad1335dSMike RapoportExamining Process Page Tables
31ad1335dSMike Rapoport=============================
41ad1335dSMike Rapoport
51ad1335dSMike Rapoportpagemap is a new (as of 2.6.25) set of interfaces in the kernel that allow
61ad1335dSMike Rapoportuserspace programs to examine the page tables and related information by
71ad1335dSMike Rapoportreading files in ``/proc``.
81ad1335dSMike Rapoport
91ad1335dSMike RapoportThere are four components to pagemap:
101ad1335dSMike Rapoport
111ad1335dSMike Rapoport * ``/proc/pid/pagemap``.  This file lets a userspace process find out which
121ad1335dSMike Rapoport   physical frame each virtual page is mapped to.  It contains one 64-bit
131ad1335dSMike Rapoport   value for each virtual page, containing the following data (from
141ad1335dSMike Rapoport   ``fs/proc/task_mmu.c``, above pagemap_read):
151ad1335dSMike Rapoport
161ad1335dSMike Rapoport    * Bits 0-54  page frame number (PFN) if present
171ad1335dSMike Rapoport    * Bits 0-4   swap type if swapped
181ad1335dSMike Rapoport    * Bits 5-54  swap offset if swapped
19e27a20f1SMike Rapoport    * Bit  55    pte is soft-dirty (see
2000cba6b6SMike Rapoport (IBM)      Documentation/admin-guide/mm/soft-dirty.rst)
211ad1335dSMike Rapoport    * Bit  56    page exclusively mapped (since 4.2)
22fb8e37f3SPeter Xu    * Bit  57    pte is uffd-wp write-protected (since 5.13) (see
2300cba6b6SMike Rapoport (IBM)      Documentation/admin-guide/mm/userfaultfd.rst)
24dd21bfa4SYun Zhou    * Bits 58-60 zero
251ad1335dSMike Rapoport    * Bit  61    page is file-page or shared-anon (since 3.5)
261ad1335dSMike Rapoport    * Bit  62    page swapped
271ad1335dSMike Rapoport    * Bit  63    page present
281ad1335dSMike Rapoport
291ad1335dSMike Rapoport   Since Linux 4.0 only users with the CAP_SYS_ADMIN capability can get PFNs.
301ad1335dSMike Rapoport   In 4.0 and 4.1 opens by unprivileged fail with -EPERM.  Starting from
311ad1335dSMike Rapoport   4.2 the PFN field is zeroed if the user does not have CAP_SYS_ADMIN.
321ad1335dSMike Rapoport   Reason: information about PFNs helps in exploiting Rowhammer vulnerability.
331ad1335dSMike Rapoport
341ad1335dSMike Rapoport   If the page is not present but in swap, then the PFN contains an
351ad1335dSMike Rapoport   encoding of the swap file number and the page's offset into the
361ad1335dSMike Rapoport   swap. Unmapped pages return a null PFN. This allows determining
371ad1335dSMike Rapoport   precisely which pages are mapped (or in swap) and comparing mapped
381ad1335dSMike Rapoport   pages between processes.
391ad1335dSMike Rapoport
401ad1335dSMike Rapoport   Efficient users of this interface will use ``/proc/pid/maps`` to
411ad1335dSMike Rapoport   determine which areas of memory are actually mapped and llseek to
421ad1335dSMike Rapoport   skip over unmapped regions.
431ad1335dSMike Rapoport
441ad1335dSMike Rapoport * ``/proc/kpagecount``.  This file contains a 64-bit count of the number of
451ad1335dSMike Rapoport   times each page is mapped, indexed by PFN.
461ad1335dSMike Rapoport
47799fb82aSSeongJae ParkThe page-types tool in the tools/mm directory can be used to query the
487f1d23e6SChristian Hansennumber of times a page is mapped.
497f1d23e6SChristian Hansen
501ad1335dSMike Rapoport * ``/proc/kpageflags``.  This file contains a 64-bit set of flags for each
511ad1335dSMike Rapoport   page, indexed by PFN.
521ad1335dSMike Rapoport
531ad1335dSMike Rapoport   The flags are (from ``fs/proc/page.c``, above kpageflags_read):
541ad1335dSMike Rapoport
551ad1335dSMike Rapoport    0. LOCKED
561ad1335dSMike Rapoport    1. ERROR
571ad1335dSMike Rapoport    2. REFERENCED
581ad1335dSMike Rapoport    3. UPTODATE
591ad1335dSMike Rapoport    4. DIRTY
601ad1335dSMike Rapoport    5. LRU
611ad1335dSMike Rapoport    6. ACTIVE
621ad1335dSMike Rapoport    7. SLAB
631ad1335dSMike Rapoport    8. WRITEBACK
641ad1335dSMike Rapoport    9. RECLAIM
651ad1335dSMike Rapoport    10. BUDDY
661ad1335dSMike Rapoport    11. MMAP
671ad1335dSMike Rapoport    12. ANON
681ad1335dSMike Rapoport    13. SWAPCACHE
691ad1335dSMike Rapoport    14. SWAPBACKED
701ad1335dSMike Rapoport    15. COMPOUND_HEAD
711ad1335dSMike Rapoport    16. COMPOUND_TAIL
721ad1335dSMike Rapoport    17. HUGE
731ad1335dSMike Rapoport    18. UNEVICTABLE
741ad1335dSMike Rapoport    19. HWPOISON
751ad1335dSMike Rapoport    20. NOPAGE
761ad1335dSMike Rapoport    21. KSM
771ad1335dSMike Rapoport    22. THP
78ca215086SDavid Hildenbrand    23. OFFLINE
791ad1335dSMike Rapoport    24. ZERO_PAGE
801ad1335dSMike Rapoport    25. IDLE
81ca215086SDavid Hildenbrand    26. PGTABLE
821ad1335dSMike Rapoport
831ad1335dSMike Rapoport * ``/proc/kpagecgroup``.  This file contains a 64-bit inode number of the
841ad1335dSMike Rapoport   memory cgroup each page is charged to, indexed by PFN. Only available when
851ad1335dSMike Rapoport   CONFIG_MEMCG is set.
861ad1335dSMike Rapoport
871ad1335dSMike RapoportShort descriptions to the page flags
881ad1335dSMike Rapoport====================================
891ad1335dSMike Rapoport
901ad1335dSMike Rapoport0 - LOCKED
910d16cfd4SSeongJae Park   The page is being locked for exclusive access, e.g. by undergoing read/write
920d16cfd4SSeongJae Park   IO.
931ad1335dSMike Rapoport7 - SLAB
94d88e2a2bSVlastimil Babka   The page is managed by the SLAB/SLUB kernel memory allocator.
95d88e2a2bSVlastimil Babka   When compound page is used, either will only set this flag on the head
96d88e2a2bSVlastimil Babka   page.
971ad1335dSMike Rapoport10 - BUDDY
980d16cfd4SSeongJae Park    A free memory block managed by the buddy system allocator.
991ad1335dSMike Rapoport    The buddy system organizes free memory in blocks of various orders.
1001ad1335dSMike Rapoport    An order N block has 2^N physically contiguous pages, with the BUDDY flag
1011ad1335dSMike Rapoport    set for and _only_ for the first page.
1021ad1335dSMike Rapoport15 - COMPOUND_HEAD
1031ad1335dSMike Rapoport    A compound page with order N consists of 2^N physically contiguous pages.
1041ad1335dSMike Rapoport    A compound page with order 2 takes the form of "HTTT", where H donates its
1051ad1335dSMike Rapoport    head page and T donates its tail page(s).  The major consumers of compound
10600cba6b6SMike Rapoport (IBM)    pages are hugeTLB pages (Documentation/admin-guide/mm/hugetlbpage.rst),
107e27a20f1SMike Rapoport    the SLUB etc.  memory allocators and various device drivers.
108e27a20f1SMike Rapoport    However in this interface, only huge/giga pages are made visible
109e27a20f1SMike Rapoport    to end users.
1101ad1335dSMike Rapoport16 - COMPOUND_TAIL
1111ad1335dSMike Rapoport    A compound page tail (see description above).
1121ad1335dSMike Rapoport17 - HUGE
1130d16cfd4SSeongJae Park    This is an integral part of a HugeTLB page.
1141ad1335dSMike Rapoport19 - HWPOISON
1150d16cfd4SSeongJae Park    Hardware detected memory corruption on this page: don't touch the data!
1161ad1335dSMike Rapoport20 - NOPAGE
1170d16cfd4SSeongJae Park    No page frame exists at the requested address.
1181ad1335dSMike Rapoport21 - KSM
1190d16cfd4SSeongJae Park    Identical memory pages dynamically shared between one or more processes.
1201ad1335dSMike Rapoport22 - THP
1210d16cfd4SSeongJae Park    Contiguous pages which construct transparent hugepages.
122ca215086SDavid Hildenbrand23 - OFFLINE
1230d16cfd4SSeongJae Park    The page is logically offline.
1241ad1335dSMike Rapoport24 - ZERO_PAGE
1250d16cfd4SSeongJae Park    Zero page for pfn_zero or huge_zero page.
1261ad1335dSMike Rapoport25 - IDLE
1270d16cfd4SSeongJae Park    The page has not been accessed since it was marked idle (see
12800cba6b6SMike Rapoport (IBM)    Documentation/admin-guide/mm/idle_page_tracking.rst).
129e27a20f1SMike Rapoport    Note that this flag may be stale in case the page was accessed via
130e27a20f1SMike Rapoport    a PTE. To make sure the flag is up-to-date one has to read
131e27a20f1SMike Rapoport    ``/sys/kernel/mm/page_idle/bitmap`` first.
132ca215086SDavid Hildenbrand26 - PGTABLE
1330d16cfd4SSeongJae Park    The page is in use as a page table.
1341ad1335dSMike Rapoport
1351ad1335dSMike RapoportIO related page flags
1361ad1335dSMike Rapoport---------------------
1371ad1335dSMike Rapoport
1381ad1335dSMike Rapoport1 - ERROR
1390d16cfd4SSeongJae Park   IO error occurred.
1401ad1335dSMike Rapoport3 - UPTODATE
1410d16cfd4SSeongJae Park   The page has up-to-date data.
1421ad1335dSMike Rapoport   ie. for file backed page: (in-memory data revision >= on-disk one)
1431ad1335dSMike Rapoport4 - DIRTY
1440d16cfd4SSeongJae Park   The page has been written to, hence contains new data.
1451ad1335dSMike Rapoport   i.e. for file backed page: (in-memory data revision >  on-disk one)
1461ad1335dSMike Rapoport8 - WRITEBACK
1470d16cfd4SSeongJae Park   The page is being synced to disk.
1481ad1335dSMike Rapoport
1491ad1335dSMike RapoportLRU related page flags
1501ad1335dSMike Rapoport----------------------
1511ad1335dSMike Rapoport
1521ad1335dSMike Rapoport5 - LRU
1530d16cfd4SSeongJae Park   The page is in one of the LRU lists.
1541ad1335dSMike Rapoport6 - ACTIVE
1550d16cfd4SSeongJae Park   The page is in the active LRU list.
1561ad1335dSMike Rapoport18 - UNEVICTABLE
1570d16cfd4SSeongJae Park   The page is in the unevictable (non-)LRU list It is somehow pinned and
1581ad1335dSMike Rapoport   not a candidate for LRU page reclaims, e.g. ramfs pages,
1590d16cfd4SSeongJae Park   shmctl(SHM_LOCK) and mlock() memory segments.
1601ad1335dSMike Rapoport2 - REFERENCED
1610d16cfd4SSeongJae Park   The page has been referenced since last LRU list enqueue/requeue.
1621ad1335dSMike Rapoport9 - RECLAIM
1630d16cfd4SSeongJae Park   The page will be reclaimed soon after its pageout IO completed.
1641ad1335dSMike Rapoport11 - MMAP
1650d16cfd4SSeongJae Park   A memory mapped page.
1661ad1335dSMike Rapoport12 - ANON
1670d16cfd4SSeongJae Park   A memory mapped page that is not part of a file.
1681ad1335dSMike Rapoport13 - SWAPCACHE
1690d16cfd4SSeongJae Park   The page is mapped to swap space, i.e. has an associated swap entry.
1701ad1335dSMike Rapoport14 - SWAPBACKED
1710d16cfd4SSeongJae Park   The page is backed by swap/RAM.
1721ad1335dSMike Rapoport
173799fb82aSSeongJae ParkThe page-types tool in the tools/mm directory can be used to query the
1741ad1335dSMike Rapoportabove flags.
1751ad1335dSMike Rapoport
1761ad1335dSMike RapoportUsing pagemap to do something useful
1771ad1335dSMike Rapoport====================================
1781ad1335dSMike Rapoport
1791ad1335dSMike RapoportThe general procedure for using pagemap to find out about a process' memory
1801ad1335dSMike Rapoportusage goes like this:
1811ad1335dSMike Rapoport
1821ad1335dSMike Rapoport 1. Read ``/proc/pid/maps`` to determine which parts of the memory space are
1831ad1335dSMike Rapoport    mapped to what.
1841ad1335dSMike Rapoport 2. Select the maps you are interested in -- all of them, or a particular
1851ad1335dSMike Rapoport    library, or the stack or the heap, etc.
1861ad1335dSMike Rapoport 3. Open ``/proc/pid/pagemap`` and seek to the pages you would like to examine.
1871ad1335dSMike Rapoport 4. Read a u64 for each page from pagemap.
1881ad1335dSMike Rapoport 5. Open ``/proc/kpagecount`` and/or ``/proc/kpageflags``.  For each PFN you
1891ad1335dSMike Rapoport    just read, seek to that entry in the file, and read the data you want.
1901ad1335dSMike Rapoport
1911ad1335dSMike RapoportFor example, to find the "unique set size" (USS), which is the amount of
1921ad1335dSMike Rapoportmemory that a process is using that is not shared with any other process,
1931ad1335dSMike Rapoportyou can go through every map in the process, find the PFNs, look those up
1941ad1335dSMike Rapoportin kpagecount, and tally up the number of pages that are only referenced
1951ad1335dSMike Rapoportonce.
1961ad1335dSMike Rapoport
197cbbb69d3STiberiu A GeorgescuExceptions for Shared Memory
198cbbb69d3STiberiu A Georgescu============================
199cbbb69d3STiberiu A Georgescu
200cbbb69d3STiberiu A GeorgescuPage table entries for shared pages are cleared when the pages are zapped or
201cbbb69d3STiberiu A Georgescuswapped out. This makes swapped out pages indistinguishable from never-allocated
202cbbb69d3STiberiu A Georgescuones.
203cbbb69d3STiberiu A Georgescu
204cbbb69d3STiberiu A GeorgescuIn kernel space, the swap location can still be retrieved from the page cache.
205cbbb69d3STiberiu A GeorgescuHowever, values stored only on the normal PTE get lost irretrievably when the
206cbbb69d3STiberiu A Georgescupage is swapped out (i.e. SOFT_DIRTY).
207cbbb69d3STiberiu A Georgescu
208cbbb69d3STiberiu A GeorgescuIn user space, whether the page is present, swapped or none can be deduced with
209cbbb69d3STiberiu A Georgescuthe help of lseek and/or mincore system calls.
210cbbb69d3STiberiu A Georgescu
211cbbb69d3STiberiu A Georgesculseek() can differentiate between accessed pages (present or swapped out) and
212cbbb69d3STiberiu A Georgescuholes (none/non-allocated) by specifying the SEEK_DATA flag on the file where
213cbbb69d3STiberiu A Georgescuthe pages are backed. For anonymous shared pages, the file can be found in
214cbbb69d3STiberiu A Georgescu``/proc/pid/map_files/``.
215cbbb69d3STiberiu A Georgescu
216cbbb69d3STiberiu A Georgescumincore() can differentiate between pages in memory (present, including swap
217cbbb69d3STiberiu A Georgescucache) and out of memory (swapped out or none/non-allocated).
218cbbb69d3STiberiu A Georgescu
2191ad1335dSMike RapoportOther notes
2201ad1335dSMike Rapoport===========
2211ad1335dSMike Rapoport
2221ad1335dSMike RapoportReading from any of the files will return -EINVAL if you are not starting
2231ad1335dSMike Rapoportthe read on an 8-byte boundary (e.g., if you sought an odd number of bytes
2241ad1335dSMike Rapoportinto the file), or if the size of the read is not a multiple of 8 bytes.
2251ad1335dSMike Rapoport
2261ad1335dSMike RapoportBefore Linux 3.11 pagemap bits 55-60 were used for "page-shift" (which is
2271ad1335dSMike Rapoportalways 12 at most architectures). Since Linux 3.11 their meaning changes
2281ad1335dSMike Rapoportafter first clear of soft-dirty bits. Since Linux 4.2 they are used for
2291ad1335dSMike Rapoportflags unconditionally.
23018825b8aSMuhammad Usama Anjum
23118825b8aSMuhammad Usama AnjumPagemap Scan IOCTL
23218825b8aSMuhammad Usama Anjum==================
23318825b8aSMuhammad Usama Anjum
23418825b8aSMuhammad Usama AnjumThe ``PAGEMAP_SCAN`` IOCTL on the pagemap file can be used to get or optionally
23518825b8aSMuhammad Usama Anjumclear the info about page table entries. The following operations are supported
23618825b8aSMuhammad Usama Anjumin this IOCTL:
23718825b8aSMuhammad Usama Anjum
23818825b8aSMuhammad Usama Anjum- Scan the address range and get the memory ranges matching the provided criteria.
23918825b8aSMuhammad Usama Anjum  This is performed when the output buffer is specified.
24018825b8aSMuhammad Usama Anjum- Write-protect the pages. The ``PM_SCAN_WP_MATCHING`` is used to write-protect
24118825b8aSMuhammad Usama Anjum  the pages of interest. The ``PM_SCAN_CHECK_WPASYNC`` aborts the operation if
24218825b8aSMuhammad Usama Anjum  non-Async Write Protected pages are found. The ``PM_SCAN_WP_MATCHING`` can be
24318825b8aSMuhammad Usama Anjum  used with or without ``PM_SCAN_CHECK_WPASYNC``.
24418825b8aSMuhammad Usama Anjum- Both of those operations can be combined into one atomic operation where we can
24518825b8aSMuhammad Usama Anjum  get and write protect the pages as well.
24618825b8aSMuhammad Usama Anjum
24718825b8aSMuhammad Usama AnjumFollowing flags about pages are currently supported:
24818825b8aSMuhammad Usama Anjum
24918825b8aSMuhammad Usama Anjum- ``PAGE_IS_WPALLOWED`` - Page has async-write-protection enabled
25018825b8aSMuhammad Usama Anjum- ``PAGE_IS_WRITTEN`` - Page has been written to from the time it was write protected
25118825b8aSMuhammad Usama Anjum- ``PAGE_IS_FILE`` - Page is file backed
25218825b8aSMuhammad Usama Anjum- ``PAGE_IS_PRESENT`` - Page is present in the memory
25318825b8aSMuhammad Usama Anjum- ``PAGE_IS_SWAPPED`` - Page is in swapped
25418825b8aSMuhammad Usama Anjum- ``PAGE_IS_PFNZERO`` - Page has zero PFN
25518825b8aSMuhammad Usama Anjum- ``PAGE_IS_HUGE`` - Page is THP or Hugetlb backed
256*e6a9a2cbSAndrei Vagin- ``PAGE_IS_SOFT_DIRTY`` - Page is soft-dirty
25718825b8aSMuhammad Usama Anjum
25818825b8aSMuhammad Usama AnjumThe ``struct pm_scan_arg`` is used as the argument of the IOCTL.
25918825b8aSMuhammad Usama Anjum
26018825b8aSMuhammad Usama Anjum 1. The size of the ``struct pm_scan_arg`` must be specified in the ``size``
26118825b8aSMuhammad Usama Anjum    field. This field will be helpful in recognizing the structure if extensions
26218825b8aSMuhammad Usama Anjum    are done later.
26318825b8aSMuhammad Usama Anjum 2. The flags can be specified in the ``flags`` field. The ``PM_SCAN_WP_MATCHING``
26418825b8aSMuhammad Usama Anjum    and ``PM_SCAN_CHECK_WPASYNC`` are the only added flags at this time. The get
26518825b8aSMuhammad Usama Anjum    operation is optionally performed depending upon if the output buffer is
26618825b8aSMuhammad Usama Anjum    provided or not.
26718825b8aSMuhammad Usama Anjum 3. The range is specified through ``start`` and ``end``.
26818825b8aSMuhammad Usama Anjum 4. The walk can abort before visiting the complete range such as the user buffer
26918825b8aSMuhammad Usama Anjum    can get full etc. The walk ending address is specified in``end_walk``.
27018825b8aSMuhammad Usama Anjum 5. The output buffer of ``struct page_region`` array and size is specified in
27118825b8aSMuhammad Usama Anjum    ``vec`` and ``vec_len``.
27218825b8aSMuhammad Usama Anjum 6. The optional maximum requested pages are specified in the ``max_pages``.
27318825b8aSMuhammad Usama Anjum 7. The masks are specified in ``category_mask``, ``category_anyof_mask``,
27418825b8aSMuhammad Usama Anjum    ``category_inverted`` and ``return_mask``.
27518825b8aSMuhammad Usama Anjum
27618825b8aSMuhammad Usama AnjumFind pages which have been written and WP them as well::
27718825b8aSMuhammad Usama Anjum
27818825b8aSMuhammad Usama Anjum   struct pm_scan_arg arg = {
27918825b8aSMuhammad Usama Anjum   .size = sizeof(arg),
28018825b8aSMuhammad Usama Anjum   .flags = PM_SCAN_CHECK_WPASYNC | PM_SCAN_CHECK_WPASYNC,
28118825b8aSMuhammad Usama Anjum   ..
28218825b8aSMuhammad Usama Anjum   .category_mask = PAGE_IS_WRITTEN,
28318825b8aSMuhammad Usama Anjum   .return_mask = PAGE_IS_WRITTEN,
28418825b8aSMuhammad Usama Anjum   };
28518825b8aSMuhammad Usama Anjum
28618825b8aSMuhammad Usama AnjumFind pages which have been written, are file backed, not swapped and either
28718825b8aSMuhammad Usama Anjumpresent or huge::
28818825b8aSMuhammad Usama Anjum
28918825b8aSMuhammad Usama Anjum   struct pm_scan_arg arg = {
29018825b8aSMuhammad Usama Anjum   .size = sizeof(arg),
29118825b8aSMuhammad Usama Anjum   .flags = 0,
29218825b8aSMuhammad Usama Anjum   ..
29318825b8aSMuhammad Usama Anjum   .category_mask = PAGE_IS_WRITTEN | PAGE_IS_SWAPPED,
29418825b8aSMuhammad Usama Anjum   .category_inverted = PAGE_IS_SWAPPED,
29518825b8aSMuhammad Usama Anjum   .category_anyof_mask = PAGE_IS_PRESENT | PAGE_IS_HUGE,
29618825b8aSMuhammad Usama Anjum   .return_mask = PAGE_IS_WRITTEN | PAGE_IS_SWAPPED |
29718825b8aSMuhammad Usama Anjum                  PAGE_IS_PRESENT | PAGE_IS_HUGE,
29818825b8aSMuhammad Usama Anjum   };
29918825b8aSMuhammad Usama Anjum
30018825b8aSMuhammad Usama AnjumThe ``PAGE_IS_WRITTEN`` flag can be considered as a better-performing alternative
30118825b8aSMuhammad Usama Anjumof soft-dirty flag. It doesn't get affected by VMA merging of the kernel and hence
30218825b8aSMuhammad Usama Anjumthe user can find the true soft-dirty pages in case of normal pages. (There may
30318825b8aSMuhammad Usama Anjumstill be extra dirty pages reported for THP or Hugetlb pages.)
30418825b8aSMuhammad Usama Anjum
30518825b8aSMuhammad Usama Anjum"PAGE_IS_WRITTEN" category is used with uffd write protect-enabled ranges to
30618825b8aSMuhammad Usama Anjumimplement memory dirty tracking in userspace:
30718825b8aSMuhammad Usama Anjum
30818825b8aSMuhammad Usama Anjum 1. The userfaultfd file descriptor is created with ``userfaultfd`` syscall.
30918825b8aSMuhammad Usama Anjum 2. The ``UFFD_FEATURE_WP_UNPOPULATED`` and ``UFFD_FEATURE_WP_ASYNC`` features
31018825b8aSMuhammad Usama Anjum    are set by ``UFFDIO_API`` IOCTL.
31118825b8aSMuhammad Usama Anjum 3. The memory range is registered with ``UFFDIO_REGISTER_MODE_WP`` mode
31218825b8aSMuhammad Usama Anjum    through ``UFFDIO_REGISTER`` IOCTL.
31318825b8aSMuhammad Usama Anjum 4. Then any part of the registered memory or the whole memory region must
31418825b8aSMuhammad Usama Anjum    be write protected using ``PAGEMAP_SCAN`` IOCTL with flag ``PM_SCAN_WP_MATCHING``
31518825b8aSMuhammad Usama Anjum    or the ``UFFDIO_WRITEPROTECT`` IOCTL can be used. Both of these perform the
31618825b8aSMuhammad Usama Anjum    same operation. The former is better in terms of performance.
31718825b8aSMuhammad Usama Anjum 5. Now the ``PAGEMAP_SCAN`` IOCTL can be used to either just find pages which
31818825b8aSMuhammad Usama Anjum    have been written to since they were last marked and/or optionally write protect
31918825b8aSMuhammad Usama Anjum    the pages as well.
320