xref: /openbmc/linux/drivers/nvdimm/bus.c (revision 3d88002e4a7bd40f355550284c6cd140e6fe29dc)
1 /*
2  * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  */
13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 #include <linux/vmalloc.h>
15 #include <linux/uaccess.h>
16 #include <linux/module.h>
17 #include <linux/fcntl.h>
18 #include <linux/async.h>
19 #include <linux/ndctl.h>
20 #include <linux/sched.h>
21 #include <linux/slab.h>
22 #include <linux/fs.h>
23 #include <linux/io.h>
24 #include <linux/mm.h>
25 #include <linux/nd.h>
26 #include "nd-core.h"
27 #include "nd.h"
28 
29 int nvdimm_major;
30 static int nvdimm_bus_major;
31 static struct class *nd_class;
32 
33 static int to_nd_device_type(struct device *dev)
34 {
35 	if (is_nvdimm(dev))
36 		return ND_DEVICE_DIMM;
37 	else if (is_nd_pmem(dev))
38 		return ND_DEVICE_REGION_PMEM;
39 	else if (is_nd_blk(dev))
40 		return ND_DEVICE_REGION_BLK;
41 	else if (is_nd_pmem(dev->parent) || is_nd_blk(dev->parent))
42 		return nd_region_to_nstype(to_nd_region(dev->parent));
43 
44 	return 0;
45 }
46 
47 static int nvdimm_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
48 {
49 	return add_uevent_var(env, "MODALIAS=" ND_DEVICE_MODALIAS_FMT,
50 			to_nd_device_type(dev));
51 }
52 
53 static int nvdimm_bus_match(struct device *dev, struct device_driver *drv)
54 {
55 	struct nd_device_driver *nd_drv = to_nd_device_driver(drv);
56 
57 	return test_bit(to_nd_device_type(dev), &nd_drv->type);
58 }
59 
60 static struct module *to_bus_provider(struct device *dev)
61 {
62 	/* pin bus providers while regions are enabled */
63 	if (is_nd_pmem(dev) || is_nd_blk(dev)) {
64 		struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
65 
66 		return nvdimm_bus->module;
67 	}
68 	return NULL;
69 }
70 
71 static int nvdimm_bus_probe(struct device *dev)
72 {
73 	struct nd_device_driver *nd_drv = to_nd_device_driver(dev->driver);
74 	struct module *provider = to_bus_provider(dev);
75 	struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
76 	int rc;
77 
78 	if (!try_module_get(provider))
79 		return -ENXIO;
80 
81 	rc = nd_drv->probe(dev);
82 	dev_dbg(&nvdimm_bus->dev, "%s.probe(%s) = %d\n", dev->driver->name,
83 			dev_name(dev), rc);
84 	if (rc != 0)
85 		module_put(provider);
86 	return rc;
87 }
88 
89 static int nvdimm_bus_remove(struct device *dev)
90 {
91 	struct nd_device_driver *nd_drv = to_nd_device_driver(dev->driver);
92 	struct module *provider = to_bus_provider(dev);
93 	struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
94 	int rc;
95 
96 	rc = nd_drv->remove(dev);
97 	dev_dbg(&nvdimm_bus->dev, "%s.remove(%s) = %d\n", dev->driver->name,
98 			dev_name(dev), rc);
99 	module_put(provider);
100 	return rc;
101 }
102 
103 static struct bus_type nvdimm_bus_type = {
104 	.name = "nd",
105 	.uevent = nvdimm_bus_uevent,
106 	.match = nvdimm_bus_match,
107 	.probe = nvdimm_bus_probe,
108 	.remove = nvdimm_bus_remove,
109 };
110 
111 static ASYNC_DOMAIN_EXCLUSIVE(nd_async_domain);
112 
113 void nd_synchronize(void)
114 {
115 	async_synchronize_full_domain(&nd_async_domain);
116 }
117 EXPORT_SYMBOL_GPL(nd_synchronize);
118 
119 static void nd_async_device_register(void *d, async_cookie_t cookie)
120 {
121 	struct device *dev = d;
122 
123 	if (device_add(dev) != 0) {
124 		dev_err(dev, "%s: failed\n", __func__);
125 		put_device(dev);
126 	}
127 	put_device(dev);
128 }
129 
130 static void nd_async_device_unregister(void *d, async_cookie_t cookie)
131 {
132 	struct device *dev = d;
133 
134 	device_unregister(dev);
135 	put_device(dev);
136 }
137 
138 void nd_device_register(struct device *dev)
139 {
140 	dev->bus = &nvdimm_bus_type;
141 	device_initialize(dev);
142 	get_device(dev);
143 	async_schedule_domain(nd_async_device_register, dev,
144 			&nd_async_domain);
145 }
146 EXPORT_SYMBOL(nd_device_register);
147 
148 void nd_device_unregister(struct device *dev, enum nd_async_mode mode)
149 {
150 	switch (mode) {
151 	case ND_ASYNC:
152 		get_device(dev);
153 		async_schedule_domain(nd_async_device_unregister, dev,
154 				&nd_async_domain);
155 		break;
156 	case ND_SYNC:
157 		nd_synchronize();
158 		device_unregister(dev);
159 		break;
160 	}
161 }
162 EXPORT_SYMBOL(nd_device_unregister);
163 
164 /**
165  * __nd_driver_register() - register a region or a namespace driver
166  * @nd_drv: driver to register
167  * @owner: automatically set by nd_driver_register() macro
168  * @mod_name: automatically set by nd_driver_register() macro
169  */
170 int __nd_driver_register(struct nd_device_driver *nd_drv, struct module *owner,
171 		const char *mod_name)
172 {
173 	struct device_driver *drv = &nd_drv->drv;
174 
175 	if (!nd_drv->type) {
176 		pr_debug("driver type bitmask not set (%pf)\n",
177 				__builtin_return_address(0));
178 		return -EINVAL;
179 	}
180 
181 	if (!nd_drv->probe || !nd_drv->remove) {
182 		pr_debug("->probe() and ->remove() must be specified\n");
183 		return -EINVAL;
184 	}
185 
186 	drv->bus = &nvdimm_bus_type;
187 	drv->owner = owner;
188 	drv->mod_name = mod_name;
189 
190 	return driver_register(drv);
191 }
192 EXPORT_SYMBOL(__nd_driver_register);
193 
194 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
195 		char *buf)
196 {
197 	return sprintf(buf, ND_DEVICE_MODALIAS_FMT "\n",
198 			to_nd_device_type(dev));
199 }
200 static DEVICE_ATTR_RO(modalias);
201 
202 static ssize_t devtype_show(struct device *dev, struct device_attribute *attr,
203 		char *buf)
204 {
205 	return sprintf(buf, "%s\n", dev->type->name);
206 }
207 static DEVICE_ATTR_RO(devtype);
208 
209 static struct attribute *nd_device_attributes[] = {
210 	&dev_attr_modalias.attr,
211 	&dev_attr_devtype.attr,
212 	NULL,
213 };
214 
215 /**
216  * nd_device_attribute_group - generic attributes for all devices on an nd bus
217  */
218 struct attribute_group nd_device_attribute_group = {
219 	.attrs = nd_device_attributes,
220 };
221 EXPORT_SYMBOL_GPL(nd_device_attribute_group);
222 
223 int nvdimm_bus_create_ndctl(struct nvdimm_bus *nvdimm_bus)
224 {
225 	dev_t devt = MKDEV(nvdimm_bus_major, nvdimm_bus->id);
226 	struct device *dev;
227 
228 	dev = device_create(nd_class, &nvdimm_bus->dev, devt, nvdimm_bus,
229 			"ndctl%d", nvdimm_bus->id);
230 
231 	if (IS_ERR(dev)) {
232 		dev_dbg(&nvdimm_bus->dev, "failed to register ndctl%d: %ld\n",
233 				nvdimm_bus->id, PTR_ERR(dev));
234 		return PTR_ERR(dev);
235 	}
236 	return 0;
237 }
238 
239 void nvdimm_bus_destroy_ndctl(struct nvdimm_bus *nvdimm_bus)
240 {
241 	device_destroy(nd_class, MKDEV(nvdimm_bus_major, nvdimm_bus->id));
242 }
243 
244 static const struct nd_cmd_desc __nd_cmd_dimm_descs[] = {
245 	[ND_CMD_IMPLEMENTED] = { },
246 	[ND_CMD_SMART] = {
247 		.out_num = 2,
248 		.out_sizes = { 4, 8, },
249 	},
250 	[ND_CMD_SMART_THRESHOLD] = {
251 		.out_num = 2,
252 		.out_sizes = { 4, 8, },
253 	},
254 	[ND_CMD_DIMM_FLAGS] = {
255 		.out_num = 2,
256 		.out_sizes = { 4, 4 },
257 	},
258 	[ND_CMD_GET_CONFIG_SIZE] = {
259 		.out_num = 3,
260 		.out_sizes = { 4, 4, 4, },
261 	},
262 	[ND_CMD_GET_CONFIG_DATA] = {
263 		.in_num = 2,
264 		.in_sizes = { 4, 4, },
265 		.out_num = 2,
266 		.out_sizes = { 4, UINT_MAX, },
267 	},
268 	[ND_CMD_SET_CONFIG_DATA] = {
269 		.in_num = 3,
270 		.in_sizes = { 4, 4, UINT_MAX, },
271 		.out_num = 1,
272 		.out_sizes = { 4, },
273 	},
274 	[ND_CMD_VENDOR] = {
275 		.in_num = 3,
276 		.in_sizes = { 4, 4, UINT_MAX, },
277 		.out_num = 3,
278 		.out_sizes = { 4, 4, UINT_MAX, },
279 	},
280 };
281 
282 const struct nd_cmd_desc *nd_cmd_dimm_desc(int cmd)
283 {
284 	if (cmd < ARRAY_SIZE(__nd_cmd_dimm_descs))
285 		return &__nd_cmd_dimm_descs[cmd];
286 	return NULL;
287 }
288 EXPORT_SYMBOL_GPL(nd_cmd_dimm_desc);
289 
290 static const struct nd_cmd_desc __nd_cmd_bus_descs[] = {
291 	[ND_CMD_IMPLEMENTED] = { },
292 	[ND_CMD_ARS_CAP] = {
293 		.in_num = 2,
294 		.in_sizes = { 8, 8, },
295 		.out_num = 2,
296 		.out_sizes = { 4, 4, },
297 	},
298 	[ND_CMD_ARS_START] = {
299 		.in_num = 4,
300 		.in_sizes = { 8, 8, 2, 6, },
301 		.out_num = 1,
302 		.out_sizes = { 4, },
303 	},
304 	[ND_CMD_ARS_STATUS] = {
305 		.out_num = 2,
306 		.out_sizes = { 4, UINT_MAX, },
307 	},
308 };
309 
310 const struct nd_cmd_desc *nd_cmd_bus_desc(int cmd)
311 {
312 	if (cmd < ARRAY_SIZE(__nd_cmd_bus_descs))
313 		return &__nd_cmd_bus_descs[cmd];
314 	return NULL;
315 }
316 EXPORT_SYMBOL_GPL(nd_cmd_bus_desc);
317 
318 u32 nd_cmd_in_size(struct nvdimm *nvdimm, int cmd,
319 		const struct nd_cmd_desc *desc, int idx, void *buf)
320 {
321 	if (idx >= desc->in_num)
322 		return UINT_MAX;
323 
324 	if (desc->in_sizes[idx] < UINT_MAX)
325 		return desc->in_sizes[idx];
326 
327 	if (nvdimm && cmd == ND_CMD_SET_CONFIG_DATA && idx == 2) {
328 		struct nd_cmd_set_config_hdr *hdr = buf;
329 
330 		return hdr->in_length;
331 	} else if (nvdimm && cmd == ND_CMD_VENDOR && idx == 2) {
332 		struct nd_cmd_vendor_hdr *hdr = buf;
333 
334 		return hdr->in_length;
335 	}
336 
337 	return UINT_MAX;
338 }
339 EXPORT_SYMBOL_GPL(nd_cmd_in_size);
340 
341 u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd,
342 		const struct nd_cmd_desc *desc, int idx, const u32 *in_field,
343 		const u32 *out_field)
344 {
345 	if (idx >= desc->out_num)
346 		return UINT_MAX;
347 
348 	if (desc->out_sizes[idx] < UINT_MAX)
349 		return desc->out_sizes[idx];
350 
351 	if (nvdimm && cmd == ND_CMD_GET_CONFIG_DATA && idx == 1)
352 		return in_field[1];
353 	else if (nvdimm && cmd == ND_CMD_VENDOR && idx == 2)
354 		return out_field[1];
355 	else if (!nvdimm && cmd == ND_CMD_ARS_STATUS && idx == 1)
356 		return ND_CMD_ARS_STATUS_MAX;
357 
358 	return UINT_MAX;
359 }
360 EXPORT_SYMBOL_GPL(nd_cmd_out_size);
361 
362 static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
363 		int read_only, unsigned int ioctl_cmd, unsigned long arg)
364 {
365 	struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
366 	size_t buf_len = 0, in_len = 0, out_len = 0;
367 	static char out_env[ND_CMD_MAX_ENVELOPE];
368 	static char in_env[ND_CMD_MAX_ENVELOPE];
369 	const struct nd_cmd_desc *desc = NULL;
370 	unsigned int cmd = _IOC_NR(ioctl_cmd);
371 	void __user *p = (void __user *) arg;
372 	struct device *dev = &nvdimm_bus->dev;
373 	const char *cmd_name, *dimm_name;
374 	unsigned long dsm_mask;
375 	void *buf;
376 	int rc, i;
377 
378 	if (nvdimm) {
379 		desc = nd_cmd_dimm_desc(cmd);
380 		cmd_name = nvdimm_cmd_name(cmd);
381 		dsm_mask = nvdimm->dsm_mask ? *(nvdimm->dsm_mask) : 0;
382 		dimm_name = dev_name(&nvdimm->dev);
383 	} else {
384 		desc = nd_cmd_bus_desc(cmd);
385 		cmd_name = nvdimm_bus_cmd_name(cmd);
386 		dsm_mask = nd_desc->dsm_mask;
387 		dimm_name = "bus";
388 	}
389 
390 	if (!desc || (desc->out_num + desc->in_num == 0) ||
391 			!test_bit(cmd, &dsm_mask))
392 		return -ENOTTY;
393 
394 	/* fail write commands (when read-only) */
395 	if (read_only)
396 		switch (ioctl_cmd) {
397 		case ND_IOCTL_VENDOR:
398 		case ND_IOCTL_SET_CONFIG_DATA:
399 		case ND_IOCTL_ARS_START:
400 			dev_dbg(&nvdimm_bus->dev, "'%s' command while read-only.\n",
401 					nvdimm ? nvdimm_cmd_name(cmd)
402 					: nvdimm_bus_cmd_name(cmd));
403 			return -EPERM;
404 		default:
405 			break;
406 		}
407 
408 	/* process an input envelope */
409 	for (i = 0; i < desc->in_num; i++) {
410 		u32 in_size, copy;
411 
412 		in_size = nd_cmd_in_size(nvdimm, cmd, desc, i, in_env);
413 		if (in_size == UINT_MAX) {
414 			dev_err(dev, "%s:%s unknown input size cmd: %s field: %d\n",
415 					__func__, dimm_name, cmd_name, i);
416 			return -ENXIO;
417 		}
418 		if (!access_ok(VERIFY_READ, p + in_len, in_size))
419 			return -EFAULT;
420 		if (in_len < sizeof(in_env))
421 			copy = min_t(u32, sizeof(in_env) - in_len, in_size);
422 		else
423 			copy = 0;
424 		if (copy && copy_from_user(&in_env[in_len], p + in_len, copy))
425 			return -EFAULT;
426 		in_len += in_size;
427 	}
428 
429 	/* process an output envelope */
430 	for (i = 0; i < desc->out_num; i++) {
431 		u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i,
432 				(u32 *) in_env, (u32 *) out_env);
433 		u32 copy;
434 
435 		if (out_size == UINT_MAX) {
436 			dev_dbg(dev, "%s:%s unknown output size cmd: %s field: %d\n",
437 					__func__, dimm_name, cmd_name, i);
438 			return -EFAULT;
439 		}
440 		if (!access_ok(VERIFY_WRITE, p + in_len + out_len, out_size))
441 			return -EFAULT;
442 		if (out_len < sizeof(out_env))
443 			copy = min_t(u32, sizeof(out_env) - out_len, out_size);
444 		else
445 			copy = 0;
446 		if (copy && copy_from_user(&out_env[out_len],
447 					p + in_len + out_len, copy))
448 			return -EFAULT;
449 		out_len += out_size;
450 	}
451 
452 	buf_len = out_len + in_len;
453 	if (!access_ok(VERIFY_WRITE, p, sizeof(buf_len)))
454 		return -EFAULT;
455 
456 	if (buf_len > ND_IOCTL_MAX_BUFLEN) {
457 		dev_dbg(dev, "%s:%s cmd: %s buf_len: %zu > %d\n", __func__,
458 				dimm_name, cmd_name, buf_len,
459 				ND_IOCTL_MAX_BUFLEN);
460 		return -EINVAL;
461 	}
462 
463 	buf = vmalloc(buf_len);
464 	if (!buf)
465 		return -ENOMEM;
466 
467 	if (copy_from_user(buf, p, buf_len)) {
468 		rc = -EFAULT;
469 		goto out;
470 	}
471 
472 	rc = nd_desc->ndctl(nd_desc, nvdimm, cmd, buf, buf_len);
473 	if (rc < 0)
474 		goto out;
475 	if (copy_to_user(p, buf, buf_len))
476 		rc = -EFAULT;
477  out:
478 	vfree(buf);
479 	return rc;
480 }
481 
482 static long nd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
483 {
484 	long id = (long) file->private_data;
485 	int rc = -ENXIO, read_only;
486 	struct nvdimm_bus *nvdimm_bus;
487 
488 	read_only = (O_RDWR != (file->f_flags & O_ACCMODE));
489 	mutex_lock(&nvdimm_bus_list_mutex);
490 	list_for_each_entry(nvdimm_bus, &nvdimm_bus_list, list) {
491 		if (nvdimm_bus->id == id) {
492 			rc = __nd_ioctl(nvdimm_bus, NULL, read_only, cmd, arg);
493 			break;
494 		}
495 	}
496 	mutex_unlock(&nvdimm_bus_list_mutex);
497 
498 	return rc;
499 }
500 
501 static int match_dimm(struct device *dev, void *data)
502 {
503 	long id = (long) data;
504 
505 	if (is_nvdimm(dev)) {
506 		struct nvdimm *nvdimm = to_nvdimm(dev);
507 
508 		return nvdimm->id == id;
509 	}
510 
511 	return 0;
512 }
513 
514 static long nvdimm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
515 {
516 	int rc = -ENXIO, read_only;
517 	struct nvdimm_bus *nvdimm_bus;
518 
519 	read_only = (O_RDWR != (file->f_flags & O_ACCMODE));
520 	mutex_lock(&nvdimm_bus_list_mutex);
521 	list_for_each_entry(nvdimm_bus, &nvdimm_bus_list, list) {
522 		struct device *dev = device_find_child(&nvdimm_bus->dev,
523 				file->private_data, match_dimm);
524 		struct nvdimm *nvdimm;
525 
526 		if (!dev)
527 			continue;
528 
529 		nvdimm = to_nvdimm(dev);
530 		rc = __nd_ioctl(nvdimm_bus, nvdimm, read_only, cmd, arg);
531 		put_device(dev);
532 		break;
533 	}
534 	mutex_unlock(&nvdimm_bus_list_mutex);
535 
536 	return rc;
537 }
538 
539 static int nd_open(struct inode *inode, struct file *file)
540 {
541 	long minor = iminor(inode);
542 
543 	file->private_data = (void *) minor;
544 	return 0;
545 }
546 
547 static const struct file_operations nvdimm_bus_fops = {
548 	.owner = THIS_MODULE,
549 	.open = nd_open,
550 	.unlocked_ioctl = nd_ioctl,
551 	.compat_ioctl = nd_ioctl,
552 	.llseek = noop_llseek,
553 };
554 
555 static const struct file_operations nvdimm_fops = {
556 	.owner = THIS_MODULE,
557 	.open = nd_open,
558 	.unlocked_ioctl = nvdimm_ioctl,
559 	.compat_ioctl = nvdimm_ioctl,
560 	.llseek = noop_llseek,
561 };
562 
563 int __init nvdimm_bus_init(void)
564 {
565 	int rc;
566 
567 	rc = bus_register(&nvdimm_bus_type);
568 	if (rc)
569 		return rc;
570 
571 	rc = register_chrdev(0, "ndctl", &nvdimm_bus_fops);
572 	if (rc < 0)
573 		goto err_bus_chrdev;
574 	nvdimm_bus_major = rc;
575 
576 	rc = register_chrdev(0, "dimmctl", &nvdimm_fops);
577 	if (rc < 0)
578 		goto err_dimm_chrdev;
579 	nvdimm_major = rc;
580 
581 	nd_class = class_create(THIS_MODULE, "nd");
582 	if (IS_ERR(nd_class))
583 		goto err_class;
584 
585 	return 0;
586 
587  err_class:
588 	unregister_chrdev(nvdimm_major, "dimmctl");
589  err_dimm_chrdev:
590 	unregister_chrdev(nvdimm_bus_major, "ndctl");
591  err_bus_chrdev:
592 	bus_unregister(&nvdimm_bus_type);
593 
594 	return rc;
595 }
596 
597 void nvdimm_bus_exit(void)
598 {
599 	class_destroy(nd_class);
600 	unregister_chrdev(nvdimm_bus_major, "ndctl");
601 	unregister_chrdev(nvdimm_major, "dimmctl");
602 	bus_unregister(&nvdimm_bus_type);
603 }
604