xref: /linux/Documentation/filesystems/mmap_prepare.rst (revision 334fbe734e687404f346eba7d5d96ed2b44d35ab)
1fdd24784SLorenzo Stoakes (Oracle).. SPDX-License-Identifier: GPL-2.0
2fdd24784SLorenzo Stoakes (Oracle)
3fdd24784SLorenzo Stoakes (Oracle)===========================
4fdd24784SLorenzo Stoakes (Oracle)mmap_prepare callback HOWTO
5fdd24784SLorenzo Stoakes (Oracle)===========================
6fdd24784SLorenzo Stoakes (Oracle)
7fdd24784SLorenzo Stoakes (Oracle)Introduction
8fdd24784SLorenzo Stoakes (Oracle)============
9fdd24784SLorenzo Stoakes (Oracle)
10fdd24784SLorenzo Stoakes (Oracle)The ``struct file->f_op->mmap()`` callback has been deprecated as it is both a
11fdd24784SLorenzo Stoakes (Oracle)stability and security risk, and doesn't always permit the merging of adjacent
12fdd24784SLorenzo Stoakes (Oracle)mappings resulting in unnecessary memory fragmentation.
13fdd24784SLorenzo Stoakes (Oracle)
14fdd24784SLorenzo Stoakes (Oracle)It has been replaced with the ``file->f_op->mmap_prepare()`` callback which
15fdd24784SLorenzo Stoakes (Oracle)solves these problems.
16fdd24784SLorenzo Stoakes (Oracle)
17fdd24784SLorenzo Stoakes (Oracle)This hook is called right at the beginning of setting up the mapping, and
18fdd24784SLorenzo Stoakes (Oracle)importantly it is invoked *before* any merging of adjacent mappings has taken
19fdd24784SLorenzo Stoakes (Oracle)place.
20fdd24784SLorenzo Stoakes (Oracle)
21fdd24784SLorenzo Stoakes (Oracle)If an error arises upon mapping, it might arise after this callback has been
22fdd24784SLorenzo Stoakes (Oracle)invoked, therefore it should be treated as effectively stateless.
23fdd24784SLorenzo Stoakes (Oracle)
24fdd24784SLorenzo Stoakes (Oracle)That is - no resources should be allocated nor state updated to reflect that a
25fdd24784SLorenzo Stoakes (Oracle)mapping has been established, as the mapping may either be merged, or fail to be
26fdd24784SLorenzo Stoakes (Oracle)mapped after the callback is complete.
27fdd24784SLorenzo Stoakes (Oracle)
28c50ca15dSLorenzo Stoakes (Oracle)Mapped callback
29c50ca15dSLorenzo Stoakes (Oracle)---------------
30c50ca15dSLorenzo Stoakes (Oracle)
31c50ca15dSLorenzo Stoakes (Oracle)If resources need to be allocated per-mapping, or state such as a reference
32c50ca15dSLorenzo Stoakes (Oracle)count needs to be manipulated, this should be done using the ``vm_ops->mapped``
33c50ca15dSLorenzo Stoakes (Oracle)hook, which itself should be set by the >mmap_prepare hook.
34c50ca15dSLorenzo Stoakes (Oracle)
35c50ca15dSLorenzo Stoakes (Oracle)This callback is only invoked if a new mapping has been established and was not
36c50ca15dSLorenzo Stoakes (Oracle)merged with any other, and is invoked at a point where no error may occur before
37c50ca15dSLorenzo Stoakes (Oracle)the mapping is established.
38c50ca15dSLorenzo Stoakes (Oracle)
39c50ca15dSLorenzo Stoakes (Oracle)You may return an error to the callback itself, which will cause the mapping to
40c50ca15dSLorenzo Stoakes (Oracle)become unmapped and an error returned to the mmap() caller. This is useful if
41c50ca15dSLorenzo Stoakes (Oracle)resources need to be allocated, and that allocation might fail.
42c50ca15dSLorenzo Stoakes (Oracle)
43fdd24784SLorenzo Stoakes (Oracle)How To Use
44fdd24784SLorenzo Stoakes (Oracle)==========
45fdd24784SLorenzo Stoakes (Oracle)
46fdd24784SLorenzo Stoakes (Oracle)In your driver's struct file_operations struct, specify an ``mmap_prepare``
47fdd24784SLorenzo Stoakes (Oracle)callback rather than an ``mmap`` one, e.g. for ext4:
48fdd24784SLorenzo Stoakes (Oracle)
49fdd24784SLorenzo Stoakes (Oracle).. code-block:: C
50fdd24784SLorenzo Stoakes (Oracle)
51fdd24784SLorenzo Stoakes (Oracle)    const struct file_operations ext4_file_operations = {
52fdd24784SLorenzo Stoakes (Oracle)        ...
53fdd24784SLorenzo Stoakes (Oracle)        .mmap_prepare    = ext4_file_mmap_prepare,
54fdd24784SLorenzo Stoakes (Oracle)    };
55fdd24784SLorenzo Stoakes (Oracle)
56fdd24784SLorenzo Stoakes (Oracle)This has a signature of ``int (*mmap_prepare)(struct vm_area_desc *)``.
57fdd24784SLorenzo Stoakes (Oracle)
58fdd24784SLorenzo Stoakes (Oracle)Examining the struct vm_area_desc type:
59fdd24784SLorenzo Stoakes (Oracle)
60fdd24784SLorenzo Stoakes (Oracle).. code-block:: C
61fdd24784SLorenzo Stoakes (Oracle)
62fdd24784SLorenzo Stoakes (Oracle)    struct vm_area_desc {
63fdd24784SLorenzo Stoakes (Oracle)        /* Immutable state. */
64fdd24784SLorenzo Stoakes (Oracle)        const struct mm_struct *const mm;
65fdd24784SLorenzo Stoakes (Oracle)        struct file *const file; /* May vary from vm_file in stacked callers. */
66fdd24784SLorenzo Stoakes (Oracle)        unsigned long start;
67fdd24784SLorenzo Stoakes (Oracle)        unsigned long end;
68fdd24784SLorenzo Stoakes (Oracle)
69fdd24784SLorenzo Stoakes (Oracle)        /* Mutable fields. Populated with initial state. */
70fdd24784SLorenzo Stoakes (Oracle)        pgoff_t pgoff;
71fdd24784SLorenzo Stoakes (Oracle)        struct file *vm_file;
72fdd24784SLorenzo Stoakes (Oracle)        vma_flags_t vma_flags;
73fdd24784SLorenzo Stoakes (Oracle)        pgprot_t page_prot;
74fdd24784SLorenzo Stoakes (Oracle)
75fdd24784SLorenzo Stoakes (Oracle)        /* Write-only fields. */
76fdd24784SLorenzo Stoakes (Oracle)        const struct vm_operations_struct *vm_ops;
77fdd24784SLorenzo Stoakes (Oracle)        void *private_data;
78fdd24784SLorenzo Stoakes (Oracle)
79fdd24784SLorenzo Stoakes (Oracle)        /* Take further action? */
80fdd24784SLorenzo Stoakes (Oracle)        struct mmap_action action;
81fdd24784SLorenzo Stoakes (Oracle)    };
82fdd24784SLorenzo Stoakes (Oracle)
83fdd24784SLorenzo Stoakes (Oracle)This is straightforward - you have all the fields you need to set up the
84fdd24784SLorenzo Stoakes (Oracle)mapping, and you can update the mutable and writable fields, for instance:
85fdd24784SLorenzo Stoakes (Oracle)
86fdd24784SLorenzo Stoakes (Oracle).. code-block:: C
87fdd24784SLorenzo Stoakes (Oracle)
88fdd24784SLorenzo Stoakes (Oracle)    static int ext4_file_mmap_prepare(struct vm_area_desc *desc)
89fdd24784SLorenzo Stoakes (Oracle)    {
90fdd24784SLorenzo Stoakes (Oracle)        int ret;
91fdd24784SLorenzo Stoakes (Oracle)        struct file *file = desc->file;
92fdd24784SLorenzo Stoakes (Oracle)        struct inode *inode = file->f_mapping->host;
93fdd24784SLorenzo Stoakes (Oracle)
94fdd24784SLorenzo Stoakes (Oracle)        ...
95fdd24784SLorenzo Stoakes (Oracle)
96fdd24784SLorenzo Stoakes (Oracle)        file_accessed(file);
97fdd24784SLorenzo Stoakes (Oracle)        if (IS_DAX(file_inode(file))) {
98fdd24784SLorenzo Stoakes (Oracle)            desc->vm_ops = &ext4_dax_vm_ops;
99fdd24784SLorenzo Stoakes (Oracle)            vma_desc_set_flags(desc, VMA_HUGEPAGE_BIT);
100fdd24784SLorenzo Stoakes (Oracle)        } else {
101fdd24784SLorenzo Stoakes (Oracle)            desc->vm_ops = &ext4_file_vm_ops;
102fdd24784SLorenzo Stoakes (Oracle)        }
103fdd24784SLorenzo Stoakes (Oracle)        return 0;
104fdd24784SLorenzo Stoakes (Oracle)    }
105fdd24784SLorenzo Stoakes (Oracle)
106fdd24784SLorenzo Stoakes (Oracle)Importantly, you no longer have to dance around with reference counts or locks
107fdd24784SLorenzo Stoakes (Oracle)when updating these fields - **you can simply go ahead and change them**.
108fdd24784SLorenzo Stoakes (Oracle)
109fdd24784SLorenzo Stoakes (Oracle)Everything is taken care of by the mapping code.
110fdd24784SLorenzo Stoakes (Oracle)
111fdd24784SLorenzo Stoakes (Oracle)VMA Flags
112fdd24784SLorenzo Stoakes (Oracle)---------
113fdd24784SLorenzo Stoakes (Oracle)
114fdd24784SLorenzo Stoakes (Oracle)Along with ``mmap_prepare``, VMA flags have undergone an overhaul. Where before
115fdd24784SLorenzo Stoakes (Oracle)you would invoke one of vm_flags_init(), vm_flags_reset(), vm_flags_set(),
116fdd24784SLorenzo Stoakes (Oracle)vm_flags_clear(), and vm_flags_mod() to modify flags (and to have the
117fdd24784SLorenzo Stoakes (Oracle)locking done correctly for you, this is no longer necessary.
118fdd24784SLorenzo Stoakes (Oracle)
119fdd24784SLorenzo Stoakes (Oracle)Also, the legacy approach of specifying VMA flags via ``VM_READ``, ``VM_WRITE``,
120fdd24784SLorenzo Stoakes (Oracle)etc. - i.e. using a ``-VM_xxx``- macro has changed too.
121fdd24784SLorenzo Stoakes (Oracle)
122fdd24784SLorenzo Stoakes (Oracle)When implementing mmap_prepare(), reference flags by their bit number, defined
123fdd24784SLorenzo Stoakes (Oracle)as a ``VMA_xxx_BIT`` macro, e.g. ``VMA_READ_BIT``, ``VMA_WRITE_BIT`` etc.,
124fdd24784SLorenzo Stoakes (Oracle)and use one of (where ``desc`` is a pointer to struct vm_area_desc):
125fdd24784SLorenzo Stoakes (Oracle)
126fdd24784SLorenzo Stoakes (Oracle)* ``vma_desc_test_any(desc, ...)`` - Specify a comma-separated list of flags
127fdd24784SLorenzo Stoakes (Oracle)  you wish to test for (whether _any_ are set), e.g. - ``vma_desc_test_any(
128fdd24784SLorenzo Stoakes (Oracle)  desc, VMA_WRITE_BIT, VMA_MAYWRITE_BIT)`` - returns ``true`` if either are set,
129fdd24784SLorenzo Stoakes (Oracle)  otherwise ``false``.
130fdd24784SLorenzo Stoakes (Oracle)* ``vma_desc_set_flags(desc, ...)`` - Update the VMA descriptor flags to set
131fdd24784SLorenzo Stoakes (Oracle)  additional flags specified by a comma-separated list,
132fdd24784SLorenzo Stoakes (Oracle)  e.g. - ``vma_desc_set_flags(desc, VMA_PFNMAP_BIT, VMA_IO_BIT)``.
133fdd24784SLorenzo Stoakes (Oracle)* ``vma_desc_clear_flags(desc, ...)`` - Update the VMA descriptor flags to clear
134fdd24784SLorenzo Stoakes (Oracle)  flags specified by a comma-separated list, e.g. - ``vma_desc_clear_flags(
135fdd24784SLorenzo Stoakes (Oracle)  desc, VMA_WRITE_BIT, VMA_MAYWRITE_BIT)``.
136fdd24784SLorenzo Stoakes (Oracle)
137fdd24784SLorenzo Stoakes (Oracle)Actions
138fdd24784SLorenzo Stoakes (Oracle)=======
139fdd24784SLorenzo Stoakes (Oracle)
140fdd24784SLorenzo Stoakes (Oracle)You can now very easily have actions be performed upon a mapping once set up by
141fdd24784SLorenzo Stoakes (Oracle)utilising simple helper functions invoked upon the struct vm_area_desc
142fdd24784SLorenzo Stoakes (Oracle)pointer. These are:
143fdd24784SLorenzo Stoakes (Oracle)
144fdd24784SLorenzo Stoakes (Oracle)* mmap_action_remap() - Remaps a range consisting only of PFNs for a specific
145fdd24784SLorenzo Stoakes (Oracle)  range starting a virtual address and PFN number of a set size.
146fdd24784SLorenzo Stoakes (Oracle)
147fdd24784SLorenzo Stoakes (Oracle)* mmap_action_remap_full() - Same as mmap_action_remap(), only remaps the
148fdd24784SLorenzo Stoakes (Oracle)  entire mapping from ``start_pfn`` onward.
149fdd24784SLorenzo Stoakes (Oracle)
150fdd24784SLorenzo Stoakes (Oracle)* mmap_action_ioremap() - Same as mmap_action_remap(), only performs an I/O
151fdd24784SLorenzo Stoakes (Oracle)  remap.
152fdd24784SLorenzo Stoakes (Oracle)
153fdd24784SLorenzo Stoakes (Oracle)* mmap_action_ioremap_full() - Same as mmap_action_ioremap(), only remaps
154fdd24784SLorenzo Stoakes (Oracle)  the entire mapping from ``start_pfn`` onward.
155fdd24784SLorenzo Stoakes (Oracle)
156a1b7fb40SLorenzo Stoakes (Oracle)* mmap_action_simple_ioremap() - Sets up an I/O remap from a specified
157a1b7fb40SLorenzo Stoakes (Oracle)  physical address and over a specified length.
158a1b7fb40SLorenzo Stoakes (Oracle)
159*62c65fd7SLorenzo Stoakes (Oracle)* mmap_action_map_kernel_pages() - Maps a specified array of `struct page`
160*62c65fd7SLorenzo Stoakes (Oracle)  pointers in the VMA from a specific offset.
161*62c65fd7SLorenzo Stoakes (Oracle)
162*62c65fd7SLorenzo Stoakes (Oracle)* mmap_action_map_kernel_pages_full() - Maps a specified array of `struct
163*62c65fd7SLorenzo Stoakes (Oracle)  page` pointers over the entire VMA. The caller must ensure there are
164*62c65fd7SLorenzo Stoakes (Oracle)  sufficient entries in the page array to cover the entire range of the
165*62c65fd7SLorenzo Stoakes (Oracle)  described VMA.
166*62c65fd7SLorenzo Stoakes (Oracle)
167fdd24784SLorenzo Stoakes (Oracle)**NOTE:** The ``action`` field should never normally be manipulated directly,
168fdd24784SLorenzo Stoakes (Oracle)rather you ought to use one of these helpers.
169