@@ -273,6 +273,39 @@ static int io_region_pin_pages(struct io_ring_ctx *ctx,
273
273
return 0 ;
274
274
}
275
275
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
+
276
309
int io_create_region (struct io_ring_ctx * ctx , struct io_mapped_region * mr ,
277
310
struct io_uring_region_desc * reg )
278
311
{
@@ -283,9 +316,10 @@ int io_create_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr,
283
316
return - EFAULT ;
284
317
if (memchr_inv (& reg -> __resv , 0 , sizeof (reg -> __resv )))
285
318
return - EINVAL ;
286
- if (reg -> flags != IORING_MEM_REGION_TYPE_USER )
319
+ if (reg -> flags & ~ IORING_MEM_REGION_TYPE_USER )
287
320
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 )
289
323
return - EFAULT ;
290
324
if (!reg -> size || reg -> mmap_offset || reg -> id )
291
325
return - EINVAL ;
@@ -304,7 +338,10 @@ int io_create_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr,
304
338
}
305
339
mr -> nr_pages = nr_pages ;
306
340
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 );
308
345
if (ret )
309
346
goto out_free ;
310
347
0 commit comments