On Thu, Jan 05, 2023 at 09:35:00 +0100, Michal Privoznik wrote:
Now that we have qemuMonitorGetCPUModelExpansion() aware of
Hyper-V Enlightenments, we can start querying it. Two conditions
need to be met:
1) KVM is in use,
2) Arch is either x86 or arm.
It may look like modifying the first call to
qemuMonitorGetCPUModelExpansion() inside of
virQEMUCapsProbeQMPHostCPU() would be sufficient but it is not.
We really need to ask QEMU for full expansion and the first call
does not guarantee that.
For the test data, I've just copied whatever
'query-cpu-model-expansion' returned earlier, therefore there are
no hv-* props. But that's okay - the full expansion is not stored
in cache (and thus not formatted in
tests/qemucapabilitiesdata/caps_*.replies files either). This is
purely runtime thing.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
[...]
diff --git a/src/qemu/qemu_capabilities.c
b/src/qemu/qemu_capabilities.c
index 4c75eea64e..93585f5af1 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
[...]
@@ -3029,6 +3036,66 @@ virQEMUCapsProbeCPUDefinitionsTest(virQEMUCaps
*qemuCaps,
}
+static int
+virQEMUCapsProbeHypervCapabilities(virQEMUCaps *qemuCaps,
+ qemuMonitorCPUModelInfo *fullQEMU)
+{
+ g_autofree virDomainCapsFeatureHyperv *hvcaps = NULL;
+ size_t i;
+
+ if (!fullQEMU)
+ return 0;
+
+ hvcaps = g_new0(virDomainCapsFeatureHyperv, 1);
+ hvcaps->features.report = true;
+
+ for (i = 0; i <fullQEMU->nprops; i++) {
Space after <
+ qemuMonitorCPUProperty prop = fullQEMU->props[i];
+ const char *name;
+ int hvprop;
+
+ if (!(name = STRSKIP(prop.name, "hv-")))
+ continue;
+
+ hvprop = virDomainHypervTypeFromString(name);
+
+ if (hvprop < 0) {
+ /* Some names are different. For instance QEMU reports hv-vendor-id
+ * but we have it as vendor_id (because of XML). Replace hyphens
+ * with underscores and try again. */
+ g_autofree char *underscoreName = NULL;
+
+ underscoreName = virStringReplace(name, "-", "_");
+
+ hvprop = virDomainHypervTypeFromString(underscoreName);
+ if (hvprop < 0) {
+ VIR_DEBUG("Not yet implement Hyper-V enlightenment: %s",
+ prop.name);
+ continue;
+ }
+ }
+
+ if ((prop.type == QEMU_MONITOR_CPU_PROPERTY_BOOLEAN &&
+ prop.value.boolean) ||
+ (prop.type == QEMU_MONITOR_CPU_PROPERTY_NUMBER &&
+ prop.value.number > 0) ||
+ (prop.type == QEMU_MONITOR_CPU_PROPERTY_STRING &&
+ prop.value.string))
+ VIR_DOMAIN_CAPS_ENUM_SET(hvcaps->features, hvprop);
+
+ }
+
+ if (hvcaps->features.values) {
+ hvcaps->supported = VIR_TRISTATE_BOOL_YES;
+ } else {
+ hvcaps->supported = VIR_TRISTATE_BOOL_NO;
After some testing with older qemus I've noticed that old qemu is
reporting an incomplete list of the hyperv features it supports. Thus
even with qemu-4.2 I get:
<hyperv supported='yes'>
<enum name='features'>
<value>spinlocks</value>
<value>vendor_id</value>
</enum>
</hyperv>
So I think the best course of actions will be to document that with
older qemus the list may be incomplete. The problem will fix itself once
we drop support for old qemus.
Still, if the data is not present we can't claim that hyperv is not
supported though, so the assignment below should be skipped in such
case.
+ }
+
+ qemuCaps->hypervCapabilities = g_steal_pointer(&hvcaps);
+ return 0;
+}
+
+
static int
virQEMUCapsProbeQMPHostCPU(virQEMUCaps *qemuCaps,
virQEMUCapsAccel *accel,
[...]
@@ -4848,6 +4977,33 @@ virQEMUCapsFormatSGXInfo(virQEMUCaps
*qemuCaps,
}
+static void
+virQEMUCapsFormatHypervCapabilities(virQEMUCaps *qemuCaps,
+ virBuffer *buf)
+{
+ virDomainCapsFeatureHyperv *hvcaps = qemuCaps->hypervCapabilities;
+ virBuffer attrBuf = VIR_BUFFER_INITIALIZER;
+ virBuffer childBuf = VIR_BUFFER_INIT_CHILD(buf);
g_auto()
+
+ virBufferAsprintf(&attrBuf, " supported='%s'",
+ virTristateBoolTypeToString(hvcaps->supported));
+
+ if (hvcaps->supported) {
+ size_t i;
+
+ for (i = 0; i < sizeof(hvcaps->features.values) * CHAR_BIT; i++) {
+ if (!(hvcaps->features.values & (1U << i)))
+ continue;
+
+ virBufferAsprintf(&childBuf, "<cap
name='%s'/>\n",
+ virDomainHypervTypeToString(i));
+ }
+ }
+
+ return virXMLFormatElement(buf, "hypervCapabilities", &attrBuf,
&childBuf);
+}
+
+
char *
virQEMUCapsFormatCache(virQEMUCaps *qemuCaps)
{
Reviewed-by: Peter Krempa <pkrempa(a)redhat.com>