@@ -273,6 +273,39 @@ static int io_region_pin_pages(struct io_ring_ctx *ctx,
273273 return 0 ;
274274}
275275
276+ static int io_region_allocate_pages (struct io_ring_ctx * ctx ,
277+ struct io_mapped_region * mr ,
278+ struct io_uring_region_desc * reg )
279+ {
280+ gfp_t gfp = GFP_KERNEL_ACCOUNT | __GFP_ZERO | __GFP_NOWARN ;
281+ unsigned long size = mr -> nr_pages << PAGE_SHIFT ;
282+ unsigned long nr_allocated ;
283+ struct page * * pages ;
284+ void * p ;
285+
286+ pages = kvmalloc_array (mr -> nr_pages , sizeof (* pages ), gfp );
287+ if (!pages )
288+ return - ENOMEM ;
289+
290+ p = io_mem_alloc_compound (pages , mr -> nr_pages , size , gfp );
291+ if (!IS_ERR (p )) {
292+ mr -> flags |= IO_REGION_F_SINGLE_REF ;
293+ mr -> pages = pages ;
294+ return 0 ;
295+ }
296+
297+ nr_allocated = alloc_pages_bulk_array_node (gfp , NUMA_NO_NODE ,
298+ mr -> nr_pages , pages );
299+ if (nr_allocated != mr -> nr_pages ) {
300+ if (nr_allocated )
301+ release_pages (pages , nr_allocated );
302+ kvfree (pages );
303+ return - ENOMEM ;
304+ }
305+ mr -> pages = pages ;
306+ return 0 ;
307+ }
308+
276309int io_create_region (struct io_ring_ctx * ctx , struct io_mapped_region * mr ,
277310 struct io_uring_region_desc * reg )
278311{
@@ -283,9 +316,10 @@ int io_create_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr,
283316 return - EFAULT ;
284317 if (memchr_inv (& reg -> __resv , 0 , sizeof (reg -> __resv )))
285318 return - EINVAL ;
286- if (reg -> flags != IORING_MEM_REGION_TYPE_USER )
319+ if (reg -> flags & ~ IORING_MEM_REGION_TYPE_USER )
287320 return - EINVAL ;
288- if (!reg -> user_addr )
321+ /* user_addr should be set IFF it's a user memory backed region */
322+ if ((reg -> flags & IORING_MEM_REGION_TYPE_USER ) != !!reg -> user_addr )
289323 return - EFAULT ;
290324 if (!reg -> size || reg -> mmap_offset || reg -> id )
291325 return - EINVAL ;
@@ -304,7 +338,10 @@ int io_create_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr,
304338 }
305339 mr -> nr_pages = nr_pages ;
306340
307- ret = io_region_pin_pages (ctx , mr , reg );
341+ if (reg -> flags & IORING_MEM_REGION_TYPE_USER )
342+ ret = io_region_pin_pages (ctx , mr , reg );
343+ else
344+ ret = io_region_allocate_pages (ctx , mr , reg );
308345 if (ret )
309346 goto out_free ;
310347
0 commit comments