hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
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,9 +382,8 @@
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,
382389 enum kmsg_dump_reason reason)
....@@ -386,7 +393,7 @@
386393 unsigned int part = 1;
387394 int ret;
388395
389
- why = get_reason_str(reason);
396
+ why = kmsg_dump_reason_str(reason);
390397
391398 if (down_trylock(&psinfo->buf_lock)) {
392399 /* Failed to acquire lock: give up if we cannot wait. */
....@@ -452,8 +459,10 @@
452459 }
453460
454461 ret = psinfo->write(&record);
455
- if (ret == 0 && reason == KMSG_DUMP_OOPS && pstore_is_mounted())
462
+ if (ret == 0 && reason == KMSG_DUMP_OOPS) {
456463 pstore_new_entry = 1;
464
+ pstore_timer_kick();
465
+ }
457466
458467 total += record.size;
459468 part++;
....@@ -484,6 +493,9 @@
484493 {
485494 struct pstore_record record;
486495
496
+ if (!c)
497
+ return;
498
+
487499 pstore_record_init(&record, psinfo);
488500 record.type = PSTORE_TYPE_CONSOLE;
489501
....@@ -493,18 +505,20 @@
493505 }
494506
495507 static struct console pstore_console = {
496
- .name = "pstore",
497508 .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
503509 .index = -1,
504510 };
505511
506512 static void pstore_register_console(void)
507513 {
514
+ /* Show which backend is going to get console writes. */
515
+ strscpy(pstore_console.name, psinfo->name,
516
+ sizeof(pstore_console.name));
517
+ /*
518
+ * Always initialize flags here since prior unregister_console()
519
+ * calls may have changed settings (specifically CON_ENABLED).
520
+ */
521
+ pstore_console.flags = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME;
508522 register_console(&pstore_console);
509523 }
510524
....@@ -549,8 +563,6 @@
549563 */
550564 int pstore_register(struct pstore_info *psi)
551565 {
552
- struct module *owner = psi->owner;
553
-
554566 if (backend && strcmp(backend, psi->name)) {
555567 pr_warn("ignoring unexpected backend '%s'\n", psi->name);
556568 return -EPERM;
....@@ -570,11 +582,11 @@
570582 return -EINVAL;
571583 }
572584
573
- spin_lock(&pstore_lock);
585
+ mutex_lock(&psinfo_lock);
574586 if (psinfo) {
575587 pr_warn("backend '%s' already loaded: ignoring '%s'\n",
576588 psinfo->name, psi->name);
577
- spin_unlock(&pstore_lock);
589
+ mutex_unlock(&psinfo_lock);
578590 return -EBUSY;
579591 }
580592
....@@ -583,21 +595,16 @@
583595 psinfo = psi;
584596 mutex_init(&psinfo->read_mutex);
585597 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
- }
592598
593599 if (psi->flags & PSTORE_FLAGS_DMESG)
594600 allocate_buf_for_compression();
595601
596
- if (pstore_is_mounted())
597
- pstore_get_records(0);
602
+ pstore_get_records(0);
598603
599
- if (psi->flags & PSTORE_FLAGS_DMESG)
604
+ if (psi->flags & PSTORE_FLAGS_DMESG) {
605
+ pstore_dumper.max_reason = psinfo->max_reason;
600606 pstore_register_kmsg();
607
+ }
601608 if (psi->flags & PSTORE_FLAGS_CONSOLE)
602609 pstore_register_console();
603610 if (psi->flags & PSTORE_FLAGS_FTRACE)
....@@ -606,33 +613,36 @@
606613 pstore_register_pmsg();
607614
608615 /* 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
- }
616
+ pstore_timer_kick();
614617
615618 /*
616619 * Update the module parameter backend, so it is visible
617620 * through /sys/module/pstore/parameters/backend
618621 */
619
- backend = psi->name;
622
+ backend = kstrdup(psi->name, GFP_KERNEL);
620623
621624 pr_info("Registered %s as persistent store backend\n", psi->name);
622625
623
- module_put(owner);
624
-
626
+ mutex_unlock(&psinfo_lock);
625627 return 0;
626628 }
627629 EXPORT_SYMBOL_GPL(pstore_register);
628630
629631 void pstore_unregister(struct pstore_info *psi)
630632 {
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);
633
+ /* It's okay to unregister nothing. */
634
+ if (!psi)
635
+ return;
635636
637
+ mutex_lock(&psinfo_lock);
638
+
639
+ /* Only one backend can be registered at a time. */
640
+ if (WARN_ON(psi != psinfo)) {
641
+ mutex_unlock(&psinfo_lock);
642
+ return;
643
+ }
644
+
645
+ /* Unregister all callbacks. */
636646 if (psi->flags & PSTORE_FLAGS_PMSG)
637647 pstore_unregister_pmsg();
638648 if (psi->flags & PSTORE_FLAGS_FTRACE)
....@@ -642,17 +652,27 @@
642652 if (psi->flags & PSTORE_FLAGS_DMESG)
643653 pstore_unregister_kmsg();
644654
655
+ /* Stop timer and make sure all work has finished. */
656
+ del_timer_sync(&pstore_timer);
657
+ flush_work(&pstore_work);
658
+
659
+ /* Remove all backend records from filesystem tree. */
660
+ pstore_put_backend_records(psi);
661
+
645662 free_buf_for_compression();
646663
647664 psinfo = NULL;
665
+ kfree(backend);
648666 backend = NULL;
667
+ mutex_unlock(&psinfo_lock);
649668 }
650669 EXPORT_SYMBOL_GPL(pstore_unregister);
651670
652671 static void decompress_record(struct pstore_record *record)
653672 {
673
+ int ret;
654674 int unzipped_len;
655
- char *decompressed;
675
+ char *unzipped, *workspace;
656676
657677 if (!IS_ENABLED(CONFIG_PSTORE_COMPRESS) || !record->compressed)
658678 return;
....@@ -663,35 +683,42 @@
663683 return;
664684 }
665685
666
- /* No compression method has created the common buffer. */
686
+ /* Missing compression buffer means compression was not initialized. */
667687 if (!big_oops_buf) {
668
- pr_warn("no decompression buffer allocated\n");
688
+ pr_warn("no decompression method initialized!\n");
669689 return;
670690 }
671691
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);
692
+ /* Allocate enough space to hold max decompression and ECC. */
693
+ unzipped_len = big_oops_buf_sz;
694
+ workspace = kmalloc(unzipped_len + record->ecc_notice_size,
695
+ GFP_KERNEL);
696
+ if (!workspace)
676697 return;
677
- }
678698
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");
699
+ /* After decompression "unzipped_len" is almost certainly smaller. */
700
+ ret = crypto_comp_decompress(tfm, record->buf, record->size,
701
+ workspace, &unzipped_len);
702
+ if (ret) {
703
+ pr_err("crypto_comp_decompress failed, ret = %d!\n", ret);
704
+ kfree(workspace);
684705 return;
685706 }
686
- memcpy(decompressed, big_oops_buf, unzipped_len);
687707
688708 /* Append ECC notice to decompressed buffer. */
689
- memcpy(decompressed + unzipped_len, record->buf + record->size,
709
+ memcpy(workspace + unzipped_len, record->buf + record->size,
690710 record->ecc_notice_size);
691711
692
- /* Swap out compresed contents with decompressed contents. */
712
+ /* Copy decompressed contents into an minimum-sized allocation. */
713
+ unzipped = kmemdup(workspace, unzipped_len + record->ecc_notice_size,
714
+ GFP_KERNEL);
715
+ kfree(workspace);
716
+ if (!unzipped)
717
+ return;
718
+
719
+ /* Swap out compressed contents with decompressed contents. */
693720 kfree(record->buf);
694
- record->buf = decompressed;
721
+ record->buf = unzipped;
695722 record->size = unzipped_len;
696723 record->compressed = false;
697724 }
....@@ -774,12 +801,10 @@
774801 schedule_work(&pstore_work);
775802 }
776803
777
- if (pstore_update_ms >= 0)
778
- mod_timer(&pstore_timer,
779
- jiffies + msecs_to_jiffies(pstore_update_ms));
804
+ pstore_timer_kick();
780805 }
781806
782
-void __init pstore_choose_compression(void)
807
+static void __init pstore_choose_compression(void)
783808 {
784809 const struct pstore_zbackend *step;
785810
....@@ -820,12 +845,6 @@
820845 pstore_exit_fs();
821846 }
822847 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");
829848
830849 MODULE_AUTHOR("Tony Luck <tony.luck@intel.com>");
831850 MODULE_LICENSE("GPL");