On 10/12/24 10:50 AM, Ard Biesheuvel wrote: ...
Right. Would the below work for you? It's not the prettiest code in the world, but at least it keeps the weird local to the function.
Its missing the "load_options_size == 0" case, then CONFIG_CMDLINE should be used even if FORCE/etc. are not set. Otherwise it looks OK. (cmdline_len also shouldn't include the NUL character, but I don't think that matters)
--- a/drivers/firmware/efi/libstub/file.c +++ b/drivers/firmware/efi/libstub/file.c @@ -189,26 +189,48 @@ unsigned long *load_addr, unsigned long *load_size) { - const efi_char16_t *cmdline = efi_table_attr(image, load_options); - u32 cmdline_len = efi_table_attr(image, load_options_size); unsigned long efi_chunk_size = ULONG_MAX; efi_file_protocol_t *volume = NULL; + const efi_char16_t *cmdline; efi_file_protocol_t *file; unsigned long alloc_addr; unsigned long alloc_size; efi_status_t status; + bool again = false; + u32 cmdline_len; int offset; if (!load_addr || !load_size) return EFI_INVALID_PARAMETER; - efi_apply_loadoptions_quirk((const void **)&cmdline, &cmdline_len); - cmdline_len /= sizeof(*cmdline); - if (IS_ENABLED(CONFIG_X86) && !efi_nochunk) efi_chunk_size = EFI_READ_CHUNK_SIZE; alloc_addr = alloc_size = 0; + +#ifdef CONFIG_CMDLINE + if (IS_ENABLED(CONFIG_CMDLINE_FORCE) || + IS_ENABLED(CONFIG_CMDLINE_OVERRIDE) || + (again = (IS_ENABLED(CONFIG_X86) || + IS_ENABLED(CONFIG_CMDLINE_EXTEND)))) { + static const efi_char16_t builtin_cmdline[] = L"" CONFIG_CMDLINE; + + cmdline = builtin_cmdline; + cmdline_len = sizeof(builtin_cmdline); + } else +#endif + { +do_load_options: + cmdline = efi_table_attr(image, load_options); + cmdline_len = efi_table_attr(image, load_options_size); + + efi_apply_loadoptions_quirk((const void **)&cmdline, + &cmdline_len); + + again = false; + } + cmdline_len /= sizeof(*cmdline); + do { struct finfo fi; unsigned long size; @@ -290,6 +312,9 @@ efi_call_proto(volume, close); } while (offset > 0); + if (again) + goto do_load_options; + *load_addr = alloc_addr; *load_size = alloc_size;