Provided by: manpages-ru-dev_4.18.1-1_all bug

ИМЯ

       ioctl_userfaultfd  -  создаёт  файловый  дескриптор  для  обработки  страничных  ошибок  в
       пользовательском пространстве

LIBRARY

       Standard C library (libc, -lc)

СИНТАКСИС

       #include <linux/userfaultfd.h>  /* определения констант UFFD* */
       #include <sys/ioctl.h>

       int ioctl(int fd, int cmd, ...);

ОПИСАНИЕ

       Над объектом userfaultfd (созданным  вызовом  userfaultfd(2))  можно  выполнять  различные
       операции ioctl(2) используя вызовы вида:

           ioctl(fd, cmd, argp);
       Здесь  fd  — файловый дескриптор, ссылающийся на объект userfaultfd, cmd — одна из команд,
       перечисленных ниже, а argp — указатель на структуру данных, используемую командой cmd.

       Операции ioctl(2) описаны ниже. Операции UFFDIO_API, UFFDIO_REGISTER  и  UFFDIO_UNREGISTER
       используются  для настройки поведения userfaultfd. Они позволяют вызывающему выбрать какие
       свойства нужно включить и какие типы  событий  будут  доставляться  приложению.  Остальные
       операции являются операциями над диапазоном. Эти операции позволяют вызывающему приложению
       воспринимать события страничных ошибок.

   UFFDIO_API
       (начиная с Linux 4.3) Включить работу с userfaultfd и выполнить согласование  программного
       интерфейса.

       В  аргументе  argp  содержится  указатель  на структуру uffdio_api, определённую следующим
       образом:

           struct uffdio_api {
               __u64 api;        /* запрашиваемая версия API (входные данные) */
               __u64 features;   /* запрашиваемые свойства (входные/выходные) */
               __u64 ioctls;     /* доступные операции ioctl() (выходные данные) */
           };

       В поле api задаётся версия программного интерфейса, запрашиваемого приложением.

       Ядро проверяет, что поддерживает запрашиваемую версию программного интерфейса  и  изменять
       поля  features  и  ioctls  в  битовой маске, представляющей все доступные свойства и общие
       операции ioctl(2).

       Before Linux 4.11, the features field must be initialized  to  zero  before  the  call  to
       UFFDIO_API, and zero (i.e., no feature bits) is placed in the features field by the kernel
       upon return from ioctl(2).

       Начиная с Linux 4.11 поле features можно использовать для запроса  поддержки  определённых
       свойств  и явно включить свойства userfaultfd, которые по умолчанию выключены. Ядро всегда
       сообщает о всех доступных свойствах через поле features.

       Чтобы включить свойство userfaultfd приложение должно  установить  соответствующий  бит  в
       поле  features.  Если  ядро  поддерживает  все  запрошенные  свойств,  то он включит их. В
       противном случае оно обнулит возвращаемую структуру uffdio_api и вернёт EINVAL.

       Могут устанавливаться следующие биты свойств:

       UFFD_FEATURE_EVENT_FORK (начиная с Linux 4.11)
              Если это свойство  включено,  то  объекты  userfaultfd,  связанные  с  родительским
              процессом,   дублируются   в  дочернем  процессе  при  вызове  fork(2),  а  событие
              UFFD_EVENT_FORK доставляется отслеживающему userfaultfd.

       UFFD_FEATURE_EVENT_REMAP (начиная с Linux 4.11)
              Если  это  свойство  включено,  то  при  вызове  mremap(2)  процессом   с   ошибкой
              отслеживающий userfaultfd будет получать событие с типом UFFD_EVENT_REMAP.

       UFFD_FEATURE_EVENT_REMOVE (начиная с Linux 4.11)
              Если   это   свойство   включено,  то  при  вызове  madvise(2)со  значением  совета
              MADV_DONTNEED или MADV_REMOVE для освобождения области виртуальной памяти процессом
              с    ошибкой   отслеживающий   userfaultfd   будет   получать   событие   с   типом
              UFFD_EVENT_REMOVE.

       UFFD_FEATURE_EVENT_UNMAP (начиная с Linux 4.11)
              Если это свойство включено, то  при  явном  вызове  mremap(2)  или  неявном  вызове
              mmap(2)  или mremap(2) процессом с ошибкой отслеживающий userfaultfd будет получать
              событие с типом UFFD_EVENT_UNMAP.

       UFFD_FEATURE_MISSING_HUGETLBFS (начиная с Linux 4.11)
              Если этот  бит  установлен,  то  ядро  включает  поддержку  регистрации  диапазонов
              userfaultfd для областей виртуальной памяти hugetlbfs.

       UFFD_FEATURE_MISSING_SHMEM (начиная с Linux 4.11)
              Если  этот  бит  установлен,  то  ядро  включает  поддержку  регистрации диапазонов
              userfaultfd для общих областей виртуальной памяти. К ним относятся все  программные
              интерфейсы  общей  памяти  ядра: общая память System V, tmpfs(5), общие отображения
              /dev/zero, mmap(2) с флагом MAP_SHARED, memfd_create(2) и т. д.

       UFFD_FEATURE_SIGBUS (начиная с Linux 4.14)
              Если этот бит установлен, то события о страничных ошибках (UFFD_EVENT_PAGEFAULT) не
              доставляются.   Вместо   них  в  ошибшийся  процесс  будет  послан  сигнал  SIGBUS.
              Приложениям, использующим этой свойство, не потребуется  использовать  слежение  за
              userfaultfd   для   обработки  доступа  к  областям  памяти,  зарегистрированным  в
              userfaultfd.

       UFFD_FEATURE_THREAD_ID (начиная с Linux 4.14)
              If this feature bit is set, uffd_msg.pagefault.feat.ptid will be set to the faulted
              thread ID for each page-fault message.

       UFFD_FEATURE_MINOR_HUGETLBFS (начиная с Linux 5.13)
              If  this  feature bit is set, the kernel supports registering userfaultfd ranges in
              minor mode on hugetlbfs-backed memory areas.

       UFFD_FEATURE_MINOR_SHMEM (начиная с Linux 5.14)
              If this feature bit is set, the kernel supports registering userfaultfd  ranges  in
              minor mode on shmem-backed memory areas.

       Возвращаемое поле ioctls можно содержать следующие биты:

       1 << _UFFDIO_API
              Поддерживается операция UFFDIO_API.

       1 << _UFFDIO_REGISTER
              Поддерживается операция UFFDIO_REGISTER.

       1 << _UFFDIO_UNREGISTER
              Поддерживается операция UFFDIO_UNREGISTER.

       This  ioctl(2)  operation returns 0 on success.  On error, -1 is returned and errno is set
       to indicate the error.  Possible errors include:

       EFAULT Значение argp ссылается  на  адрес,  который  находится  вне  доступного  адресного
              пространства вызывающего процесса.

       EINVAL Дескриптор userfaultfd уже включён предыдущей операцией UFFDIO_API.

       EINVAL Версия  программного  интерфейса,  запрошенная в поле api, не поддерживается данным
              ядром,  или  в  переданном  ядру  поле  features  установлены  биты,   которые   не
              поддерживаются текущей версией ядра.

   UFFDIO_REGISTER
       (Since  Linux  4.3.)   Register  a  memory address range with the userfaultfd object.  The
       pages in the range must be "compatible".  Please refer to the list of register modes below
       for the compatible memory backends for each mode.

       В аргументе argp содержится указатель на структуру uffdio_register, определённую следующим
       образом:

           struct uffdio_range {
               __u64 start;    /* начало диапазона */
               __u64 len;      /* длина диапазона (в байтах) */
           };

           struct uffdio_register {
               struct uffdio_range range;
               __u64 mode;     /* желаемый режим операции (входные данные) */
               __u64 ioctls;   /* доступные операции ioctl() (результат) */
           };

       В поле range задаётся диапазон памяти (начинающийся с start и длиной  len  байт),  который
       должен обрабатываться userfaultfd.

       В  поле mode задаётся режим операции на этим диапазоном памяти. У режима userfaultfd могут
       быть указаны следующие значения (через операцию ИЛИ) для задаваемого диапазона:

       UFFDIO_REGISTER_MODE_MISSING
              Track page faults on missing pages.  Since Linux 4.3, only private anonymous ranges
              are  compatible.   Since  Linux  4.11,  hugetlbfs and shared memory ranges are also
              compatible.

       UFFDIO_REGISTER_MODE_WP
              Track page  faults  on  write-protected  pages.   Since  Linux  5.7,  only  private
              anonymous ranges are compatible.

       UFFDIO_REGISTER_MODE_MINOR
              Track  minor  page faults.  Since Linux 5.13, only hugetlbfs ranges are compatible.
              Since Linux 5.14, compatibility with shmem ranges was added.

       If the operation is successful, the kernel modifies the ioctls bit-mask field to  indicate
       which  ioctl(2)  operations are available for the specified range.  This returned bit mask
       can contain the following bits:

       1 << _UFFDIO_COPY
              Поддерживается операция UFFDIO_COPY.

       1 << _UFFDIO_WAKE
              Поддерживается операция UFFDIO_WAKE.

       1 << _UFFDIO_WRITEPROTECT
              The UFFDIO_WRITEPROTECT

       1 << _UFFDIO_ZEROPAGE
              The UFFDIO_ZEROPAGE operation is supported.

       1 << _UFFDIO_CONTINUE
              Поддерживается операция UFFDIO_CONTINUE.

       This ioctl(2)  operation returns 0 on success.  On error, -1 is returned and errno is  set
       to indicate the error.  Possible errors include:

       EBUSY  Отображение в указанном диапазоне зарегистрировано в другом объекте userfaultfd.

       EFAULT Значение  argp  ссылается  на  адрес,  который  находится  вне доступного адресного
              пространства вызывающего процесса.

       EINVAL В поле mode указан некорректный или неподдерживаемый бит или поле mode равно нулю.

       EINVAL Отображение в указанном адресном диапазоне отсутствует.

       EINVAL Значение range.start  или  range.len  не  кратно  размеру  системной  страницы  или
              значение range.len равно или эти поля содержат другие некорректные значения.

       EINVAL В указанном адресном диапазоне имеется несовместимое отображение.

   UFFDIO_UNREGISTER
       (начиная с Linux 4.3) Снять регистрацию диапазона адресов памяти в userfaultfd. Страницы в
       диапазоне должны быть «совместимыми» (смотрите описание UFFDIO_REGISTER).

       Снимаемый с регистрации  диапазон  адресов  задаётся  в  структуре  uffdio_range,  которая
       указывается в argp.

       This  ioctl(2)  operation returns 0 on success.  On error, -1 is returned and errno is set
       to indicate the error.  Possible errors include:

       EINVAL Поле start или len структуры ufdio_range не кратно размеру системной  страницы  или
              поле len равно нулю или эти поля содержат другие некорректные значения.

       EINVAL В указанном адресном диапазоне имеется несовместимое отображение.

       EINVAL Отображение в указанном адресном диапазоне отсутствует.

   UFFDIO_COPY
       (начиная  с Linux 4.3) Атомарно копировать непрерывный участок памяти в зарегистрированный
       в userfault диапазон и разбудить заблокированную нить (не обязательно). Адреса источника и
       назначения  и  количество  копируемых  байт  задаётся  в  полях  src,  dst и len структуры
       uffdio_copy, на которую указывает argp:

           struct uffdio_copy {
               __u64 dst;    /* Destination of copy */
               __u64 src;    /* Source of copy */
               __u64 len;    /* Number of bytes to copy */
               __u64 mode;   /* Flags controlling behavior of copy */
               __s64 copy;   /* Number of bytes copied, or negated error */
           };

       Для изменения поведения операции UFFDIO_COPY можно использовать  следующие  значения  mode
       (побитовое ИЛИ):

       UFFDIO_COPY_MODE_DONTWAKE
              Не будить нить, которая ждёт решения страничной ошибки

       UFFDIO_COPY_MODE_WP
              Copy  the  page  with  read-only permission.  This allows the user to trap the next
              write to the page, which will block and generate  another  write-protect  userfault
              message.    This   is   used   only   when  both  UFFDIO_REGISTER_MODE_MISSING  and
              UFFDIO_REGISTER_MODE_WP modes are enabled for the registered range.

       Поле copy используется ядром для возврата количества байт, которые были  скопированы,  или
       ошибки  (отрицательное  значение,  подобное errno). Если значение, возвращённое в copy, не
       совпадает со значением, указанным в len, то операция завершается ошибкой EAGAIN. Поле copy
       используется только для результата; оно не читается операцией UFFDIO_COPY.

       This  ioctl(2)  operation returns 0 on success.  In this case, the entire area was copied.
       On error, -1 is returned and errno is set to indicate the error.  Possible errors include:

       EAGAIN Количество скопированных байт (т. е., значение, возвращаемое в поле copy) не  равно
              значению, указанному в поле len.

       EINVAL Значение  dst или len не кратно размеру системной страницы или диапазон, заданный в
              src и len или dst и len является неправильным.

       EINVAL В поле mode установлен недопустимый бит.

       ENOENT (начиная с Linux 4.11)
              Процесс с ошибкой изменил раскладку  своей  виртуальной  памяти  одновременно  имея
              незавершённую операцию UFFDIO_COPY.

       ENOSPC (в Linux 4.11 по Linux 4.13)
              Процесс с ошибкой завершил работу в момент выполнения операции UFFDIO_COPY.

       ESRCH (начиная с Linux 4.13)
              Процесс с ошибкой завершил работу в момент выполнения операции UFFDIO_COPY.

   UFFDIO_ZEROPAGE
       (начиная с Linux 4.3) Обнулить диапазон памяти, зарегистрированный в userfaultfd.

       Запрашиваемый  диапазон  указывается  в  поле  range структуры uffdio_zeropage, на которую
       указывает argp:

           struct uffdio_zeropage {
               struct uffdio_range range;
               __u64 mode;     /* флаги, определяющие поведение копирования */
               __s64 zeropage; /* количество обнуляемых байт или отрицательная ошибка */
           };

       Для изменения поведения операции UFFDIO_ZEROPAGE  можно  использовать  следующие  значения
       mode (побитовое ИЛИ):

       UFFDIO_ZEROPAGE_MODE_DONTWAKE
              Не будить нить, которая ждёт решения страничной ошибки.

       Поле  zeropage используется ядром для возврата количества байт, которые были обнулены, или
       ошибки (также, как для UFFDIO_COPY). Если значение, возвращённое в zeropage, не  совпадает
       со значением, указанным в range.len, то операция завершается ошибкой EAGAIN. Поле zeropage
       используется только для результата; оно не читается операцией UFFDIO_ZEROPAGE.

       This ioctl(2)  operation returns 0 on success.  In this case, the entire area was  zeroed.
       On error, -1 is returned and errno is set to indicate the error.  Possible errors include:

       EAGAIN Количество обнулённых байт (т. е., значение, возвращаемое в поле zeropage) не равно
              значению, указанному в поле range.len.

       EINVAL Значение range.start или range.len не кратно размеру системной  страницы,  значение
              range.len равно нулю, указанный диапазон является неправильным.

       EINVAL В поле mode установлен недопустимый бит.

       ESRCH (начиная с Linux 4.13)
              Процесс с ошибкой завершил работу в момент выполнения операции UFFDIO_ZEROPAGE.

   UFFDIO_WAKE
       (начиная  с  Linux 4.3) Разбудить нить, которая ждёт решения страничной ошибки в указанном
       диапазоне адресов памяти.

       Операция UFFDIO_WAKE используется  вместе  с  UFFDIO_COPY  и  UFFDIO_ZEROPAGE,  у  которых
       установлен  бит  UFFDIO_COPY_MODE_DONTWAKE  или UFFDIO_ZEROPAGE_MODE_DONTWAKE в поле mode.
       При  отслеживании   userfault   можно   выполнять   несколько   операций   UFFDIO_COPY   и
       UFFDIO_ZEROPAGE вместе и затем явно будить нить с ошибкой с помощью UFFDIO_WAKE.

       В аргументе argp содержится указатель на структуру uffdio_range (показана выше), в которой
       задаётся диапазон адресов.

       This ioctl(2)  operation returns 0 on success.  On error, -1 is returned and errno is  set
       to indicate the error.  Possible errors include:

       EINVAL Поле  start  или len структуры ufdio_range не кратно размеру системной страницы или
              поле len равно нулю или указанный диапазон является неправильным.

   UFFDIO_WRITEPROTECT (начиная с Linux 5.7)
       Write-protect or write-unprotect a userfaultfd-registered  memory  range  registered  with
       mode UFFDIO_REGISTER_MODE_WP.

       The argp argument is a pointer to a uffdio_range structure as shown below:

           struct uffdio_writeprotect {
               struct uffdio_range range; /* Range to change write permission*/
               __u64 mode;                /* Mode to change write permission */
           };

       There are two mode bits that are supported in this structure:

       UFFDIO_WRITEPROTECT_MODE_WP
              When  this  mode  bit  is set, the ioctl will be a write-protect operation upon the
              memory range specified by range.  Otherwise it will be a write-unprotect  operation
              upon  the specified range, which can be used to resolve a userfaultfd write-protect
              page fault.

       UFFDIO_WRITEPROTECT_MODE_DONTWAKE
              When this mode bit is set, do not wake up any  thread  that  waits  for  page-fault
              resolution    after    the    operation.    This   can   be   specified   only   if
              UFFDIO_WRITEPROTECT_MODE_WP is not specified.

       This ioctl(2)  operation returns 0 on success.  On error, -1 is returned and errno is  set
       to indicate the error.  Possible errors include:

       EINVAL Поле  start  или len структуры ufdio_range не кратно размеру системной страницы или
              поле len равно нулю или указанный диапазон является неправильным.

       EAGAIN The process was interrupted; retry this call.

       ENOENT The range specified in range is not valid.  For example, the virtual  address  does
              not exist, or not registered with userfaultfd write-protect mode.

       EFAULT Encountered a generic fault during processing.

   UFFDIO_CONTINUE
       (Since  Linux  5.13.)   Resolve  a  minor  page fault by installing page table entries for
       existing pages in the page cache.

       The argp argument is a pointer to a uffdio_continue structure as shown below:

           struct uffdio_continue {
               struct uffdio_range range;
                              /* Range to install PTEs for and continue */
               __u64 mode;    /* Flags controlling the behavior of continue */
               __s64 mapped;  /* Number of bytes mapped, or negated error */
           };

       Для изменения поведения операции UFFDIO_CONTINUE  можно  использовать  следующие  значения
       mode (побитовое ИЛИ):

       UFFDIO_CONTINUE_MODE_DONTWAKE
              Не будить нить, которая ждёт решения страничной ошибки.

       The  mapped  field  is used by the kernel to return the number of bytes that were actually
       mapped, or an error in the same manner as UFFDIO_COPY.   If  the  value  returned  in  the
       mapped  field doesn't match the value that was specified in range.len, the operation fails
       with the error  EAGAIN.   The  mapped  field  is  output-only;  it  is  not  read  by  the
       UFFDIO_CONTINUE operation.

       This  ioctl(2)  operation returns 0 on success.  In this case, the entire area was mapped.
       On error, -1 is returned and errno is set to indicate the error.  Possible errors include:

       EAGAIN The number of bytes mapped (i.e., the value returned in the mapped field) does  not
              equal the value that was specified in the range.len field.

       EINVAL Значение  range.start  или range.len не кратно размеру системной страницы, значение
              range.len равно нулю, указанный диапазон является неправильным.

       EINVAL В поле mode установлен недопустимый бит.

       EEXIST One or more pages were already mapped in the given range.

       ENOENT Процесс с ошибкой изменил раскладку  своей  виртуальной  памяти  одновременно  имея
              незавершённую операцию UFFDIO_CONTINUE.

       ENOMEM Allocating memory needed to setup the page table mappings failed.

       EFAULT No existing page could be found in the page cache for the given range.

       ESRCH  Процесс с ошибкой завершил работу в момент выполнения операции UFFDIO_CONTINUE.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

       Смотрите описание приведённое выше для каждой операции.

