src/vmx/vmx.c | 50 ++++++++++++++++++++++++++++++++++++++ tests/vmx2xmldata/vtpm.vmx | 22 +++++++++++++++++ tests/vmx2xmldata/vtpm.xml | 32 ++++++++++++++++++++++++ tests/vmx2xmltest.c | 2 ++ 4 files changed, 106 insertions(+) create mode 100644 tests/vmx2xmldata/vtpm.vmx create mode 100644 tests/vmx2xmldata/vtpm.xml
Parses vtpm.present from VMX files and converts to libvirt TPM
device with CRB model and emulator backend. VMware vTPM uses
TPM 2.0 with the CRB
Signed-off-by: Srihari Parimi <sparimi@redhat.com>
---
src/vmx/vmx.c | 50 ++++++++++++++++++++++++++++++++++++++
tests/vmx2xmldata/vtpm.vmx | 22 +++++++++++++++++
tests/vmx2xmldata/vtpm.xml | 32 ++++++++++++++++++++++++
tests/vmx2xmltest.c | 2 ++
4 files changed, 106 insertions(+)
create mode 100644 tests/vmx2xmldata/vtpm.vmx
create mode 100644 tests/vmx2xmldata/vtpm.xml
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index 57dfd57cfc..9231968175 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -599,6 +599,7 @@ static int virVMXParseSerial(virVMXContext *ctx, virConf *conf, int port,
static int virVMXParseParallel(virVMXContext *ctx, virConf *conf, int port,
virDomainChrDef **def);
static int virVMXParseSVGA(virConf *conf, virDomainVideoDef **def);
+static int virVMXParseTPM(virConf *conf, virDomainTPMDef **def);
static int virVMXFormatVNC(virDomainGraphicsDef *def, virBuffer *buffer);
static int virVMXFormatDisk(virVMXContext *ctx, virDomainDiskDef *def,
@@ -1403,6 +1404,7 @@ virVMXParseConfig(virVMXContext *ctx,
char *guestOS = NULL;
bool smbios_reflecthost = false;
bool uefi_secureboot = false;
+ bool vtpm_present = false;
int controller;
int bus;
int port;
@@ -1938,6 +1940,16 @@ virVMXParseConfig(virVMXContext *ctx,
def->nvideos = 1;
+ /* def:tpms */
+ {
+ virDomainTPMDef *tpm = NULL;
+ if (virVMXParseTPM(conf, &tpm) < 0)
+ goto cleanup;
+
+ if (tpm)
+ VIR_APPEND_ELEMENT(def->tpms, def->ntpms, tpm);
+ }
+
/* def:sounds */
/* FIXME */
@@ -2001,6 +2013,18 @@ virVMXParseConfig(virVMXContext *ctx,
}
}
+ /* vmx: vtpm.present (optional) */
+ if (virVMXGetConfigBoolean(conf, "vtpm.present",
+ &vtpm_present, false, true) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to parse vtpm.present"));
+ goto cleanup;
+ }
+ if (vtpm_present) {
+ VIR_DEBUG("Processing vtpm_present: %s",
+ (vtpm_present == true) ? "yes" : "no");
+ }
+
/* vmx:uefi.secureBoot.enabled */
if (virVMXGetConfigBoolean(conf, "uefi.secureBoot.enabled",
&uefi_secureboot, false, true) < 0) {
@@ -3367,6 +3391,32 @@ virVMXParseSVGA(virConf *conf, virDomainVideoDef **def)
return result;
}
+static int
+virVMXParseTPM(virConf *conf, virDomainTPMDef **def)
+{
+ bool vtpm_present = false;
+
+ if (def == NULL || *def != NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+ return -1;
+ }
+
+ /* vmx:vtpm.present */
+ if (virVMXGetConfigBoolean(conf, "vtpm.present", &vtpm_present,
+ false, true) < 0) {
+ return -1;
+ }
+
+ if (!vtpm_present)
+ return 0;
+
+ *def = g_new0(virDomainTPMDef, 1);
+ (*def)->type = VIR_DOMAIN_TPM_TYPE_EMULATOR;
+ (*def)->model = VIR_DOMAIN_TPM_MODEL_CRB;
+ (*def)->data.emulator.version = VIR_DOMAIN_TPM_VERSION_2_0;
+
+ return 0;
+}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
diff --git a/tests/vmx2xmldata/vtpm.vmx b/tests/vmx2xmldata/vtpm.vmx
new file mode 100644
index 0000000000..6e2fd725b7
--- /dev/null
+++ b/tests/vmx2xmldata/vtpm.vmx
@@ -0,0 +1,22 @@
+config.version = "8"
+virtualHW.version = "19"
+displayName = "test-vtpm"
+memsize = "4096"
+numvcpus = "2"
+guestOS = "windows9-64"
+
+# Disk Configuration
+scsi0.present = "TRUE"
+scsi0.virtualDev = "lsisas1068"
+scsi0:0.present = "TRUE"
+scsi0:0.deviceType = "scsi-hardDisk"
+scsi0:0.fileName = "test_disk.vmdk"
+
+# vTPM configuration
+vtpm.present = "TRUE"
+
+# Network Configuration
+ethernet0.present = "TRUE"
+ethernet0.connectionType = "nat"
+ethernet0.virtualDev = "e1000e"
+ethernet0.addressType = "generated"
diff --git a/tests/vmx2xmldata/vtpm.xml b/tests/vmx2xmldata/vtpm.xml
new file mode 100644
index 0000000000..cbb23ce673
--- /dev/null
+++ b/tests/vmx2xmldata/vtpm.xml
@@ -0,0 +1,32 @@
+<domain type='vmware'>
+ <name>test-vtpm</name>
+ <uuid>00000000-0000-0000-0000-000000000000</uuid>
+ <memory unit='KiB'>4194304</memory>
+ <currentMemory unit='KiB'>4194304</currentMemory>
+ <vcpu placement='static'>2</vcpu>
+ <os>
+ <type arch='x86_64'>hvm</type>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <disk type='file' device='disk'>
+ <source file='[datastore] directory/test_disk.vmdk'/>
+ <target dev='sda' bus='scsi'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='scsi' index='0' model='lsisas1068'/>
+ <interface type='user'>
+ <mac address='00:00:00:00:00:00' type='generated'/>
+ <model type='e1000e'/>
+ </interface>
+ <tpm model='tpm-crb'>
+ <backend type='emulator' version='2.0'/>
+ </tpm>
+ <video>
+ <model type='vmvga' vram='4096' primary='yes'/>
+ </video>
+ </devices>
+</domain>
diff --git a/tests/vmx2xmltest.c b/tests/vmx2xmltest.c
index fcca765bed..3ffc04fda4 100644
--- a/tests/vmx2xmltest.c
+++ b/tests/vmx2xmltest.c
@@ -243,6 +243,8 @@ mymain(void)
DO_TEST("firmware-efi");
+ DO_TEST("vtpm");
+
ctx.datacenterPath = "folder1/folder2/datacenter1";
DO_TEST("datacenterpath");
--
2.53.0
In summary of the commit mention 'vmx' as the driver instead of the
obvious 'libvirt'
On Fri, Apr 17, 2026 at 11:45:15 +0530, Srihari Parimi via Devel wrote:
> Parses vtpm.present from VMX files and converts to libvirt TPM
> device with CRB model and emulator backend. VMware vTPM uses
> TPM 2.0 with the CRB
Do you know of any docs to point to for which version of TPM is used?
>
> Signed-off-by: Srihari Parimi <sparimi@redhat.com>
> ---
> src/vmx/vmx.c | 50 ++++++++++++++++++++++++++++++++++++++
> tests/vmx2xmldata/vtpm.vmx | 22 +++++++++++++++++
> tests/vmx2xmldata/vtpm.xml | 32 ++++++++++++++++++++++++
> tests/vmx2xmltest.c | 2 ++
> 4 files changed, 106 insertions(+)
> create mode 100644 tests/vmx2xmldata/vtpm.vmx
> create mode 100644 tests/vmx2xmldata/vtpm.xml
>
> diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
> index 57dfd57cfc..9231968175 100644
> --- a/src/vmx/vmx.c
> +++ b/src/vmx/vmx.c
> @@ -599,6 +599,7 @@ static int virVMXParseSerial(virVMXContext *ctx, virConf *conf, int port,
> static int virVMXParseParallel(virVMXContext *ctx, virConf *conf, int port,
> virDomainChrDef **def);
> static int virVMXParseSVGA(virConf *conf, virDomainVideoDef **def);
> +static int virVMXParseTPM(virConf *conf, virDomainTPMDef **def);
>
> static int virVMXFormatVNC(virDomainGraphicsDef *def, virBuffer *buffer);
> static int virVMXFormatDisk(virVMXContext *ctx, virDomainDiskDef *def,
> @@ -1403,6 +1404,7 @@ virVMXParseConfig(virVMXContext *ctx,
> char *guestOS = NULL;
> bool smbios_reflecthost = false;
> bool uefi_secureboot = false;
> + bool vtpm_present = false;
> int controller;
> int bus;
> int port;
> @@ -1938,6 +1940,16 @@ virVMXParseConfig(virVMXContext *ctx,
>
> def->nvideos = 1;
>
> + /* def:tpms */
> + {
> + virDomainTPMDef *tpm = NULL;
> + if (virVMXParseTPM(conf, &tpm) < 0)
> + goto cleanup;
So this parses 'vtpm.present'
> +
> + if (tpm)
> + VIR_APPEND_ELEMENT(def->tpms, def->ntpms, tpm);
> + }
> +
> /* def:sounds */
> /* FIXME */
>
> @@ -2001,6 +2013,18 @@ virVMXParseConfig(virVMXContext *ctx,
> }
> }
>
> + /* vmx: vtpm.present (optional) */
And inside the same function ...
> + if (virVMXGetConfigBoolean(conf, "vtpm.present",
> + &vtpm_present, false, true) < 0) {
You parse it again ...
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Unable to parse vtpm.present"));
> + goto cleanup;
> + }
> + if (vtpm_present) {
> + VIR_DEBUG("Processing vtpm_present: %s",
> + (vtpm_present == true) ? "yes" : "no");
just to add a debug statement? Can you explain this please?
> + }
> +
> /* vmx:uefi.secureBoot.enabled */
> if (virVMXGetConfigBoolean(conf, "uefi.secureBoot.enabled",
> &uefi_secureboot, false, true) < 0) {
> @@ -3367,6 +3391,32 @@ virVMXParseSVGA(virConf *conf, virDomainVideoDef **def)
> return result;
> }
>
> +static int
> +virVMXParseTPM(virConf *conf, virDomainTPMDef **def)
> +{
> + bool vtpm_present = false;
> +
> + if (def == NULL || *def != NULL) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
> + return -1;
> + }
The only caller always passes these, so this check isn't needed.
> +
> + /* vmx:vtpm.present */
> + if (virVMXGetConfigBoolean(conf, "vtpm.present", &vtpm_present,
> + false, true) < 0) {
> + return -1;
> + }
> +
> + if (!vtpm_present)
> + return 0;
> +
> + *def = g_new0(virDomainTPMDef, 1);
> + (*def)->type = VIR_DOMAIN_TPM_TYPE_EMULATOR;
> + (*def)->model = VIR_DOMAIN_TPM_MODEL_CRB;
> + (*def)->data.emulator.version = VIR_DOMAIN_TPM_VERSION_2_0;
> +
> + return 0;
> +}
>
>
> /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
On 4/17/26 6:15 AM, Peter Krempa via Devel wrote: > > In summary of the commit mention 'vmx' as the driver instead of the > obvious 'libvirt' > > > On Fri, Apr 17, 2026 at 11:45:15 +0530, Srihari Parimi via Devel wrote: >> Parses vtpm.present from VMX files and converts to libvirt TPM >> device with CRB model and emulator backend. VMware vTPM uses >> TPM 2.0 with the CRB > > Do you know of any docs to point to for which version of TPM is used? > I wrote the original RFE so I'll provide this piece. Docs: https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-security/securing-virtual-machines-with-virtual-trusted-platform-module/vtpm-overview.html Has this quote: "A virtual Trusted Platform Module (vTPM) is a software-based representation of a physical Trusted Platform Module 2.0 chip." So, emulated version 2.0. Can't find anything about CRB vs TIS but I believe CRB is default for TPM 2.0 devices in general so I took that to be implied. I lack a setup to confirm at the moment but I can scrounge one up if you'd like Thanks, Cole
© 2016 - 2026 Red Hat, Inc.