0001
0002
0003
0004
0005
0006
0007
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/slab.h>
0013 #include <linux/mount.h>
0014 #include <linux/printk.h>
0015 #include <linux/fs.h>
0016 #include <linux/pstore_zone.h>
0017 #include <linux/kdev_t.h>
0018 #include <linux/device.h>
0019 #include <linux/namei.h>
0020 #include <linux/fcntl.h>
0021 #include <linux/uio.h>
0022 #include <linux/writeback.h>
0023 #include "internal.h"
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 struct psz_buffer {
0034 #define PSZ_SIG (0x43474244)
0035 uint32_t sig;
0036 atomic_t datalen;
0037 atomic_t start;
0038 uint8_t data[];
0039 };
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 struct psz_kmsg_header {
0054 #define PSTORE_KMSG_HEADER_MAGIC 0x4dfc3ae5
0055 uint32_t magic;
0056 struct timespec64 time;
0057 bool compressed;
0058 uint32_t counter;
0059 enum kmsg_dump_reason reason;
0060 uint8_t data[];
0061 };
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 struct pstore_zone {
0078 loff_t off;
0079 const char *name;
0080 enum pstore_type_id type;
0081
0082 struct psz_buffer *buffer;
0083 struct psz_buffer *oldbuf;
0084 size_t buffer_size;
0085 bool should_recover;
0086 atomic_t dirty;
0087 };
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 struct psz_context {
0112 struct pstore_zone **kpszs;
0113 struct pstore_zone *ppsz;
0114 struct pstore_zone *cpsz;
0115 struct pstore_zone **fpszs;
0116 unsigned int kmsg_max_cnt;
0117 unsigned int kmsg_read_cnt;
0118 unsigned int kmsg_write_cnt;
0119 unsigned int pmsg_read_cnt;
0120 unsigned int console_read_cnt;
0121 unsigned int ftrace_max_cnt;
0122 unsigned int ftrace_read_cnt;
0123
0124
0125
0126
0127 unsigned int oops_counter;
0128 unsigned int panic_counter;
0129 atomic_t recovered;
0130 atomic_t on_panic;
0131
0132
0133
0134
0135
0136 struct mutex pstore_zone_info_lock;
0137 struct pstore_zone_info *pstore_zone_info;
0138 struct pstore_info pstore;
0139 };
0140 static struct psz_context pstore_zone_cxt;
0141
0142 static void psz_flush_all_dirty_zones(struct work_struct *);
0143 static DECLARE_DELAYED_WORK(psz_cleaner, psz_flush_all_dirty_zones);
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153 enum psz_flush_mode {
0154 FLUSH_NONE = 0,
0155 FLUSH_PART,
0156 FLUSH_META,
0157 FLUSH_ALL,
0158 };
0159
0160 static inline int buffer_datalen(struct pstore_zone *zone)
0161 {
0162 return atomic_read(&zone->buffer->datalen);
0163 }
0164
0165 static inline int buffer_start(struct pstore_zone *zone)
0166 {
0167 return atomic_read(&zone->buffer->start);
0168 }
0169
0170 static inline bool is_on_panic(void)
0171 {
0172 return atomic_read(&pstore_zone_cxt.on_panic);
0173 }
0174
0175 static ssize_t psz_zone_read_buffer(struct pstore_zone *zone, char *buf,
0176 size_t len, unsigned long off)
0177 {
0178 if (!buf || !zone || !zone->buffer)
0179 return -EINVAL;
0180 if (off > zone->buffer_size)
0181 return -EINVAL;
0182 len = min_t(size_t, len, zone->buffer_size - off);
0183 memcpy(buf, zone->buffer->data + off, len);
0184 return len;
0185 }
0186
0187 static int psz_zone_read_oldbuf(struct pstore_zone *zone, char *buf,
0188 size_t len, unsigned long off)
0189 {
0190 if (!buf || !zone || !zone->oldbuf)
0191 return -EINVAL;
0192 if (off > zone->buffer_size)
0193 return -EINVAL;
0194 len = min_t(size_t, len, zone->buffer_size - off);
0195 memcpy(buf, zone->oldbuf->data + off, len);
0196 return 0;
0197 }
0198
0199 static int psz_zone_write(struct pstore_zone *zone,
0200 enum psz_flush_mode flush_mode, const char *buf,
0201 size_t len, unsigned long off)
0202 {
0203 struct pstore_zone_info *info = pstore_zone_cxt.pstore_zone_info;
0204 ssize_t wcnt = 0;
0205 ssize_t (*writeop)(const char *buf, size_t bytes, loff_t pos);
0206 size_t wlen;
0207
0208 if (off > zone->buffer_size)
0209 return -EINVAL;
0210
0211 wlen = min_t(size_t, len, zone->buffer_size - off);
0212 if (buf && wlen) {
0213 memcpy(zone->buffer->data + off, buf, wlen);
0214 atomic_set(&zone->buffer->datalen, wlen + off);
0215 }
0216
0217
0218 if (!is_on_panic() && !atomic_read(&pstore_zone_cxt.recovered))
0219 goto dirty;
0220
0221 writeop = is_on_panic() ? info->panic_write : info->write;
0222 if (!writeop)
0223 goto dirty;
0224
0225 switch (flush_mode) {
0226 case FLUSH_NONE:
0227 if (unlikely(buf && wlen))
0228 goto dirty;
0229 return 0;
0230 case FLUSH_PART:
0231 wcnt = writeop((const char *)zone->buffer->data + off, wlen,
0232 zone->off + sizeof(*zone->buffer) + off);
0233 if (wcnt != wlen)
0234 goto dirty;
0235 fallthrough;
0236 case FLUSH_META:
0237 wlen = sizeof(struct psz_buffer);
0238 wcnt = writeop((const char *)zone->buffer, wlen, zone->off);
0239 if (wcnt != wlen)
0240 goto dirty;
0241 break;
0242 case FLUSH_ALL:
0243 wlen = zone->buffer_size + sizeof(*zone->buffer);
0244 wcnt = writeop((const char *)zone->buffer, wlen, zone->off);
0245 if (wcnt != wlen)
0246 goto dirty;
0247 break;
0248 }
0249
0250 return 0;
0251 dirty:
0252
0253 if (wcnt == -ENOMSG)
0254 return -ENOMSG;
0255 atomic_set(&zone->dirty, true);
0256
0257 if (wcnt == -EBUSY && !is_on_panic())
0258 schedule_delayed_work(&psz_cleaner, msecs_to_jiffies(500));
0259 return -EBUSY;
0260 }
0261
0262 static int psz_flush_dirty_zone(struct pstore_zone *zone)
0263 {
0264 int ret;
0265
0266 if (unlikely(!zone))
0267 return -EINVAL;
0268
0269 if (unlikely(!atomic_read(&pstore_zone_cxt.recovered)))
0270 return -EBUSY;
0271
0272 if (!atomic_xchg(&zone->dirty, false))
0273 return 0;
0274
0275 ret = psz_zone_write(zone, FLUSH_ALL, NULL, 0, 0);
0276 if (ret)
0277 atomic_set(&zone->dirty, true);
0278 return ret;
0279 }
0280
0281 static int psz_flush_dirty_zones(struct pstore_zone **zones, unsigned int cnt)
0282 {
0283 int i, ret;
0284 struct pstore_zone *zone;
0285
0286 if (!zones)
0287 return -EINVAL;
0288
0289 for (i = 0; i < cnt; i++) {
0290 zone = zones[i];
0291 if (!zone)
0292 return -EINVAL;
0293 ret = psz_flush_dirty_zone(zone);
0294 if (ret)
0295 return ret;
0296 }
0297 return 0;
0298 }
0299
0300 static int psz_move_zone(struct pstore_zone *old, struct pstore_zone *new)
0301 {
0302 const char *data = (const char *)old->buffer->data;
0303 int ret;
0304
0305 ret = psz_zone_write(new, FLUSH_ALL, data, buffer_datalen(old), 0);
0306 if (ret) {
0307 atomic_set(&new->buffer->datalen, 0);
0308 atomic_set(&new->dirty, false);
0309 return ret;
0310 }
0311 atomic_set(&old->buffer->datalen, 0);
0312 return 0;
0313 }
0314
0315 static void psz_flush_all_dirty_zones(struct work_struct *work)
0316 {
0317 struct psz_context *cxt = &pstore_zone_cxt;
0318 int ret = 0;
0319
0320 if (cxt->ppsz)
0321 ret |= psz_flush_dirty_zone(cxt->ppsz);
0322 if (cxt->cpsz)
0323 ret |= psz_flush_dirty_zone(cxt->cpsz);
0324 if (cxt->kpszs)
0325 ret |= psz_flush_dirty_zones(cxt->kpszs, cxt->kmsg_max_cnt);
0326 if (cxt->fpszs)
0327 ret |= psz_flush_dirty_zones(cxt->fpszs, cxt->ftrace_max_cnt);
0328 if (ret && cxt->pstore_zone_info)
0329 schedule_delayed_work(&psz_cleaner, msecs_to_jiffies(1000));
0330 }
0331
0332 static int psz_kmsg_recover_data(struct psz_context *cxt)
0333 {
0334 struct pstore_zone_info *info = cxt->pstore_zone_info;
0335 struct pstore_zone *zone = NULL;
0336 struct psz_buffer *buf;
0337 unsigned long i;
0338 ssize_t rcnt;
0339
0340 if (!info->read)
0341 return -EINVAL;
0342
0343 for (i = 0; i < cxt->kmsg_max_cnt; i++) {
0344 zone = cxt->kpszs[i];
0345 if (unlikely(!zone))
0346 return -EINVAL;
0347 if (atomic_read(&zone->dirty)) {
0348 unsigned int wcnt = cxt->kmsg_write_cnt;
0349 struct pstore_zone *new = cxt->kpszs[wcnt];
0350 int ret;
0351
0352 ret = psz_move_zone(zone, new);
0353 if (ret) {
0354 pr_err("move zone from %lu to %d failed\n",
0355 i, wcnt);
0356 return ret;
0357 }
0358 cxt->kmsg_write_cnt = (wcnt + 1) % cxt->kmsg_max_cnt;
0359 }
0360 if (!zone->should_recover)
0361 continue;
0362 buf = zone->buffer;
0363 rcnt = info->read((char *)buf, zone->buffer_size + sizeof(*buf),
0364 zone->off);
0365 if (rcnt != zone->buffer_size + sizeof(*buf))
0366 return rcnt < 0 ? rcnt : -EIO;
0367 }
0368 return 0;
0369 }
0370
0371 static int psz_kmsg_recover_meta(struct psz_context *cxt)
0372 {
0373 struct pstore_zone_info *info = cxt->pstore_zone_info;
0374 struct pstore_zone *zone;
0375 ssize_t rcnt, len;
0376 struct psz_buffer *buf;
0377 struct psz_kmsg_header *hdr;
0378 struct timespec64 time = { };
0379 unsigned long i;
0380
0381
0382
0383
0384 char buffer_header[sizeof(*buf) + sizeof(*hdr)] = {0};
0385
0386 if (!info->read)
0387 return -EINVAL;
0388
0389 len = sizeof(*buf) + sizeof(*hdr);
0390 buf = (struct psz_buffer *)buffer_header;
0391 for (i = 0; i < cxt->kmsg_max_cnt; i++) {
0392 zone = cxt->kpszs[i];
0393 if (unlikely(!zone))
0394 return -EINVAL;
0395
0396 rcnt = info->read((char *)buf, len, zone->off);
0397 if (rcnt == -ENOMSG) {
0398 pr_debug("%s with id %lu may be broken, skip\n",
0399 zone->name, i);
0400 continue;
0401 } else if (rcnt != len) {
0402 pr_err("read %s with id %lu failed\n", zone->name, i);
0403 return rcnt < 0 ? rcnt : -EIO;
0404 }
0405
0406 if (buf->sig != zone->buffer->sig) {
0407 pr_debug("no valid data in kmsg dump zone %lu\n", i);
0408 continue;
0409 }
0410
0411 if (zone->buffer_size < atomic_read(&buf->datalen)) {
0412 pr_info("found overtop zone: %s: id %lu, off %lld, size %zu\n",
0413 zone->name, i, zone->off,
0414 zone->buffer_size);
0415 continue;
0416 }
0417
0418 hdr = (struct psz_kmsg_header *)buf->data;
0419 if (hdr->magic != PSTORE_KMSG_HEADER_MAGIC) {
0420 pr_info("found invalid zone: %s: id %lu, off %lld, size %zu\n",
0421 zone->name, i, zone->off,
0422 zone->buffer_size);
0423 continue;
0424 }
0425
0426
0427
0428
0429
0430 if (hdr->time.tv_sec >= time.tv_sec) {
0431 time.tv_sec = hdr->time.tv_sec;
0432 cxt->kmsg_write_cnt = (i + 1) % cxt->kmsg_max_cnt;
0433 }
0434
0435 if (hdr->reason == KMSG_DUMP_OOPS)
0436 cxt->oops_counter =
0437 max(cxt->oops_counter, hdr->counter);
0438 else if (hdr->reason == KMSG_DUMP_PANIC)
0439 cxt->panic_counter =
0440 max(cxt->panic_counter, hdr->counter);
0441
0442 if (!atomic_read(&buf->datalen)) {
0443 pr_debug("found erased zone: %s: id %lu, off %lld, size %zu, datalen %d\n",
0444 zone->name, i, zone->off,
0445 zone->buffer_size,
0446 atomic_read(&buf->datalen));
0447 continue;
0448 }
0449
0450 if (!is_on_panic())
0451 zone->should_recover = true;
0452 pr_debug("found nice zone: %s: id %lu, off %lld, size %zu, datalen %d\n",
0453 zone->name, i, zone->off,
0454 zone->buffer_size, atomic_read(&buf->datalen));
0455 }
0456
0457 return 0;
0458 }
0459
0460 static int psz_kmsg_recover(struct psz_context *cxt)
0461 {
0462 int ret;
0463
0464 if (!cxt->kpszs)
0465 return 0;
0466
0467 ret = psz_kmsg_recover_meta(cxt);
0468 if (ret)
0469 goto recover_fail;
0470
0471 ret = psz_kmsg_recover_data(cxt);
0472 if (ret)
0473 goto recover_fail;
0474
0475 return 0;
0476 recover_fail:
0477 pr_debug("psz_recover_kmsg failed\n");
0478 return ret;
0479 }
0480
0481 static int psz_recover_zone(struct psz_context *cxt, struct pstore_zone *zone)
0482 {
0483 struct pstore_zone_info *info = cxt->pstore_zone_info;
0484 struct psz_buffer *oldbuf, tmpbuf;
0485 int ret = 0;
0486 char *buf;
0487 ssize_t rcnt, len, start, off;
0488
0489 if (!zone || zone->oldbuf)
0490 return 0;
0491
0492 if (is_on_panic()) {
0493
0494 psz_flush_dirty_zone(zone);
0495 return 0;
0496 }
0497
0498 if (unlikely(!info->read))
0499 return -EINVAL;
0500
0501 len = sizeof(struct psz_buffer);
0502 rcnt = info->read((char *)&tmpbuf, len, zone->off);
0503 if (rcnt != len) {
0504 pr_debug("read zone %s failed\n", zone->name);
0505 return rcnt < 0 ? rcnt : -EIO;
0506 }
0507
0508 if (tmpbuf.sig != zone->buffer->sig) {
0509 pr_debug("no valid data in zone %s\n", zone->name);
0510 return 0;
0511 }
0512
0513 if (zone->buffer_size < atomic_read(&tmpbuf.datalen) ||
0514 zone->buffer_size < atomic_read(&tmpbuf.start)) {
0515 pr_info("found overtop zone: %s: off %lld, size %zu\n",
0516 zone->name, zone->off, zone->buffer_size);
0517
0518 return 0;
0519 }
0520
0521 if (!atomic_read(&tmpbuf.datalen)) {
0522 pr_debug("found erased zone: %s: off %lld, size %zu, datalen %d\n",
0523 zone->name, zone->off, zone->buffer_size,
0524 atomic_read(&tmpbuf.datalen));
0525 return 0;
0526 }
0527
0528 pr_debug("found nice zone: %s: off %lld, size %zu, datalen %d\n",
0529 zone->name, zone->off, zone->buffer_size,
0530 atomic_read(&tmpbuf.datalen));
0531
0532 len = atomic_read(&tmpbuf.datalen) + sizeof(*oldbuf);
0533 oldbuf = kzalloc(len, GFP_KERNEL);
0534 if (!oldbuf)
0535 return -ENOMEM;
0536
0537 memcpy(oldbuf, &tmpbuf, sizeof(*oldbuf));
0538 buf = (char *)oldbuf + sizeof(*oldbuf);
0539 len = atomic_read(&oldbuf->datalen);
0540 start = atomic_read(&oldbuf->start);
0541 off = zone->off + sizeof(*oldbuf);
0542
0543
0544 rcnt = info->read(buf, len - start, off + start);
0545 if (rcnt != len - start) {
0546 pr_err("read zone %s failed\n", zone->name);
0547 ret = rcnt < 0 ? rcnt : -EIO;
0548 goto free_oldbuf;
0549 }
0550
0551
0552 rcnt = info->read(buf + len - start, start, off);
0553 if (rcnt != start) {
0554 pr_err("read zone %s failed\n", zone->name);
0555 ret = rcnt < 0 ? rcnt : -EIO;
0556 goto free_oldbuf;
0557 }
0558
0559 zone->oldbuf = oldbuf;
0560 psz_flush_dirty_zone(zone);
0561 return 0;
0562
0563 free_oldbuf:
0564 kfree(oldbuf);
0565 return ret;
0566 }
0567
0568 static int psz_recover_zones(struct psz_context *cxt,
0569 struct pstore_zone **zones, unsigned int cnt)
0570 {
0571 int ret;
0572 unsigned int i;
0573 struct pstore_zone *zone;
0574
0575 if (!zones)
0576 return 0;
0577
0578 for (i = 0; i < cnt; i++) {
0579 zone = zones[i];
0580 if (unlikely(!zone))
0581 continue;
0582 ret = psz_recover_zone(cxt, zone);
0583 if (ret)
0584 goto recover_fail;
0585 }
0586
0587 return 0;
0588 recover_fail:
0589 pr_debug("recover %s[%u] failed\n", zone->name, i);
0590 return ret;
0591 }
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601 static inline int psz_recovery(struct psz_context *cxt)
0602 {
0603 int ret;
0604
0605 if (atomic_read(&cxt->recovered))
0606 return 0;
0607
0608 ret = psz_kmsg_recover(cxt);
0609 if (ret)
0610 goto out;
0611
0612 ret = psz_recover_zone(cxt, cxt->ppsz);
0613 if (ret)
0614 goto out;
0615
0616 ret = psz_recover_zone(cxt, cxt->cpsz);
0617 if (ret)
0618 goto out;
0619
0620 ret = psz_recover_zones(cxt, cxt->fpszs, cxt->ftrace_max_cnt);
0621
0622 out:
0623 if (unlikely(ret))
0624 pr_err("recover failed\n");
0625 else {
0626 pr_debug("recover end!\n");
0627 atomic_set(&cxt->recovered, 1);
0628 }
0629 return ret;
0630 }
0631
0632 static int psz_pstore_open(struct pstore_info *psi)
0633 {
0634 struct psz_context *cxt = psi->data;
0635
0636 cxt->kmsg_read_cnt = 0;
0637 cxt->pmsg_read_cnt = 0;
0638 cxt->console_read_cnt = 0;
0639 cxt->ftrace_read_cnt = 0;
0640 return 0;
0641 }
0642
0643 static inline bool psz_old_ok(struct pstore_zone *zone)
0644 {
0645 if (zone && zone->oldbuf && atomic_read(&zone->oldbuf->datalen))
0646 return true;
0647 return false;
0648 }
0649
0650 static inline bool psz_ok(struct pstore_zone *zone)
0651 {
0652 if (zone && zone->buffer && buffer_datalen(zone))
0653 return true;
0654 return false;
0655 }
0656
0657 static inline int psz_kmsg_erase(struct psz_context *cxt,
0658 struct pstore_zone *zone, struct pstore_record *record)
0659 {
0660 struct psz_buffer *buffer = zone->buffer;
0661 struct psz_kmsg_header *hdr =
0662 (struct psz_kmsg_header *)buffer->data;
0663 size_t size;
0664
0665 if (unlikely(!psz_ok(zone)))
0666 return 0;
0667
0668
0669 if (record->count != hdr->counter)
0670 return 0;
0671
0672 size = buffer_datalen(zone) + sizeof(*zone->buffer);
0673 atomic_set(&zone->buffer->datalen, 0);
0674 if (cxt->pstore_zone_info->erase)
0675 return cxt->pstore_zone_info->erase(size, zone->off);
0676 else
0677 return psz_zone_write(zone, FLUSH_META, NULL, 0, 0);
0678 }
0679
0680 static inline int psz_record_erase(struct psz_context *cxt,
0681 struct pstore_zone *zone)
0682 {
0683 if (unlikely(!psz_old_ok(zone)))
0684 return 0;
0685
0686 kfree(zone->oldbuf);
0687 zone->oldbuf = NULL;
0688
0689
0690
0691
0692
0693 if (!buffer_datalen(zone))
0694 return psz_zone_write(zone, FLUSH_META, NULL, 0, 0);
0695 psz_flush_dirty_zone(zone);
0696 return 0;
0697 }
0698
0699 static int psz_pstore_erase(struct pstore_record *record)
0700 {
0701 struct psz_context *cxt = record->psi->data;
0702
0703 switch (record->type) {
0704 case PSTORE_TYPE_DMESG:
0705 if (record->id >= cxt->kmsg_max_cnt)
0706 return -EINVAL;
0707 return psz_kmsg_erase(cxt, cxt->kpszs[record->id], record);
0708 case PSTORE_TYPE_PMSG:
0709 return psz_record_erase(cxt, cxt->ppsz);
0710 case PSTORE_TYPE_CONSOLE:
0711 return psz_record_erase(cxt, cxt->cpsz);
0712 case PSTORE_TYPE_FTRACE:
0713 if (record->id >= cxt->ftrace_max_cnt)
0714 return -EINVAL;
0715 return psz_record_erase(cxt, cxt->fpszs[record->id]);
0716 default: return -EINVAL;
0717 }
0718 }
0719
0720 static void psz_write_kmsg_hdr(struct pstore_zone *zone,
0721 struct pstore_record *record)
0722 {
0723 struct psz_context *cxt = record->psi->data;
0724 struct psz_buffer *buffer = zone->buffer;
0725 struct psz_kmsg_header *hdr =
0726 (struct psz_kmsg_header *)buffer->data;
0727
0728 hdr->magic = PSTORE_KMSG_HEADER_MAGIC;
0729 hdr->compressed = record->compressed;
0730 hdr->time.tv_sec = record->time.tv_sec;
0731 hdr->time.tv_nsec = record->time.tv_nsec;
0732 hdr->reason = record->reason;
0733 if (hdr->reason == KMSG_DUMP_OOPS)
0734 hdr->counter = ++cxt->oops_counter;
0735 else if (hdr->reason == KMSG_DUMP_PANIC)
0736 hdr->counter = ++cxt->panic_counter;
0737 else
0738 hdr->counter = 0;
0739 }
0740
0741
0742
0743
0744
0745 static inline int notrace psz_kmsg_write_record(struct psz_context *cxt,
0746 struct pstore_record *record)
0747 {
0748 size_t size, hlen;
0749 struct pstore_zone *zone;
0750 unsigned int i;
0751
0752 for (i = 0; i < cxt->kmsg_max_cnt; i++) {
0753 unsigned int zonenum, len;
0754 int ret;
0755
0756 zonenum = (cxt->kmsg_write_cnt + i) % cxt->kmsg_max_cnt;
0757 zone = cxt->kpszs[zonenum];
0758 if (unlikely(!zone))
0759 return -ENOSPC;
0760
0761
0762 len = zone->buffer_size + sizeof(*zone->buffer);
0763 zone->oldbuf = zone->buffer;
0764 zone->buffer = kzalloc(len, GFP_KERNEL);
0765 if (!zone->buffer) {
0766 zone->buffer = zone->oldbuf;
0767 return -ENOMEM;
0768 }
0769 zone->buffer->sig = zone->oldbuf->sig;
0770
0771 pr_debug("write %s to zone id %d\n", zone->name, zonenum);
0772 psz_write_kmsg_hdr(zone, record);
0773 hlen = sizeof(struct psz_kmsg_header);
0774 size = min_t(size_t, record->size, zone->buffer_size - hlen);
0775 ret = psz_zone_write(zone, FLUSH_ALL, record->buf, size, hlen);
0776 if (likely(!ret || ret != -ENOMSG)) {
0777 cxt->kmsg_write_cnt = zonenum + 1;
0778 cxt->kmsg_write_cnt %= cxt->kmsg_max_cnt;
0779
0780 kfree(zone->oldbuf);
0781 zone->oldbuf = NULL;
0782 return ret;
0783 }
0784
0785 pr_debug("zone %u may be broken, try next dmesg zone\n",
0786 zonenum);
0787 kfree(zone->buffer);
0788 zone->buffer = zone->oldbuf;
0789 zone->oldbuf = NULL;
0790 }
0791
0792 return -EBUSY;
0793 }
0794
0795 static int notrace psz_kmsg_write(struct psz_context *cxt,
0796 struct pstore_record *record)
0797 {
0798 int ret;
0799
0800
0801
0802
0803
0804
0805
0806 if (record->part != 1)
0807 return -ENOSPC;
0808
0809 if (!cxt->kpszs)
0810 return -ENOSPC;
0811
0812 ret = psz_kmsg_write_record(cxt, record);
0813 if (!ret && is_on_panic()) {
0814
0815 pr_debug("try to flush other dirty zones\n");
0816 psz_flush_all_dirty_zones(NULL);
0817 }
0818
0819
0820 return 0;
0821 }
0822
0823 static int notrace psz_record_write(struct pstore_zone *zone,
0824 struct pstore_record *record)
0825 {
0826 size_t start, rem;
0827 bool is_full_data = false;
0828 char *buf;
0829 int cnt;
0830
0831 if (!zone || !record)
0832 return -ENOSPC;
0833
0834 if (atomic_read(&zone->buffer->datalen) >= zone->buffer_size)
0835 is_full_data = true;
0836
0837 cnt = record->size;
0838 buf = record->buf;
0839 if (unlikely(cnt > zone->buffer_size)) {
0840 buf += cnt - zone->buffer_size;
0841 cnt = zone->buffer_size;
0842 }
0843
0844 start = buffer_start(zone);
0845 rem = zone->buffer_size - start;
0846 if (unlikely(rem < cnt)) {
0847 psz_zone_write(zone, FLUSH_PART, buf, rem, start);
0848 buf += rem;
0849 cnt -= rem;
0850 start = 0;
0851 is_full_data = true;
0852 }
0853
0854 atomic_set(&zone->buffer->start, cnt + start);
0855 psz_zone_write(zone, FLUSH_PART, buf, cnt, start);
0856
0857
0858
0859
0860
0861
0862
0863
0864
0865 if (is_full_data) {
0866 atomic_set(&zone->buffer->datalen, zone->buffer_size);
0867 psz_zone_write(zone, FLUSH_META, NULL, 0, 0);
0868 }
0869 return 0;
0870 }
0871
0872 static int notrace psz_pstore_write(struct pstore_record *record)
0873 {
0874 struct psz_context *cxt = record->psi->data;
0875
0876 if (record->type == PSTORE_TYPE_DMESG &&
0877 record->reason == KMSG_DUMP_PANIC)
0878 atomic_set(&cxt->on_panic, 1);
0879
0880
0881
0882
0883
0884 if (is_on_panic() && record->type != PSTORE_TYPE_DMESG)
0885 return -EBUSY;
0886
0887 switch (record->type) {
0888 case PSTORE_TYPE_DMESG:
0889 return psz_kmsg_write(cxt, record);
0890 case PSTORE_TYPE_CONSOLE:
0891 return psz_record_write(cxt->cpsz, record);
0892 case PSTORE_TYPE_PMSG:
0893 return psz_record_write(cxt->ppsz, record);
0894 case PSTORE_TYPE_FTRACE: {
0895 int zonenum = smp_processor_id();
0896
0897 if (!cxt->fpszs)
0898 return -ENOSPC;
0899 return psz_record_write(cxt->fpszs[zonenum], record);
0900 }
0901 default:
0902 return -EINVAL;
0903 }
0904 }
0905
0906 static struct pstore_zone *psz_read_next_zone(struct psz_context *cxt)
0907 {
0908 struct pstore_zone *zone = NULL;
0909
0910 while (cxt->kmsg_read_cnt < cxt->kmsg_max_cnt) {
0911 zone = cxt->kpszs[cxt->kmsg_read_cnt++];
0912 if (psz_ok(zone))
0913 return zone;
0914 }
0915
0916 if (cxt->ftrace_read_cnt < cxt->ftrace_max_cnt)
0917
0918
0919
0920
0921
0922 return cxt->fpszs[cxt->ftrace_read_cnt++];
0923
0924 if (cxt->pmsg_read_cnt == 0) {
0925 cxt->pmsg_read_cnt++;
0926 zone = cxt->ppsz;
0927 if (psz_old_ok(zone))
0928 return zone;
0929 }
0930
0931 if (cxt->console_read_cnt == 0) {
0932 cxt->console_read_cnt++;
0933 zone = cxt->cpsz;
0934 if (psz_old_ok(zone))
0935 return zone;
0936 }
0937
0938 return NULL;
0939 }
0940
0941 static int psz_kmsg_read_hdr(struct pstore_zone *zone,
0942 struct pstore_record *record)
0943 {
0944 struct psz_buffer *buffer = zone->buffer;
0945 struct psz_kmsg_header *hdr =
0946 (struct psz_kmsg_header *)buffer->data;
0947
0948 if (hdr->magic != PSTORE_KMSG_HEADER_MAGIC)
0949 return -EINVAL;
0950 record->compressed = hdr->compressed;
0951 record->time.tv_sec = hdr->time.tv_sec;
0952 record->time.tv_nsec = hdr->time.tv_nsec;
0953 record->reason = hdr->reason;
0954 record->count = hdr->counter;
0955 return 0;
0956 }
0957
0958 static ssize_t psz_kmsg_read(struct pstore_zone *zone,
0959 struct pstore_record *record)
0960 {
0961 ssize_t size, hlen = 0;
0962
0963 size = buffer_datalen(zone);
0964
0965 if (psz_kmsg_read_hdr(zone, record)) {
0966 atomic_set(&zone->buffer->datalen, 0);
0967 atomic_set(&zone->dirty, 0);
0968 return -ENOMSG;
0969 }
0970 size -= sizeof(struct psz_kmsg_header);
0971
0972 if (!record->compressed) {
0973 char *buf = kasprintf(GFP_KERNEL, "%s: Total %d times\n",
0974 kmsg_dump_reason_str(record->reason),
0975 record->count);
0976 hlen = strlen(buf);
0977 record->buf = krealloc(buf, hlen + size, GFP_KERNEL);
0978 if (!record->buf) {
0979 kfree(buf);
0980 return -ENOMEM;
0981 }
0982 } else {
0983 record->buf = kmalloc(size, GFP_KERNEL);
0984 if (!record->buf)
0985 return -ENOMEM;
0986 }
0987
0988 size = psz_zone_read_buffer(zone, record->buf + hlen, size,
0989 sizeof(struct psz_kmsg_header));
0990 if (unlikely(size < 0)) {
0991 kfree(record->buf);
0992 return -ENOMSG;
0993 }
0994
0995 return size + hlen;
0996 }
0997
0998
0999 static ssize_t psz_ftrace_read(struct pstore_zone *zone,
1000 struct pstore_record *record)
1001 {
1002 struct psz_context *cxt;
1003 struct psz_buffer *buf;
1004 int ret;
1005
1006 if (!zone || !record)
1007 return -ENOSPC;
1008
1009 if (!psz_old_ok(zone))
1010 goto out;
1011
1012 buf = (struct psz_buffer *)zone->oldbuf;
1013 if (!buf)
1014 return -ENOMSG;
1015
1016 ret = pstore_ftrace_combine_log(&record->buf, &record->size,
1017 (char *)buf->data, atomic_read(&buf->datalen));
1018 if (unlikely(ret))
1019 return ret;
1020
1021 out:
1022 cxt = record->psi->data;
1023 if (cxt->ftrace_read_cnt < cxt->ftrace_max_cnt)
1024
1025 return -ENOMSG;
1026 record->id = 0;
1027 return record->size ? record->size : -ENOMSG;
1028 }
1029
1030 static ssize_t psz_record_read(struct pstore_zone *zone,
1031 struct pstore_record *record)
1032 {
1033 size_t len;
1034 struct psz_buffer *buf;
1035
1036 if (!zone || !record)
1037 return -ENOSPC;
1038
1039 buf = (struct psz_buffer *)zone->oldbuf;
1040 if (!buf)
1041 return -ENOMSG;
1042
1043 len = atomic_read(&buf->datalen);
1044 record->buf = kmalloc(len, GFP_KERNEL);
1045 if (!record->buf)
1046 return -ENOMEM;
1047
1048 if (unlikely(psz_zone_read_oldbuf(zone, record->buf, len, 0))) {
1049 kfree(record->buf);
1050 return -ENOMSG;
1051 }
1052
1053 return len;
1054 }
1055
1056 static ssize_t psz_pstore_read(struct pstore_record *record)
1057 {
1058 struct psz_context *cxt = record->psi->data;
1059 ssize_t (*readop)(struct pstore_zone *zone,
1060 struct pstore_record *record);
1061 struct pstore_zone *zone;
1062 ssize_t ret;
1063
1064
1065 ret = psz_recovery(cxt);
1066 if (ret)
1067 return ret;
1068
1069 next_zone:
1070 zone = psz_read_next_zone(cxt);
1071 if (!zone)
1072 return 0;
1073
1074 record->type = zone->type;
1075 switch (record->type) {
1076 case PSTORE_TYPE_DMESG:
1077 readop = psz_kmsg_read;
1078 record->id = cxt->kmsg_read_cnt - 1;
1079 break;
1080 case PSTORE_TYPE_FTRACE:
1081 readop = psz_ftrace_read;
1082 break;
1083 case PSTORE_TYPE_CONSOLE:
1084 case PSTORE_TYPE_PMSG:
1085 readop = psz_record_read;
1086 break;
1087 default:
1088 goto next_zone;
1089 }
1090
1091 ret = readop(zone, record);
1092 if (ret == -ENOMSG)
1093 goto next_zone;
1094 return ret;
1095 }
1096
1097 static struct psz_context pstore_zone_cxt = {
1098 .pstore_zone_info_lock =
1099 __MUTEX_INITIALIZER(pstore_zone_cxt.pstore_zone_info_lock),
1100 .recovered = ATOMIC_INIT(0),
1101 .on_panic = ATOMIC_INIT(0),
1102 .pstore = {
1103 .owner = THIS_MODULE,
1104 .open = psz_pstore_open,
1105 .read = psz_pstore_read,
1106 .write = psz_pstore_write,
1107 .erase = psz_pstore_erase,
1108 },
1109 };
1110
1111 static void psz_free_zone(struct pstore_zone **pszone)
1112 {
1113 struct pstore_zone *zone = *pszone;
1114
1115 if (!zone)
1116 return;
1117
1118 kfree(zone->buffer);
1119 kfree(zone);
1120 *pszone = NULL;
1121 }
1122
1123 static void psz_free_zones(struct pstore_zone ***pszones, unsigned int *cnt)
1124 {
1125 struct pstore_zone **zones = *pszones;
1126
1127 if (!zones)
1128 return;
1129
1130 while (*cnt > 0) {
1131 (*cnt)--;
1132 psz_free_zone(&(zones[*cnt]));
1133 }
1134 kfree(zones);
1135 *pszones = NULL;
1136 }
1137
1138 static void psz_free_all_zones(struct psz_context *cxt)
1139 {
1140 if (cxt->kpszs)
1141 psz_free_zones(&cxt->kpszs, &cxt->kmsg_max_cnt);
1142 if (cxt->ppsz)
1143 psz_free_zone(&cxt->ppsz);
1144 if (cxt->cpsz)
1145 psz_free_zone(&cxt->cpsz);
1146 if (cxt->fpszs)
1147 psz_free_zones(&cxt->fpszs, &cxt->ftrace_max_cnt);
1148 }
1149
1150 static struct pstore_zone *psz_init_zone(enum pstore_type_id type,
1151 loff_t *off, size_t size)
1152 {
1153 struct pstore_zone_info *info = pstore_zone_cxt.pstore_zone_info;
1154 struct pstore_zone *zone;
1155 const char *name = pstore_type_to_name(type);
1156
1157 if (!size)
1158 return NULL;
1159
1160 if (*off + size > info->total_size) {
1161 pr_err("no room for %s (0x%zx@0x%llx over 0x%lx)\n",
1162 name, size, *off, info->total_size);
1163 return ERR_PTR(-ENOMEM);
1164 }
1165
1166 zone = kzalloc(sizeof(struct pstore_zone), GFP_KERNEL);
1167 if (!zone)
1168 return ERR_PTR(-ENOMEM);
1169
1170 zone->buffer = kmalloc(size, GFP_KERNEL);
1171 if (!zone->buffer) {
1172 kfree(zone);
1173 return ERR_PTR(-ENOMEM);
1174 }
1175 memset(zone->buffer, 0xFF, size);
1176 zone->off = *off;
1177 zone->name = name;
1178 zone->type = type;
1179 zone->buffer_size = size - sizeof(struct psz_buffer);
1180 zone->buffer->sig = type ^ PSZ_SIG;
1181 zone->oldbuf = NULL;
1182 atomic_set(&zone->dirty, 0);
1183 atomic_set(&zone->buffer->datalen, 0);
1184 atomic_set(&zone->buffer->start, 0);
1185
1186 *off += size;
1187
1188 pr_debug("pszone %s: off 0x%llx, %zu header, %zu data\n", zone->name,
1189 zone->off, sizeof(*zone->buffer), zone->buffer_size);
1190 return zone;
1191 }
1192
1193 static struct pstore_zone **psz_init_zones(enum pstore_type_id type,
1194 loff_t *off, size_t total_size, ssize_t record_size,
1195 unsigned int *cnt)
1196 {
1197 struct pstore_zone_info *info = pstore_zone_cxt.pstore_zone_info;
1198 struct pstore_zone **zones, *zone;
1199 const char *name = pstore_type_to_name(type);
1200 int c, i;
1201
1202 *cnt = 0;
1203 if (!total_size || !record_size)
1204 return NULL;
1205
1206 if (*off + total_size > info->total_size) {
1207 pr_err("no room for zones %s (0x%zx@0x%llx over 0x%lx)\n",
1208 name, total_size, *off, info->total_size);
1209 return ERR_PTR(-ENOMEM);
1210 }
1211
1212 c = total_size / record_size;
1213 zones = kcalloc(c, sizeof(*zones), GFP_KERNEL);
1214 if (!zones) {
1215 pr_err("allocate for zones %s failed\n", name);
1216 return ERR_PTR(-ENOMEM);
1217 }
1218 memset(zones, 0, c * sizeof(*zones));
1219
1220 for (i = 0; i < c; i++) {
1221 zone = psz_init_zone(type, off, record_size);
1222 if (!zone || IS_ERR(zone)) {
1223 pr_err("initialize zones %s failed\n", name);
1224 psz_free_zones(&zones, &i);
1225 return (void *)zone;
1226 }
1227 zones[i] = zone;
1228 }
1229
1230 *cnt = c;
1231 return zones;
1232 }
1233
1234 static int psz_alloc_zones(struct psz_context *cxt)
1235 {
1236 struct pstore_zone_info *info = cxt->pstore_zone_info;
1237 loff_t off = 0;
1238 int err;
1239 size_t off_size = 0;
1240
1241 off_size += info->pmsg_size;
1242 cxt->ppsz = psz_init_zone(PSTORE_TYPE_PMSG, &off, info->pmsg_size);
1243 if (IS_ERR(cxt->ppsz)) {
1244 err = PTR_ERR(cxt->ppsz);
1245 cxt->ppsz = NULL;
1246 goto free_out;
1247 }
1248
1249 off_size += info->console_size;
1250 cxt->cpsz = psz_init_zone(PSTORE_TYPE_CONSOLE, &off,
1251 info->console_size);
1252 if (IS_ERR(cxt->cpsz)) {
1253 err = PTR_ERR(cxt->cpsz);
1254 cxt->cpsz = NULL;
1255 goto free_out;
1256 }
1257
1258 off_size += info->ftrace_size;
1259 cxt->fpszs = psz_init_zones(PSTORE_TYPE_FTRACE, &off,
1260 info->ftrace_size,
1261 info->ftrace_size / nr_cpu_ids,
1262 &cxt->ftrace_max_cnt);
1263 if (IS_ERR(cxt->fpszs)) {
1264 err = PTR_ERR(cxt->fpszs);
1265 cxt->fpszs = NULL;
1266 goto free_out;
1267 }
1268
1269 cxt->kpszs = psz_init_zones(PSTORE_TYPE_DMESG, &off,
1270 info->total_size - off_size,
1271 info->kmsg_size, &cxt->kmsg_max_cnt);
1272 if (IS_ERR(cxt->kpszs)) {
1273 err = PTR_ERR(cxt->kpszs);
1274 cxt->kpszs = NULL;
1275 goto free_out;
1276 }
1277
1278 return 0;
1279 free_out:
1280 psz_free_all_zones(cxt);
1281 return err;
1282 }
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293 int register_pstore_zone(struct pstore_zone_info *info)
1294 {
1295 int err = -EINVAL;
1296 struct psz_context *cxt = &pstore_zone_cxt;
1297
1298 if (info->total_size < 4096) {
1299 pr_warn("total_size must be >= 4096\n");
1300 return -EINVAL;
1301 }
1302 if (info->total_size > SZ_128M) {
1303 pr_warn("capping size to 128MiB\n");
1304 info->total_size = SZ_128M;
1305 }
1306
1307 if (!info->kmsg_size && !info->pmsg_size && !info->console_size &&
1308 !info->ftrace_size) {
1309 pr_warn("at least one record size must be non-zero\n");
1310 return -EINVAL;
1311 }
1312
1313 if (!info->name || !info->name[0])
1314 return -EINVAL;
1315
1316 #define check_size(name, size) { \
1317 if (info->name > 0 && info->name < (size)) { \
1318 pr_err(#name " must be over %d\n", (size)); \
1319 return -EINVAL; \
1320 } \
1321 if (info->name & (size - 1)) { \
1322 pr_err(#name " must be a multiple of %d\n", \
1323 (size)); \
1324 return -EINVAL; \
1325 } \
1326 }
1327
1328 check_size(total_size, 4096);
1329 check_size(kmsg_size, SECTOR_SIZE);
1330 check_size(pmsg_size, SECTOR_SIZE);
1331 check_size(console_size, SECTOR_SIZE);
1332 check_size(ftrace_size, SECTOR_SIZE);
1333
1334 #undef check_size
1335
1336
1337
1338
1339
1340
1341 if (!info->read || !info->write) {
1342 pr_err("no valid general read/write interface\n");
1343 return -EINVAL;
1344 }
1345
1346 mutex_lock(&cxt->pstore_zone_info_lock);
1347 if (cxt->pstore_zone_info) {
1348 pr_warn("'%s' already loaded: ignoring '%s'\n",
1349 cxt->pstore_zone_info->name, info->name);
1350 mutex_unlock(&cxt->pstore_zone_info_lock);
1351 return -EBUSY;
1352 }
1353 cxt->pstore_zone_info = info;
1354
1355 pr_debug("register %s with properties:\n", info->name);
1356 pr_debug("\ttotal size : %ld Bytes\n", info->total_size);
1357 pr_debug("\tkmsg size : %ld Bytes\n", info->kmsg_size);
1358 pr_debug("\tpmsg size : %ld Bytes\n", info->pmsg_size);
1359 pr_debug("\tconsole size : %ld Bytes\n", info->console_size);
1360 pr_debug("\tftrace size : %ld Bytes\n", info->ftrace_size);
1361
1362 err = psz_alloc_zones(cxt);
1363 if (err) {
1364 pr_err("alloc zones failed\n");
1365 goto fail_out;
1366 }
1367
1368 if (info->kmsg_size) {
1369 cxt->pstore.bufsize = cxt->kpszs[0]->buffer_size -
1370 sizeof(struct psz_kmsg_header);
1371 cxt->pstore.buf = kzalloc(cxt->pstore.bufsize, GFP_KERNEL);
1372 if (!cxt->pstore.buf) {
1373 err = -ENOMEM;
1374 goto fail_free;
1375 }
1376 }
1377 cxt->pstore.data = cxt;
1378
1379 pr_info("registered %s as backend for", info->name);
1380 cxt->pstore.max_reason = info->max_reason;
1381 cxt->pstore.name = info->name;
1382 if (info->kmsg_size) {
1383 cxt->pstore.flags |= PSTORE_FLAGS_DMESG;
1384 pr_cont(" kmsg(%s",
1385 kmsg_dump_reason_str(cxt->pstore.max_reason));
1386 if (cxt->pstore_zone_info->panic_write)
1387 pr_cont(",panic_write");
1388 pr_cont(")");
1389 }
1390 if (info->pmsg_size) {
1391 cxt->pstore.flags |= PSTORE_FLAGS_PMSG;
1392 pr_cont(" pmsg");
1393 }
1394 if (info->console_size) {
1395 cxt->pstore.flags |= PSTORE_FLAGS_CONSOLE;
1396 pr_cont(" console");
1397 }
1398 if (info->ftrace_size) {
1399 cxt->pstore.flags |= PSTORE_FLAGS_FTRACE;
1400 pr_cont(" ftrace");
1401 }
1402 pr_cont("\n");
1403
1404 err = pstore_register(&cxt->pstore);
1405 if (err) {
1406 pr_err("registering with pstore failed\n");
1407 goto fail_free;
1408 }
1409 mutex_unlock(&pstore_zone_cxt.pstore_zone_info_lock);
1410
1411 return 0;
1412
1413 fail_free:
1414 kfree(cxt->pstore.buf);
1415 cxt->pstore.buf = NULL;
1416 cxt->pstore.bufsize = 0;
1417 psz_free_all_zones(cxt);
1418 fail_out:
1419 pstore_zone_cxt.pstore_zone_info = NULL;
1420 mutex_unlock(&pstore_zone_cxt.pstore_zone_info_lock);
1421 return err;
1422 }
1423 EXPORT_SYMBOL_GPL(register_pstore_zone);
1424
1425
1426
1427
1428
1429
1430 void unregister_pstore_zone(struct pstore_zone_info *info)
1431 {
1432 struct psz_context *cxt = &pstore_zone_cxt;
1433
1434 mutex_lock(&cxt->pstore_zone_info_lock);
1435 if (!cxt->pstore_zone_info) {
1436 mutex_unlock(&cxt->pstore_zone_info_lock);
1437 return;
1438 }
1439
1440
1441 pstore_unregister(&cxt->pstore);
1442
1443
1444 psz_flush_all_dirty_zones(NULL);
1445 flush_delayed_work(&psz_cleaner);
1446
1447
1448 kfree(cxt->pstore.buf);
1449 cxt->pstore.buf = NULL;
1450 cxt->pstore.bufsize = 0;
1451 cxt->pstore_zone_info = NULL;
1452
1453 psz_free_all_zones(cxt);
1454
1455
1456 cxt->oops_counter = 0;
1457 cxt->panic_counter = 0;
1458 atomic_set(&cxt->recovered, 0);
1459 atomic_set(&cxt->on_panic, 0);
1460
1461 mutex_unlock(&cxt->pstore_zone_info_lock);
1462 }
1463 EXPORT_SYMBOL_GPL(unregister_pstore_zone);
1464
1465 MODULE_LICENSE("GPL");
1466 MODULE_AUTHOR("WeiXiong Liao <liaoweixiong@allwinnertech.com>");
1467 MODULE_AUTHOR("Kees Cook <keescook@chromium.org>");
1468 MODULE_DESCRIPTION("Storage Manager for pstore/blk");