import OL libvirt-10.10.0-15.4.0.1.el9_7

This commit is contained in:
eabdullin 2025-12-22 06:34:37 +00:00
parent 6cd0995b61
commit 3c0c8e1218
32 changed files with 4362 additions and 2 deletions

View File

@ -0,0 +1,35 @@
From 9e481e4b77d05a8951845272ec4ee51013b245ee Mon Sep 17 00:00:00 2001
Message-ID: <9e481e4b77d05a8951845272ec4ee51013b245ee.1763133104.git.jdenemar@redhat.com>
From: Martin Kletzander <mkletzan@redhat.com>
Date: Fri, 10 Jan 2025 15:56:34 +0100
Subject: [PATCH] conf: Do not parse hyperv features with passthrough mode
The schema does not allow that anyway and we then format them all back
which leads to libvirt producing an invalid XML.
Resolves: https://issues.redhat.com/browse/RHEL-70656
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit a4def2eb9597b83c7c6a4b9f8b08c995cbf7ee1a)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/conf/domain_conf.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 38179a7e59..8c69feda6e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -16735,6 +16735,9 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
def->features[VIR_DOMAIN_FEATURE_HYPERV] = mode;
+ if (mode == VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH)
+ return 0;
+
node = xmlFirstElementChild(node);
while (node != NULL) {
int feature;
--
2.51.1

View File

@ -0,0 +1,251 @@
From d90f7c57e9cd6a146788726a5a0d1c6ba3de4a19 Mon Sep 17 00:00:00 2001
Message-ID: <d90f7c57e9cd6a146788726a5a0d1c6ba3de4a19.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 29 Sep 2025 10:20:41 +0200
Subject: [PATCH] conf: Introduce hyperv host-model mode
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
So far we have two modes for hyperv features:
1) custom, where users have to enable features explicitly, and
2) passthrough, where hypervisor enables features automagically.
Problem with 'custom' mode is that some features are not plain
on/off switches but expect int/string value. Until very recently,
these were not reported in domcaps. And even if they were it's a
bit cumbersome.
Problem with 'passthrough' mode is that users don't get to see
the expanded list of enlightenments enabled.
Therefore, mimic what we're already doing with CPUs: have
'host-model' which gets expanded at domain startup and is fixed
throughout domain's run.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit c181c7dd1358ee1a2d125a869a44f46eee393452)
Conflicts:
src/libxl/libxl_conf.c: Not enabled in RHEL, so nobody cares.
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
docs/formatdomain.rst | 6 ++++
src/conf/domain_conf.c | 4 ++-
src/conf/domain_conf.h | 1 +
src/conf/schemas/domaincommon.rng | 3 ++
src/qemu/qemu_command.c | 1 +
.../hyperv-host-model.x86_64-latest.args | 32 ++++++++++++++++++
.../hyperv-host-model.x86_64-latest.xml | 33 +++++++++++++++++++
tests/qemuxmlconfdata/hyperv-host-model.xml | 27 +++++++++++++++
tests/qemuxmlconftest.c | 1 +
9 files changed, 107 insertions(+), 1 deletion(-)
create mode 100644 tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
create mode 100644 tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml
create mode 100644 tests/qemuxmlconfdata/hyperv-host-model.xml
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index bfe28759e7..3dba9e3073 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -2126,6 +2126,12 @@ are:
virtual CPU may or may not contain features which may block migration
even to an identical host.
+ ``host-model``
+ Similar to the ``passthrough`` mode, except libvirt detects which
+ enlightenments are supported by hypervisor and expands them on domain
+ startup into the live XML. In a sense, this is similar to ``host-model``
+ CPU mode (See `CPU model and topology`_). :since:`Since 11.9.0`
+
The ``mode`` attribute can be omitted and will default to ``custom``.
``pvspinlock``
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 67f8ef4676..b869ac885b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -145,6 +145,7 @@ VIR_ENUM_IMPL(virDomainHyperVMode,
"none",
"custom",
"passthrough",
+ "host-model",
);
VIR_ENUM_IMPL(virDomainBoot,
@@ -16742,7 +16743,8 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
def->features[VIR_DOMAIN_FEATURE_HYPERV] = mode;
- if (mode == VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH)
+ if (mode == VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH ||
+ mode == VIR_DOMAIN_HYPERV_MODE_HOST_MODEL)
return 0;
node = xmlFirstElementChild(node);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 643deefec2..abb50dd5cf 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -164,6 +164,7 @@ typedef enum {
VIR_DOMAIN_HYPERV_MODE_NONE = 0,
VIR_DOMAIN_HYPERV_MODE_CUSTOM,
VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH,
+ VIR_DOMAIN_HYPERV_MODE_HOST_MODEL,
VIR_DOMAIN_HYPERV_MODE_LAST
} virDomainHyperVMode;
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 93bc128dec..58dbe478af 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -8038,6 +8038,9 @@
<attribute name="mode">
<value>passthrough</value>
</attribute>
+ <attribute name="mode">
+ <value>host-model</value>
+ </attribute>
<group>
<optional>
<attribute name="mode">
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 3f290931a1..61aeb14757 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6289,6 +6289,7 @@ qemuBuildCpuHypervCommandLine(virBuffer *buf,
switch ((virDomainHyperVMode) def->features[VIR_DOMAIN_FEATURE_HYPERV]) {
case VIR_DOMAIN_HYPERV_MODE_CUSTOM:
+ case VIR_DOMAIN_HYPERV_MODE_HOST_MODEL:
break;
case VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH:
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
new file mode 100644
index 0000000000..2ed72fcd1b
--- /dev/null
+++ b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
@@ -0,0 +1,32 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
+-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=on \
+-accel tcg \
+-cpu qemu64 \
+-m size=219136k \
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
+-overcommit mem-lock=off \
+-smp 6,sockets=6,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml
new file mode 100644
index 0000000000..453a43b3c9
--- /dev/null
+++ b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml
@@ -0,0 +1,33 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>6</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <features>
+ <acpi/>
+ <hyperv mode='host-model'/>
+ </features>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='usb' index='0' model='piix3-uhci'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.xml b/tests/qemuxmlconfdata/hyperv-host-model.xml
new file mode 100644
index 0000000000..fae00d86dd
--- /dev/null
+++ b/tests/qemuxmlconfdata/hyperv-host-model.xml
@@ -0,0 +1,27 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>6</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <features>
+ <acpi/>
+ <hyperv mode='host-model'/>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='usb' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 5683e76599..009849950a 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -1507,6 +1507,7 @@ mymain(void)
DO_TEST_CAPS_VER("hyperv-passthrough", "6.1.0");
DO_TEST_CAPS_LATEST("hyperv-passthrough");
DO_TEST_CAPS_LATEST("hyperv-stimer-direct");
+ DO_TEST_CAPS_LATEST("hyperv-host-model");
DO_TEST_CAPS_LATEST("kvm-features");
DO_TEST_CAPS_LATEST("kvm-features-off");
--
2.51.1

View File

@ -0,0 +1,79 @@
From 44eca2ab460f77453733a0c3403ba440f8ecec9c Mon Sep 17 00:00:00 2001
Message-ID: <44eca2ab460f77453733a0c3403ba440f8ecec9c.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 7 Oct 2025 13:42:03 +0200
Subject: [PATCH] conf: Introduce virDomainDefHasTimer()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is a simple helper to tell whether domain definition has
certain type of timer or not.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 359909749ae9af9d23a916b9906e97d69945fc81)
Conflicts:
- src/conf/domain_conf.h:
- src/libvirt_private.syms: Both context.
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/conf/domain_conf.c | 17 +++++++++++++++++
src/conf/domain_conf.h | 4 ++++
src/libvirt_private.syms | 1 +
3 files changed, 22 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 8c69feda6e..7fd5f76fb6 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -31927,3 +31927,20 @@ virDomainWatchdogDefFind(const virDomainDef *def,
return -1;
}
+
+
+bool
+virDomainDefHasTimer(const virDomainDef *def,
+ virDomainTimerNameType name)
+{
+ size_t i;
+
+ for (i = 0; i < def->clock.ntimers; i++) {
+ if (def->clock.timers[i]->name == name &&
+ def->clock.timers[i]->present == VIR_TRISTATE_BOOL_YES) {
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 15aacc71c1..24a1089552 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -4641,3 +4641,7 @@ virDomainObjGetMessages(virDomainObj *vm,
bool
virDomainDefHasSpiceGraphics(const virDomainDef *def);
+
+bool
+virDomainDefHasTimer(const virDomainDef *def,
+ virDomainTimerNameType name);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index be313ad67b..0a1235e6d8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -344,6 +344,7 @@ virDomainDefHasOldStyleROUEFI;
virDomainDefHasOldStyleUEFI;
virDomainDefHasPCIHostdev;
virDomainDefHasSpiceGraphics;
+virDomainDefHasTimer;
virDomainDefHasUSB;
virDomainDefHasVcpusOffline;
virDomainDefHasVDPANet;
--
2.51.1

View File

@ -0,0 +1,439 @@
From 99abc9c66f605ca907a6291dd1918ec7112db18c Mon Sep 17 00:00:00 2001
Message-ID: <99abc9c66f605ca907a6291dd1918ec7112db18c.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 30 Sep 2025 10:27:27 +0200
Subject: [PATCH] conf: More hyperv related members into a single struct
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
So far, we have an array of integers (hyperv_features), an uint
(hyperv_spinlocks), a string (hyperv_vendor_id) and some tristate
switches scattered across virDomainDef. Soon, new knobs will be
introduced and keeping the current state would only worsen
readability.
Introduce virDomainHypervFeatures struct to place hyperv related
features there.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 47271c204e5471f1cbd22cf34c0166455affc095)
Conflicts:
- src/libxl/libxl_conf.c: Original commit changed this file, but
because 064682ab330535bb1559045b5900398ae7a8d91d is not
backported, then the change doesn't make sense. The libxl
driver is not enabled in RHEL anyway.
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/conf/domain_conf.c | 77 ++++++++++++++++++++++------------------
src/conf/domain_conf.h | 15 ++++----
src/conf/virconftypes.h | 2 ++
src/qemu/qemu_command.c | 16 ++++-----
src/qemu/qemu_process.c | 8 ++---
src/qemu/qemu_validate.c | 12 +++----
6 files changed, 71 insertions(+), 59 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f02efaca4e..67f8ef4676 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3949,6 +3949,13 @@ virDomainOSDefClear(virDomainOSDef *os)
}
+static void
+virDomainHypervFeaturesClear(virDomainHypervFeatures *hv)
+{
+ g_free(hv->vendor_id);
+}
+
+
void virDomainDefFree(virDomainDef *def)
{
size_t i;
@@ -4076,8 +4083,8 @@ void virDomainDefFree(virDomainDef *def)
g_free(def->emulator);
g_free(def->description);
g_free(def->title);
+ virDomainHypervFeaturesClear(&def->hyperv);
g_free(def->kvm_features);
- g_free(def->hyperv_vendor_id);
g_free(def->tcg_features);
virBlkioDeviceArrayClear(def->blkio.devices,
@@ -16756,7 +16763,7 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
&value) < 0)
return -1;
- def->hyperv_features[feature] = value;
+ def->hyperv.features[feature] = value;
switch ((virDomainHyperv) feature) {
case VIR_DOMAIN_HYPERV_RELAXED:
@@ -16782,11 +16789,11 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
while (child) {
if (STREQ((const char *)child->name, "direct")) {
if (virXMLPropTristateSwitch(child, "state", VIR_XML_PROP_REQUIRED,
- &def->hyperv_tlbflush_direct) < 0)
+ &def->hyperv.tlbflush_direct) < 0)
return -1;
} else if (STREQ((const char *)child->name, "extended")) {
if (virXMLPropTristateSwitch(child, "state", VIR_XML_PROP_REQUIRED,
- &def->hyperv_tlbflush_extended) < 0)
+ &def->hyperv.tlbflush_extended) < 0)
return -1;
} else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -16813,7 +16820,7 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
}
if (virXMLPropTristateSwitch(child, "state", VIR_XML_PROP_REQUIRED,
- &def->hyperv_stimer_direct) < 0)
+ &def->hyperv.stimer_direct) < 0)
return -1;
child = xmlNextElementSibling(child);
@@ -16825,10 +16832,10 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
break;
if (virXMLPropUInt(node, "retries", 0, VIR_XML_PROP_REQUIRED,
- &def->hyperv_spinlocks) < 0)
+ &def->hyperv.spinlocks) < 0)
return -1;
- if (def->hyperv_spinlocks < 0xFFF) {
+ if (def->hyperv.spinlocks < 0xFFF) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("HyperV spinlock retry count must be at least 4095"));
return -1;
@@ -16839,15 +16846,15 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
if (value != VIR_TRISTATE_SWITCH_ON)
break;
- g_clear_pointer(&def->hyperv_vendor_id, g_free);
+ g_clear_pointer(&def->hyperv.vendor_id, g_free);
- if (!(def->hyperv_vendor_id = virXMLPropString(node, "value"))) {
+ if (!(def->hyperv.vendor_id = virXMLPropString(node, "value"))) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("missing 'value' attribute for HyperV feature 'vendor_id'"));
return -1;
}
- if (!STRLIM(def->hyperv_vendor_id, VIR_DOMAIN_HYPERV_VENDOR_ID_MAX)) {
+ if (!STRLIM(def->hyperv.vendor_id, VIR_DOMAIN_HYPERV_VENDOR_ID_MAX)) {
virReportError(VIR_ERR_XML_ERROR,
_("HyperV vendor_id value must not be more than %1$d characters."),
VIR_DOMAIN_HYPERV_VENDOR_ID_MAX);
@@ -16855,7 +16862,7 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
}
/* ensure that the string can be passed to qemu */
- if (strchr(def->hyperv_vendor_id, ',')) {
+ if (strchr(def->hyperv.vendor_id, ',')) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("HyperV vendor_id value is invalid"));
return -1;
@@ -21296,12 +21303,12 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
case VIR_DOMAIN_HYPERV_AVIC:
case VIR_DOMAIN_HYPERV_EMSR_BITMAP:
case VIR_DOMAIN_HYPERV_XMM_INPUT:
- if (src->hyperv_features[i] != dst->hyperv_features[i]) {
+ if (src->hyperv.features[i] != dst->hyperv.features[i]) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("State of HyperV enlightenment feature '%1$s' differs: source: '%2$s', destination: '%3$s'"),
virDomainHypervTypeToString(i),
- virTristateSwitchTypeToString(src->hyperv_features[i]),
- virTristateSwitchTypeToString(dst->hyperv_features[i]));
+ virTristateSwitchTypeToString(src->hyperv.features[i]),
+ virTristateSwitchTypeToString(dst->hyperv.features[i]));
return false;
}
@@ -21309,21 +21316,21 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
case VIR_DOMAIN_HYPERV_SPINLOCKS:
/* spinlock count matters! */
- if (src->hyperv_spinlocks != dst->hyperv_spinlocks) {
+ if (src->hyperv.spinlocks != dst->hyperv.spinlocks) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("HyperV spinlock retry count differs: source: '%1$u', destination: '%2$u'"),
- src->hyperv_spinlocks,
- dst->hyperv_spinlocks);
+ src->hyperv.spinlocks,
+ dst->hyperv.spinlocks);
return false;
}
break;
case VIR_DOMAIN_HYPERV_VENDOR_ID:
- if (STRNEQ_NULLABLE(src->hyperv_vendor_id, dst->hyperv_vendor_id)) {
+ if (STRNEQ_NULLABLE(src->hyperv.vendor_id, dst->hyperv.vendor_id)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("HyperV vendor_id differs: source: '%1$s', destination: '%2$s'"),
- src->hyperv_vendor_id,
- dst->hyperv_vendor_id);
+ src->hyperv.vendor_id,
+ dst->hyperv.vendor_id);
return false;
}
break;
@@ -21334,12 +21341,12 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
}
}
- if (src->hyperv_features[VIR_DOMAIN_HYPERV_STIMER] == VIR_TRISTATE_SWITCH_ON) {
- if (src->hyperv_stimer_direct != dst->hyperv_stimer_direct) {
+ if (src->hyperv.features[VIR_DOMAIN_HYPERV_STIMER] == VIR_TRISTATE_SWITCH_ON) {
+ if (src->hyperv.stimer_direct != dst->hyperv.stimer_direct) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("State of HyperV stimer direct feature differs: source: '%1$s', destination: '%2$s'"),
- virTristateSwitchTypeToString(src->hyperv_stimer_direct),
- virTristateSwitchTypeToString(dst->hyperv_stimer_direct));
+ virTristateSwitchTypeToString(src->hyperv.stimer_direct),
+ virTristateSwitchTypeToString(dst->hyperv.stimer_direct));
return false;
}
}
@@ -28040,11 +28047,11 @@ virDomainFeaturesHyperVDefFormat(virBuffer *buf,
g_auto(virBuffer) hypervAttrBuf = VIR_BUFFER_INITIALIZER;
g_auto(virBuffer) hypervChildBuf = VIR_BUFFER_INIT_CHILD(&childBuf);
- if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ABSENT)
+ if (def->hyperv.features[j] == VIR_TRISTATE_SWITCH_ABSENT)
continue;
virBufferAsprintf(&hypervAttrBuf, " state='%s'",
- virTristateSwitchTypeToString(def->hyperv_features[j]));
+ virTristateSwitchTypeToString(def->hyperv.features[j]));
switch ((virDomainHyperv) j) {
case VIR_DOMAIN_HYPERV_RELAXED:
@@ -28063,34 +28070,34 @@ virDomainFeaturesHyperVDefFormat(virBuffer *buf,
break;
case VIR_DOMAIN_HYPERV_SPINLOCKS:
- if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.features[j] == VIR_TRISTATE_SWITCH_ON) {
virBufferAsprintf(&hypervAttrBuf,
- " retries='%d'", def->hyperv_spinlocks);
+ " retries='%d'", def->hyperv.spinlocks);
}
break;
case VIR_DOMAIN_HYPERV_STIMER:
- if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON &&
- def->hyperv_stimer_direct == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.features[j] == VIR_TRISTATE_SWITCH_ON &&
+ def->hyperv.stimer_direct == VIR_TRISTATE_SWITCH_ON) {
virBufferAddLit(&hypervChildBuf, "<direct state='on'/>\n");
}
break;
case VIR_DOMAIN_HYPERV_VENDOR_ID:
- if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.features[j] == VIR_TRISTATE_SWITCH_ON) {
virBufferEscapeString(&hypervAttrBuf, " value='%s'",
- def->hyperv_vendor_id);
+ def->hyperv.vendor_id);
}
break;
case VIR_DOMAIN_HYPERV_TLBFLUSH:
- if (def->hyperv_features[j] != VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.features[j] != VIR_TRISTATE_SWITCH_ON)
break;
- if (def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.tlbflush_direct == VIR_TRISTATE_SWITCH_ON)
virBufferAddLit(&hypervChildBuf, "<direct state='on'/>\n");
- if (def->hyperv_tlbflush_extended == VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.tlbflush_extended == VIR_TRISTATE_SWITCH_ON)
virBufferAddLit(&hypervChildBuf, "<extended state='on'/>\n");
break;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 24a1089552..643deefec2 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3080,6 +3080,14 @@ struct _virDomainPstoreDef {
virDomainDeviceInfo info;
};
+struct _virDomainHypervFeatures {
+ int features[VIR_DOMAIN_HYPERV_LAST];
+ unsigned int spinlocks;
+ virTristateSwitch stimer_direct;
+ virTristateSwitch tlbflush_direct;
+ virTristateSwitch tlbflush_extended;
+ char *vendor_id;
+};
#define SCSI_SUPER_WIDE_BUS_MAX_CONT_UNIT 64
#define SCSI_WIDE_BUS_MAX_CONT_UNIT 16
@@ -3147,19 +3155,14 @@ struct _virDomainDef {
* See virDomainDefFeaturesCheckABIStability() for details. */
int features[VIR_DOMAIN_FEATURE_LAST];
int caps_features[VIR_DOMAIN_PROCES_CAPS_FEATURE_LAST];
- int hyperv_features[VIR_DOMAIN_HYPERV_LAST];
+ virDomainHypervFeatures hyperv;
virDomainFeatureKVM *kvm_features;
int msrs_features[VIR_DOMAIN_MSRS_LAST];
int xen_features[VIR_DOMAIN_XEN_LAST];
virDomainXenPassthroughMode xen_passthrough_mode;
- unsigned int hyperv_spinlocks;
- virTristateSwitch hyperv_stimer_direct;
- virTristateSwitch hyperv_tlbflush_direct;
- virTristateSwitch hyperv_tlbflush_extended;
virGICVersion gic_version;
virDomainHPTResizing hpt_resizing;
unsigned long long hpt_maxpagesize; /* Stored in KiB */
- char *hyperv_vendor_id;
virTristateSwitch apic_eoi;
virDomainFeatureTCG *tcg_features;
diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h
index d46da4bdda..e93d260d37 100644
--- a/src/conf/virconftypes.h
+++ b/src/conf/virconftypes.h
@@ -138,6 +138,8 @@ typedef struct _virDomainHubDef virDomainHubDef;
typedef struct _virDomainHugePage virDomainHugePage;
+typedef struct _virDomainHypervFeatures virDomainHypervFeatures;
+
typedef struct _virDomainIOMMUDef virDomainIOMMUDef;
typedef struct _virDomainIOThreadIDDef virDomainIOThreadIDDef;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 13e23c7ee3..3f290931a1 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6320,7 +6320,7 @@ qemuBuildCpuHypervCommandLine(virBuffer *buf,
case VIR_DOMAIN_HYPERV_AVIC:
case VIR_DOMAIN_HYPERV_EMSR_BITMAP:
case VIR_DOMAIN_HYPERV_XMM_INPUT:
- if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.features[i] == VIR_TRISTATE_SWITCH_ON) {
const char *name = virDomainHypervTypeToString(i);
g_autofree char *full_name = g_strdup_printf("hv-%s", name);
const char *qemu_name = virQEMUCapsCPUFeatureToQEMU(def->os.arch,
@@ -6328,27 +6328,27 @@ qemuBuildCpuHypervCommandLine(virBuffer *buf,
virBufferAsprintf(buf, ",%s=on", qemu_name);
}
if ((i == VIR_DOMAIN_HYPERV_STIMER) &&
- (def->hyperv_stimer_direct == VIR_TRISTATE_SWITCH_ON))
+ (def->hyperv.stimer_direct == VIR_TRISTATE_SWITCH_ON))
virBufferAsprintf(buf, ",%s=on", VIR_CPU_x86_HV_STIMER_DIRECT);
if (i == VIR_DOMAIN_HYPERV_TLBFLUSH) {
- if (def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.tlbflush_direct == VIR_TRISTATE_SWITCH_ON)
virBufferAsprintf(buf, ",%s=on", VIR_CPU_x86_HV_TLBFLUSH_DIRECT);
- if (def->hyperv_tlbflush_extended == VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.tlbflush_extended == VIR_TRISTATE_SWITCH_ON)
virBufferAsprintf(buf, ",%s=on", VIR_CPU_x86_HV_TLBFLUSH_EXT);
}
break;
case VIR_DOMAIN_HYPERV_SPINLOCKS:
- if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.features[i] == VIR_TRISTATE_SWITCH_ON)
virBufferAsprintf(buf, ",%s=0x%x",
VIR_CPU_x86_HV_SPINLOCKS,
- def->hyperv_spinlocks);
+ def->hyperv.spinlocks);
break;
case VIR_DOMAIN_HYPERV_VENDOR_ID:
- if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.features[i] == VIR_TRISTATE_SWITCH_ON)
virBufferAsprintf(buf, ",hv-vendor-id=%s",
- def->hyperv_vendor_id);
+ def->hyperv.vendor_id);
break;
case VIR_DOMAIN_HYPERV_LAST:
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 7b6c02bc27..798dabaf0a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4381,7 +4381,7 @@ qemuProcessVerifyHypervFeatures(virDomainDef *def,
i == VIR_DOMAIN_HYPERV_SPINLOCKS)
continue;
- if (def->hyperv_features[i] != VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.features[i] != VIR_TRISTATE_SWITCH_ON)
continue;
cpuFeature = g_strdup_printf("hv-%s", virDomainHypervTypeToString(i));
@@ -4392,7 +4392,7 @@ qemuProcessVerifyHypervFeatures(virDomainDef *def,
return -1;
} else if (rc == 1) {
if (i == VIR_DOMAIN_HYPERV_STIMER) {
- if (def->hyperv_stimer_direct != VIR_TRISTATE_SWITCH_ON)
+ if (def->hyperv.stimer_direct != VIR_TRISTATE_SWITCH_ON)
continue;
rc = virCPUDataCheckFeature(cpu, VIR_CPU_x86_HV_STIMER_DIRECT);
@@ -4407,7 +4407,7 @@ qemuProcessVerifyHypervFeatures(virDomainDef *def,
return -1;
}
if (i == VIR_DOMAIN_HYPERV_TLBFLUSH) {
- if (def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.tlbflush_direct == VIR_TRISTATE_SWITCH_ON) {
rc = virCPUDataCheckFeature(cpu, VIR_CPU_x86_HV_TLBFLUSH_DIRECT);
if (rc < 0)
return -1;
@@ -4418,7 +4418,7 @@ qemuProcessVerifyHypervFeatures(virDomainDef *def,
return -1;
}
}
- if (def->hyperv_tlbflush_extended == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.tlbflush_extended == VIR_TRISTATE_SWITCH_ON) {
rc = virCPUDataCheckFeature(cpu, VIR_CPU_x86_HV_TLBFLUSH_EXT);
if (rc < 0)
return -1;
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 22565d9e36..ed769efc7c 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -89,8 +89,8 @@ qemuValidateDomainDefPSeriesFeature(const virDomainDef *def,
#define CHECK_HV_FEAT(feat, requires) \
- if (def->hyperv_features[feat] == VIR_TRISTATE_SWITCH_ON && \
- def->hyperv_features[requires] != VIR_TRISTATE_SWITCH_ON) { \
+ if (def->hyperv.features[feat] == VIR_TRISTATE_SWITCH_ON && \
+ def->hyperv.features[requires] != VIR_TRISTATE_SWITCH_ON) { \
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \
_("'%1$s' hyperv feature requires '%2$s' feature"), \
virDomainHypervTypeToString(feat), \
@@ -114,7 +114,7 @@ qemuValidateDomainDefHypervFeatures(const virDomainDef *def)
CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_SYNIC, VIR_DOMAIN_HYPERV_VPINDEX);
- if (def->hyperv_features[VIR_DOMAIN_HYPERV_STIMER] == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.features[VIR_DOMAIN_HYPERV_STIMER] == VIR_TRISTATE_SWITCH_ON) {
if (!virDomainDefHasTimer(def, VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("'%1$s' hyperv feature requires '%2$s' timer"),
@@ -133,9 +133,9 @@ qemuValidateDomainDefHypervFeatures(const virDomainDef *def)
CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_EVMCS, VIR_DOMAIN_HYPERV_VAPIC);
- if (def->hyperv_features[VIR_DOMAIN_HYPERV_TLBFLUSH] == VIR_TRISTATE_SWITCH_ON &&
- def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON) {
- if (def->hyperv_features[VIR_DOMAIN_HYPERV_VAPIC] != VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.features[VIR_DOMAIN_HYPERV_TLBFLUSH] == VIR_TRISTATE_SWITCH_ON &&
+ def->hyperv.tlbflush_direct == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv.features[VIR_DOMAIN_HYPERV_VAPIC] != VIR_TRISTATE_SWITCH_ON) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("'%1$s' hyperv feature requires '%2$s' feature"),
VIR_CPU_x86_HV_TLBFLUSH_DIRECT,
--
2.51.1

View File

@ -0,0 +1,285 @@
From 7dc415a0708f4389bfb470c36cfaa3886882419f Mon Sep 17 00:00:00 2001
Message-ID: <7dc415a0708f4389bfb470c36cfaa3886882419f.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 30 Sep 2025 15:05:10 +0200
Subject: [PATCH] conf: Report default hyperv values in domain capabilities
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
So far the set of available Hyper-V enlightenments are reported
in domain capabilities. Well, some enlightenments are more than
just simple on/off switch. For instance, the 'spinlocks'
enlightenment expects a number, or 'vendor_id' expects a string.
All of these have some default values (at least in QEMU) and are
used when the passthrough mode is set.
Allow querying these defaults in domain capabilities XML.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 57d2f4a0f0cbdb8006e99a3271bf363582843e91)
Conflicts:
- src/qemu/qemu_capabilities.c: Since
48f04627c8faf505a98e07e542729c135a615dcc is not backported yet,
the original code had g_memdup() but the bacported patch
expected g_memdup2().
Additionally, virDomainCapsFeatureHypervCopy() inside of
domain_capabilities.c had to be changed to use g_memdup() since
g_memdup2() wasn't introduced until glib-2.68.
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
docs/formatdomaincaps.rst | 5 ++-
src/conf/domain_capabilities.c | 61 ++++++++++++++++++++++++++++++++-
src/conf/domain_capabilities.h | 11 ++++++
src/conf/schemas/domaincaps.rng | 29 ++++++++++++++++
src/libvirt_private.syms | 2 ++
src/qemu/qemu_capabilities.c | 12 +++----
6 files changed, 111 insertions(+), 9 deletions(-)
diff --git a/docs/formatdomaincaps.rst b/docs/formatdomaincaps.rst
index 664194b16d..aee0af1045 100644
--- a/docs/formatdomaincaps.rst
+++ b/docs/formatdomaincaps.rst
@@ -869,7 +869,10 @@ Hyper-V Enlightenments
Report which features improving behavior of guests running Microsoft Windows
are supported. The ``features`` enum corresponds to the ``<hyperv/>`` element
(well, its children) as documented in `Hypervisor features
-<formatdomain.html#hypervisor-features>`__.
+<formatdomain.html#hypervisor-features>`__. The ``defaults`` element then
+contains child elements describing default values as reported by hypervisor,
+e.h. whether direct or extended TLB flushes are available. :since:`(since
+11.9.0)`
Please note that depending on the QEMU version some capabilities might be
missing even though QEMU does support them. This is because prior to QEMU-6.1.0
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
index b8f17e6d2f..5f1e1e7100 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -91,6 +91,32 @@ virSGXCapabilitiesFree(virSGXCapability *cap)
}
+void
+virDomainCapsFeatureHypervFree(virDomainCapsFeatureHyperv *cap)
+{
+ if (!cap)
+ return;
+
+ g_free(cap->vendor_id);
+ g_free(cap);
+}
+
+
+virDomainCapsFeatureHyperv *
+virDomainCapsFeatureHypervCopy(virDomainCapsFeatureHyperv *cap)
+{
+ virDomainCapsFeatureHyperv *ret = NULL;
+
+ if (!cap)
+ return NULL;
+
+ ret = g_memdup(cap, sizeof(virDomainCapsFeatureHyperv));
+ ret->vendor_id = g_strdup(cap->vendor_id);
+
+ return ret;
+}
+
+
static void
virDomainCapsDispose(void *obj)
{
@@ -104,7 +130,7 @@ virDomainCapsDispose(void *obj)
virCPUDefFree(caps->cpu.hostModel);
virSEVCapabilitiesFree(caps->sev);
virSGXCapabilitiesFree(caps->sgx);
- g_free(caps->hyperv);
+ virDomainCapsFeatureHypervFree(caps->hyperv);
values = &caps->os.loader.values;
for (i = 0; i < values->nvalues; i++)
@@ -779,6 +805,8 @@ static void
virDomainCapsFeatureHypervFormat(virBuffer *buf,
const virDomainCapsFeatureHyperv *hyperv)
{
+ virBuffer defaults = VIR_BUFFER_INIT_CHILD(buf);
+
if (!hyperv)
return;
@@ -786,6 +814,37 @@ virDomainCapsFeatureHypervFormat(virBuffer *buf,
ENUM_PROCESS(hyperv, features, virDomainHypervTypeToString);
+ virBufferAdjustIndent(&defaults, 2);
+
+ if (VIR_DOMAIN_CAPS_ENUM_IS_SET(hyperv->features, VIR_DOMAIN_HYPERV_SPINLOCKS) &&
+ hyperv->spinlocks != 0) {
+ virBufferAsprintf(&defaults, "<spinlocks>%u</spinlocks>\n", hyperv->spinlocks);
+ }
+
+ if (VIR_DOMAIN_CAPS_ENUM_IS_SET(hyperv->features, VIR_DOMAIN_HYPERV_STIMER) &&
+ hyperv->stimer_direct != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(&defaults, "<stimer_direct>%s</stimer_direct>\n",
+ virTristateSwitchTypeToString(hyperv->stimer_direct));
+ }
+
+ if (VIR_DOMAIN_CAPS_ENUM_IS_SET(hyperv->features, VIR_DOMAIN_HYPERV_TLBFLUSH)) {
+ if (hyperv->tlbflush_direct != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(&defaults, "<tlbflush_direct>%s</tlbflush_direct>\n",
+ virTristateSwitchTypeToString(hyperv->tlbflush_direct));
+ }
+
+ if (hyperv->tlbflush_extended != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(&defaults, "<tlbflush_extended>%s</tlbflush_extended>\n",
+ virTristateSwitchTypeToString(hyperv->tlbflush_extended));
+ }
+ }
+
+ if (VIR_DOMAIN_CAPS_ENUM_IS_SET(hyperv->features, VIR_DOMAIN_HYPERV_VENDOR_ID)) {
+ virBufferEscapeString(&defaults, "<vendor_id>%s</vendor_id>\n", hyperv->vendor_id);
+ }
+
+ virXMLFormatElement(buf, "defaults", NULL, &defaults);
+
FORMAT_EPILOGUE(hyperv);
}
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
index eacbd6b6b3..5421c8cfce 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -163,6 +163,11 @@ typedef struct _virDomainCapsFeatureHyperv virDomainCapsFeatureHyperv;
struct _virDomainCapsFeatureHyperv {
virTristateBool supported;
virDomainCapsEnum features; /* Info about supported virDomainHyperv features */
+ unsigned int spinlocks;
+ virTristateSwitch stimer_direct;
+ virTristateSwitch tlbflush_direct;
+ virTristateSwitch tlbflush_extended;
+ char *vendor_id;
};
STATIC_ASSERT_ENUM(VIR_DOMAIN_LAUNCH_SECURITY_LAST);
@@ -370,3 +375,9 @@ void
virSGXCapabilitiesFree(virSGXCapability *capabilities);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virSGXCapability, virSGXCapabilitiesFree);
+
+void virDomainCapsFeatureHypervFree(virDomainCapsFeatureHyperv *capabilities);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainCapsFeatureHyperv, virDomainCapsFeatureHypervFree);
+
+virDomainCapsFeatureHyperv *
+virDomainCapsFeatureHypervCopy(virDomainCapsFeatureHyperv *cap);
diff --git a/src/conf/schemas/domaincaps.rng b/src/conf/schemas/domaincaps.rng
index 850e7d63a0..9e1a80e22e 100644
--- a/src/conf/schemas/domaincaps.rng
+++ b/src/conf/schemas/domaincaps.rng
@@ -494,6 +494,35 @@
<element name="hyperv">
<ref name="supported"/>
<ref name="enum"/>
+ <optional>
+ <element name="defaults">
+ <optional>
+ <element name="spinlocks">
+ <ref name="unsignedInt"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="stimer_direct">
+ <ref name="virOnOff"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="tlbflush_direct">
+ <ref name="virOnOff"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="tlbflush_extended">
+ <ref name="virOnOff"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="vendor_id">
+ <text/>
+ </element>
+ </optional>
+ </element>
+ </optional>
</element>
</define>
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index bbe1e252af..d609064a19 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -217,6 +217,8 @@ virDomainCapsCPUUsableTypeFromString;
virDomainCapsCPUUsableTypeToString;
virDomainCapsEnumClear;
virDomainCapsEnumSet;
+virDomainCapsFeatureHypervCopy;
+virDomainCapsFeatureHypervFree;
virDomainCapsFormat;
virDomainCapsNew;
virSEVCapabilitiesFree;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 28d3a78d8c..b54bcbd527 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2051,8 +2051,7 @@ virQEMUCaps *virQEMUCapsNewCopy(virQEMUCaps *qemuCaps)
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SGX_EPC))
virQEMUCapsSGXInfoCopy(&ret->sgxCapabilities, qemuCaps->sgxCapabilities);
- ret->hypervCapabilities = g_memdup(qemuCaps->hypervCapabilities,
- sizeof(virDomainCapsFeatureHyperv));
+ ret->hypervCapabilities = virDomainCapsFeatureHypervCopy(qemuCaps->hypervCapabilities);
return g_steal_pointer(&ret);
}
@@ -2094,7 +2093,7 @@ void virQEMUCapsDispose(void *obj)
virSEVCapabilitiesFree(qemuCaps->sevCapabilities);
virSGXCapabilitiesFree(qemuCaps->sgxCapabilities);
- g_free(qemuCaps->hypervCapabilities);
+ virDomainCapsFeatureHypervFree(qemuCaps->hypervCapabilities);
virQEMUCapsAccelClear(&qemuCaps->kvm);
virQEMUCapsAccelClear(&qemuCaps->hvf);
@@ -3116,7 +3115,7 @@ static int
virQEMUCapsProbeHypervCapabilities(virQEMUCaps *qemuCaps,
qemuMonitorCPUModelInfo *fullQEMU)
{
- g_autofree virDomainCapsFeatureHyperv *hvcaps = NULL;
+ g_autoptr(virDomainCapsFeatureHyperv) hvcaps = NULL;
size_t i;
if (!fullQEMU)
@@ -4555,7 +4554,7 @@ static int
virQEMUCapsParseHypervCapabilities(virQEMUCaps *qemuCaps,
xmlXPathContextPtr ctxt)
{
- g_autofree virDomainCapsFeatureHyperv *hvcaps = NULL;
+ g_autoptr(virDomainCapsFeatureHyperv) hvcaps = NULL;
xmlNodePtr n = NULL;
g_autofree xmlNodePtr *capNodes = NULL;
int ncapNodes;
@@ -6965,8 +6964,7 @@ static void
virQEMUCapsFillDomainFeatureHypervCaps(virQEMUCaps *qemuCaps,
virDomainCaps *domCaps)
{
- domCaps->hyperv = g_memdup(qemuCaps->hypervCapabilities,
- sizeof(virDomainCapsFeatureHyperv));
+ domCaps->hyperv = virDomainCapsFeatureHypervCopy(qemuCaps->hypervCapabilities);
}
--
2.51.1

View File

@ -0,0 +1,138 @@
From 2da81198df9206a69c368a29da1771e9bce94583 Mon Sep 17 00:00:00 2001
Message-ID: <2da81198df9206a69c368a29da1771e9bce94583.1763747165.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 24 Oct 2025 15:07:45 +0200
Subject: [PATCH] cpu_conf: Make virCPUDefFilterFeatures return void
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The only thing that can fail inside virCPUDefFilterFeatures is
VIR_DELETE_ELEMENT_INPLACE macro. The macro just calls
virDeleteElementsN, which reports a warning when all elements to be
removed are not within the array bounds and returns -1. The function
succeeds otherwise. But since VIR_DELETE_ELEMENT_INPLACE sets the number
of elements to be removed to 1 and we call it with i < cpu->nfeatures,
the safety check in virDeleteElementsN will never fail. And even if we
theoretically called it with wrong arguments, it just wouldn't do
anything.
Thus we can safely assume VIR_DELETE_ELEMENT_INPLACE always succeeds in
virCPUDefFilterFeatures and avoid reporting any errors to simplify
callers.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit fd6cf1b44accd1856a4611933ad51c0e04221aaa)
https://issues.redhat.com/browse/RHEL-126096
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/conf/cpu_conf.c | 9 ++++-----
src/conf/cpu_conf.h | 2 +-
src/qemu/qemu_capabilities.c | 15 ++++++---------
src/qemu/qemu_domain.c | 3 +--
src/qemu/qemu_process.c | 5 ++---
5 files changed, 14 insertions(+), 20 deletions(-)
diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index 31425783ba..7aeedf64f5 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -1017,7 +1017,7 @@ virCPUDefListExplicitFeatures(const virCPUDef *def)
}
-int
+void
virCPUDefFilterFeatures(virCPUDef *cpu,
virCPUDefFeatureFilter filter,
void *opaque)
@@ -1031,11 +1031,10 @@ virCPUDefFilterFeatures(virCPUDef *cpu,
}
VIR_FREE(cpu->features[i].name);
- if (VIR_DELETE_ELEMENT_INPLACE(cpu->features, i, cpu->nfeatures) < 0)
- return -1;
- }
- return 0;
+ /* Safe to ignore as an error is returned only for invalid arguments */
+ ignore_value(VIR_DELETE_ELEMENT_INPLACE(cpu->features, i, cpu->nfeatures));
+ }
}
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
index 28e26303ef..cfb8f1a461 100644
--- a/src/conf/cpu_conf.h
+++ b/src/conf/cpu_conf.h
@@ -260,7 +260,7 @@ virCPUFeatureDef *
virCPUDefFindFeature(const virCPUDef *def,
const char *name);
-int
+void
virCPUDefFilterFeatures(virCPUDef *cpu,
virCPUDefFeatureFilter filter,
void *opaque);
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 7273f59175..6e79bd98c8 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4085,17 +4085,14 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
if (ARCH_IS_X86(qemuCaps->arch) &&
!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_UNAVAILABLE_FEATURES)) {
- if (cpu &&
- virCPUDefFilterFeatures(cpu, virCPUx86FeatureFilterDropMSR, NULL) < 0)
- goto error;
+ if (cpu)
+ virCPUDefFilterFeatures(cpu, virCPUx86FeatureFilterDropMSR, NULL);
- if (migCPU &&
- virCPUDefFilterFeatures(migCPU, virCPUx86FeatureFilterDropMSR, NULL) < 0)
- goto error;
+ if (migCPU)
+ virCPUDefFilterFeatures(migCPU, virCPUx86FeatureFilterDropMSR, NULL);
- if (fullCPU &&
- virCPUDefFilterFeatures(fullCPU, virCPUx86FeatureFilterDropMSR, NULL) < 0)
- goto error;
+ if (fullCPU)
+ virCPUDefFilterFeatures(fullCPU, virCPUx86FeatureFilterDropMSR, NULL);
}
if (virQEMUCapsTypeIsAccelerated(type))
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 56d8bb4827..21a4169c58 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5101,8 +5101,7 @@ qemuDomainMakeCPUMigratable(virArch arch,
g_auto(GStrv) keep = virCPUDefListExplicitFeatures(origCPU);
data.keep = keep;
- if (virCPUDefFilterFeatures(cpu, qemuDomainDropAddedCPUFeatures, &data) < 0)
- return -1;
+ virCPUDefFilterFeatures(cpu, qemuDomainDropAddedCPUFeatures, &data);
}
}
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e2e2822013..f5f9d4a348 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6516,9 +6516,8 @@ qemuProcessUpdateGuestCPU(virDomainDef *def,
def->cpu->fallback = VIR_CPU_FALLBACK_FORBID;
}
- if (virCPUDefFilterFeatures(def->cpu, virQEMUCapsCPUFilterFeatures,
- &def->os.arch) < 0)
- return -1;
+ virCPUDefFilterFeatures(def->cpu, virQEMUCapsCPUFilterFeatures,
+ &def->os.arch);
if (def->cpu->deprecated_feats &&
!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_DEPRECATED_PROPS)) {
--
2.51.1

View File

@ -0,0 +1,196 @@
From e270ac04c7b49177d342b9aa425741a4b748ca2b Mon Sep 17 00:00:00 2001
Message-ID: <e270ac04c7b49177d342b9aa425741a4b748ca2b.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 29 Sep 2025 16:20:17 +0200
Subject: [PATCH] domain_conf: Move format of hyperv features into a function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 78aa096ae21668c14efa30a23876f07ca3f49a6c)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/conf/domain_conf.c | 158 ++++++++++++++++++++++-------------------
1 file changed, 84 insertions(+), 74 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7fd5f76fb6..0b42c283bb 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -28022,6 +28022,89 @@ virDomainFeatureTCGFormat(virBuffer *buf,
}
+static void
+virDomainFeaturesHyperVDefFormat(virBuffer *buf,
+ const virDomainDef *def)
+{
+ virBuffer tmpChildBuf = VIR_BUFFER_INIT_CHILD(buf);
+ size_t j;
+
+ if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_DOMAIN_HYPERV_MODE_NONE)
+ return;
+
+ virBufferAsprintf(buf, "<hyperv mode='%s'>\n",
+ virDomainHyperVModeTypeToString(def->features[VIR_DOMAIN_FEATURE_HYPERV]));
+
+ for (j = 0; j < VIR_DOMAIN_HYPERV_LAST; j++) {
+ g_auto(virBuffer) hypervAttrBuf = VIR_BUFFER_INITIALIZER;
+ g_auto(virBuffer) hypervChildBuf = VIR_BUFFER_INIT_CHILD(&tmpChildBuf);
+
+ if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ABSENT)
+ continue;
+
+ virBufferAsprintf(&hypervAttrBuf, " state='%s'",
+ virTristateSwitchTypeToString(def->hyperv_features[j]));
+
+ switch ((virDomainHyperv) j) {
+ case VIR_DOMAIN_HYPERV_RELAXED:
+ case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_VPINDEX:
+ case VIR_DOMAIN_HYPERV_RUNTIME:
+ case VIR_DOMAIN_HYPERV_SYNIC:
+ case VIR_DOMAIN_HYPERV_RESET:
+ case VIR_DOMAIN_HYPERV_FREQUENCIES:
+ case VIR_DOMAIN_HYPERV_REENLIGHTENMENT:
+ case VIR_DOMAIN_HYPERV_IPI:
+ case VIR_DOMAIN_HYPERV_EVMCS:
+ case VIR_DOMAIN_HYPERV_AVIC:
+ case VIR_DOMAIN_HYPERV_EMSR_BITMAP:
+ case VIR_DOMAIN_HYPERV_XMM_INPUT:
+ break;
+
+ case VIR_DOMAIN_HYPERV_SPINLOCKS:
+ if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON) {
+ virBufferAsprintf(&hypervAttrBuf,
+ " retries='%d'", def->hyperv_spinlocks);
+ }
+ break;
+
+ case VIR_DOMAIN_HYPERV_STIMER:
+ if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON &&
+ def->hyperv_stimer_direct == VIR_TRISTATE_SWITCH_ON) {
+ virBufferAddLit(&hypervChildBuf, "<direct state='on'/>\n");
+ }
+
+ break;
+
+ case VIR_DOMAIN_HYPERV_VENDOR_ID:
+ if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON) {
+ virBufferEscapeString(&hypervAttrBuf, " value='%s'",
+ def->hyperv_vendor_id);
+ }
+ break;
+
+ case VIR_DOMAIN_HYPERV_TLBFLUSH:
+ if (def->hyperv_features[j] != VIR_TRISTATE_SWITCH_ON)
+ break;
+
+ if (def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON)
+ virBufferAddLit(&hypervChildBuf, "<direct state='on'/>\n");
+ if (def->hyperv_tlbflush_extended == VIR_TRISTATE_SWITCH_ON)
+ virBufferAddLit(&hypervChildBuf, "<extended state='on'/>\n");
+ break;
+
+ case VIR_DOMAIN_HYPERV_LAST:
+ break;
+ }
+
+ virXMLFormatElement(&tmpChildBuf, virDomainHypervTypeToString(j),
+ &hypervAttrBuf, &hypervChildBuf);
+ }
+
+ virBufferAddBuffer(buf, &tmpChildBuf);
+ virBufferAddLit(buf, "</hyperv>\n");
+}
+
static int
virDomainDefFormatFeatures(virBuffer *buf,
virDomainDef *def)
@@ -28119,80 +28202,7 @@ virDomainDefFormatFeatures(virBuffer *buf,
break;
case VIR_DOMAIN_FEATURE_HYPERV:
- if (def->features[i] == VIR_DOMAIN_HYPERV_MODE_NONE)
- break;
-
- virBufferAsprintf(&childBuf, "<hyperv mode='%s'>\n",
- virDomainHyperVModeTypeToString(def->features[i]));
-
- for (j = 0; j < VIR_DOMAIN_HYPERV_LAST; j++) {
- g_auto(virBuffer) hypervAttrBuf = VIR_BUFFER_INITIALIZER;
- g_auto(virBuffer) hypervChildBuf = VIR_BUFFER_INIT_CHILD(&tmpChildBuf);
-
- if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ABSENT)
- continue;
-
- virBufferAsprintf(&hypervAttrBuf, " state='%s'",
- virTristateSwitchTypeToString(def->hyperv_features[j]));
-
- switch ((virDomainHyperv) j) {
- case VIR_DOMAIN_HYPERV_RELAXED:
- case VIR_DOMAIN_HYPERV_VAPIC:
- case VIR_DOMAIN_HYPERV_VPINDEX:
- case VIR_DOMAIN_HYPERV_RUNTIME:
- case VIR_DOMAIN_HYPERV_SYNIC:
- case VIR_DOMAIN_HYPERV_RESET:
- case VIR_DOMAIN_HYPERV_FREQUENCIES:
- case VIR_DOMAIN_HYPERV_REENLIGHTENMENT:
- case VIR_DOMAIN_HYPERV_IPI:
- case VIR_DOMAIN_HYPERV_EVMCS:
- case VIR_DOMAIN_HYPERV_AVIC:
- case VIR_DOMAIN_HYPERV_EMSR_BITMAP:
- case VIR_DOMAIN_HYPERV_XMM_INPUT:
- break;
-
- case VIR_DOMAIN_HYPERV_SPINLOCKS:
- if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON) {
- virBufferAsprintf(&hypervAttrBuf,
- " retries='%d'", def->hyperv_spinlocks);
- }
- break;
-
- case VIR_DOMAIN_HYPERV_STIMER:
- if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON &&
- def->hyperv_stimer_direct == VIR_TRISTATE_SWITCH_ON) {
- virBufferAddLit(&hypervChildBuf, "<direct state='on'/>\n");
- }
-
- break;
-
- case VIR_DOMAIN_HYPERV_VENDOR_ID:
- if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON) {
- virBufferEscapeString(&hypervAttrBuf, " value='%s'",
- def->hyperv_vendor_id);
- }
- break;
-
- case VIR_DOMAIN_HYPERV_TLBFLUSH:
- if (def->hyperv_features[j] != VIR_TRISTATE_SWITCH_ON)
- break;
-
- if (def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON)
- virBufferAddLit(&hypervChildBuf, "<direct state='on'/>\n");
- if (def->hyperv_tlbflush_extended == VIR_TRISTATE_SWITCH_ON)
- virBufferAddLit(&hypervChildBuf, "<extended state='on'/>\n");
- break;
-
- case VIR_DOMAIN_HYPERV_LAST:
- break;
- }
-
- virXMLFormatElement(&tmpChildBuf, virDomainHypervTypeToString(j),
- &hypervAttrBuf, &hypervChildBuf);
- }
-
- virBufferAddBuffer(&childBuf, &tmpChildBuf);
- virBufferAddLit(&childBuf, "</hyperv>\n");
+ virDomainFeaturesHyperVDefFormat(&childBuf, def);
break;
case VIR_DOMAIN_FEATURE_KVM:
--
2.51.1

