Hi Lorzeno, On 9/10/25 4:22 PM, Lorenzo Stoakes wrote: > Some drivers/filesystems need to perform additional tasks after the VMA is > set up. This is typically in the form of pre-population. > > The forms of pre-population most likely to be performed are a PFN remap or > insertion of a mixed map, so we provide this functionality, ensuring that > we perform the appropriate actions at the appropriate time - that is > setting flags at the point of .mmap_prepare, and performing the actual > remap at the point at which the VMA is fully established. > > This prevents the driver from doing anything too crazy with a VMA at any > stage, and we retain complete control over how the mm functionality is > applied. > > Unfortunately callers still do often require some kind of custom action, so > we add an optional success/error _hook to allow the caller to do something > after the action has succeeded or failed. > > This is done at the point when the VMA has already been established, so the > harm that can be done is limited. > > The error hook can be used to filter errors if necessary. > > We implement actions as abstracted from the vm_area_desc, so we provide the > ability for custom hooks to invoke actions distinct from the vma > descriptor. > > If any error arises on these final actions, we simply unmap the VMA > altogether. > > Also update the stacked filesystem compatibility layer to utilise the > action behaviour, and update the VMA tests accordingly. > > For drivers which perform truly custom logic, we provide a custom action > hook which is invoked at the point of action execution. > > This can then, in turn, update the desc object and perform other actions, > such as partially remapping ranges for instance. We export > vma_desc_action_prepare() and vma_desc_action_complete() for drivers to do > this. > > This is performed at a stage where the VMA is already established, > immediately prior to mapping completion, so it is considerably less > problematic than a general mmap hook. > > Note that at the point of the action being taken, the VMA is visible via > the rmap, only the VMA write lock is held, so if anything needs to access > the VMA, it is able to. > > Essentially the action is taken as if it were performed after the mapping, > but is kept atomic with VMA state. > > Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@xxxxxxxxxx> > --- > include/linux/mm.h | 30 ++++++ > include/linux/mm_types.h | 61 ++++++++++++ > mm/util.c | 150 +++++++++++++++++++++++++++- > mm/vma.c | 70 ++++++++----- > tools/testing/vma/vma_internal.h | 164 ++++++++++++++++++++++++++++++- > 5 files changed, 447 insertions(+), 28 deletions(-) > [ ... ] > +/** > + * mmap_action_complete - Execute VMA descriptor action. > + * @action: The action to perform. > + * @vma: The VMA to perform the action upon. > + * > + * Similar to mmap_action_prepare(), other than internal mm usage this is > + * intended for mmap_prepare users who implement a custom hook - with this > + * function being called from the custom hook itself. > + * > + * Return: 0 on success, or error, at which point the VMA will be unmapped. > + */ > +int mmap_action_complete(struct mmap_action *action, > + struct vm_area_struct *vma) > +{ > + int err = 0; > + > + switch (action->type) { > + case MMAP_NOTHING: > + break; > + case MMAP_REMAP_PFN: > + VM_WARN_ON_ONCE((vma->vm_flags & VM_REMAP_FLAGS) != > + VM_REMAP_FLAGS); > + > + err = remap_pfn_range_complete(vma, action->remap.addr, > + action->remap.pfn, action->remap.size, > + action->remap.pgprot); > + > + break; > + case MMAP_INSERT_MIXED: > + { > + unsigned long pgnum = 0; > + unsigned long pfn = action->mixedmap.pfn; > + unsigned long addr = action->mixedmap.addr; > + unsigned long vaddr = vma->vm_start; > + > + VM_WARN_ON_ONCE(!(vma->vm_flags & VM_MIXEDMAP)); > + > + for (; pgnum < action->mixedmap.num_pages; > + pgnum++, pfn++, addr += PAGE_SIZE, vaddr += PAGE_SIZE) { > + vm_fault_t vmf; > + > + vmf = vmf_insert_mixed(vma, vaddr, addr); ^^^^^ Should this be pfn instead of addr? -chris