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