View File

@ -0,0 +1,105 @@
From d0c72934e0922d19eca8ed0cd812fb56f9222ec6 Mon Sep 17 00:00:00 2001
Message-ID: <d0c72934e0922d19eca8ed0cd812fb56f9222ec6.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 29 Sep 2025 16:05:31 +0200
Subject: [PATCH] domain_conf: Use virXMLFormatElement() to format hyperv
features
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Not only is it more modern that old virBufferAsprintf() of
opening and closing tag, it's also aware of child elements buffer
and thus formats a singleton properly.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit c9716c0e0904c86d7e1c9258bc6e808ba7bc8262)
Additionally, hyperv-passthrough.x86_64-6.1.0.xml was modified
too, since the file doesn't exist upstream anymore (see
v11.2.0-rc1~225), but downstream it does.
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/conf/domain_conf.c | 13 +++++++------
.../hyperv-passthrough.x86_64-6.1.0.xml | 3 +--
.../hyperv-passthrough.x86_64-latest.xml | 3 +--
3 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 0b42c283bb..f02efaca4e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -28026,18 +28026,19 @@ static void
virDomainFeaturesHyperVDefFormat(virBuffer *buf,
const virDomainDef *def)
{
- virBuffer tmpChildBuf = VIR_BUFFER_INIT_CHILD(buf);
+ virBuffer childBuf = VIR_BUFFER_INIT_CHILD(buf);
+ virBuffer attrBuf = VIR_BUFFER_INITIALIZER;
size_t j;
if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_DOMAIN_HYPERV_MODE_NONE)
return;
- virBufferAsprintf(buf, "<hyperv mode='%s'>\n",
+ virBufferAsprintf(&attrBuf, " mode='%s'",
virDomainHyperVModeTypeToString(def->features[VIR_DOMAIN_FEATURE_HYPERV]));
for (j = 0; j < VIR_DOMAIN_HYPERV_LAST; j++) {
g_auto(virBuffer) hypervAttrBuf = VIR_BUFFER_INITIALIZER;
- g_auto(virBuffer) hypervChildBuf = VIR_BUFFER_INIT_CHILD(&tmpChildBuf);
+ g_auto(virBuffer) hypervChildBuf = VIR_BUFFER_INIT_CHILD(&childBuf);
if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ABSENT)
continue;
@@ -28097,14 +28098,14 @@ virDomainFeaturesHyperVDefFormat(virBuffer *buf,
break;
}
- virXMLFormatElement(&tmpChildBuf, virDomainHypervTypeToString(j),
+ virXMLFormatElement(&childBuf, virDomainHypervTypeToString(j),
&hypervAttrBuf, &hypervChildBuf);
}
- virBufferAddBuffer(buf, &tmpChildBuf);
- virBufferAddLit(buf, "</hyperv>\n");
+ virXMLFormatElement(buf, "hyperv", &attrBuf, &childBuf);
}
+
static int
virDomainDefFormatFeatures(virBuffer *buf,
virDomainDef *def)
diff --git a/tests/qemuxmlconfdata/hyperv-passthrough.x86_64-6.1.0.xml b/tests/qemuxmlconfdata/hyperv-passthrough.x86_64-6.1.0.xml
index 02410a403e..d2130dc5c0 100644
--- a/tests/qemuxmlconfdata/hyperv-passthrough.x86_64-6.1.0.xml
+++ b/tests/qemuxmlconfdata/hyperv-passthrough.x86_64-6.1.0.xml
@@ -10,8 +10,7 @@
</os>
<features>
<acpi/>
- <hyperv mode='passthrough'>
- </hyperv>
+ <hyperv mode='passthrough'/>
</features>
<cpu mode='custom' match='exact' check='none'>
<model fallback='forbid'>qemu64</model>
diff --git a/tests/qemuxmlconfdata/hyperv-passthrough.x86_64-latest.xml b/tests/qemuxmlconfdata/hyperv-passthrough.x86_64-latest.xml
index 2cfae8fa4c..0ce5bab605 100644
--- a/tests/qemuxmlconfdata/hyperv-passthrough.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/hyperv-passthrough.x86_64-latest.xml
@@ -10,8 +10,7 @@
</os>
<features>
<acpi/>
- <hyperv mode='passthrough'>
- </hyperv>
+ <hyperv mode='passthrough'/>
</features>
<cpu mode='custom' match='exact' check='none'>
<model fallback='forbid'>qemu64</model>
--
2.51.1

