diff --git a/man/smbios-type-11.xml b/man/smbios-type-11.xml
index b576677d27..70f66fe0f6 100644
--- a/man/smbios-type-11.xml
+++ b/man/smbios-type-11.xml
@@ -80,10 +80,20 @@
This allows inserting additional entries into the systemd-boot
menu. For details see
- systemd-boot7
+ systemd-boot7.
+
+
+ io.systemd.boot.loglevel=LEVEL
+
+ This allows configuration of the log level, and is read by systemd-boot.
+ For details see
+ systemd-boot7.
+
+
+
diff --git a/man/systemd-boot.xml b/man/systemd-boot.xml
index b01299143c..94eaae2d6b 100644
--- a/man/systemd-boot.xml
+++ b/man/systemd-boot.xml
@@ -640,6 +640,16 @@ uki-url http://example.com/somedir/fooos.efi
+
+
+ io.systemd.boot.loglevel
+ If set, the value of this string is used as log level. Valid values (from most to
+ least critical) are emerg, alert, crit,
+ err, warning, notice, info,
+ and debug.
+
+
+
diff --git a/src/boot/boot.c b/src/boot/boot.c
index 3dd91f4396..3ac59866aa 100644
--- a/src/boot/boot.c
+++ b/src/boot/boot.c
@@ -2991,6 +2991,9 @@ static EFI_STATUS run(EFI_HANDLE image) {
uint64_t init_usec;
bool menu = false;
+ /* set loglevel early to simplify debugging before loader.conf is loaded */
+ log_set_max_level_from_smbios();
+
init_usec = time_usec();
err = BS->HandleProtocol(image, MAKE_GUID_PTR(EFI_LOADED_IMAGE_PROTOCOL), (void **) &loaded_image);
diff --git a/src/boot/efi-log.c b/src/boot/efi-log.c
index 5bb2c0e490..3cecc7be06 100644
--- a/src/boot/efi-log.c
+++ b/src/boot/efi-log.c
@@ -3,7 +3,9 @@
#include "efi-log.h"
#include "efi-string-table.h"
#include "proto/rng.h"
+#include "smbios.h"
#include "util.h"
+#include "vmm.h"
static unsigned log_count = 0;
static LogLevel log_max_level = LOG_INFO;
@@ -57,6 +59,21 @@ int log_set_max_level_from_string(const char *e) {
return 0;
}
+void log_set_max_level_from_smbios(void) {
+ int r;
+
+ if (is_confidential_vm())
+ return; /* Don't consume SMBIOS in Confidential Computing contexts */
+
+ const char *level_str = smbios_find_oem_string("io.systemd.boot.loglevel=", /* after= */ NULL);
+ if (!level_str)
+ return;
+
+ r = log_set_max_level_from_string(level_str);
+ if (r < 0)
+ log_warning("Failed to parse log level '%s', ignoring.", level_str);
+}
+
void freeze(void) {
for (;;)
BS->Stall(60 * 1000 * 1000);
diff --git a/src/boot/efi-log.h b/src/boot/efi-log.h
index 418b9f90be..459838782b 100644
--- a/src/boot/efi-log.h
+++ b/src/boot/efi-log.h
@@ -40,6 +40,7 @@ const char* log_level_to_string(LogLevel l) _const_;
LogLevel log_get_max_level(void) _pure_;
int log_set_max_level(LogLevel level);
int log_set_max_level_from_string(const char *e);
+void log_set_max_level_from_smbios(void);
_noreturn_ void freeze(void);
void log_wait(void);