Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IB: ucontext should be set properly for all cmd & ioctl paths

the Attempt to use the below commit to initialize the ucontext for the
uobject destroy path has shown that the below commit is incomplete.

Parts were reverted and the ucontext set up in the uverbs_attr_bundle was
moved to rdma_lookup_get_uobject which is called from the uobj_get_XXX
macros and rdma_alloc_begin_uobject which is called when uobject is
created.

Fixes: 3d9dfd060391 ("IB/uverbs: Add ib_ucontext to uverbs_attr_bundle sent from ioctl and cmd flows")
Signed-off-by: Shamir Rabinovitch <shamir.rabinovitch@oracle.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>

authored by

Shamir Rabinovitch and committed by
Jason Gunthorpe
70f06b26 fae7a699

+44 -81
+21 -49
drivers/infiniband/core/rdma_core.c
··· 224 224 * uverbs_put_destroy. 225 225 */ 226 226 struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj, 227 - u32 id, 228 - const struct uverbs_attr_bundle *attrs) 227 + u32 id, struct uverbs_attr_bundle *attrs) 229 228 { 230 229 struct ib_uobject *uobj; 231 230 int ret; 232 231 233 232 uobj = rdma_lookup_get_uobject(obj, attrs->ufile, id, 234 - UVERBS_LOOKUP_DESTROY); 233 + UVERBS_LOOKUP_DESTROY, attrs); 235 234 if (IS_ERR(uobj)) 236 235 return uobj; 237 236 ··· 248 249 * (negative errno on failure). For use by callers that do not need the uobj. 249 250 */ 250 251 int __uobj_perform_destroy(const struct uverbs_api_object *obj, u32 id, 251 - const struct uverbs_attr_bundle *attrs) 252 + struct uverbs_attr_bundle *attrs) 252 253 { 253 254 struct ib_uobject *uobj; 254 255 ··· 392 393 393 394 struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_api_object *obj, 394 395 struct ib_uverbs_file *ufile, s64 id, 395 - enum rdma_lookup_mode mode) 396 + enum rdma_lookup_mode mode, 397 + struct uverbs_attr_bundle *attrs) 396 398 { 397 399 struct ib_uobject *uobj; 398 400 int ret; ··· 431 431 ret = uverbs_try_lock_object(uobj, mode); 432 432 if (ret) 433 433 goto free; 434 + if (attrs) 435 + attrs->context = uobj->context; 434 436 435 437 return uobj; 436 438 free: 437 439 uobj->uapi_object->type_class->lookup_put(uobj, mode); 438 440 uverbs_uobject_put(uobj); 439 441 return ERR_PTR(ret); 440 - } 441 - struct ib_uobject *_uobj_get_read(enum uverbs_default_objects type, 442 - u32 object_id, 443 - struct uverbs_attr_bundle *attrs) 444 - { 445 - struct ib_uobject *uobj; 446 - 447 - uobj = rdma_lookup_get_uobject(uobj_get_type(attrs, type), attrs->ufile, 448 - object_id, UVERBS_LOOKUP_READ); 449 - if (IS_ERR(uobj)) 450 - return uobj; 451 - 452 - attrs->context = uobj->context; 453 - 454 - return uobj; 455 - } 456 - 457 - struct ib_uobject *_uobj_get_write(enum uverbs_default_objects type, 458 - u32 object_id, 459 - struct uverbs_attr_bundle *attrs) 460 - { 461 - struct ib_uobject *uobj; 462 - 463 - uobj = rdma_lookup_get_uobject(uobj_get_type(attrs, type), attrs->ufile, 464 - object_id, UVERBS_LOOKUP_WRITE); 465 - 466 - if (IS_ERR(uobj)) 467 - return uobj; 468 - 469 - attrs->context = uobj->context; 470 - 471 - return uobj; 472 442 } 473 443 474 444 static struct ib_uobject * ··· 496 526 } 497 527 498 528 struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_api_object *obj, 499 - struct ib_uverbs_file *ufile) 529 + struct ib_uverbs_file *ufile, 530 + struct uverbs_attr_bundle *attrs) 500 531 { 501 532 struct ib_uobject *ret; 502 533 ··· 517 546 up_read(&ufile->hw_destroy_rwsem); 518 547 return ret; 519 548 } 549 + if (attrs) 550 + attrs->context = ret->context; 520 551 return ret; 521 552 } 522 553 ··· 940 967 EXPORT_SYMBOL(uverbs_fd_class); 941 968 942 969 struct ib_uobject * 943 - uverbs_get_uobject_from_file(u16 object_id, 944 - struct ib_uverbs_file *ufile, 945 - enum uverbs_obj_access access, s64 id) 970 + uverbs_get_uobject_from_file(u16 object_id, enum uverbs_obj_access access, 971 + s64 id, struct uverbs_attr_bundle *attrs) 946 972 { 947 973 const struct uverbs_api_object *obj = 948 - uapi_get_object(ufile->device->uapi, object_id); 974 + uapi_get_object(attrs->ufile->device->uapi, object_id); 949 975 950 976 switch (access) { 951 977 case UVERBS_ACCESS_READ: 952 - return rdma_lookup_get_uobject(obj, ufile, id, 953 - UVERBS_LOOKUP_READ); 978 + return rdma_lookup_get_uobject(obj, attrs->ufile, id, 979 + UVERBS_LOOKUP_READ, attrs); 954 980 case UVERBS_ACCESS_DESTROY: 955 981 /* Actual destruction is done inside uverbs_handle_method */ 956 - return rdma_lookup_get_uobject(obj, ufile, id, 957 - UVERBS_LOOKUP_DESTROY); 982 + return rdma_lookup_get_uobject(obj, attrs->ufile, id, 983 + UVERBS_LOOKUP_DESTROY, attrs); 958 984 case UVERBS_ACCESS_WRITE: 959 - return rdma_lookup_get_uobject(obj, ufile, id, 960 - UVERBS_LOOKUP_WRITE); 985 + return rdma_lookup_get_uobject(obj, attrs->ufile, id, 986 + UVERBS_LOOKUP_WRITE, attrs); 961 987 case UVERBS_ACCESS_NEW: 962 - return rdma_alloc_begin_uobject(obj, ufile); 988 + return rdma_alloc_begin_uobject(obj, attrs->ufile, attrs); 963 989 default: 964 990 WARN_ON(true); 965 991 return ERR_PTR(-EOPNOTSUPP);
+2 -3
drivers/infiniband/core/rdma_core.h
··· 83 83 * uverbs_finalize_objects are called. 84 84 */ 85 85 struct ib_uobject * 86 - uverbs_get_uobject_from_file(u16 object_id, 87 - struct ib_uverbs_file *ufile, 88 - enum uverbs_obj_access access, s64 id); 86 + uverbs_get_uobject_from_file(u16 object_id, enum uverbs_obj_access access, 87 + s64 id, struct uverbs_attr_bundle *attrs); 89 88 90 89 /* 91 90 * Note that certain finalize stages could return a status:
+1 -1
drivers/infiniband/core/uverbs_cmd.c
··· 175 175 } 176 176 177 177 static struct ib_uverbs_completion_event_file * 178 - _ib_uverbs_lookup_comp_file(s32 fd, const struct uverbs_attr_bundle *attrs) 178 + _ib_uverbs_lookup_comp_file(s32 fd, struct uverbs_attr_bundle *attrs) 179 179 { 180 180 struct ib_uobject *uobj = ufd_get_read(UVERBS_OBJECT_COMP_CHANNEL, 181 181 fd, attrs);
+4 -8
drivers/infiniband/core/uverbs_ioctl.c
··· 207 207 208 208 for (i = 0; i != array_len; i++) { 209 209 attr->uobjects[i] = uverbs_get_uobject_from_file( 210 - spec->u2.objs_arr.obj_type, pbundle->bundle.ufile, 211 - spec->u2.objs_arr.access, idr_vals[i]); 210 + spec->u2.objs_arr.obj_type, spec->u2.objs_arr.access, 211 + idr_vals[i], &pbundle->bundle); 212 212 if (IS_ERR(attr->uobjects[i])) { 213 213 ret = PTR_ERR(attr->uobjects[i]); 214 214 break; 215 215 } 216 - pbundle->bundle.context = attr->uobjects[i]->context; 217 216 } 218 217 219 218 attr->len = i; ··· 324 325 * IDR implementation today rejects negative IDs 325 326 */ 326 327 o_attr->uobject = uverbs_get_uobject_from_file( 327 - spec->u.obj.obj_type, 328 - pbundle->bundle.ufile, 329 - spec->u.obj.access, 330 - uattr->data_s64); 328 + spec->u.obj.obj_type, spec->u.obj.access, 329 + uattr->data_s64, &pbundle->bundle); 331 330 if (IS_ERR(o_attr->uobject)) 332 331 return PTR_ERR(o_attr->uobject); 333 - pbundle->bundle.context = o_attr->uobject->context; 334 332 __set_bit(attr_bkey, pbundle->uobj_finalize); 335 333 336 334 if (spec->u.obj.access == UVERBS_ACCESS_NEW) {
+12 -18
include/rdma/uverbs_std_types.h
··· 48 48 #define uobj_get_type(_attrs, _object) \ 49 49 uapi_get_object((_attrs)->ufile->device->uapi, _object) 50 50 51 - struct ib_uobject *_uobj_get_read(enum uverbs_default_objects type, 52 - u32 object_id, 53 - struct uverbs_attr_bundle *attrs); 54 - 55 51 #define uobj_get_read(_type, _id, _attrs) \ 56 - _uobj_get_read(_type, _uobj_check_id(_id), _attrs) 52 + rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \ 53 + _uobj_check_id(_id), UVERBS_LOOKUP_READ, \ 54 + _attrs) 57 55 58 56 #define ufd_get_read(_type, _fdnum, _attrs) \ 59 57 rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \ 60 58 (_fdnum)*typecheck(s32, _fdnum), \ 61 - UVERBS_LOOKUP_READ) 59 + UVERBS_LOOKUP_READ, _attrs) 62 60 63 61 static inline void *_uobj_get_obj_read(struct ib_uobject *uobj) 64 62 { ··· 68 70 ((struct ib_##_object *)_uobj_get_obj_read( \ 69 71 uobj_get_read(_type, _id, _attrs))) 70 72 71 - struct ib_uobject *_uobj_get_write(enum uverbs_default_objects type, 72 - u32 object_id, 73 - struct uverbs_attr_bundle *attrs); 74 - 75 73 #define uobj_get_write(_type, _id, _attrs) \ 76 - _uobj_get_write(_type, _uobj_check_id(_id), _attrs) 74 + rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \ 75 + _uobj_check_id(_id), UVERBS_LOOKUP_WRITE, \ 76 + _attrs) 77 77 78 78 int __uobj_perform_destroy(const struct uverbs_api_object *obj, u32 id, 79 - const struct uverbs_attr_bundle *attrs); 79 + struct uverbs_attr_bundle *attrs); 80 80 #define uobj_perform_destroy(_type, _id, _attrs) \ 81 81 __uobj_perform_destroy(uobj_get_type(_attrs, _type), \ 82 82 _uobj_check_id(_id), _attrs) 83 83 84 84 struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj, 85 - u32 id, 86 - const struct uverbs_attr_bundle *attrs); 85 + u32 id, struct uverbs_attr_bundle *attrs); 87 86 88 87 #define uobj_get_destroy(_type, _id, _attrs) \ 89 88 __uobj_get_destroy(uobj_get_type(_attrs, _type), _uobj_check_id(_id), \ ··· 122 127 __uobj_alloc(const struct uverbs_api_object *obj, 123 128 struct uverbs_attr_bundle *attrs, struct ib_device **ib_dev) 124 129 { 125 - struct ib_uobject *uobj = rdma_alloc_begin_uobject(obj, attrs->ufile); 130 + struct ib_uobject *uobj = 131 + rdma_alloc_begin_uobject(obj, attrs->ufile, attrs); 126 132 127 - if (!IS_ERR(uobj)) { 133 + if (!IS_ERR(uobj)) 128 134 *ib_dev = uobj->context->device; 129 - attrs->context = uobj->context; 130 - } 131 135 return uobj; 132 136 } 133 137
+4 -2
include/rdma/uverbs_types.h
··· 131 131 132 132 struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_api_object *obj, 133 133 struct ib_uverbs_file *ufile, s64 id, 134 - enum rdma_lookup_mode mode); 134 + enum rdma_lookup_mode mode, 135 + struct uverbs_attr_bundle *attrs); 135 136 void rdma_lookup_put_uobject(struct ib_uobject *uobj, 136 137 enum rdma_lookup_mode mode); 137 138 struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_api_object *obj, 138 - struct ib_uverbs_file *ufile); 139 + struct ib_uverbs_file *ufile, 140 + struct uverbs_attr_bundle *attrs); 139 141 void rdma_alloc_abort_uobject(struct ib_uobject *uobj); 140 142 int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj); 141 143