Skip to content

Commit 791205e

Browse files
committed
pstore/ram: Introduce max_reason and convert dump_oops
Now that pstore_register() can correctly pass max_reason to the kmesg dump facility, introduce a new "max_reason" module parameter and "max-reason" Device Tree field. The "dump_oops" module parameter and "dump-oops" Device Tree field are now considered deprecated, but are now automatically converted to their corresponding max_reason values when present, though the new max_reason setting has precedence. For struct ramoops_platform_data, the "dump_oops" member is entirely replaced by a new "max_reason" member, with the only existing user updated in place. Additionally remove the "reason" filter logic from ramoops_pstore_write(), as that is not specifically needed anymore, though technically this is a change in behavior for any ramoops users also setting the printk.always_kmsg_dump boot param, which will cause ramoops to behave as if max_reason was set to KMSG_DUMP_MAX. Co-developed-by: Pavel Tatashin <[email protected]> Signed-off-by: Pavel Tatashin <[email protected]> Link: https://lore.kernel.org/lkml/[email protected]/ Signed-off-by: Kees Cook <[email protected]>
1 parent 3524e68 commit 791205e

File tree

4 files changed

+51
-25
lines changed

4 files changed

+51
-25
lines changed

Documentation/admin-guide/ramoops.rst

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,17 @@ memory to be mapped strongly ordered, and atomic operations on strongly ordered
3232
memory are implementation defined, and won't work on many ARMs such as omaps.
3333

3434
The memory area is divided into ``record_size`` chunks (also rounded down to
35-
power of two) and each oops/panic writes a ``record_size`` chunk of
35+
power of two) and each kmesg dump writes a ``record_size`` chunk of
3636
information.
3737

38-
Dumping both oopses and panics can be done by setting 1 in the ``dump_oops``
39-
variable while setting 0 in that variable dumps only the panics.
38+
Limiting which kinds of kmsg dumps are stored can be controlled via
39+
the ``max_reason`` value, as defined in include/linux/kmsg_dump.h's
40+
``enum kmsg_dump_reason``. For example, to store both Oopses and Panics,
41+
``max_reason`` should be set to 2 (KMSG_DUMP_OOPS), to store only Panics
42+
``max_reason`` should be set to 1 (KMSG_DUMP_PANIC). Setting this to 0
43+
(KMSG_DUMP_UNDEF), means the reason filtering will be controlled by the
44+
``printk.always_kmsg_dump`` boot param: if unset, it'll be KMSG_DUMP_OOPS,
45+
otherwise KMSG_DUMP_MAX.
4046

4147
The module uses a counter to record multiple dumps but the counter gets reset
4248
on restart (i.e. new dumps after the restart will overwrite old ones).
@@ -90,7 +96,7 @@ Setting the ramoops parameters can be done in several different manners:
9096
.mem_address = <...>,
9197
.mem_type = <...>,
9298
.record_size = <...>,
93-
.dump_oops = <...>,
99+
.max_reason = <...>,
94100
.ecc = <...>,
95101
};
96102

drivers/platform/chrome/chromeos_pstore.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ static struct ramoops_platform_data chromeos_ramoops_data = {
5757
.record_size = 0x40000,
5858
.console_size = 0x20000,
5959
.ftrace_size = 0x20000,
60-
.dump_oops = 1,
60+
.max_reason = KMSG_DUMP_OOPS,
6161
};
6262