View File

@ -0,0 +1,290 @@
From b9646a88096cda2840560b907ce8c68f0de2f36b Mon Sep 17 00:00:00 2001
Message-ID: <b9646a88096cda2840560b907ce8c68f0de2f36b.1763747165.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 24 Oct 2025 14:17:56 +0200
Subject: [PATCH] qemu: Ignore "ht" CPU feature
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The feature does not do anything, QEMU will always set it according to
the CPU topology completely ignoring what we asked for. Unfortunately,
the way the state of "ht" is reported changed in QEMU 10.0.0 (commit
c6bd2dd634208).
QEMU older than 10.0.0 would just report whatever was specified on the
command line totally ignoring the actual state of the feature visible to
a guest. But after the change QEMU reports ht=on in case it enabled "ht"
based on the CPU topology. In all other cases QEMU still reports the
state requested on the command line.
As a result of this change a domain with multiple CPU threads started on
QEMU < 10.0.0 could not be migrated to QEMU >= 10.0.0 unless "ht" was
explicitly enabled in the domain XML because libvirt would see "ht"
enabled on the destination, but disabled on the source (the guest would
see "ht" enabled in both cases anyway). Outgoing migration of domains
started on QEMU >= 10.0.0 is not affected.
To fix this issue we can completely ignore "ht" both in the domain XML
and in the CPU properties reported by QEMU. With this fix incoming
migration to QEMU >= 10.0.0 works again.
Fixes: https://gitlab.com/libvirt/libvirt/-/issues/821
Fixes: https://issues.redhat.com/browse/RHEL-104216
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit ba16113c76050a10bbccaae0192a0d30f97de5ae)
https://issues.redhat.com/browse/RHEL-126096
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 1 +
tests/qemuxmlconfdata/cpu-cache-disable3.x86_64-latest.args | 2 +-
.../cpu-check-default-partial.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.xml | 1 -
tests/qemuxmlconfdata/cpu-exact2-nofallback.xml | 1 -
tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.xml | 1 -
tests/qemuxmlconfdata/cpu-exact2.xml | 1 -
tests/qemuxmlconfdata/cpu-host-model-cmt.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-host-model-vendor.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-minimum1.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-minimum2.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-phys-bits-emulate2.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.xml | 1 -
tests/qemuxmlconfdata/cpu-strict1.xml | 1 -
tests/qemuxmlconfdata/cpu-tsc-frequency.x86_64-latest.args | 2 +-
18 files changed, 12 insertions(+), 17 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 6e79bd98c8..b75ecd5046 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3725,6 +3725,7 @@ const char *ignoredFeatures[] = {
"osxsave", "ospke", /* dropped from QEMU */
"vmx-ept-uc", "vmx-ept-wb", /* never supported by QEMU */
"vmx-invvpid-single-context", /* never supported by QEMU */
+ "ht", /* ignored by QEMU, set according to topology */
};
bool
diff --git a/tests/qemuxmlconfdata/cpu-cache-disable3.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-cache-disable3.x86_64-latest.args
index 4adf20b55a..1e962589c9 100644
--- a/tests/qemuxmlconfdata/cpu-cache-disable3.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-cache-disable3.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-foo/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-foo/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu Haswell,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,l3-cache=off \
+-cpu Haswell,vme=on,ds=on,acpi=on,ss=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,l3-cache=off \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-check-default-partial.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-check-default-partial.x86_64-latest.args
index a92da44bd8..fe553fd31b 100644
--- a/tests/qemuxmlconfdata/cpu-check-default-partial.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-check-default-partial.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu Haswell,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on \
+-cpu Haswell,vme=on,ds=on,acpi=on,ss=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.args
index 20b0306268..7464609aba 100644
--- a/tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu core2duo,ds=on,ht=on,tm=on,ds-cpl=on,xtpr=on,3dnowext=on,lahf-lm=on,nx=off,cx16=off,tm2=off,pbe=off,ss=off,sse4a=off,wdt=off \
+-cpu core2duo,ds=on,tm=on,ds-cpl=on,xtpr=on,3dnowext=on,lahf-lm=on,nx=off,cx16=off,tm2=off,pbe=off,ss=off,sse4a=off,wdt=off \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.xml b/tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.xml
index d66d0a182b..05c78334ab 100644
--- a/tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/cpu-exact2-nofallback.x86_64-latest.xml
@@ -11,7 +11,6 @@
<cpu mode='custom' match='exact' check='partial'>
<model fallback='forbid'>core2duo</model>
<feature policy='require' name='ds'/>
- <feature policy='require' name='ht'/>
<feature policy='optional' name='tm'/>
<feature policy='require' name='ds_cpl'/>
<feature policy='require' name='xtpr'/>
diff --git a/tests/qemuxmlconfdata/cpu-exact2-nofallback.xml b/tests/qemuxmlconfdata/cpu-exact2-nofallback.xml
index 4cd1d18216..d7c3e4f40f 100644
--- a/tests/qemuxmlconfdata/cpu-exact2-nofallback.xml
+++ b/tests/qemuxmlconfdata/cpu-exact2-nofallback.xml
@@ -11,7 +11,6 @@
<cpu match='exact'>
<model fallback='forbid'>core2duo</model>
<feature name='ds' policy='require'/>
- <feature name='ht' policy='require'/>
<feature name='tm' policy='optional'/>
<feature name='ds_cpl' policy='require'/>
<feature name='xtpr' policy='require'/>
diff --git a/tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.args
index 20b0306268..7464609aba 100644
--- a/tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu core2duo,ds=on,ht=on,tm=on,ds-cpl=on,xtpr=on,3dnowext=on,lahf-lm=on,nx=off,cx16=off,tm2=off,pbe=off,ss=off,sse4a=off,wdt=off \
+-cpu core2duo,ds=on,tm=on,ds-cpl=on,xtpr=on,3dnowext=on,lahf-lm=on,nx=off,cx16=off,tm2=off,pbe=off,ss=off,sse4a=off,wdt=off \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.xml b/tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.xml
index 7dccf6902c..cf9d241372 100644
--- a/tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/cpu-exact2.x86_64-latest.xml
@@ -11,7 +11,6 @@
<cpu mode='custom' match='exact' check='partial'>
<model fallback='allow'>core2duo</model>
<feature policy='require' name='ds'/>
- <feature policy='require' name='ht'/>
<feature policy='optional' name='tm'/>
<feature policy='require' name='ds_cpl'/>
<feature policy='require' name='xtpr'/>
diff --git a/tests/qemuxmlconfdata/cpu-exact2.xml b/tests/qemuxmlconfdata/cpu-exact2.xml
index 4239796f31..b4800262f6 100644
--- a/tests/qemuxmlconfdata/cpu-exact2.xml
+++ b/tests/qemuxmlconfdata/cpu-exact2.xml
@@ -11,7 +11,6 @@
<cpu match='exact'>
<model>core2duo</model>
<feature name='ds' policy='require'/>
- <feature name='ht' policy='require'/>
<feature name='tm' policy='optional'/>
<feature name='ds_cpl' policy='require'/>
<feature name='xtpr' policy='require'/>
diff --git a/tests/qemuxmlconfdata/cpu-host-model-cmt.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-cmt.x86_64-latest.args
index 510e19bba6..d6b57d40a3 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-cmt.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-cmt.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel tcg \
--cpu Haswell,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on \
+-cpu Haswell,vme=on,ds=on,acpi=on,ss=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-host-model-vendor.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-host-model-vendor.x86_64-latest.args
index c258a1ab36..ef7d442d5b 100644
--- a/tests/qemuxmlconfdata/cpu-host-model-vendor.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-host-model-vendor.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel tcg \
--cpu 'Haswell,vendor=Libvirt QEMU,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on' \
+-cpu 'Haswell,vendor=Libvirt QEMU,vme=on,ds=on,acpi=on,ss=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on' \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-minimum1.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-minimum1.x86_64-latest.args
index a92da44bd8..fe553fd31b 100644
--- a/tests/qemuxmlconfdata/cpu-minimum1.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-minimum1.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu Haswell,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on \
+-cpu Haswell,vme=on,ds=on,acpi=on,ss=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-minimum2.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-minimum2.x86_64-latest.args
index 62e0101568..ddd0c64080 100644
--- a/tests/qemuxmlconfdata/cpu-minimum2.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-minimum2.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu Haswell,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,syscall=off,nx=off,lm=off,svm=off \
+-cpu Haswell,vme=on,ds=on,acpi=on,ss=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,syscall=off,nx=off,lm=off,svm=off \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-phys-bits-emulate2.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-phys-bits-emulate2.x86_64-latest.args
index 92c719b553..3808af7399 100644
--- a/tests/qemuxmlconfdata/cpu-phys-bits-emulate2.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-phys-bits-emulate2.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-foo/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-foo/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu Haswell,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,phys-bits=42 \
+-cpu Haswell,vme=on,ds=on,acpi=on,ss=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,phys-bits=42 \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.args
index 3f9c3516bb..7e870db393 100644
--- a/tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu Haswell,ds=on,acpi=on,ht=on,tm=on,ds-cpl=on,vmx=on,est=on,xtpr=on,3dnowext=on,lahf-lm=on,nx=off,cx16=off,tm2=off,pbe=off,ss=off,sse4a=off,wdt=off,vme=off,invtsc=off,abm=off,pdpe1gb=off,rdrand=off,f16c=off,pdcm=off,smx=off,monitor=off,dtes64=off \
+-cpu Haswell,ds=on,acpi=on,tm=on,ds-cpl=on,vmx=on,est=on,xtpr=on,3dnowext=on,lahf-lm=on,nx=off,cx16=off,tm2=off,pbe=off,ss=off,sse4a=off,wdt=off,vme=off,invtsc=off,abm=off,pdpe1gb=off,rdrand=off,f16c=off,pdcm=off,smx=off,monitor=off,dtes64=off \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.xml b/tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.xml
index beeaf5c682..9c5e083aee 100644
--- a/tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/cpu-strict1.x86_64-latest.xml
@@ -12,7 +12,6 @@
<model fallback='allow'>Haswell</model>
<feature policy='require' name='ds'/>
<feature policy='optional' name='acpi'/>
- <feature policy='require' name='ht'/>
<feature policy='optional' name='tm'/>
<feature policy='require' name='ds_cpl'/>
<feature policy='optional' name='vmx'/>
diff --git a/tests/qemuxmlconfdata/cpu-strict1.xml b/tests/qemuxmlconfdata/cpu-strict1.xml
index 63db54ecad..c0548b3dca 100644
--- a/tests/qemuxmlconfdata/cpu-strict1.xml
+++ b/tests/qemuxmlconfdata/cpu-strict1.xml
@@ -12,7 +12,6 @@
<model>Haswell</model>
<feature name='ds' policy='require'/>
<feature name='acpi' policy='optional'/>
- <feature name='ht' policy='require'/>
<feature name='tm' policy='optional'/>
<feature name='ds_cpl' policy='require'/>
<feature name='vmx' policy='optional'/>
diff --git a/tests/qemuxmlconfdata/cpu-tsc-frequency.x86_64-latest.args b/tests/qemuxmlconfdata/cpu-tsc-frequency.x86_64-latest.args
index 4353d65ac2..e926d309f5 100644
--- a/tests/qemuxmlconfdata/cpu-tsc-frequency.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/cpu-tsc-frequency.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
--cpu Haswell,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,invtsc=on,tsc-frequency=4567890000 \
+-cpu Haswell,vme=on,ds=on,acpi=on,ss=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,invtsc=on,tsc-frequency=4567890000 \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
--
2.51.1

