[PATCH v4 7/8] hw/ppc: Enable fadump for PSeries

Aditya Gupta posted 8 patches 10 months, 3 weeks ago
Maintainers: Nicholas Piggin <npiggin@gmail.com>, Daniel Henrique Barboza <danielhb413@gmail.com>, Harsh Prateek Bora <harshpb@linux.ibm.com>, Thomas Huth <thuth@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, "Daniel P. Berrangé" <berrange@redhat.com>
There is a newer version of this series
[PATCH v4 7/8] hw/ppc: Enable fadump for PSeries
Posted by Aditya Gupta 10 months, 3 weeks ago
With all support in place for preserving memory regions, enable fadump by
exporting the "ibm,kernel-dump" property in the device tree, representing
the fadump dump information, in case of a crash.

Currently "ibm,configure-kernel-dump" RTAS call is already registered,
which tells the kernel that the platform (QEMU) supports fadump.

Now, in case of a crash, if fadump was registered, we also pass
"ibm,kernel-dump" in device tree, which tells the kernel that the fadump
dump is active.

Pass "fadump=on" to enable Linux to use firmware assisted dump.

Logs of a linux boot with firmware assisted dump:

    $ ./build/qemu-system-ppc64 -M pseries,x-vof=on --cpu power10 --smp 4 -m 4G -kernel some-vmlinux -initrd some-initrd -append "debug fadump=on crashkernel=1G" -nographic

    [    0.000000] fadump: Reserved 1024MB of memory at 0x00000040000000 (System RAM: 4096MB)
    [    0.000000] fadump: Initialized 0x40000000 bytes cma area at 1024MB from 0x400102a8 bytes of memory reserved for firmware-assisted dump
    ...
    [    1.084686] rtas fadump: Registration is successful!
    ...
    # cat /sys/kernel/debug/powerpc/fadump_region
    CPU :[0x00000040000000-0x000000400013df] 0x13e0 bytes, Dumped: 0x0
    HPTE:[0x000000400013e0-0x000000400013df] 0x0 bytes, Dumped: 0x0
    DUMP: Src: 0x00000000000000, Dest: 0x00000040010000, Size: 0x40000000, Dumped: 0x0 bytes

    [0x0000000921a000-0x0000000921a7ff]: cmdline append: ''
    # echo c > /proc/sysrq-trigger

The fadump boot after crash:

    [    0.000000] rtas fadump: Firmware-assisted dump is active.
    [    0.000000] fadump: Updated cmdline: debug fadump=on crashkernel=1G
    [    0.000000] fadump: Firmware-assisted dump is active.
    [    0.000000] fadump: Reserving 3072MB of memory at 0x00000040000000 for preserving crash data
    ....
    # file /proc/vmcore
    /proc/vmcore: ELF 64-bit LSB core file, 64-bit PowerPC or cisco 7500, OpenPOWER ELF V2 ABI, version 1 (SYSV), SVR4-style

Analysing the vmcore with crash-utility:

          KERNEL: vmlinux-6.14-rc2
        DUMPFILE: vmcore-fc92fb373aa0
            CPUS: 4
            DATE: Wed Mar 12 23:39:23 CDT 2025
          UPTIME: 00:00:22
    LOAD AVERAGE: 0.13, 0.03, 0.01
           TASKS: 95
        NODENAME: buildroot
         RELEASE: 6.12.0-rc4+
         VERSION: #1 SMP Fri Jan  3 00:15:17 IST 2025
         MACHINE: ppc64le  (1000 Mhz)
          MEMORY: 4 GB
           PANIC: "Kernel panic - not syncing: sysrq triggered crash"
             PID: 269
         COMMAND: "sh"
            TASK: c00000000a050b00  [THREAD_INFO: c00000000a050b00]
             CPU: 0
           STATE: TASK_RUNNING (PANIC)

Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
---
 hw/ppc/spapr.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 3cbc6a7409b7..f6e666ad4344 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -904,6 +904,9 @@ static void spapr_dt_rtas_fadump(SpaprMachineState *spapr, void *fdt, int rtas)
 {
     MachineState *ms = MACHINE(spapr);
     MachineClass *mc = MACHINE_GET_CLASS(ms);
+    FadumpMemStruct *fdm = &spapr->registered_fdm;
+    uint16_t dump_status_flag;
+    bool     is_next_boot_fadump;
 
     uint32_t max_possible_cpus = mc->possible_cpu_arch_ids(ms)->len;
     uint64_t fadump_cpu_state_size = 0;
@@ -953,6 +956,18 @@ static void spapr_dt_rtas_fadump(SpaprMachineState *spapr, void *fdt, int rtas)
                     fadump_versions, sizeof(fadump_versions))));
     _FDT((fdt_setprop(fdt, rtas, "ibm,configure-kernel-dump-sizes",
                     fadump_rgn_sizes, sizeof(fadump_rgn_sizes))));
