Skip to content

Commit 059c4a3

Browse files
committed
Merge tag 'pstore-v6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
Pull pstore updates from Kees Cook: "A small collection of bug fixes, refactorings, and general improvements: - Reporting improvements and return path fixes (Guilherme G. Piccoli, Wang Yufen, Kees Cook) - Clean up kmsg_bytes module parameter usage (Guilherme G. Piccoli) - Add Guilherme to pstore MAINTAINERS entry - Choose friendlier allocation flags (Qiujun Huang, Stephen Boyd)" * tag 'pstore-v6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: pstore: Avoid kcore oops by vmap()ing with VM_IOREMAP pstore/ram: Fix error return code in ramoops_probe() pstore: Alert on backend write error MAINTAINERS: Update pstore maintainers pstore/ram: Set freed addresses to NULL pstore/ram: Move internal definitions out of kernel-wide include pstore/ram: Move pmsg init earlier pstore/ram: Consolidate kfree() paths efi: pstore: Follow convention for the efi-pstore backend name pstore: Inform unregistered backend names as well pstore: Expose kmsg_bytes as a module parameter pstore: Improve error reporting in case of backend overlap pstore/zone: Use GFP_ATOMIC to allocate zone buffer
2 parents 3a28c2c + e6b8427 commit 059c4a3

File tree

8 files changed

+165
-133
lines changed

8 files changed

+165
-133
lines changed

MAINTAINERS

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16661,10 +16661,10 @@ F: net/psample
1666116661

1666216662
PSTORE FILESYSTEM
1666316663
M: Kees Cook <[email protected]>
16664-
M: Anton Vorontsov <[email protected]>
16665-
M: Colin Cross <ccross@android.com>
16666-
M: Tony Luck <[email protected]>
16667-
S: Maintained
16664+
R: Tony Luck <[email protected]>
16665+
R: Guilherme G. Piccoli <gpiccoli@igalia.com>
16666+
16667+
S: Supported
1666816668
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/pstore
1666916669
F: Documentation/admin-guide/ramoops.rst
1667016670
F: Documentation/admin-guide/pstore-blk.rst

drivers/firmware/efi/efi-pstore.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ static int efi_pstore_erase(struct pstore_record *record)
207207

