[PATCH v6 09/39] docs: filesystems: update mmap_prepare docs for discontig kernel pgs

David Hildenbrand (Arm) david at kernel.org
Tue Oct 13 08:25:35 PDT 2026


On 10/13/26 17:04, Lorenzo Stoakes (ARM) wrote:
> Describe the newly introduced discontiguous kernel page mapping mechanism,
> detailing how to use it sensibly and how the API looks.
> 
> Explicitly detail the various discontiguous actions available and how to
> use them.
> 
> Reviewed-by: Suren Baghdasaryan <surenb at google.com>
> Signed-off-by: Lorenzo Stoakes (ARM) <ljs at kernel.org>
> ---
>  Documentation/filesystems/mmap_prepare.rst | 81 ++++++++++++++++++++++++++++++
>  1 file changed, 81 insertions(+)
> 
> diff --git a/Documentation/filesystems/mmap_prepare.rst b/Documentation/filesystems/mmap_prepare.rst
> index 82c99c95ad85..b5afbb33e5c8 100644
> --- a/Documentation/filesystems/mmap_prepare.rst
> +++ b/Documentation/filesystems/mmap_prepare.rst
> @@ -164,5 +164,86 @@ pointer. These are:
>    sufficient entries in the page array to cover the entire range of the
>    described VMA.
>  
> +* mmap_action_map_discontig_kernel_pages() - Maps a discontiguous range of
> +  `struct page` pointers over the VMA. They must span from the start of the VMA,
> +  but may terminate prior to the end (leaving the remainder unmapped).
> +
>  **NOTE:** The ``action`` field should never normally be manipulated directly,
>  rather you ought to use one of these helpers.
> +
> +Discontiguous Actions
> +=====================
> +
> +Some actions can be performed across discontiguous ranges.
> +
> +Map kernel pages
> +----------------
> +
> +To map kernel pages discontiguously, you must provide hooks using ``struct
> +discontig_kernel_page_ops``:
> +
> +.. code-block:: C
> +
> +    struct discontig_kernel_page_ops {
> +        int (*init)(void *vm_private_data, void **private);
> +        int (*get)(struct discontig_kernel_page_state *state);
> +    };
> +
> +The ``init`` hook is optional and allows state to be established before the
> +operation starts, for instance taking a reference count. Nothing is invoked
> +after the operation, so ``init`` must not leave locks held, and state that must
> +be released once the mapping goes away should be released in
> +``vm_ops->close``.
> +
> +The ``init`` hook, if provided, is invoked prior to the operation starting. It
> +may update what is pointed to by ``vm_private_data`` and/or ``private``. If an
> +error is returned, then the operation is aborted. The ``private`` field can be
> +reassigned.
> +
> +**NOTE:** The operation may sleep between invocations of ``get``, so locks
> +needed to stabilise state must be taken and released within each hook.
> +
> +The ``get`` handler is the key means through which the operation is
> +executed. The current state of the operation is provided through ``struct
> +discontig_kernel_page_state``:
> +
> +.. code-block:: C
> +
> +    struct discontig_kernel_page_state {
> +        /* Map state. */
> +        unsigned long start;            /* Start address of VMA. */
> +        unsigned long end;              /* End address of VMA. */
> +        unsigned long addr;             /* The current address to be mapped. */
> +        pgoff_t pgoff;                  /* The current pgoff to be mapped. */
> +        unsigned long nr_pages_mapped;  /* The number of pages mapped. */
> +        unsigned long nr_pages_remain;  /* The number of pages remaining. */
> +
> +        /* User-defined state. */
> +        void *vm_private_data;          /* VMA private data. */
> +        void *private;                  /* Mapping private data. */
> +
> +        /* Users should not touch these, use discontig_kernel_map_*() helpers. */
> +        ... internal fields ...
> +    };
> +
> +With ``private`` being an additional user-controllable state variable,
> +initialised via ``mmap_action_map_discontig_kernel_pages()``, and
> +``vm_private_data`` being equal to the ``desc->private_data`` field set in
> +the ``mmap_prepare()`` hook.
> +
> +In the ``get`` hook, the user must choose how to map kernel pages:
> +
> +* ``discontig_kernel_map_abort()`` - Call this to abort the operation, whatever
> +  has been mapped so far will be retained, the rest of the mapping will SIGBUS
> +  if accessed.
> +* ``discontig_kernel_map_page()`` - Maps a single page, correctly handling

"single page" can be misleading with compound pages.

"Map an entire (compound) page" or sth like that would be clearer.

Acked-by: David Hildenbrand (Arm) <david at kernel.org>

-- 
Cheers,

David



More information about the kvm-riscv mailing list