When 'tdx' is used, the VM will be launched with Intel TDX feature enabled.
TDX feature supports running encrypted VM (Trust Domain, TD) under the
control of KVM. A TD runs in a CPU model which protects the confidentiality
of its memory and its CPU state from other software.
There are four optional child elements. Element policy is 64bit hex, bit 0
is set to enable TDX debug, bit 28 is set to enable sept-ve-disable, other
bits are reserved currently. When policy isn't specified, QEMU will use its
own default value 0x10000000. mrConfigId, mrOwner and mrOwnerConfig are
base64 encoded SHA384 digest string.
For example:
<launchSecurity type='tdx'>
<policy>0x10000001</policy>
<mrConfigId>xxx</mrConfigId>
<mrOwner>xxx</mrOwner>
<mrOwnerConfig>xxx</mrOwnerConfig>
</launchSecurity>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
"sev",
"sev-snp",
"s390-pv",
+ "tdx",
);
VIR_ENUM_IMPL(virDomainPstoreBackend,
g_free(def->data.sev_snp.id_auth);
g_free(def->data.sev_snp.host_data);
break;
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
+ g_free(def->data.tdx.mrconfigid);
+ g_free(def->data.tdx.mrowner);
+ g_free(def->data.tdx.mrownerconfig);
+ break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
}
+static int
+virDomainTDXDefParseXML(virDomainTDXDef *def,
+ xmlXPathContextPtr ctxt)
+{
+ int rc;
+
+ rc = virXPathULongLongBase("string(./policy)", ctxt, 16, &def->policy);
+ if (rc == 0) {
+ def->havePolicy = true;
+ } else if (rc == -2) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("failed to get launch security policy for launch security type TDX"));
+ return -1;
+ }
+
+ def->mrconfigid = virXPathString("string(./mrConfigId)", ctxt);
+ def->mrowner = virXPathString("string(./mrOwner)", ctxt);
+ def->mrownerconfig = virXPathString("string(./mrOwnerConfig)", ctxt);
+
+ return 0;
+}
+
+
static virDomainSecDef *
virDomainSecDefParseXML(xmlNodePtr lsecNode,
xmlXPathContextPtr ctxt)
if (virDomainSEVSNPDefParseXML(&sec->data.sev_snp, ctxt) < 0)
return NULL;
break;
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
+ if (virDomainTDXDefParseXML(&sec->data.tdx, ctxt) < 0)
+ return NULL;
+ break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
}
+static void
+virDomainTDXDefFormat(virBuffer *childBuf, virDomainTDXDef *def)
+{
+ if (def->havePolicy)
+ virBufferAsprintf(childBuf, "<policy>0x%llx</policy>\n", def->policy);
+
+ virBufferEscapeString(childBuf, "<mrConfigId>%s</mrConfigId>\n", def->mrconfigid);
+ virBufferEscapeString(childBuf, "<mrOwner>%s</mrOwner>\n", def->mrowner);
+ virBufferEscapeString(childBuf, "<mrOwnerConfig>%s</mrOwnerConfig>\n", def->mrownerconfig);
+}
+
+
static void
virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec)
{
virDomainSEVSNPDefFormat(&attrBuf, &childBuf, &sec->data.sev_snp);
break;
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
+ virDomainTDXDefFormat(&childBuf, &sec->data.tdx);
+ break;
+
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
break;
VIR_DOMAIN_LAUNCH_SECURITY_SEV,
VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP,
VIR_DOMAIN_LAUNCH_SECURITY_PV,
+ VIR_DOMAIN_LAUNCH_SECURITY_TDX,
VIR_DOMAIN_LAUNCH_SECURITY_LAST,
} virDomainLaunchSecurity;
};
+struct _virDomainTDXDef {
+ bool havePolicy;
+ unsigned long long policy;
+ char *mrconfigid;
+ char *mrowner;
+ char *mrownerconfig;
+};
+
+
struct _virDomainSecDef {
virDomainLaunchSecurity sectype;
union {
virDomainSEVDef sev;
virDomainSEVSNPDef sev_snp;
+ virDomainTDXDef tdx;
} data;
};
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
break;
}
<value>s390-pv</value>
</attribute>
</group>
+ <group>
+ <ref name="launchSecurityTDX"/>
+ </group>
</choice>
</element>
</define>
</optional>
</interleave>
</define>
+
+ <define name="launchSecurityTDX">
+ <attribute name="type">
+ <value>tdx</value>
+ </attribute>
+ <interleave>
+ <optional>
+ <element name="policy">
+ <ref name="hexuint"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="mrConfigId">
+ <data type="string"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="mrOwner">
+ <data type="string"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="mrOwnerConfig">
+ <data type="string"/>
+ </element>
+ </optional>
+ </interleave>
+ </define>
+
<!--
Enable or disable perf events for the domain. For each
of the events the following rules apply:
typedef struct _virDomainSEVSNPDef virDomainSEVSNPDef;
+typedef struct _virDomainTDXDef virDomainTDXDef;
+
typedef struct _virDomainSecDef virDomainSecDef;
typedef struct _virDomainShmemDef virDomainShmemDef;
return -1;
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
}
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
virBufferAddLit(&buf, ",confidential-guest-support=lsec0");
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
return qemuBuildPVCommandLine(cmd);
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
virReportEnumRangeError(virDomainLaunchSecurity, sec->sectype);
goto cleanup;
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
}
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
VIR_DEBUG("Set up launch security for SEV");
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
return -1;
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
return 0;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
return -1;
}
break;
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
virReportEnumRangeError(virDomainLaunchSecurity, def->sec->sectype);
rc = -1;
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
return -1;
break;
case VIR_DOMAIN_LAUNCH_SECURITY_PV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_TDX:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST: