ioctl_pagemap_scan(2)

πŸ“¦
version 6.7 Β· 2 versions
, in ubuntu noble

πŸ’… ioctl_pagemap_scan β€” bestie edition

okay so this is a page from the System Calls Manual (section 2, obvi) and it's literally about getting and/or clearing page flags. come learn with me 🫢


✨ NAME ✨

ioctl_pagemap_scan β€” get and/or clear page flags


πŸ“š LIBRARY πŸ“š

Standard C library (libc, -lc)


🌸 SYNOPSIS 🌸

#include <linux/fs.h>  /* Definition of struct pm_scan_arg,
                          struct page_region, and PAGE_IS_* constants */
#include <sys/ioctl.h>

int ioctl(int pagemap_fd, PAGEMAP_SCAN, struct pm_scan_arg *arg);

πŸ¦‹ DESCRIPTION πŸ¦‹

So this ioctl(2) is your girl for getting and optionally clearing some specific flags from page table entries. the tea gets returned with PAGE_SIZE granularity, so don't expect anything finer than that, bestie.

Now listen, if you wanna start tracking the written state (that's the flag, mwah) of a page or a range of memory, you gotta have UFFD_FEATURE_WP_ASYNC enabled by the UFFDIO_API ioctl(2) on userfaultfd, and the memory range has to be registered with the UFFDIO_REGISTER ioctl(2) in UFFDIO_REGISTER_MODE_WP mode. no shortcuts, it's giving prerequisites πŸ’€

πŸ‘‘ Supported page flags

these page table entry flags are the ones that get a seat at the table:

  • PAGE_IS_WPALLOWED β€” the page has asynchronous write-protection enabled. iconic.
  • PAGE_IS_WRITTEN β€” the page has been written to from the time it was write protected.
  • PAGE_IS_FILE β€” the page is file backed.
  • PAGE_IS_PRESENT β€” the page is present in the memory.
  • PAGE_IS_SWAPPED β€” the page is swapped.
  • PAGE_IS_PFNZERO β€” the page has zero PFN.
  • PAGE_IS_HUGE β€” the page is THP or Hugetlb backed.

πŸ’« Supported operations

the get operation is always performed if the output buffer is specified. the other operations are as follows:

  • PM_SCAN_WP_MATCHING β€” write protect the matched pages.
  • PM_SCAN_CHECK_WPASYNC β€” abort the scan when a page is found which doesn't have the Userfaultfd Asynchronous Write protection enabled.

πŸŽ€ The struct pm_scan_arg argument

struct pm_scan_arg {
    __u64  size;
    __u64  flags;
    __u64  start;
    __u64  end;
    __u64  walk_end;
    __u64  vec;
    __u64  vec_len;
    __u64  max_pages
    __u64  category_inverted;
    __u64  category_mask;
    __u64  category_anyof_mask
    __u64  return_mask;
};
  • size β€” set this bad boy to the size of the structure in bytes, like sizeof(struct pm_scan_arg). don't freestyle it.
  • flags β€” the operations you wanna perform go right here.
  • start β€” the starting address of the scan lives here.
  • end β€” and the ending address of the scan lives here.
  • walk_end β€” the kernel hands you back the scan's ending address in this one. if walk_end equals end, that means the scan completed on the entire range. slay, full coverage ✨
  • vec β€” the address of the page_region array for output. and that struct is:
struct page_region {
    __u64  start;
    __u64  end;
    __u64  categories;
};
  • vec_len β€” the length of the page_region struct array.
  • max_pages β€” the optional limit for the number of output pages you need.
  • category_inverted β€” PAGE_IS_* categories whose values match if 0 instead of 1. yes, inverted, we love a plot twist πŸ™ˆ
  • category_mask β€” skip pages for which any PAGE_IS_* category doesn't match.
  • category_anyof_mask β€” skip pages for which no PAGE_IS_* category matches.
  • return_mask β€” PAGE_IS_* categories that are to be reported in page_region.

πŸ”₯ RETURN VALUE πŸ”₯

if it goes wrong, -1 comes back and errno gets set to tell you exactly what went down.


πŸ’€ ERRORS πŸ’€

error codes can be one of these (but not limited to, so don't come for me):

  • EINVAL β€” invalid arguments, i.e. invalid size of the argument, invalid flags, invalid categories, the start address isn't aligned with PAGE_SIZE, or vec_len is specified when vec is NULL.
  • EFAULT β€” invalid arg pointer, invalid vec pointer, or invalid address range specified by start and end.
  • ENOMEM β€” no memory is available. tragic.
  • EINTR β€” Fetal signal is pending.

⭐ STANDARDS ⭐

Linux. periodt.


🧚 HISTORY 🧚

Linux 6.7. she's new here but she's already that girl.


🌈 SEE ALSO 🌈

ioctl(2)


okay bestie that's the whole page πŸ’– this was Linux man-pages 6.7, dated 2024-01-28, and yes we read the whole thing, no skimming, main character energy only πŸ‘‘βœ¨

πŸ“¦ where this page comes from