size_t n_entries;
size_t idx_default;
size_t idx_default_efivar;
- uint64_t timeout_sec; /* Actual timeout used (efi_main() override > efivar > config). */
+ uint64_t timeout_sec; /* Actual timeout used (efi_main() override > smbios > efivar > config). */
+ uint64_t timeout_sec_smbios;
uint64_t timeout_sec_config;
uint64_t timeout_sec_efivar;
char16_t *entry_default_config;
print_timeout_status(" timeout (config)", config->timeout_sec_config);
print_timeout_status(" timeout (EFI var)", config->timeout_sec_efivar);
+ print_timeout_status(" timeout (smbios)", config->timeout_sec_smbios);
if (config->entry_default_config)
printf(" default (config): %ls\n", config->entry_default_config);
DEFINE_TRIVIAL_CLEANUP_FUNC(BootEntry *, boot_entry_free);
+static EFI_STATUS config_timeout_sec_from_string(const char *value, uint64_t *dst) {
+ if (streq8(value, "menu-disabled"))
+ *dst = TIMEOUT_MENU_DISABLED;
+ else if (streq8(value, "menu-force"))
+ *dst = TIMEOUT_MENU_DISABLED;
+ else if (streq8(value, "menu-hidden"))
+ *dst = TIMEOUT_MENU_DISABLED;
+ else {
+ uint64_t u;
+ if (!parse_number8(value, &u, NULL) || u > TIMEOUT_TYPE_MAX)
+ return EFI_INVALID_PARAMETER;
+ *dst = u;
+ }
+ return EFI_SUCCESS;
+}
+
+static void config_timeout_load_from_smbios(Config *config) {
+ EFI_STATUS err;
+
+ if (is_confidential_vm())
+ return; /* Don't consume SMBIOS in Confidential Computing contexts */
+
+ const char *value = smbios_find_oem_string("io.systemd.boot.timeout=", /* after= */ NULL);
+ if (!value)
+ return;
+
+ err = config_timeout_sec_from_string(value, &config->timeout_sec_smbios);
+ if (err != EFI_SUCCESS) {
+ log_warning_status(err, "Error parsing 'timeout' smbios option, ignoring: %s",
+ value);
+ return;
+ }
+ config->timeout_sec = config->timeout_sec_smbios;
+}
+
static void config_defaults_load_from_file(Config *config, char *content) {
char *line;
size_t pos = 0;
* shared/bootspec.c@boot_loader_read_conf() to make parsing by bootctl/logind/etc. work. */
while ((line = line_get_key_value(content, " \t", &pos, &key, &value)))
if (streq8(key, "timeout")) {
- if (streq8(value, "menu-disabled"))
- config->timeout_sec_config = TIMEOUT_MENU_DISABLED;
- else if (streq8(value, "menu-force"))
- config->timeout_sec_config = TIMEOUT_MENU_FORCE;
- else if (streq8(value, "menu-hidden"))
- config->timeout_sec_config = TIMEOUT_MENU_HIDDEN;
- else {
- uint64_t u;
- if (!parse_number8(value, &u, NULL) || u > TIMEOUT_TYPE_MAX) {
- log_error("Error parsing 'timeout' config option, ignoring: %s",
- value);
- continue;
- }
- config->timeout_sec_config = u;
+ EFI_STATUS err = config_timeout_sec_from_string(value, &config->timeout_sec_config);
+ if (err != EFI_SUCCESS) {
+ log_warning_status(err, "Error parsing 'timeout' config option, ignoring: %s",
+ value);
+ continue;
}
config->timeout_sec = config->timeout_sec_config;
.console_mode_efivar = CONSOLE_MODE_KEEP,
.timeout_sec_config = TIMEOUT_UNSET,
.timeout_sec_efivar = TIMEOUT_UNSET,
+ .timeout_sec_smbios = TIMEOUT_UNSET,
};
err = file_read(root_dir, u"\\loader\\loader.conf", 0, 0, &content, &content_size);
config->timeout_sec = config->timeout_sec_efivar;
else if (err != EFI_NOT_FOUND)
log_warning_status(err, "Error reading LoaderConfigTimeout EFI variable, ignoring: %m");
+ config_timeout_load_from_smbios(config);
err = efivar_get_timeout(u"LoaderConfigTimeoutOneShot", &config->timeout_sec);
if (err == EFI_SUCCESS) {