Parses vtpm.present from VMX files and converts to libvirt TPM device with CRB model and emulator backend. VMware vTPM uses TPM 2.0 as specified in the document below https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/8-0/vsphere-s... implement support for formatting TPM devices in virVMXFormatConfig Signed-off-by: Srihari Parimi <sparimi@redhat.com> --- src/vmx/vmx.c | 74 ++++++++++++++++++++++++++++++++++++++ tests/vmx2xmldata/vtpm.vmx | 22 ++++++++++++ tests/vmx2xmldata/vtpm.xml | 32 +++++++++++++++++ tests/vmx2xmltest.c | 2 ++ 4 files changed, 130 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..977fd3b346 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, @@ -609,6 +610,7 @@ static int virVMXFormatFileSystem(virDomainFSDef *def, int number, virBuffer *buffer); static int virVMXFormatEthernet(virDomainNetDef *def, int controller, virBuffer *buffer, int virtualHW_version); +static int virVMXFormatTPM(virDomainTPMDef *def, virBuffer *buffer); static int virVMXFormatSerial(virVMXContext *ctx, virDomainChrDef *def, virBuffer *buffer); static int virVMXFormatParallel(virVMXContext *ctx, virDomainChrDef *def, @@ -1938,6 +1940,15 @@ 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 */ @@ -3367,6 +3378,27 @@ virVMXParseSVGA(virConf *conf, virDomainVideoDef **def) return result; } +static int +virVMXParseTPM(virConf *conf, virDomainTPMDef **def) +{ + bool vtpm_present = false; + + /* 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; +} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -3701,6 +3733,31 @@ virVMXFormatConfig(virVMXContext *ctx, virDomainXMLOption *xmlopt, virDomainDef goto cleanup; } + /* def:vTPM */ + if (def->ntpms > 0) { + /* Validate TPM requirements */ + if (def->ntpms > 1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("VMware only supports a single TPM device")); + goto cleanup; + } + + if (virtualHW_version < 14) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("vTPM requires virtual hardware version 14 or higher")); + goto cleanup; + } + + if (def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_EFI) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("vTPM requires EFI firmware")); + goto cleanup; + } + + if (virVMXFormatTPM(def->tpms[0], &buffer) < 0) + goto cleanup; + } + /* def:inputs */ /* FIXME */ @@ -4231,6 +4288,23 @@ virVMXFormatEthernet(virDomainNetDef *def, int controller, } +static int virVMXFormatTPM(virDomainTPMDef *def, virBuffer *buffer) +{ + /* VMware vTPM specifically requires TPM 2.0 */ + if (def->model != VIR_DOMAIN_TPM_MODEL_CRB || + def->type != VIR_DOMAIN_TPM_TYPE_EMULATOR || + def->data.emulator.version != VIR_DOMAIN_TPM_VERSION_2_0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("VMware driver only supports TPM 2.0 with the CRB model")); + return -1; + } + + /* VMX parameters for vTPM */ + virBufferAddLit(buffer, "vtpm.present = \"TRUE\"\n"); + + return 0; +} + static int virVMXFormatSerial(virVMXContext *ctx, virDomainChrDef *def, 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