forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/fs/pstore/platform.c
....@@ -1,21 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Persistent Storage - platform driver interface parts.
34 *
45 * Copyright (C) 2007-2008 Google, Inc.
56 * Copyright (C) 2010 Intel Corporation <tony.luck@intel.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License version 2 as
9
- * published by the Free Software Foundation.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program; if not, write to the Free Software
18
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
197 */
208
219 #define pr_fmt(fmt) "pstore: " fmt
....@@ -56,8 +44,24 @@
5644 module_param_named(update_ms, pstore_update_ms, int, 0600);
5745 MODULE_PARM_DESC(update_ms, "milliseconds before pstore updates its content "
5846 "(default is -1, which means runtime updates are disabled; "
59
- "enabling this option is not safe, it may lead to further "
47
+ "enabling this option may not be safe; it may lead to further "
6048 "corruption on Oopses)");
49
+
50
+/* Names should be in the same order as the enum pstore_type_id */
51
+static const char * const pstore_type_names[] = {
52
+ "dmesg",
53
+ "mce",
54
+ "console",
55
+ "ftrace",
56
+ "rtas",
57
+ "powerpc-ofw",
58
+ "powerpc-common",
59
+ "pmsg",
60
+ "powerpc-opal",
61
+#ifdef CONFIG_PSTORE_BOOT_LOG
62
+ "boot-log",
63
+#endif
64
+};
6165
6266 static int pstore_new_entry;
6367
....@@ -68,19 +72,25 @@
6872 static DECLARE_WORK(pstore_work, pstore_dowork);
6973
7074 /*
71
- * pstore_lock just protects "psinfo" during
72
- * calls to pstore_register()
75
+ * psinfo_lock protects "psinfo" during calls to
76
+ * pstore_register(), pstore_unregister(), and
77
+ * the filesystem mount/unmount routines.
7378 */
74
-static DEFINE_SPINLOCK(pstore_lock);
79
+static DEFINE_MUTEX(psinfo_lock);
7580 struct pstore_info *psinfo;
7681
7782 static char *backend;
83
+module_param(backend, charp, 0444);
84
+MODULE_PARM_DESC(backend, "specific backend to use");
85
+
7886 static char *compress =
7987 #ifdef CONFIG_PSTORE_COMPRESS_DEFAULT
8088 CONFIG_PSTORE_COMPRESS_DEFAULT;
8189 #else
8290 NULL;
8391 #endif
92
+module_param(compress, charp, 0444);
93
+MODULE_PARM_DESC(compress, "compression to use");
8494
8595 /* Compression parameters */
8696 static struct crypto_comp *tfm;
....@@ -104,24 +114,36 @@
104114 /* Tag each group of saved records with a sequence number */
105115 static int oopscount;
106116
107
-static const char *get_reason_str(enum kmsg_dump_reason reason)
117
+const char *pstore_type_to_name(enum pstore_type_id type)
108118 {
109
- switch (reason) {
110
- case KMSG_DUMP_PANIC:
111
- return "Panic";
112
- case KMSG_DUMP_OOPS:
113
- return "Oops";
114
- case KMSG_DUMP_EMERG:
115
- return "Emergency";
116
- case KMSG_DUMP_RESTART:
117
- return "Restart";
118
- case KMSG_DUMP_HALT:
119
- return "Halt";
120
- case KMSG_DUMP_POWEROFF:
121
- return "Poweroff";
122
- default:
123
- return "Unknown";
119
+ BUILD_BUG_ON(ARRAY_SIZE(pstore_type_names) != PSTORE_TYPE_MAX);
120
+
121
+ if (WARN_ON_ONCE(type >= PSTORE_TYPE_MAX))
122
+ return "unknown";
123
+
124
+ return pstore_type_names[type];
125
+}
126
+EXPORT_SYMBOL_GPL(pstore_type_to_name);
127
+
128
+enum pstore_type_id pstore_name_to_type(const char *name)
129
+{
130
+ int i;
131
+
132
+ for (i = 0; i < PSTORE_TYPE_MAX; i++) {
133
+ if (!strcmp(pstore_type_names[i], name))
134
+ return i;
124135 }
136
+
137
+ return PSTORE_TYPE_MAX;
138
+}
139
+EXPORT_SYMBOL_GPL(pstore_name_to_type);
140
+
141
+static void pstore_timer_kick(void)
142
+{
143
+ if (pstore_update_ms < 0)
144
+ return;
145
+
146
+ mod_timer(&pstore_timer, jiffies + msecs_to_jiffies(pstore_update_ms));
125147 }
126148
127149 /*
....@@ -262,20 +284,6 @@
262284 return outlen;
263285 }
264286
265
-static int pstore_decompress(void *in, void *out,
266
- unsigned int inlen, unsigned int outlen)
267
-{
268
- int ret;
269
-
270
- ret = crypto_comp_decompress(tfm, in, inlen, out, &outlen);
271
- if (ret) {
272
- pr_err("crypto_comp_decompress failed, ret = %d!\n", ret);
273
- return ret;
274
- }
275
-
276
- return outlen;
277
-}
278
-
279287 static void allocate_buf_for_compression(void)
280288 {
281289 struct crypto_comp *ctx;
....@@ -322,7 +330,7 @@
322330 big_oops_buf_sz = size;
323331 big_oops_buf = buf;
324332
325
- pr_info("Using compression: %s\n", zbackend->name);
333
+ pr_info("Using crash dump compression: %s\n", zbackend->name);
326334 }
327335
328336 static void free_buf_for_compression(void)
....@@ -374,19 +382,19 @@
374382 }
375383
376384 /*
377
- * callback from kmsg_dump. (s2,l2) has the most recently
378
- * written bytes, older bytes are in (s1,l1). Save as much
379
- * as we can from the end of the buffer.
385
+ * callback from kmsg_dump. Save as much as we can (up to kmsg_bytes) from the
386
+ * end of the buffer.
380387 */
381388 static void pstore_dump(struct kmsg_dumper *dumper,
382
- enum kmsg_dump_reason reason)
389
+ enum kmsg_dump_reason reason,
390
+ struct kmsg_dumper_iter *iter)
383391 {
384392 unsigned long total = 0;
385393 const char *why;
386394 unsigned int part = 1;
387395 int ret;
388396
389
- why = get_reason_str(reason);
397
+ why = kmsg_dump_reason_str(reason);
390398
391399 if (down_trylock(&psinfo->buf_lock)) {
392400 /* Failed to acquire lock: give up if we cannot wait. */
....@@ -431,7 +439,7 @@
431439 dst_size -= header_size;
432440
433441 /* Write dump contents. */
434
- if (!kmsg_dump_get_buffer(dumper, true, dst + header_size,
442
+ if (!kmsg_dump_get_buffer(iter, true, dst + header_size,
435443 dst_size, &dump_size))
436444 break;
437445
....@@ -452,8 +460,10 @@
452460 }
453461
454462 ret = psinfo->write(&record);
455
- if (ret == 0 && reason == KMSG_DUMP_OOPS && pstore_is_mounted())
463
+ if (ret == 0 && reason == KMSG_DUMP_OOPS) {
456464 pstore_new_entry = 1;
465
+ pstore_timer_kick();
466
+ }
457467
458468 total += record.size;
459469 part++;
....@@ -484,6 +494,9 @@
484494 {
485495 struct pstore_record record;
486496
497
+ if (!c)
498
+ return;
499
+
487500 pstore_record_init(&record, psinfo);
488501 record.type = PSTORE_TYPE_CONSOLE;
489502
....@@ -493,18 +506,20 @@
493506 }
494507
495508 static struct console pstore_console = {
496
- .name = "pstore",
497509 .write = pstore_console_write,
498
-#ifdef CON_PSTORE
499
- .flags = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME | CON_PSTORE,
500
-#else
501
- .flags = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME,
502
-#endif
503510 .index = -1,
504511 };
505512
506513 static void pstore_register_console(void)
507514 {
515
+ /* Show which backend is going to get console writes. */
516
+ strscpy(pstore_console.name, psinfo->name,
517
+ sizeof(pstore_console.name));
518
+ /*
519
+ * Always initialize flags here since prior unregister_console()
520
+ * calls may have changed settings (specifically CON_ENABLED).
521
+ */
522
+ pstore_console.flags = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME;
508523 register_console(&pstore_console);
509524 }
510525
....@@ -549,8 +564,6 @@
549564 */
550565 int pstore_register(struct pstore_info *psi)
551566 {
552
- struct module *owner = psi->owner;
553
-
554567 if (backend && strcmp(backend, psi->name)) {
555568 pr_warn("ignoring unexpected backend '%s'\n", psi->name);
556569 return -EPERM;
....@@ -570,11 +583,11 @@
570583 return -EINVAL;
571584 }
572585
573
- spin_lock(&pstore_lock);
586
+ mutex_lock(&psinfo_lock);
574587 if (psinfo) {
575588 pr_warn("backend '%s' already loaded: ignoring '%s'\n",
576589 psinfo->name, psi->name);
577
- spin_unlock(&pstore_lock);
590
+ mutex_unlock(&psinfo_lock);
578591 return -EBUSY;
579592 }
580593
....@@ -583,21 +596,16 @@
583596 psinfo = psi;
584597 mutex_init(&psinfo->read_mutex);
585598 sema_init(&psinfo->buf_lock, 1);
586
- spin_unlock(&pstore_lock);
587
-
588
- if (owner && !try_module_get(owner)) {
589
- psinfo = NULL;
590
- return -EINVAL;
591
- }
592599
593600 if (psi->flags & PSTORE_FLAGS_DMESG)
594601 allocate_buf_for_compression();
595602
596
- if (pstore_is_mounted())
597
- pstore_get_records(0);
603
+ pstore_get_records(0);
598604
599
- if (psi->flags & PSTORE_FLAGS_DMESG)
605
+ if (psi->flags & PSTORE_FLAGS_DMESG) {
606
+ pstore_dumper.max_reason = psinfo->max_reason;
600607 pstore_register_kmsg();
608
+ }
601609 if (psi->flags & PSTORE_FLAGS_CONSOLE)
602610 pstore_register_console();
603611 if (psi->flags & PSTORE_FLAGS_FTRACE)
....@@ -606,33 +614,36 @@
606614 pstore_register_pmsg();
607615
608616 /* Start watching for new records, if desired. */
609
- if (pstore_update_ms >= 0) {
610
- pstore_timer.expires = jiffies +
611
- msecs_to_jiffies(pstore_update_ms);
612
- add_timer(&pstore_timer);
613
- }
617
+ pstore_timer_kick();
614618
615619 /*
616620 * Update the module parameter backend, so it is visible
617621 * through /sys/module/pstore/parameters/backend
618622 */
619
- backend = psi->name;
623
+ backend = kstrdup(psi->name, GFP_KERNEL);
620624
621625 pr_info("Registered %s as persistent store backend\n", psi->name);
622626
623
- module_put(owner);
624
-
627
+ mutex_unlock(&psinfo_lock);
625628 return 0;
626629 }
627630 EXPORT_SYMBOL_GPL(pstore_register);
628631
629632 void pstore_unregister(struct pstore_info *psi)
630633 {
631
- /* Stop timer and make sure all work has finished. */
632
- pstore_update_ms = -1;
633
- del_timer_sync(&pstore_timer);
634
- flush_work(&pstore_work);
634
+ /* It's okay to unregister nothing. */
635
+ if (!psi)
636
+ return;
635637
638
+ mutex_lock(&psinfo_lock);
639
+
640
+ /* Only one backend can be registered at a time. */
641
+ if (WARN_ON(psi != psinfo)) {
642
+ mutex_unlock(&psinfo_lock);
643
+ return;
644
+ }
645
+
646
+ /* Unregister all callbacks. */
636647 if (psi->flags & PSTORE_FLAGS_PMSG)
637648 pstore_unregister_pmsg();
638649 if (psi->flags & PSTORE_FLAGS_FTRACE)
....@@ -642,17 +653,27 @@
642653 if (psi->flags & PSTORE_FLAGS_DMESG)
643654 pstore_unregister_kmsg();
644655
656
+ /* Stop timer and make sure all work has finished. */
657
+ del_timer_sync(&pstore_timer);
658
+ flush_work(&pstore_work);
659
+
660
+ /* Remove all backend records from filesystem tree. */
661
+ pstore_put_backend_records(psi);
662
+
645663 free_buf_for_compression();
646664
647665 psinfo = NULL;
666
+ kfree(backend);
648667 backend = NULL;
668
+ mutex_unlock(&psinfo_lock);
649669 }
650670 EXPORT_SYMBOL_GPL(pstore_unregister);
651671
652672 static void decompress_record(struct pstore_record *record)
653673 {
674
+ int ret;
654675 int unzipped_len;
655
- char *decompressed;
676
+ char *unzipped, *workspace;
656677
657678 if (!IS_ENABLED(CONFIG_PSTORE_COMPRESS) || !record->compressed)
658679 return;
....@@ -663,35 +684,42 @@
663684 return;
664685 }
665686
666
- /* No compression method has created the common buffer. */
687
+ /* Missing compression buffer means compression was not initialized. */
667688 if (!big_oops_buf) {
668
- pr_warn("no decompression buffer allocated\n");
689
+ pr_warn("no decompression method initialized!\n");
669690 return;
670691 }
671692
672
- unzipped_len = pstore_decompress(record->buf, big_oops_buf,
673
- record->size, big_oops_buf_sz);
674
- if (unzipped_len <= 0) {
675
- pr_err("decompression failed: %d\n", unzipped_len);
693
+ /* Allocate enough space to hold max decompression and ECC. */
694
+ unzipped_len = big_oops_buf_sz;
695
+ workspace = kmalloc(unzipped_len + record->ecc_notice_size,
696
+ GFP_KERNEL);
697
+ if (!workspace)
676698 return;
677
- }
678699
679
- /* Build new buffer for decompressed contents. */
680
- decompressed = kmalloc(unzipped_len + record->ecc_notice_size,
681
- GFP_KERNEL);
682
- if (!decompressed) {
683
- pr_err("decompression ran out of memory\n");
700
+ /* After decompression "unzipped_len" is almost certainly smaller. */
701
+ ret = crypto_comp_decompress(tfm, record->buf, record->size,
702
+ workspace, &unzipped_len);
703
+ if (ret) {
704
+ pr_err("crypto_comp_decompress failed, ret = %d!\n", ret);
705
+ kfree(workspace);
684706 return;
685707 }
686
- memcpy(decompressed, big_oops_buf, unzipped_len);
687708
688709 /* Append ECC notice to decompressed buffer. */
689
- memcpy(decompressed + unzipped_len, record->buf + record->size,
710
+ memcpy(workspace + unzipped_len, record->buf + record->size,
690711 record->ecc_notice_size);
691712
692
- /* Swap out compresed contents with decompressed contents. */
713
+ /* Copy decompressed contents into an minimum-sized allocation. */
714
+ unzipped = kmemdup(workspace, unzipped_len + record->ecc_notice_size,
715
+ GFP_KERNEL);
716
+ kfree(workspace);
717
+ if (!unzipped)
718
+ return;
719
+
720
+ /* Swap out compressed contents with decompressed contents. */
693721 kfree(record->buf);
694
- record->buf = decompressed;
722
+ record->buf = unzipped;
695723 record->size = unzipped_len;
696724 record->compressed = false;
697725 }
....@@ -774,12 +802,10 @@
774802 schedule_work(&pstore_work);
775803 }
776804
777
- if (pstore_update_ms >= 0)
778
- mod_timer(&pstore_timer,
779
- jiffies + msecs_to_jiffies(pstore_update_ms));
805
+ pstore_timer_kick();
780806 }
781807
782
-void __init pstore_choose_compression(void)
808
+static void __init pstore_choose_compression(void)
783809 {
784810 const struct pstore_zbackend *step;
785811
....@@ -820,12 +846,6 @@
820846 pstore_exit_fs();
821847 }
822848 module_exit(pstore_exit)
823
-
824
-module_param(compress, charp, 0444);
825
-MODULE_PARM_DESC(compress, "Pstore compression to use");
826
-
827
-module_param(backend, charp, 0444);
828
-MODULE_PARM_DESC(backend, "Pstore backend to use");
829849
830850 MODULE_AUTHOR("Tony Luck <tony.luck@intel.com>");
831851 MODULE_LICENSE("GPL");