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