From: Michal Privoznik <[email protected]>

Since some hyperv features might be already enabled/disabled when
entering qemuProcessEnableDomainFeatures() only those which are
not set in domain XML (i.e. are VIR_TRISTATE_SWITCH_ABSENT)
should be modified. Furthermore, some features are not a simple
on/off switch, but a number or a string even. Well, that doesn't
matter really as the logic for setting them is the same: only set
their value iff they are not already set.

Resolves: https://issues.redhat.com/browse/RHEL-148219
Signed-off-by: Michal Privoznik <[email protected]>
---
 src/qemu/qemu_process.c                       | 24 ++++++++++++-------
 .../hyperv-host-model.x86_64-latest.args      |  2 +-
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index c5b2a5fda8..27aa1896d4 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6960,30 +6960,38 @@ qemuProcessEnableDomainFeatures(virDomainObj *vm)
     }
 
     for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
+        virTristateSwitch origState = vm->def->hyperv.features[i];
+
         if (!VIR_DOMAIN_CAPS_ENUM_IS_SET(hv->features, i))
             continue;
 
-        vm->def->hyperv.features[i] = VIR_TRISTATE_SWITCH_ON;
+        if (vm->def->hyperv.features[i] == VIR_TRISTATE_SWITCH_ABSENT)
+            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;
+                if (vm->def->hyperv.spinlocks == 0)
+                    vm->def->hyperv.spinlocks = hv->spinlocks;
             } else {
-                vm->def->hyperv.features[i] = VIR_TRISTATE_SWITCH_ABSENT;
+                vm->def->hyperv.features[i] = origState;
             }
         } else if (i == VIR_DOMAIN_HYPERV_STIMER) {
-            vm->def->hyperv.stimer_direct = hv->stimer_direct;
+            if (vm->def->hyperv.stimer_direct == VIR_TRISTATE_SWITCH_ABSENT)
+                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;
+            if (vm->def->hyperv.tlbflush_direct == VIR_TRISTATE_SWITCH_ABSENT)
+                vm->def->hyperv.tlbflush_direct = hv->tlbflush_direct;
+            if (vm->def->hyperv.tlbflush_extended == 
VIR_TRISTATE_SWITCH_ABSENT)
+                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);
+                if (!vm->def->hyperv.vendor_id)
+                    vm->def->hyperv.vendor_id = g_strdup(hv->vendor_id);
             } else {
-                vm->def->hyperv.features[i] = VIR_TRISTATE_SWITCH_ABSENT;
+                vm->def->hyperv.features[i] = origState;
             }
         }
     }
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args 
b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
index 58502ff51e..d1f2326da1 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,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'
 \
+-cpu 
'qemu64,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x2000,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'
 \
 -m size=219136k \
 -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
 -overcommit mem-lock=off \
-- 
2.52.0

Reply via email to