On Mon, Aug 11, 2025 at 04:37:36PM +0100, Usama Arif wrote: > If the kernel is enabled with CONFIG_BOOT_CONFIG_FORCE, it will > always append the bootconfig at the start of the kernel commandline. > If reuse-cmdline option is used in kexec, the bootconfig will be > repeatedly appended at the start of the commandline on every kexec. > As there is a limit on the size of kernel commandline that can be > used, --reuse-cmdline option will break kexec depending on the > size of bootconfig on repeated kexec. > > Bootconfig is embedded in the kernel, so it should not be considered > when reusing kernel command line. > Modify get_command_line() to first attempt reading kernel parameters > from /proc/bootconfig before falling back to /proc/cmdline. This allows > kexec to use the original boot parameters without bootconfig which > is embedded in the kernel. > > The function will fallback to /proc/cmdline behavior when: > > - /proc/bootconfig doesn't exist > - /proc/bootconfig is empty > - /proc/bootconfig doesn't contain the expected marker format > - The extracted parameter line is empty > > Signed-off-by: Usama Arif <usamaarif...@gmail.com>
Reviewed-by: Paul E. McKenney <paul...@kernel.org> > --- > kexec/kexec.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------ > 1 file changed, 44 insertions(+), 6 deletions(-) > > diff --git a/kexec/kexec.c b/kexec/kexec.c > index 6bf12d7..b31cb1f 100644 > --- a/kexec/kexec.c > +++ b/kexec/kexec.c > @@ -1235,15 +1235,53 @@ static char *slurp_proc_file(const char *filename, > size_t *len) > */ > char *get_command_line(void) > { > - char *p, *line; > + char *p, *line = NULL; > size_t size; > + char *bootconfig_line; > + size_t bootconfig_size; > + > + /* First try to get command line parameters from /proc/bootconfig */ > + bootconfig_line = slurp_proc_file("/proc/bootconfig", &bootconfig_size); > + if (bootconfig_line && bootconfig_size > 0) { > + /* Look for "# Parameters from bootloader:" */ > + char *params_marker = strstr(bootconfig_line, "# Parameters > from bootloader:"); > + if (params_marker) { > + /* Find the next line after the marker */ > + char *params_start = strchr(params_marker, '\n'); > + if (params_start) { > + params_start++; /* Move past the newline */ > + > + /* Check if this line starts with "# " */ > + if (strncmp(params_start, "# ", 2) == 0) { > + /* Skip the "# " prefix */ > + params_start += 2; > + > + /* Find the end of the line */ > + char *params_end = strchr(params_start, > '\n'); > + if (params_end) { > + *params_end = '\0'; > + } > + > + /* Check if the extracted line is not > empty */ > + if (strlen(params_start) > 0) { > + /* Allocate and copy the > parameters */ > + line = xstrdup(params_start); > + } > + } > + } > + } > + free(bootconfig_line); > + } > > - line = slurp_proc_file("/proc/cmdline", &size); > - if (!line || !size) > - die("Failed to read /proc/cmdline\n"); > + /* Fall back to reading /proc/cmdline if we didn't get a line from > bootconfig */ > + if (!line) { > + line = slurp_proc_file("/proc/cmdline", &size); > + if (!line || !size) > + die("Failed to read /proc/cmdline\n"); > > - /* strip newline */ > - line[size-1] = '\0'; > + /* strip newline */ > + line[size-1] = '\0'; > + } > > p = strpbrk(line, "\r\n"); > if (p) > -- > 2.47.3 >