1 // SPDX-License-Identifier: GPL-2.0
3 * Implements pstore backend driver that write to block (or non-block) storage
4 * devices, using the pstore/zone API.
7 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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>
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>
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");
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)");
30 #if IS_ENABLED(CONFIG_PSTORE_PMSG)
31 static long pmsg_size
= CONFIG_PSTORE_BLK_PMSG_SIZE
;
33 static long pmsg_size
= -1;
35 module_param(pmsg_size
, long, 0400);
36 MODULE_PARM_DESC(pmsg_size
, "pmsg size in kbytes");
38 #if IS_ENABLED(CONFIG_PSTORE_CONSOLE)
39 static long console_size
= CONFIG_PSTORE_BLK_CONSOLE_SIZE
;
41 static long console_size
= -1;
43 module_param(console_size
, long, 0400);
44 MODULE_PARM_DESC(console_size
, "console size in kbytes");
46 #if IS_ENABLED(CONFIG_PSTORE_FTRACE)
47 static long ftrace_size
= CONFIG_PSTORE_BLK_FTRACE_SIZE
;
49 static long ftrace_size
= -1;
51 module_param(ftrace_size
, long, 0400);
52 MODULE_PARM_DESC(ftrace_size
, "ftrace size in kbytes");
54 static bool best_effort
;
55 module_param(best_effort
, bool, 0400);
56 MODULE_PARM_DESC(best_effort
, "use best effort to write (i.e. do not require storage driver pstore support, default: off)");
59 * blkdev - the block device to use for pstore storage
61 * Usually, this will be a partition of a block device.
63 * blkdev accepts the following variants:
64 * 1) <hex_major><hex_minor> device number in hexadecimal representation,
65 * with no leading 0x, for example b302.
66 * 2) /dev/<disk_name> represents the device number of disk
67 * 3) /dev/<disk_name><decimal> represents the device number
68 * of partition - device number of disk plus the partition number
69 * 4) /dev/<disk_name>p<decimal> - same as the above, that form is
70 * used when disk name of partitioned disk ends on a digit.
71 * 5) PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing the
72 * unique id of a partition if the partition table provides it.
73 * The UUID may be either an EFI/GPT UUID, or refer to an MSDOS
74 * partition using the format SSSSSSSS-PP, where SSSSSSSS is a zero-
75 * filled hex representation of the 32-bit "NT disk signature", and PP
76 * is a zero-filled hex representation of the 1-based partition number.
77 * 6) PARTUUID=<UUID>/PARTNROFF=<int> to select a partition in relation to
78 * a partition with a known unique id.
79 * 7) <major>:<minor> major and minor number of the device separated by
82 static char blkdev
[80] = CONFIG_PSTORE_BLK_BLKDEV
;
83 module_param_string(blkdev
, blkdev
, 80, 0400);
84 MODULE_PARM_DESC(blkdev
, "block device for pstore storage");
87 * All globals must only be accessed under the pstore_blk_lock
88 * during the register/unregister functions.
90 static DEFINE_MUTEX(pstore_blk_lock
);
91 static struct block_device
*psblk_bdev
;
92 static struct pstore_zone_info
*pstore_zone_info
;
93 static pstore_blk_panic_write_op blkdev_panic_write
;
101 #define check_size(name, alignsize) ({ \
102 long _##name_ = (name); \
103 _##name_ = _##name_ <= 0 ? 0 : (_##name_ * 1024); \
104 if (_##name_ & ((alignsize) - 1)) { \
105 pr_info(#name " must align to %d\n", \
107 _##name_ = ALIGN(name, (alignsize)); \
112 static int __register_pstore_device(struct pstore_device_info
*dev
)
116 lockdep_assert_held(&pstore_blk_lock
);
118 if (!dev
|| !dev
->total_size
|| !dev
->read
|| !dev
->write
)
121 /* someone already registered before */
122 if (pstore_zone_info
)
125 pstore_zone_info
= kzalloc(sizeof(struct pstore_zone_info
), GFP_KERNEL
);
126 if (!pstore_zone_info
)
129 /* zero means not limit on which backends to attempt to store. */
131 dev
->flags
= UINT_MAX
;
133 #define verify_size(name, alignsize, enabled) { \
136 _##name_ = check_size(name, alignsize); \
139 name = _##name_ / 1024; \
140 pstore_zone_info->name = _##name_; \
143 verify_size(kmsg_size
, 4096, dev
->flags
& PSTORE_FLAGS_DMESG
);
144 verify_size(pmsg_size
, 4096, dev
->flags
& PSTORE_FLAGS_PMSG
);
145 verify_size(console_size
, 4096, dev
->flags
& PSTORE_FLAGS_CONSOLE
);
146 verify_size(ftrace_size
, 4096, dev
->flags
& PSTORE_FLAGS_FTRACE
);
149 pstore_zone_info
->total_size
= dev
->total_size
;
150 pstore_zone_info
->max_reason
= max_reason
;
151 pstore_zone_info
->read
= dev
->read
;
152 pstore_zone_info
->write
= dev
->write
;
153 pstore_zone_info
->erase
= dev
->erase
;
154 pstore_zone_info
->panic_write
= dev
->panic_write
;
155 pstore_zone_info
->name
= KBUILD_MODNAME
;
156 pstore_zone_info
->owner
= THIS_MODULE
;
158 ret
= register_pstore_zone(pstore_zone_info
);
160 kfree(pstore_zone_info
);
161 pstore_zone_info
= NULL
;
166 * register_pstore_device() - register non-block device to pstore/blk
168 * @dev: non-block device information
172 * * Others - something error.
174 int register_pstore_device(struct pstore_device_info
*dev
)
178 mutex_lock(&pstore_blk_lock
);
179 ret
= __register_pstore_device(dev
);
180 mutex_unlock(&pstore_blk_lock
);
184 EXPORT_SYMBOL_GPL(register_pstore_device
);
186 static void __unregister_pstore_device(struct pstore_device_info
*dev
)
188 lockdep_assert_held(&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
;
197 * unregister_pstore_device() - unregister non-block device from pstore/blk
199 * @dev: non-block device information
201 void unregister_pstore_device(struct pstore_device_info
*dev
)
203 mutex_lock(&pstore_blk_lock
);
204 __unregister_pstore_device(dev
);
205 mutex_unlock(&pstore_blk_lock
);
207 EXPORT_SYMBOL_GPL(unregister_pstore_device
);
210 * psblk_get_bdev() - open block device
212 * @holder: Exclusive holder identifier
213 * @info: Information about bdev to fill in
215 * Return: pointer to block device on success and others on error.
217 * On success, the returned block_device has reference count of one.
219 static struct block_device
*psblk_get_bdev(void *holder
,
220 struct bdev_info
*info
)
222 struct block_device
*bdev
= ERR_PTR(-ENODEV
);
223 fmode_t mode
= FMODE_READ
| FMODE_WRITE
;
226 lockdep_assert_held(&pstore_blk_lock
);
228 if (pstore_zone_info
)
229 return ERR_PTR(-EBUSY
);
232 return ERR_PTR(-ENODEV
);
236 bdev
= blkdev_get_by_path(blkdev
, mode
, holder
);
240 devt
= name_to_dev_t(blkdev
);
242 return ERR_PTR(-ENODEV
);
243 bdev
= blkdev_get_by_dev(devt
, mode
, holder
);
248 nr_sects
= part_nr_sects_read(bdev
->bd_part
);
250 pr_err("not enough space for '%s'\n", blkdev
);
251 blkdev_put(bdev
, mode
);
252 return ERR_PTR(-ENOSPC
);
256 info
->devt
= bdev
->bd_dev
;
257 info
->nr_sects
= nr_sects
;
258 info
->start_sect
= get_start_sect(bdev
);
264 static void psblk_put_bdev(struct block_device
*bdev
, void *holder
)
266 fmode_t mode
= FMODE_READ
| FMODE_WRITE
;
268 lockdep_assert_held(&pstore_blk_lock
);
275 blkdev_put(bdev
, mode
);
278 static ssize_t
psblk_generic_blk_read(char *buf
, size_t bytes
, loff_t pos
)
280 struct block_device
*bdev
= psblk_bdev
;
283 struct iov_iter iter
;
284 struct kvec iov
= {.iov_base
= buf
, .iov_len
= bytes
};
289 memset(&file
, 0, sizeof(struct file
));
290 file
.f_mapping
= bdev
->bd_inode
->i_mapping
;
291 file
.f_flags
= O_DSYNC
| __O_SYNC
| O_NOATIME
;
292 file
.f_inode
= bdev
->bd_inode
;
293 file_ra_state_init(&file
.f_ra
, file
.f_mapping
);
295 init_sync_kiocb(&kiocb
, &file
);
297 iov_iter_kvec(&iter
, READ
, &iov
, 1, bytes
);
299 return generic_file_read_iter(&kiocb
, &iter
);
302 static ssize_t
psblk_generic_blk_write(const char *buf
, size_t bytes
,
305 struct block_device
*bdev
= psblk_bdev
;
306 struct iov_iter iter
;
310 struct kvec iov
= {.iov_base
= (void *)buf
, .iov_len
= bytes
};
315 /* Console/Ftrace backend may handle buffer until flush dirty zones */
316 if (in_interrupt() || irqs_disabled())
319 memset(&file
, 0, sizeof(struct file
));
320 file
.f_mapping
= bdev
->bd_inode
->i_mapping
;
321 file
.f_flags
= O_DSYNC
| __O_SYNC
| O_NOATIME
;
322 file
.f_inode
= bdev
->bd_inode
;
324 init_sync_kiocb(&kiocb
, &file
);
326 iov_iter_kvec(&iter
, WRITE
, &iov
, 1, bytes
);
328 inode_lock(bdev
->bd_inode
);
329 ret
= generic_write_checks(&kiocb
, &iter
);
331 ret
= generic_perform_write(&file
, &iter
, pos
);
332 inode_unlock(bdev
->bd_inode
);
334 if (likely(ret
> 0)) {
335 const struct file_operations f_op
= {.fsync
= blkdev_fsync
};
339 ret
= generic_write_sync(&kiocb
, ret
);
344 static ssize_t
psblk_blk_panic_write(const char *buf
, size_t size
,
349 if (!blkdev_panic_write
)
352 /* size and off must align to SECTOR_SIZE for block device */
353 ret
= blkdev_panic_write(buf
, off
>> SECTOR_SHIFT
,
354 size
>> SECTOR_SHIFT
);
358 return ret
? -EIO
: size
;
361 static int __register_pstore_blk(struct pstore_blk_info
*info
)
363 char bdev_name
[BDEVNAME_SIZE
];
364 struct block_device
*bdev
;
365 struct pstore_device_info dev
;
366 struct bdev_info binfo
;
367 void *holder
= blkdev
;
370 lockdep_assert_held(&pstore_blk_lock
);
372 /* hold bdev exclusively */
373 memset(&binfo
, 0, sizeof(binfo
));
374 bdev
= psblk_get_bdev(holder
, &binfo
);
376 pr_err("failed to open '%s'!\n", blkdev
);
377 return PTR_ERR(bdev
);
380 /* only allow driver matching the @blkdev */
381 if (!binfo
.devt
|| (!best_effort
&&
382 MAJOR(binfo
.devt
) != info
->major
)) {
383 pr_debug("invalid major %u (expect %u)\n",
384 info
->major
, MAJOR(binfo
.devt
));
389 /* psblk_bdev must be assigned before register to pstore/blk */
391 blkdev_panic_write
= info
->panic_write
;
393 /* Copy back block device details. */
394 info
->devt
= binfo
.devt
;
395 info
->nr_sects
= binfo
.nr_sects
;
396 info
->start_sect
= binfo
.start_sect
;
398 memset(&dev
, 0, sizeof(dev
));
399 dev
.total_size
= info
->nr_sects
<< SECTOR_SHIFT
;
400 dev
.flags
= info
->flags
;
401 dev
.read
= psblk_generic_blk_read
;
402 dev
.write
= psblk_generic_blk_write
;
404 dev
.panic_write
= info
->panic_write
? psblk_blk_panic_write
: NULL
;
406 ret
= __register_pstore_device(&dev
);
410 bdevname(bdev
, bdev_name
);
411 pr_info("attached %s%s\n", bdev_name
,
412 info
->panic_write
? "" : " (no dedicated panic_write!)");
417 blkdev_panic_write
= NULL
;
418 psblk_put_bdev(bdev
, holder
);
423 * register_pstore_blk() - register block device to pstore/blk
425 * @info: details on the desired block device interface
429 * * Others - something error.
431 int register_pstore_blk(struct pstore_blk_info
*info
)
435 mutex_lock(&pstore_blk_lock
);
436 ret
= __register_pstore_blk(info
);
437 mutex_unlock(&pstore_blk_lock
);
441 EXPORT_SYMBOL_GPL(register_pstore_blk
);
443 static void __unregister_pstore_blk(unsigned int major
)
445 struct pstore_device_info dev
= { .read
= psblk_generic_blk_read
};
446 void *holder
= blkdev
;
448 lockdep_assert_held(&pstore_blk_lock
);
449 if (psblk_bdev
&& MAJOR(psblk_bdev
->bd_dev
) == major
) {
450 __unregister_pstore_device(&dev
);
451 psblk_put_bdev(psblk_bdev
, holder
);
452 blkdev_panic_write
= NULL
;
458 * unregister_pstore_blk() - unregister block device from pstore/blk
460 * @major: the major device number of device
462 void unregister_pstore_blk(unsigned int major
)
464 mutex_lock(&pstore_blk_lock
);
465 __unregister_pstore_blk(major
);
466 mutex_unlock(&pstore_blk_lock
);
468 EXPORT_SYMBOL_GPL(unregister_pstore_blk
);
470 /* get information of pstore/blk */
471 int pstore_blk_get_config(struct pstore_blk_config
*info
)
473 strncpy(info
->device
, blkdev
, 80);
474 info
->max_reason
= max_reason
;
475 info
->kmsg_size
= check_size(kmsg_size
, 4096);
476 info
->pmsg_size
= check_size(pmsg_size
, 4096);
477 info
->ftrace_size
= check_size(ftrace_size
, 4096);
478 info
->console_size
= check_size(console_size
, 4096);
482 EXPORT_SYMBOL_GPL(pstore_blk_get_config
);
484 static int __init
pstore_blk_init(void)
486 struct pstore_blk_info info
= { };
489 mutex_lock(&pstore_blk_lock
);
490 if (!pstore_zone_info
&& best_effort
&& blkdev
[0])
491 ret
= __register_pstore_blk(&info
);
492 mutex_unlock(&pstore_blk_lock
);
496 late_initcall(pstore_blk_init
);
498 static void __exit
pstore_blk_exit(void)
500 mutex_lock(&pstore_blk_lock
);
502 __unregister_pstore_blk(MAJOR(psblk_bdev
->bd_dev
));
504 struct pstore_device_info dev
= { };
506 if (pstore_zone_info
)
507 dev
.read
= pstore_zone_info
->read
;
508 __unregister_pstore_device(&dev
);
510 mutex_unlock(&pstore_blk_lock
);
512 module_exit(pstore_blk_exit
);
514 MODULE_LICENSE("GPL");
515 MODULE_AUTHOR("WeiXiong Liao <liaoweixiong@allwinnertech.com>");
516 MODULE_AUTHOR("Kees Cook <keescook@chromium.org>");
517 MODULE_DESCRIPTION("pstore backend for block devices");