char **machineTypes;
char **machineAliases;
unsigned int *machineMaxCpus;
+
+ size_t ngicCapabilities;
+ virGICCapability *gicCapabilities;
};
struct virQEMUCapsSearchData {
VIR_FREE(qemuCaps->package);
VIR_FREE(qemuCaps->binary);
+
+ VIR_FREE(qemuCaps->gicCapabilities);
}
void
return 0;
}
+/**
+ * virQEMUCapsProbeQMPGICCapabilities:
+ * @qemuCaps: QEMU binary capabilities
+ * @mon: QEMU monitor
+ *
+ * Use @mon to obtain information about the GIC capabilities for the
+ * corresponding QEMU binary, and store them in @qemuCaps.
+ *
+ * Returns: 0 on success, <0 on failure
+ */
+static int
+virQEMUCapsProbeQMPGICCapabilities(virQEMUCapsPtr qemuCaps,
+ qemuMonitorPtr mon)
+{
+ virGICCapability *caps = NULL;
+ int ncaps;
+
+ if ((ncaps = qemuMonitorGetGICCapabilities(mon, &caps)) < 0)
+ return -1;
+
+ VIR_FREE(qemuCaps->gicCapabilities);
+
+ qemuCaps->gicCapabilities = caps;
+ qemuCaps->ngicCapabilities = ncaps;
+
+ return 0;
+}
+
int virQEMUCapsProbeQMP(virQEMUCapsPtr qemuCaps,
qemuMonitorPtr mon)
{
VIR_FREE(qemuCaps->machineAliases);
VIR_FREE(qemuCaps->machineMaxCpus);
qemuCaps->nmachineTypes = 0;
+
+ VIR_FREE(qemuCaps->gicCapabilities);
+ qemuCaps->ngicCapabilities = 0;
}
if (virQEMUCapsProbeQMPMigrationCapabilities(qemuCaps, mon) < 0)
goto cleanup;
+ /* GIC capabilities, eg. available GIC versions */
+ if ((qemuCaps->arch == VIR_ARCH_AARCH64 ||
+ qemuCaps->arch == VIR_ARCH_ARMV7L) &&
+ virQEMUCapsProbeQMPGICCapabilities(qemuCaps, mon) < 0)
+ goto cleanup;
+
ret = 0;
cleanup:
return ret;
}
+/**
+ * qemuMonitorGetGICCapabilities:
+ * @mon: QEMU monitor
+ * @capabilities: where to store the GIC capabilities
+ *
+ * See qemuMonitorJSONGetGICCapabilities().
+ */
+int
+qemuMonitorGetGICCapabilities(qemuMonitorPtr mon,
+ virGICCapability **capabilities)
+{
+ QEMU_CHECK_MONITOR_JSON(mon);
+
+ return qemuMonitorJSONGetGICCapabilities(mon, capabilities);
+}
+
+
int
qemuMonitorNBDServerStart(qemuMonitorPtr mon,
const char *host,
# include "virnetdev.h"
# include "device_conf.h"
# include "cpu/cpu.h"
+# include "util/virgic.h"
typedef struct _qemuMonitor qemuMonitor;
typedef qemuMonitor *qemuMonitorPtr;
qemuMonitorMigrationCaps capability,
bool state);
+int qemuMonitorGetGICCapabilities(qemuMonitorPtr mon,
+ virGICCapability **capabilities);
+
typedef enum {
QEMU_MONITOR_MIGRATE_BACKGROUND = 1 << 0,
QEMU_MONITOR_MIGRATE_NON_SHARED_DISK = 1 << 1, /* migration with non-shared storage with full disk copy */
return ret;
}
+
+/**
+ * qemuMonitorJSONGetGICCapabilities:
+ * @mon: QEMU JSON monitor
+ * @capabilities: where to store the GIC capabilities
+ *
+ * Use @mon to obtain information about the GIC capabilities for the
+ * corresponding QEMU binary, and store them in @capabilities.
+ *
+ * If the QEMU binary has no GIC capabilities, or if GIC capabilities could
+ * not be determined due to the lack of 'query-gic-capabilities' QMP command,
+ * a NULL pointer will be returned instead of an empty array.
+ *
+ * Returns: the number of GIC capabilities obtained from the monitor,
+ * <0 on failure
+ */
+int
+qemuMonitorJSONGetGICCapabilities(qemuMonitorPtr mon,
+ virGICCapability **capabilities)
+{
+ int ret;
+ virJSONValuePtr cmd;
+ virJSONValuePtr reply = NULL;
+ virJSONValuePtr caps;
+ virGICCapability *list = NULL;
+ size_t i;
+ ssize_t n;
+
+ *capabilities = NULL;
+
+ if (!(cmd = qemuMonitorJSONMakeCommand("query-gic-capabilities",
+ NULL)))
+ return -1;
+
+ ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+ if (ret == 0) {
+ /* If the 'query-gic-capabilities' QMP command was not available
+ * we simply successfully return zero capabilities.
+ * This is the case for QEMU <2.6 and all non-ARM architectures */
+ if (qemuMonitorJSONHasError(reply, "CommandNotFound"))
+ goto cleanup;
+ ret = qemuMonitorJSONCheckError(cmd, reply);
+ }
+
+ if (ret < 0)
+ goto cleanup;
+
+ ret = -1;
+
+ if (!(caps = virJSONValueObjectGetArray(reply, "return")) ||
+ (n = virJSONValueArraySize(caps)) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("missing GIC capabilities"));
+ goto cleanup;
+ }
+
+ /* If the returned array was empty we have to return successfully */
+ if (n == 0) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ if (VIR_ALLOC_N(list, n) < 0)
+ goto cleanup;
+
+ for (i = 0; i < n; i++) {
+ virJSONValuePtr cap = virJSONValueArrayGet(caps, i);
+ int version;
+ bool kernel;
+ bool emulated;
+
+ if (!cap || cap->type != VIR_JSON_TYPE_OBJECT) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("missing entry in GIC capabilities list"));
+ goto cleanup;
+ }
+
+ if (virJSONValueObjectGetNumberInt(cap, "version", &version) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("missing GIC version"));
+ goto cleanup;
+ }
+
+ if (virJSONValueObjectGetBoolean(cap, "kernel", &kernel) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("missing in-kernel GIC information"));
+ goto cleanup;
+ }
+
+ if (virJSONValueObjectGetBoolean(cap, "emulated", &emulated) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("missing emulated GIC information"));
+ goto cleanup;
+ }
+
+ list[i].version = version;
+ if (kernel)
+ list[i].implementation |= VIR_GIC_IMPLEMENTATION_KERNEL;
+ if (emulated)
+ list[i].implementation |= VIR_GIC_IMPLEMENTATION_EMULATED;
+ }
+
+ ret = n;
+ *capabilities = list;
+
+ cleanup:
+ if (ret < 0)
+ VIR_FREE(list);
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+
+ return ret;
+}
+
static virJSONValuePtr
qemuMonitorJSONBuildInetSocketAddress(const char *host,
const char *port)
# include "qemu_monitor.h"
# include "virbitmap.h"
# include "cpu/cpu.h"
+# include "util/virgic.h"
int qemuMonitorJSONIOProcess(qemuMonitorPtr mon,
const char *data,
qemuMonitorMigrationCaps capability,
bool state);
+int qemuMonitorJSONGetGICCapabilities(qemuMonitorPtr mon,
+ virGICCapability **capabilities);
+
int qemuMonitorJSONMigrate(qemuMonitorPtr mon,
unsigned int flags,
const char *uri);
/* Consider GIC v2 the default */
# define VIR_GIC_VERSION_DEFAULT VIR_GIC_VERSION_2
+typedef enum {
+ VIR_GIC_IMPLEMENTATION_NONE = 0,
+ VIR_GIC_IMPLEMENTATION_KERNEL = (1 << 1),
+ VIR_GIC_IMPLEMENTATION_EMULATED = (1 << 2)
+} virGICImplementation;
+
+typedef struct _virGICCapability virGICCapability;
+typedef virGICCapability *virGICCapabilityPtr;
+struct _virGICCapability {
+ virGICVersion version;
+ virGICImplementation implementation;
+};
+
#endif /* __VIR_GIC_H__ */