View File

@ -0,0 +1,52 @@
From 21dece5adb14014a8f8e6cc1c1b82fd98082fe75 Mon Sep 17 00:00:00 2001
Message-ID: <21dece5adb14014a8f8e6cc1c1b82fd98082fe75.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Thu, 2 Oct 2025 09:38:04 +0200
Subject: [PATCH] qemu: Use virXPathTristateBool()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There are two places in our code base which can use freshly
introduced virXPathTristateBool():
qemuStorageSourcePrivateDataParse() and
qemuDomainObjPrivateXMLParseBlockjobs().
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 5369f071e40cb91a8b7ee79efda078eca7b15035)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_domain.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 8879a45ffb..56d8bb4827 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2072,7 +2072,7 @@ qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt,
g_autofree char *authalias = NULL;
g_autofree char *httpcookiealias = NULL;
g_autofree char *tlskeyalias = NULL;
- g_autofree char *thresholdEventWithIndex = NULL;
+ virTristateBool thresholdEventWithIndex;
bool fdsetPresent = false;
unsigned int fdSetID;
int enccount;
@@ -2138,9 +2138,10 @@ qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt,
if (virStorageSourcePrivateDataParseRelPath(ctxt, src) < 0)
return -1;
- if ((thresholdEventWithIndex = virXPathString("string(./thresholdEvent/@indexUsed)", ctxt)) &&
- virTristateBoolTypeFromString(thresholdEventWithIndex) == VIR_TRISTATE_BOOL_YES)
- src->thresholdEventWithIndex = true;
+ if (virXPathTristateBool("string(./thresholdEvent/@indexUsed)",
+ ctxt, &thresholdEventWithIndex) >= 0) {
+ virTristateBoolToBool(thresholdEventWithIndex, &src->thresholdEventWithIndex);
+ }
if ((nbdkitnode = virXPathNode("nbdkit", ctxt))) {
if (qemuStorageSourcePrivateDataParseNbdkit(nbdkitnode, ctxt, src) < 0)
--
2.51.1

View File

@ -0,0 +1,684 @@
From 64f14820e423b85d5af0ffffe87f43f2332b023e Mon Sep 17 00:00:00 2001
Message-ID: <64f14820e423b85d5af0ffffe87f43f2332b023e.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 30 Sep 2025 15:37:24 +0200
Subject: [PATCH] qemu_capabilities: Fetch new hyperv domcaps
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Now that everything is prepared, we can start storing the default
values for some hyperv features that are reported in domain
capabilities XML later.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit ba011bebd9a13d4926aeb56d4c88f0e03ef22c50)
Conflicts:
tests/domaincapsdata/qemu_10.0.0-q35.x86_64+amdsev.xml
tests/domaincapsdata/qemu_10.0.0.x86_64+amdsev.xml
tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml
tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml
tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml
tests/domaincapsdata/qemu_6.0.0.x86_64.xml
tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml
tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml
tests/domaincapsdata/qemu_6.1.0.x86_64.xml
tests/domaincapsdata/qemu_9.2.0-q35.x86_64+amdsev.xml
tests/domaincapsdata/qemu_9.2.0-tcg.x86_64+amdsev.xml
tests/domaincapsdata/qemu_9.2.0.x86_64+amdsev.xml
tests/qemucapabilitiesdata/caps_10.1.0_x86_64.xml
tests/qemucapabilitiesdata/caps_5.2.0_x86_64.xml
tests/qemucapabilitiesdata/caps_6.0.0_x86_64.xml
tests/qemucapabilitiesdata/caps_6.1.0_x86_64.xml: Some files
don't exist downstream yet, others have context issues.
Regenerated with VIR_TEST_REGENERATE_OUTPUT=1.
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_capabilities.c | 44 +++++++++++++++++++
.../domaincapsdata/qemu_10.0.0-q35.x86_64.xml | 7 +++
.../domaincapsdata/qemu_10.0.0-tcg.x86_64.xml | 7 +++
tests/domaincapsdata/qemu_10.0.0.x86_64.xml | 7 +++
.../qemu_10.1.0-q35.x86_64+inteltdx.xml | 7 +++
.../qemu_10.1.0-tcg.x86_64+inteltdx.xml | 7 +++
.../qemu_10.1.0.x86_64+inteltdx.xml | 7 +++
.../domaincapsdata/qemu_8.0.0-q35.x86_64.xml | 7 +++
.../domaincapsdata/qemu_8.0.0-tcg.x86_64.xml | 7 +++
tests/domaincapsdata/qemu_8.0.0.x86_64.xml | 7 +++
.../domaincapsdata/qemu_8.1.0-q35.x86_64.xml | 7 +++
.../domaincapsdata/qemu_8.1.0-tcg.x86_64.xml | 7 +++
tests/domaincapsdata/qemu_8.1.0.x86_64.xml | 7 +++
.../domaincapsdata/qemu_8.2.0-q35.x86_64.xml | 7 +++
.../domaincapsdata/qemu_8.2.0-tcg.x86_64.xml | 7 +++
tests/domaincapsdata/qemu_8.2.0.x86_64.xml | 7 +++
.../domaincapsdata/qemu_9.0.0-q35.x86_64.xml | 7 +++
.../domaincapsdata/qemu_9.0.0-tcg.x86_64.xml | 7 +++
tests/domaincapsdata/qemu_9.0.0.x86_64.xml | 7 +++
.../domaincapsdata/qemu_9.1.0-q35.x86_64.xml | 7 +++
.../domaincapsdata/qemu_9.1.0-tcg.x86_64.xml | 7 +++
tests/domaincapsdata/qemu_9.1.0.x86_64.xml | 7 +++
.../domaincapsdata/qemu_9.2.0-q35.x86_64.xml | 7 +++
.../domaincapsdata/qemu_9.2.0-tcg.x86_64.xml | 7 +++
tests/domaincapsdata/qemu_9.2.0.x86_64.xml | 7 +++
.../caps_10.0.0_x86_64.xml | 5 +++
.../caps_10.1.0_x86_64+inteltdx.xml | 5 +++
.../caps_8.0.0_x86_64.xml | 5 +++
.../caps_8.1.0_x86_64.xml | 5 +++
.../caps_8.2.0_x86_64.xml | 5 +++
.../caps_9.0.0_x86_64.xml | 5 +++
.../caps_9.1.0_x86_64.xml | 5 +++
.../caps_9.2.0_x86_64.xml | 5 +++
33 files changed, 252 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 0452600195..edd4494fa1 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3133,6 +3133,50 @@ virQEMUCapsProbeHypervCapabilities(virQEMUCaps *qemuCaps,
if (!(name = STRSKIP(prop.name, "hv-")))
continue;
+ if (STREQ(prop.name, VIR_CPU_x86_HV_SPINLOCKS)) {
+ if (prop.type != QEMU_MONITOR_CPU_PROPERTY_NUMBER) {
+ VIR_DEBUG("Unexpected type '%s' for name '%s'",
+ qemuMonitorCPUPropertyTypeToString(prop.type), prop.name);
+ continue;
+ }
+
+ if ((uint32_t)prop.value.number != (uint32_t)-1)
+ hvcaps->spinlocks = prop.value.number;
+ } else if (STREQ(prop.name, VIR_CPU_x86_HV_STIMER_DIRECT)) {
+ if (prop.type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN) {
+ VIR_DEBUG("Unexpected type '%s' for name '%s'",
+ qemuMonitorCPUPropertyTypeToString(prop.type), prop.name);
+ } else {
+ hvcaps->stimer_direct = virTristateSwitchFromBool(prop.value.boolean);
+ }
+ continue;
+ } else if (STREQ(prop.name, VIR_CPU_x86_HV_TLBFLUSH_DIRECT)) {
+ if (prop.type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN) {
+ VIR_DEBUG("Unexpected type '%s' for name '%s'",
+ qemuMonitorCPUPropertyTypeToString(prop.type), prop.name);
+ } else {
+ hvcaps->tlbflush_direct = virTristateSwitchFromBool(prop.value.boolean);
+ }
+ continue;
+ } else if (STREQ(prop.name, VIR_CPU_x86_HV_TLBFLUSH_EXT)) {
+ if (prop.type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN) {
+ VIR_DEBUG("Unexpected type '%s' for name '%s'",
+ qemuMonitorCPUPropertyTypeToString(prop.type), prop.name);
+ } else {
+ hvcaps->tlbflush_extended = virTristateSwitchFromBool(prop.value.boolean);
+ }
+ continue;
+ } else if (STREQ(prop.name, "hv-vendor-id")) {
+ if (prop.type != QEMU_MONITOR_CPU_PROPERTY_STRING) {
+ VIR_DEBUG("Unexpected type '%s' for name '%s'",
+ qemuMonitorCPUPropertyTypeToString(prop.type), prop.name);
+ continue;
+ }
+
+ if (STRNEQ(prop.value.string, ""))
+ hvcaps->vendor_id = g_strdup(prop.value.string);
+ }
+
hvprop = virDomainHypervTypeFromString(name);
if (hvprop < 0) {
diff --git a/tests/domaincapsdata/qemu_10.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_10.0.0-q35.x86_64.xml
index f1a7963d34..d730151180 100644
--- a/tests/domaincapsdata/qemu_10.0.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_10.0.0-q35.x86_64.xml
@@ -1695,6 +1695,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64.xml
index 9a7d39c1f8..5a7a574009 100644
--- a/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_10.0.0-tcg.x86_64.xml
@@ -1804,6 +1804,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_10.0.0.x86_64.xml b/tests/domaincapsdata/qemu_10.0.0.x86_64.xml
index 64dc451eda..ee22265745 100644
--- a/tests/domaincapsdata/qemu_10.0.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_10.0.0.x86_64.xml
@@ -1695,6 +1695,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml
index fedf50a52a..a3f337d95b 100644
--- a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml
+++ b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64+inteltdx.xml
@@ -756,6 +756,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='yes'>
<enum name='sectype'>
diff --git a/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64+inteltdx.xml b/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64+inteltdx.xml
index c9913316b8..9a841c114c 100644
--- a/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64+inteltdx.xml
+++ b/tests/domaincapsdata/qemu_10.1.0-tcg.x86_64+inteltdx.xml
@@ -1803,6 +1803,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='yes'>
<enum name='sectype'>
diff --git a/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml b/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml
index c1aebf16b2..b2937414d4 100644
--- a/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml
+++ b/tests/domaincapsdata/qemu_10.1.0.x86_64+inteltdx.xml
@@ -756,6 +756,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='yes'>
<enum name='sectype'>
diff --git a/tests/domaincapsdata/qemu_8.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_8.0.0-q35.x86_64.xml
index b8c376cb14..84a200e572 100644
--- a/tests/domaincapsdata/qemu_8.0.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.0.0-q35.x86_64.xml
@@ -1242,6 +1242,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>off</tlbflush_direct>
+ <tlbflush_extended>off</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_8.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_8.0.0-tcg.x86_64.xml
index d3c9830a1a..92d4d85c95 100644
--- a/tests/domaincapsdata/qemu_8.0.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.0.0-tcg.x86_64.xml
@@ -1735,6 +1735,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>off</tlbflush_direct>
+ <tlbflush_extended>off</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_8.0.0.x86_64.xml b/tests/domaincapsdata/qemu_8.0.0.x86_64.xml
index e8df30ae07..bca6510b5d 100644
--- a/tests/domaincapsdata/qemu_8.0.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.0.0.x86_64.xml
@@ -1242,6 +1242,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>off</tlbflush_direct>
+ <tlbflush_extended>off</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml
index e80e175376..e9455d302c 100644
--- a/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml
@@ -1500,6 +1500,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml
index 62ffabb3e2..adfd3f67ac 100644
--- a/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml
@@ -1756,6 +1756,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_8.1.0.x86_64.xml b/tests/domaincapsdata/qemu_8.1.0.x86_64.xml
index 4117d926cb..a0b2e72b03 100644
--- a/tests/domaincapsdata/qemu_8.1.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.1.0.x86_64.xml
@@ -1500,6 +1500,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml
index dfa88bcf96..b95bcb4716 100644
--- a/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml
@@ -1502,6 +1502,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml
index 327cad253e..f4c775f4e6 100644
--- a/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml
@@ -1723,6 +1723,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_8.2.0.x86_64.xml b/tests/domaincapsdata/qemu_8.2.0.x86_64.xml
index f8dbb717f1..6f80d7e852 100644
--- a/tests/domaincapsdata/qemu_8.2.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.2.0.x86_64.xml
@@ -1502,6 +1502,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_9.0.0-q35.x86_64.xml
index c5a653f57b..d01c6734be 100644
--- a/tests/domaincapsdata/qemu_9.0.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.0.0-q35.x86_64.xml
@@ -1502,6 +1502,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_9.0.0-tcg.x86_64.xml
index 30876c5fef..09625af704 100644
--- a/tests/domaincapsdata/qemu_9.0.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.0.0-tcg.x86_64.xml
@@ -1652,6 +1652,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.0.0.x86_64.xml b/tests/domaincapsdata/qemu_9.0.0.x86_64.xml
index 6c141e1cb9..bfb75d5346 100644
--- a/tests/domaincapsdata/qemu_9.0.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.0.0.x86_64.xml
@@ -1502,6 +1502,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_9.1.0-q35.x86_64.xml
index 9445d999b5..e1b93389fc 100644
--- a/tests/domaincapsdata/qemu_9.1.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.1.0-q35.x86_64.xml
@@ -1638,6 +1638,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_9.1.0-tcg.x86_64.xml
index 61d92550c1..91479bf34f 100644
--- a/tests/domaincapsdata/qemu_9.1.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.1.0-tcg.x86_64.xml
@@ -1757,6 +1757,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.1.0.x86_64.xml b/tests/domaincapsdata/qemu_9.1.0.x86_64.xml
index 5e87efe5e8..67f643bc1a 100644
--- a/tests/domaincapsdata/qemu_9.1.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.1.0.x86_64.xml
@@ -1638,6 +1638,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_9.2.0-q35.x86_64.xml
index d5db9af49e..ec3db76484 100644
--- a/tests/domaincapsdata/qemu_9.2.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.2.0-q35.x86_64.xml
@@ -1695,6 +1695,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64.xml
index 7ccdc11412..b3af908680 100644
--- a/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.2.0-tcg.x86_64.xml
@@ -1804,6 +1804,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/domaincapsdata/qemu_9.2.0.x86_64.xml b/tests/domaincapsdata/qemu_9.2.0.x86_64.xml
index 05a5ce4bee..39a7b6eed5 100644
--- a/tests/domaincapsdata/qemu_9.2.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_9.2.0.x86_64.xml
@@ -1695,6 +1695,13 @@
<value>emsr_bitmap</value>
<value>xmm_input</value>
</enum>
+ <defaults>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
+ </defaults>
</hyperv>
<launchSecurity supported='no'/>
</features>
diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml
index 432d60b02b..18977d63da 100644
--- a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml
@@ -4158,5 +4158,10 @@
<cap name='avic'/>
<cap name='emsr_bitmap'/>
<cap name='xmm_input'/>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
</hypervCapabilities>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml
index 54b09813a8..09bff5f829 100644
--- a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml
+++ b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml
@@ -3584,5 +3584,10 @@
<cap name='avic'/>
<cap name='emsr_bitmap'/>
<cap name='xmm_input'/>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
</hypervCapabilities>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_8.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_8.0.0_x86_64.xml
index f28b8df68e..d805b9ec9a 100644
--- a/tests/qemucapabilitiesdata/caps_8.0.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_8.0.0_x86_64.xml
@@ -3460,5 +3460,10 @@
<cap name='avic'/>
<cap name='emsr_bitmap'/>
<cap name='xmm_input'/>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>off</tlbflush_direct>
+ <tlbflush_extended>off</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
</hypervCapabilities>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_8.1.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_8.1.0_x86_64.xml
index d6fbb11064..14ce16bcc8 100644
--- a/tests/qemucapabilitiesdata/caps_8.1.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_8.1.0_x86_64.xml
@@ -3789,5 +3789,10 @@
<cap name='avic'/>
<cap name='emsr_bitmap'/>
<cap name='xmm_input'/>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
</hypervCapabilities>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_8.2.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_8.2.0_x86_64.xml
index 27ecaee290..8c7ed8c91b 100644
--- a/tests/qemucapabilitiesdata/caps_8.2.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_8.2.0_x86_64.xml
@@ -3763,5 +3763,10 @@
<cap name='avic'/>
<cap name='emsr_bitmap'/>
<cap name='xmm_input'/>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
</hypervCapabilities>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml
index 452e7384c0..009025a255 100644
--- a/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_9.0.0_x86_64.xml
@@ -3698,5 +3698,10 @@
<cap name='avic'/>
<cap name='emsr_bitmap'/>
<cap name='xmm_input'/>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
</hypervCapabilities>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml
index 26883bd672..0482a6feb9 100644
--- a/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml
@@ -3954,5 +3954,10 @@
<cap name='avic'/>
<cap name='emsr_bitmap'/>
<cap name='xmm_input'/>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
</hypervCapabilities>
</qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml
index 1353761fab..be8718defb 100644
--- a/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_9.2.0_x86_64.xml
@@ -3935,5 +3935,10 @@
<cap name='avic'/>
<cap name='emsr_bitmap'/>
<cap name='xmm_input'/>
+ <spinlocks>4095</spinlocks>
+ <stimer_direct>on</stimer_direct>
+ <tlbflush_direct>on</tlbflush_direct>
+ <tlbflush_extended>on</tlbflush_extended>
+ <vendor_id>Linux KVM Hv</vendor_id>
</hypervCapabilities>
</qemuCaps>
--
2.51.1

View File

@ -0,0 +1,92 @@
From 4f855a934bc9649b96734db69197b26d9995cede Mon Sep 17 00:00:00 2001
Message-ID: <4f855a934bc9649b96734db69197b26d9995cede.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 1 Oct 2025 15:50:39 +0200
Subject: [PATCH] qemu_capabilities: Format and parse new hyperv domcaps
members
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
After previous commit the virDomainCapsFeatureHyperv struct
gained new members. Since virQEMUCaps struct holds a pointer to
such struct we must format and parse it to/from capabilities XML.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 0141f6544cda75d47eb35b95c10878793c22c187)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_capabilities.c | 42 ++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index b54bcbd527..0452600195 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4557,6 +4557,7 @@ virQEMUCapsParseHypervCapabilities(virQEMUCaps *qemuCaps,
g_autoptr(virDomainCapsFeatureHyperv) hvcaps = NULL;
xmlNodePtr n = NULL;
g_autofree xmlNodePtr *capNodes = NULL;
+ int rc;
int ncapNodes;
size_t i;
@@ -4592,6 +4593,28 @@ virQEMUCapsParseHypervCapabilities(virQEMUCaps *qemuCaps,
VIR_DOMAIN_CAPS_ENUM_SET(hvcaps->features, val);
}
+ rc = virXPathUInt("string(./hypervCapabilities/spinlocks)",
+ ctxt, &hvcaps->spinlocks);
+ if (rc == -2)
+ return -1;
+
+ rc = virXPathTristateSwitch("string(./hypervCapabilities/stimer_direct)",
+ ctxt, &hvcaps->stimer_direct);
+ if (rc == -2)
+ return -1;
+
+ rc = virXPathTristateSwitch("string(./hypervCapabilities/tlbflush_direct)",
+ ctxt, &hvcaps->tlbflush_direct);
+ if (rc == -2)
+ return -1;
+
+ rc = virXPathTristateSwitch("string(./hypervCapabilities/tlbflush_extended)",
+ ctxt, &hvcaps->tlbflush_extended);
+ if (rc == -2)
+ return -1;
+
+ hvcaps->vendor_id = virXPathString("string(./hypervCapabilities/vendor_id)", ctxt);
+
qemuCaps->hypervCapabilities = g_steal_pointer(&hvcaps);
return 0;
}
@@ -5131,6 +5154,25 @@ virQEMUCapsFormatHypervCapabilities(virQEMUCaps *qemuCaps,
virBufferAsprintf(&childBuf, "<cap name='%s'/>\n",
virDomainHypervTypeToString(i));
}
+
+ if (hvcaps->spinlocks != 0) {
+ virBufferAsprintf(&childBuf, "<spinlocks>%u</spinlocks>\n",
+ hvcaps->spinlocks);
+ }
+ if (hvcaps->stimer_direct != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(&childBuf, "<stimer_direct>%s</stimer_direct>\n",
+ virTristateSwitchTypeToString(hvcaps->stimer_direct));
+ }
+ if (hvcaps->tlbflush_direct != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(&childBuf, "<tlbflush_direct>%s</tlbflush_direct>\n",
+ virTristateSwitchTypeToString(hvcaps->tlbflush_direct));
+ }
+ if (hvcaps->tlbflush_extended != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(&childBuf, "<tlbflush_extended>%s</tlbflush_extended>\n",
+ virTristateSwitchTypeToString(hvcaps->tlbflush_extended));
+ }
+ virBufferEscapeString(&childBuf, "<vendor_id>%s</vendor_id>\n",
+ hvcaps->vendor_id);
}
return virXMLFormatElement(buf, "hypervCapabilities", &attrBuf, &childBuf);
--
2.51.1

