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