ОШИБКИ

       Смотрите  описание  приведённое  выше  для  каждой операции. Также для всех описанных выше
       операций могут возникать общие ошибки:

       EFAULT Значение argp указывает на некорректный адрес памяти.

       EINVAL (для все операций кроме UFFDIO_API) Объект userfaultfd пока не включён  (с  помощью
              операции UFFDIO_API).

СТАНДАРТЫ

       Данные операции ioctl(2) есть только в Linux.

ДЕФЕКТЫ

       Чтобы  определить  доступные  свойства userfault и включить некоторые из них нужно закрыть
       файловый дескриптор userfaultfd после  первой  операции  UFFDIO_API,  которая  запрашивает
       доступность  свойств,  и  повторно  открыть его перед второй операцией UFFDIO_API, которая
       теперь включит желаемый свойства.

ПРИМЕРЫ

       Смотрите userfaultfd(2).

СМ. ТАКЖЕ

       ioctl(2), mmap(2), userfaultfd(2)

       Файл Documentation/admin-guide/mm/userfaultfd.rst из дерева исходного кода ядра Linux

ПЕРЕВОД

       Русский   перевод   этой    страницы    руководства    был    сделан    Azamat    Hackimov
       <azamat.hackimov@gmail.com>,    Dmitriy   S.   Seregin   <dseregin@59.ru>,   Yuri   Kozlov
       <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

       Этот  перевод  является  бесплатной  документацией;  прочитайте  Стандартную  общественную
       лицензию GNU версии 3 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ или более позднюю, чтобы
       узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

       Если вы обнаружите ошибки в переводе  этой  страницы  руководства,  пожалуйста,  отправьте
       электронное письмо на ⟨man-pages-ru-talks@lists.sourceforge.net⟩.