1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /*
3  * Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved
4  */
5 
6 #include <linux/kref.h>
7 #include <linux/cdev.h>
8 #include <linux/mutex.h>
9 #include <linux/file.h>
10 #include <linux/fs.h>
11 #include <rdma/ib_ucaps.h>
12 
13 #define RDMA_UCAP_FIRST RDMA_UCAP_MLX5_CTRL_LOCAL
14 
15 static DEFINE_MUTEX(ucaps_mutex);
16 static struct ib_ucap *ucaps_list[RDMA_UCAP_MAX];
17 static bool ucaps_class_is_registered;
18 static dev_t ucaps_base_dev;
19 
20 struct ib_ucap {
21 	struct cdev cdev;
22 	struct device dev;
23 	struct kref ref;
24 };
25 
26 static const char *ucap_names[RDMA_UCAP_MAX] = {
27 	[RDMA_UCAP_MLX5_CTRL_LOCAL] = "mlx5_perm_ctrl_local",
28 	[RDMA_UCAP_MLX5_CTRL_OTHER_VHCA] = "mlx5_perm_ctrl_other_vhca"
29 };
30 
31 static char *ucaps_devnode(const struct device *dev, umode_t *mode)
32 {
33 	if (mode)
34 		*mode = 0600;
35 
36 	return kasprintf(GFP_KERNEL, "infiniband/%s", dev_name(dev));
37 }
38 
39 static const struct class ucaps_class = {
40 	.name = "infiniband_ucaps",
41 	.devnode = ucaps_devnode,
42 };
43 
44 static const struct file_operations ucaps_cdev_fops = {
45 	.owner = THIS_MODULE,
46 	.open = simple_open,
47 };
48 
49 /**
50  * ib_cleanup_ucaps - cleanup all API resources and class.
51  *
52  * This is called once, when removing the ib_uverbs module.
53  */
54 void ib_cleanup_ucaps(void)
55 {
56 	mutex_lock(&ucaps_mutex);
57 	if (!ucaps_class_is_registered) {
58 		mutex_unlock(&ucaps_mutex);
59 		return;
60 	}
61 
62 	for (int i = RDMA_UCAP_FIRST; i < RDMA_UCAP_MAX; i++)
63 		WARN_ON(ucaps_list[i]);
64 
65 	class_unregister(&ucaps_class);
66 	ucaps_class_is_registered = false;
67 	unregister_chrdev_region(ucaps_base_dev, RDMA_UCAP_MAX);
68 	mutex_unlock(&ucaps_mutex);
69 }
70 
71 static int get_ucap_from_devt(dev_t devt, u64 *idx_mask)
72 {
73 	for (int type = RDMA_UCAP_FIRST; type < RDMA_UCAP_MAX; type++) {
74 		if (ucaps_list[type] && ucaps_list[type]->dev.devt == devt) {
75 			*idx_mask |= 1 << type;
76 			return 0;
77 		}
78 	}
79 
80 	return -EINVAL;
81 }
82 
83 static int get_devt_from_fd(unsigned int fd, dev_t *ret_dev)
84 {
85 	struct file *file;
86 
87 	file = fget(fd);
88 	if (!file)
89 		return -EBADF;
90 
91 	*ret_dev = file_inode(file)->i_rdev;
92 	fput(file);
93 	return 0;
94 }
95 
96 /**
97  * ib_ucaps_init - Initialization required before ucap creation.
98  *
99  * Return: 0 on success, or a negative errno value on failure
100  */
101 static int ib_ucaps_init(void)
102 {
103 	int ret = 0;
104 
105 	if (ucaps_class_is_registered)
106 		return ret;
107 
108 	ret = class_register(&ucaps_class);
109 	if (ret)
110 		return ret;
111 
112 	ret = alloc_chrdev_region(&ucaps_base_dev, 0, RDMA_UCAP_MAX,
113 				  ucaps_class.name);
114 	if (ret < 0) {
115 		class_unregister(&ucaps_class);
116 		return ret;
117 	}
118 
119 	ucaps_class_is_registered = true;
120 
121 	return 0;
122 }
123 
124 static void ucap_dev_release(struct device *device)
125 {
126 	struct ib_ucap *ucap = container_of(device, struct ib_ucap, dev);
127 
128 	kfree(ucap);
129 }
130 
131 /**
132  * ib_create_ucap - Add a ucap character device
133  * @type: UCAP type
134  *
135  * Creates a ucap character device in the /dev/infiniband directory. By default,
136  * the device has root-only read-write access.
137  *
138  * A driver may call this multiple times with the same UCAP type. A reference
139  * count tracks creations and deletions.
140  *
141  * Return: 0 on success, or a negative errno value on failure
142  */
143 int ib_create_ucap(enum rdma_user_cap type)
144 {
145 	struct ib_ucap *ucap;
146 	int ret;
147 
148 	if (type >= RDMA_UCAP_MAX)
149 		return -EINVAL;
150 
151 	mutex_lock(&ucaps_mutex);
152 	ret = ib_ucaps_init();
153 	if (ret)
154 		goto unlock;
155 
156 	ucap = ucaps_list[type];
157 	if (ucap) {
158 		kref_get(&ucap->ref);
159 		mutex_unlock(&ucaps_mutex);
160 		return 0;
161 	}
162 
163 	ucap = kzalloc(sizeof(*ucap), GFP_KERNEL);
164 	if (!ucap) {
165 		ret = -ENOMEM;
166 		goto unlock;
167 	}
168 
169 	device_initialize(&ucap->dev);
170 	ucap->dev.class = &ucaps_class;
171 	ucap->dev.devt = MKDEV(MAJOR(ucaps_base_dev), type);
172 	ucap->dev.release = ucap_dev_release;
173 	ret = dev_set_name(&ucap->dev, "%s", ucap_names[type]);
174 	if (ret)
175 		goto err_device;
176 
177 	cdev_init(&ucap->cdev, &ucaps_cdev_fops);
178 	ucap->cdev.owner = THIS_MODULE;
179 
180 	ret = cdev_device_add(&ucap->cdev, &ucap->dev);
181 	if (ret)
182 		goto err_device;
183 
184 	kref_init(&ucap->ref);
185 	ucaps_list[type] = ucap;
186 	mutex_unlock(&ucaps_mutex);
187 
188 	return 0;
189 
190 err_device:
191 	put_device(&ucap->dev);
192 unlock:
193 	mutex_unlock(&ucaps_mutex);
194 	return ret;
195 }
196 EXPORT_SYMBOL(ib_create_ucap);
197 
198 static void ib_release_ucap(struct kref *ref)
199 {
200 	struct ib_ucap *ucap = container_of(ref, struct ib_ucap, ref);
201 	enum rdma_user_cap type;
202 
203 	for (type = RDMA_UCAP_FIRST; type < RDMA_UCAP_MAX; type++) {
204 		if (ucaps_list[type] == ucap)
205 			break;
206 	}
207 	WARN_ON(type == RDMA_UCAP_MAX);
208 
209 	ucaps_list[type] = NULL;
210 	cdev_device_del(&ucap->cdev, &ucap->dev);
211 	put_device(&ucap->dev);
212 }
213 
214 /**
215  * ib_remove_ucap - Remove a ucap character device
216  * @type: User cap type
217  *
218  * Removes the ucap character device according to type. The device is completely
219  * removed from the filesystem when its reference count reaches 0.
220  */
221 void ib_remove_ucap(enum rdma_user_cap type)
222 {
223 	struct ib_ucap *ucap;
224 
225 	mutex_lock(&ucaps_mutex);
226 	ucap = ucaps_list[type];
227 	if (WARN_ON(!ucap))
228 		goto end;
229 
230 	kref_put(&ucap->ref, ib_release_ucap);
231 end:
232 	mutex_unlock(&ucaps_mutex);
233 }
234 EXPORT_SYMBOL(ib_remove_ucap);
235 
236 /**
237  * ib_get_ucaps - Get bitmask of ucap types from file descriptors
238  * @fds: Array of file descriptors
239  * @fd_count: Number of file descriptors in the array
240  * @idx_mask: Bitmask to be updated based on the ucaps in the fd list
241  *
242  * Given an array of file descriptors, this function returns a bitmask of
243  * the ucaps where a bit is set if an FD for that ucap type was in the array.
244  *
245  * Return: 0 on success, or a negative errno value on failure
246  */
247 int ib_get_ucaps(int *fds, int fd_count, uint64_t *idx_mask)
248 {
249 	int ret = 0;
250 	dev_t dev;
251 
252 	*idx_mask = 0;
253 	mutex_lock(&ucaps_mutex);
254 	for (int i = 0; i < fd_count; i++) {
255 		ret = get_devt_from_fd(fds[i], &dev);
256 		if (ret)
257 			goto end;
258 
259 		ret = get_ucap_from_devt(dev, idx_mask);
260 		if (ret)
261 			goto end;
262 	}
263 
264 end:
265 	mutex_unlock(&ucaps_mutex);
266 	return ret;
267 }
268