[RFC PATCH 2/3] powerpc/fadump: pass additional parameters to dump capture kernel
Hari Bathini
hbathini at linux.ibm.com
Mon Dec 18 17:40:47 AEDT 2023
Hi Sourabh,
On 15/12/23 2:12 pm, Sourabh Jain wrote:
> Hello Hari,
>
> On 06/12/23 01:48, Hari Bathini wrote:
>> For fadump case, passing additional parameters to dump capture kernel
>> helps in minimizing the memory footprint for it and also provides the
>> flexibility to disable components/modules, like hugepages, that are
>> hindering the boot process of the special dump capture environment.
>>
>> Set up a dedicated parameter area to be passed to the capture kernel.
>> This area type is defined as RTAS_FADUMP_PARAM_AREA. Sysfs attribute
>> '/sys/kernel/fadump/bootargs_append' is exported to the userspace to
>> specify the additional parameters to be passed to the capture kernel
>>
>> Signed-off-by: Hari Bathini <hbathini at linux.ibm.com>
>> ---
>> arch/powerpc/include/asm/fadump-internal.h | 3 +
>> arch/powerpc/kernel/fadump.c | 80 ++++++++++++++++++++
>> arch/powerpc/platforms/powernv/opal-fadump.c | 6 +-
>> arch/powerpc/platforms/pseries/rtas-fadump.c | 35 ++++++++-
>> arch/powerpc/platforms/pseries/rtas-fadump.h | 11 ++-
>> 5 files changed, 126 insertions(+), 9 deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/fadump-internal.h
>> b/arch/powerpc/include/asm/fadump-internal.h
>> index b3956c400519..81629226b15f 100644
>> --- a/arch/powerpc/include/asm/fadump-internal.h
>> +++ b/arch/powerpc/include/asm/fadump-internal.h
>> @@ -97,6 +97,8 @@ struct fw_dump {
>> unsigned long cpu_notes_buf_vaddr;
>> unsigned long cpu_notes_buf_size;
>> + unsigned long param_area;
>> +
>> /*
>> * Maximum size supported by firmware to copy from source to
>> * destination address per entry.
>> @@ -111,6 +113,7 @@ struct fw_dump {
>> unsigned long dump_active:1;
>> unsigned long dump_registered:1;
>> unsigned long nocma:1;
>> + unsigned long param_area_supported:1;
>> struct fadump_ops *ops;
>> };
>> diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
>> index 757681658dda..98f089747ac9 100644
>> --- a/arch/powerpc/kernel/fadump.c
>> +++ b/arch/powerpc/kernel/fadump.c
>> @@ -1470,6 +1470,7 @@ static ssize_t mem_reserved_show(struct kobject
>> *kobj,
>> return sprintf(buf, "%ld\n", fw_dump.reserve_dump_area_size);
>> }
>> +
>> static ssize_t registered_show(struct kobject *kobj,
>> struct kobj_attribute *attr,
>> char *buf)
>> @@ -1477,6 +1478,43 @@ static ssize_t registered_show(struct kobject
>> *kobj,
>> return sprintf(buf, "%d\n", fw_dump.dump_registered);
>> }
>> +static ssize_t bootargs_append_show(struct kobject *kobj,
>> + struct kobj_attribute *attr,
>> + char *buf)
>> +{
>> + return sprintf(buf, "%s\n", (char *)__va(fw_dump.param_area));
>> +}
>> +
>> +static ssize_t bootargs_append_store(struct kobject *kobj,
>> + struct kobj_attribute *attr,
>> + const char *buf, size_t count)
>> +{
>> + char *params;
>> +
>> + if (!fw_dump.fadump_enabled || fw_dump.dump_active)
>> + return -EPERM;
>> +
>> + if (count >= COMMAND_LINE_SIZE)
>> + return -EINVAL;
>> +
>> + /*
>> + * Fail here instead of handling this scenario with
>> + * some silly workaround in capture kernel.
>> + */
>> + if (saved_command_line_len + count >= COMMAND_LINE_SIZE) {
>> + pr_err("Appending parameters exceeds cmdline size!\n");
>> + return -ENOSPC;
>> + }
>> +
>> + params = __va(fw_dump.param_area);
>> + strscpy_pad(params, buf, COMMAND_LINE_SIZE);
>> + /* Remove newline character at the end. */
>> + if (params[count-1] == '\n')
>> + params[count-1] = '\0';
>> +
>> + return count;
>> +}
>> +
>> static ssize_t registered_store(struct kobject *kobj,
>> struct kobj_attribute *attr,
>> const char *buf, size_t count)
>> @@ -1535,6 +1573,7 @@ static struct kobj_attribute release_attr =
>> __ATTR_WO(release_mem);
>> static struct kobj_attribute enable_attr = __ATTR_RO(enabled);
>> static struct kobj_attribute register_attr = __ATTR_RW(registered);
>> static struct kobj_attribute mem_reserved_attr =
>> __ATTR_RO(mem_reserved);
>> +static struct kobj_attribute bootargs_append_attr =
>> __ATTR_RW(bootargs_append);
>> static struct attribute *fadump_attrs[] = {
>> &enable_attr.attr,
>> @@ -1611,6 +1650,46 @@ static void __init fadump_init_files(void)
>> return;
>> }
>> +/*
>> + * Reserve memory to store additional parameters to be passed
>> + * for fadump/capture kernel.
>> + */
>> +static void fadump_setup_param_area(void)
>> +{
>> + phys_addr_t range_start, range_end;
>> +
>> + if (!fw_dump.param_area_supported || fw_dump.dump_active)
>> + return;
>> +
>> + /* This memory can't be used by PFW or bootloader as it is shared
>> across kernels */
>> + if (radix_enabled()) {
>> + /*
>> + * Anywhere in the upper half should be good enough as all
>> memory
>> + * is accessible in real mode.
>> + */
>> + range_start = memblock_end_of_DRAM() / 2;
>> + range_end = memblock_end_of_DRAM();
>> + } else {
>> + /*
>> + * Passing additional parameters is supported for hash MMU only
>> + * if the first memory block size is 768MB or higher.
>> + */
>> + if (ppc64_rma_size < 0x30000000)
>> + return;
>> +
>> + /* 640 MB to 768 MB is not used by bootloader */
>> + range_start = 0x28000000;
>> + range_end = range_start + 0x4000000;
>> + }
>> +
>> + fw_dump.param_area = memblock_phys_alloc_range(COMMAND_LINE_SIZE,
>> + COMMAND_LINE_SIZE,
>> + range_start,
>> + range_end);
>
> Should we initialize the `param_area` to avoid garbage values, or retrieve
> command-line arguments from the previous boot?
>
> I observed that cat /sys/kernel/fadump/bootargs_append prints the same
> value which I set before reboot. Is this expected?
I implemented it as such to reuse the arguments set in the
previous boot. Not likely to see garbage there. Even if we
do, unlikely that garbage is going to have a negative impact
on capture kernel boot (even if we don't reset the bootargs
in the userspace before crash)..
Thanks
Hari
More information about the Linuxppc-dev
mailing list