}
+static int
+qemuCapsProbeQMPKVMState(qemuCapsPtr caps,
+ qemuMonitorPtr mon)
+{
+ bool enabled = false;
+ bool present = false;
+
+ if (!qemuCapsGet(caps, QEMU_CAPS_KVM))
+ return 0;
+
+ if (qemuMonitorGetKVMState(mon, &enabled, &present) < 0)
+ return -1;
+
+ /* The QEMU_CAPS_KVM flag was initially set according to the QEMU
+ * reporting the recognition of 'query-kvm' QMP command, but the
+ * flag means whether the KVM is enabled by default and should be
+ * disabled in case we want SW emulated machine, so let's fix that
+ * if it's true. */
+ if (!enabled) {
+ qemuCapsClear(caps, QEMU_CAPS_KVM);
+ qemuCapsSet(caps, QEMU_CAPS_ENABLE_KVM);
+ }
+
+ return 0;
+}
+
+
int qemuCapsProbeQMP(qemuCapsPtr caps,
qemuMonitorPtr mon)
{
qemuCapsSet(caps, QEMU_CAPS_DRIVE_SERIAL);
qemuCapsSet(caps, QEMU_CAPS_MIGRATE_QEMU_UNIX);
qemuCapsSet(caps, QEMU_CAPS_CHARDEV);
- qemuCapsSet(caps, QEMU_CAPS_ENABLE_KVM);
qemuCapsSet(caps, QEMU_CAPS_MONITOR_JSON);
qemuCapsSet(caps, QEMU_CAPS_BALLOON);
qemuCapsSet(caps, QEMU_CAPS_DEVICE);
goto cleanup;
if (qemuCapsProbeQMPCPUDefinitions(caps, mon) < 0)
goto cleanup;
+ if (qemuCapsProbeQMPKVMState(caps, mon) < 0)
+ goto cleanup;
ret = 0;
QEMU_CAPS_MIGRATE_QEMU_TCP = 10, /* have qemu tcp migration */
QEMU_CAPS_MIGRATE_QEMU_EXEC = 11, /* have qemu exec migration */
QEMU_CAPS_DRIVE_CACHE_V2 = 12, /* cache= flag wanting new v2 values */
- QEMU_CAPS_KVM = 13, /* Whether KVM is compiled in */
+ QEMU_CAPS_KVM = 13, /* Whether KVM is enabled by default */
QEMU_CAPS_DRIVE_FORMAT = 14, /* Is -drive format= avail */
QEMU_CAPS_VGA = 15, /* Is -vga avail */
}
+int qemuMonitorGetKVMState(qemuMonitorPtr mon,
+ bool *enabled,
+ bool *present)
+{
+ VIR_DEBUG("mon=%p enabled=%p present=%p",
+ mon, enabled, present);
+
+ if (!mon) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("monitor must not be NULL"));
+ return -1;
+ }
+
+ if (!mon->json) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("JSON monitor is required"));
+ return -1;
+ }
+
+ return qemuMonitorJSONGetKVMState(mon, enabled, present);
+}
+
+
int qemuMonitorGetObjectTypes(qemuMonitorPtr mon,
char ***types)
{
int qemuMonitorGetEvents(qemuMonitorPtr mon,
char ***events);
+int qemuMonitorGetKVMState(qemuMonitorPtr mon,
+ bool *enabled,
+ bool *present);
+
int qemuMonitorGetObjectTypes(qemuMonitorPtr mon,
char ***types);
int qemuMonitorGetObjectProps(qemuMonitorPtr mon,
}
+int qemuMonitorJSONGetKVMState(qemuMonitorPtr mon,
+ bool *enabled,
+ bool *present)
+{
+ int ret;
+ virJSONValuePtr cmd = NULL;
+ virJSONValuePtr reply = NULL;
+ virJSONValuePtr data = NULL;
+
+ /* Safe defaults */
+ *enabled = *present = false;
+
+ if (!(cmd = qemuMonitorJSONMakeCommand("query-kvm", NULL)))
+ return -1;
+
+ ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+ if (ret == 0) {
+ if (qemuMonitorJSONHasError(reply, "CommandNotFound"))
+ goto cleanup;
+
+ ret = qemuMonitorJSONCheckError(cmd, reply);
+ }
+
+ if (ret < 0)
+ goto cleanup;
+
+ ret = -1;
+
+ if (!(data = virJSONValueObjectGet(reply, "return"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-kvm reply was missing return data"));
+ goto cleanup;
+ }
+
+ if (virJSONValueObjectGetBoolean(data, "enabled", enabled) < 0 ||
+ virJSONValueObjectGetBoolean(data, "present", present) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-kvm replied unexpected data"));
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ return ret;
+}
+
+
int qemuMonitorJSONGetObjectTypes(qemuMonitorPtr mon,
char ***types)
{
char ***events)
ATTRIBUTE_NONNULL(2);
+int qemuMonitorJSONGetKVMState(qemuMonitorPtr mon,
+ bool *enabled,
+ bool *present)
+ ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+
int qemuMonitorJSONGetObjectTypes(qemuMonitorPtr mon,
char ***types)
ATTRIBUTE_NONNULL(2);