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_DM_MR_REG)( 43 struct ib_uverbs_file *file, struct uverbs_attr_bundle *attrs) 44 { 45 struct ib_dm_mr_attr attr = {}; 46 struct ib_uobject *uobj = 47 uverbs_attr_get_uobject(attrs, UVERBS_ATTR_REG_DM_MR_HANDLE); 48 struct ib_dm *dm = 49 uverbs_attr_get_obj(attrs, UVERBS_ATTR_REG_DM_MR_DM_HANDLE); 50 struct ib_pd *pd = 51 uverbs_attr_get_obj(attrs, UVERBS_ATTR_REG_DM_MR_PD_HANDLE); 52 struct ib_device *ib_dev = pd->device; 53 54 struct ib_mr *mr; 55 int ret; 56 57 if (!ib_dev->reg_dm_mr) 58 return -EOPNOTSUPP; 59 60 ret = uverbs_copy_from(&attr.offset, attrs, UVERBS_ATTR_REG_DM_MR_OFFSET); 61 if (ret) 62 return ret; 63 64 ret = uverbs_copy_from(&attr.length, attrs, 65 UVERBS_ATTR_REG_DM_MR_LENGTH); 66 if (ret) 67 return ret; 68 69 ret = uverbs_get_flags32(&attr.access_flags, attrs, 70 UVERBS_ATTR_REG_DM_MR_ACCESS_FLAGS, 71 IB_ACCESS_SUPPORTED); 72 if (ret) 73 return ret; 74 75 if (!(attr.access_flags & IB_ZERO_BASED)) 76 return -EINVAL; 77 78 ret = ib_check_mr_access(attr.access_flags); 79 if (ret) 80 return ret; 81 82 if (attr.offset > dm->length || attr.length > dm->length || 83 attr.length > dm->length - attr.offset) 84 return -EINVAL; 85 86 mr = pd->device->reg_dm_mr(pd, dm, &attr, attrs); 87 if (IS_ERR(mr)) 88 return PTR_ERR(mr); 89 90 mr->device = pd->device; 91 mr->pd = pd; 92 mr->dm = dm; 93 mr->uobject = uobj; 94 atomic_inc(&pd->usecnt); 95 atomic_inc(&dm->usecnt); 96 97 uobj->object = mr; 98 99 ret = uverbs_copy_to(attrs, UVERBS_ATTR_REG_DM_MR_RESP_LKEY, &mr->lkey, 100 sizeof(mr->lkey)); 101 if (ret) 102 goto err_dereg; 103 104 ret = uverbs_copy_to(attrs, UVERBS_ATTR_REG_DM_MR_RESP_RKEY, 105 &mr->rkey, sizeof(mr->rkey)); 106 if (ret) 107 goto err_dereg; 108 109 return 0; 110 111 err_dereg: 112 ib_dereg_mr(mr); 113 114 return ret; 115 } 116 117 DECLARE_UVERBS_NAMED_METHOD( 118 UVERBS_METHOD_DM_MR_REG, 119 UVERBS_ATTR_IDR(UVERBS_ATTR_REG_DM_MR_HANDLE, 120 UVERBS_OBJECT_MR, 121 UVERBS_ACCESS_NEW, 122 UA_MANDATORY), 123 UVERBS_ATTR_PTR_IN(UVERBS_ATTR_REG_DM_MR_OFFSET, 124 UVERBS_ATTR_TYPE(u64), 125 UA_MANDATORY), 126 UVERBS_ATTR_PTR_IN(UVERBS_ATTR_REG_DM_MR_LENGTH, 127 UVERBS_ATTR_TYPE(u64), 128 UA_MANDATORY), 129 UVERBS_ATTR_IDR(UVERBS_ATTR_REG_DM_MR_PD_HANDLE, 130 UVERBS_OBJECT_PD, 131 UVERBS_ACCESS_READ, 132 UA_MANDATORY), 133 UVERBS_ATTR_FLAGS_IN(UVERBS_ATTR_REG_DM_MR_ACCESS_FLAGS, 134 enum ib_access_flags), 135 UVERBS_ATTR_IDR(UVERBS_ATTR_REG_DM_MR_DM_HANDLE, 136 UVERBS_OBJECT_DM, 137 UVERBS_ACCESS_READ, 138 UA_MANDATORY), 139 UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_REG_DM_MR_RESP_LKEY, 140 UVERBS_ATTR_TYPE(u32), 141 UA_MANDATORY), 142 UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_REG_DM_MR_RESP_RKEY, 143 UVERBS_ATTR_TYPE(u32), 144 UA_MANDATORY)); 145 146 DECLARE_UVERBS_NAMED_OBJECT( 147 UVERBS_OBJECT_MR, 148 UVERBS_TYPE_ALLOC_IDR(uverbs_free_mr), 149 &UVERBS_METHOD(UVERBS_METHOD_DM_MR_REG)); 150