On Sat, Sep 13, 2025 at 06:54:06PM -0400, Chris Mason wrote: > 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 <[email protected]> > > --- > > 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?
Yeah, sigh, this is a direct product of cramfs seemingly having a bug where it was passing PA's and not PFNs. I thought I had fixed this but clearly I missed this here. Let me send a fix-patch! > > -chris Cheers, Lorenzo
