xref: /openbmc/linux/fs/pstore/blk.c (revision 335426c6)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Implements pstore backend driver that write to block (or non-block) storage
4  * devices, using the pstore/zone API.
5  */
6 
7 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8 
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include "../../block/blk.h"
12 #include <linux/blkdev.h>
13 #include <linux/string.h>
14 #include <linux/of.h>
15 #include <linux/of_address.h>
16 #include <linux/platform_device.h>
17 #include <linux/pstore_blk.h>
18 #include <linux/mount.h>
19 #include <linux/uio.h>
20 
21 static long kmsg_size = CONFIG_PSTORE_BLK_KMSG_SIZE;
22 module_param(kmsg_size, long, 0400);
23 MODULE_PARM_DESC(kmsg_size, "kmsg dump record size in kbytes");
24 
25 static int max_reason = CONFIG_PSTORE_BLK_MAX_REASON;
26 module_param(max_reason, int, 0400);
27 MODULE_PARM_DESC(max_reason,
28 		 "maximum reason for kmsg dump (default 2: Oops and Panic)");
29 
30 #if IS_ENABLED(CONFIG_PSTORE_PMSG)
31 static long pmsg_size = CONFIG_PSTORE_BLK_PMSG_SIZE;
32 #else
33 static long pmsg_size = -1;
34 #endif
35 module_param(pmsg_size, long, 0400);
36 MODULE_PARM_DESC(pmsg_size, "pmsg size in kbytes");
37 
38 #if IS_ENABLED(CONFIG_PSTORE_CONSOLE)
39 static long console_size = CONFIG_PSTORE_BLK_CONSOLE_SIZE;
40 #else
41 static long console_size = -1;
42 #endif
43 module_param(console_size, long, 0400);
44 MODULE_PARM_DESC(console_size, "console size in kbytes");
45 
46 #if IS_ENABLED(CONFIG_PSTORE_FTRACE)
47 static long ftrace_size = CONFIG_PSTORE_BLK_FTRACE_SIZE;
48 #else
49 static long ftrace_size = -1;
50 #endif
51 module_param(ftrace_size, long, 0400);
52 MODULE_PARM_DESC(ftrace_size, "ftrace size in kbytes");
53 
54 /*
55  * blkdev - the block device to use for pstore storage
56  *
57  * Usually, this will be a partition of a block device.
58  *
59  * blkdev accepts the following variants:
60  * 1) <hex_major><hex_minor> device number in hexadecimal representation,
61  *    with no leading 0x, for example b302.
62  * 2) /dev/<disk_name> represents the device number of disk
63  * 3) /dev/<disk_name><decimal> represents the device number
64  *    of partition - device number of disk plus the partition number
65  * 4) /dev/<disk_name>p<decimal> - same as the above, that form is
66  *    used when disk name of partitioned disk ends on a digit.
67  * 5) PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing the
68  *    unique id of a partition if the partition table provides it.
69  *    The UUID may be either an EFI/GPT UUID, or refer to an MSDOS
70  *    partition using the format SSSSSSSS-PP, where SSSSSSSS is a zero-
71  *    filled hex representation of the 32-bit "NT disk signature", and PP
72  *    is a zero-filled hex representation of the 1-based partition number.
73  * 6) PARTUUID=<UUID>/PARTNROFF=<int> to select a partition in relation to
74  *    a partition with a known unique id.
75  * 7) <major>:<minor> major and minor number of the device separated by
76  *    a colon.
77  */
78 static char blkdev[80] = CONFIG_PSTORE_BLK_BLKDEV;
79 module_param_string(blkdev, blkdev, 80, 0400);
80 MODULE_PARM_DESC(blkdev, "block device for pstore storage");
81 
82 /*
83  * All globals must only be accessed under the pstore_blk_lock
84  * during the register/unregister functions.
85  */
86 static DEFINE_MUTEX(pstore_blk_lock);
87 static struct block_device *psblk_bdev;
88 static struct pstore_zone_info *pstore_zone_info;
89 static pstore_blk_panic_write_op blkdev_panic_write;
90 
91 struct bdev_info {
92 	dev_t devt;
93 	sector_t nr_sects;
94 	sector_t start_sect;
95 };
96 
97 /**
98  * struct pstore_device_info - back-end pstore/blk driver structure.
99  *
100  * @total_size: The total size in bytes pstore/blk can use. It must be greater
101  *		than 4096 and be multiple of 4096.
102  * @flags:	Refer to macro starting with PSTORE_FLAGS defined in
103  *		linux/pstore.h. It means what front-ends this device support.
104  *		Zero means all backends for compatible.
105  * @read:	The general read operation. Both of the function parameters
106  *		@size and @offset are relative value to bock device (not the
107  *		whole disk).
108  *		On success, the number of bytes should be returned, others
109  *		means error.
110  * @write:	The same as @read, but the following error number:
111  *		-EBUSY means try to write again later.
112  *		-ENOMSG means to try next zone.
113  * @panic_write:The write operation only used for panic case. It's optional
114  *		if you do not care panic log. The parameters are relative
115  *		value to storage.
116  *		On success, the number of bytes should be returned, others
117  *		excluding -ENOMSG mean error. -ENOMSG means to try next zone.
118  */
119 struct pstore_device_info {
120 	unsigned long total_size;
121 	unsigned int flags;
122 	pstore_zone_read_op read;
123 	pstore_zone_write_op write;
124 	pstore_zone_write_op panic_write;
125 };
126 
127 static int psblk_register_do(struct pstore_device_info *dev)
128 {
129 	int ret;
130 
131 	if (!dev || !dev->total_size || !dev->read || !dev->write)
132 		return -EINVAL;
133 
134 	mutex_lock(&pstore_blk_lock);
135 
136 	/* someone already registered before */
137 	if (pstore_zone_info) {
138 		mutex_unlock(&pstore_blk_lock);
139 		return -EBUSY;
140 	}
141 	pstore_zone_info = kzalloc(sizeof(struct pstore_zone_info), GFP_KERNEL);
142 	if (!pstore_zone_info) {
143 		mutex_unlock(&pstore_blk_lock);
144 		return -ENOMEM;
145 	}
146 
147 	/* zero means not limit on which backends to attempt to store. */
148 	if (!dev->flags)
149 		dev->flags = UINT_MAX;
150 
151 #define verify_size(name, alignsize, enabled) {				\
152 		long _##name_ = (enabled) ? (name) : 0;			\
153 		_##name_ = _##name_ <= 0 ? 0 : (_##name_ * 1024);	\
154 		if (_##name_ & ((alignsize) - 1)) {			\
155 			pr_info(#name " must align to %d\n",		\
156 					(alignsize));			\
157 			_##name_ = ALIGN(name, (alignsize));		\
158 		}							\
159 		name = _##name_ / 1024;					\
160 		pstore_zone_info->name = _##name_;			\
161 	}
162 
163 	verify_size(kmsg_size, 4096, dev->flags & PSTORE_FLAGS_DMESG);
164 	verify_size(pmsg_size, 4096, dev->flags & PSTORE_FLAGS_PMSG);
165 	verify_size(console_size, 4096, dev->flags & PSTORE_FLAGS_CONSOLE);
166 	verify_size(ftrace_size, 4096, dev->flags & PSTORE_FLAGS_FTRACE);
167 #undef verify_size
168 
169 	pstore_zone_info->total_size = dev->total_size;
170 	pstore_zone_info->max_reason = max_reason;
171 	pstore_zone_info->read = dev->read;
172 	pstore_zone_info->write = dev->write;
173 	pstore_zone_info->panic_write = dev->panic_write;
174 	pstore_zone_info->name = KBUILD_MODNAME;
175 	pstore_zone_info->owner = THIS_MODULE;
176 
177 	ret = register_pstore_zone(pstore_zone_info);
178 	if (ret) {
179 		kfree(pstore_zone_info);
180 		pstore_zone_info = NULL;
181 	}
182 	mutex_unlock(&pstore_blk_lock);
183 	return ret;
184 }
185 
186 static void psblk_unregister_do(struct pstore_device_info *dev)
187 {
188 	mutex_lock(&pstore_blk_lock);
189 	if (pstore_zone_info && pstore_zone_info->read == dev->read) {
190 		unregister_pstore_zone(pstore_zone_info);
191 		kfree(pstore_zone_info);
192 		pstore_zone_info = NULL;
193 	}
194 	mutex_unlock(&pstore_blk_lock);
195 }
196 
197 /**
198  * psblk_get_bdev() - open block device
199  *
200  * @holder:	Exclusive holder identifier
201  * @info:	Information about bdev to fill in
202  *
203  * Return: pointer to block device on success and others on error.
204  *
205  * On success, the returned block_device has reference count of one.
206  */
207 static struct block_device *psblk_get_bdev(void *holder,
208 					   struct bdev_info *info)
209 {
210 	struct block_device *bdev = ERR_PTR(-ENODEV);
211 	fmode_t mode = FMODE_READ | FMODE_WRITE;
212 	sector_t nr_sects;
213 
214 	lockdep_assert_held(&pstore_blk_lock);
215 
216 	if (pstore_zone_info)
217 		return ERR_PTR(-EBUSY);
218 
219 	if (!blkdev[0])
220 		return ERR_PTR(-ENODEV);
221 
222 	if (holder)
223 		mode |= FMODE_EXCL;
224 	bdev = blkdev_get_by_path(blkdev, mode, holder);
225 	if (IS_ERR(bdev)) {
226 		dev_t devt;
227 
228 		devt = name_to_dev_t(blkdev);
229 		if (devt == 0)
230 			return ERR_PTR(-ENODEV);
231 		bdev = blkdev_get_by_dev(devt, mode, holder);
232 		if (IS_ERR(bdev))
233 			return bdev;
234 	}
235 
236 	nr_sects = part_nr_sects_read(bdev->bd_part);
237 	if (!nr_sects) {
238 		pr_err("not enough space for '%s'\n", blkdev);
239 		blkdev_put(bdev, mode);
240 		return ERR_PTR(-ENOSPC);
241 	}
242 
243 	if (info) {
244 		info->devt = bdev->bd_dev;
245 		info->nr_sects = nr_sects;
246 		info->start_sect = get_start_sect(bdev);
247 	}
248 
249 	return bdev;
250 }
251 
252 static void psblk_put_bdev(struct block_device *bdev, void *holder)
253 {
254 	fmode_t mode = FMODE_READ | FMODE_WRITE;
255 
256 	lockdep_assert_held(&pstore_blk_lock);
257 
258 	if (!bdev)
259 		return;
260 
261 	if (holder)
262 		mode |= FMODE_EXCL;
263 	blkdev_put(bdev, mode);
264 }
265 
266 static ssize_t psblk_generic_blk_read(char *buf, size_t bytes, loff_t pos)
267 {
268 	struct block_device *bdev = psblk_bdev;
269 	struct file file;
270 	struct kiocb kiocb;
271 	struct iov_iter iter;
272 	struct kvec iov = {.iov_base = buf, .iov_len = bytes};
273 
274 	if (!bdev)
275 		return -ENODEV;
276 
277 	memset(&file, 0, sizeof(struct file));
278 	file.f_mapping = bdev->bd_inode->i_mapping;
279 	file.f_flags = O_DSYNC | __O_SYNC | O_NOATIME;
280 	file.f_inode = bdev->bd_inode;
281 	file_ra_state_init(&file.f_ra, file.f_mapping);
282 
283 	init_sync_kiocb(&kiocb, &file);
284 	kiocb.ki_pos = pos;
285 	iov_iter_kvec(&iter, READ, &iov, 1, bytes);
286 
287 	return generic_file_read_iter(&kiocb, &iter);
288 }
289 
290 static ssize_t psblk_generic_blk_write(const char *buf, size_t bytes,
291 		loff_t pos)
292 {
293 	struct block_device *bdev = psblk_bdev;
294 	struct iov_iter iter;
295 	struct kiocb kiocb;
296 	struct file file;
297 	ssize_t ret;
298 	struct kvec iov = {.iov_base = (void *)buf, .iov_len = bytes};
299 
300 	if (!bdev)
301 		return -ENODEV;
302 
303 	/* Console/Ftrace backend may handle buffer until flush dirty zones */
304 	if (in_interrupt() || irqs_disabled())
305 		return -EBUSY;
306 
307 	memset(&file, 0, sizeof(struct file));
308 	file.f_mapping = bdev->bd_inode->i_mapping;
309 	file.f_flags = O_DSYNC | __O_SYNC | O_NOATIME;
310 	file.f_inode = bdev->bd_inode;
311 
312 	init_sync_kiocb(&kiocb, &file);
313 	kiocb.ki_pos = pos;
314 	iov_iter_kvec(&iter, WRITE, &iov, 1, bytes);
315 
316 	inode_lock(bdev->bd_inode);
317 	ret = generic_write_checks(&kiocb, &iter);
318 	if (ret > 0)
319 		ret = generic_perform_write(&file, &iter, pos);
320 	inode_unlock(bdev->bd_inode);
321 
322 	if (likely(ret > 0)) {
323 		const struct file_operations f_op = {.fsync = blkdev_fsync};
324 
325 		file.f_op = &f_op;
326 		kiocb.ki_pos += ret;
327 		ret = generic_write_sync(&kiocb, ret);
328 	}
329 	return ret;
330 }
331 
332 static ssize_t psblk_blk_panic_write(const char *buf, size_t size,
333 		loff_t off)
334 {
335 	int ret;
336 
337 	if (!blkdev_panic_write)
338 		return -EOPNOTSUPP;
339 
340 	/* size and off must align to SECTOR_SIZE for block device */
341 	ret = blkdev_panic_write(buf, off >> SECTOR_SHIFT,
342 			size >> SECTOR_SHIFT);
343 	/* try next zone */
344 	if (ret == -ENOMSG)
345 		return ret;
346 	return ret ? -EIO : size;
347 }
348 
349 static int __register_pstore_blk(struct pstore_blk_info *info)
350 {
351 	char bdev_name[BDEVNAME_SIZE];
352 	struct block_device *bdev;
353 	struct pstore_device_info dev;
354 	struct bdev_info binfo;
355 	void *holder = blkdev;
356 	int ret = -ENODEV;
357 
358 	lockdep_assert_held(&pstore_blk_lock);
359 
360 	/* hold bdev exclusively */
361 	memset(&binfo, 0, sizeof(binfo));
362 	bdev = psblk_get_bdev(holder, &binfo);
363 	if (IS_ERR(bdev)) {
364 		pr_err("failed to open '%s'!\n", blkdev);
365 		return PTR_ERR(bdev);
366 	}
367 
368 	/* only allow driver matching the @blkdev */
369 	if (!binfo.devt || MAJOR(binfo.devt) != info->major) {
370 		pr_debug("invalid major %u (expect %u)\n",
371 				info->major, MAJOR(binfo.devt));
372 		ret = -ENODEV;
373 		goto err_put_bdev;
374 	}
375 
376 	/* psblk_bdev must be assigned before register to pstore/blk */
377 	psblk_bdev = bdev;
378 	blkdev_panic_write = info->panic_write;
379 
380 	/* Copy back block device details. */
381 	info->devt = binfo.devt;
382 	info->nr_sects = binfo.nr_sects;
383 	info->start_sect = binfo.start_sect;
384 
385 	memset(&dev, 0, sizeof(dev));
386 	dev.total_size = info->nr_sects << SECTOR_SHIFT;
387 	dev.flags = info->flags;
388 	dev.read = psblk_generic_blk_read;
389 	dev.write = psblk_generic_blk_write;
390 	dev.panic_write = info->panic_write ? psblk_blk_panic_write : NULL;
391 
392 	ret = psblk_register_do(&dev);
393 	if (ret)
394 		goto err_put_bdev;
395 
396 	bdevname(bdev, bdev_name);
397 	pr_info("attached %s%s\n", bdev_name,
398 		info->panic_write ? "" : " (no dedicated panic_write!)");
399 	return 0;
400 
401 err_put_bdev:
402 	psblk_bdev = NULL;
403 	blkdev_panic_write = NULL;
404 	psblk_put_bdev(bdev, holder);
405 	return ret;
406 }
407 
408 /**
409  * register_pstore_blk() - register block device to pstore/blk
410  *
411  * @info: details on the desired block device interface
412  *
413  * Return:
414  * * 0		- OK
415  * * Others	- something error.
416  */
417 int register_pstore_blk(struct pstore_blk_info *info)
418 {
419 	int ret;
420 
421 	mutex_lock(&pstore_blk_lock);
422 	ret = __register_pstore_blk(info);
423 	mutex_unlock(&pstore_blk_lock);
424 
425 	return ret;
426 }
427 EXPORT_SYMBOL_GPL(register_pstore_blk);
428 
429 static void __unregister_pstore_blk(unsigned int major)
430 {
431 	struct pstore_device_info dev = { .read = psblk_generic_blk_read };
432 	void *holder = blkdev;
433 
434 	lockdep_assert_held(&pstore_blk_lock);
435 	if (psblk_bdev && MAJOR(psblk_bdev->bd_dev) == major) {
436 		psblk_unregister_do(&dev);
437 		psblk_put_bdev(psblk_bdev, holder);
438 		blkdev_panic_write = NULL;
439 		psblk_bdev = NULL;
440 	}
441 }
442 
443 /**
444  * unregister_pstore_blk() - unregister block device from pstore/blk
445  *
446  * @major: the major device number of device
447  */
448 void unregister_pstore_blk(unsigned int major)
449 {
450 	mutex_lock(&pstore_blk_lock);
451 	__unregister_pstore_blk(major);
452 	mutex_unlock(&pstore_blk_lock);
453 }
454 EXPORT_SYMBOL_GPL(unregister_pstore_blk);
455 
456 static void __exit pstore_blk_exit(void)
457 {
458 	mutex_lock(&pstore_blk_lock);
459 	if (psblk_bdev)
460 		__unregister_pstore_blk(MAJOR(psblk_bdev->bd_dev));
461 	mutex_unlock(&pstore_blk_lock);
462 }
463 module_exit(pstore_blk_exit);
464 
465 MODULE_LICENSE("GPL");
466 MODULE_AUTHOR("WeiXiong Liao <liaoweixiong@allwinnertech.com>");
467 MODULE_AUTHOR("Kees Cook <keescook@chromium.org>");
468 MODULE_DESCRIPTION("pstore backend for block devices");
469