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 | 16 ++++++++
src/conf/domain_conf.h | 4 ++
src/conf/domain_validate.c | 1 +
src/conf/schemas/domaincommon.rng | 18 +++++++++
src/qemu/qemu_capabilities.c | 4 +-
src/qemu/qemu_cgroup.c | 1 +
src/qemu/qemu_command.c | 11 ++++-
src/qemu/qemu_domain.c | 3 ++
src/qemu/qemu_namespace.c | 1 +
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 +
tests/qemuxml2argvdata/tpm-external.xml | 40 +++++++++++++++++++
.../tpm-external.x86_64-latest.xml | 1 +
tests/qemuxml2xmltest.c | 1 +
57 files changed, 156 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 7dba65cfeb..2059c60a63 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1280,6 +1280,7 @@ VIR_ENUM_IMPL(virDomainTPMBackend,
VIR_DOMAIN_TPM_TYPE_LAST,
"passthrough",
"emulator",
+ "external",
);
VIR_ENUM_IMPL(virDomainTPMVersion,
@@ -3291,6 +3292,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;
}
@@ -10322,6 +10326,13 @@ virDomainTPMDefParseXML(virDomainXMLOption *xmlopt,
virBitmapSetBitExpand(def->data.emulator.activePcrBanks, bank);
}
break;
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
+ if (!(def->data.external.source = virDomainChrSourceDefNew(xmlopt)))
+ goto error;
+ path = virXPathString("string(./backend/source/@path)", ctxt);
+ def->data.external.source->type = VIR_DOMAIN_CHR_TYPE_UNIX;
+ def->data.external.source->data.nix.path = g_steal_pointer(&path);
+ break;
case VIR_DOMAIN_TPM_TYPE_LAST:
goto error;
}
@@ -20513,6 +20524,7 @@ virDomainTPMDefCheckABIStability(virDomainTPMDef *src,
break;
case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
}
@@ -24095,6 +24107,10 @@ virDomainTPMDefFormat(virBuffer *buf,
virXMLFormatElement(&backendChildBuf, "active_pcr_banks", NULL,
&activePcrBanksBuf);
}
break;
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
+ virBufferEscapeString(&backendChildBuf, "<source
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 8f8a54bc41..91d9afeb11 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;
@@ -1462,6 +1463,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 81f6d5dbd5..3104899192 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -2712,6 +2712,7 @@ virDomainTPMDevValidate(const virDomainTPMDef *tpm)
break;
case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
}
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 6e30512c73..3da210faca 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -5565,6 +5565,12 @@
</attribute>
</optional>
</group>
+ <group>
+ <attribute name="type">
+ <value>external</value>
+ </attribute>
+ <ref name="tpm-external-source"/>
+ </group>
</choice>
<optional>
<attribute name="version">
@@ -5589,6 +5595,18 @@
</optional>
</define>
+ <define name="tpm-external-source">
+ <optional>
+ <element name="source">
+ <optional>
+ <attribute name="path">
+ <ref name="filePath"/>
+ </attribute>
+ </optional>
+ </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 40da6f1b50..561f56c658 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -6313,8 +6313,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 d6f27a5a4d..2020e6f2ab 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -375,6 +375,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 150824f2e1..2811aeb0eb 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9145,7 +9145,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) {
@@ -9157,6 +9160,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:
@@ -9199,6 +9203,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 4c14fc2aef..f675b1811f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -11643,6 +11643,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 311c66d46e..5e46962664 100644
--- a/src/qemu/qemu_namespace.c
+++ b/src/qemu/qemu_namespace.c
@@ -433,6 +433,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/security/security_dac.c b/src/security/security_dac.c
index 21cebae694..6c90e407c2 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1697,6 +1697,7 @@ virSecurityDACSetTPMFileLabel(virSecurityManager *mgr,
tpm->data.emulator.source,
false, false);
break;
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
}
@@ -1720,6 +1721,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 a296cb7613..05e1f8cc4e 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -1658,6 +1658,7 @@ virSecuritySELinuxSetTPMFileLabel(virSecurityManager *mgr,
if (rc < 0)
return -1;
break;
+ case VIR_DOMAIN_TPM_TYPE_EXTERNAL:
case VIR_DOMAIN_TPM_TYPE_LAST:
break;
}
@@ -1693,6 +1694,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 5b83883e39..5b19bf95fe 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 ab55ec2452..e8ae7197e7 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 a6eaf7962f..b3a6b387c5 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 232f1f0e12..2900350fa5 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 ce2c08f205..ff6436ffea 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 9215371d0c..4234454f76 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 fcc77ad8db..1e4f4a8f64 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 711ccc2cb0..545407bbe1 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 f52613f584..90eceb8eeb 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 542d32b018..4f36f72fa7 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 8bd5c6073c..4510d7eb20 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 5c48efc8c6..b6678864d0 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 70c4f3cbd1..50448cecd8 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 636a84e55f..deb0c353ea 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 900d10f720..06f39e2b2b 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 fcc77ad8db..1e4f4a8f64 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 99c2767276..c0fc259abb 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 db22085e31..e016915059 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 395eb3b9eb..3a098cbe99 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 769a1147b6..d2e71470f8 100644
--- a/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml
@@ -229,6 +229,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 2f56e36c28..d7df5b3fb6 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 4639a84c1d..a6f98d553a 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 2be8f3e33b..9196297486 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 f23e758b1a..3009149945 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 f78abdefc5..a3775a6093 100644
--- a/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml
@@ -229,6 +229,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 9de18c682e..f0667c1afb 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 dff92d65aa..f4b06e3c66 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 f027eb25a5..c26cc37766 100644
--- a/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.2.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.2.0-virt.aarch64.xml
b/tests/domaincapsdata/qemu_6.2.0-virt.aarch64.xml
index c572b0481c..f25b74eb91 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 eb521a0cfa..910c5b398f 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 7797b94cf2..1cb156b248 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 aff2ee6662..9c4a69751f 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 e70b0990a7..8f82388648 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 03c5411c4e..0a1b2eebcd 100644
--- a/tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_7.0.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.0.0-virt.aarch64.xml
b/tests/domaincapsdata/qemu_7.0.0-virt.aarch64.xml
index 59f89afd9b..cbb1acb3f8 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 1e6bf544dc..b11f513d28 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 76da1f4f7d..d99a7ba511 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 da23f5703a..d10687f304 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 05b36ee79e..15ce55416d 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 0786cd8430..cf9d335fa3 100644
--- a/tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_7.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>2.0</value>
diff --git a/tests/domaincapsdata/qemu_7.1.0.ppc64.xml
b/tests/domaincapsdata/qemu_7.1.0.ppc64.xml
index d430e54caa..0b83d37f79 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 ae67a16947..d8a8f1561b 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/qemuxml2argvdata/tpm-external.xml
b/tests/qemuxml2argvdata/tpm-external.xml
new file mode 100644
index 0000000000..fe47f1e963
--- /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 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 3a2d029c4f..03546d68ad 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -753,6 +753,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.37.3