6363
static struct platform_device chromeos_ramoops = {

fs/pstore/ram.c

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ module_param(mem_type, uint, 0400);
5858
MODULE_PARM_DESC(mem_type,
5959
"set to 1 to try to use unbuffered memory (default 0)");
6060

61-
static int dump_oops = 1;
62-
module_param(dump_oops, int, 0400);
63-
MODULE_PARM_DESC(dump_oops,
64-
"set to 1 to dump oopses, 0 to only dump panics (default 1)");
61+
static int ramoops_max_reason = -1;
62+
module_param_named(max_reason, ramoops_max_reason, int, 0400);
63+
MODULE_PARM_DESC(max_reason,
64+
"maximum reason for kmsg dump (default 2: Oops and Panic) ");
6565

6666
static int ramoops_ecc;
6767
module_param_named(ecc, ramoops_ecc, int, 0400);
@@ -70,6 +70,11 @@ MODULE_PARM_DESC(ramoops_ecc,
7070
"ECC buffer size in bytes (1 is a special value, means 16 "
7171
"bytes ECC)");
7272

73+
static int ramoops_dump_oops = -1;
74+
module_param_named(dump_oops, ramoops_dump_oops, int, 0400);
75+
MODULE_PARM_DESC(dump_oops,
76+
"(deprecated: use max_reason instead) set to 1 to dump oopses & panics, 0 to only dump panics");
77+
7378
struct ramoops_context {
7479
struct persistent_ram_zone **dprzs; /* Oops dump zones */
7580
struct persistent_ram_zone *cprz; /* Console zone */
@@ -82,7 +87,6 @@ struct ramoops_context {
8287
size_t console_size;
8388
size_t ftrace_size;
8489
size_t pmsg_size;
85-
int dump_oops;
8690
u32 flags;
8791
struct persistent_ram_ecc_info ecc_info;
8892
unsigned int max_dump_cnt;
@@ -336,16 +340,14 @@ static int notrace ramoops_pstore_write(struct pstore_record *record)
336340
return -EINVAL;
337341

338342
/*
339-
* Out of the various dmesg dump types, ramoops is currently designed
340-
* to only store crash logs, rather than storing general kernel logs.
343+
* We could filter on record->reason here if we wanted to (which
344+
* would duplicate what happened before the "max_reason" setting
345+
* was added), but that would defeat the purpose of a system
346+
* changing printk.always_kmsg_dump, so instead log everything that
347+
* the kmsg dumper sends us, since it should be doing the filtering
348+
* based on the combination of printk.always_kmsg_dump and our
349+
* requested "max_reason".
341350
*/
342-
if (record->reason != KMSG_DUMP_OOPS &&
343-
record->reason != KMSG_DUMP_PANIC)
344-
return -EINVAL;
345-
346-
/* Skip Oopes when configured to do so. */
347-
if (record->reason == KMSG_DUMP_OOPS && !cxt->dump_oops)
348-
return -EINVAL;
349351

350352
/*
351353
* Explicitly only take the first part of any new crash.
@@ -647,7 +649,14 @@ static int ramoops_parse_dt(struct platform_device *pdev,
647649
pdata->mem_size = resource_size(res);
648650
pdata->mem_address = res->start;
649651
pdata->mem_type = of_property_read_bool(of_node, "unbuffered");
650-
pdata->dump_oops = !of_property_read_bool(of_node, "no-dump-oops");
652+
/*
653+
* Setting "no-dump-oops" is deprecated and will be ignored if
654+
* "max_reason" is also specified.
655+
*/
656+
if (of_property_read_bool(of_node, "no-dump-oops"))
657+
pdata->max_reason = KMSG_DUMP_PANIC;
658+
else
659+
pdata->max_reason = KMSG_DUMP_OOPS;
651660

652661
#define parse_u32(name, field, default_value) { \
653662
ret = ramoops_parse_dt_u32(pdev, name, default_value, \
@@ -663,6 +672,7 @@ static int ramoops_parse_dt(struct platform_device *pdev,
663672
parse_u32("pmsg-size", pdata->pmsg_size, 0);
664673
parse_u32("ecc-size", pdata->ecc_info.ecc_size, 0);
665674
parse_u32("flags", pdata->flags, 0);
675+
parse_u32("max-reason", pdata->max_reason, pdata->max_reason);
666676

667677
#undef parse_u32
668678

@@ -746,7 +756,6 @@ static int ramoops_probe(struct platform_device *pdev)
746756
cxt->console_size = pdata->console_size;
747757
cxt->ftrace_size = pdata->ftrace_size;
748758
cxt->pmsg_size = pdata->pmsg_size;
749-
cxt->dump_oops = pdata->dump_oops;
750759
cxt->flags = pdata->flags;
751760
cxt->ecc_info = pdata->ecc_info;
752761

@@ -789,8 +798,10 @@ static int ramoops_probe(struct platform_device *pdev)
789798
* the single region size is how to check.
790799
*/
791800
cxt->pstore.flags = 0;
792-
if (cxt->max_dump_cnt)
801+
if (cxt->max_dump_cnt) {
793802
cxt->pstore.flags |= PSTORE_FLAGS_DMESG;
803+
cxt->pstore.max_reason = pdata->max_reason;
804+
}
794805
if (cxt->console_size)
795806
cxt->pstore.flags |= PSTORE_FLAGS_CONSOLE;
796807
if (cxt->max_ftrace_cnt)
@@ -826,7 +837,7 @@ static int ramoops_probe(struct platform_device *pdev)
826837
mem_size = pdata->mem_size;
827838
mem_address = pdata->mem_address;
828839
record_size = pdata->record_size;
829-
dump_oops = pdata->dump_oops;
840+
ramoops_max_reason = pdata->max_reason;
830841
ramoops_console_size = pdata->console_size;
831842
ramoops_pmsg_size = pdata->pmsg_size;
832843
ramoops_ftrace_size = pdata->ftrace_size;
@@ -909,7 +920,16 @@ static void __init ramoops_register_dummy(void)
909920
pdata.console_size = ramoops_console_size;
910921
pdata.ftrace_size = ramoops_ftrace_size;
911922
pdata.pmsg_size = ramoops_pmsg_size;
912-
pdata.dump_oops = dump_oops;
923+
/* If "max_reason" is set, its value has priority over "dump_oops". */
924+
if (ramoops_max_reason >= 0)
925+
pdata.max_reason = ramoops_max_reason;
926+
/* Otherwise, if "dump_oops" is set, parse it into "max_reason". */
927+
else if (ramoops_dump_oops != -1)
928+
pdata.max_reason = ramoops_dump_oops ? KMSG_DUMP_OOPS
929+
: KMSG_DUMP_PANIC;
930+
/* And if neither are explicitly set, use the default. */
931+
else
932+
pdata.max_reason = KMSG_DUMP_OOPS;
913933
pdata.flags = RAMOOPS_FLAG_FTRACE_PER_CPU;
914934

915935
/*

include/linux/pstore_ram.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ struct ramoops_platform_data {
133133
unsigned long console_size;
134134
unsigned long ftrace_size;
135135
unsigned long pmsg_size;
136-
int dump_oops;
136+
int max_reason;
137137
u32 flags;
138138
struct persistent_ram_ecc_info ecc_info;
139139
};

0 commit comments

Comments
 (0)