+
+    dump_status_flag = be16_to_cpu(fdm->header.dump_status_flag);
+    is_next_boot_fadump =
+        (dump_status_flag & FADUMP_STATUS_DUMP_TRIGGERED) != 0;
+    if (is_next_boot_fadump) {
+        uint64_t fdm_size =
+            sizeof(struct FadumpSectionHeader) +
+            (be16_to_cpu(fdm->header.dump_num_sections) *
+            sizeof(struct FadumpSection));
+
+        _FDT((fdt_setprop(fdt, rtas, "ibm,kernel-dump", fdm, fdm_size)));
+    }
 }
 
 static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
-- 
2.49.0
Re: [PATCH v4 7/8] hw/ppc: Enable fadump for PSeries
Posted by Sourabh Jain 3 months, 3 weeks ago

On 23/03/25 23:10, Aditya Gupta wrote:
> With all support in place for preserving memory regions, enable fadump by
> exporting the "ibm,kernel-dump" property in the device tree, representing
> the fadump dump information, in case of a crash.
>
> Currently "ibm,configure-kernel-dump" RTAS call is already registered,
> which tells the kernel that the platform (QEMU) supports fadump.
>
> Now, in case of a crash, if fadump was registered, we also pass
> "ibm,kernel-dump" in device tree, which tells the kernel that the fadump
> dump is active.
>
> Pass "fadump=on" to enable Linux to use firmware assisted dump.
>
> Logs of a linux boot with firmware assisted dump:
>
>      $ ./build/qemu-system-ppc64 -M pseries,x-vof=on --cpu power10 --smp 4 -m 4G -kernel some-vmlinux -initrd some-initrd -append "debug fadump=on crashkernel=1G" -nographic
>
>      [    0.000000] fadump: Reserved 1024MB of memory at 0x00000040000000 (System RAM: 4096MB)
>      [    0.000000] fadump: Initialized 0x40000000 bytes cma area at 1024MB from 0x400102a8 bytes of memory reserved for firmware-assisted dump
>      ...
>      [    1.084686] rtas fadump: Registration is successful!
>      ...
>      # cat /sys/kernel/debug/powerpc/fadump_region
>      CPU :[0x00000040000000-0x000000400013df] 0x13e0 bytes, Dumped: 0x0
>      HPTE:[0x000000400013e0-0x000000400013df] 0x0 bytes, Dumped: 0x0
>      DUMP: Src: 0x00000000000000, Dest: 0x00000040010000, Size: 0x40000000, Dumped: 0x0 bytes
>
>      [0x0000000921a000-0x0000000921a7ff]: cmdline append: ''
>      # echo c > /proc/sysrq-trigger
>
> The fadump boot after crash:
>
>      [    0.000000] rtas fadump: Firmware-assisted dump is active.
>      [    0.000000] fadump: Updated cmdline: debug fadump=on crashkernel=1G
>      [    0.000000] fadump: Firmware-assisted dump is active.

Kernel is printing twice about fadump is active. :)

>      [    0.000000] fadump: Reserving 3072MB of memory at 0x00000040000000 for preserving crash data
>      ....
>      # file /proc/vmcore
>      /proc/vmcore: ELF 64-bit LSB core file, 64-bit PowerPC or cisco 7500, OpenPOWER ELF V2 ABI, version 1 (SYSV), SVR4-style
>
> Analysing the vmcore with crash-utility:
>
>            KERNEL: vmlinux-6.14-rc2
>          DUMPFILE: vmcore-fc92fb373aa0
>              CPUS: 4
>              DATE: Wed Mar 12 23:39:23 CDT 2025
>            UPTIME: 00:00:22
>      LOAD AVERAGE: 0.13, 0.03, 0.01
>             TASKS: 95
>          NODENAME: buildroot
>           RELEASE: 6.12.0-rc4+
>           VERSION: #1 SMP Fri Jan  3 00:15:17 IST 2025
>           MACHINE: ppc64le  (1000 Mhz)
>            MEMORY: 4 GB
>             PANIC: "Kernel panic - not syncing: sysrq triggered crash"
>               PID: 269
>           COMMAND: "sh"
>              TASK: c00000000a050b00  [THREAD_INFO: c00000000a050b00]
>               CPU: 0
>             STATE: TASK_RUNNING (PANIC)
>
> Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
> ---
>   hw/ppc/spapr.c | 15 +++++++++++++++
>   1 file changed, 15 insertions(+)
>
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 3cbc6a7409b7..f6e666ad4344 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -904,6 +904,9 @@ static void spapr_dt_rtas_fadump(SpaprMachineState *spapr, void *fdt, int rtas)
>   {
>       MachineState *ms = MACHINE(spapr);
>       MachineClass *mc = MACHINE_GET_CLASS(ms);
> +    FadumpMemStruct *fdm = &spapr->registered_fdm;
> +    uint16_t dump_status_flag;
> +    bool     is_next_boot_fadump;
>   
>       uint32_t max_possible_cpus = mc->possible_cpu_arch_ids(ms)->len;
>       uint64_t fadump_cpu_state_size = 0;
> @@ -953,6 +956,18 @@ static void spapr_dt_rtas_fadump(SpaprMachineState *spapr, void *fdt, int rtas)
>                       fadump_versions, sizeof(fadump_versions))));
>       _FDT((fdt_setprop(fdt, rtas, "ibm,configure-kernel-dump-sizes",
>                       fadump_rgn_sizes, sizeof(fadump_rgn_sizes))));
> +
> +    dump_status_flag = be16_to_cpu(fdm->header.dump_status_flag);
> +    is_next_boot_fadump =

