diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h
index e115f7b998..3112f2b676 100644
--- a/include/libvirt/libvirt-host.h
+++ b/include/libvirt/libvirt-host.h
@@ -537,6 +537,17 @@ typedef virNodeMemoryStats *virNodeMemoryStatsPtr;
*/
# define VIR_NODE_SEV_CERT_CHAIN "cert-chain"
+/**
+ * VIR_NODE_SEV_CPU0_ID:
+ *
+ * Macro represents the unique ID of CPU0 (socket 0) needed to retrieve
+ * the signed CEK of the CPU from AMD's Key Distribution Service (KDS),
+ * as VIR_TYPED_PARAMS_STRING.
+ *
+ * Since: 8.4.0
+ */
+# define VIR_NODE_SEV_CPU0_ID "cpu0-id"
+
/**
* VIR_NODE_SEV_CBITPOS:
*
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
index c394a7a390..2a888da1a9 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -601,6 +601,10 @@ virDomainCapsFeatureSEVFormat(virBuffer *buf,
sev->max_guests);
virBufferAsprintf(buf, "%d\n",
sev->max_es_guests);
+ if (sev->cpu0_id != NULL) {
+ virBufferAsprintf(buf, "%s\n",
+ sev->cpu0_id);
+ }
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "\n");
}
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
index 1d2f4ac7a5..f2eed80b15 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -185,6 +185,7 @@ typedef struct _virSEVCapability virSEVCapability;
struct _virSEVCapability {
char *pdh;
char *cert_chain;
+ char *cpu0_id;
unsigned int cbitpos;
unsigned int reduced_phys_bits;
unsigned int max_guests;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 9a0b7ebeb4..1ed4cda7f0 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1957,6 +1957,9 @@ virQEMUCapsSEVInfoCopy(virSEVCapability **dst,
tmp->pdh = g_strdup(src->pdh);
tmp->cert_chain = g_strdup(src->cert_chain);
+ if (src->cpu0_id != NULL) {
+ tmp->cpu0_id = g_strdup(src->cpu0_id);
+ }
tmp->cbitpos = src->cbitpos;
tmp->reduced_phys_bits = src->reduced_phys_bits;
@@ -4693,6 +4696,11 @@ virQEMUCapsFormatSEVInfo(virQEMUCaps *qemuCaps, virBuffer *buf)
virBufferEscapeString(buf, "%s\n", sev->pdh);
virBufferEscapeString(buf, "%s\n",
sev->cert_chain);
+ if (sev->cpu0_id != NULL) {
+ virBufferEscapeString(buf, "%s\n",
+ sev->cpu0_id);
+ }
+
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "\n");
}
@@ -6478,6 +6486,10 @@ virQEMUCapsFillDomainFeatureSEVCaps(virQEMUCaps *qemuCaps,
domCaps->sev->pdh = g_strdup(cap->pdh);
domCaps->sev->cert_chain = g_strdup(cap->cert_chain);
+ if (cap->cpu0_id != NULL) {
+ domCaps->sev->cpu0_id = g_strdup(cap->cpu0_id);
+ }
+
domCaps->sev->cbitpos = cap->cbitpos;
domCaps->sev->reduced_phys_bits = cap->reduced_phys_bits;
domCaps->sev->max_guests = cap->max_guests;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ee0963c30d..464c080409 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19861,6 +19861,11 @@ qemuGetSEVInfoToParams(virQEMUCaps *qemuCaps,
VIR_NODE_SEV_CERT_CHAIN, sev->cert_chain) < 0)
goto cleanup;
+ if ((sev->cpu0_id != NULL) &&
+ (virTypedParamsAddString(&sevParams, &n, &maxpar,
+ VIR_NODE_SEV_CPU0_ID, sev->cpu0_id) < 0))
+ goto cleanup;
+
if (virTypedParamsAddUInt(&sevParams, &n, &maxpar,
VIR_NODE_SEV_CBITPOS, sev->cbitpos) < 0)
goto cleanup;
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 776f4ab2ea..9e611e93e8 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -6400,6 +6400,7 @@ qemuMonitorJSONGetSEVCapabilities(qemuMonitor *mon,
virJSONValue *caps;
const char *pdh = NULL;
const char *cert_chain = NULL;
+ const char *cpu0_id = NULL;
unsigned int cbitpos;
unsigned int reduced_phys_bits;
g_autoptr(virSEVCapability) capability = NULL;
@@ -6457,6 +6458,11 @@ qemuMonitorJSONGetSEVCapabilities(qemuMonitor *mon,
capability->cert_chain = g_strdup(cert_chain);
+ cpu0_id = virJSONValueObjectGetString(caps, "cpu0-id");
+ if (cpu0_id != NULL) {
+ capability->cpu0_id = g_strdup(cpu0_id);
+ }
+
capability->cbitpos = cbitpos;
capability->reduced_phys_bits = reduced_phys_bits;
*capabilities = g_steal_pointer(&capability);