Introduce a new backend type 'external' for connecting to a swtpm daemon
not managed by libvirtd.
Mostly in one commit, thanks to -Wswitch and the way we generate
capabilities.
https://bugzilla.redhat.com/show_bug.cgi?id=2063723
Signed-off-by: Ján Tomko <jtomko(a)redhat.com>
---
src/conf/domain_audit.c | 11 +++++
src/conf/domain_conf.c | 35 ++++++++++++++++
src/conf/domain_conf.h | 4 ++
src/conf/domain_validate.c | 15 +++++++
src/conf/schemas/domaincommon.rng | 22 ++++++++++
src/qemu/qemu_capabilities.c | 4 +-
src/qemu/qemu_cgroup.c | 1 +
src/qemu/qemu_command.c | 11 ++++-
src/qemu/qemu_domain.c | 4 ++
src/qemu/qemu_namespace.c | 1 +
src/qemu/qemu_tpm.c | 2 +
src/security/security_dac.c | 2 +
src/security/security_selinux.c | 2 +
.../domaincapsdata/qemu_4.2.0-q35.x86_64.xml | 1 +
.../domaincapsdata/qemu_4.2.0-tcg.x86_64.xml | 1 +
tests/domaincapsdata/qemu_4.2.0.x86_64.xml | 1 +
.../domaincapsdata/qemu_5.0.0-q35.x86_64.xml | 1 +
.../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml | 1 +
.../qemu_5.0.0-virt.aarch64.xml | 1 +
tests/domaincapsdata/qemu_5.0.0.aarch64.xml | 1 +
tests/domaincapsdata/qemu_5.0.0.ppc64.xml | 1 +
tests/domaincapsdata/qemu_5.0.0.x86_64.xml | 1 +
.../domaincapsdata/qemu_5.1.0-q35.x86_64.xml | 1 +
.../domaincapsdata/qemu_5.1.0-tcg.x86_64.xml | 1 +
tests/domaincapsdata/qemu_5.1.0.x86_64.xml | 1 +
.../domaincapsdata/qemu_5.2.0-q35.x86_64.xml | 1 +
.../domaincapsdata/qemu_5.2.0-tcg.x86_64.xml | 1 +
.../qemu_5.2.0-virt.aarch64.xml | 1 +
tests/domaincapsdata/qemu_5.2.0.aarch64.xml | 1 +
tests/domaincapsdata/qemu_5.2.0.ppc64.xml | 1 +
tests/domaincapsdata/qemu_5.2.0.x86_64.xml | 1 +
.../domaincapsdata/qemu_6.0.0-q35.x86_64.xml | 1 +
.../domaincapsdata/qemu_6.0.0-tcg.x86_64.xml | 1 +
.../qemu_6.0.0-virt.aarch64.xml | 1 +
tests/domaincapsdata/qemu_6.0.0.aarch64.xml | 1 +
tests/domaincapsdata/qemu_6.0.0.x86_64.xml | 1 +
.../domaincapsdata/qemu_6.1.0-q35.x86_64.xml | 1 +
.../domaincapsdata/qemu_6.1.0-tcg.x86_64.xml | 1 +
tests/domaincapsdata/qemu_6.1.0.x86_64.xml | 1 +
.../domaincapsdata/qemu_6.2.0-q35.x86_64.xml | 1 +
.../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml | 1 +
.../qemu_6.2.0-virt.aarch64.xml | 1 +
tests/domaincapsdata/qemu_6.2.0.aarch64.xml | 1 +
tests/domaincapsdata/qemu_6.2.0.ppc64.xml | 1 +
tests/domaincapsdata/qemu_6.2.0.x86_64.xml | 1 +
.../domaincapsdata/qemu_7.0.0-q35.x86_64.xml | 1 +
.../domaincapsdata/qemu_7.0.0-tcg.x86_64.xml | 1 +
.../qemu_7.0.0-virt.aarch64.xml | 1 +
tests/domaincapsdata/qemu_7.0.0.aarch64.xml | 1 +
tests/domaincapsdata/qemu_7.0.0.ppc64.xml | 1 +
tests/domaincapsdata/qemu_7.0.0.x86_64.xml | 1 +
.../domaincapsdata/qemu_7.1.0-q35.x86_64.xml | 1 +
.../domaincapsdata/qemu_7.1.0-tcg.x86_64.xml | 1 +
tests/domaincapsdata/qemu_7.1.0.ppc64.xml | 1 +
tests/domaincapsdata/qemu_7.1.0.x86_64.xml | 1 +
.../domaincapsdata/qemu_7.2.0-q35.x86_64.xml | 1 +
.../domaincapsdata/qemu_7.2.0-tcg.x86_64.xml | 1 +
tests/domaincapsdata/qemu_7.2.0.x86_64.xml | 1 +
tests/qemuxml2argvdata/tpm-external.xml | 40 +++++++++++++++++++
.../tpm-external.x86_64-latest.xml | 1 +
tests/qemuxml2xmltest.c | 1 +
61 files changed, 199 insertions(+), 2 deletions(-)
create mode 100644 tests/qemuxml2argvdata/tpm-external.xml
create mode 120000 tests/qemuxml2xmloutdata/tpm-external.x86_64-latest.xml
diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c
index 974df5a037..82cf6ab749 100644
--- a/src/conf/domain_audit.c
+++ b/src/conf/domain_audit.c
@@ -556,6 +556,17 @@ virDomainAuditTPM(virDomainObj *vm, virDomainTPMDef *tpm,
"virt=%s resrc=tpm-emulator reason=%s %s uuid=%s %s",
virt, reason, vmname, uuidstr, device);
break;
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
+ path = tpm->data.external.source->data.nix.path;
+ if (!(device = virAuditEncode("device", VIR_AUDIT_STR(path)))) {
+ VIR_WARN("OOM while encoding audit message");
+ goto cleanup;
+ }
+
+ VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success,
+ "virt=%s resrc=tpm-external reason=%s %s uuid=%s %s",
+ virt, reason, vmname, uuidstr, device);
+ break;
case VIR_DOMAIN_TPM_TYPE_LAST:
default:
break;
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a180398b14..c1e6732cde 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1281,6 +1281,7 @@ VIR_ENUM_IMPL(virDomainTPMBackend,
VIR_DOMAIN_TPM_TYPE_LAST,
"passthrough",
"emulator",
+ "external",
);
VIR_ENUM_IMPL(virDomainTPMVersion,
@@ -3309,6 +3310,9 @@ void virDomainTPMDefFree(virDomainTPMDef *def)
g_free(def->data.emulator.logfile);
virBitmapFree(def->data.emulator.activePcrBanks);
break;
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
+ virObjectUnref(def->data.external.source);
+ break;
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
}
@@ -10257,6 +10261,7 @@ virDomainTPMDefParseXML(virDomainXMLOption *xmlopt,
g_autofree char *persistent_state = NULL;
g_autofree xmlNodePtr *backends = NULL;
g_autofree xmlNodePtr *nodes = NULL;
+ g_autofree char *type = NULL;
int bank;
if (!(def = virDomainTPMDefNew(xmlopt)))
@@ -10344,6 +10349,28 @@ virDomainTPMDefParseXML(virDomainXMLOption *xmlopt,
virBitmapSetBitExpand(def->data.emulator.activePcrBanks, bank);
}
break;
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
+ if (!(type = virXPathString("string(./backend/source/@type)", ctxt)))
{
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing external TPM backend type"));
+ goto error;
+ }
+
+ if (!(def->data.external.source = virDomainChrSourceDefNew(xmlopt)))
+ goto error;
+
+ def->data.external.source->type = virDomainChrTypeFromString(type);
+ if (def->data.external.source->type < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown backend type '%s' for external
TPM"),
+ type);
+ goto error;
+ }
+
+ if (virDomainChrSourceDefParseXML(def->data.external.source, backends[0],
+ flags, NULL, ctxt) < 0)
+ goto error;
+ break;
case VIR_DOMAIN_TPM_TYPE_LAST:
goto error;
}
@@ -20443,6 +20470,7 @@ virDomainTPMDefCheckABIStability(virDomainTPMDef *src,
break;
case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
}
@@ -24047,6 +24075,13 @@ virDomainTPMDefFormat(virBuffer *buf,
virXMLFormatElement(&backendChildBuf, "active_pcr_banks", NULL,
&activePcrBanksBuf);
}
break;
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
+ if (def->data.external.source->type == VIR_DOMAIN_CHR_TYPE_UNIX) {
+ virBufferAddLit(&backendChildBuf, "<source type='unix'
mode='connect'");
+ virBufferEscapeString(&backendChildBuf, "
path='%s'/>\n",
+ def->data.external.source->data.nix.path);
+ }
+ break;
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index c19dfc5470..1404c55053 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1421,6 +1421,7 @@ typedef enum {
typedef enum {
VIR_DOMAIN_TPM_TYPE_PASSTHROUGH,
VIR_DOMAIN_TPM_TYPE_EMULATOR,
+ VIR_DOMAIN_TPM_TYPE_EXTERNAL,
VIR_DOMAIN_TPM_TYPE_LAST
} virDomainTPMBackendType;
@@ -1464,6 +1465,9 @@ struct _virDomainTPMDef {
bool persistent_state;
virBitmap *activePcrBanks;
} emulator;
+ struct {
+ virDomainChrSourceDef *source;
+ } external;
} data;
};
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 95b8d9b419..8a9a79d7ea 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -2727,6 +2727,21 @@ virDomainTPMDevValidate(const virDomainTPMDef *tpm)
break;
case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
+ break;
+
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
+ if (tpm->data.external.source->type != VIR_DOMAIN_CHR_TYPE_UNIX) {
+ virReportError(VIR_ERR_XML_ERROR, "%s", _("only source type
'unix' is supported for external TPM device"));
+ return -1;
+ }
+ if (tpm->data.external.source->data.nix.listen) {
+ virReportError(VIR_ERR_XML_ERROR, "%s", _("only
'client' mode is supported for external TPM device"));
+ return -1;
+ }
+ if (tpm->data.external.source->data.nix.path == NULL) {
+ virReportError(VIR_ERR_XML_ERROR, "%s", _("missing socket path
for external TPM device"));
+ return -1;
+ }
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
}
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 8bc627d114..c588a48fd2 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -5583,6 +5583,12 @@
</attribute>
</optional>
</group>
+ <group>
+ <attribute name="type">
+ <value>external</value>
+ </attribute>
+ <ref name="tpm-external-source"/>
+ </group>
</choice>
<optional>
<attribute name="version">
@@ -5607,6 +5613,22 @@
</optional>
</define>
+ <define name="tpm-external-source">
+ <optional>
+ <element name="source">
+ <attribute name="type">
+ <value>unix</value>
+ </attribute>
+ <attribute name="path">
+ <ref name="filePath"/>
+ </attribute>
+ <attribute name="mode">
+ <value>connect</value>
+ </attribute>
+ </element>
+ </optional>
+ </define>
+
<define name="tpm-backend-emulator-encryption">
<optional>
<element name="encryption">
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2553b5b3ad..3aba9299b1 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -6471,8 +6471,10 @@ virQEMUCapsFillDomainDeviceTPMCaps(virQEMUCaps *qemuCaps,
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_TPM_PASSTHROUGH))
VIR_DOMAIN_CAPS_ENUM_SET(tpm->backendModel, VIR_DOMAIN_TPM_TYPE_PASSTHROUGH);
if (virTPMHasSwtpm()) {
- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_TPM_EMULATOR))
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_TPM_EMULATOR)) {
VIR_DOMAIN_CAPS_ENUM_SET(tpm->backendModel,
VIR_DOMAIN_TPM_TYPE_EMULATOR);
+ VIR_DOMAIN_CAPS_ENUM_SET(tpm->backendModel,
VIR_DOMAIN_TPM_TYPE_EXTERNAL);
+ }
if (virTPMSwtpmSetupCapsGet(VIR_TPM_SWTPM_SETUP_FEATURE_TPM_1_2)) {
VIR_DOMAIN_CAPS_ENUM_SET(tpm->backendVersion,
VIR_DOMAIN_TPM_VERSION_1_2);
tpm->backendVersion.report = true;
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 78c4a035bf..9cf2d6474a 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -397,6 +397,7 @@ qemuSetupTPMCgroup(virDomainObj *vm,
case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
return qemuSetupChrSourceCgroup(vm, dev->data.passthrough.source);
case VIR_DOMAIN_TPM_TYPE_EMULATOR:
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
}
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 42bd7cb99f..ee2e873b95 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9241,7 +9241,10 @@ qemuBuildTPMBackendStr(virDomainTPMDef *tpm,
{
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
- virBufferAsprintf(&buf, "%s",
virDomainTPMBackendTypeToString(tpm->type));
+ if (tpm->type == VIR_DOMAIN_TPM_TYPE_EXTERNAL)
+ virBufferAddLit(&buf, "emulator");
+ else
+ virBufferAsprintf(&buf, "%s",
virDomainTPMBackendTypeToString(tpm->type));
virBufferAsprintf(&buf, ",id=tpm-%s", tpm->info.alias);
switch (tpm->type) {
@@ -9253,6 +9256,7 @@ qemuBuildTPMBackendStr(virDomainTPMDef *tpm,
virQEMUBuildBufferEscapeComma(&buf, qemuFDPassGetPath(passcancel));
break;
case VIR_DOMAIN_TPM_TYPE_EMULATOR:
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
virBufferAddLit(&buf, ",chardev=chrtpm");
break;
case VIR_DOMAIN_TPM_TYPE_LAST:
@@ -9295,6 +9299,11 @@ qemuBuildTPMCommandLine(virCommand *cmd,
return -1;
break;
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
+ if (qemuBuildChardevCommand(cmd, tpm->data.external.source,
"chrtpm", priv->qemuCaps) < 0)
+ return -1;
+ break;
+
case VIR_DOMAIN_TPM_TYPE_LAST:
virReportEnumRangeError(virDomainTPMBackendType, tpm->type);
return -1;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 8892f28fce..5c05032ce3 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1201,6 +1201,7 @@ qemuDomainTPMPrivateFormat(const virDomainTPMDef *tpm,
break;
case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
}
@@ -11753,6 +11754,9 @@ qemuDomainDeviceBackendChardevForeachOne(virDomainDeviceDef *dev,
case VIR_DOMAIN_TPM_TYPE_EMULATOR:
return cb(dev, dev->data.tpm->data.emulator.source, opaque);
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
+ return cb(dev, dev->data.tpm->data.external.source, opaque);
+
case VIR_DOMAIN_TPM_TYPE_LAST:
return 0;
}
diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c
index 90c0b90024..0f7351ad46 100644
--- a/src/qemu/qemu_namespace.c
+++ b/src/qemu/qemu_namespace.c
@@ -457,6 +457,7 @@ qemuDomainSetupTPM(virDomainTPMDef *dev,
break;
case VIR_DOMAIN_TPM_TYPE_EMULATOR:
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
case VIR_DOMAIN_TPM_TYPE_LAST:
/* nada */
break;
diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c
index 36d5beb202..f2edaf5eaa 100644
--- a/src/qemu/qemu_tpm.c
+++ b/src/qemu/qemu_tpm.c
@@ -1028,6 +1028,7 @@ qemuTPMHasSharedStorage(virDomainDef *def)
case VIR_DOMAIN_TPM_TYPE_EMULATOR:
return virFileIsSharedFS(tpm->data.emulator.storagepath) == 1;
case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
}
@@ -1048,6 +1049,7 @@ qemuTPMCanMigrateSharedStorage(virDomainDef *def)
case VIR_DOMAIN_TPM_TYPE_EMULATOR:
return QEMU_DOMAIN_TPM_PRIVATE(tpm)->swtpm.can_migrate_shared_storage;
case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
}
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 5ca63e30f4..917fcf76a3 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1699,6 +1699,7 @@ virSecurityDACSetTPMFileLabel(virSecurityManager *mgr,
tpm->data.emulator.source,
false, false);
break;
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
}
@@ -1722,6 +1723,7 @@ virSecurityDACRestoreTPMFileLabel(virSecurityManager *mgr,
break;
case VIR_DOMAIN_TPM_TYPE_EMULATOR:
/* swtpm will have removed the Unix socket upon termination */
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
}
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 415a26a386..93cc12407a 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -1660,6 +1660,7 @@ virSecuritySELinuxSetTPMFileLabel(virSecurityManager *mgr,
if (rc < 0)
return -1;
break;
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
}
@@ -1695,6 +1696,7 @@ virSecuritySELinuxRestoreTPMFileLabelInt(virSecurityManager *mgr,
break;
case VIR_DOMAIN_TPM_TYPE_EMULATOR:
/* swtpm will have removed the Unix socket upon termination */
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
}
diff --git a/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml
b/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml
index 9375fc9457..d0bf0bdc7b 100644
--- a/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml
@@ -211,6 +211,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml
b/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml
index 860ffd1047..6a3818fb4e 100644
--- a/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml
@@ -226,6 +226,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_4.2.0.x86_64.xml
b/tests/domaincapsdata/qemu_4.2.0.x86_64.xml
index 0187584e6b..36a4081764 100644
--- a/tests/domaincapsdata/qemu_4.2.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_4.2.0.x86_64.xml
@@ -211,6 +211,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml
b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml
index 3f534b77a2..05884cdb86 100644
--- a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml
@@ -213,6 +213,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml
b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml
index 2826ce58e1..c53b84c140 100644
--- a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml
@@ -228,6 +228,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml
b/tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml
index 1ae7dfdc01..e74a3d9f5f 100644
--- a/tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml
+++ b/tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml
@@ -172,6 +172,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_5.0.0.aarch64.xml
b/tests/domaincapsdata/qemu_5.0.0.aarch64.xml
index 74db0a2561..605575c793 100644
--- a/tests/domaincapsdata/qemu_5.0.0.aarch64.xml
+++ b/tests/domaincapsdata/qemu_5.0.0.aarch64.xml
@@ -170,6 +170,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_5.0.0.ppc64.xml
b/tests/domaincapsdata/qemu_5.0.0.ppc64.xml
index 804172d013..a5b718618b 100644
--- a/tests/domaincapsdata/qemu_5.0.0.ppc64.xml
+++ b/tests/domaincapsdata/qemu_5.0.0.ppc64.xml
@@ -137,6 +137,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml
b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml
index a83e942ca5..fd1f42b555 100644
--- a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml
@@ -213,6 +213,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml
b/tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml
index f10a106d9a..a04c3e7130 100644
--- a/tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml
@@ -214,6 +214,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml
b/tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml
index a2a3b501cc..a7b2ff8d7d 100644
--- a/tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml
@@ -228,6 +228,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_5.1.0.x86_64.xml
b/tests/domaincapsdata/qemu_5.1.0.x86_64.xml
index 926ac6c231..45b7dcf6e4 100644
--- a/tests/domaincapsdata/qemu_5.1.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_5.1.0.x86_64.xml
@@ -214,6 +214,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml
b/tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml
index 31ff03f9f0..61cfa7d449 100644
--- a/tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml
@@ -214,6 +214,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml
b/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml
index fdaa0ae5bc..caced52187 100644
--- a/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml
@@ -228,6 +228,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_5.2.0-virt.aarch64.xml
b/tests/domaincapsdata/qemu_5.2.0-virt.aarch64.xml
index 762fbe2f50..f19ad32693 100644
--- a/tests/domaincapsdata/qemu_5.2.0-virt.aarch64.xml
+++ b/tests/domaincapsdata/qemu_5.2.0-virt.aarch64.xml
@@ -172,6 +172,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_5.2.0.aarch64.xml
b/tests/domaincapsdata/qemu_5.2.0.aarch64.xml
index 74db0a2561..605575c793 100644
--- a/tests/domaincapsdata/qemu_5.2.0.aarch64.xml
+++ b/tests/domaincapsdata/qemu_5.2.0.aarch64.xml
@@ -170,6 +170,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_5.2.0.ppc64.xml
b/tests/domaincapsdata/qemu_5.2.0.ppc64.xml
index 02e038d445..8ae7487c1e 100644
--- a/tests/domaincapsdata/qemu_5.2.0.ppc64.xml
+++ b/tests/domaincapsdata/qemu_5.2.0.ppc64.xml
@@ -137,6 +137,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_5.2.0.x86_64.xml
b/tests/domaincapsdata/qemu_5.2.0.x86_64.xml
index cfd6ff1d84..67f8b0fd83 100644
--- a/tests/domaincapsdata/qemu_5.2.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_5.2.0.x86_64.xml
@@ -214,6 +214,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml
b/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml
index 048c47e9f6..08585e6cb0 100644
--- a/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml
@@ -215,6 +215,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml
b/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml
index 75bf330a79..7536a42ad5 100644
--- a/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml
@@ -230,6 +230,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_6.0.0-virt.aarch64.xml
b/tests/domaincapsdata/qemu_6.0.0-virt.aarch64.xml
index 30446b75f7..1235dd0ab7 100644
--- a/tests/domaincapsdata/qemu_6.0.0-virt.aarch64.xml
+++ b/tests/domaincapsdata/qemu_6.0.0-virt.aarch64.xml
@@ -173,6 +173,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_6.0.0.aarch64.xml
b/tests/domaincapsdata/qemu_6.0.0.aarch64.xml
index 6c30318d34..461e34f1d6 100644
--- a/tests/domaincapsdata/qemu_6.0.0.aarch64.xml
+++ b/tests/domaincapsdata/qemu_6.0.0.aarch64.xml
@@ -171,6 +171,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_6.0.0.x86_64.xml
b/tests/domaincapsdata/qemu_6.0.0.x86_64.xml
index 8b9e910fdc..632f7c21d1 100644
--- a/tests/domaincapsdata/qemu_6.0.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.0.0.x86_64.xml
@@ -215,6 +215,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml
b/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml
index bc4912bc62..35d1014626 100644
--- a/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml
@@ -216,6 +216,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml
b/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml
index 6cbdb1d6ae..9d56f2dda7 100644
--- a/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml
@@ -230,6 +230,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_6.1.0.x86_64.xml
b/tests/domaincapsdata/qemu_6.1.0.x86_64.xml
index 5efb7b595c..591ca12d72 100644
--- a/tests/domaincapsdata/qemu_6.1.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.1.0.x86_64.xml
@@ -216,6 +216,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml
b/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml
index 1281dc5ff8..7558e78423 100644
--- a/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml
@@ -216,6 +216,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml
b/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml
index 2fcff7a96f..c667b944da 100644
--- a/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml
@@ -232,6 +232,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_6.2.0-virt.aarch64.xml
b/tests/domaincapsdata/qemu_6.2.0-virt.aarch64.xml
index 5aa8820612..2c9ba98a0a 100644
--- a/tests/domaincapsdata/qemu_6.2.0-virt.aarch64.xml
+++ b/tests/domaincapsdata/qemu_6.2.0-virt.aarch64.xml
@@ -175,6 +175,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_6.2.0.aarch64.xml
b/tests/domaincapsdata/qemu_6.2.0.aarch64.xml
index 96c426cd4f..9b546f59bc 100644
--- a/tests/domaincapsdata/qemu_6.2.0.aarch64.xml
+++ b/tests/domaincapsdata/qemu_6.2.0.aarch64.xml
@@ -173,6 +173,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_6.2.0.ppc64.xml
b/tests/domaincapsdata/qemu_6.2.0.ppc64.xml
index 350c55e2c0..fd7c9d8d5a 100644
--- a/tests/domaincapsdata/qemu_6.2.0.ppc64.xml
+++ b/tests/domaincapsdata/qemu_6.2.0.ppc64.xml
@@ -135,6 +135,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_6.2.0.x86_64.xml
b/tests/domaincapsdata/qemu_6.2.0.x86_64.xml
index ae789c3a9b..a20d3722fd 100644
--- a/tests/domaincapsdata/qemu_6.2.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.2.0.x86_64.xml
@@ -216,6 +216,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>1.2</value>
diff --git a/tests/domaincapsdata/qemu_7.0.0-q35.x86_64.xml
b/tests/domaincapsdata/qemu_7.0.0-q35.x86_64.xml
index 59b2988de0..ac9d384bb3 100644
--- a/tests/domaincapsdata/qemu_7.0.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_7.0.0-q35.x86_64.xml
@@ -218,6 +218,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>2.0</value>
diff --git a/tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml
b/tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml
index 58d8bdee3f..2419875474 100644
--- a/tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml
@@ -234,6 +234,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>2.0</value>
diff --git a/tests/domaincapsdata/qemu_7.0.0-virt.aarch64.xml
b/tests/domaincapsdata/qemu_7.0.0-virt.aarch64.xml
index 4ec23a8b85..f4eb8a728b 100644
--- a/tests/domaincapsdata/qemu_7.0.0-virt.aarch64.xml
+++ b/tests/domaincapsdata/qemu_7.0.0-virt.aarch64.xml
@@ -175,6 +175,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>2.0</value>
diff --git a/tests/domaincapsdata/qemu_7.0.0.aarch64.xml
b/tests/domaincapsdata/qemu_7.0.0.aarch64.xml
index d3f90db5a8..053bec369b 100644
--- a/tests/domaincapsdata/qemu_7.0.0.aarch64.xml
+++ b/tests/domaincapsdata/qemu_7.0.0.aarch64.xml
@@ -173,6 +173,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>2.0</value>
diff --git a/tests/domaincapsdata/qemu_7.0.0.ppc64.xml
b/tests/domaincapsdata/qemu_7.0.0.ppc64.xml
index e9322a02e2..9c09174d77 100644
--- a/tests/domaincapsdata/qemu_7.0.0.ppc64.xml
+++ b/tests/domaincapsdata/qemu_7.0.0.ppc64.xml
@@ -137,6 +137,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>2.0</value>
diff --git a/tests/domaincapsdata/qemu_7.0.0.x86_64.xml
b/tests/domaincapsdata/qemu_7.0.0.x86_64.xml
index 368c359dcf..886e14ea49 100644
--- a/tests/domaincapsdata/qemu_7.0.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_7.0.0.x86_64.xml
@@ -218,6 +218,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>2.0</value>
diff --git a/tests/domaincapsdata/qemu_7.1.0-q35.x86_64.xml
b/tests/domaincapsdata/qemu_7.1.0-q35.x86_64.xml
index 831ef667e9..6b5e8a6820 100644
--- a/tests/domaincapsdata/qemu_7.1.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_7.1.0-q35.x86_64.xml
@@ -217,6 +217,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>2.0</value>
diff --git a/tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml
b/tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml
index e5d5768b40..e44804c21c 100644
--- a/tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml
@@ -232,6 +232,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>2.0</value>
diff --git a/tests/domaincapsdata/qemu_7.1.0.ppc64.xml
b/tests/domaincapsdata/qemu_7.1.0.ppc64.xml
index 73c2cb84e4..15cf6a9cf8 100644
--- a/tests/domaincapsdata/qemu_7.1.0.ppc64.xml
+++ b/tests/domaincapsdata/qemu_7.1.0.ppc64.xml
@@ -130,6 +130,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>2.0</value>
diff --git a/tests/domaincapsdata/qemu_7.1.0.x86_64.xml
b/tests/domaincapsdata/qemu_7.1.0.x86_64.xml
index 0e2aa77a7d..d4069dd6f0 100644
--- a/tests/domaincapsdata/qemu_7.1.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_7.1.0.x86_64.xml
@@ -217,6 +217,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>2.0</value>
diff --git a/tests/domaincapsdata/qemu_7.2.0-q35.x86_64.xml
b/tests/domaincapsdata/qemu_7.2.0-q35.x86_64.xml
index 8c6399a7b6..e6997ccbc6 100644
--- a/tests/domaincapsdata/qemu_7.2.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_7.2.0-q35.x86_64.xml
@@ -222,6 +222,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>2.0</value>
diff --git a/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64.xml
b/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64.xml
index b04beaa9d6..b9bf0b6a04 100644
--- a/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_7.2.0-tcg.x86_64.xml
@@ -221,6 +221,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>2.0</value>
diff --git a/tests/domaincapsdata/qemu_7.2.0.x86_64.xml
b/tests/domaincapsdata/qemu_7.2.0.x86_64.xml
index 86385dacbd..67ecdc0b12 100644
--- a/tests/domaincapsdata/qemu_7.2.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_7.2.0.x86_64.xml
@@ -222,6 +222,7 @@
<enum name='backendModel'>
<value>passthrough</value>
<value>emulator</value>
+ <value>external</value>
</enum>
<enum name='backendVersion'>
<value>2.0</value>
diff --git a/tests/qemuxml2argvdata/tpm-external.xml
b/tests/qemuxml2argvdata/tpm-external.xml
new file mode 100644
index 0000000000..c8f9c72b1f
--- /dev/null
+++ b/tests/qemuxml2argvdata/tpm-external.xml
@@ -0,0 +1,40 @@
+<domain type='qemu'>
+ <name>TPM-VM</name>
+ <uuid>11d7cd22-da89-3094-6212-079a48a309a1</uuid>
+ <memory unit='KiB'>2097152</memory>
+ <currentMemory unit='KiB'>512288</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc-i440fx-2.12'>hvm</type>
+ <boot dev='hd'/>
+ <bootmenu enable='yes'/>
+ </os>
+ <features>
+ <acpi/>
+ </features>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='usb' index='0' model='piix3-uhci'>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <tpm model='tpm-tis'>
+ <backend type='external'>
+ <source type='unix' mode='connect'
path='/tmp/path.sock'/>
+ </backend>
+ </tpm>
+ <audio id='1' type='none'/>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x02' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/tpm-external.x86_64-latest.xml
b/tests/qemuxml2xmloutdata/tpm-external.x86_64-latest.xml
new file mode 120000
index 0000000000..3ce73f0a84
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/tpm-external.x86_64-latest.xml
@@ -0,0 +1 @@
+../qemuxml2argvdata/tpm-external.xml
\ No newline at end of file
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index e13da8bd2c..0e729ca905 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -744,6 +744,7 @@ mymain(void)
DO_TEST_CAPS_LATEST("tpm-emulator-tpm2-enc");
DO_TEST_CAPS_LATEST("tpm-emulator-tpm2-pstate");
DO_TEST_CAPS_ARCH_LATEST("aarch64-tpm", "aarch64");
+ DO_TEST_CAPS_LATEST("tpm-external");
DO_TEST_NOCAPS("metadata");
DO_TEST_NOCAPS("metadata-duplicate");
--
2.38.1