View File

@ -0,0 +1,56 @@
From c07935fbeaef24de98089398b800c86afb84d0c4 Mon Sep 17 00:00:00 2001
Message-ID: <c07935fbeaef24de98089398b800c86afb84d0c4.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 29 Sep 2025 14:53:58 +0200
Subject: [PATCH] qemu_caps: Introduce virQEMUCapsGetHypervCapabilities()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We'll need to access hypervCapabilities memeber later on.
Introduce a getter function.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 4545827ba39b61b4c206576b8381fe455635291f)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_capabilities.c | 7 +++++++
src/qemu/qemu_capabilities.h | 3 +++
2 files changed, 10 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index edd4494fa1..7273f59175 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2691,6 +2691,13 @@ virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps)
}
+virDomainCapsFeatureHyperv *
+virQEMUCapsGetHypervCapabilities(virQEMUCaps *qemuCaps)
+{
+ return qemuCaps->hypervCapabilities;
+}
+
+
static int
virQEMUCapsProbeQMPObjectTypes(virQEMUCaps *qemuCaps,
qemuMonitor *mon)
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 1334a668f0..9cce91d643 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -934,6 +934,9 @@ virQEMUCapsGetSEVCapabilities(virQEMUCaps *qemuCaps);
virSGXCapability *
virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps);
+virDomainCapsFeatureHyperv *
+virQEMUCapsGetHypervCapabilities(virQEMUCaps *qemuCaps);
+
bool
virQEMUCapsGetKVMSupportsSecureGuest(virQEMUCaps *qemuCaps) G_NO_INLINE;
--
2.51.1

View File

