diff options
| -rw-r--r-- | drivers/infiniband/core/ucma.c | 76 | ||||
| -rw-r--r-- | include/uapi/rdma/rdma_user_cm.h | 22 |
2 files changed, 93 insertions, 5 deletions
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index e813774bf7a7..18bdccc0c2ec 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | #include <rdma/ib_marshall.h> | 47 | #include <rdma/ib_marshall.h> |
| 48 | #include <rdma/rdma_cm.h> | 48 | #include <rdma/rdma_cm.h> |
| 49 | #include <rdma/rdma_cm_ib.h> | 49 | #include <rdma/rdma_cm_ib.h> |
| 50 | #include <rdma/ib_addr.h> | ||
| 50 | 51 | ||
| 51 | MODULE_AUTHOR("Sean Hefty"); | 52 | MODULE_AUTHOR("Sean Hefty"); |
| 52 | MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access"); | 53 | MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access"); |
| @@ -649,7 +650,7 @@ static ssize_t ucma_query_route(struct ucma_file *file, | |||
| 649 | const char __user *inbuf, | 650 | const char __user *inbuf, |
| 650 | int in_len, int out_len) | 651 | int in_len, int out_len) |
| 651 | { | 652 | { |
| 652 | struct rdma_ucm_query_route cmd; | 653 | struct rdma_ucm_query cmd; |
| 653 | struct rdma_ucm_query_route_resp resp; | 654 | struct rdma_ucm_query_route_resp resp; |
| 654 | struct ucma_context *ctx; | 655 | struct ucma_context *ctx; |
| 655 | struct sockaddr *addr; | 656 | struct sockaddr *addr; |
| @@ -709,6 +710,76 @@ out: | |||
| 709 | return ret; | 710 | return ret; |
| 710 | } | 711 | } |
| 711 | 712 | ||
| 713 | static void ucma_query_device_addr(struct rdma_cm_id *cm_id, | ||
| 714 | struct rdma_ucm_query_addr_resp *resp) | ||
| 715 | { | ||
| 716 | if (!cm_id->device) | ||
| 717 | return; | ||
| 718 | |||
| 719 | resp->node_guid = (__force __u64) cm_id->device->node_guid; | ||
| 720 | resp->port_num = cm_id->port_num; | ||
| 721 | resp->pkey = (__force __u16) cpu_to_be16( | ||
| 722 | ib_addr_get_pkey(&cm_id->route.addr.dev_addr)); | ||
| 723 | } | ||
| 724 | |||
| 725 | static ssize_t ucma_query_addr(struct ucma_context *ctx, | ||
| 726 | void __user *response, int out_len) | ||
| 727 | { | ||
| 728 | struct rdma_ucm_query_addr_resp resp; | ||
| 729 | struct sockaddr *addr; | ||
| 730 | int ret = 0; | ||
| 731 | |||
| 732 | if (out_len < sizeof(resp)) | ||
| 733 | return -ENOSPC; | ||
| 734 | |||
| 735 | memset(&resp, 0, sizeof resp); | ||
| 736 | |||
| 737 | addr = (struct sockaddr *) &ctx->cm_id->route.addr.src_addr; | ||
| 738 | resp.src_size = rdma_addr_size(addr); | ||
| 739 | memcpy(&resp.src_addr, addr, resp.src_size); | ||
| 740 | |||
| 741 | addr = (struct sockaddr *) &ctx->cm_id->route.addr.dst_addr; | ||
| 742 | resp.dst_size = rdma_addr_size(addr); | ||
| 743 | memcpy(&resp.dst_addr, addr, resp.dst_size); | ||
| 744 | |||
| 745 | ucma_query_device_addr(ctx->cm_id, &resp); | ||
| 746 | |||
| 747 | if (copy_to_user(response, &resp, sizeof(resp))) | ||
| 748 | ret = -EFAULT; | ||
| 749 | |||
| 750 | return ret; | ||
| 751 | } | ||
| 752 | |||
| 753 | static ssize_t ucma_query(struct ucma_file *file, | ||
| 754 | const char __user *inbuf, | ||
| 755 | int in_len, int out_len) | ||
| 756 | { | ||
| 757 | struct rdma_ucm_query cmd; | ||
| 758 | struct ucma_context *ctx; | ||
| 759 | void __user *response; | ||
| 760 | int ret; | ||
| 761 | |||
| 762 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | ||
| 763 | return -EFAULT; | ||
| 764 | |||
| 765 | response = (void __user *)(unsigned long) cmd.response; | ||
| 766 | ctx = ucma_get_ctx(file, cmd.id); | ||
| 767 | if (IS_ERR(ctx)) | ||
| 768 | return PTR_ERR(ctx); | ||
| 769 | |||
| 770 | switch (cmd.option) { | ||
| 771 | case RDMA_USER_CM_QUERY_ADDR: | ||
| 772 | ret = ucma_query_addr(ctx, response, out_len); | ||
| 773 | break; | ||
| 774 | default: | ||
| 775 | ret = -ENOSYS; | ||
| 776 | break; | ||
| 777 | } | ||
| 778 | |||
| 779 | ucma_put_ctx(ctx); | ||
| 780 | return ret; | ||
| 781 | } | ||
| 782 | |||
| 712 | static void ucma_copy_conn_param(struct rdma_cm_id *id, | 783 | static void ucma_copy_conn_param(struct rdma_cm_id *id, |
| 713 | struct rdma_conn_param *dst, | 784 | struct rdma_conn_param *dst, |
| 714 | struct rdma_ucm_conn_param *src) | 785 | struct rdma_ucm_conn_param *src) |
| @@ -1241,7 +1312,8 @@ static ssize_t (*ucma_cmd_table[])(struct ucma_file *file, | |||
| 1241 | [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify, | 1312 | [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify, |
| 1242 | [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast, | 1313 | [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast, |
| 1243 | [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast, | 1314 | [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast, |
| 1244 | [RDMA_USER_CM_CMD_MIGRATE_ID] = ucma_migrate_id | 1315 | [RDMA_USER_CM_CMD_MIGRATE_ID] = ucma_migrate_id, |
| 1316 | [RDMA_USER_CM_CMD_QUERY] = ucma_query | ||
| 1245 | }; | 1317 | }; |
| 1246 | 1318 | ||
| 1247 | static ssize_t ucma_write(struct file *filp, const char __user *buf, | 1319 | static ssize_t ucma_write(struct file *filp, const char __user *buf, |
diff --git a/include/uapi/rdma/rdma_user_cm.h b/include/uapi/rdma/rdma_user_cm.h index 29de08f603ac..3ea7e7a4d54b 100644 --- a/include/uapi/rdma/rdma_user_cm.h +++ b/include/uapi/rdma/rdma_user_cm.h | |||
| @@ -61,7 +61,8 @@ enum { | |||
| 61 | RDMA_USER_CM_CMD_NOTIFY, | 61 | RDMA_USER_CM_CMD_NOTIFY, |
| 62 | RDMA_USER_CM_CMD_JOIN_MCAST, | 62 | RDMA_USER_CM_CMD_JOIN_MCAST, |
| 63 | RDMA_USER_CM_CMD_LEAVE_MCAST, | 63 | RDMA_USER_CM_CMD_LEAVE_MCAST, |
| 64 | RDMA_USER_CM_CMD_MIGRATE_ID | 64 | RDMA_USER_CM_CMD_MIGRATE_ID, |
| 65 | RDMA_USER_CM_CMD_QUERY | ||
| 65 | }; | 66 | }; |
| 66 | 67 | ||
| 67 | /* | 68 | /* |
| @@ -113,10 +114,14 @@ struct rdma_ucm_resolve_route { | |||
| 113 | __u32 timeout_ms; | 114 | __u32 timeout_ms; |
| 114 | }; | 115 | }; |
| 115 | 116 | ||
| 116 | struct rdma_ucm_query_route { | 117 | enum { |
| 118 | RDMA_USER_CM_QUERY_ADDR | ||
| 119 | }; | ||
| 120 | |||
| 121 | struct rdma_ucm_query { | ||
| 117 | __u64 response; | 122 | __u64 response; |
| 118 | __u32 id; | 123 | __u32 id; |
| 119 | __u32 reserved; | 124 | __u32 option; |
| 120 | }; | 125 | }; |
| 121 | 126 | ||
| 122 | struct rdma_ucm_query_route_resp { | 127 | struct rdma_ucm_query_route_resp { |
| @@ -129,6 +134,17 @@ struct rdma_ucm_query_route_resp { | |||
| 129 | __u8 reserved[3]; | 134 | __u8 reserved[3]; |
| 130 | }; | 135 | }; |
| 131 | 136 | ||
| 137 | struct rdma_ucm_query_addr_resp { | ||
| 138 | __u64 node_guid; | ||
| 139 | __u8 port_num; | ||
| 140 | __u8 reserved; | ||
| 141 | __u16 pkey; | ||
| 142 | __u16 src_size; | ||
| 143 | __u16 dst_size; | ||
| 144 | struct sockaddr_storage src_addr; | ||
| 145 | struct sockaddr_storage dst_addr; | ||
| 146 | }; | ||
| 147 | |||
| 132 | struct rdma_ucm_conn_param { | 148 | struct rdma_ucm_conn_param { |
| 133 | __u32 qp_num; | 149 | __u32 qp_num; |
| 134 | __u32 qkey; | 150 | __u32 qkey; |
