diff options
author | Sean Hefty <sean.hefty@intel.com> | 2006-06-17 23:37:27 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2006-06-17 23:37:27 -0400 |
commit | 6a9af2e18a5c6ebcf8283309d20ac0e9fa35e346 (patch) | |
tree | 550bf42e4fff6b89160224fdf130085fefd0fe2e /drivers/infiniband | |
parent | 4e56ea794ec8636991e21942fc2e0d071ea8ee1d (diff) |
IB: common handling for marshalling parameters to/from userspace
Provide common handling for marshalling data between userspace clients
and kernel InfiniBand drivers.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/Makefile | 3 | ||||
-rw-r--r-- | drivers/infiniband/core/ucm.c | 131 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_marshall.c | 138 |
3 files changed, 154 insertions, 118 deletions
diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile index ec3353f24b27..a56bf9c994f6 100644 --- a/drivers/infiniband/core/Makefile +++ b/drivers/infiniband/core/Makefile | |||
@@ -16,4 +16,5 @@ ib_umad-y := user_mad.o | |||
16 | 16 | ||
17 | ib_ucm-y := ucm.o | 17 | ib_ucm-y := ucm.o |
18 | 18 | ||
19 | ib_uverbs-y := uverbs_main.o uverbs_cmd.o uverbs_mem.o | 19 | ib_uverbs-y := uverbs_main.o uverbs_cmd.o uverbs_mem.o \ |
20 | uverbs_marshall.o | ||
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index 9164a09b6ccd..b396bf703f80 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c | |||
@@ -30,7 +30,7 @@ | |||
30 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 30 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
31 | * SOFTWARE. | 31 | * SOFTWARE. |
32 | * | 32 | * |
33 | * $Id: ucm.c 2594 2005-06-13 19:46:02Z libor $ | 33 | * $Id: ucm.c 4311 2005-12-05 18:42:01Z sean.hefty $ |
34 | */ | 34 | */ |
35 | 35 | ||
36 | #include <linux/completion.h> | 36 | #include <linux/completion.h> |
@@ -50,6 +50,7 @@ | |||
50 | 50 | ||
51 | #include <rdma/ib_cm.h> | 51 | #include <rdma/ib_cm.h> |
52 | #include <rdma/ib_user_cm.h> | 52 | #include <rdma/ib_user_cm.h> |
53 | #include <rdma/ib_marshall.h> | ||
53 | 54 | ||
54 | MODULE_AUTHOR("Libor Michalek"); | 55 | MODULE_AUTHOR("Libor Michalek"); |
55 | MODULE_DESCRIPTION("InfiniBand userspace Connection Manager access"); | 56 | MODULE_DESCRIPTION("InfiniBand userspace Connection Manager access"); |
@@ -205,36 +206,6 @@ error: | |||
205 | return NULL; | 206 | return NULL; |
206 | } | 207 | } |
207 | 208 | ||
208 | static void ib_ucm_event_path_get(struct ib_ucm_path_rec *upath, | ||
209 | struct ib_sa_path_rec *kpath) | ||
210 | { | ||
211 | if (!kpath || !upath) | ||
212 | return; | ||
213 | |||
214 | memcpy(upath->dgid, kpath->dgid.raw, sizeof *upath->dgid); | ||
215 | memcpy(upath->sgid, kpath->sgid.raw, sizeof *upath->sgid); | ||
216 | |||
217 | upath->dlid = kpath->dlid; | ||
218 | upath->slid = kpath->slid; | ||
219 | upath->raw_traffic = kpath->raw_traffic; | ||
220 | upath->flow_label = kpath->flow_label; | ||
221 | upath->hop_limit = kpath->hop_limit; | ||
222 | upath->traffic_class = kpath->traffic_class; | ||
223 | upath->reversible = kpath->reversible; | ||
224 | upath->numb_path = kpath->numb_path; | ||
225 | upath->pkey = kpath->pkey; | ||
226 | upath->sl = kpath->sl; | ||
227 | upath->mtu_selector = kpath->mtu_selector; | ||
228 | upath->mtu = kpath->mtu; | ||
229 | upath->rate_selector = kpath->rate_selector; | ||
230 | upath->rate = kpath->rate; | ||
231 | upath->packet_life_time = kpath->packet_life_time; | ||
232 | upath->preference = kpath->preference; | ||
233 | |||
234 | upath->packet_life_time_selector = | ||
235 | kpath->packet_life_time_selector; | ||
236 | } | ||
237 | |||
238 | static void ib_ucm_event_req_get(struct ib_ucm_req_event_resp *ureq, | 209 | static void ib_ucm_event_req_get(struct ib_ucm_req_event_resp *ureq, |
239 | struct ib_cm_req_event_param *kreq) | 210 | struct ib_cm_req_event_param *kreq) |
240 | { | 211 | { |
@@ -253,8 +224,10 @@ static void ib_ucm_event_req_get(struct ib_ucm_req_event_resp *ureq, | |||
253 | ureq->srq = kreq->srq; | 224 | ureq->srq = kreq->srq; |
254 | ureq->port = kreq->port; | 225 | ureq->port = kreq->port; |
255 | 226 | ||
256 | ib_ucm_event_path_get(&ureq->primary_path, kreq->primary_path); | 227 | ib_copy_path_rec_to_user(&ureq->primary_path, kreq->primary_path); |
257 | ib_ucm_event_path_get(&ureq->alternate_path, kreq->alternate_path); | 228 | if (kreq->alternate_path) |
229 | ib_copy_path_rec_to_user(&ureq->alternate_path, | ||
230 | kreq->alternate_path); | ||
258 | } | 231 | } |
259 | 232 | ||
260 | static void ib_ucm_event_rep_get(struct ib_ucm_rep_event_resp *urep, | 233 | static void ib_ucm_event_rep_get(struct ib_ucm_rep_event_resp *urep, |
@@ -324,8 +297,8 @@ static int ib_ucm_event_process(struct ib_cm_event *evt, | |||
324 | info = evt->param.rej_rcvd.ari; | 297 | info = evt->param.rej_rcvd.ari; |
325 | break; | 298 | break; |
326 | case IB_CM_LAP_RECEIVED: | 299 | case IB_CM_LAP_RECEIVED: |
327 | ib_ucm_event_path_get(&uvt->resp.u.lap_resp.path, | 300 | ib_copy_path_rec_to_user(&uvt->resp.u.lap_resp.path, |
328 | evt->param.lap_rcvd.alternate_path); | 301 | evt->param.lap_rcvd.alternate_path); |
329 | uvt->data_len = IB_CM_LAP_PRIVATE_DATA_SIZE; | 302 | uvt->data_len = IB_CM_LAP_PRIVATE_DATA_SIZE; |
330 | uvt->resp.present = IB_UCM_PRES_ALTERNATE; | 303 | uvt->resp.present = IB_UCM_PRES_ALTERNATE; |
331 | break; | 304 | break; |
@@ -637,65 +610,11 @@ static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file, | |||
637 | return result; | 610 | return result; |
638 | } | 611 | } |
639 | 612 | ||
640 | static void ib_ucm_copy_ah_attr(struct ib_ucm_ah_attr *dest_attr, | ||
641 | struct ib_ah_attr *src_attr) | ||
642 | { | ||
643 | memcpy(dest_attr->grh_dgid, src_attr->grh.dgid.raw, | ||
644 | sizeof src_attr->grh.dgid); | ||
645 | dest_attr->grh_flow_label = src_attr->grh.flow_label; | ||
646 | dest_attr->grh_sgid_index = src_attr->grh.sgid_index; | ||
647 | dest_attr->grh_hop_limit = src_attr->grh.hop_limit; | ||
648 | dest_attr->grh_traffic_class = src_attr->grh.traffic_class; | ||
649 | |||
650 | dest_attr->dlid = src_attr->dlid; | ||
651 | dest_attr->sl = src_attr->sl; | ||
652 | dest_attr->src_path_bits = src_attr->src_path_bits; | ||
653 | dest_attr->static_rate = src_attr->static_rate; | ||
654 | dest_attr->is_global = (src_attr->ah_flags & IB_AH_GRH); | ||
655 | dest_attr->port_num = src_attr->port_num; | ||
656 | } | ||
657 | |||
658 | static void ib_ucm_copy_qp_attr(struct ib_ucm_init_qp_attr_resp *dest_attr, | ||
659 | struct ib_qp_attr *src_attr) | ||
660 | { | ||
661 | dest_attr->cur_qp_state = src_attr->cur_qp_state; | ||
662 | dest_attr->path_mtu = src_attr->path_mtu; | ||
663 | dest_attr->path_mig_state = src_attr->path_mig_state; | ||
664 | dest_attr->qkey = src_attr->qkey; | ||
665 | dest_attr->rq_psn = src_attr->rq_psn; | ||
666 | dest_attr->sq_psn = src_attr->sq_psn; | ||
667 | dest_attr->dest_qp_num = src_attr->dest_qp_num; | ||
668 | dest_attr->qp_access_flags = src_attr->qp_access_flags; | ||
669 | |||
670 | dest_attr->max_send_wr = src_attr->cap.max_send_wr; | ||
671 | dest_attr->max_recv_wr = src_attr->cap.max_recv_wr; | ||
672 | dest_attr->max_send_sge = src_attr->cap.max_send_sge; | ||
673 | dest_attr->max_recv_sge = src_attr->cap.max_recv_sge; | ||
674 | dest_attr->max_inline_data = src_attr->cap.max_inline_data; | ||
675 | |||
676 | ib_ucm_copy_ah_attr(&dest_attr->ah_attr, &src_attr->ah_attr); | ||
677 | ib_ucm_copy_ah_attr(&dest_attr->alt_ah_attr, &src_attr->alt_ah_attr); | ||
678 | |||
679 | dest_attr->pkey_index = src_attr->pkey_index; | ||
680 | dest_attr->alt_pkey_index = src_attr->alt_pkey_index; | ||
681 | dest_attr->en_sqd_async_notify = src_attr->en_sqd_async_notify; | ||
682 | dest_attr->sq_draining = src_attr->sq_draining; | ||
683 | dest_attr->max_rd_atomic = src_attr->max_rd_atomic; | ||
684 | dest_attr->max_dest_rd_atomic = src_attr->max_dest_rd_atomic; | ||
685 | dest_attr->min_rnr_timer = src_attr->min_rnr_timer; | ||
686 | dest_attr->port_num = src_attr->port_num; | ||
687 | dest_attr->timeout = src_attr->timeout; | ||
688 | dest_attr->retry_cnt = src_attr->retry_cnt; | ||
689 | dest_attr->rnr_retry = src_attr->rnr_retry; | ||
690 | dest_attr->alt_port_num = src_attr->alt_port_num; | ||
691 | dest_attr->alt_timeout = src_attr->alt_timeout; | ||
692 | } | ||
693 | |||
694 | static ssize_t ib_ucm_init_qp_attr(struct ib_ucm_file *file, | 613 | static ssize_t ib_ucm_init_qp_attr(struct ib_ucm_file *file, |
695 | const char __user *inbuf, | 614 | const char __user *inbuf, |
696 | int in_len, int out_len) | 615 | int in_len, int out_len) |
697 | { | 616 | { |
698 | struct ib_ucm_init_qp_attr_resp resp; | 617 | struct ib_uverbs_qp_attr resp; |
699 | struct ib_ucm_init_qp_attr cmd; | 618 | struct ib_ucm_init_qp_attr cmd; |
700 | struct ib_ucm_context *ctx; | 619 | struct ib_ucm_context *ctx; |
701 | struct ib_qp_attr qp_attr; | 620 | struct ib_qp_attr qp_attr; |
@@ -718,7 +637,7 @@ static ssize_t ib_ucm_init_qp_attr(struct ib_ucm_file *file, | |||
718 | if (result) | 637 | if (result) |
719 | goto out; | 638 | goto out; |
720 | 639 | ||
721 | ib_ucm_copy_qp_attr(&resp, &qp_attr); | 640 | ib_copy_qp_attr_to_user(&resp, &qp_attr); |
722 | 641 | ||
723 | if (copy_to_user((void __user *)(unsigned long)cmd.response, | 642 | if (copy_to_user((void __user *)(unsigned long)cmd.response, |
724 | &resp, sizeof(resp))) | 643 | &resp, sizeof(resp))) |
@@ -793,7 +712,7 @@ static int ib_ucm_alloc_data(const void **dest, u64 src, u32 len) | |||
793 | 712 | ||
794 | static int ib_ucm_path_get(struct ib_sa_path_rec **path, u64 src) | 713 | static int ib_ucm_path_get(struct ib_sa_path_rec **path, u64 src) |
795 | { | 714 | { |
796 | struct ib_ucm_path_rec ucm_path; | 715 | struct ib_user_path_rec upath; |
797 | struct ib_sa_path_rec *sa_path; | 716 | struct ib_sa_path_rec *sa_path; |
798 | 717 | ||
799 | *path = NULL; | 718 | *path = NULL; |
@@ -805,36 +724,14 @@ static int ib_ucm_path_get(struct ib_sa_path_rec **path, u64 src) | |||
805 | if (!sa_path) | 724 | if (!sa_path) |
806 | return -ENOMEM; | 725 | return -ENOMEM; |
807 | 726 | ||
808 | if (copy_from_user(&ucm_path, (void __user *)(unsigned long)src, | 727 | if (copy_from_user(&upath, (void __user *)(unsigned long)src, |
809 | sizeof(ucm_path))) { | 728 | sizeof(upath))) { |
810 | 729 | ||
811 | kfree(sa_path); | 730 | kfree(sa_path); |
812 | return -EFAULT; | 731 | return -EFAULT; |
813 | } | 732 | } |
814 | 733 | ||
815 | memcpy(sa_path->dgid.raw, ucm_path.dgid, sizeof sa_path->dgid); | 734 | ib_copy_path_rec_from_user(sa_path, &upath); |
816 | memcpy(sa_path->sgid.raw, ucm_path.sgid, sizeof sa_path->sgid); | ||
817 | |||
818 | sa_path->dlid = ucm_path.dlid; | ||
819 | sa_path->slid = ucm_path.slid; | ||
820 | sa_path->raw_traffic = ucm_path.raw_traffic; | ||
821 | sa_path->flow_label = ucm_path.flow_label; | ||
822 | sa_path->hop_limit = ucm_path.hop_limit; | ||
823 | sa_path->traffic_class = ucm_path.traffic_class; | ||
824 | sa_path->reversible = ucm_path.reversible; | ||
825 | sa_path->numb_path = ucm_path.numb_path; | ||
826 | sa_path->pkey = ucm_path.pkey; | ||
827 | sa_path->sl = ucm_path.sl; | ||
828 | sa_path->mtu_selector = ucm_path.mtu_selector; | ||
829 | sa_path->mtu = ucm_path.mtu; | ||
830 | sa_path->rate_selector = ucm_path.rate_selector; | ||
831 | sa_path->rate = ucm_path.rate; | ||
832 | sa_path->packet_life_time = ucm_path.packet_life_time; | ||
833 | sa_path->preference = ucm_path.preference; | ||
834 | |||
835 | sa_path->packet_life_time_selector = | ||
836 | ucm_path.packet_life_time_selector; | ||
837 | |||
838 | *path = sa_path; | 735 | *path = sa_path; |
839 | return 0; | 736 | return 0; |
840 | } | 737 | } |
diff --git a/drivers/infiniband/core/uverbs_marshall.c b/drivers/infiniband/core/uverbs_marshall.c new file mode 100644 index 000000000000..ce46b13ae02b --- /dev/null +++ b/drivers/infiniband/core/uverbs_marshall.c | |||
@@ -0,0 +1,138 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005 Intel Corporation. All rights reserved. | ||
3 | * | ||
4 | * This software is available to you under a choice of one of two | ||
5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
6 | * General Public License (GPL) Version 2, available from the file | ||
7 | * COPYING in the main directory of this source tree, or the | ||
8 | * OpenIB.org BSD license below: | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or | ||
11 | * without modification, are permitted provided that the following | ||
12 | * conditions are met: | ||
13 | * | ||
14 | * - Redistributions of source code must retain the above | ||
15 | * copyright notice, this list of conditions and the following | ||
16 | * disclaimer. | ||
17 | * | ||
18 | * - Redistributions in binary form must reproduce the above | ||
19 | * copyright notice, this list of conditions and the following | ||
20 | * disclaimer in the documentation and/or other materials | ||
21 | * provided with the distribution. | ||
22 | * | ||
23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
30 | * SOFTWARE. | ||
31 | */ | ||
32 | |||
33 | #include <rdma/ib_marshall.h> | ||
34 | |||
35 | static void ib_copy_ah_attr_to_user(struct ib_uverbs_ah_attr *dst, | ||
36 | struct ib_ah_attr *src) | ||
37 | { | ||
38 | memcpy(dst->grh.dgid, src->grh.dgid.raw, sizeof src->grh.dgid); | ||
39 | dst->grh.flow_label = src->grh.flow_label; | ||
40 | dst->grh.sgid_index = src->grh.sgid_index; | ||
41 | dst->grh.hop_limit = src->grh.hop_limit; | ||
42 | dst->grh.traffic_class = src->grh.traffic_class; | ||
43 | dst->dlid = src->dlid; | ||
44 | dst->sl = src->sl; | ||
45 | dst->src_path_bits = src->src_path_bits; | ||
46 | dst->static_rate = src->static_rate; | ||
47 | dst->is_global = src->ah_flags & IB_AH_GRH ? 1 : 0; | ||
48 | dst->port_num = src->port_num; | ||
49 | } | ||
50 | |||
51 | void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst, | ||
52 | struct ib_qp_attr *src) | ||
53 | { | ||
54 | dst->cur_qp_state = src->cur_qp_state; | ||
55 | dst->path_mtu = src->path_mtu; | ||
56 | dst->path_mig_state = src->path_mig_state; | ||
57 | dst->qkey = src->qkey; | ||
58 | dst->rq_psn = src->rq_psn; | ||
59 | dst->sq_psn = src->sq_psn; | ||
60 | dst->dest_qp_num = src->dest_qp_num; | ||
61 | dst->qp_access_flags = src->qp_access_flags; | ||
62 | |||
63 | dst->max_send_wr = src->cap.max_send_wr; | ||
64 | dst->max_recv_wr = src->cap.max_recv_wr; | ||
65 | dst->max_send_sge = src->cap.max_send_sge; | ||
66 | dst->max_recv_sge = src->cap.max_recv_sge; | ||
67 | dst->max_inline_data = src->cap.max_inline_data; | ||
68 | |||
69 | ib_copy_ah_attr_to_user(&dst->ah_attr, &src->ah_attr); | ||
70 | ib_copy_ah_attr_to_user(&dst->alt_ah_attr, &src->alt_ah_attr); | ||
71 | |||
72 | dst->pkey_index = src->pkey_index; | ||
73 | dst->alt_pkey_index = src->alt_pkey_index; | ||
74 | dst->en_sqd_async_notify = src->en_sqd_async_notify; | ||
75 | dst->sq_draining = src->sq_draining; | ||
76 | dst->max_rd_atomic = src->max_rd_atomic; | ||
77 | dst->max_dest_rd_atomic = src->max_dest_rd_atomic; | ||
78 | dst->min_rnr_timer = src->min_rnr_timer; | ||
79 | dst->port_num = src->port_num; | ||
80 | dst->timeout = src->timeout; | ||
81 | dst->retry_cnt = src->retry_cnt; | ||
82 | dst->rnr_retry = src->rnr_retry; | ||
83 | dst->alt_port_num = src->alt_port_num; | ||
84 | dst->alt_timeout = src->alt_timeout; | ||
85 | } | ||
86 | EXPORT_SYMBOL(ib_copy_qp_attr_to_user); | ||
87 | |||
88 | void ib_copy_path_rec_to_user(struct ib_user_path_rec *dst, | ||
89 | struct ib_sa_path_rec *src) | ||
90 | { | ||
91 | memcpy(dst->dgid, src->dgid.raw, sizeof src->dgid); | ||
92 | memcpy(dst->sgid, src->sgid.raw, sizeof src->sgid); | ||
93 | |||
94 | dst->dlid = src->dlid; | ||
95 | dst->slid = src->slid; | ||
96 | dst->raw_traffic = src->raw_traffic; | ||
97 | dst->flow_label = src->flow_label; | ||
98 | dst->hop_limit = src->hop_limit; | ||
99 | dst->traffic_class = src->traffic_class; | ||
100 | dst->reversible = src->reversible; | ||
101 | dst->numb_path = src->numb_path; | ||
102 | dst->pkey = src->pkey; | ||
103 | dst->sl = src->sl; | ||
104 | dst->mtu_selector = src->mtu_selector; | ||
105 | dst->mtu = src->mtu; | ||
106 | dst->rate_selector = src->rate_selector; | ||
107 | dst->rate = src->rate; | ||
108 | dst->packet_life_time = src->packet_life_time; | ||
109 | dst->preference = src->preference; | ||
110 | dst->packet_life_time_selector = src->packet_life_time_selector; | ||
111 | } | ||
112 | EXPORT_SYMBOL(ib_copy_path_rec_to_user); | ||
113 | |||
114 | void ib_copy_path_rec_from_user(struct ib_sa_path_rec *dst, | ||
115 | struct ib_user_path_rec *src) | ||
116 | { | ||
117 | memcpy(dst->dgid.raw, src->dgid, sizeof dst->dgid); | ||
118 | memcpy(dst->sgid.raw, src->sgid, sizeof dst->sgid); | ||
119 | |||
120 | dst->dlid = src->dlid; | ||
121 | dst->slid = src->slid; | ||
122 | dst->raw_traffic = src->raw_traffic; | ||
123 | dst->flow_label = src->flow_label; | ||
124 | dst->hop_limit = src->hop_limit; | ||
125 | dst->traffic_class = src->traffic_class; | ||
126 | dst->reversible = src->reversible; | ||
127 | dst->numb_path = src->numb_path; | ||
128 | dst->pkey = src->pkey; | ||
129 | dst->sl = src->sl; | ||
130 | dst->mtu_selector = src->mtu_selector; | ||
131 | dst->mtu = src->mtu; | ||
132 | dst->rate_selector = src->rate_selector; | ||
133 | dst->rate = src->rate; | ||
134 | dst->packet_life_time = src->packet_life_time; | ||
135 | dst->preference = src->preference; | ||
136 | dst->packet_life_time_selector = src->packet_life_time_selector; | ||
137 | } | ||
138 | EXPORT_SYMBOL(ib_copy_path_rec_from_user); | ||