208208
static struct pstore_info efi_pstore_info = {
209209
.owner = THIS_MODULE,
210-
.name = "efi",
210+
.name = KBUILD_MODNAME,
211211
.flags = PSTORE_FLAGS_DMESG,
212212
.open = efi_pstore_open,
213213
.close = efi_pstore_close,

fs/pstore/platform.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ static char *compress =
8989
module_param(compress, charp, 0444);
9090
MODULE_PARM_DESC(compress, "compression to use");
9191

92+
/* How much of the kernel log to snapshot */
93+
unsigned long kmsg_bytes = CONFIG_PSTORE_DEFAULT_KMSG_BYTES;
94+
module_param(kmsg_bytes, ulong, 0444);
95+
MODULE_PARM_DESC(kmsg_bytes, "amount of kernel log to snapshot (in bytes)");
96+
9297
/* Compression parameters */
9398
static struct crypto_comp *tfm;
9499

@@ -100,9 +105,6 @@ struct pstore_zbackend {
100105
static char *big_oops_buf;
101106
static size_t big_oops_buf_sz;
102107

103-
/* How much of the console log to snapshot */
104-
unsigned long kmsg_bytes = CONFIG_PSTORE_DEFAULT_KMSG_BYTES;
105-
106108
void pstore_set_kmsg_bytes(int bytes)
107109
{
108110
kmsg_bytes = bytes;
@@ -391,6 +393,7 @@ static void pstore_dump(struct kmsg_dumper *dumper,
391393
const char *why;
392394
unsigned int part = 1;
393395
unsigned long flags = 0;
396+
int saved_ret = 0;
394397
int ret;
395398

396399
why = kmsg_dump_reason_str(reason);
@@ -461,12 +464,21 @@ static void pstore_dump(struct kmsg_dumper *dumper,
461464
if (ret == 0 && reason == KMSG_DUMP_OOPS) {
462465
pstore_new_entry = 1;
463466
pstore_timer_kick();
467+
} else {
468+
/* Preserve only the first non-zero returned value. */
469+
if (!saved_ret)
470+
saved_ret = ret;
464471
}
465472

466473
total += record.size;
467474
part++;
468475
}
469476
spin_unlock_irqrestore(&psinfo->buf_lock, flags);
477+
478+
if (saved_ret) {
479+
pr_err_once("backend (%s) writing error (%d)\n", psinfo->name,
480+
saved_ret);
481+
}
470482
}
471483

472484
static struct kmsg_dumper pstore_dumper = {
@@ -562,8 +574,9 @@ static int pstore_write_user_compat(struct pstore_record *record,
562574
int pstore_register(struct pstore_info *psi)
563575
{
564576
if (backend && strcmp(backend, psi->name)) {
565-
pr_warn("ignoring unexpected backend '%s'\n", psi->name);
566-
return -EPERM;
577+
pr_warn("backend '%s' already in use: ignoring '%s'\n",
578+
backend, psi->name);
579+
return -EBUSY;
567580
}
568581

569582
/* Sanity check flags. */
@@ -662,6 +675,8 @@ void pstore_unregister(struct pstore_info *psi)
662675
psinfo = NULL;
663676
kfree(backend);
664677
backend = NULL;
678+
679+
pr_info("Unregistered %s as persistent store backend\n", psi->name);
665680
mutex_unlock(&psinfo_lock);
666681
}
667682
EXPORT_SYMBOL_GPL(pstore_unregister);

fs/pstore/ram.c

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@
1818
#include <linux/platform_device.h>
1919
#include <linux/slab.h>
2020
#include <linux/compiler.h>
21-
#include <linux/pstore_ram.h>
2221
#include <linux/of.h>
2322
#include <linux/of_address.h>
23+
2424
#include "internal.h"
25+
#include "ram_internal.h"
2526

2627
#define RAMOOPS_KERNMSG_HDR "===="
2728
#define MIN_MEM_SIZE 4096UL
@@ -451,20 +452,28 @@ static void ramoops_free_przs(struct ramoops_context *cxt)
451452
{
452453
int i;
453454

455+
/* Free pmsg PRZ */
456+
persistent_ram_free(&cxt->mprz);
457+
458+
/* Free console PRZ */
459+
persistent_ram_free(&cxt->cprz);
460+
454461
/* Free dump PRZs */
455462
if (cxt->dprzs) {
456463
for (i = 0; i < cxt->max_dump_cnt; i++)
457-
persistent_ram_free(cxt->dprzs[i]);
464+
persistent_ram_free(&cxt->dprzs[i]);
458465

459466
kfree(cxt->dprzs);
467+
cxt->dprzs = NULL;
460468
cxt->max_dump_cnt = 0;
461469
}
462470

463471
/* Free ftrace PRZs */
464472
if (cxt->fprzs) {
465473
for (i = 0; i < cxt->max_ftrace_cnt; i++)
466-
persistent_ram_free(cxt->fprzs[i]);
474+
persistent_ram_free(&cxt->fprzs[i]);
467475
kfree(cxt->fprzs);
476+
cxt->fprzs = NULL;
468477
cxt->max_ftrace_cnt = 0;
469478
}
470479
}
@@ -548,9 +557,10 @@ static int ramoops_init_przs(const char *name,
548557

549558
while (i > 0) {
550559
i--;
551-
persistent_ram_free(prz_ar[i]);
560+
persistent_ram_free(&prz_ar[i]);
552561
}
553562
kfree(prz_ar);
563+
prz_ar = NULL;
554564
goto fail;
555565
}
556566
*paddr += zone_sz;
@@ -735,13 +745,15 @@ static int ramoops_probe(struct platform_device *pdev)
735745
/* Make sure we didn't get bogus platform data pointer. */
736746
if (!pdata) {
737747
pr_err("NULL platform data\n");
748+
err = -EINVAL;
738749
goto fail_out;
739750
}
740751

741752
if (!pdata->mem_size || (!pdata->record_size && !pdata->console_size &&
742753
!pdata->ftrace_size && !pdata->pmsg_size)) {
743754
pr_err("The memory size and the record/console size must be "
744755
"non-zero\n");
756+
err = -EINVAL;
745757
goto fail_out;
746758
}
747759

@@ -772,12 +784,17 @@ static int ramoops_probe(struct platform_device *pdev)
772784
dump_mem_sz, cxt->record_size,
773785
&cxt->max_dump_cnt, 0, 0);
774786
if (err)
775-
goto fail_out;
787+
goto fail_init;
776788

777789
err = ramoops_init_prz("console", dev, cxt, &cxt->cprz, &paddr,
778790
cxt->console_size, 0);
779791
if (err)
780-
goto fail_init_cprz;
792+
goto fail_init;
793+
794+
err = ramoops_init_prz("pmsg", dev, cxt, &cxt->mprz, &paddr,
795+
cxt->pmsg_size, 0);
796+
if (err)
797+
goto fail_init;
781798

782799
cxt->max_ftrace_cnt = (cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU)
783800
? nr_cpu_ids
@@ -788,12 +805,7 @@ static int ramoops_probe(struct platform_device *pdev)
788805
(cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU)
789806
? PRZ_FLAG_NO_LOCK : 0);
790807
if (err)
791-
goto fail_init_fprz;
792-
793-
err = ramoops_init_prz("pmsg", dev, cxt, &cxt->mprz, &paddr,
794-
cxt->pmsg_size, 0);
795-
if (err)
796-
goto fail_init_mprz;
808+
goto fail_init;
797809

798810
cxt->pstore.data = cxt;
799811
/*
@@ -857,11 +869,7 @@ static int ramoops_probe(struct platform_device *pdev)
857869
kfree(cxt->pstore.buf);
858870
fail_clear:
859871
cxt->pstore.bufsize = 0;
860-
persistent_ram_free(cxt->mprz);
861-
fail_init_mprz:
862-
fail_init_fprz:
863-
persistent_ram_free(cxt->cprz);
864-
fail_init_cprz:
872+
fail_init:
865873
ramoops_free_przs(cxt);
866874
fail_out:
867875
return err;
@@ -876,8 +884,6 @@ static int ramoops_remove(struct platform_device *pdev)
876884
kfree(cxt->pstore.buf);
877885
cxt->pstore.bufsize = 0;
878886

879-
persistent_ram_free(cxt->mprz);
880-
persistent_ram_free(cxt->cprz);
881887
ramoops_free_przs(cxt);
882888

883889
return 0;

fs/pstore/ram_core.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@
1313
#include <linux/kernel.h>
1414
#include <linux/list.h>
1515
#include <linux/memblock.h>
16-
#include <linux/pstore_ram.h>
1716
#include <linux/rslib.h>
1817
#include <linux/slab.h>
1918
#include <linux/uaccess.h>
2019
#include <linux/vmalloc.h>
2120
#include <asm/page.h>
2221

22+
#include "ram_internal.h"
23+
2324
/**
2425
* struct persistent_ram_buffer - persistent circular RAM buffer
2526
*
@@ -439,7 +440,11 @@ static void *persistent_ram_vmap(phys_addr_t start, size_t size,
439440
phys_addr_t addr = page_start + i * PAGE_SIZE;
440441
pages[i] = pfn_to_page(addr >> PAGE_SHIFT);
441442
}
442-
vaddr = vmap(pages, page_count, VM_MAP, prot);
443+
/*
444+
* VM_IOREMAP used here to bypass this region during vread()
445+
* and kmap_atomic() (i.e. kcore) to avoid __va() failures.
446+
*/
447+
vaddr = vmap(pages, page_count, VM_MAP | VM_IOREMAP, prot);
443448
kfree(pages);
444449

445450
/*
@@ -543,8 +548,14 @@ static int persistent_ram_post_init(struct persistent_ram_zone *prz, u32 sig,
543548
return 0;
544549
}
545550

546-
void persistent_ram_free(struct persistent_ram_zone *prz)
551+
void persistent_ram_free(struct persistent_ram_zone **_prz)
547552
{
553+
struct persistent_ram_zone *prz;
554+
555+
if (!_prz)
556+
return;
557+
558+
prz = *_prz;
548559
if (!prz)
549560
return;
550561

@@ -568,6 +579,7 @@ void persistent_ram_free(struct persistent_ram_zone *prz)
568579
persistent_ram_free_old(prz);
569580
kfree(prz->label);
570581
kfree(prz);
582+
*_prz = NULL;
571583
}
572584

573585
struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
@@ -604,6 +616,6 @@ struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
604616

605617
return prz;
606618
err:
607-
persistent_ram_free(prz);
619+
persistent_ram_free(&prz);
608620
return ERR_PTR(ret);
609621
}

fs/pstore/ram_internal.h

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Copyright (C) 2010 Marco Stornelli <[email protected]>
4+
* Copyright (C) 2011 Kees Cook <[email protected]>
5+
* Copyright (C) 2011 Google, Inc.
6+
*/
7+
8+
#include <linux/pstore_ram.h>
9+
10+
/*
11+
* Choose whether access to the RAM zone requires locking or not. If a zone
12+
* can be written to from different CPUs like with ftrace for example, then
13+
* PRZ_FLAG_NO_LOCK is used. For all other cases, locking is required.
14+
*/
15+
#define PRZ_FLAG_NO_LOCK BIT(0)
16+
/*
17+
* If a PRZ should only have a single-boot lifetime, this marks it as
18+
* getting wiped after its contents get copied out after boot.
19+
*/
20+
#define PRZ_FLAG_ZAP_OLD BIT(1)
21+
22+
/**
23+
* struct persistent_ram_zone - Details of a persistent RAM zone (PRZ)
24+
* used as a pstore backend
25+
*
26+
* @paddr: physical address of the mapped RAM area
27+
* @size: size of mapping
28+
* @label: unique name of this PRZ
29+
* @type: frontend type for this PRZ
30+
* @flags: holds PRZ_FLAGS_* bits
31+
*
32+
* @buffer_lock:
33+
* locks access to @buffer "size" bytes and "start" offset
34+
* @buffer:
35+
* pointer to actual RAM area managed by this PRZ
36+
* @buffer_size:
37+
* bytes in @buffer->data (not including any trailing ECC bytes)
38+
*
39+
* @par_buffer:
40+
* pointer into @buffer->data containing ECC bytes for @buffer->data
41+
* @par_header:
42+
* pointer into @buffer->data containing ECC bytes for @buffer header
43+
* (i.e. all fields up to @data)
44+
* @rs_decoder:
45+
* RSLIB instance for doing ECC calculations
46+
* @corrected_bytes:
47+
* ECC corrected bytes accounting since boot
48+
* @bad_blocks:
49+
* ECC uncorrectable bytes accounting since boot
50+
* @ecc_info:
51+
* ECC configuration details
52+
*
53+
* @old_log:
54+
* saved copy of @buffer->data prior to most recent wipe
55+
* @old_log_size:
56+
* bytes contained in @old_log
57+
*
58+
*/
59+
struct persistent_ram_zone {
60+
phys_addr_t paddr;
61+
size_t size;
62+
void *vaddr;
63+
char *label;
64+
enum pstore_type_id type;
65+
u32 flags;
66+
67+
raw_spinlock_t buffer_lock;
68+
struct persistent_ram_buffer *buffer;
69+
size_t buffer_size;
70+
71+
char *par_buffer;
72+
char *par_header;
73+
struct rs_control *rs_decoder;
74+
int corrected_bytes;
75+
int bad_blocks;
76+
struct persistent_ram_ecc_info ecc_info;
77+
78+
char *old_log;
79+
size_t old_log_size;
80+
};
81+
82+
struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
83+
u32 sig, struct persistent_ram_ecc_info *ecc_info,
84+
unsigned int memtype, u32 flags, char *label);
85+
void persistent_ram_free(struct persistent_ram_zone **_prz);
86+
void persistent_ram_zap(struct persistent_ram_zone *prz);
87+
88+
int persistent_ram_write(struct persistent_ram_zone *prz, const void *s,
89+
unsigned int count);
90+
int persistent_ram_write_user(struct persistent_ram_zone *prz,
91+
const void __user *s, unsigned int count);
92+
93+
void persistent_ram_save_old(struct persistent_ram_zone *prz);
94+
size_t persistent_ram_old_size(struct persistent_ram_zone *prz);
95+
void *persistent_ram_old(struct persistent_ram_zone *prz);
96+
void persistent_ram_free_old(struct persistent_ram_zone *prz);
97+
ssize_t persistent_ram_ecc_string(struct persistent_ram_zone *prz,
98+
char *str, size_t len);

fs/pstore/zone.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,7 @@ static inline int notrace psz_kmsg_write_record(struct psz_context *cxt,
761761
/* avoid destroying old data, allocate a new one */
762762
len = zone->buffer_size + sizeof(*zone->buffer);
763763
zone->oldbuf = zone->buffer;
764-
zone->buffer = kzalloc(len, GFP_KERNEL);
764+
zone->buffer = kzalloc(len, GFP_ATOMIC);
765765
if (!zone->buffer) {
766766
zone->buffer = zone->oldbuf;
767767
return -ENOMEM;

0 commit comments

Comments
 (0)