diff options
Diffstat (limited to 'drivers/infiniband/core')
| -rw-r--r-- | drivers/infiniband/core/cma.c | 5 | ||||
| -rw-r--r-- | drivers/infiniband/core/core_priv.h | 1 | ||||
| -rw-r--r-- | drivers/infiniband/core/device.c | 13 | ||||
| -rw-r--r-- | drivers/infiniband/core/nldev.c | 4 | ||||
| -rw-r--r-- | drivers/infiniband/core/rdma_core.h | 2 | ||||
| -rw-r--r-- | drivers/infiniband/core/umem_odp.c | 3 | ||||
| -rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 11 | ||||
| -rw-r--r-- | drivers/infiniband/core/uverbs_ioctl.c | 62 | ||||
| -rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 26 | ||||
| -rw-r--r-- | drivers/infiniband/core/uverbs_std_types_device.c | 8 |
10 files changed, 102 insertions, 33 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 63a7cc00bae0..84f077b2b90a 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
| @@ -494,7 +494,10 @@ static void _cma_attach_to_dev(struct rdma_id_private *id_priv, | |||
| 494 | id_priv->id.route.addr.dev_addr.transport = | 494 | id_priv->id.route.addr.dev_addr.transport = |
| 495 | rdma_node_get_transport(cma_dev->device->node_type); | 495 | rdma_node_get_transport(cma_dev->device->node_type); |
| 496 | list_add_tail(&id_priv->list, &cma_dev->id_list); | 496 | list_add_tail(&id_priv->list, &cma_dev->id_list); |
| 497 | rdma_restrack_kadd(&id_priv->res); | 497 | if (id_priv->res.kern_name) |
| 498 | rdma_restrack_kadd(&id_priv->res); | ||
| 499 | else | ||
| 500 | rdma_restrack_uadd(&id_priv->res); | ||
| 498 | } | 501 | } |
| 499 | 502 | ||
| 500 | static void cma_attach_to_dev(struct rdma_id_private *id_priv, | 503 | static void cma_attach_to_dev(struct rdma_id_private *id_priv, |
diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h index 3cd830d52967..616734313f0c 100644 --- a/drivers/infiniband/core/core_priv.h +++ b/drivers/infiniband/core/core_priv.h | |||
| @@ -267,7 +267,6 @@ static inline int ib_mad_enforce_security(struct ib_mad_agent_private *map, | |||
| 267 | #endif | 267 | #endif |
| 268 | 268 | ||
| 269 | struct ib_device *ib_device_get_by_index(u32 ifindex); | 269 | struct ib_device *ib_device_get_by_index(u32 ifindex); |
| 270 | void ib_device_put(struct ib_device *device); | ||
| 271 | /* RDMA device netlink */ | 270 | /* RDMA device netlink */ |
| 272 | void nldev_init(void); | 271 | void nldev_init(void); |
| 273 | void nldev_exit(void); | 272 | void nldev_exit(void); |
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 8872453e26c0..238ec42778ef 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c | |||
| @@ -156,19 +156,26 @@ struct ib_device *ib_device_get_by_index(u32 index) | |||
| 156 | down_read(&lists_rwsem); | 156 | down_read(&lists_rwsem); |
| 157 | device = __ib_device_get_by_index(index); | 157 | device = __ib_device_get_by_index(index); |
| 158 | if (device) { | 158 | if (device) { |
| 159 | /* Do not return a device if unregistration has started. */ | 159 | if (!ib_device_try_get(device)) |
| 160 | if (!refcount_inc_not_zero(&device->refcount)) | ||
| 161 | device = NULL; | 160 | device = NULL; |
| 162 | } | 161 | } |
| 163 | up_read(&lists_rwsem); | 162 | up_read(&lists_rwsem); |
| 164 | return device; | 163 | return device; |
| 165 | } | 164 | } |
| 166 | 165 | ||
| 166 | /** | ||
| 167 | * ib_device_put - Release IB device reference | ||
| 168 | * @device: device whose reference to be released | ||
| 169 | * | ||
| 170 | * ib_device_put() releases reference to the IB device to allow it to be | ||
| 171 | * unregistered and eventually free. | ||
| 172 | */ | ||
| 167 | void ib_device_put(struct ib_device *device) | 173 | void ib_device_put(struct ib_device *device) |
| 168 | { | 174 | { |
| 169 | if (refcount_dec_and_test(&device->refcount)) | 175 | if (refcount_dec_and_test(&device->refcount)) |
| 170 | complete(&device->unreg_completion); | 176 | complete(&device->unreg_completion); |
| 171 | } | 177 | } |
| 178 | EXPORT_SYMBOL(ib_device_put); | ||
| 172 | 179 | ||
| 173 | static struct ib_device *__ib_device_get_by_name(const char *name) | 180 | static struct ib_device *__ib_device_get_by_name(const char *name) |
| 174 | { | 181 | { |
| @@ -303,7 +310,6 @@ struct ib_device *ib_alloc_device(size_t size) | |||
| 303 | rwlock_init(&device->client_data_lock); | 310 | rwlock_init(&device->client_data_lock); |
| 304 | INIT_LIST_HEAD(&device->client_data_list); | 311 | INIT_LIST_HEAD(&device->client_data_list); |
| 305 | INIT_LIST_HEAD(&device->port_list); | 312 | INIT_LIST_HEAD(&device->port_list); |
| 306 | refcount_set(&device->refcount, 1); | ||
| 307 | init_completion(&device->unreg_completion); | 313 | init_completion(&device->unreg_completion); |
| 308 | 314 | ||
| 309 | return device; | 315 | return device; |
| @@ -620,6 +626,7 @@ int ib_register_device(struct ib_device *device, const char *name, | |||
| 620 | goto cg_cleanup; | 626 | goto cg_cleanup; |
| 621 | } | 627 | } |
| 622 | 628 | ||
| 629 | refcount_set(&device->refcount, 1); | ||
| 623 | device->reg_state = IB_DEV_REGISTERED; | 630 | device->reg_state = IB_DEV_REGISTERED; |
| 624 | 631 | ||
| 625 | list_for_each_entry(client, &client_list, list) | 632 | list_for_each_entry(client, &client_list, list) |
diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c index e600fc23ae62..3c97a8b6bf1e 100644 --- a/drivers/infiniband/core/nldev.c +++ b/drivers/infiniband/core/nldev.c | |||
| @@ -584,10 +584,6 @@ static int fill_res_pd_entry(struct sk_buff *msg, struct netlink_callback *cb, | |||
| 584 | if (nla_put_u64_64bit(msg, RDMA_NLDEV_ATTR_RES_USECNT, | 584 | if (nla_put_u64_64bit(msg, RDMA_NLDEV_ATTR_RES_USECNT, |
| 585 | atomic_read(&pd->usecnt), RDMA_NLDEV_ATTR_PAD)) | 585 | atomic_read(&pd->usecnt), RDMA_NLDEV_ATTR_PAD)) |
| 586 | goto err; | 586 | goto err; |
| 587 | if ((pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY) && | ||
| 588 | nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_UNSAFE_GLOBAL_RKEY, | ||
| 589 | pd->unsafe_global_rkey)) | ||
| 590 | goto err; | ||
| 591 | 587 | ||
| 592 | if (fill_res_name_pid(msg, res)) | 588 | if (fill_res_name_pid(msg, res)) |
| 593 | goto err; | 589 | goto err; |
diff --git a/drivers/infiniband/core/rdma_core.h b/drivers/infiniband/core/rdma_core.h index be6b8e1257d0..69f8db66925e 100644 --- a/drivers/infiniband/core/rdma_core.h +++ b/drivers/infiniband/core/rdma_core.h | |||
| @@ -106,6 +106,8 @@ int uverbs_finalize_object(struct ib_uobject *uobj, | |||
| 106 | enum uverbs_obj_access access, | 106 | enum uverbs_obj_access access, |
| 107 | bool commit); | 107 | bool commit); |
| 108 | 108 | ||
| 109 | int uverbs_output_written(const struct uverbs_attr_bundle *bundle, size_t idx); | ||
| 110 | |||
| 109 | void setup_ufile_idr_uobject(struct ib_uverbs_file *ufile); | 111 | void setup_ufile_idr_uobject(struct ib_uverbs_file *ufile); |
| 110 | void release_ufile_idr_uobject(struct ib_uverbs_file *ufile); | 112 | void release_ufile_idr_uobject(struct ib_uverbs_file *ufile); |
| 111 | 113 | ||
diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c index a4ec43093cb3..acb882f279cb 100644 --- a/drivers/infiniband/core/umem_odp.c +++ b/drivers/infiniband/core/umem_odp.c | |||
| @@ -352,6 +352,8 @@ struct ib_umem_odp *ib_alloc_odp_umem(struct ib_ucontext_per_mm *per_mm, | |||
| 352 | umem->writable = 1; | 352 | umem->writable = 1; |
| 353 | umem->is_odp = 1; | 353 | umem->is_odp = 1; |
| 354 | odp_data->per_mm = per_mm; | 354 | odp_data->per_mm = per_mm; |
| 355 | umem->owning_mm = per_mm->mm; | ||
| 356 | mmgrab(umem->owning_mm); | ||
| 355 | 357 | ||
| 356 | mutex_init(&odp_data->umem_mutex); | 358 | mutex_init(&odp_data->umem_mutex); |
| 357 | init_completion(&odp_data->notifier_completion); | 359 | init_completion(&odp_data->notifier_completion); |
| @@ -384,6 +386,7 @@ struct ib_umem_odp *ib_alloc_odp_umem(struct ib_ucontext_per_mm *per_mm, | |||
| 384 | out_page_list: | 386 | out_page_list: |
| 385 | vfree(odp_data->page_list); | 387 | vfree(odp_data->page_list); |
| 386 | out_odp_data: | 388 | out_odp_data: |
| 389 | mmdrop(umem->owning_mm); | ||
| 387 | kfree(odp_data); | 390 | kfree(odp_data); |
| 388 | return ERR_PTR(ret); | 391 | return ERR_PTR(ret); |
| 389 | } | 392 | } |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 6b12cc5f97b2..3317300ab036 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
| @@ -60,6 +60,10 @@ static int uverbs_response(struct uverbs_attr_bundle *attrs, const void *resp, | |||
| 60 | { | 60 | { |
| 61 | int ret; | 61 | int ret; |
| 62 | 62 | ||
| 63 | if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CORE_OUT)) | ||
| 64 | return uverbs_copy_to_struct_or_zero( | ||
| 65 | attrs, UVERBS_ATTR_CORE_OUT, resp, resp_len); | ||
| 66 | |||
| 63 | if (copy_to_user(attrs->ucore.outbuf, resp, | 67 | if (copy_to_user(attrs->ucore.outbuf, resp, |
| 64 | min(attrs->ucore.outlen, resp_len))) | 68 | min(attrs->ucore.outlen, resp_len))) |
| 65 | return -EFAULT; | 69 | return -EFAULT; |
| @@ -1181,6 +1185,9 @@ static int ib_uverbs_poll_cq(struct uverbs_attr_bundle *attrs) | |||
| 1181 | goto out_put; | 1185 | goto out_put; |
| 1182 | } | 1186 | } |
| 1183 | 1187 | ||
| 1188 | if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CORE_OUT)) | ||
| 1189 | ret = uverbs_output_written(attrs, UVERBS_ATTR_CORE_OUT); | ||
| 1190 | |||
| 1184 | ret = 0; | 1191 | ret = 0; |
| 1185 | 1192 | ||
| 1186 | out_put: | 1193 | out_put: |
| @@ -2012,8 +2019,10 @@ static int ib_uverbs_post_send(struct uverbs_attr_bundle *attrs) | |||
| 2012 | return -ENOMEM; | 2019 | return -ENOMEM; |
| 2013 | 2020 | ||
| 2014 | qp = uobj_get_obj_read(qp, UVERBS_OBJECT_QP, cmd.qp_handle, attrs); | 2021 | qp = uobj_get_obj_read(qp, UVERBS_OBJECT_QP, cmd.qp_handle, attrs); |
| 2015 | if (!qp) | 2022 | if (!qp) { |
| 2023 | ret = -EINVAL; | ||
| 2016 | goto out; | 2024 | goto out; |
| 2025 | } | ||
| 2017 | 2026 | ||
| 2018 | is_ud = qp->qp_type == IB_QPT_UD; | 2027 | is_ud = qp->qp_type == IB_QPT_UD; |
| 2019 | sg_ind = 0; | 2028 | sg_ind = 0; |
diff --git a/drivers/infiniband/core/uverbs_ioctl.c b/drivers/infiniband/core/uverbs_ioctl.c index 8c81ff698052..0ca04d224015 100644 --- a/drivers/infiniband/core/uverbs_ioctl.c +++ b/drivers/infiniband/core/uverbs_ioctl.c | |||
| @@ -144,6 +144,21 @@ static bool uverbs_is_attr_cleared(const struct ib_uverbs_attr *uattr, | |||
| 144 | 0, uattr->len - len); | 144 | 0, uattr->len - len); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | static int uverbs_set_output(const struct uverbs_attr_bundle *bundle, | ||
| 148 | const struct uverbs_attr *attr) | ||
| 149 | { | ||
| 150 | struct bundle_priv *pbundle = | ||
| 151 | container_of(bundle, struct bundle_priv, bundle); | ||
| 152 | u16 flags; | ||
| 153 | |||
| 154 | flags = pbundle->uattrs[attr->ptr_attr.uattr_idx].flags | | ||
| 155 | UVERBS_ATTR_F_VALID_OUTPUT; | ||
| 156 | if (put_user(flags, | ||
| 157 | &pbundle->user_attrs[attr->ptr_attr.uattr_idx].flags)) | ||
| 158 | return -EFAULT; | ||
| 159 | return 0; | ||
| 160 | } | ||
| 161 | |||
| 147 | static int uverbs_process_idrs_array(struct bundle_priv *pbundle, | 162 | static int uverbs_process_idrs_array(struct bundle_priv *pbundle, |
| 148 | const struct uverbs_api_attr *attr_uapi, | 163 | const struct uverbs_api_attr *attr_uapi, |
| 149 | struct uverbs_objs_arr_attr *attr, | 164 | struct uverbs_objs_arr_attr *attr, |
| @@ -456,6 +471,19 @@ static int ib_uverbs_run_method(struct bundle_priv *pbundle, | |||
| 456 | } | 471 | } |
| 457 | 472 | ||
| 458 | /* | 473 | /* |
| 474 | * Until the drivers are revised to use the bundle directly we have to | ||
| 475 | * assume that the driver wrote to its UHW_OUT and flag userspace | ||
| 476 | * appropriately. | ||
| 477 | */ | ||
| 478 | if (!ret && pbundle->method_elm->has_udata) { | ||
| 479 | const struct uverbs_attr *attr = | ||
| 480 | uverbs_attr_get(&pbundle->bundle, UVERBS_ATTR_UHW_OUT); | ||
| 481 | |||
| 482 | if (!IS_ERR(attr)) | ||
| 483 | ret = uverbs_set_output(&pbundle->bundle, attr); | ||
| 484 | } | ||
| 485 | |||
| 486 | /* | ||
| 459 | * EPROTONOSUPPORT is ONLY to be returned if the ioctl framework can | 487 | * EPROTONOSUPPORT is ONLY to be returned if the ioctl framework can |
| 460 | * not invoke the method because the request is not supported. No | 488 | * not invoke the method because the request is not supported. No |
| 461 | * other cases should return this code. | 489 | * other cases should return this code. |
| @@ -706,10 +734,7 @@ void uverbs_fill_udata(struct uverbs_attr_bundle *bundle, | |||
| 706 | int uverbs_copy_to(const struct uverbs_attr_bundle *bundle, size_t idx, | 734 | int uverbs_copy_to(const struct uverbs_attr_bundle *bundle, size_t idx, |
| 707 | const void *from, size_t size) | 735 | const void *from, size_t size) |
| 708 | { | 736 | { |
| 709 | struct bundle_priv *pbundle = | ||
| 710 | container_of(bundle, struct bundle_priv, bundle); | ||
| 711 | const struct uverbs_attr *attr = uverbs_attr_get(bundle, idx); | 737 | const struct uverbs_attr *attr = uverbs_attr_get(bundle, idx); |
| 712 | u16 flags; | ||
| 713 | size_t min_size; | 738 | size_t min_size; |
| 714 | 739 | ||
| 715 | if (IS_ERR(attr)) | 740 | if (IS_ERR(attr)) |
| @@ -719,16 +744,25 @@ int uverbs_copy_to(const struct uverbs_attr_bundle *bundle, size_t idx, | |||
| 719 | if (copy_to_user(u64_to_user_ptr(attr->ptr_attr.data), from, min_size)) | 744 | if (copy_to_user(u64_to_user_ptr(attr->ptr_attr.data), from, min_size)) |
| 720 | return -EFAULT; | 745 | return -EFAULT; |
| 721 | 746 | ||
| 722 | flags = pbundle->uattrs[attr->ptr_attr.uattr_idx].flags | | 747 | return uverbs_set_output(bundle, attr); |
| 723 | UVERBS_ATTR_F_VALID_OUTPUT; | ||
| 724 | if (put_user(flags, | ||
| 725 | &pbundle->user_attrs[attr->ptr_attr.uattr_idx].flags)) | ||
| 726 | return -EFAULT; | ||
| 727 | |||
| 728 | return 0; | ||
| 729 | } | 748 | } |
| 730 | EXPORT_SYMBOL(uverbs_copy_to); | 749 | EXPORT_SYMBOL(uverbs_copy_to); |
| 731 | 750 | ||
| 751 | |||
| 752 | /* | ||
| 753 | * This is only used if the caller has directly used copy_to_use to write the | ||
| 754 | * data. It signals to user space that the buffer is filled in. | ||
| 755 | */ | ||
| 756 | int uverbs_output_written(const struct uverbs_attr_bundle *bundle, size_t idx) | ||
| 757 | { | ||
| 758 | const struct uverbs_attr *attr = uverbs_attr_get(bundle, idx); | ||
| 759 | |||
| 760 | if (IS_ERR(attr)) | ||
| 761 | return PTR_ERR(attr); | ||
| 762 | |||
| 763 | return uverbs_set_output(bundle, attr); | ||
| 764 | } | ||
| 765 | |||
| 732 | int _uverbs_get_const(s64 *to, const struct uverbs_attr_bundle *attrs_bundle, | 766 | int _uverbs_get_const(s64 *to, const struct uverbs_attr_bundle *attrs_bundle, |
| 733 | size_t idx, s64 lower_bound, u64 upper_bound, | 767 | size_t idx, s64 lower_bound, u64 upper_bound, |
| 734 | s64 *def_val) | 768 | s64 *def_val) |
| @@ -757,8 +791,10 @@ int uverbs_copy_to_struct_or_zero(const struct uverbs_attr_bundle *bundle, | |||
| 757 | { | 791 | { |
| 758 | const struct uverbs_attr *attr = uverbs_attr_get(bundle, idx); | 792 | const struct uverbs_attr *attr = uverbs_attr_get(bundle, idx); |
| 759 | 793 | ||
| 760 | if (clear_user(u64_to_user_ptr(attr->ptr_attr.data), | 794 | if (size < attr->ptr_attr.len) { |
| 761 | attr->ptr_attr.len)) | 795 | if (clear_user(u64_to_user_ptr(attr->ptr_attr.data) + size, |
| 762 | return -EFAULT; | 796 | attr->ptr_attr.len - size)) |
| 797 | return -EFAULT; | ||
| 798 | } | ||
| 763 | return uverbs_copy_to(bundle, idx, from, size); | 799 | return uverbs_copy_to(bundle, idx, from, size); |
| 764 | } | 800 | } |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index fb0007aa0c27..5f366838b7ff 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
| @@ -204,6 +204,9 @@ void ib_uverbs_release_file(struct kref *ref) | |||
| 204 | if (atomic_dec_and_test(&file->device->refcount)) | 204 | if (atomic_dec_and_test(&file->device->refcount)) |
| 205 | ib_uverbs_comp_dev(file->device); | 205 | ib_uverbs_comp_dev(file->device); |
| 206 | 206 | ||
| 207 | if (file->async_file) | ||
| 208 | kref_put(&file->async_file->ref, | ||
| 209 | ib_uverbs_release_async_event_file); | ||
| 207 | put_device(&file->device->dev); | 210 | put_device(&file->device->dev); |
| 208 | kfree(file); | 211 | kfree(file); |
| 209 | } | 212 | } |
| @@ -690,6 +693,7 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, | |||
| 690 | 693 | ||
| 691 | buf += sizeof(hdr); | 694 | buf += sizeof(hdr); |
| 692 | 695 | ||
| 696 | memset(bundle.attr_present, 0, sizeof(bundle.attr_present)); | ||
| 693 | bundle.ufile = file; | 697 | bundle.ufile = file; |
| 694 | if (!method_elm->is_ex) { | 698 | if (!method_elm->is_ex) { |
| 695 | size_t in_len = hdr.in_words * 4 - sizeof(hdr); | 699 | size_t in_len = hdr.in_words * 4 - sizeof(hdr); |
| @@ -963,11 +967,19 @@ void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile) | |||
| 963 | 967 | ||
| 964 | /* Get an arbitrary mm pointer that hasn't been cleaned yet */ | 968 | /* Get an arbitrary mm pointer that hasn't been cleaned yet */ |
| 965 | mutex_lock(&ufile->umap_lock); | 969 | mutex_lock(&ufile->umap_lock); |
| 966 | if (!list_empty(&ufile->umaps)) { | 970 | while (!list_empty(&ufile->umaps)) { |
| 967 | mm = list_first_entry(&ufile->umaps, | 971 | int ret; |
| 968 | struct rdma_umap_priv, list) | 972 | |
| 969 | ->vma->vm_mm; | 973 | priv = list_first_entry(&ufile->umaps, |
| 970 | mmget(mm); | 974 | struct rdma_umap_priv, list); |
| 975 | mm = priv->vma->vm_mm; | ||
| 976 | ret = mmget_not_zero(mm); | ||
| 977 | if (!ret) { | ||
| 978 | list_del_init(&priv->list); | ||
| 979 | mm = NULL; | ||
| 980 | continue; | ||
| 981 | } | ||
| 982 | break; | ||
| 971 | } | 983 | } |
| 972 | mutex_unlock(&ufile->umap_lock); | 984 | mutex_unlock(&ufile->umap_lock); |
| 973 | if (!mm) | 985 | if (!mm) |
| @@ -1095,10 +1107,6 @@ static int ib_uverbs_close(struct inode *inode, struct file *filp) | |||
| 1095 | list_del_init(&file->list); | 1107 | list_del_init(&file->list); |
| 1096 | mutex_unlock(&file->device->lists_mutex); | 1108 | mutex_unlock(&file->device->lists_mutex); |
| 1097 | 1109 | ||
| 1098 | if (file->async_file) | ||
| 1099 | kref_put(&file->async_file->ref, | ||
| 1100 | ib_uverbs_release_async_event_file); | ||
| 1101 | |||
| 1102 | kref_put(&file->ref, ib_uverbs_release_file); | 1110 | kref_put(&file->ref, ib_uverbs_release_file); |
| 1103 | 1111 | ||
| 1104 | return 0; | 1112 | return 0; |
diff --git a/drivers/infiniband/core/uverbs_std_types_device.c b/drivers/infiniband/core/uverbs_std_types_device.c index 5030ec480370..2a3f2f01028d 100644 --- a/drivers/infiniband/core/uverbs_std_types_device.c +++ b/drivers/infiniband/core/uverbs_std_types_device.c | |||
| @@ -168,12 +168,18 @@ void copy_port_attr_to_resp(struct ib_port_attr *attr, | |||
| 168 | static int UVERBS_HANDLER(UVERBS_METHOD_QUERY_PORT)( | 168 | static int UVERBS_HANDLER(UVERBS_METHOD_QUERY_PORT)( |
| 169 | struct uverbs_attr_bundle *attrs) | 169 | struct uverbs_attr_bundle *attrs) |
| 170 | { | 170 | { |
| 171 | struct ib_device *ib_dev = attrs->ufile->device->ib_dev; | 171 | struct ib_device *ib_dev; |
| 172 | struct ib_port_attr attr = {}; | 172 | struct ib_port_attr attr = {}; |
| 173 | struct ib_uverbs_query_port_resp_ex resp = {}; | 173 | struct ib_uverbs_query_port_resp_ex resp = {}; |
| 174 | struct ib_ucontext *ucontext; | ||
| 174 | int ret; | 175 | int ret; |
| 175 | u8 port_num; | 176 | u8 port_num; |
| 176 | 177 | ||
| 178 | ucontext = ib_uverbs_get_ucontext(attrs); | ||
| 179 | if (IS_ERR(ucontext)) | ||
| 180 | return PTR_ERR(ucontext); | ||
| 181 | ib_dev = ucontext->device; | ||
| 182 | |||
| 177 | /* FIXME: Extend the UAPI_DEF_OBJ_NEEDS_FN stuff.. */ | 183 | /* FIXME: Extend the UAPI_DEF_OBJ_NEEDS_FN stuff.. */ |
| 178 | if (!ib_dev->ops.query_port) | 184 | if (!ib_dev->ops.query_port) |
| 179 | return -EOPNOTSUPP; | 185 | return -EOPNOTSUPP; |
