diff options
-rw-r--r-- | drivers/infiniband/core/uverbs.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 124 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 3 | ||||
-rw-r--r-- | include/rdma/ib_verbs.h | 5 | ||||
-rw-r--r-- | include/uapi/rdma/ib_user_verbs.h | 14 |
5 files changed, 103 insertions, 44 deletions
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 643c08a025a5..b716b0815644 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
@@ -258,5 +258,6 @@ IB_UVERBS_DECLARE_CMD(close_xrcd); | |||
258 | 258 | ||
259 | IB_UVERBS_DECLARE_EX_CMD(create_flow); | 259 | IB_UVERBS_DECLARE_EX_CMD(create_flow); |
260 | IB_UVERBS_DECLARE_EX_CMD(destroy_flow); | 260 | IB_UVERBS_DECLARE_EX_CMD(destroy_flow); |
261 | IB_UVERBS_DECLARE_EX_CMD(query_device); | ||
261 | 262 | ||
262 | #endif /* UVERBS_H */ | 263 | #endif /* UVERBS_H */ |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 5ba2a86aab6a..c7a43624c96b 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -378,6 +378,52 @@ err: | |||
378 | return ret; | 378 | return ret; |
379 | } | 379 | } |
380 | 380 | ||
381 | static void copy_query_dev_fields(struct ib_uverbs_file *file, | ||
382 | struct ib_uverbs_query_device_resp *resp, | ||
383 | struct ib_device_attr *attr) | ||
384 | { | ||
385 | resp->fw_ver = attr->fw_ver; | ||
386 | resp->node_guid = file->device->ib_dev->node_guid; | ||
387 | resp->sys_image_guid = attr->sys_image_guid; | ||
388 | resp->max_mr_size = attr->max_mr_size; | ||
389 | resp->page_size_cap = attr->page_size_cap; | ||
390 | resp->vendor_id = attr->vendor_id; | ||
391 | resp->vendor_part_id = attr->vendor_part_id; | ||
392 | resp->hw_ver = attr->hw_ver; | ||
393 | resp->max_qp = attr->max_qp; | ||
394 | resp->max_qp_wr = attr->max_qp_wr; | ||
395 | resp->device_cap_flags = attr->device_cap_flags; | ||
396 | resp->max_sge = attr->max_sge; | ||
397 | resp->max_sge_rd = attr->max_sge_rd; | ||
398 | resp->max_cq = attr->max_cq; | ||
399 | resp->max_cqe = attr->max_cqe; | ||
400 | resp->max_mr = attr->max_mr; | ||
401 | resp->max_pd = attr->max_pd; | ||
402 | resp->max_qp_rd_atom = attr->max_qp_rd_atom; | ||
403 | resp->max_ee_rd_atom = attr->max_ee_rd_atom; | ||
404 | resp->max_res_rd_atom = attr->max_res_rd_atom; | ||
405 | resp->max_qp_init_rd_atom = attr->max_qp_init_rd_atom; | ||
406 | resp->max_ee_init_rd_atom = attr->max_ee_init_rd_atom; | ||
407 | resp->atomic_cap = attr->atomic_cap; | ||
408 | resp->max_ee = attr->max_ee; | ||
409 | resp->max_rdd = attr->max_rdd; | ||
410 | resp->max_mw = attr->max_mw; | ||
411 | resp->max_raw_ipv6_qp = attr->max_raw_ipv6_qp; | ||
412 | resp->max_raw_ethy_qp = attr->max_raw_ethy_qp; | ||
413 | resp->max_mcast_grp = attr->max_mcast_grp; | ||
414 | resp->max_mcast_qp_attach = attr->max_mcast_qp_attach; | ||
415 | resp->max_total_mcast_qp_attach = attr->max_total_mcast_qp_attach; | ||
416 | resp->max_ah = attr->max_ah; | ||
417 | resp->max_fmr = attr->max_fmr; | ||
418 | resp->max_map_per_fmr = attr->max_map_per_fmr; | ||
419 | resp->max_srq = attr->max_srq; | ||
420 | resp->max_srq_wr = attr->max_srq_wr; | ||
421 | resp->max_srq_sge = attr->max_srq_sge; | ||
422 | resp->max_pkeys = attr->max_pkeys; | ||
423 | resp->local_ca_ack_delay = attr->local_ca_ack_delay; | ||
424 | resp->phys_port_cnt = file->device->ib_dev->phys_port_cnt; | ||
425 | } | ||
426 | |||
381 | ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file, | 427 | ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file, |
382 | const char __user *buf, | 428 | const char __user *buf, |
383 | int in_len, int out_len) | 429 | int in_len, int out_len) |
@@ -398,47 +444,7 @@ ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file, | |||
398 | return ret; | 444 | return ret; |
399 | 445 | ||
400 | memset(&resp, 0, sizeof resp); | 446 | memset(&resp, 0, sizeof resp); |
401 | 447 | copy_query_dev_fields(file, &resp, &attr); | |
402 | resp.fw_ver = attr.fw_ver; | ||
403 | resp.node_guid = file->device->ib_dev->node_guid; | ||
404 | resp.sys_image_guid = attr.sys_image_guid; | ||
405 | resp.max_mr_size = attr.max_mr_size; | ||
406 | resp.page_size_cap = attr.page_size_cap; | ||
407 | resp.vendor_id = attr.vendor_id; | ||
408 | resp.vendor_part_id = attr.vendor_part_id; | ||
409 | resp.hw_ver = attr.hw_ver; | ||
410 | resp.max_qp = attr.max_qp; | ||
411 | resp.max_qp_wr = attr.max_qp_wr; | ||
412 | resp.device_cap_flags = attr.device_cap_flags; | ||
413 | resp.max_sge = attr.max_sge; | ||
414 | resp.max_sge_rd = attr.max_sge_rd; | ||
415 | resp.max_cq = attr.max_cq; | ||
416 | resp.max_cqe = attr.max_cqe; | ||
417 | resp.max_mr = attr.max_mr; | ||
418 | resp.max_pd = attr.max_pd; | ||
419 | resp.max_qp_rd_atom = attr.max_qp_rd_atom; | ||
420 | resp.max_ee_rd_atom = attr.max_ee_rd_atom; | ||
421 | resp.max_res_rd_atom = attr.max_res_rd_atom; | ||
422 | resp.max_qp_init_rd_atom = attr.max_qp_init_rd_atom; | ||
423 | resp.max_ee_init_rd_atom = attr.max_ee_init_rd_atom; | ||
424 | resp.atomic_cap = attr.atomic_cap; | ||
425 | resp.max_ee = attr.max_ee; | ||
426 | resp.max_rdd = attr.max_rdd; | ||
427 | resp.max_mw = attr.max_mw; | ||
428 | resp.max_raw_ipv6_qp = attr.max_raw_ipv6_qp; | ||
429 | resp.max_raw_ethy_qp = attr.max_raw_ethy_qp; | ||
430 | resp.max_mcast_grp = attr.max_mcast_grp; | ||
431 | resp.max_mcast_qp_attach = attr.max_mcast_qp_attach; | ||
432 | resp.max_total_mcast_qp_attach = attr.max_total_mcast_qp_attach; | ||
433 | resp.max_ah = attr.max_ah; | ||
434 | resp.max_fmr = attr.max_fmr; | ||
435 | resp.max_map_per_fmr = attr.max_map_per_fmr; | ||
436 | resp.max_srq = attr.max_srq; | ||
437 | resp.max_srq_wr = attr.max_srq_wr; | ||
438 | resp.max_srq_sge = attr.max_srq_sge; | ||
439 | resp.max_pkeys = attr.max_pkeys; | ||
440 | resp.local_ca_ack_delay = attr.local_ca_ack_delay; | ||
441 | resp.phys_port_cnt = file->device->ib_dev->phys_port_cnt; | ||
442 | 448 | ||
443 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | 449 | if (copy_to_user((void __user *) (unsigned long) cmd.response, |
444 | &resp, sizeof resp)) | 450 | &resp, sizeof resp)) |
@@ -3253,3 +3259,39 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, | |||
3253 | 3259 | ||
3254 | return ret ? ret : in_len; | 3260 | return ret ? ret : in_len; |
3255 | } | 3261 | } |
3262 | |||
3263 | int ib_uverbs_ex_query_device(struct ib_uverbs_file *file, | ||
3264 | struct ib_udata *ucore, | ||
3265 | struct ib_udata *uhw) | ||
3266 | { | ||
3267 | struct ib_uverbs_ex_query_device_resp resp; | ||
3268 | struct ib_uverbs_ex_query_device cmd; | ||
3269 | struct ib_device_attr attr; | ||
3270 | struct ib_device *device; | ||
3271 | int err; | ||
3272 | |||
3273 | device = file->device->ib_dev; | ||
3274 | if (ucore->inlen < sizeof(cmd)) | ||
3275 | return -EINVAL; | ||
3276 | |||
3277 | err = ib_copy_from_udata(&cmd, ucore, sizeof(cmd)); | ||
3278 | if (err) | ||
3279 | return err; | ||
3280 | |||
3281 | if (cmd.reserved) | ||
3282 | return -EINVAL; | ||
3283 | |||
3284 | err = device->query_device(device, &attr); | ||
3285 | if (err) | ||
3286 | return err; | ||
3287 | |||
3288 | memset(&resp, 0, sizeof(resp)); | ||
3289 | copy_query_dev_fields(file, &resp.base, &attr); | ||
3290 | resp.comp_mask = 0; | ||
3291 | |||
3292 | err = ib_copy_to_udata(ucore, &resp, sizeof(resp)); | ||
3293 | if (err) | ||
3294 | return err; | ||
3295 | |||
3296 | return 0; | ||
3297 | } | ||
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 71ab83fde472..974025028790 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -122,7 +122,8 @@ static int (*uverbs_ex_cmd_table[])(struct ib_uverbs_file *file, | |||
122 | struct ib_udata *ucore, | 122 | struct ib_udata *ucore, |
123 | struct ib_udata *uhw) = { | 123 | struct ib_udata *uhw) = { |
124 | [IB_USER_VERBS_EX_CMD_CREATE_FLOW] = ib_uverbs_ex_create_flow, | 124 | [IB_USER_VERBS_EX_CMD_CREATE_FLOW] = ib_uverbs_ex_create_flow, |
125 | [IB_USER_VERBS_EX_CMD_DESTROY_FLOW] = ib_uverbs_ex_destroy_flow | 125 | [IB_USER_VERBS_EX_CMD_DESTROY_FLOW] = ib_uverbs_ex_destroy_flow, |
126 | [IB_USER_VERBS_EX_CMD_QUERY_DEVICE] = ib_uverbs_ex_query_device | ||
126 | }; | 127 | }; |
127 | 128 | ||
128 | static void ib_uverbs_add_one(struct ib_device *device); | 129 | static void ib_uverbs_add_one(struct ib_device *device); |
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 470a011d6fa4..97a999f9e4d8 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h | |||
@@ -1662,7 +1662,10 @@ static inline int ib_copy_from_udata(void *dest, struct ib_udata *udata, size_t | |||
1662 | 1662 | ||
1663 | static inline int ib_copy_to_udata(struct ib_udata *udata, void *src, size_t len) | 1663 | static inline int ib_copy_to_udata(struct ib_udata *udata, void *src, size_t len) |
1664 | { | 1664 | { |
1665 | return copy_to_user(udata->outbuf, src, len) ? -EFAULT : 0; | 1665 | size_t copy_sz; |
1666 | |||
1667 | copy_sz = min_t(size_t, len, udata->outlen); | ||
1668 | return copy_to_user(udata->outbuf, src, copy_sz) ? -EFAULT : 0; | ||
1666 | } | 1669 | } |
1667 | 1670 | ||
1668 | /** | 1671 | /** |
diff --git a/include/uapi/rdma/ib_user_verbs.h b/include/uapi/rdma/ib_user_verbs.h index 26daf55ff76e..e8a96071e352 100644 --- a/include/uapi/rdma/ib_user_verbs.h +++ b/include/uapi/rdma/ib_user_verbs.h | |||
@@ -90,8 +90,9 @@ enum { | |||
90 | }; | 90 | }; |
91 | 91 | ||
92 | enum { | 92 | enum { |
93 | IB_USER_VERBS_EX_CMD_QUERY_DEVICE = IB_USER_VERBS_CMD_QUERY_DEVICE, | ||
93 | IB_USER_VERBS_EX_CMD_CREATE_FLOW = IB_USER_VERBS_CMD_THRESHOLD, | 94 | IB_USER_VERBS_EX_CMD_CREATE_FLOW = IB_USER_VERBS_CMD_THRESHOLD, |
94 | IB_USER_VERBS_EX_CMD_DESTROY_FLOW | 95 | IB_USER_VERBS_EX_CMD_DESTROY_FLOW, |
95 | }; | 96 | }; |
96 | 97 | ||
97 | /* | 98 | /* |
@@ -201,6 +202,17 @@ struct ib_uverbs_query_device_resp { | |||
201 | __u8 reserved[4]; | 202 | __u8 reserved[4]; |
202 | }; | 203 | }; |
203 | 204 | ||
205 | struct ib_uverbs_ex_query_device { | ||
206 | __u32 comp_mask; | ||
207 | __u32 reserved; | ||
208 | }; | ||
209 | |||
210 | struct ib_uverbs_ex_query_device_resp { | ||
211 | struct ib_uverbs_query_device_resp base; | ||
212 | __u32 comp_mask; | ||
213 | __u32 reserved; | ||
214 | }; | ||
215 | |||
204 | struct ib_uverbs_query_port { | 216 | struct ib_uverbs_query_port { |
205 | __u64 response; | 217 | __u64 response; |
206 | __u8 port_num; | 218 | __u8 port_num; |