@ -0,0 +1,37 @@
From 3ccbf88062419dc604e9e98e44287fdc65c94bbc Mon Sep 17 00:00:00 2001
Message-ID: <3ccbf88062419dc604e9e98e44287fdc65c94bbc.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 29 Sep 2025 14:54:17 +0200
Subject: [PATCH] qemu_caps: Prefer VIR_DOMAIN_CAPS_ENUM_IS_SET()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
While virDomainCapsEnum is in fact a bitmap, we also have a macro
to manipulate/query individual bits. Prefer it to make the code
more readable.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 727c858d6a837bd26f8cedc7e24c54dbff301e29)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_capabilities.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 4f239ae77b..28d3a78d8c 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -5126,7 +5126,7 @@ virQEMUCapsFormatHypervCapabilities(virQEMUCaps *qemuCaps,
size_t i;
for (i = 0; i < sizeof(hvcaps->features.values) * CHAR_BIT; i++) {
- if (!(hvcaps->features.values & (1U << i)))
+ if (!VIR_DOMAIN_CAPS_ENUM_IS_SET(hvcaps->features, i))
continue;
virBufferAsprintf(&childBuf, "<cap name='%s'/>\n",
--
2.51.1

View File

@ -0,0 +1,193 @@
From 156bc1d762fa4441d9bb5252670a8421e58a3338 Mon Sep 17 00:00:00 2001
Message-ID: <156bc1d762fa4441d9bb5252670a8421e58a3338.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 29 Sep 2025 10:20:20 +0200
Subject: [PATCH] qemu_command: Move hyperv cmd line generation into a function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 8b316fac497dc2a121788fef9d91b22bfd4e343c)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_command.c | 155 ++++++++++++++++++++++------------------
1 file changed, 85 insertions(+), 70 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 5fe39f45ff..705d5ab1a1 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6277,6 +6277,89 @@ qemuBuildCpuModelArgStr(virQEMUDriver *driver,
return 0;
}
+
+static int
+qemuBuildCpuHypervCommandLine(virBuffer *buf,
+ const virDomainDef *def)
+{
+ size_t i;
+
+ if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_DOMAIN_HYPERV_MODE_NONE)
+ return 0;
+
+ switch ((virDomainHyperVMode) def->features[VIR_DOMAIN_FEATURE_HYPERV]) {
+ case VIR_DOMAIN_HYPERV_MODE_CUSTOM:
+ break;
+
+ case VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH:
+ virBufferAsprintf(buf, ",hv-%s=on", "passthrough");
+ break;
+
+ case VIR_DOMAIN_HYPERV_MODE_NONE:
+ case VIR_DOMAIN_HYPERV_MODE_LAST:
+ default:
+ virReportEnumRangeError(virDomainHyperVMode,
+ def->features[VIR_DOMAIN_FEATURE_HYPERV]);
+ return -1;
+ }
+
+ for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
+ switch ((virDomainHyperv) i) {
+ case VIR_DOMAIN_HYPERV_RELAXED:
+ case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_VPINDEX:
+ case VIR_DOMAIN_HYPERV_RUNTIME:
+ case VIR_DOMAIN_HYPERV_SYNIC:
+ case VIR_DOMAIN_HYPERV_STIMER:
+ case VIR_DOMAIN_HYPERV_RESET:
+ case VIR_DOMAIN_HYPERV_FREQUENCIES:
+ case VIR_DOMAIN_HYPERV_REENLIGHTENMENT:
+ case VIR_DOMAIN_HYPERV_TLBFLUSH:
+ case VIR_DOMAIN_HYPERV_IPI:
+ case VIR_DOMAIN_HYPERV_EVMCS:
+ case VIR_DOMAIN_HYPERV_AVIC:
+ case VIR_DOMAIN_HYPERV_EMSR_BITMAP:
+ case VIR_DOMAIN_HYPERV_XMM_INPUT:
+ if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON) {
+ const char *name = virDomainHypervTypeToString(i);
+ g_autofree char *full_name = g_strdup_printf("hv-%s", name);
+ const char *qemu_name = virQEMUCapsCPUFeatureToQEMU(def->os.arch,
+ full_name);
+ virBufferAsprintf(buf, ",%s=on", qemu_name);
+ }
+ if ((i == VIR_DOMAIN_HYPERV_STIMER) &&
+ (def->hyperv_stimer_direct == VIR_TRISTATE_SWITCH_ON))
+ virBufferAsprintf(buf, ",%s=on", VIR_CPU_x86_HV_STIMER_DIRECT);
+ if (i == VIR_DOMAIN_HYPERV_TLBFLUSH) {
+ if (def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON)
+ virBufferAsprintf(buf, ",%s=on", VIR_CPU_x86_HV_TLBFLUSH_DIRECT);
+ if (def->hyperv_tlbflush_extended == VIR_TRISTATE_SWITCH_ON)
+ virBufferAsprintf(buf, ",%s=on", VIR_CPU_x86_HV_TLBFLUSH_EXT);
+ }
+ break;
+
+ case VIR_DOMAIN_HYPERV_SPINLOCKS:
+ if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
+ virBufferAsprintf(buf, ",%s=0x%x",
+ VIR_CPU_x86_HV_SPINLOCKS,
+ def->hyperv_spinlocks);
+ break;
+
+ case VIR_DOMAIN_HYPERV_VENDOR_ID:
+ if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
+ virBufferAsprintf(buf, ",hv-vendor-id=%s",
+ def->hyperv_vendor_id);
+ break;
+
+ case VIR_DOMAIN_HYPERV_LAST:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
static int
qemuBuildCpuCommandLine(virCommand *cmd,
virQEMUDriver *driver,
@@ -6373,76 +6456,8 @@ qemuBuildCpuCommandLine(virCommand *cmd,
VIR_TRISTATE_SWITCH_ON ? "on" : "off");
}
- if (def->features[VIR_DOMAIN_FEATURE_HYPERV] != VIR_DOMAIN_HYPERV_MODE_NONE) {
- switch ((virDomainHyperVMode) def->features[VIR_DOMAIN_FEATURE_HYPERV]) {
- case VIR_DOMAIN_HYPERV_MODE_CUSTOM:
- break;
-
- case VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH:
- virBufferAsprintf(&buf, ",hv-%s=on", "passthrough");
- break;
-
- case VIR_DOMAIN_HYPERV_MODE_NONE:
- case VIR_DOMAIN_HYPERV_MODE_LAST:
- default:
- virReportEnumRangeError(virDomainHyperVMode,
- def->features[VIR_DOMAIN_FEATURE_HYPERV]);
- return -1;
- }
-
- for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
- switch ((virDomainHyperv) i) {
- case VIR_DOMAIN_HYPERV_RELAXED:
- case VIR_DOMAIN_HYPERV_VAPIC:
- case VIR_DOMAIN_HYPERV_VPINDEX:
- case VIR_DOMAIN_HYPERV_RUNTIME:
- case VIR_DOMAIN_HYPERV_SYNIC:
- case VIR_DOMAIN_HYPERV_STIMER:
- case VIR_DOMAIN_HYPERV_RESET:
- case VIR_DOMAIN_HYPERV_FREQUENCIES:
- case VIR_DOMAIN_HYPERV_REENLIGHTENMENT:
- case VIR_DOMAIN_HYPERV_TLBFLUSH:
- case VIR_DOMAIN_HYPERV_IPI:
- case VIR_DOMAIN_HYPERV_EVMCS:
- case VIR_DOMAIN_HYPERV_AVIC:
- case VIR_DOMAIN_HYPERV_EMSR_BITMAP:
- case VIR_DOMAIN_HYPERV_XMM_INPUT:
- if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON) {
- const char *name = virDomainHypervTypeToString(i);
- g_autofree char *full_name = g_strdup_printf("hv-%s", name);
- const char *qemu_name = virQEMUCapsCPUFeatureToQEMU(def->os.arch,
- full_name);
- virBufferAsprintf(&buf, ",%s=on", qemu_name);
- }
- if ((i == VIR_DOMAIN_HYPERV_STIMER) &&
- (def->hyperv_stimer_direct == VIR_TRISTATE_SWITCH_ON))
- virBufferAsprintf(&buf, ",%s=on", VIR_CPU_x86_HV_STIMER_DIRECT);
- if (i == VIR_DOMAIN_HYPERV_TLBFLUSH) {
- if (def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON)
- virBufferAsprintf(&buf, ",%s=on", VIR_CPU_x86_HV_TLBFLUSH_DIRECT);
- if (def->hyperv_tlbflush_extended == VIR_TRISTATE_SWITCH_ON)
- virBufferAsprintf(&buf, ",%s=on", VIR_CPU_x86_HV_TLBFLUSH_EXT);
- }
- break;
-
- case VIR_DOMAIN_HYPERV_SPINLOCKS:
- if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
- virBufferAsprintf(&buf, ",%s=0x%x",
- VIR_CPU_x86_HV_SPINLOCKS,
- def->hyperv_spinlocks);
- break;
-
- case VIR_DOMAIN_HYPERV_VENDOR_ID:
- if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
- virBufferAsprintf(&buf, ",hv-vendor-id=%s",
- def->hyperv_vendor_id);
- break;
-
- case VIR_DOMAIN_HYPERV_LAST:
- break;
- }
- }
- }
+ if (qemuBuildCpuHypervCommandLine(&buf, def) < 0)
+ return -1;
for (i = 0; i < def->npanics; i++) {
if (def->panics[i]->model == VIR_DOMAIN_PANIC_MODEL_HYPERV) {
--
2.51.1

View File

@ -0,0 +1,37 @@
From f8b5688caf50edd2b6a07948032ec30f6b3e2b7c Mon Sep 17 00:00:00 2001
Message-ID: <f8b5688caf50edd2b6a07948032ec30f6b3e2b7c.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 29 Sep 2025 13:50:18 +0200
Subject: [PATCH] qemu_command: Prefer virBufferAddLit() in
qemuBuildCpuHypervCommandLine()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Using virBufferAsprintf() just to concatenate two literal strings
is excessive. Use virBufferAddLit().
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit c66bbac8d56df24674ab15202e4b5611766524d7)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_command.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 705d5ab1a1..13e23c7ee3 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6292,7 +6292,7 @@ qemuBuildCpuHypervCommandLine(virBuffer *buf,
break;
case VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH:
- virBufferAsprintf(buf, ",hv-%s=on", "passthrough");
+ virBufferAddLit(buf, ",hv-passthrough=on");
break;
case VIR_DOMAIN_HYPERV_MODE_NONE:
--
2.51.1

View File

@ -0,0 +1,74 @@
From 331e4aed19e8693b41aafb2397d135ab0e8edcab Mon Sep 17 00:00:00 2001
Message-ID: <331e4aed19e8693b41aafb2397d135ab0e8edcab.1763747165.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 24 Oct 2025 15:27:03 +0200
Subject: [PATCH] qemu_domain: Fix qemuDomainFixupCPUs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The function was apparently created when the list of ignored CPU
features contained just cmt and related features. The list grew quite a
bit since then and this function stopped making sense as it would remove
all ignored features from CPU definitions but only if cmt was present.
The issue with cmt is long gone and this function was not really doing
anything. Surprisingly this didn't cause any real issues as we don't
update CPU definitions with features unknown to QEMU. But we may still
want to remove ignored features even though QEMU knows about them for
compatibility reasons.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 2ab6925218df7298c17f0186425624aa792a5e84)
https://issues.redhat.com/browse/RHEL-126096
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_domain.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 5f96e34866..ba89015a55 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -9430,15 +9430,20 @@ qemuDomainUpdateCPU(virDomainObj *vm,
/**
- * qemuDomainFixupCPUS:
+ * qemuDomainFixupCPUs:
* @vm: domain object
* @origCPU: original CPU used when the domain was started
*
* Libvirt older than 3.9.0 could have messed up the expansion of host-model
* CPU when reconnecting to a running domain by adding features QEMU does not
- * support (such as cmt). This API fixes both the actual CPU provided by QEMU
- * (stored in the domain object) and the @origCPU used when starting the
- * domain.
+ * support (such as cmt).
+ *
+ * Newer libvirt would not include feature unknown to QEMU, but the CPU
+ * definitions could contain features that were removed from QEMU and added to
+ * our list of ignored features as they were not actually doing anything.
+ *
+ * This API fixes both the actual CPU provided by QEMU (stored in the domain
+ * object) and the @origCPU used when starting the domain.
*
* This is safe even if the original CPU definition used mode='custom' (rather
* than host-model) since we know QEMU was able to start the domain and thus
@@ -9468,11 +9473,8 @@ qemuDomainFixupCPUs(virDomainObj *vm,
if (!origCPU)
return;
- if (virCPUDefFindFeature(vm->def->cpu, "cmt"))
- virCPUDefFilterFeatures(vm->def->cpu, virQEMUCapsCPUFilterFeatures, &arch);
-
- if (virCPUDefFindFeature(origCPU, "cmt"))
- virCPUDefFilterFeatures(origCPU, virQEMUCapsCPUFilterFeatures, &arch);
+ virCPUDefFilterFeatures(vm->def->cpu, virQEMUCapsCPUFilterFeatures, &arch);
+ virCPUDefFilterFeatures(origCPU, virQEMUCapsCPUFilterFeatures, &arch);
}
--
2.51.1

View File

@ -0,0 +1,108 @@
From 6efbe939d36af3dfe530d40723323ff13331450a Mon Sep 17 00:00:00 2001
Message-ID: <6efbe939d36af3dfe530d40723323ff13331450a.1763747165.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 24 Oct 2025 15:13:49 +0200
Subject: [PATCH] qemu_domain: Simplify qemuDomainFixupCPUs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Since virCPUDefFilterFeatures never fails, we can use it for in-place
modifications instead of modifying a temporary virCPUDef copy.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit fbf44bc8cf63ab5c7641f1aa04aaf7fb5eaab62e)
https://issues.redhat.com/browse/RHEL-126096
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_domain.c | 26 ++++++--------------------
src/qemu/qemu_domain.h | 2 +-
src/qemu/qemu_process.c | 4 ++--
3 files changed, 9 insertions(+), 23 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 21a4169c58..5f96e34866 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -9449,7 +9449,7 @@ qemuDomainUpdateCPU(virDomainObj *vm,
*/
void
qemuDomainFixupCPUs(virDomainObj *vm,
- virCPUDef **origCPU)
+ virCPUDef *origCPU)
{
virArch arch = vm->def->os.arch;
@@ -9465,28 +9465,14 @@ qemuDomainFixupCPUs(virDomainObj *vm,
* we asked for or libvirt was too old to mess up the translation from
* host-model.
*/
- if (!*origCPU)
+ if (!origCPU)
return;
- if (virCPUDefFindFeature(vm->def->cpu, "cmt")) {
- g_autoptr(virCPUDef) fixedCPU = virCPUDefCopyWithoutModel(vm->def->cpu);
+ if (virCPUDefFindFeature(vm->def->cpu, "cmt"))
+ virCPUDefFilterFeatures(vm->def->cpu, virQEMUCapsCPUFilterFeatures, &arch);
- virCPUDefCopyModelFilter(fixedCPU, vm->def->cpu, false,
- virQEMUCapsCPUFilterFeatures, &arch);
-
- virCPUDefFree(vm->def->cpu);
- vm->def->cpu = g_steal_pointer(&fixedCPU);
- }
-
- if (virCPUDefFindFeature(*origCPU, "cmt")) {
- g_autoptr(virCPUDef) fixedOrig = virCPUDefCopyWithoutModel(*origCPU);
-
- virCPUDefCopyModelFilter(fixedOrig, *origCPU, false,
- virQEMUCapsCPUFilterFeatures, &arch);
-
- virCPUDefFree(*origCPU);
- *origCPU = g_steal_pointer(&fixedOrig);
- }
+ if (virCPUDefFindFeature(origCPU, "cmt"))
+ virCPUDefFilterFeatures(origCPU, virQEMUCapsCPUFilterFeatures, &arch);
}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index d787d2a065..41daea01d7 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -1002,7 +1002,7 @@ qemuDomainUpdateCPU(virDomainObj *vm,
void
qemuDomainFixupCPUs(virDomainObj *vm,
- virCPUDef **origCPU);
+ virCPUDef *origCPU);
char *
qemuDomainGetMachineName(virDomainObj *vm);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index f5f9d4a348..7c16390e8f 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8640,7 +8640,7 @@ qemuProcessStartWithMemoryState(virConnectPtr conn,
* the CPU definitions.
*/
if (cookie)
- qemuDomainFixupCPUs(vm, &cookie->cpu);
+ qemuDomainFixupCPUs(vm, cookie->cpu);
if (cookie && !cookie->slirpHelper)
priv->disableSlirp = true;
@@ -9453,7 +9453,7 @@ qemuProcessRefreshCPU(virQEMUDriver *driver,
* case the host-model is known to not contain features which QEMU
* doesn't know about.
*/
- qemuDomainFixupCPUs(vm, &priv->origCPU);
+ qemuDomainFixupCPUs(vm, priv->origCPU);
}
return 0;
--
2.51.1

View File

@ -0,0 +1,182 @@
From fd576f22b2c25d086b73f6e3798d81f03bbc609d Mon Sep 17 00:00:00 2001
Message-ID: <fd576f22b2c25d086b73f6e3798d81f03bbc609d.1763747165.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 24 Oct 2025 17:16:32 +0200
Subject: [PATCH] qemu_monitor: Filter CPU features reported by QEMU
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Some features may be on our ignore list because they do nothing even
though QEMU still supports them and reports their state. But as the
features do nothing, the state reported by QEMU may not correspond to
what the guest sees. To avoid possible confusion we may just pretend
QEMU did not report any of the features on our ignore list.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 4d5c1bc24119e90dfbcdae6a120027e5c1ede608)
https://issues.redhat.com/browse/RHEL-126096
Conflicts:
src/qemu/qemu_monitor.c
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c
src/qemu/qemu_process.c
tests/qemumonitorjsontest.c
- the qom-list-get series optimizing CPU feature probing was
not backported
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_monitor.c | 6 ++++--
src/qemu/qemu_monitor.h | 1 +
src/qemu/qemu_monitor_json.c | 18 +++++++++++++++---
src/qemu/qemu_monitor_json.h | 1 +
src/qemu/qemu_process.c | 1 +
5 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index a9fe4f2f6b..ecf54a5dda 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3735,7 +3735,8 @@ qemuMonitorGetGuestCPUx86(qemuMonitor *mon,
* @arch: CPU architecture
* @cpuQOMPath: QOM path of a CPU to probe
* @translate: callback for translating CPU feature names from QEMU to libvirt
- * @opaque: data for @translate callback
+ * @filter: callback for filtering ignored features, a pointer to @arch is
+ * passed as opaque pointer to the callback
* @enabled: returns the CPU data for all enabled features
* @disabled: returns the CPU data for features which we asked for
* (either explicitly or via a named CPU model) but QEMU disabled them
@@ -3749,6 +3750,7 @@ qemuMonitorGetGuestCPU(qemuMonitor *mon,
virArch arch,
const char *cpuQOMPath,
qemuMonitorCPUFeatureTranslationCallback translate,
+ virCPUDefFeatureFilter filter,
virCPUData **enabled,
virCPUData **disabled)
{
@@ -3762,7 +3764,7 @@ qemuMonitorGetGuestCPU(qemuMonitor *mon,
*disabled = NULL;
return qemuMonitorJSONGetGuestCPU(mon, arch, cpuQOMPath, translate,
- enabled, disabled);
+ filter, enabled, disabled);
}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index d4730162ca..12e5388e0b 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1273,6 +1273,7 @@ int qemuMonitorGetGuestCPU(qemuMonitor *mon,
virArch arch,
const char *cpuQOMPath,
qemuMonitorCPUFeatureTranslationCallback translate,
+ virCPUDefFeatureFilter filter,
virCPUData **enabled,
virCPUData **disabled);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index cbe10ad907..cedf761018 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -6769,6 +6769,7 @@ static int
qemuMonitorJSONGetCPUData(qemuMonitor *mon,
const char *cpuQOMPath,
qemuMonitorCPUFeatureTranslationCallback translate,
+ virCPUDefFeatureFilter filter,
virCPUData *data)
{
qemuMonitorJSONObjectProperty prop = { .type = QEMU_MONITOR_OBJECT_PROPERTY_BOOLEAN };
@@ -6790,6 +6791,9 @@ qemuMonitorJSONGetCPUData(qemuMonitor *mon,
if (translate)
name = translate(data->arch, name);
+ if (filter && !filter(name, VIR_CPU_FEATURE_REQUIRE, &data->arch))
+ continue;
+
if (virCPUDataAddFeature(data, name) < 0)
return -1;
}
@@ -6802,6 +6806,7 @@ static int
qemuMonitorJSONGetCPUDataDisabled(qemuMonitor *mon,
const char *cpuQOMPath,
qemuMonitorCPUFeatureTranslationCallback translate,
+ virCPUDefFeatureFilter filter,
virCPUData *data)
{
g_auto(GStrv) props = NULL;
@@ -6817,6 +6822,9 @@ qemuMonitorJSONGetCPUDataDisabled(qemuMonitor *mon,
if (translate)
name = translate(data->arch, name);
+ if (filter && !filter(name, VIR_CPU_FEATURE_REQUIRE, &data->arch))
+ continue;
+
if (virCPUDataAddFeature(data, name) < 0)
return -1;
}
@@ -6831,7 +6839,8 @@ qemuMonitorJSONGetCPUDataDisabled(qemuMonitor *mon,
* @arch: CPU architecture
* @cpuQOMPath: QOM path of a CPU to probe
* @translate: callback for translating CPU feature names from QEMU to libvirt
- * @opaque: data for @translate callback
+ * @filter: callback for filtering ignored features, a pointer to @arch is
+ * passed as opaque pointer to the callback
* @enabled: returns the CPU data for all enabled features
* @disabled: returns the CPU data for features which we asked for
* (either explicitly or via a named CPU model) but QEMU disabled them
@@ -6845,6 +6854,7 @@ qemuMonitorJSONGetGuestCPU(qemuMonitor *mon,
virArch arch,
const char *cpuQOMPath,
qemuMonitorCPUFeatureTranslationCallback translate,
+ virCPUDefFeatureFilter filter,
virCPUData **enabled,
virCPUData **disabled)
{
@@ -6855,11 +6865,13 @@ qemuMonitorJSONGetGuestCPU(qemuMonitor *mon,
!(cpuDisabled = virCPUDataNew(arch)))
return -1;
- if (qemuMonitorJSONGetCPUData(mon, cpuQOMPath, translate, cpuEnabled) < 0)
+ if (qemuMonitorJSONGetCPUData(mon, cpuQOMPath, translate, filter,
+ cpuEnabled) < 0)
return -1;
if (disabled &&
- qemuMonitorJSONGetCPUDataDisabled(mon, cpuQOMPath, translate, cpuDisabled) < 0)
+ qemuMonitorJSONGetCPUDataDisabled(mon, cpuQOMPath, translate, filter,
+ cpuDisabled) < 0)
return -1;
*enabled = g_steal_pointer(&cpuEnabled);
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 68f60aec61..fb1a3cef44 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -576,6 +576,7 @@ qemuMonitorJSONGetGuestCPU(qemuMonitor *mon,
virArch arch,
const char *cpuQOMPath,
qemuMonitorCPUFeatureTranslationCallback translate,
+ virCPUDefFeatureFilter filter,
virCPUData **enabled,
virCPUData **disabled);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 561c04f879..f24f5c8b92 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4561,6 +4561,7 @@ qemuProcessFetchGuestCPU(virDomainObj *vm,
vm->def->os.arch,
cpuQOMPath,
virQEMUCapsCPUFeatureFromQEMU,
+ virQEMUCapsCPUFilterFeatures,
&dataEnabled, &dataDisabled);
} else {
rc = qemuMonitorGetGuestCPUx86(priv->mon, cpuQOMPath, &dataEnabled, &dataDisabled);
--
2.51.1

View File

@ -0,0 +1,46 @@
From 132d30089ba007c53098f4b381dfd38db07ad1a0 Mon Sep 17 00:00:00 2001
Message-ID: <132d30089ba007c53098f4b381dfd38db07ad1a0.1763747165.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 24 Oct 2025 15:36:18 +0200
Subject: [PATCH] qemu_process: Always fix CPUs on reconnect
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We fix CPUs (i.e., remove ignored CPU features) only when libvirt/QEMU
combo used to start the domain is very old and doesn't support
query-cpu-model-expansion, in which case the CPU definition may contain
features that are unknown to QEMU. But even if both libvirt and QEMU are
new enough, we still want to remove features that do nothing to minimize
confusion or to avoid false migration issues.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit c15ae99dab903004b82f8447f44df09973696f72)
https://issues.redhat.com/browse/RHEL-126096
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_process.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 7c16390e8f..561c04f879 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -9447,12 +9447,7 @@ qemuProcessRefreshCPU(virQEMUDriver *driver,
if (qemuProcessUpdateCPU(vm, VIR_ASYNC_JOB_NONE) < 0)
return -1;
- } else if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) {
- /* We only try to fix CPUs when the libvirt/QEMU combo used to start
- * the domain did not know about query-cpu-model-expansion in which
- * case the host-model is known to not contain features which QEMU
- * doesn't know about.
- */
+ } else {
qemuDomainFixupCPUs(vm, priv->origCPU);
}
--
2.51.1

View File

@ -0,0 +1,150 @@
From edf171344cf52ab53e1bf5672badf5d621d3aa79 Mon Sep 17 00:00:00 2001
Message-ID: <edf171344cf52ab53e1bf5672badf5d621d3aa79.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 29 Sep 2025 14:54:23 +0200
Subject: [PATCH] qemu_process: Populate hyperv features for host-model
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Pretty straightforward. The only "weird" thing here is that
'hv-time' enlightenment is exposed as a <timer/> under <clock/>
element. Since it's required by 'hv-stimer' and
'hv-stimer-direct' it needs to be enabled too.
Resolves: https://issues.redhat.com/browse/RHEL-114003
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 8458bb521ea4bb7b50d8d5f6ffea4e2d2fe8f0f5)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_command.c | 2 +-
src/qemu/qemu_process.c | 72 +++++++++++++++++++
.../hyperv-host-model.x86_64-latest.args | 2 +-
3 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 61aeb14757..a9e1f7a8f8 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6289,13 +6289,13 @@ qemuBuildCpuHypervCommandLine(virBuffer *buf,
switch ((virDomainHyperVMode) def->features[VIR_DOMAIN_FEATURE_HYPERV]) {
case VIR_DOMAIN_HYPERV_MODE_CUSTOM:
- case VIR_DOMAIN_HYPERV_MODE_HOST_MODEL:
break;
case VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH:
virBufferAddLit(buf, ",hv-passthrough=on");
break;
+ case VIR_DOMAIN_HYPERV_MODE_HOST_MODEL:
case VIR_DOMAIN_HYPERV_MODE_NONE:
case VIR_DOMAIN_HYPERV_MODE_LAST:
default:
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 798dabaf0a..e2e2822013 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6795,6 +6795,75 @@ qemuProcessPrepareChardevSource(virDomainDef *def,
}
+static void
+qemuProcessMaybeAddHypervTimer(virDomainDef *def)
+{
+ g_autofree virDomainTimerDef *timer = NULL;
+
+ if (virDomainDefHasTimer(def, VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK))
+ return;
+
+ timer = g_new0(virDomainTimerDef, 1);
+ timer->name = VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK;
+ timer->present = VIR_TRISTATE_BOOL_YES;
+
+ VIR_APPEND_ELEMENT(def->clock.timers, def->clock.ntimers, timer);
+}
+
+
+static int
+qemuProcessEnableDomainFeatures(virDomainObj *vm)
+{
+ virDomainCapsFeatureHyperv *hv = NULL;
+ qemuDomainObjPrivate *priv = vm->privateData;
+ size_t i;
+
+ if (vm->def->features[VIR_DOMAIN_FEATURE_HYPERV] != VIR_DOMAIN_HYPERV_MODE_HOST_MODEL)
+ return 0;
+
+ hv = virQEMUCapsGetHypervCapabilities(priv->qemuCaps);
+ if (!hv || hv->supported != VIR_TRISTATE_BOOL_YES) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("host-model hyperv mode unsupported, no hyperv capabilities found"));
+ return -1;
+ }
+
+ for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
+ if (!VIR_DOMAIN_CAPS_ENUM_IS_SET(hv->features, i))
+ continue;
+
+ vm->def->hyperv.features[i] = VIR_TRISTATE_SWITCH_ON;
+
+ if (i == VIR_DOMAIN_HYPERV_SPINLOCKS) {
+ if (hv->spinlocks != 0) {
+ vm->def->hyperv.spinlocks = hv->spinlocks;
+ } else {
+ vm->def->hyperv.features[i] = VIR_TRISTATE_SWITCH_ABSENT;
+ }
+ } else if (i == VIR_DOMAIN_HYPERV_STIMER) {
+ vm->def->hyperv.stimer_direct = hv->stimer_direct;
+ /* Both hv-stimer and hv-stimer-direct require hv-time which is
+ * expose as a timer. Enable it. */
+ qemuProcessMaybeAddHypervTimer(vm->def);
+ } else if (i == VIR_DOMAIN_HYPERV_TLBFLUSH) {
+ vm->def->hyperv.tlbflush_direct = hv->tlbflush_direct;
+ vm->def->hyperv.tlbflush_extended = hv->tlbflush_extended;
+ } else if (i == VIR_DOMAIN_HYPERV_VENDOR_ID) {
+ if (hv->vendor_id) {
+ vm->def->hyperv.vendor_id = g_strdup(hv->vendor_id);
+ } else {
+ vm->def->hyperv.features[i] = VIR_TRISTATE_SWITCH_ABSENT;
+ }
+ }
+ }
+
+ vm->def->features[VIR_DOMAIN_FEATURE_HYPERV] = VIR_DOMAIN_HYPERV_MODE_CUSTOM;
+
+ return 0;
+}
+
+
+
/**
* qemuProcessPrepareDomain:
* @driver: qemu driver
@@ -6908,6 +6977,9 @@ qemuProcessPrepareDomain(virQEMUDriver *driver,
VIR_DEBUG("Aligning guest memory");
if (qemuDomainAlignMemorySizes(vm->def) < 0)
return -1;
+
+ if (qemuProcessEnableDomainFeatures(vm) < 0)
+ return -1;
}
for (i = 0; i < vm->def->nchannels; i++) {
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
index 2ed72fcd1b..58502ff51e 100644
--- a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=on \
-accel tcg \
--cpu qemu64 \
+-cpu 'qemu64,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0xfff,hv-vpindex=on,hv-runtime=on,hv-synic=on,hv-stimer=on,hv-stimer-direct=on,hv-reset=on,hv-vendor-id=Linux KVM Hv,hv-frequencies=on,hv-reenlightenment=on,hv-tlbflush=on,hv-tlbflush-direct=on,hv-tlbflush-ext=on,hv-ipi=on,hv-avic=on,hv-emsr-bitmap=on,hv-xmm-input=on' \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
--
2.51.1

View File

@ -0,0 +1,42 @@
From 552bba4e9631fd324b061d2405d0ae3a49f116e3 Mon Sep 17 00:00:00 2001
Message-ID: <552bba4e9631fd324b061d2405d0ae3a49f116e3.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 8 Oct 2025 10:51:53 +0200
Subject: [PATCH] qemu_validate: Reflect dependencies of hv-evmcs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Per QEMU documentation (docs/system/i386/hyperv.rst):
``hv-evmcs``
The enlightenment is nested specific, it targets Hyper-V on KVM guests. <snip/>
Requires: ``hv-vapic``
Reflect this dependency when validating domain definition.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit c6114de13c473bfd131fd64863ad9ccd18238ae5)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_validate.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 8e8c9c5c1d..3d07c23ea5 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -131,6 +131,8 @@ qemuValidateDomainDefHypervFeatures(const virDomainDef *def)
CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_IPI, VIR_DOMAIN_HYPERV_VPINDEX);
+ CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_EVMCS, VIR_DOMAIN_HYPERV_VAPIC);
+
return 0;
}
--
2.51.1

View File

@ -0,0 +1,42 @@
From 26f42f59d3ab109e2f9390b18339fe5a9c62a1b5 Mon Sep 17 00:00:00 2001
Message-ID: <26f42f59d3ab109e2f9390b18339fe5a9c62a1b5.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 8 Oct 2025 10:50:32 +0200
Subject: [PATCH] qemu_validate: Reflect dependencies of hv-ipi
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Per QEMU documentation (docs/system/i386/hyperv.rst):
``hv-ipi``
Enables paravirtualized IPI send mechanism. <snip/>
Requires: ``hv-vpindex``
Reflect this dependency when validating domain definition.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit f4557315f32747d45cf2da78af6e009f513892f4)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_validate.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 33fec89134..8e8c9c5c1d 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -129,6 +129,8 @@ qemuValidateDomainDefHypervFeatures(const virDomainDef *def)
CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_TLBFLUSH, VIR_DOMAIN_HYPERV_VPINDEX);
+ CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_IPI, VIR_DOMAIN_HYPERV_VPINDEX);
+
return 0;
}
--
2.51.1

View File

@ -0,0 +1,53 @@
From edef2af6d026dd6293f9acec5581851554825ed4 Mon Sep 17 00:00:00 2001
Message-ID: <edef2af6d026dd6293f9acec5581851554825ed4.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 7 Oct 2025 13:42:19 +0200
Subject: [PATCH] qemu_validate: Reflect dependencies of hv-stimer
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Per QEMU documentation (docs/system/i386/hyperv.rst):
``hv-stimer``
Enables Hyper-V synthetic timers. <snip/>
Requires: ``hv-vpindex``, ``hv-synic``, ``hv-time``
Reflect these dependencies when validating domain definition.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit da261327ea94300d1aa2d3b76ba9dcd4de6160f6)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_validate.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index f7543cbc14..4cbbc59f2c 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -114,6 +114,19 @@ qemuValidateDomainDefHypervFeatures(const virDomainDef *def)
CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_SYNIC, VIR_DOMAIN_HYPERV_VPINDEX);
+ if (def->hyperv_features[VIR_DOMAIN_HYPERV_STIMER] == VIR_TRISTATE_SWITCH_ON) {
+ if (!virDomainDefHasTimer(def, VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("'%1$s' hyperv feature requires '%2$s' timer"),
+ virDomainHypervTypeToString(VIR_DOMAIN_HYPERV_STIMER),
+ virDomainTimerNameTypeToString(VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK));
+ return -1;
+ }
+ }
+
+ CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_STIMER, VIR_DOMAIN_HYPERV_VPINDEX);
+ CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_STIMER, VIR_DOMAIN_HYPERV_SYNIC);
+
return 0;
}
--
2.51.1

View File

@ -0,0 +1,89 @@
From a8ad71a626a29d6c8b855d32132a5a5f1cfee941 Mon Sep 17 00:00:00 2001
Message-ID: <a8ad71a626a29d6c8b855d32132a5a5f1cfee941.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 8 Oct 2025 09:56:50 +0200
Subject: [PATCH] qemu_validate: Reflect dependencies of hv-synic
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Per QEMU documentation (docs/system/i386/hyperv.rst):
``hv-synic``
Enables Hyper-V Synthetic interrupt controller <snip/>
Requires: ``hv-vpindex``
Reflect this dependency when validating domain definition.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 1822d030c32d9857020ee8385b0a8808a29a472f)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_validate.c | 42 ++++++++++++++++++++++++++++++++--------
1 file changed, 34 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 6c711444eb..f7543cbc14 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -88,6 +88,38 @@ qemuValidateDomainDefPSeriesFeature(const virDomainDef *def,
}
+#define CHECK_HV_FEAT(feat, requires) \
+ if (def->hyperv_features[feat] == VIR_TRISTATE_SWITCH_ON && \
+ def->hyperv_features[requires] != VIR_TRISTATE_SWITCH_ON) { \
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \
+ _("'%1$s' hyperv feature requires '%2$s' feature"), \
+ virDomainHypervTypeToString(feat), \
+ virDomainHypervTypeToString(requires)); \
+ return -1; \
+ }
+
+static int
+qemuValidateDomainDefHypervFeatures(const virDomainDef *def)
+{
+ if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_DOMAIN_HYPERV_MODE_NONE)
+ return 0;
+
+ if (!ARCH_IS_X86(def->os.arch) && !qemuDomainIsARMVirt(def)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Hyperv features are not supported for architecture '%1$s' or machine type '%2$s'"),
+ virArchToString(def->os.arch),
+ def->os.machine);
+ return -1;
+ }
+
+ CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_SYNIC, VIR_DOMAIN_HYPERV_VPINDEX);
+
+ return 0;
+}
+
+#undef CHECK_HV_FEAT
+
+
static int
qemuValidateDomainDefFeatures(const virDomainDef *def,
virQEMUCaps *qemuCaps)
@@ -187,14 +219,8 @@ qemuValidateDomainDefFeatures(const virDomainDef *def,
break;
case VIR_DOMAIN_FEATURE_HYPERV:
- if (def->features[i] != VIR_DOMAIN_HYPERV_MODE_NONE &&
- !ARCH_IS_X86(def->os.arch) && !qemuDomainIsARMVirt(def)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Hyperv features are not supported for architecture '%1$s' or machine type '%2$s'"),
- virArchToString(def->os.arch),
- def->os.machine);
- return -1;
- }
+ if (qemuValidateDomainDefHypervFeatures(def) < 0)
+ return -1;
break;
case VIR_DOMAIN_FEATURE_PMU:
--
2.51.1

View File

@ -0,0 +1,51 @@
From 2e6abea3a9ab2e6c32279d9513bab291d4095d94 Mon Sep 17 00:00:00 2001
Message-ID: <2e6abea3a9ab2e6c32279d9513bab291d4095d94.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 8 Oct 2025 12:24:12 +0200
Subject: [PATCH] qemu_validate: Reflect dependencies of hv-tlbflush-direct
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Per QEMU documentation (docs/system/i386/hyperv.rst):
``hv-tlbflush-direct``
The enlightenment is nested specific, it targets Hyper-V on KVM guests. <snip/>
Requires: ``hv-vapic``
Reflect this dependency when validating domain definition.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 1d2873f9c6f8de24b47183249cc137861413ea56)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_validate.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 3d07c23ea5..22565d9e36 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -133,6 +133,17 @@ qemuValidateDomainDefHypervFeatures(const virDomainDef *def)
CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_EVMCS, VIR_DOMAIN_HYPERV_VAPIC);
+ if (def->hyperv_features[VIR_DOMAIN_HYPERV_TLBFLUSH] == VIR_TRISTATE_SWITCH_ON &&
+ def->hyperv_tlbflush_direct == VIR_TRISTATE_SWITCH_ON) {
+ if (def->hyperv_features[VIR_DOMAIN_HYPERV_VAPIC] != VIR_TRISTATE_SWITCH_ON) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("'%1$s' hyperv feature requires '%2$s' feature"),
+ VIR_CPU_x86_HV_TLBFLUSH_DIRECT,
+ virDomainHypervTypeToString(VIR_DOMAIN_HYPERV_VAPIC));
+ return -1;
+ }
+ }
+
return 0;
}
--
2.51.1

View File

@ -0,0 +1,42 @@
From 95ac8bf578f14bb95d80eb663c4683897d909dcd Mon Sep 17 00:00:00 2001
Message-ID: <95ac8bf578f14bb95d80eb663c4683897d909dcd.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 8 Oct 2025 10:48:07 +0200
Subject: [PATCH] qemu_validate: Reflect dependencies of hv-tlbflush
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Per QEMU documentation (docs/system/i386/hyperv.rst):
``hv-tlbflush``
Enables paravirtualized TLB shoot-down mechanism. <snip/>
Requires: ``hv-vpindex``
Reflect this dependency when validating domain definition.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 941af83360d1aa57d8dec1b0af85d8cde18c7c04)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_validate.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 4cbbc59f2c..33fec89134 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -127,6 +127,8 @@ qemuValidateDomainDefHypervFeatures(const virDomainDef *def)
CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_STIMER, VIR_DOMAIN_HYPERV_VPINDEX);
CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_STIMER, VIR_DOMAIN_HYPERV_SYNIC);
+ CHECK_HV_FEAT(VIR_DOMAIN_HYPERV_TLBFLUSH, VIR_DOMAIN_HYPERV_VPINDEX);
+
return 0;
}
--
2.51.1

View File

@ -0,0 +1,114 @@
From ee8d4bd99dcfbd853d066cda904b989a0c8156c7 Mon Sep 17 00:00:00 2001
Message-ID: <ee8d4bd99dcfbd853d066cda904b989a0c8156c7.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 7 Oct 2025 11:54:21 +0200
Subject: [PATCH] qemuxmlconfdata: Adjust hv-stimer related tests
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In QEMU, hv-stimer and hv-stimer-direct require hv-time. Reflect
this fact in our tests.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit da76c1e8fe40ee2bb0b6f0176fd14908e6a21fb6)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.xml | 4 +++-
tests/qemuxmlconfdata/hyperv-stimer-direct.xml | 4 +++-
tests/qemuxmlconfdata/hyperv.x86_64-latest.args | 2 +-
tests/qemuxmlconfdata/hyperv.x86_64-latest.xml | 4 +++-
tests/qemuxmlconfdata/hyperv.xml | 4 +++-
6 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.args b/tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.args
index b665e5365d..0a6d84fbd2 100644
--- a/tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=on \
-accel tcg \
--cpu qemu64,hv-vpindex=on,hv-synic=on,hv-stimer=on,hv-stimer-direct=on \
+-cpu qemu64,hv-time=on,hv-vpindex=on,hv-synic=on,hv-stimer=on,hv-stimer-direct=on \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.xml b/tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.xml
index efb9d0072e..5f6223bf3e 100644
--- a/tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/hyperv-stimer-direct.x86_64-latest.xml
@@ -21,7 +21,9 @@
<cpu mode='custom' match='exact' check='none'>
<model fallback='forbid'>qemu64</model>
</cpu>
- <clock offset='utc'/>
+ <clock offset='utc'>
+ <timer name='hypervclock' present='yes'/>
+ </clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
diff --git a/tests/qemuxmlconfdata/hyperv-stimer-direct.xml b/tests/qemuxmlconfdata/hyperv-stimer-direct.xml
index 21163b41ad..4116b7a450 100644
--- a/tests/qemuxmlconfdata/hyperv-stimer-direct.xml
+++ b/tests/qemuxmlconfdata/hyperv-stimer-direct.xml
@@ -18,7 +18,9 @@
</stimer>
</hyperv>
</features>
- <clock offset='utc'/>
+ <clock offset='utc'>
+ <timer name='hypervclock' present='yes'/>
+ </clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
diff --git a/tests/qemuxmlconfdata/hyperv.x86_64-latest.args b/tests/qemuxmlconfdata/hyperv.x86_64-latest.args
index 5a32b80e71..30d63bae6b 100644
--- a/tests/qemuxmlconfdata/hyperv.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/hyperv.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=on \
-accel tcg \
--cpu 'qemu64,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x2fff,hv-vpindex=on,hv-runtime=on,hv-synic=on,hv-stimer=on,hv-reset=on,hv-vendor-id=KVM Hv,hv-frequencies=on,hv-reenlightenment=on,hv-tlbflush=on,hv-tlbflush-direct=on,hv-tlbflush-ext=on,hv-ipi=on,hv-evmcs=on,hv-avic=on,hv-emsr-bitmap=on,hv-xmm-input=on' \
+-cpu 'qemu64,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x2fff,hv-vpindex=on,hv-runtime=on,hv-synic=on,hv-stimer=on,hv-reset=on,hv-vendor-id=KVM Hv,hv-frequencies=on,hv-reenlightenment=on,hv-tlbflush=on,hv-tlbflush-direct=on,hv-tlbflush-ext=on,hv-ipi=on,hv-evmcs=on,hv-avic=on,hv-emsr-bitmap=on,hv-xmm-input=on' \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
diff --git a/tests/qemuxmlconfdata/hyperv.x86_64-latest.xml b/tests/qemuxmlconfdata/hyperv.x86_64-latest.xml
index 49537188af..ee412164ed 100644
--- a/tests/qemuxmlconfdata/hyperv.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/hyperv.x86_64-latest.xml
@@ -36,7 +36,9 @@
<cpu mode='custom' match='exact' check='none'>
<model fallback='forbid'>qemu64</model>
</cpu>
- <clock offset='utc'/>
+ <clock offset='utc'>
+ <timer name='hypervclock' present='yes'/>
+ </clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
diff --git a/tests/qemuxmlconfdata/hyperv.xml b/tests/qemuxmlconfdata/hyperv.xml
index 8c323f6578..44aec004a8 100644
--- a/tests/qemuxmlconfdata/hyperv.xml
+++ b/tests/qemuxmlconfdata/hyperv.xml
@@ -33,7 +33,9 @@
<xmm_input state='on'/>
</hyperv>
</features>
- <clock offset='utc'/>
+ <clock offset='utc'>
+ <timer name='hypervclock' present='yes'/>
+ </clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
--
2.51.1

View File

@ -0,0 +1,125 @@
From b8d1da3b78332fca2555c125c0510a70c7df8d7b Mon Sep 17 00:00:00 2001
Message-ID: <b8d1da3b78332fca2555c125c0510a70c7df8d7b.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 7 Oct 2025 09:32:47 +0200
Subject: [PATCH] src: Drop needless typecast to virDomainTimerNameType
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This was missed in v8.10.0-rc1~229 which switched the 'name'
member of _virDomainTimerDef struct from int to
virDomainTimerNameType.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 6b71d327793bbd6d31c953ad33365c160899cc2b)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/libxl/libxl_conf.c | 2 +-
src/libxl/xen_common.c | 2 +-
src/lxc/lxc_cgroup.c | 2 +-
src/lxc/lxc_controller.c | 2 +-
src/qemu/qemu_command.c | 6 +++---
src/qemu/qemu_validate.c | 2 +-
6 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 7d845b97ec..7fe681f1fd 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -397,7 +397,7 @@ libxlMakeDomBuildInfo(virDomainDef *def,
}
for (i = 0; i < clock.ntimers; i++) {
- switch ((virDomainTimerNameType) clock.timers[i]->name) {
+ switch (clock.timers[i]->name) {
case VIR_DOMAIN_TIMER_NAME_TSC:
switch (clock.timers[i]->mode) {
case VIR_DOMAIN_TIMER_MODE_NATIVE:
diff --git a/src/libxl/xen_common.c b/src/libxl/xen_common.c
index 3a64f565f7..0e98b6f9c1 100644
--- a/src/libxl/xen_common.c
+++ b/src/libxl/xen_common.c
@@ -2097,7 +2097,7 @@ xenFormatHypervisorFeatures(virConf *conf, virDomainDef *def)
}
for (i = 0; i < def->clock.ntimers; i++) {
- switch ((virDomainTimerNameType)def->clock.timers[i]->name) {
+ switch (def->clock.timers[i]->name) {
case VIR_DOMAIN_TIMER_NAME_TSC:
switch (def->clock.timers[i]->mode) {
case VIR_DOMAIN_TIMER_MODE_NATIVE:
diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
index 7c889667ba..02e44441b0 100644
--- a/src/lxc/lxc_cgroup.c
+++ b/src/lxc/lxc_cgroup.c
@@ -335,7 +335,7 @@ static int virLXCCgroupSetupDeviceACL(virDomainDef *def,
if (timer->present == VIR_TRISTATE_BOOL_NO)
continue;
- switch ((virDomainTimerNameType)timer->name) {
+ switch (timer->name) {
case VIR_DOMAIN_TIMER_NAME_PLATFORM:
case VIR_DOMAIN_TIMER_NAME_TSC:
case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 7b432a1160..d45e023645 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -1504,7 +1504,7 @@ virLXCControllerSetupTimers(virLXCController *ctrl)
if (timer->present == VIR_TRISTATE_BOOL_NO)
continue;
- switch ((virDomainTimerNameType)timer->name) {
+ switch (timer->name) {
case VIR_DOMAIN_TIMER_NAME_PLATFORM:
case VIR_DOMAIN_TIMER_NAME_TSC:
case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index c6b826a007..5fe39f45ff 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5878,7 +5878,7 @@ qemuBuildClockCommandLine(virCommand *cmd,
}
for (i = 0; i < def->clock.ntimers; i++) {
- switch ((virDomainTimerNameType)def->clock.timers[i]->name) {
+ switch (def->clock.timers[i]->name) {
case VIR_DOMAIN_TIMER_NAME_PLATFORM:
/* qemuDomainDefValidateClockTimers will handle this
* error condition */
@@ -6319,7 +6319,7 @@ qemuBuildCpuCommandLine(virCommand *cmd,
for (i = 0; i < def->clock.ntimers; i++) {
virDomainTimerDef *timer = def->clock.timers[i];
- switch ((virDomainTimerNameType)timer->name) {
+ switch (timer->name) {
case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
if (timer->present != VIR_TRISTATE_BOOL_ABSENT) {
/* QEMU expects on/off -> virTristateSwitch. */
@@ -7023,7 +7023,7 @@ qemuBuildMachineCommandLine(virCommand *cmd,
}
for (i = 0; i < def->clock.ntimers; i++) {
- switch ((virDomainTimerNameType)def->clock.timers[i]->name) {
+ switch (def->clock.timers[i]->name) {
case VIR_DOMAIN_TIMER_NAME_HPET:
/* qemuBuildClockCommandLine handles the old-style config via '-no-hpet' */
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_HPET) &&
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index bbd838c7f0..6c711444eb 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -462,7 +462,7 @@ qemuValidateDomainDefClockTimers(const virDomainDef *def,
for (i = 0; i < def->clock.ntimers; i++) {
virDomainTimerDef *timer = def->clock.timers[i];
- switch ((virDomainTimerNameType)timer->name) {
+ switch (timer->name) {
case VIR_DOMAIN_TIMER_NAME_PLATFORM:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported timer type (name) '%1$s'"),
--
2.51.1

View File

@ -0,0 +1,94 @@
From 85152cf8dd0fe044d3831746e2f5d693778d8da0 Mon Sep 17 00:00:00 2001
Message-ID: <85152cf8dd0fe044d3831746e2f5d693778d8da0.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Thu, 2 Oct 2025 09:29:19 +0200
Subject: [PATCH] virxml: Introduce virXPathTristateBool()
Similarly to other virXPath* functions, let's have a helper that
evaluates an XPath and stores the value into virTristateBool.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit e3e4c620f1af03c35c4f0dc7c8a65ea5464df687)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virxml.c | 34 ++++++++++++++++++++++++++++++++++
src/util/virxml.h | 5 +++++
3 files changed, 40 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0edd526a68..bbe1e252af 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3796,6 +3796,7 @@ virXPathLongLong;
virXPathNode;
virXPathNodeSet;
virXPathString;
+virXPathTristateBool;
virXPathTristateSwitch;
virXPathUInt;
virXPathUIntBase;
diff --git a/src/util/virxml.c b/src/util/virxml.c
index cb0a59ffda..6917253ac0 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -292,6 +292,40 @@ virXPathTristateSwitch(const char *xpath,
}
+/**
+ * virXPathTristateBool:
+ * @xpath: the XPath string to evaluate
+ * @ctxt: an XPath context
+ * @value: the returned virTristateBool value
+ *
+ * Convenience function to evaluate an XPath tristate value. The @xpath
+ * expression must ensure that the evaluated value is returned as a
+ * string (use the 'string()' conversion in the expression).
+ *
+ * Returns 0 in case of success in which case @value is set,
+ * or -1 if the XPath evaluation failed or -2 if the
+ * value isn't of a virTristateBool value.
+ */
+int
+virXPathTristateBool(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ virTristateBool *value)
+{
+ g_autoptr(xmlXPathObject) obj = NULL;
+ int rc;
+
+ if (!(obj = virXPathEvalString(xpath, ctxt)))
+ return -1;
+
+ rc = virTristateBoolTypeFromString((char *)obj->stringval);
+ if (rc < 0)
+ return -2;
+
+ *value = rc;
+ return 0;
+}
+
+
/**
* virXMLCheckIllegalChars:
* @nodeName: Name of checked node
diff --git a/src/util/virxml.h b/src/util/virxml.h
index 3d2de4f976..4d7eb4d25c 100644
--- a/src/util/virxml.h
+++ b/src/util/virxml.h
@@ -78,6 +78,11 @@ virXPathTristateSwitch(const char *xpath,
xmlXPathContextPtr ctxt,
virTristateSwitch *value);
+int
+virXPathTristateBool(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ virTristateBool *value);
+
xmlNodePtr
virXMLNodeGetSubelement(xmlNodePtr node,
const char *name);
--
2.51.1

View File

@ -0,0 +1,98 @@
From 712964c94adb60b390c283d997e398d1c9cd9930 Mon Sep 17 00:00:00 2001
Message-ID: <712964c94adb60b390c283d997e398d1c9cd9930.1763133105.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Thu, 2 Oct 2025 09:26:59 +0200
Subject: [PATCH] virxml: Introduce virXPathTristateSwitch()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Similarly to other virXPath* functions, let's have a helper that
evaluates an XPath and stores the value into virTristateSwitch.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit c689aa80c10242b9c1c4633089ba7ee3f7c1f801)
Resolves: https://issues.redhat.com/browse/RHEL-122930
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virxml.c | 34 ++++++++++++++++++++++++++++++++++
src/util/virxml.h | 5 +++++
3 files changed, 40 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0a1235e6d8..0edd526a68 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3796,6 +3796,7 @@ virXPathLongLong;
virXPathNode;
virXPathNodeSet;
virXPathString;
+virXPathTristateSwitch;
virXPathUInt;
virXPathUIntBase;
virXPathULongLong;
diff --git a/src/util/virxml.c b/src/util/virxml.c
index 51173303fe..cb0a59ffda 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -258,6 +258,40 @@ virXPathLongLong(const char *xpath,
}
+/**
+ * virXPathTristateSwitch:
+ * @xpath: the XPath string to evaluate
+ * @ctxt: an XPath context
+ * @value: the returned virTristateSwitch value
+ *
+ * Convenience function to evaluate an XPath tristate value. The @xpath
+ * expression must ensure that the evaluated value is returned as a
+ * string (use the 'string()' conversion in the expression).
+ *
+ * Returns 0 in case of success in which case @value is set,
+ * or -1 if the XPath evaluation failed or -2 if the
+ * value isn't of a virTristateSwitch value.
+ */
+int
+virXPathTristateSwitch(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ virTristateSwitch *value)
+{
+ g_autoptr(xmlXPathObject) obj = NULL;
+ int rc;
+
+ if (!(obj = virXPathEvalString(xpath, ctxt)))
+ return -1;
+
+ rc = virTristateSwitchTypeFromString((char *)obj->stringval);
+ if (rc < 0)
+ return -2;
+
+ *value = rc;
+ return 0;
+}
+
+
/**
* virXMLCheckIllegalChars:
* @nodeName: Name of checked node
diff --git a/src/util/virxml.h b/src/util/virxml.h
index 06ba324df0..3d2de4f976 100644
--- a/src/util/virxml.h
+++ b/src/util/virxml.h
@@ -73,6 +73,11 @@ virXPathLongLong(const char *xpath,
xmlXPathContextPtr ctxt,
long long *value);
+int
+virXPathTristateSwitch(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ virTristateSwitch *value);
+
xmlNodePtr
virXMLNodeGetSubelement(xmlNodePtr node,
const char *name);
--
2.51.1

View File

@ -289,7 +289,7 @@
Summary: Library providing a simple virtualization API
Name: libvirt
Version: 10.10.0
Release: 15.1%{?dist}%{?extra_release}
Release: 15.4.0.1%{?dist}%{?extra_release}
License: GPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND OFL-1.1
URL: https://libvirt.org/
@ -473,6 +473,37 @@ Patch173: libvirt-qemu-Send-event-VIR_DOMAIN_EVENT_-STOPPED-STARTED-during-recre
Patch174: libvirt-qemu-Support-domain-reset-command-for-TDX-guest.patch
Patch175: libvirt-qemuxmlconftest-Add-latest-version-of-launch-security-tdx-test-data.patch
Patch176: libvirt-docs-domain-Add-documentation-for-Intel-TDX-guest.patch
Patch177: libvirt-conf-Do-not-parse-hyperv-features-with-passthrough-mode.patch
Patch178: libvirt-src-Drop-needless-typecast-to-virDomainTimerNameType.patch
Patch179: libvirt-conf-Introduce-virDomainDefHasTimer.patch
Patch180: libvirt-qemuxmlconfdata-Adjust-hv-stimer-related-tests.patch
Patch181: libvirt-qemu_validate-Reflect-dependencies-of-hv-synic.patch
Patch182: libvirt-qemu_validate-Reflect-dependencies-of-hv-stimer.patch
Patch183: libvirt-qemu_validate-Reflect-dependencies-of-hv-tlbflush.patch
Patch184: libvirt-qemu_validate-Reflect-dependencies-of-hv-ipi.patch
Patch185: libvirt-qemu_validate-Reflect-dependencies-of-hv-evmcs.patch
Patch186: libvirt-qemu_validate-Reflect-dependencies-of-hv-tlbflush-direct.patch
Patch187: libvirt-virxml-Introduce-virXPathTristateSwitch.patch
Patch188: libvirt-virxml-Introduce-virXPathTristateBool.patch
Patch189: libvirt-qemu-Use-virXPathTristateBool.patch
Patch190: libvirt-domain_conf-Move-format-of-hyperv-features-into-a-function.patch
Patch191: libvirt-domain_conf-Use-virXMLFormatElement-to-format-hyperv-features.patch
Patch192: libvirt-qemu_caps-Prefer-VIR_DOMAIN_CAPS_ENUM_IS_SET.patch
Patch193: libvirt-qemu_command-Move-hyperv-cmd-line-generation-into-a-function.patch
Patch194: libvirt-qemu_command-Prefer-virBufferAddLit-in-qemuBuildCpuHypervCommandLine.patch
Patch195: libvirt-conf-More-hyperv-related-members-into-a-single-struct.patch
Patch196: libvirt-conf-Report-default-hyperv-values-in-domain-capabilities.patch
Patch197: libvirt-qemu_capabilities-Format-and-parse-new-hyperv-domcaps-members.patch
Patch198: libvirt-qemu_capabilities-Fetch-new-hyperv-domcaps.patch
Patch199: libvirt-qemu_caps-Introduce-virQEMUCapsGetHypervCapabilities.patch
Patch200: libvirt-conf-Introduce-hyperv-host-model-mode.patch
Patch201: libvirt-qemu_process-Populate-hyperv-features-for-host-model.patch
Patch202: libvirt-cpu_conf-Make-virCPUDefFilterFeatures-return-void.patch
Patch203: libvirt-qemu_domain-Simplify-qemuDomainFixupCPUs.patch
Patch204: libvirt-qemu_domain-Fix-qemuDomainFixupCPUs.patch
Patch205: libvirt-qemu_process-Always-fix-CPUs-on-reconnect.patch
Patch206: libvirt-qemu_monitor-Filter-CPU-features-reported-by-QEMU.patch
Patch207: libvirt-qemu-Ignore-ht-CPU-feature.patch
Requires: libvirt-daemon = %{version}-%{release}
@ -1494,7 +1525,8 @@ exit 1
%define arg_packager_version -Dpackager_version="%{release}"
%define arg_selinux_mount -Dselinux_mount="/sys/fs/selinux"
# place macros above and build commands below this comment
# Set SOURCE_DATE_EPOCH from changelog
%define source_date_epoch_from_changelog 1
export SOURCE_DATE_EPOCH=$(stat --printf='%Y' %{_specdir}/libvirt.spec)
@ -2798,6 +2830,55 @@ exit 0
%endif
%changelog
* Thu Dec 18 2025 EL Errata <el-errata_ww@oracle.com> - 10.10.0-15.4.0.1
- Set SOURCE_DATE_EPOCH from changelog [Orabug: 32019554]
* Fri Nov 21 2025 Jiri Denemark <jdenemar@redhat.com> - 10.10.0-15.4.el9_7
- cpu_conf: Make virCPUDefFilterFeatures return void (RHEL-126096)
- qemu_domain: Simplify qemuDomainFixupCPUs (RHEL-126096)
- qemu_domain: Fix qemuDomainFixupCPUs (RHEL-126096)
- qemu_process: Always fix CPUs on reconnect (RHEL-126096)
- qemu_monitor: Filter CPU features reported by QEMU (RHEL-126096)
- qemu: Ignore "ht" CPU feature (RHEL-126096)
* Fri Nov 14 2025 Jiri Denemark <jdenemar@redhat.com> - 10.10.0-15.3.el9_7
- conf: Do not parse hyperv features with passthrough mode (RHEL-122930)
- src: Drop needless typecast to virDomainTimerNameType (RHEL-122930)
- conf: Introduce virDomainDefHasTimer() (RHEL-122930)
- qemuxmlconfdata: Adjust hv-stimer related tests (RHEL-122930)
- qemu_validate: Reflect dependencies of hv-synic (RHEL-122930)
- qemu_validate: Reflect dependencies of hv-stimer (RHEL-122930)
- qemu_validate: Reflect dependencies of hv-tlbflush (RHEL-122930)
- qemu_validate: Reflect dependencies of hv-ipi (RHEL-122930)
- qemu_validate: Reflect dependencies of hv-evmcs (RHEL-122930)
- qemu_validate: Reflect dependencies of hv-tlbflush-direct (RHEL-122930)
- virxml: Introduce virXPathTristateSwitch() (RHEL-122930)
- virxml: Introduce virXPathTristateBool() (RHEL-122930)
- qemu: Use virXPathTristateBool() (RHEL-122930)
- domain_conf: Move format of hyperv features into a function (RHEL-122930)
- domain_conf: Use virXMLFormatElement() to format hyperv features (RHEL-122930)
- qemu_caps: Prefer VIR_DOMAIN_CAPS_ENUM_IS_SET() (RHEL-122930)
- qemu_command: Move hyperv cmd line generation into a function (RHEL-122930)
- qemu_command: Prefer virBufferAddLit() in qemuBuildCpuHypervCommandLine() (RHEL-122930)
- conf: More hyperv related members into a single struct (RHEL-122930)
- conf: Report default hyperv values in domain capabilities (RHEL-122930)
- qemu_capabilities: Format and parse new hyperv domcaps members (RHEL-122930)
- qemu_capabilities: Fetch new hyperv domcaps (RHEL-122930)
- qemu_caps: Introduce virQEMUCapsGetHypervCapabilities() (RHEL-122930)
- conf: Introduce hyperv host-model mode (RHEL-122930)
- qemu_process: Populate hyperv features for host-model (RHEL-122930)
- RHEL: Remove patches from invalid 10.10.0-15.2.el9_7 build (RHEL-122930)
* Wed Nov 12 2025 Jiri Denemark <jdenemar@redhat.com> - 10.10.0-15.2.el9_7
- virBitmapFormat: Don't check return value (RHEL-122930)
- domain_conf: Make virDomainMemoryDefFormat() return void (RHEL-122930)
- domain_conf: Switch to virXMLFormatElement() in virDomainMemoryDefFormat() (RHEL-122930)
- conf: Introduce virDomainMemoryIsVirtioModel() (RHEL-122930)
- qemu: Use virDomainMemoryIsVirtioModel() (RHEL-122930)
- conf: Introduce virtio options for virtio memory models (RHEL-122930)
- qemu_command: Generate virtio options for memory device (RHEL-122930)
- domain_conf: Avoid memory leak in virDomainMemoryDefFree() (RHEL-122930)
* Tue Oct 7 2025 Jiri Denemark <jdenemar@redhat.com> - 10.10.0-15.1.el9_7
- tools: Secure guest check for Intel in virt-host-validate (RHEL-111840)
- qemu: Check if INTEL Trust Domain Extention support is enabled (RHEL-111840)