@@ -366,9 +366,53 @@ unsigned long io_uring_get_unmapped_area(struct file *filp, unsigned long addr,
366366
367367#else /* !CONFIG_MMU */
368368
369+ /*
370+ * Drop the pages that were initially referenced and added in
371+ * io_uring_mmap(). We cannot have had a mremap() as that isn't supported,
372+ * hence the vma should be identical to the one we initially referenced and
373+ * mapped, and partial unmaps and splitting isn't possible on a file backed
374+ * mapping.
375+ */
376+ static void io_uring_nommu_vm_close (struct vm_area_struct * vma )
377+ {
378+ unsigned long index ;
379+
380+ for (index = vma -> vm_start ; index < vma -> vm_end ; index += PAGE_SIZE )
381+ put_page (virt_to_page ((void * ) index ));
382+ }
383+
384+ static const struct vm_operations_struct io_uring_nommu_vm_ops = {
385+ .close = io_uring_nommu_vm_close ,
386+ };
387+
369388int io_uring_mmap (struct file * file , struct vm_area_struct * vma )
370389{
371- return is_nommu_shared_mapping (vma -> vm_flags ) ? 0 : - EINVAL ;
390+ struct io_ring_ctx * ctx = file -> private_data ;
391+ struct io_mapped_region * region ;
392+ unsigned long i ;
393+
394+ if (!is_nommu_shared_mapping (vma -> vm_flags ))
395+ return - EINVAL ;
396+
397+ guard (mutex )(& ctx -> mmap_lock );
398+ region = io_mmap_get_region (ctx , vma -> vm_pgoff );
399+ if (!region || !io_region_is_set (region ))
400+ return - EINVAL ;
401+
402+ if ((vma -> vm_end - vma -> vm_start ) !=
403+ (unsigned long ) region -> nr_pages << PAGE_SHIFT )
404+ return - EINVAL ;
405+
406+ /*
407+ * Pin the pages so io_free_region()'s release_pages() does not
408+ * drop the last reference while this VMA exists. delete_vma()
409+ * in mm/nommu.c calls vma_close() which runs ->close above.
410+ */
411+ for (i = 0 ; i < region -> nr_pages ; i ++ )
412+ get_page (region -> pages [i ]);
413+
414+ vma -> vm_ops = & io_uring_nommu_vm_ops ;
415+ return 0 ;
372416}
373417
374418unsigned int io_uring_nommu_mmap_capabilities (struct file * file )
0 commit comments