1 /* 2 * Copyright (c) 2018, Mellanox Technologies inc. 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 "uverbs.h" 34 #include <rdma/uverbs_std_types.h> 35 36 static int uverbs_free_mr(struct ib_uobject *uobject, 37 enum rdma_remove_reason why) 38 { 39 return ib_dereg_mr((struct ib_mr *)uobject->object); 40 } 41 42 static int UVERBS_HANDLER(UVERBS_METHOD_ADVISE_MR)( 43 struct uverbs_attr_bundle *attrs) 44 { 45 struct ib_pd *pd = 46 uverbs_attr_get_obj(attrs, UVERBS_ATTR_ADVISE_MR_PD_HANDLE); 47 enum ib_uverbs_advise_mr_advice advice; 48 struct ib_device *ib_dev = pd->device; 49 struct ib_sge *sg_list; 50 int num_sge; 51 u32 flags; 52 int ret; 53 54 /* FIXME: Extend the UAPI_DEF_OBJ_NEEDS_FN stuff.. */ 55 if (!ib_dev->ops.advise_mr) 56 return -EOPNOTSUPP; 57 58 ret = uverbs_get_const(&advice, attrs, UVERBS_ATTR_ADVISE_MR_ADVICE); 59 if (ret) 60 return ret; 61 62 ret = uverbs_get_flags32(&flags, attrs, UVERBS_ATTR_ADVISE_MR_FLAGS, 63 IB_UVERBS_ADVISE_MR_FLAG_FLUSH); 64 if (ret) 65 return ret; 66 67 num_sge = uverbs_attr_ptr_get_array_size( 68 attrs, UVERBS_ATTR_ADVISE_MR_SGE_LIST, sizeof(struct ib_sge)); 69 if (num_sge < 0) 70 return num_sge; 71 72 sg_list = uverbs_attr_get_alloced_ptr(attrs, 73 UVERBS_ATTR_ADVISE_MR_SGE_LIST); 74 return ib_dev->ops.advise_mr(pd, advice, flags, sg_list, num_sge, 75 attrs); 76 } 77 78 static int UVERBS_HANDLER(UVERBS_METHOD_DM_MR_REG)( 79 struct uverbs_attr_bundle *attrs) 80 { 81 struct ib_dm_mr_attr attr = {}; 82 struct ib_uobject *uobj = 83 uverbs_attr_get_uobject(attrs, UVERBS_ATTR_REG_DM_MR_HANDLE); 84 struct ib_dm *dm = 85 uverbs_attr_get_obj(attrs, UVERBS_ATTR_REG_DM_MR_DM_HANDLE); 86 struct ib_pd *pd = 87 uverbs_attr_get_obj(attrs, UVERBS_ATTR_REG_DM_MR_PD_HANDLE); 88 struct ib_device *ib_dev = pd->device; 89 90 struct ib_mr *mr; 91 int ret; 92 93 if (!ib_dev->ops.reg_dm_mr) 94 return -EOPNOTSUPP; 95 96 ret = uverbs_copy_from(&attr.offset, attrs, UVERBS_ATTR_REG_DM_MR_OFFSET); 97 if (ret) 98 return ret; 99 100 ret = uverbs_copy_from(&attr.length, attrs, 101 UVERBS_ATTR_REG_DM_MR_LENGTH); 102 if (ret) 103 return ret; 104 105 ret = uverbs_get_flags32(&attr.access_flags, attrs, 106 UVERBS_ATTR_REG_DM_MR_ACCESS_FLAGS, 107 IB_ACCESS_SUPPORTED); 108 if (ret) 109 return ret; 110 111 if (!(attr.access_flags & IB_ZERO_BASED)) 112 return -EINVAL; 113 114 ret = ib_check_mr_access(attr.access_flags); 115 if (ret) 116 return ret; 117 118 if (attr.offset > dm->length || attr.length > dm->length || 119 attr.length > dm->length - attr.offset) 120 return -EINVAL; 121 122 mr = pd->device->ops.reg_dm_mr(pd, dm, &attr, attrs); 123 if (IS_ERR(mr)) 124 return PTR_ERR(mr); 125 126 mr->device = pd->device; 127 mr->pd = pd; 128 mr->dm = dm; 129 mr->uobject = uobj; 130 atomic_inc(&pd->usecnt); 131 atomic_inc(&dm->usecnt); 132 133 uobj->object = mr; 134 135 ret = uverbs_copy_to(attrs, UVERBS_ATTR_REG_DM_MR_RESP_LKEY, &mr->lkey, 136 sizeof(mr->lkey)); 137 if (ret) 138 goto err_dereg; 139 140 ret = uverbs_copy_to(attrs, UVERBS_ATTR_REG_DM_MR_RESP_RKEY, 141 &mr->rkey, sizeof(mr->rkey)); 142 if (ret) 143 goto err_dereg; 144 145 return 0; 146 147 err_dereg: 148 ib_dereg_mr(mr); 149 150 return ret; 151 } 152 153 DECLARE_UVERBS_NAMED_METHOD( 154 UVERBS_METHOD_ADVISE_MR, 155 UVERBS_ATTR_IDR(UVERBS_ATTR_ADVISE_MR_PD_HANDLE, 156 UVERBS_OBJECT_PD, 157 UVERBS_ACCESS_READ, 158 UA_MANDATORY), 159 UVERBS_ATTR_CONST_IN(UVERBS_ATTR_ADVISE_MR_ADVICE, 160 enum ib_uverbs_advise_mr_advice, 161 UA_MANDATORY), 162 UVERBS_ATTR_FLAGS_IN(UVERBS_ATTR_ADVISE_MR_FLAGS, 163 enum ib_uverbs_advise_mr_flag, 164 UA_MANDATORY), 165 UVERBS_ATTR_PTR_IN(UVERBS_ATTR_ADVISE_MR_SGE_LIST, 166 UVERBS_ATTR_MIN_SIZE(sizeof(struct ib_uverbs_sge)), 167 UA_MANDATORY, 168 UA_ALLOC_AND_COPY)); 169 170 DECLARE_UVERBS_NAMED_METHOD( 171 UVERBS_METHOD_DM_MR_REG, 172 UVERBS_ATTR_IDR(UVERBS_ATTR_REG_DM_MR_HANDLE, 173 UVERBS_OBJECT_MR, 174 UVERBS_ACCESS_NEW, 175 UA_MANDATORY), 176 UVERBS_ATTR_PTR_IN(UVERBS_ATTR_REG_DM_MR_OFFSET, 177 UVERBS_ATTR_TYPE(u64), 178 UA_MANDATORY), 179 UVERBS_ATTR_PTR_IN(UVERBS_ATTR_REG_DM_MR_LENGTH, 180 UVERBS_ATTR_TYPE(u64), 181 UA_MANDATORY), 182 UVERBS_ATTR_IDR(UVERBS_ATTR_REG_DM_MR_PD_HANDLE, 183 UVERBS_OBJECT_PD, 184 UVERBS_ACCESS_READ, 185 UA_MANDATORY), 186 UVERBS_ATTR_FLAGS_IN(UVERBS_ATTR_REG_DM_MR_ACCESS_FLAGS, 187 enum ib_access_flags), 188 UVERBS_ATTR_IDR(UVERBS_ATTR_REG_DM_MR_DM_HANDLE, 189 UVERBS_OBJECT_DM, 190 UVERBS_ACCESS_READ, 191 UA_MANDATORY), 192 UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_REG_DM_MR_RESP_LKEY, 193 UVERBS_ATTR_TYPE(u32), 194 UA_MANDATORY), 195 UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_REG_DM_MR_RESP_RKEY, 196 UVERBS_ATTR_TYPE(u32), 197 UA_MANDATORY)); 198 199 DECLARE_UVERBS_NAMED_METHOD_DESTROY( 200 UVERBS_METHOD_MR_DESTROY, 201 UVERBS_ATTR_IDR(UVERBS_ATTR_DESTROY_MR_HANDLE, 202 UVERBS_OBJECT_MR, 203 UVERBS_ACCESS_DESTROY, 204 UA_MANDATORY)); 205 206 DECLARE_UVERBS_NAMED_OBJECT( 207 UVERBS_OBJECT_MR, 208 UVERBS_TYPE_ALLOC_IDR(uverbs_free_mr), 209 &UVERBS_METHOD(UVERBS_METHOD_DM_MR_REG), 210 &UVERBS_METHOD(UVERBS_METHOD_MR_DESTROY), 211 &UVERBS_METHOD(UVERBS_METHOD_ADVISE_MR)); 212 213 const struct uapi_definition uverbs_def_obj_mr[] = { 214 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_MR, 215 UAPI_DEF_OBJ_NEEDS_FN(dereg_mr)), 216 {} 217 }; 218