Do we really need is_next_boot_fadump variable?

> +        (dump_status_flag & FADUMP_STATUS_DUMP_TRIGGERED) != 0;
> +    if (is_next_boot_fadump) {
> +        uint64_t fdm_size =
> +            sizeof(struct FadumpSectionHeader) +
> +            (be16_to_cpu(fdm->header.dump_num_sections) *
> +            sizeof(struct FadumpSection));
> +
> +        _FDT((fdt_setprop(fdt, rtas, "ibm,kernel-dump", fdm, fdm_size)));

Is this common in QEMU to call _FDT to add prop to the FDT? Feels odd.

> +    }
>   }
>   
>   static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
Re: [PATCH v4 7/8] hw/ppc: Enable fadump for PSeries
Posted by Aditya Gupta 3 months, 3 weeks ago
Hello Sourabh,

On 25/10/18 05:34PM, Sourabh Jain wrote:
> 
> 
> > <...snip...>
> > The fadump boot after crash:
> > 
> >      [    0.000000] rtas fadump: Firmware-assisted dump is active.
> >      [    0.000000] fadump: Updated cmdline: debug fadump=on crashkernel=1G
> >      [    0.000000] fadump: Firmware-assisted dump is active.
> 
> Kernel is printing twice about fadump is active. :)

Yeah i noticed, that seems to be the case atleast with 6.14

> 
> > <...snip...>
> >       MachineState *ms = MACHINE(spapr);
> >       MachineClass *mc = MACHINE_GET_CLASS(ms);
> > +    FadumpMemStruct *fdm = &spapr->registered_fdm;
> > +    uint16_t dump_status_flag;
> > +    bool     is_next_boot_fadump;
> >       uint32_t max_possible_cpus = mc->possible_cpu_arch_ids(ms)->len;
> >       uint64_t fadump_cpu_state_size = 0;
> > @@ -953,6 +956,18 @@ static void spapr_dt_rtas_fadump(SpaprMachineState *spapr, void *fdt, int rtas)
> >                       fadump_versions, sizeof(fadump_versions))));
> >       _FDT((fdt_setprop(fdt, rtas, "ibm,configure-kernel-dump-sizes",
> >                       fadump_rgn_sizes, sizeof(fadump_rgn_sizes))));
> > +
> > +    dump_status_flag = be16_to_cpu(fdm->header.dump_status_flag);
> > +    is_next_boot_fadump =
> 
> Do we really need is_next_boot_fadump variable?

Agreed, not needed now, will remove it in v5.

> 
> > +        (dump_status_flag & FADUMP_STATUS_DUMP_TRIGGERED) != 0;
> > +    if (is_next_boot_fadump) {
> > +        uint64_t fdm_size =
> > +            sizeof(struct FadumpSectionHeader) +
> > +            (be16_to_cpu(fdm->header.dump_num_sections) *
> > +            sizeof(struct FadumpSection));
> > +
> > +        _FDT((fdt_setprop(fdt, rtas, "ibm,kernel-dump", fdm, fdm_size)));
> 
> Is this common in QEMU to call _FDT to add prop to the FDT? Feels odd.

Yes, that's just a wrapper for error checking in QEMU, used extensively
atleast in hw/ppc

Thanks for your reviews Sourabh !

- Aditya G

> 
> > +    }
> >   }
> >   static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
>