151 lines
5.8 KiB
Diff
151 lines
5.8 KiB
Diff
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
|