From: Praveen K Paladugu <prapal@linux.microsoft.com>
Use the `query-accelerators` command to generically query the enabled
acclerator. Below is an example invocation in Qemu:
{ "execute": "query-accelerators"}
"return": {"enabled": "kvm", "present": ["kvm", "mshv", "qtest", "tcg", "xen"]}}
"enabled" here indicates "kvm" is the enabled accelertor.
If query-accelerators command is not available, fallback to existing
mechnisms for querying kvm and hvf capabilities.
Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
---
src/qemu/qemu_capabilities.c | 38 ++++++++++++++++---
src/qemu/qemu_monitor.c | 9 +++++
src/qemu/qemu_monitor.h | 4 ++
src/qemu/qemu_monitor_json.c | 23 +++++++++++
src/qemu/qemu_monitor_json.h | 5 +++
.../caps_10.2.0_x86_64.replies | 11 ++++--
6 files changed, 82 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index b0d4e76572..38e1913d49 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3466,6 +3466,29 @@ virQEMUCapsProbeQMPKVMState(virQEMUCaps *qemuCaps,
return 0;
}
+static int
+virQEMUCapsProbeAccels(virQEMUCaps *qemuCaps,
+ qemuMonitor *mon)
+{
+ g_autofree char *enabled = NULL;
+
+ if (qemuMonitorGetAccelerators(mon, &enabled) < 0)
+ return -1;
+
+ if (!enabled) {
+ return 0;
+ }
+
+ if (STREQ(enabled, "tcg"))
+ virQEMUCapsSet(qemuCaps, QEMU_CAPS_TCG);
+ else if (STREQ(enabled, "hvf"))
+ virQEMUCapsSet(qemuCaps, QEMU_CAPS_HVF);
+ else if (STREQ(enabled, "kvm"))
+ virQEMUCapsSet(qemuCaps, QEMU_CAPS_KVM);
+
+ return 0;
+}
+
#ifdef __APPLE__
bool
virQEMUCapsProbeHVF(virQEMUCaps *qemuCaps)
@@ -5781,12 +5804,17 @@ virQEMUCapsInitQMPMonitor(virQEMUCaps *qemuCaps,
if (virQEMUCapsProbeQMPSchemaCapabilities(qemuCaps, mon) < 0)
return -1;
- /* Some capabilities may differ depending on KVM state */
- if (virQEMUCapsProbeQMPKVMState(qemuCaps, mon) < 0)
- return -1;
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_ACCELERATORS)) {
+ if (virQEMUCapsProbeAccels(qemuCaps, mon) < 0)
+ return -1;
+ } else {
+ /* Some capabilities may differ depending on KVM state */
+ if (virQEMUCapsProbeQMPKVMState(qemuCaps, mon) < 0)
+ return -1;
- if (virQEMUCapsProbeHVF(qemuCaps))
- virQEMUCapsSet(qemuCaps, QEMU_CAPS_HVF);
+ if (virQEMUCapsProbeHVF(qemuCaps))
+ virQEMUCapsSet(qemuCaps, QEMU_CAPS_HVF);
+ }
type = virQEMUCapsGetVirtType(qemuCaps);
accel = virQEMUCapsGetAccel(qemuCaps, type);
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index f61da140ea..f2df59d12d 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3446,6 +3446,15 @@ qemuMonitorGetKVMState(qemuMonitor *mon,
return qemuMonitorJSONGetKVMState(mon, enabled, present);
}
+int
+qemuMonitorGetAccelerators(qemuMonitor *mon,
+ char **enabled)
+{
+ QEMU_CHECK_MONITOR(mon);
+
+ return qemuMonitorJSONGetAccelerators(mon, enabled);
+}
+
int
qemuMonitorGetObjectTypes(qemuMonitor *mon,
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 83d702a96c..dd038f2775 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1477,6 +1477,10 @@ qemuMonitorGetKVMState(qemuMonitor *mon,
bool *enabled,
bool *present);
+int
+qemuMonitorGetAccelerators(qemuMonitor *mon,
+ char **enabled);
+
int
qemuMonitorGetObjectTypes(qemuMonitor *mon,
char ***types);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index c7d291a201..12d8b11e11 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -5675,6 +5675,29 @@ qemuMonitorJSONGetKVMState(qemuMonitor *mon,
return 0;
}
+int
+qemuMonitorJSONGetAccelerators(qemuMonitor *mon, char **enabled)
+{
+ g_autoptr(virJSONValue) cmd = NULL;
+ g_autoptr(virJSONValue) reply = NULL;
+ virJSONValue *data;
+
+ *enabled = NULL;
+
+ if (!(cmd = qemuMonitorJSONMakeCommand("query-accelerators", NULL)))
+ return -1;
+
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ return -1;
+
+ if (!(data = qemuMonitorJSONGetReply(cmd, reply, VIR_JSON_TYPE_OBJECT)))
+ return -1;
+
+ *enabled = g_strdup(virJSONValueObjectGetString(data, "enabled"));
+
+ return 0;
+}
+
int
qemuMonitorJSONGetObjectTypes(qemuMonitor *mon,
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index f20830532d..db9160eb68 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -451,6 +451,11 @@ qemuMonitorJSONGetKVMState(qemuMonitor *mon,
bool *present)
ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+int
+qemuMonitorJSONGetAccelerators(qemuMonitor *mon,
+ char **enabled)
+ ATTRIBUTE_NONNULL(2);
+
int
qemuMonitorJSONGetObjectTypes(qemuMonitor *mon,
char ***types)
diff --git a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies
index 6c14a0f9f6..3b6d4e0575 100644
--- a/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies
+++ b/tests/qemucapabilitiesdata/caps_10.2.0_x86_64.replies
@@ -24947,14 +24947,19 @@
}
{
- "execute": "query-kvm",
+ "execute": "query-accelerators",
"id": "libvirt-5"
}
{
"return": {
- "enabled": true,
- "present": true
+ "enabled": "kvm",
+ "present": [
+ "kvm",
+ "mshv",
+ "qtest",
+ "tcg"
+ ]
},
"id": "libvirt-5"
}
--
2.51.0
On 11/6/25 17:26, Praveen K Paladugu wrote:
> From: Praveen K Paladugu <prapal@linux.microsoft.com>
>
> Use the `query-accelerators` command to generically query the enabled
> acclerator. Below is an example invocation in Qemu:
>
> { "execute": "query-accelerators"}
> "return": {"enabled": "kvm", "present": ["kvm", "mshv", "qtest", "tcg", "xen"]}}
>
> "enabled" here indicates "kvm" is the enabled accelertor.
>
> If query-accelerators command is not available, fallback to existing
> mechnisms for querying kvm and hvf capabilities.
>
> Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
> ---
> src/qemu/qemu_capabilities.c | 38 ++++++++++++++++---
> src/qemu/qemu_monitor.c | 9 +++++
> src/qemu/qemu_monitor.h | 4 ++
> src/qemu/qemu_monitor_json.c | 23 +++++++++++
> src/qemu/qemu_monitor_json.h | 5 +++
> .../caps_10.2.0_x86_64.replies | 11 ++++--
> 6 files changed, 82 insertions(+), 8 deletions(-)
>
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index b0d4e76572..38e1913d49 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
> @@ -3466,6 +3466,29 @@ virQEMUCapsProbeQMPKVMState(virQEMUCaps *qemuCaps,
> return 0;
> }
>
> +static int
> +virQEMUCapsProbeAccels(virQEMUCaps *qemuCaps,
> + qemuMonitor *mon)
> +{
> + g_autofree char *enabled = NULL;
> +
> + if (qemuMonitorGetAccelerators(mon, &enabled) < 0)
> + return -1;
> +
> + if (!enabled) {
> + return 0;
> + }
> +
> + if (STREQ(enabled, "tcg"))
> + virQEMUCapsSet(qemuCaps, QEMU_CAPS_TCG);
> + else if (STREQ(enabled, "hvf"))
> + virQEMUCapsSet(qemuCaps, QEMU_CAPS_HVF);
> + else if (STREQ(enabled, "kvm"))
> + virQEMUCapsSet(qemuCaps, QEMU_CAPS_KVM);
Ignoring an unknown accelerator is fine, but failing to extract one from
QEMU reply (of QEMU failing to set 'enabled' attribute should be a failure.
> +
> + return 0;
> +}
> +
Michal
© 2016 - 2025 Red Hat, Inc.