Re: [PATCH] printk: Add a short description string to kmsg_dump()

2024-06-28 Thread Kees Cook
On Fri, Jun 28, 2024 at 09:13:11AM +0200, Jocelyn Falempe wrote:
> It is present in the kdump log, but before all the register dumps.
> So to retrieve it you need to parse the last 30~40 lines of logs, and search
> for a line starting with "Kernel panic - not syncing".
> https://elixir.bootlin.com/linux/v6.10-rc5/source/kernel/panic.c#L341
> But I think that's a bit messy, and I prefer having a kmsg_dump parameter.

Yeah, I totally agree: it should be easy to access the panic reason. I
just wanted to double-check that from pstore's perspective there wasn't
any "new" information here that should be captured somehow.

Thanks!

-- 
Kees Cook


Re: [PATCH] printk: Add a short description string to kmsg_dump()

2024-06-28 Thread Jocelyn Falempe




On 26/06/2024 18:26, Kees Cook wrote:

On Tue, Jun 25, 2024 at 02:39:29PM +0200, Jocelyn Falempe wrote:

kmsg_dump doesn't forward the panic reason string to the kmsg_dumper
callback.
This patch adds a new parameter "const char *desc" to the kmsg_dumper
dump() callback, and update all drivers that are using it.

To avoid updating all kmsg_dump() call, it adds a kmsg_dump_desc()
function and a macro for backward compatibility.

I've written this for drm_panic, but it can be useful for other
kmsg_dumper.
It allows to see the panic reason, like "sysrq triggered crash"
or "VFS: Unable to mount root fs on " on the drm panic screen.


Seems reasonable. Given the prototype before/after:

dump(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason)

dump(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason,
  const char *desc)

Perhaps this should instead be a struct that the panic fills in? Then
it'll be easy to adjust the struct in the future:


yes that's a good idea, so it's a bit more flexible.



struct kmsg_dump_detail {
enum kmsg_dump_reason reason;
const char *description;
};

dump(struct kmsg_dumper *dumper, struct kmsg_dump *detail)

This .cocci could do the conversion:


@ dump_func @
identifier DUMPER, CALLBACK;
@@

   struct kmsg_dumper DUMPER = {
 .dump = CALLBACK,
   };

@ detail @
identifier dump_func.CALLBACK;
identifier DUMPER, REASON;
@@

CALLBACK(struct kmsg_dumper *DUMPER,
-enum kmsg_dump_reason REASON
+struct kmsg_dump_detail *detail
)
{
<...
-   REASON
+   detail->reason
...>
}


Also, just to double-check, doesn't the panic reason show up in the
kmsg_dump log itself (at the end?) I ask since for pstore, "desc" is
likely redundant since it's capturing the entire console log.


It is present in the kdump log, but before all the register dumps.
So to retrieve it you need to parse the last 30~40 lines of logs, and 
search for a line starting with "Kernel panic - not syncing".

https://elixir.bootlin.com/linux/v6.10-rc5/source/kernel/panic.c#L341
But I think that's a bit messy, and I prefer having a kmsg_dump parameter.

--

Jocelyn


-Kees

Here's the patch from the above cocci:


