@@ -266,6 +266,122 @@ static int UVERBS_HANDLER(UVERBS_METHOD_REG_DMABUF_MR)(
266
266
return ret ;
267
267
}
268
268
269
+ static int UVERBS_HANDLER (UVERBS_METHOD_REG_MR )(
270
+ struct uverbs_attr_bundle * attrs )
271
+ {
272
+ struct ib_uobject * uobj =
273
+ uverbs_attr_get_uobject (attrs , UVERBS_ATTR_REG_MR_HANDLE );
274
+ struct ib_pd * pd =
275
+ uverbs_attr_get_obj (attrs , UVERBS_ATTR_REG_MR_PD_HANDLE );
276
+ u32 valid_access_flags = IB_ACCESS_SUPPORTED ;
277
+ u64 length , iova , fd_offset = 0 , addr = 0 ;
278
+ struct ib_device * ib_dev = pd -> device ;
279
+ bool has_fd_offset = false;
280
+ bool has_addr = false;
281
+ bool has_fd = false;
282
+ u32 access_flags ;
283
+ struct ib_mr * mr ;
284
+ int fd ;
285
+ int ret ;
286
+
287
+ ret = uverbs_copy_from (& iova , attrs , UVERBS_ATTR_REG_MR_IOVA );
288
+ if (ret )
289
+ return ret ;
290
+
291
+ ret = uverbs_copy_from (& length , attrs , UVERBS_ATTR_REG_MR_LENGTH );
292
+ if (ret )
293
+ return ret ;
294
+
295
+ if (uverbs_attr_is_valid (attrs , UVERBS_ATTR_REG_MR_ADDR )) {
296
+ ret = uverbs_copy_from (& addr , attrs ,
297
+ UVERBS_ATTR_REG_MR_ADDR );
298
+ if (ret )
299
+ return ret ;
300
+ has_addr = true;
301
+ }
302
+
303
+ if (uverbs_attr_is_valid (attrs , UVERBS_ATTR_REG_MR_FD_OFFSET )) {
304
+ ret = uverbs_copy_from (& fd_offset , attrs ,
305
+ UVERBS_ATTR_REG_MR_FD_OFFSET );
306
+ if (ret )
307
+ return ret ;
308
+ has_fd_offset = true;
309
+ }
310
+
311
+ if (uverbs_attr_is_valid (attrs , UVERBS_ATTR_REG_MR_FD )) {
312
+ ret = uverbs_get_raw_fd (& fd , attrs ,
313
+ UVERBS_ATTR_REG_MR_FD );
314
+ if (ret )
315
+ return ret ;
316
+ has_fd = true;
317
+ }
318
+
319
+ if (has_fd ) {
320
+ if (!ib_dev -> ops .reg_user_mr_dmabuf )
321
+ return - EOPNOTSUPP ;
322
+
323
+ /* FD requires offset and can't come with addr */
324
+ if (!has_fd_offset || has_addr )
325
+ return - EINVAL ;
326
+
327
+ if ((fd_offset & ~PAGE_MASK ) != (iova & ~PAGE_MASK ))
328
+ return - EINVAL ;
329
+
330
+ valid_access_flags = IB_ACCESS_LOCAL_WRITE |
331
+ IB_ACCESS_REMOTE_READ |
332
+ IB_ACCESS_REMOTE_WRITE |
333
+ IB_ACCESS_REMOTE_ATOMIC |
334
+ IB_ACCESS_RELAXED_ORDERING ;
335
+ } else {
336
+ if (!has_addr || has_fd_offset )
337
+ return - EINVAL ;
338
+
339
+ if ((addr & ~PAGE_MASK ) != (iova & ~PAGE_MASK ))
340
+ return - EINVAL ;
341
+ }
342
+
343
+ ret = uverbs_get_flags32 (& access_flags , attrs ,
344
+ UVERBS_ATTR_REG_MR_ACCESS_FLAGS ,
345
+ valid_access_flags );
346
+ if (ret )
347
+ return ret ;
348
+
349
+ ret = ib_check_mr_access (ib_dev , access_flags );
350
+ if (ret )
351
+ return ret ;
352
+
353
+ if (has_fd )
354
+ mr = pd -> device -> ops .reg_user_mr_dmabuf (pd , fd_offset , length , iova ,
355
+ fd , access_flags , attrs );
356
+ else
357
+ mr = pd -> device -> ops .reg_user_mr (pd , addr , length ,
358
+ iova , access_flags , NULL );
359
+
360
+ if (IS_ERR (mr ))
361
+ return PTR_ERR (mr );
362
+
363
+ mr -> device = pd -> device ;
364
+ mr -> pd = pd ;
365
+ mr -> type = IB_MR_TYPE_USER ;
366
+ mr -> uobject = uobj ;
367
+ atomic_inc (& pd -> usecnt );
368
+ rdma_restrack_new (& mr -> res , RDMA_RESTRACK_MR );
369
+ rdma_restrack_set_name (& mr -> res , NULL );
370
+ rdma_restrack_add (& mr -> res );
371
+ uobj -> object = mr ;
372
+
373
+ uverbs_finalize_uobj_create (attrs , UVERBS_ATTR_REG_MR_HANDLE );
374
+
375
+ ret = uverbs_copy_to (attrs , UVERBS_ATTR_REG_MR_RESP_LKEY ,
376
+ & mr -> lkey , sizeof (mr -> lkey ));
377
+ if (ret )
378
+ return ret ;
379
+
380
+ ret = uverbs_copy_to (attrs , UVERBS_ATTR_REG_MR_RESP_RKEY ,
381
+ & mr -> rkey , sizeof (mr -> rkey ));
382
+ return ret ;
383
+ }
384
+
269
385
DECLARE_UVERBS_NAMED_METHOD (
270
386
UVERBS_METHOD_ADVISE_MR ,
271
387
UVERBS_ATTR_IDR (UVERBS_ATTR_ADVISE_MR_PD_HANDLE ,
@@ -362,6 +478,40 @@ DECLARE_UVERBS_NAMED_METHOD(
362
478
UVERBS_ATTR_TYPE (u32 ),
363
479
UA_MANDATORY ));
364
480
481
+ DECLARE_UVERBS_NAMED_METHOD (
482
+ UVERBS_METHOD_REG_MR ,
483
+ UVERBS_ATTR_IDR (UVERBS_ATTR_REG_MR_HANDLE ,
484
+ UVERBS_OBJECT_MR ,
485
+ UVERBS_ACCESS_NEW ,
486
+ UA_MANDATORY ),
487
+ UVERBS_ATTR_IDR (UVERBS_ATTR_REG_MR_PD_HANDLE ,
488
+ UVERBS_OBJECT_PD ,
489
+ UVERBS_ACCESS_READ ,
490
+ UA_MANDATORY ),
491
+ UVERBS_ATTR_PTR_IN (UVERBS_ATTR_REG_MR_IOVA ,
492
+ UVERBS_ATTR_TYPE (u64 ),
493
+ UA_MANDATORY ),
494
+ UVERBS_ATTR_PTR_IN (UVERBS_ATTR_REG_MR_LENGTH ,
495
+ UVERBS_ATTR_TYPE (u64 ),
496
+ UA_MANDATORY ),
497
+ UVERBS_ATTR_FLAGS_IN (UVERBS_ATTR_REG_MR_ACCESS_FLAGS ,
498
+ enum ib_access_flags ,
499
+ UA_MANDATORY ),
500
+ UVERBS_ATTR_PTR_IN (UVERBS_ATTR_REG_MR_ADDR ,
501
+ UVERBS_ATTR_TYPE (u64 ),
502
+ UA_OPTIONAL ),
503
+ UVERBS_ATTR_PTR_IN (UVERBS_ATTR_REG_MR_FD_OFFSET ,
504
+ UVERBS_ATTR_TYPE (u64 ),
505
+ UA_OPTIONAL ),
506
+ UVERBS_ATTR_RAW_FD (UVERBS_ATTR_REG_MR_FD ,
507
+ UA_OPTIONAL ),
508
+ UVERBS_ATTR_PTR_OUT (UVERBS_ATTR_REG_MR_RESP_LKEY ,
509
+ UVERBS_ATTR_TYPE (u32 ),
510
+ UA_MANDATORY ),
511
+ UVERBS_ATTR_PTR_OUT (UVERBS_ATTR_REG_MR_RESP_RKEY ,
512
+ UVERBS_ATTR_TYPE (u32 ),
513
+ UA_MANDATORY ));
514
+
365
515
DECLARE_UVERBS_NAMED_METHOD_DESTROY (
366
516
UVERBS_METHOD_MR_DESTROY ,
367
517
UVERBS_ATTR_IDR (UVERBS_ATTR_DESTROY_MR_HANDLE ,
@@ -376,7 +526,8 @@ DECLARE_UVERBS_NAMED_OBJECT(
376
526
& UVERBS_METHOD (UVERBS_METHOD_DM_MR_REG ),
377
527
& UVERBS_METHOD (UVERBS_METHOD_MR_DESTROY ),
378
528
& UVERBS_METHOD (UVERBS_METHOD_QUERY_MR ),
379
- & UVERBS_METHOD (UVERBS_METHOD_REG_DMABUF_MR ));
529
+ & UVERBS_METHOD (UVERBS_METHOD_REG_DMABUF_MR ),
530
+ & UVERBS_METHOD (UVERBS_METHOD_REG_MR ));
380
531
381
532
const struct uapi_definition uverbs_def_obj_mr [] = {
382
533
UAPI_DEF_CHAIN_OBJ_TREE_NAMED (UVERBS_OBJECT_MR ,
0 commit comments