Skip to content

Commit d541e45

Browse files
Dasaratharaman Chandramoulidledford
Dasaratharaman Chandramouli
authored andcommitted
IB/core: Convert ah_attr from OPA to IB when copying to user
OPA address handle atttibutes that have 32 bit LIDs would have to be converted to IB address handle attribute with the LID field programmed in the GID before copying to user space. Signed-off-by: Dasaratharaman Chandramouli <[email protected]> Reviewed-by: Don Hiatt <[email protected]> Reviewed-by: Ira Weiny <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent 520eccd commit d541e45

File tree

4 files changed

+54
-12
lines changed

4 files changed

+54
-12
lines changed

drivers/infiniband/core/ucm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ static ssize_t ib_ucm_init_qp_attr(struct ib_ucm_file *file,
618618
if (result)
619619
goto out;
620620

621-
ib_copy_qp_attr_to_user(&resp, &qp_attr);
621+
ib_copy_qp_attr_to_user(ctx->cm_id->device, &resp, &qp_attr);
622622

623623
if (copy_to_user((void __user *)(unsigned long)cmd.response,
624624
&resp, sizeof(resp)))

drivers/infiniband/core/ucma.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -248,14 +248,15 @@ static void ucma_copy_conn_event(struct rdma_ucm_conn_param *dst,
248248
dst->qp_num = src->qp_num;
249249
}
250250

251-
static void ucma_copy_ud_event(struct rdma_ucm_ud_param *dst,
251+
static void ucma_copy_ud_event(struct ib_device *device,
252+
struct rdma_ucm_ud_param *dst,
252253
struct rdma_ud_param *src)
253254
{
254255
if (src->private_data_len)
255256
memcpy(dst->private_data, src->private_data,
256257
src->private_data_len);
257258
dst->private_data_len = src->private_data_len;
258-
ib_copy_ah_attr_to_user(&dst->ah_attr, &src->ah_attr);
259+
ib_copy_ah_attr_to_user(device, &dst->ah_attr, &src->ah_attr);
259260
dst->qp_num = src->qp_num;
260261
dst->qkey = src->qkey;
261262
}
@@ -335,7 +336,8 @@ static int ucma_event_handler(struct rdma_cm_id *cm_id,
335336
uevent->resp.event = event->event;
336337
uevent->resp.status = event->status;
337338
if (cm_id->qp_type == IB_QPT_UD)
338-
ucma_copy_ud_event(&uevent->resp.param.ud, &event->param.ud);
339+
ucma_copy_ud_event(cm_id->device, &uevent->resp.param.ud,
340+
&event->param.ud);
339341
else
340342
ucma_copy_conn_event(&uevent->resp.param.conn,
341343
&event->param.conn);
@@ -1157,7 +1159,7 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file,
11571159
if (ret)
11581160
goto out;
11591161

1160-
ib_copy_qp_attr_to_user(&resp, &qp_attr);
1162+
ib_copy_qp_attr_to_user(ctx->cm_id->device, &resp, &qp_attr);
11611163
if (copy_to_user((void __user *)(unsigned long)cmd.response,
11621164
&resp, sizeof(resp)))
11631165
ret = -EFAULT;

drivers/infiniband/core/uverbs_marshall.c

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,47 @@
3333
#include <linux/export.h>
3434
#include <rdma/ib_marshall.h>
3535

36-
void ib_copy_ah_attr_to_user(struct ib_uverbs_ah_attr *dst,
37-
struct rdma_ah_attr *src)
36+
#define OPA_DEFAULT_GID_PREFIX cpu_to_be64(0xfe80000000000000ULL)
37+
static int rdma_ah_conv_opa_to_ib(struct ib_device *dev,
38+
struct rdma_ah_attr *ib,
39+
struct rdma_ah_attr *opa)
3840
{
41+
struct ib_port_attr port_attr;
42+
int ret = 0;
43+
44+
/* Do structure copy and the over-write fields */
45+
*ib = *opa;
46+
47+
ib->type = RDMA_AH_ATTR_TYPE_IB;
48+
rdma_ah_set_grh(ib, NULL, 0, 0, 1, 0);
49+
50+
if (ib_query_port(dev, opa->port_num, &port_attr)) {
51+
/* Set to default subnet to indicate error */
52+
rdma_ah_set_subnet_prefix(ib, OPA_DEFAULT_GID_PREFIX);
53+
ret = -EINVAL;
54+
} else {
55+
rdma_ah_set_subnet_prefix(ib,
56+
cpu_to_be64(port_attr.subnet_prefix));
57+
}
58+
rdma_ah_set_interface_id(ib, OPA_MAKE_ID(rdma_ah_get_dlid(opa)));
59+
return ret;
60+
}
61+
62+
void ib_copy_ah_attr_to_user(struct ib_device *device,
63+
struct ib_uverbs_ah_attr *dst,
64+
struct rdma_ah_attr *ah_attr)
65+
{
66+
struct rdma_ah_attr *src = ah_attr;
67+
struct rdma_ah_attr conv_ah;
68+
3969
memset(&dst->grh.reserved, 0, sizeof(dst->grh.reserved));
70+
71+
if ((ah_attr->type == RDMA_AH_ATTR_TYPE_OPA) &&
72+
(rdma_ah_get_dlid(ah_attr) >=
73+
be16_to_cpu(IB_MULTICAST_LID_BASE)) &&
74+
(!rdma_ah_conv_opa_to_ib(device, &conv_ah, ah_attr)))
75+
src = &conv_ah;
76+
4077
dst->dlid = rdma_ah_get_dlid(src);
4178
dst->sl = rdma_ah_get_sl(src);
4279
dst->src_path_bits = rdma_ah_get_path_bits(src);
@@ -57,7 +94,8 @@ void ib_copy_ah_attr_to_user(struct ib_uverbs_ah_attr *dst,
5794
}
5895
EXPORT_SYMBOL(ib_copy_ah_attr_to_user);
5996

60-
void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst,
97+
void ib_copy_qp_attr_to_user(struct ib_device *device,
98+
struct ib_uverbs_qp_attr *dst,
6199
struct ib_qp_attr *src)
62100
{
63101
dst->qp_state = src->qp_state;
@@ -76,8 +114,8 @@ void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst,
76114
dst->max_recv_sge = src->cap.max_recv_sge;
77115
dst->max_inline_data = src->cap.max_inline_data;
78116

79-
ib_copy_ah_attr_to_user(&dst->ah_attr, &src->ah_attr);
80-
ib_copy_ah_attr_to_user(&dst->alt_ah_attr, &src->alt_ah_attr);
117+
ib_copy_ah_attr_to_user(device, &dst->ah_attr, &src->ah_attr);
118+
ib_copy_ah_attr_to_user(device, &dst->alt_ah_attr, &src->alt_ah_attr);
81119

82120
dst->pkey_index = src->pkey_index;
83121
dst->alt_pkey_index = src->alt_pkey_index;

include/rdma/ib_marshall.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@
3838
#include <rdma/ib_user_verbs.h>
3939
#include <rdma/ib_user_sa.h>
4040

41-
void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst,
41+
void ib_copy_qp_attr_to_user(struct ib_device *device,
42+
struct ib_uverbs_qp_attr *dst,
4243
struct ib_qp_attr *src);
4344

44-
void ib_copy_ah_attr_to_user(struct ib_uverbs_ah_attr *dst,
45+
void ib_copy_ah_attr_to_user(struct ib_device *device,
46+
struct ib_uverbs_ah_attr *dst,
4547
struct rdma_ah_attr *src);
4648

4749
void ib_copy_path_rec_to_user(struct ib_user_path_rec *dst,

0 commit comments

Comments
 (0)