diff -u -p a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -207,13 +207,13 @@ static int hv_die_panic_notify_crash(str
   * buffer and call into Hyper-V to transfer the data.
   */
  static void hv_kmsg_dump(struct kmsg_dumper *dumper,
-enum kmsg_dump_reason reason)
+struct kmsg_dump_detail *detail)
  {
struct kmsg_dump_iter iter;
size_t bytes_written;
  
  	/* We are only interested in panics. */

-   if (reason != KMSG_DUMP_PANIC || !sysctl_record_panic_msg)
+   if (detail->reason != KMSG_DUMP_PANIC || !sysctl_record_panic_msg)
return;
  
  	/*

diff -u -p a/arch/powerpc/platforms/powernv/opal-kmsg.c 
b/arch/powerpc/platforms/powernv/opal-kmsg.c
--- a/arch/powerpc/platforms/powernv/opal-kmsg.c
+++ b/arch/powerpc/platforms/powernv/opal-kmsg.c
@@ -20,13 +20,13 @@
   * message, it just ensures that OPAL completely flushes the console buffer.
   */
  static void kmsg_dump_opal_console_flush(struct kmsg_dumper *dumper,
-enum kmsg_dump_reason reason)
+struct kmsg_dump_detail *detail)
  {
/*
 * Outside of a panic context the pollers will continue to run,
 * so we don't need to do any special flushing.
 */
-   if (reason != KMSG_DUMP_PANIC)
+   if (detail->reason != KMSG_DUMP_PANIC)
return;
  
  	opal_flush_console(0);

diff -u -p a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -73,7 +73,7 @@ static const char *nvram_os_partitions[]
  };
  
  static void oops_to_nvram(struct kmsg_dumper *dumper,

- enum kmsg_dump_reason reason);
+ struct kmsg_dump_detail *detail);
  
  static struct kmsg_dumper nvram_kmsg_dumper = {

.dump = oops_to_nvram
@@ -643,7 +643,7 @@ void __init nvram_init_oops_partition(in
   * partition.  If that's too much, go back and capture uncompressed text.
   */
  static void oops_to_nvram(struct kmsg_dumper *dumper,
- enum kmsg_dump_reason reason)
+ struct kmsg_dump_detail *detail)
  {
struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
static unsigned int oops_count = 0;
@@ -655,7 +655,7 @@ static void oops_to_nvram(struct kmsg_du
unsigned int err_type = ERR_TYPE_KERNEL_PANIC_GZ;
int rc = -1;
  
-	switch (reason) {

+   switch (detail->reason) {
case KMSG_DUMP_SHUTDOWN:
/* These are almost always 

Re: [PATCH] printk: Add a short description string to kmsg_dump()

2024-06-27 Thread Jocelyn Falempe




On 26/06/2024 10:00, Petr Mladek wrote:

On Tue 2024-06-25 14:39:29, Jocelyn Falempe wrote:

kmsg_dump doesn't forward the panic reason string to the kmsg_dumper
callback.
This patch adds a new parameter "const char *desc" to the kmsg_dumper
dump() callback, and update all drivers that are using it.

To avoid updating all kmsg_dump() call, it adds a kmsg_dump_desc()
function and a macro for backward compatibility.

I've written this for drm_panic, but it can be useful for other
kmsg_dumper.
It allows to see the panic reason, like "sysrq triggered crash"
or "VFS: Unable to mount root fs on " on the drm panic screen.

Signed-off-by: Jocelyn Falempe 
---
  arch/powerpc/kernel/nvram_64.c |  3 ++-
  arch/powerpc/platforms/powernv/opal-kmsg.c |  3 ++-
  drivers/gpu/drm/drm_panic.c|  3 ++-
  drivers/hv/hv_common.c |  3 ++-
  drivers/mtd/mtdoops.c  |  3 ++-
  fs/pstore/platform.c   |  3 ++-
  include/linux/kmsg_dump.h  | 13 ++---
  kernel/panic.c |  2 +-
  kernel/printk/printk.c |  8 +---
  9 files changed, 28 insertions(+), 13 deletions(-)


The parameter is added into all dumpers. I guess that it would be
used only drm_panic() because it is graphics and might be "fancy".
The others simply dump the log buffer and the reason is in
the dumped log as well.


Ok, I also tried to retrieve the reason from the dumped log, but that's 
really fragile.




Anyway, the passed buffer is static. Alternative solution would
be to make it global and export it like, for example, panic_cpu.


It's not a static buffer, because the string is generated at runtime.
eg: https://elixir.bootlin.com/linux/latest/source/arch/arm/mm/init.c#L158

So it will be hard to avoid race conditions.



Best Regards,
Petr





[PATCH] printk: Add a short description string to kmsg_dump()

2024-06-26 Thread Jocelyn Falempe
kmsg_dump doesn't forward the panic reason string to the kmsg_dumper
callback.
This patch adds a new parameter "const char *desc" to the kmsg_dumper
dump() callback, and update all drivers that are using it.

To avoid updating all kmsg_dump() call, it adds a kmsg_dump_desc()
function and a macro for backward compatibility.

I've written this for drm_panic, but it can be useful for other
kmsg_dumper.
It allows to see the panic reason, like "sysrq triggered crash"
or "VFS: Unable to mount root fs on " on the drm panic screen.

Signed-off-by: Jocelyn Falempe 
---
 arch/powerpc/kernel/nvram_64.c |  3 ++-
 arch/powerpc/platforms/powernv/opal-kmsg.c |  3 ++-
 drivers/gpu/drm/drm_panic.c|  3 ++-
 drivers/hv/hv_common.c |  3 ++-
 drivers/mtd/mtdoops.c  |  3 ++-
 fs/pstore/platform.c   |  3 ++-
 include/linux/kmsg_dump.h  | 13 ++---
 kernel/panic.c |  2 +-
 kernel/printk/printk.c |  8 +---
 9 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
index e385d3164648c..6b3a80d8cfa64 100644
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -643,7 +643,8 @@ void __init nvram_init_oops_partition(int 
rtas_partition_exists)
  * partition.  If that's too much, go back and capture uncompressed text.
  */
 static void oops_to_nvram(struct kmsg_dumper *dumper,
- enum kmsg_dump_reason reason)
+ enum kmsg_dump_reason reason,
+ const char *desc)
 {
struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
static unsigned int oops_count = 0;
diff --git a/arch/powerpc/platforms/powernv/opal-kmsg.c 
b/arch/powerpc/platforms/powernv/opal-kmsg.c
index 6c3bc4b4da983..49b60de6feb04 100644
--- a/arch/powerpc/platforms/powernv/opal-kmsg.c
+++ b/arch/powerpc/platforms/powernv/opal-kmsg.c
@@ -20,7 +20,8 @@
  * message, it just ensures that OPAL completely flushes the console buffer.
  */
 static void kmsg_dump_opal_console_flush(struct kmsg_dumper *dumper,
-enum kmsg_dump_reason reason)
+enum kmsg_dump_reason reason,
+const char *desc)
 {
/*
 * Outside of a panic context the pollers will continue to run,
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index 293d4dcbc80da..88e9359fe6d78 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -604,7 +604,8 @@ static struct drm_plane *to_drm_plane(struct kmsg_dumper 
*kd)
return container_of(kd, struct drm_plane, kmsg_panic);
 }
 
-static void drm_panic(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason)
+static void drm_panic(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason,
+ const char *desc)
 {
struct drm_plane *plane = to_drm_plane(dumper);
 
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 9c452bfbd5719..b0786ee9c94e3 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -207,7 +207,8 @@ static int hv_die_panic_notify_crash(struct notifier_block 
*self,
  * buffer and call into Hyper-V to transfer the data.
  */
 static void hv_kmsg_dump(struct kmsg_dumper *dumper,
-enum kmsg_dump_reason reason)
+enum kmsg_dump_reason reason,
+const char *desc)
 {
struct kmsg_dump_iter iter;
size_t bytes_written;
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
index 2f11585b5613e..c618999a96832 100644
--- a/drivers/mtd/mtdoops.c
+++ b/drivers/mtd/mtdoops.c
@@ -298,7 +298,8 @@ static void find_next_position(struct mtdoops_context *cxt)
 }
 
 static void mtdoops_do_dump(struct kmsg_dumper *dumper,
-   enum kmsg_dump_reason reason)
+   enum kmsg_dump_reason reason,
+   const char *desc)
 {
struct mtdoops_context *cxt = container_of(dumper,
struct mtdoops_context, dump);
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 3497ede88aa01..a6ed5d56021ef 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -275,7 +275,8 @@ void pstore_record_init(struct pstore_record *record,
  * end of the buffer.
  */
 static void pstore_dump(struct kmsg_dumper *dumper,
-   enum kmsg_dump_reason reason)
+   enum kmsg_dump_reason reason,
+   const char *desc)
 {
struct kmsg_dump_iter iter;
unsigned long   total = 0;
diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h
index 906521c2329ca..a8f8a6204542d 100644
--- a/include/linux/kmsg_dump.h
+++ b/include/linux/kmsg_dump.h
@@ -49,13 +49,15 @@ struct kmsg_dump_iter 

Re: [PATCH] printk: Add a short description string to kmsg_dump()

2024-06-26 Thread Kees Cook
On Tue, Jun 25, 2024 at 02:39:29PM +0200, Jocelyn Falempe wrote:
> kmsg_dump doesn't forward the panic reason string to the kmsg_dumper
> callback.
> This patch adds a new parameter "const char *desc" to the kmsg_dumper
> dump() callback, and update all drivers that are using it.
> 
> To avoid updating all kmsg_dump() call, it adds a kmsg_dump_desc()
> function and a macro for backward compatibility.
> 
> I've written this for drm_panic, but it can be useful for other
> kmsg_dumper.
> It allows to see the panic reason, like "sysrq triggered crash"
> or "VFS: Unable to mount root fs on " on the drm panic screen.

Seems reasonable. Given the prototype before/after:

dump(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason)

dump(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason,
 const char *desc)

Perhaps this should instead be a struct that the panic fills in? Then
it'll be easy to adjust the struct in the future:

struct kmsg_dump_detail {
enum kmsg_dump_reason reason;
const char *description;
};

dump(struct kmsg_dumper *dumper, struct kmsg_dump *detail)

This .cocci could do the conversion:


@ dump_func @
identifier DUMPER, CALLBACK;
@@

  struct kmsg_dumper DUMPER = {
.dump = CALLBACK,
  };

@ detail @
identifier dump_func.CALLBACK;
identifier DUMPER, REASON;
@@

CALLBACK(struct kmsg_dumper *DUMPER,
-enum kmsg_dump_reason REASON
+struct kmsg_dump_detail *detail
)
{
<...
-   REASON
+   detail->reason
...>
}


Also, just to double-check, doesn't the panic reason show up in the
kmsg_dump log itself (at the end?) I ask since for pstore, "desc" is
likely redundant since it's capturing the entire console log.

-Kees

Here's the patch from the above cocci:


diff -u -p a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -207,13 +207,13 @@ static int hv_die_panic_notify_crash(str
  * buffer and call into Hyper-V to transfer the data.
  */
 static void hv_kmsg_dump(struct kmsg_dumper *dumper,
-enum kmsg_dump_reason reason)
+struct kmsg_dump_detail *detail)
 {
struct kmsg_dump_iter iter;
size_t bytes_written;
 
/* We are only interested in panics. */
-   if (reason != KMSG_DUMP_PANIC || !sysctl_record_panic_msg)
+   if (detail->reason != KMSG_DUMP_PANIC || !sysctl_record_panic_msg)
return;
 
/*
diff -u -p a/arch/powerpc/platforms/powernv/opal-kmsg.c 
b/arch/powerpc/platforms/powernv/opal-kmsg.c
--- a/arch/powerpc/platforms/powernv/opal-kmsg.c
+++ b/arch/powerpc/platforms/powernv/opal-kmsg.c
@@ -20,13 +20,13 @@
  * message, it just ensures that OPAL completely flushes the console buffer.
  */
 static void kmsg_dump_opal_console_flush(struct kmsg_dumper *dumper,
-enum kmsg_dump_reason reason)
+struct kmsg_dump_detail *detail)
 {
/*
 * Outside of a panic context the pollers will continue to run,
 * so we don't need to do any special flushing.
 */
-   if (reason != KMSG_DUMP_PANIC)
+   if (detail->reason != KMSG_DUMP_PANIC)
return;
 
opal_flush_console(0);
diff -u -p a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -73,7 +73,7 @@ static const char *nvram_os_partitions[]
 };
 
 static void oops_to_nvram(struct kmsg_dumper *dumper,
- enum kmsg_dump_reason reason);
+ struct kmsg_dump_detail *detail);
 
 static struct kmsg_dumper nvram_kmsg_dumper = {
.dump = oops_to_nvram
@@ -643,7 +643,7 @@ void __init nvram_init_oops_partition(in
  * partition.  If that's too much, go back and capture uncompressed text.
  */
 static void oops_to_nvram(struct kmsg_dumper *dumper,
- enum kmsg_dump_reason reason)
+ struct kmsg_dump_detail *detail)
 {
struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
static unsigned int oops_count = 0;
@@ -655,7 +655,7 @@ static void oops_to_nvram(struct kmsg_du
unsigned int err_type = ERR_TYPE_KERNEL_PANIC_GZ;
int rc = -1;
 
-   switch (reason) {
+   switch (detail->reason) {
case KMSG_DUMP_SHUTDOWN:
/* These are almost always orderly shutdowns. */
return;
@@ -671,7 +671,7 @@ static void oops_to_nvram(struct kmsg_du
break;
default:
pr_err("%s: ignoring unrecognized KMSG_DUMP_* reason %d\n",
-  __func__, (int) reason);
+  __func__, (int) detail->reason);
return;
}
 
warning: detail, node 59: record.reason = ... ;[1,2,21,22,32] in pstore_dump 
may be 

Re: [PATCH] printk: Add a short description string to kmsg_dump()

2024-06-26 Thread Petr Mladek
On Tue 2024-06-25 14:39:29, Jocelyn Falempe wrote:
> kmsg_dump doesn't forward the panic reason string to the kmsg_dumper
> callback.
> This patch adds a new parameter "const char *desc" to the kmsg_dumper
> dump() callback, and update all drivers that are using it.
> 
> To avoid updating all kmsg_dump() call, it adds a kmsg_dump_desc()
> function and a macro for backward compatibility.
> 
> I've written this for drm_panic, but it can be useful for other
> kmsg_dumper.
> It allows to see the panic reason, like "sysrq triggered crash"
> or "VFS: Unable to mount root fs on " on the drm panic screen.
>
> Signed-off-by: Jocelyn Falempe 
> ---
>  arch/powerpc/kernel/nvram_64.c |  3 ++-
>  arch/powerpc/platforms/powernv/opal-kmsg.c |  3 ++-
>  drivers/gpu/drm/drm_panic.c|  3 ++-
>  drivers/hv/hv_common.c |  3 ++-
>  drivers/mtd/mtdoops.c  |  3 ++-
>  fs/pstore/platform.c   |  3 ++-
>  include/linux/kmsg_dump.h  | 13 ++---
>  kernel/panic.c |  2 +-
>  kernel/printk/printk.c |  8 +---
>  9 files changed, 28 insertions(+), 13 deletions(-)

The parameter is added into all dumpers. I guess that it would be
used only drm_panic() because it is graphics and might be "fancy".
The others simply dump the log buffer and the reason is in
the dumped log as well.

Anyway, the passed buffer is static. Alternative solution would
be to make it global and export it like, for example, panic_cpu.

Best Regards,
Petr