[PATCH] hyperv: report whether guests have TPM enabled
Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- src/hyperv/hyperv_driver.c | 32 +++++++++++++++++++++++++++ src/hyperv/hyperv_wmi.c | 26 ++++++++++++++++++++++ src/hyperv/hyperv_wmi.h | 4 ++++ src/hyperv/hyperv_wmi_generator.input | 9 ++++++++ 4 files changed, 71 insertions(+) diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index b01b4919fe..7cc67129cd 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -200,6 +200,22 @@ hypervGetOperatingSystem(hypervPrivate *priv, Win32_OperatingSystem **operatingS } +static int +hypervDomainGetTPMEnabled(hypervPrivate *priv, + const char *id, + bool *enabled) +{ + g_autoptr(Msvm_SecuritySettingData) securitySD = NULL; + + if (hypervGetSecuritySD(priv, id, &securitySD) < 0) + return -1; + + VIR_DEBUG("Getting TPM state for '%s': %u", id, securitySD->data->TpmEnabled); + *enabled = securitySD->data->TpmEnabled; + return 0; +} + + static int hypervRequestStateChange(virDomainPtr domain, int state) { @@ -2651,6 +2667,7 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) g_autoptr(Msvm_SerialPortSettingData) spsd = NULL; Msvm_ResourceAllocationSettingData *serialDevices = NULL; g_autoptr(Msvm_EthernetPortAllocationSettingData) nets = NULL; + bool tpmEnabled = false; virCheckFlags(VIR_DOMAIN_XML_COMMON_FLAGS, NULL); @@ -2791,6 +2808,21 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) if (hypervDomainDefParseEthernet(domain, def, nets) < 0) return NULL; + if (hypervDomainGetTPMEnabled(priv, virtualSystemSettingData->data->InstanceID, &tpmEnabled) == 0 + && tpmEnabled) { + virDomainTPMDef* tpm = NULL; + + if (!def->tpms) { + def->tpms = g_new0(virDomainTPMDef *, 1); + } + + tpm = g_new0(virDomainTPMDef, 1); + tpm->model = VIR_DOMAIN_TPM_MODEL_DEFAULT; + tpm->type = VIR_DOMAIN_TPM_TYPE_EMULATOR; + + def->tpms[def->ntpms++] = tpm; + } + /* XXX xmlopts must be non-NULL */ return virDomainDefFormat(def, NULL, virDomainDefFormatConvertXMLFlags(flags)); } diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c index 7ae3afc40a..1cf442dad3 100644 --- a/src/hyperv/hyperv_wmi.c +++ b/src/hyperv/hyperv_wmi.c @@ -1625,3 +1625,29 @@ hypervMsvmVSMSModifyResourceSettings(hypervPrivate *priv, return 0; } + + +int +hypervGetSecuritySD(hypervPrivate *priv, + const char *vssd_instanceid, + Msvm_SecuritySettingData **data) +{ + g_auto(virBuffer) query = VIR_BUFFER_INITIALIZER; + + virBufferEscapeSQL(&query, + "ASSOCIATORS OF {Msvm_VirtualSystemSettingData.InstanceID='%s'} " + "WHERE ResultClass = Msvm_SecuritySettingData", + vssd_instanceid); + + if (hypervGetWmiClass(Msvm_SecuritySettingData, data) < 0) + return -1; + + if (!*data) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not look up security setting data with virtual system instance ID '%1$s'"), + vssd_instanceid); + return -1; + } + + return 0; +} diff --git a/src/hyperv/hyperv_wmi.h b/src/hyperv/hyperv_wmi.h index 65b1211b89..0f8cfb30bc 100644 --- a/src/hyperv/hyperv_wmi.h +++ b/src/hyperv/hyperv_wmi.h @@ -269,6 +269,10 @@ int hypervImageManagementServiceGetVHDSD(hypervPrivate *priv, const char *vhdPath, WsXmlDocH *settingDataDoc); +int hypervGetSecuritySD(hypervPrivate *priv, + const char *vssd_instanceid, + Msvm_SecuritySettingData **data); + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Msvm_VirtualSystemManagementService */ diff --git a/src/hyperv/hyperv_wmi_generator.input b/src/hyperv/hyperv_wmi_generator.input index 017b7a0fa5..b3cd9d19fb 100644 --- a/src/hyperv/hyperv_wmi_generator.input +++ b/src/hyperv/hyperv_wmi_generator.input @@ -1252,3 +1252,12 @@ class Win32_DiskDrive uint64 TotalTracks uint32 TracksPerCylinder end + +class Msvm_SecuritySettingData + boolean TpmEnabled + boolean KsdEnabled + boolean ShieldingRequested + boolean DataProtectionRequested + boolean EncryptStateAndVmMigrationTraffic + boolean VirtualizationBasedSecurityOptOut +end -- 2.53.0
On 2/24/26 20:43, Jonathon Jongsma via Devel wrote:
Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> --- src/hyperv/hyperv_driver.c | 32 +++++++++++++++++++++++++++ src/hyperv/hyperv_wmi.c | 26 ++++++++++++++++++++++ src/hyperv/hyperv_wmi.h | 4 ++++ src/hyperv/hyperv_wmi_generator.input | 9 ++++++++ 4 files changed, 71 insertions(+)
diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index b01b4919fe..7cc67129cd 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -200,6 +200,22 @@ hypervGetOperatingSystem(hypervPrivate *priv, Win32_OperatingSystem **operatingS }
+static int +hypervDomainGetTPMEnabled(hypervPrivate *priv, + const char *id, + bool *enabled) +{ + g_autoptr(Msvm_SecuritySettingData) securitySD = NULL; + + if (hypervGetSecuritySD(priv, id, &securitySD) < 0) + return -1; + + VIR_DEBUG("Getting TPM state for '%s': %u", id, securitySD->data->TpmEnabled); + *enabled = securitySD->data->TpmEnabled; + return 0; +} + + static int hypervRequestStateChange(virDomainPtr domain, int state) { @@ -2651,6 +2667,7 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) g_autoptr(Msvm_SerialPortSettingData) spsd = NULL; Msvm_ResourceAllocationSettingData *serialDevices = NULL; g_autoptr(Msvm_EthernetPortAllocationSettingData) nets = NULL; + bool tpmEnabled = false;
virCheckFlags(VIR_DOMAIN_XML_COMMON_FLAGS, NULL);
@@ -2791,6 +2808,21 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) if (hypervDomainDefParseEthernet(domain, def, nets) < 0) return NULL;
+ if (hypervDomainGetTPMEnabled(priv, virtualSystemSettingData->data->InstanceID, &tpmEnabled) == 0 + && tpmEnabled) { + virDomainTPMDef* tpm = NULL; + + if (!def->tpms) { + def->tpms = g_new0(virDomainTPMDef *, 1); + } + + tpm = g_new0(virDomainTPMDef, 1); + tpm->model = VIR_DOMAIN_TPM_MODEL_DEFAULT;
The model is CRB in version 2. So this should be: tpm = g_new0(virDomainTPMDef, 1); tpm->model = VIR_DOMAIN_TPM_MODEL_CRB; tpm->type = VIR_DOMAIN_TPM_TYPE_EMULATOR; tpm->data.emulator.version = VIR_DOMAIN_TPM_VERSION_2_0;
+ tpm->type = VIR_DOMAIN_TPM_TYPE_EMULATOR; + + def->tpms[def->ntpms++] = tpm; + } + /* XXX xmlopts must be non-NULL */ return virDomainDefFormat(def, NULL, virDomainDefFormatConvertXMLFlags(flags)); } diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c index 7ae3afc40a..1cf442dad3 100644 --- a/src/hyperv/hyperv_wmi.c +++ b/src/hyperv/hyperv_wmi.c @@ -1625,3 +1625,29 @@ hypervMsvmVSMSModifyResourceSettings(hypervPrivate *priv,
return 0; } + + +int +hypervGetSecuritySD(hypervPrivate *priv, + const char *vssd_instanceid, + Msvm_SecuritySettingData **data) +{ + g_auto(virBuffer) query = VIR_BUFFER_INITIALIZER; + + virBufferEscapeSQL(&query, + "ASSOCIATORS OF {Msvm_VirtualSystemSettingData.InstanceID='%s'} " + "WHERE ResultClass = Msvm_SecuritySettingData", + vssd_instanceid);
AAAgrh. I was stuck on this for a week! The closest I get was: virBufferAsprintf(&query, "ASSOCIATORS OF {Msvm_VirtualSystemSettingData.InstanceID='%s'} " "WHERE AssocClass = Msvm_SecurityElementSettingData " "ResultClass = Msvm_SecuritySettingData", id); Which works flawlessly in PowerShell inside my Windows VM. But the moment I tried via wsman I got an empty answer. Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Michal
participants (2)
-
Jonathon Jongsma -
Michal Prívozník