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 Fri, Apr 17, 2026 at 3:45 PM Peter Krempa <pkrempa@redhat.com> 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?
>
Google search general suggestions
1. TIS supports TPM 1.2, TPM 2.0
2. CRB strictly supports TPM 2.0
3. CRB is generally recommended for Windows 11 or for UEFI based systems
which requires TPM 2.0
>
>
> >
> > 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?
>
Agree - this is not needed. Mistake on my part when I moved the code into
the function *virVMXParseTPM*, this should have been removed. I need to
review the patch before posting it.
>
> > + }
> > +
> > /* 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.
>
Agree. I have removed the checks. Was wondering if we need to be more
defensive ?
>
> > +
> > + /* 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.