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