[PATCH v3 2/2] qemu: Use query-accelerators to query accelerators

Praveen K Paladugu posted 2 patches 2 weeks ago
[PATCH v3 2/2] qemu: Use query-accelerators to query accelerators
Posted by Praveen K Paladugu 2 weeks ago
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
Re: [PATCH v3 2/2] qemu: Use query-accelerators to query accelerators
Posted by Michal Prívozník via Devel 1 week, 6 days ago
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