diff options
| -rw-r--r-- | drivers/infiniband/core/uverbs.h | 1 | ||||
| -rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 93 | ||||
| -rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 1 | ||||
| -rw-r--r-- | include/rdma/ib_verbs.h | 10 | ||||
| -rw-r--r-- | include/uapi/rdma/ib_user_verbs.h | 16 |
5 files changed, 120 insertions, 1 deletions
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index a283274a5a09..643c08a025a5 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
| @@ -221,6 +221,7 @@ IB_UVERBS_DECLARE_CMD(query_port); | |||
| 221 | IB_UVERBS_DECLARE_CMD(alloc_pd); | 221 | IB_UVERBS_DECLARE_CMD(alloc_pd); |
| 222 | IB_UVERBS_DECLARE_CMD(dealloc_pd); | 222 | IB_UVERBS_DECLARE_CMD(dealloc_pd); |
| 223 | IB_UVERBS_DECLARE_CMD(reg_mr); | 223 | IB_UVERBS_DECLARE_CMD(reg_mr); |
| 224 | IB_UVERBS_DECLARE_CMD(rereg_mr); | ||
| 224 | IB_UVERBS_DECLARE_CMD(dereg_mr); | 225 | IB_UVERBS_DECLARE_CMD(dereg_mr); |
| 225 | IB_UVERBS_DECLARE_CMD(alloc_mw); | 226 | IB_UVERBS_DECLARE_CMD(alloc_mw); |
| 226 | IB_UVERBS_DECLARE_CMD(dealloc_mw); | 227 | IB_UVERBS_DECLARE_CMD(dealloc_mw); |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index ea6203ee7bcc..0600c50e6215 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
| @@ -1002,6 +1002,99 @@ err_free: | |||
| 1002 | return ret; | 1002 | return ret; |
| 1003 | } | 1003 | } |
| 1004 | 1004 | ||
| 1005 | ssize_t ib_uverbs_rereg_mr(struct ib_uverbs_file *file, | ||
| 1006 | const char __user *buf, int in_len, | ||
| 1007 | int out_len) | ||
| 1008 | { | ||
| 1009 | struct ib_uverbs_rereg_mr cmd; | ||
| 1010 | struct ib_uverbs_rereg_mr_resp resp; | ||
| 1011 | struct ib_udata udata; | ||
| 1012 | struct ib_pd *pd = NULL; | ||
| 1013 | struct ib_mr *mr; | ||
| 1014 | struct ib_pd *old_pd; | ||
| 1015 | int ret; | ||
| 1016 | struct ib_uobject *uobj; | ||
| 1017 | |||
| 1018 | if (out_len < sizeof(resp)) | ||
| 1019 | return -ENOSPC; | ||
| 1020 | |||
| 1021 | if (copy_from_user(&cmd, buf, sizeof(cmd))) | ||
| 1022 | return -EFAULT; | ||
| 1023 | |||
| 1024 | INIT_UDATA(&udata, buf + sizeof(cmd), | ||
| 1025 | (unsigned long) cmd.response + sizeof(resp), | ||
| 1026 | in_len - sizeof(cmd), out_len - sizeof(resp)); | ||
| 1027 | |||
| 1028 | if (cmd.flags & ~IB_MR_REREG_SUPPORTED || !cmd.flags) | ||
| 1029 | return -EINVAL; | ||
| 1030 | |||
| 1031 | if ((cmd.flags & IB_MR_REREG_TRANS) && | ||
| 1032 | (!cmd.start || !cmd.hca_va || 0 >= cmd.length || | ||
| 1033 | (cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK))) | ||
| 1034 | return -EINVAL; | ||
| 1035 | |||
| 1036 | uobj = idr_write_uobj(&ib_uverbs_mr_idr, cmd.mr_handle, | ||
| 1037 | file->ucontext); | ||
| 1038 | |||
| 1039 | if (!uobj) | ||
| 1040 | return -EINVAL; | ||
| 1041 | |||
| 1042 | mr = uobj->object; | ||
| 1043 | |||
| 1044 | if (cmd.flags & IB_MR_REREG_ACCESS) { | ||
| 1045 | ret = ib_check_mr_access(cmd.access_flags); | ||
| 1046 | if (ret) | ||
| 1047 | goto put_uobjs; | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | if (cmd.flags & IB_MR_REREG_PD) { | ||
| 1051 | pd = idr_read_pd(cmd.pd_handle, file->ucontext); | ||
| 1052 | if (!pd) { | ||
| 1053 | ret = -EINVAL; | ||
| 1054 | goto put_uobjs; | ||
| 1055 | } | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | if (atomic_read(&mr->usecnt)) { | ||
| 1059 | ret = -EBUSY; | ||
| 1060 | goto put_uobj_pd; | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | old_pd = mr->pd; | ||
| 1064 | ret = mr->device->rereg_user_mr(mr, cmd.flags, cmd.start, | ||
| 1065 | cmd.length, cmd.hca_va, | ||
| 1066 | cmd.access_flags, pd, &udata); | ||
| 1067 | if (!ret) { | ||
| 1068 | if (cmd.flags & IB_MR_REREG_PD) { | ||
| 1069 | atomic_inc(&pd->usecnt); | ||
| 1070 | mr->pd = pd; | ||
| 1071 | atomic_dec(&old_pd->usecnt); | ||
| 1072 | } | ||
| 1073 | } else { | ||
| 1074 | goto put_uobj_pd; | ||
| 1075 | } | ||
| 1076 | |||
| 1077 | memset(&resp, 0, sizeof(resp)); | ||
| 1078 | resp.lkey = mr->lkey; | ||
| 1079 | resp.rkey = mr->rkey; | ||
| 1080 | |||
| 1081 | if (copy_to_user((void __user *)(unsigned long)cmd.response, | ||
| 1082 | &resp, sizeof(resp))) | ||
| 1083 | ret = -EFAULT; | ||
| 1084 | else | ||
| 1085 | ret = in_len; | ||
| 1086 | |||
| 1087 | put_uobj_pd: | ||
| 1088 | if (cmd.flags & IB_MR_REREG_PD) | ||
| 1089 | put_pd_read(pd); | ||
| 1090 | |||
| 1091 | put_uobjs: | ||
| 1092 | |||
| 1093 | put_uobj_write(mr->uobject); | ||
| 1094 | |||
| 1095 | return ret; | ||
| 1096 | } | ||
| 1097 | |||
| 1005 | ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file, | 1098 | ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file, |
| 1006 | const char __user *buf, int in_len, | 1099 | const char __user *buf, int in_len, |
| 1007 | int out_len) | 1100 | int out_len) |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 08219fb3338b..c73b22a257fe 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
| @@ -87,6 +87,7 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file, | |||
| 87 | [IB_USER_VERBS_CMD_ALLOC_PD] = ib_uverbs_alloc_pd, | 87 | [IB_USER_VERBS_CMD_ALLOC_PD] = ib_uverbs_alloc_pd, |
| 88 | [IB_USER_VERBS_CMD_DEALLOC_PD] = ib_uverbs_dealloc_pd, | 88 | [IB_USER_VERBS_CMD_DEALLOC_PD] = ib_uverbs_dealloc_pd, |
| 89 | [IB_USER_VERBS_CMD_REG_MR] = ib_uverbs_reg_mr, | 89 | [IB_USER_VERBS_CMD_REG_MR] = ib_uverbs_reg_mr, |
| 90 | [IB_USER_VERBS_CMD_REREG_MR] = ib_uverbs_rereg_mr, | ||
| 90 | [IB_USER_VERBS_CMD_DEREG_MR] = ib_uverbs_dereg_mr, | 91 | [IB_USER_VERBS_CMD_DEREG_MR] = ib_uverbs_dereg_mr, |
| 91 | [IB_USER_VERBS_CMD_ALLOC_MW] = ib_uverbs_alloc_mw, | 92 | [IB_USER_VERBS_CMD_ALLOC_MW] = ib_uverbs_alloc_mw, |
| 92 | [IB_USER_VERBS_CMD_DEALLOC_MW] = ib_uverbs_dealloc_mw, | 93 | [IB_USER_VERBS_CMD_DEALLOC_MW] = ib_uverbs_dealloc_mw, |
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 7ccef342f724..ed44cc07a7b3 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h | |||
| @@ -1097,7 +1097,8 @@ struct ib_mr_attr { | |||
| 1097 | enum ib_mr_rereg_flags { | 1097 | enum ib_mr_rereg_flags { |
| 1098 | IB_MR_REREG_TRANS = 1, | 1098 | IB_MR_REREG_TRANS = 1, |
| 1099 | IB_MR_REREG_PD = (1<<1), | 1099 | IB_MR_REREG_PD = (1<<1), |
| 1100 | IB_MR_REREG_ACCESS = (1<<2) | 1100 | IB_MR_REREG_ACCESS = (1<<2), |
| 1101 | IB_MR_REREG_SUPPORTED = ((IB_MR_REREG_ACCESS << 1) - 1) | ||
| 1101 | }; | 1102 | }; |
| 1102 | 1103 | ||
| 1103 | /** | 1104 | /** |
| @@ -1547,6 +1548,13 @@ struct ib_device { | |||
| 1547 | u64 virt_addr, | 1548 | u64 virt_addr, |
| 1548 | int mr_access_flags, | 1549 | int mr_access_flags, |
| 1549 | struct ib_udata *udata); | 1550 | struct ib_udata *udata); |
| 1551 | int (*rereg_user_mr)(struct ib_mr *mr, | ||
| 1552 | int flags, | ||
| 1553 | u64 start, u64 length, | ||
| 1554 | u64 virt_addr, | ||
| 1555 | int mr_access_flags, | ||
| 1556 | struct ib_pd *pd, | ||
| 1557 | struct ib_udata *udata); | ||
| 1550 | int (*query_mr)(struct ib_mr *mr, | 1558 | int (*query_mr)(struct ib_mr *mr, |
| 1551 | struct ib_mr_attr *mr_attr); | 1559 | struct ib_mr_attr *mr_attr); |
| 1552 | int (*dereg_mr)(struct ib_mr *mr); | 1560 | int (*dereg_mr)(struct ib_mr *mr); |
diff --git a/include/uapi/rdma/ib_user_verbs.h b/include/uapi/rdma/ib_user_verbs.h index cbfdd4ca9510..26daf55ff76e 100644 --- a/include/uapi/rdma/ib_user_verbs.h +++ b/include/uapi/rdma/ib_user_verbs.h | |||
| @@ -276,6 +276,22 @@ struct ib_uverbs_reg_mr_resp { | |||
| 276 | __u32 rkey; | 276 | __u32 rkey; |
| 277 | }; | 277 | }; |
| 278 | 278 | ||
| 279 | struct ib_uverbs_rereg_mr { | ||
| 280 | __u64 response; | ||
| 281 | __u32 mr_handle; | ||
| 282 | __u32 flags; | ||
| 283 | __u64 start; | ||
| 284 | __u64 length; | ||
| 285 | __u64 hca_va; | ||
| 286 | __u32 pd_handle; | ||
| 287 | __u32 access_flags; | ||
| 288 | }; | ||
| 289 | |||
| 290 | struct ib_uverbs_rereg_mr_resp { | ||
| 291 | __u32 lkey; | ||
| 292 | __u32 rkey; | ||
| 293 | }; | ||
| 294 | |||
| 279 | struct ib_uverbs_dereg_mr { | 295 | struct ib_uverbs_dereg_mr { |
| 280 | __u32 mr_handle; | 296 | __u32 mr_handle; |
| 281 | }; | 297 | }; |
