Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions docs/formatdomain.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9767,10 +9767,11 @@ Arm Confidential Compute Architecture software stack:
...
</domain>

Note: Arm CCA guests must provide firmware via a ROM loader (for example,
``<loader readonly='yes' type='rom'>/usr/share/qemu/QEMU_EFI.fd</loader>``).
The pflash/NVRAM path is not supported, so any ``<nvram>`` element will be
rejected.
Note: Arm CCA guests require firmware to be loaded via ROM (``-bios`` in QEMU) rather
than pflash devices, as the CCA-enabled virt machine disables flash devices in Realm mode.
If a ``<loader type='pflash'>`` is specified, libvirt will automatically convert it to
``type='rom'`` and ignore any ``<nvram>`` configuration. This allows the same domain XML
to work for both CCA and non-CCA guests by simply toggling the ``<launchSecurity>`` element.

The ``<launchSecurity/>`` element accepts the following attributes:

Expand Down
43 changes: 43 additions & 0 deletions src/qemu/qemu_postparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1863,6 +1863,46 @@ qemuDomainDefNumaCPUsPostParse(virDomainDef *def,
}


/**
* qemuDomainDefCCAFirmwarePostParse:
* @def: domain definition
*
* For CCA (Confidential Compute Architecture) guests, automatically convert
* pflash loader to ROM. CCA-enabled ARM virt machine doesn't support pflash
* devices when realm mode is active. This allows users to use the same domain
* XML for both CCA and non-CCA guests by simply toggling launchSecurity.
*/
static void
qemuDomainDefCCAFirmwarePostParse(virDomainDef *def)
{
/* Only process CCA guests with a loader defined */
if (!def->sec ||
def->sec->sectype != VIR_DOMAIN_LAUNCH_SECURITY_CCA ||
!def->os.loader)
return;

/* Auto-convert pflash to ROM for CCA compatibility */
if (def->os.loader->type == VIR_DOMAIN_LOADER_TYPE_PFLASH) {
VIR_INFO("Converting pflash loader to ROM for CCA guest '%s'", def->name);
def->os.loader->type = VIR_DOMAIN_LOADER_TYPE_ROM;
def->os.loader->readonly = VIR_TRISTATE_BOOL_YES;

/* Clear NVRAM - it's incompatible with ROM loaders */
if (def->os.loader->nvram) {
VIR_WARN("Ignoring NVRAM configuration for CCA guest '%s' (ROM loader does not support NVRAM)",
def->name);
g_clear_pointer(&def->os.loader->nvram, virObjectUnref);
}

if (def->os.loader->nvramTemplate) {
VIR_WARN("Ignoring NVRAM template for CCA guest '%s' (ROM loader does not support NVRAM)",
def->name);
g_clear_pointer(&def->os.loader->nvramTemplate, g_free);
}
}
}


int
qemuDomainDefPostParse(virDomainDef *def,
unsigned int parseFlags,
Expand All @@ -1888,6 +1928,9 @@ qemuDomainDefPostParse(virDomainDef *def,
if (qemuDomainDefBootPostParse(def, driver, parseFlags) < 0)
return -1;

/* Convert pflash to ROM for CCA guests after boot post-parse */
qemuDomainDefCCAFirmwarePostParse(def);

if (qemuDomainDefAddDefaultDevices(driver, def, qemuCaps) < 0)
return -1;

Expand Down
17 changes: 10 additions & 7 deletions src/qemu/qemu_validate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1338,11 +1338,13 @@ qemuValidateDomainDef(const virDomainDef *def,
return -1;
}

/* On aarch64, ACPI requires UEFI */
/* On aarch64, ACPI requires UEFI (except for CCA guests where UEFI
* is loaded via ROM after pflash conversion) */
if (def->features[VIR_DOMAIN_FEATURE_ACPI] == VIR_TRISTATE_SWITCH_ON &&
def->os.arch == VIR_ARCH_AARCH64 &&
(def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_EFI &&
!virDomainDefHasOldStyleUEFI(def))) {
!virDomainDefHasOldStyleUEFI(def)) &&
!(def->sec && def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_CCA)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("ACPI requires UEFI on this architecture"));
return -1;
Expand Down Expand Up @@ -1518,18 +1520,19 @@ qemuValidateDomainDef(const virDomainDef *def,
case VIR_DOMAIN_LAUNCH_SECURITY_CCA:
/* CCA firmware must be supplied via -bios (loader type='rom').
* The virt machine disables its flash devices for confidential
* guests, so reject any pflash/NVRAM configuration up front.
* guests. The post-parse code should have already converted any
* pflash configuration to ROM, but verify it here as a sanity check.
*/
if (def->os.loader) {
if (def->os.loader->type != VIR_DOMAIN_LOADER_TYPE_ROM) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Arm CCA guests require a ROM firmware loader"));
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Arm CCA guests require a ROM firmware loader (post-parse should have converted pflash)"));
return -1;
}

if (def->os.loader->nvram || def->os.loader->nvramTemplate) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Arm CCA guests do not support NVRAM flash devices"));
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Arm CCA guests do not support NVRAM flash devices (post-parse should have cleared this)"));
return -1;
}
}
Expand Down