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 <linux/blkdev.h>
12  #include <linux/string.h>
13  #include <linux/of.h>
14  #include <linux/of_address.h>
15  #include <linux/platform_device.h>
16  #include <linux/pstore_blk.h>
17  #include <linux/fs.h>
18  #include <linux/file.h>
19  #include <linux/init_syscalls.h>
20  #include <linux/mount.h>
21  
22  static long kmsg_size = CONFIG_PSTORE_BLK_KMSG_SIZE;
23  module_param(kmsg_size, long, 0400);
24  MODULE_PARM_DESC(kmsg_size, "kmsg dump record size in kbytes");
25  
26  static int max_reason = CONFIG_PSTORE_BLK_MAX_REASON;
27  module_param(max_reason, int, 0400);
28  MODULE_PARM_DESC(max_reason,
29  		 "maximum reason for kmsg dump (default 2: Oops and Panic)");
30  
31  #if IS_ENABLED(CONFIG_PSTORE_PMSG)
32  static long pmsg_size = CONFIG_PSTORE_BLK_PMSG_SIZE;
33  #else
34  static long pmsg_size = -1;
35  #endif
36  module_param(pmsg_size, long, 0400);
37  MODULE_PARM_DESC(pmsg_size, "pmsg size in kbytes");
38  
39  #if IS_ENABLED(CONFIG_PSTORE_CONSOLE)
40  static long console_size = CONFIG_PSTORE_BLK_CONSOLE_SIZE;
41  #else
42  static long console_size = -1;
43  #endif
44  module_param(console_size, long, 0400);
45  MODULE_PARM_DESC(console_size, "console size in kbytes");
46  
47  #if IS_ENABLED(CONFIG_PSTORE_FTRACE)
48  static long ftrace_size = CONFIG_PSTORE_BLK_FTRACE_SIZE;
49  #else
50  static long ftrace_size = -1;
51  #endif
52  module_param(ftrace_size, long, 0400);
53  MODULE_PARM_DESC(ftrace_size, "ftrace size in kbytes");
54  
55  static bool best_effort;
56  module_param(best_effort, bool, 0400);
57  MODULE_PARM_DESC(best_effort, "use best effort to write (i.e. do not require storage driver pstore support, default: off)");
58  
59  /*
60   * blkdev - the block device to use for pstore storage
61   * See Documentation/admin-guide/pstore-blk.rst for details.
62   */
63  static char blkdev[80] = CONFIG_PSTORE_BLK_BLKDEV;
64  module_param_string(blkdev, blkdev, 80, 0400);
65  MODULE_PARM_DESC(blkdev, "block device for pstore storage");
66  
67  /*
68   * All globals must only be accessed under the pstore_blk_lock
69   * during the register/unregister functions.
70   */
71  static DEFINE_MUTEX(pstore_blk_lock);
72  static struct file *psblk_file;
73  static struct pstore_device_info *pstore_device_info;
74  
75  #define check_size(name, alignsize) ({				\
76  	long _##name_ = (name);					\
77  	_##name_ = _##name_ <= 0 ? 0 : (_##name_ * 1024);	\
78  	if (_##name_ & ((alignsize) - 1)) {			\
79  		pr_info(#name " must align to %d\n",		\
80  				(alignsize));			\
81  		_##name_ = ALIGN(name, (alignsize));		\
82  	}							\
83  	_##name_;						\
84  })
85  
86  #define verify_size(name, alignsize, enabled) {			\
87  	long _##name_;						\
88  	if (enabled)						\
89  		_##name_ = check_size(name, alignsize);		\
90  	else							\
91  		_##name_ = 0;					\
92  	/* Synchronize module parameters with resuls. */	\
93  	name = _##name_ / 1024;					\
94  	dev->zone.name = _##name_;				\
95  }
96  
__register_pstore_device(struct pstore_device_info * dev)97  static int __register_pstore_device(struct pstore_device_info *dev)
98  {
99  	int ret;
100  
101  	lockdep_assert_held(&pstore_blk_lock);
102  
103  	if (!dev) {
104  		pr_err("NULL device info\n");
105  		return -EINVAL;
106  	}
107  	if (!dev->zone.total_size) {
108  		pr_err("zero sized device\n");
109  		return -EINVAL;
110  	}
111  	if (!dev->zone.read) {
112  		pr_err("no read handler for device\n");
113  		return -EINVAL;
114  	}
115  	if (!dev->zone.write) {
116  		pr_err("no write handler for device\n");
117  		return -EINVAL;
118  	}
119  
120  	/* someone already registered before */
121  	if (pstore_device_info)
122  		return -EBUSY;
123  
124  	/* zero means not limit on which backends to attempt to store. */
125  	if (!dev->flags)
126  		dev->flags = UINT_MAX;
127  
128  	/* Copy in module parameters. */
129  	verify_size(kmsg_size, 4096, dev->flags & PSTORE_FLAGS_DMESG);
130  	verify_size(pmsg_size, 4096, dev->flags & PSTORE_FLAGS_PMSG);
131  	verify_size(console_size, 4096, dev->flags & PSTORE_FLAGS_CONSOLE);
132  	verify_size(ftrace_size, 4096, dev->flags & PSTORE_FLAGS_FTRACE);
133  	dev->zone.max_reason = max_reason;
134  
135  	/* Initialize required zone ownership details. */
136  	dev->zone.name = KBUILD_MODNAME;
137  	dev->zone.owner = THIS_MODULE;
138  
139  	ret = register_pstore_zone(&dev->zone);
140  	if (ret == 0)
141  		pstore_device_info = dev;
142  
143  	return ret;
144  }
145  /**
146   * register_pstore_device() - register non-block device to pstore/blk
147   *
148   * @dev: non-block device information
149   *
150   * Return:
151   * * 0		- OK
152   * * Others	- something error.
153   */
register_pstore_device(struct pstore_device_info * dev)154  int register_pstore_device(struct pstore_device_info *dev)
155  {
156  	int ret;
157  
158  	mutex_lock(&pstore_blk_lock);
159  	ret = __register_pstore_device(dev);
160  	mutex_unlock(&pstore_blk_lock);
161  
162  	return ret;
163  }
164  EXPORT_SYMBOL_GPL(register_pstore_device);
165  
__unregister_pstore_device(struct pstore_device_info * dev)166  static void __unregister_pstore_device(struct pstore_device_info *dev)
167  {
168  	lockdep_assert_held(&pstore_blk_lock);
169  	if (pstore_device_info && pstore_device_info == dev) {
170  		unregister_pstore_zone(&dev->zone);
171  		pstore_device_info = NULL;
172  	}
173  }
174  
175  /**
176   * unregister_pstore_device() - unregister non-block device from pstore/blk
177   *
178   * @dev: non-block device information
179   */
unregister_pstore_device(struct pstore_device_info * dev)180  void unregister_pstore_device(struct pstore_device_info *dev)
181  {
182  	mutex_lock(&pstore_blk_lock);
183  	__unregister_pstore_device(dev);
184  	mutex_unlock(&pstore_blk_lock);
185  }
186  EXPORT_SYMBOL_GPL(unregister_pstore_device);
187  
psblk_generic_blk_read(char * buf,size_t bytes,loff_t pos)188  static ssize_t psblk_generic_blk_read(char *buf, size_t bytes, loff_t pos)
189  {
190  	return kernel_read(psblk_file, buf, bytes, &pos);
191  }
192  
psblk_generic_blk_write(const char * buf,size_t bytes,loff_t pos)193  static ssize_t psblk_generic_blk_write(const char *buf, size_t bytes,
194  		loff_t pos)
195  {
196  	/* Console/Ftrace backend may handle buffer until flush dirty zones */
197  	if (in_interrupt() || irqs_disabled())
198  		return -EBUSY;
199  	return kernel_write(psblk_file, buf, bytes, &pos);
200  }
201  
202  /*
203   * This takes its configuration only from the module parameters now.
204   */
__register_pstore_blk(struct pstore_device_info * dev,const char * devpath)205  static int __register_pstore_blk(struct pstore_device_info *dev,
206  				 const char *devpath)
207  {
208  	int ret = -ENODEV;
209  
210  	lockdep_assert_held(&pstore_blk_lock);
211  
212  	psblk_file = filp_open(devpath, O_RDWR | O_DSYNC | O_NOATIME | O_EXCL, 0);
213  	if (IS_ERR(psblk_file)) {
214  		ret = PTR_ERR(psblk_file);
215  		pr_err("failed to open '%s': %d!\n", devpath, ret);
216  		goto err;
217  	}
218  
219  	if (!S_ISBLK(file_inode(psblk_file)->i_mode)) {
220  		pr_err("'%s' is not block device!\n", devpath);
221  		goto err_fput;
222  	}
223  
224  	dev->zone.total_size =
225  		bdev_nr_bytes(I_BDEV(psblk_file->f_mapping->host));
226  
227  	ret = __register_pstore_device(dev);
228  	if (ret)
229  		goto err_fput;
230  
231  	return 0;
232  
233  err_fput:
234  	fput(psblk_file);
235  err:
236  	psblk_file = NULL;
237  
238  	return ret;
239  }
240  
241  /* get information of pstore/blk */
pstore_blk_get_config(struct pstore_blk_config * info)242  int pstore_blk_get_config(struct pstore_blk_config *info)
243  {
244  	strscpy(info->device, blkdev);
245  	info->max_reason = max_reason;
246  	info->kmsg_size = check_size(kmsg_size, 4096);
247  	info->pmsg_size = check_size(pmsg_size, 4096);
248  	info->ftrace_size = check_size(ftrace_size, 4096);
249  	info->console_size = check_size(console_size, 4096);
250  
251  	return 0;
252  }
253  EXPORT_SYMBOL_GPL(pstore_blk_get_config);
254  
255  
256  #ifndef MODULE
257  static const char devname[] = "/dev/pstore-blk";
early_boot_devpath(const char * initial_devname)258  static __init const char *early_boot_devpath(const char *initial_devname)
259  {
260  	/*
261  	 * During early boot the real root file system hasn't been
262  	 * mounted yet, and no device nodes are present yet. Use the
263  	 * same scheme to find the device that we use for mounting
264  	 * the root file system.
265  	 */
266  	dev_t dev;
267  
268  	if (early_lookup_bdev(initial_devname, &dev)) {
269  		pr_err("failed to resolve '%s'!\n", initial_devname);
270  		return initial_devname;
271  	}
272  
273  	init_unlink(devname);
274  	init_mknod(devname, S_IFBLK | 0600, new_encode_dev(dev));
275  
276  	return devname;
277  }
278  #else
early_boot_devpath(const char * initial_devname)279  static inline const char *early_boot_devpath(const char *initial_devname)
280  {
281  	return initial_devname;
282  }
283  #endif
284  
__best_effort_init(void)285  static int __init __best_effort_init(void)
286  {
287  	struct pstore_device_info *best_effort_dev;
288  	int ret;
289  
290  	/* No best-effort mode requested. */
291  	if (!best_effort)
292  		return 0;
293  
294  	/* Reject an empty blkdev. */
295  	if (!blkdev[0]) {
296  		pr_err("blkdev empty with best_effort=Y\n");
297  		return -EINVAL;
298  	}
299  
300  	best_effort_dev = kzalloc(sizeof(*best_effort_dev), GFP_KERNEL);
301  	if (!best_effort_dev)
302  		return -ENOMEM;
303  
304  	best_effort_dev->zone.read = psblk_generic_blk_read;
305  	best_effort_dev->zone.write = psblk_generic_blk_write;
306  
307  	ret = __register_pstore_blk(best_effort_dev,
308  				    early_boot_devpath(blkdev));
309  	if (ret)
310  		kfree(best_effort_dev);
311  	else
312  		pr_info("attached %s (%lu) (no dedicated panic_write!)\n",
313  			blkdev, best_effort_dev->zone.total_size);
314  
315  	return ret;
316  }
317  
__best_effort_exit(void)318  static void __exit __best_effort_exit(void)
319  {
320  	/*
321  	 * Currently, the only user of psblk_file is best_effort, so
322  	 * we can assume that pstore_device_info is associated with it.
323  	 * Once there are "real" blk devices, there will need to be a
324  	 * dedicated pstore_blk_info, etc.
325  	 */
326  	if (psblk_file) {
327  		struct pstore_device_info *dev = pstore_device_info;
328  
329  		__unregister_pstore_device(dev);
330  		kfree(dev);
331  		fput(psblk_file);
332  		psblk_file = NULL;
333  	}
334  }
335  
pstore_blk_init(void)336  static int __init pstore_blk_init(void)
337  {
338  	int ret;
339  
340  	mutex_lock(&pstore_blk_lock);
341  	ret = __best_effort_init();
342  	mutex_unlock(&pstore_blk_lock);
343  
344  	return ret;
345  }
346  late_initcall(pstore_blk_init);
347  
pstore_blk_exit(void)348  static void __exit pstore_blk_exit(void)
349  {
350  	mutex_lock(&pstore_blk_lock);
351  	__best_effort_exit();
352  	/* If we've been asked to unload, unregister any remaining device. */
353  	__unregister_pstore_device(pstore_device_info);
354  	mutex_unlock(&pstore_blk_lock);
355  }
356  module_exit(pstore_blk_exit);
357  
358  MODULE_LICENSE("GPL");
359  MODULE_AUTHOR("WeiXiong Liao <liaoweixiong@allwinnertech.com>");
360  MODULE_AUTHOR("Kees Cook <keescook@chromium.org>");
361  MODULE_DESCRIPTION("pstore backend for block devices");
362