<listitem><para>Takes an absolute path, or a relative path beginning with
<filename>./</filename>. Specifies the path to an EFI NVRAM template file to copy and use as the
initial EFI variable NVRAM state. If not specified, the default NVRAM template from the firmware
- definition is copied and used.</para>
+ definition is copied and used. Cannot be used together with <option>--coco=</option>, as
+ confidential computing firmware is stateless.</para>
<xi:include href="version-info.xml" xpointer="v261"/></listitem>
</varlistentry>
automatically derived from the VM image path or directory path, with the
<literal>.efinvramstate</literal> suffix appended. If set to the special string
<literal>off</literal> the EFI variable NVRAM state is only maintained transiently and flushed out
- when the VM shuts down. Defaults to <literal>auto</literal>.</para>
+ when the VM shuts down. Defaults to <literal>auto</literal>. An explicit path cannot be used
+ together with <option>--coco=</option>, as confidential computing firmware is stateless.</para>
<para>If <option>--ephemeral</option> is specified, <literal>auto</literal> behaves like
<literal>off</literal>.</para>
<option>--firmware-features=~secure-boot</option>. Setting this to <literal>auto</literal>
removes <literal>secure-boot</literal> from both the included and excluded feature lists.</para>
+ <para>With <option>--coco=</option>, setting this to <literal>yes</literal> additionally
+ requires the <literal>enrolled-keys</literal> firmware feature, overriding its default
+ exclusion: confidential computing firmware is stateless, so keys cannot be enrolled at runtime
+ and Secure Boot is only operative with keys baked into the image at build time, which in turn
+ makes the firmware refuse to boot unsigned images from the very first boot. The default
+ exclusion of <literal>enrolled-keys</literal> hence keeps unsigned images bootable.</para>
+
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
SNP-capable hardware and firmware. A suitable SNP-built OVMF firmware is picked automatically
from the installed QEMU firmware descriptors, by requiring the <literal>amd-sev-snp</literal>
firmware feature; use <option>--firmware=</option> with a path to a firmware descriptor file to
- select a specific one. Secure Boot is unavailable. Direct kernel boot via
+ select a specific one. Secure Boot is effectively off by default (see
+ <option>--secure-boot=</option>). Direct kernel boot via
<option>--linux=</option> is required so that the kernel, initrd and command line are hashed
into the launch measurement (<literal>kernel-hashes=on</literal>); booting the kernel off the
disk image via the firmware would leave it outside the measurement. Credentials passed via
<option>--firmware=</option> with a path to a firmware descriptor file to select a specific
one. The CPU model is fixed to <literal>host</literal>. Firmware is measured into MRTD when the
TD is built. Secure Boot cannot be enrolled at runtime (there is no writable NVRAM); its state
- is fixed by the selected TDVF image and is part of the measured firmware.
+ is fixed by the selected TDVF image and is part of the measured firmware (see
+ <option>--secure-boot=</option>).
When booting a UKI, the whole UKI PE is measured into RTMR 1, and the loaded sections are
measured individually by <command>systemd-stub</command> into RTMR 2. For direct linux boot,
firmware measures the kernel PE into RTMR 1, and the Linux EFI stub measures initrd and
r = set_put_strdup(&arg_firmware_features_include, coco_feature);
if (r < 0)
return log_oom();
+
+ /* CoCo firmware is stateless, so Secure Boot keys cannot be enrolled at runtime
+ * but must have baked-in, enrolled keys, which we avoid in other cases. */
+ if (set_contains(arg_firmware_features_include, "secure-boot")) {
+ r = set_put_strdup(&arg_firmware_features_include, "enrolled-keys");
+ if (r < 0)
+ return log_oom();
+ }
}
FindOvmfConfigFlags flags =
if (r == -ENOENT && coco_feature)
return log_error_errno(r, "No suitable firmware descriptor found for --coco=%s "
"(requires stateless firmware in raw format with the '%s' firmware feature). "
- "Install a suitable firmware or select a firmware descriptor with --firmware=.",
+ "Install a suitable firmware, select a firmware descriptor with --firmware=, or "
+ "opt in with --secure-boot=yes if the installed firmware enforces Secure Boot.",
confidential_computing_to_string(arg_confidential_computing), coco_feature);
if (r < 0)
return log_error_errno(r, "Failed to find OVMF config: %m");
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"--grow-image is not supported for qcow2 images, use 'qemu-img resize FILE SIZE'.");
+ if (arg_confidential_computing != COCO_NO) {
+ /* Confidential computing firmware is stateless, there is no NVRAM to instantiate from a
+ * template or to persist. */
+ if (arg_efi_nvram_template)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "--efi-nvram-template= cannot be used with --coco=, "
+ "confidential computing firmware is stateless.");
+ if (arg_efi_nvram_state_mode == STATE_PATH)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "An explicit --efi-nvram-state= path cannot be used with --coco=, "
+ "confidential computing firmware is stateless. Use 'off' or 'auto'.");
+ }
+
if (arg_confidential_computing == COCO_AMD_SEV_SNP) {
if (native_architecture() != ARCHITECTURE_X86_64)
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"--coco=sev-snp can't be used with %s firmware",
firmware_to_string(arg_firmware_type));
- if (set_contains(arg_firmware_features_include, "secure-boot"))
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "--coco=sev-snp cannot be combined with --secure-boot=yes.");
if (arg_tpm > 0)
log_warning("TPM can't be trusted by the confidential computing guest");
/* kernel-hashes=on only covers what QEMU itself loads via -kernel/-initrd/-append.
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"--coco=tdx can't be used with %s firmware",
firmware_to_string(arg_firmware_type));
- /* Secure Boot state is baked into the supplied TDVF image and can't be enrolled at
- * runtime (no writable NVRAM), so --secure-boot=yes would silently have no effect. */
- if (set_contains(arg_firmware_features_include, "secure-boot"))
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "--coco=tdx cannot be combined with --secure-boot=yes.");
if (arg_tpm > 0)
log_warning("TPM can't be trusted by the confidential computing guest");
}