qemu/hw/core/machine-qmp-cmds.c
<<
>>
Prefs
   1/*
   2 * QMP commands related to machines and CPUs
   3 *
   4 * Copyright (C) 2014 Red Hat Inc
   5 *
   6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
   7 * See the COPYING file in the top-level directory.
   8 */
   9
  10#include "qemu/osdep.h"
  11#include "hw/boards.h"
  12#include "qapi/error.h"
  13#include "qapi/qapi-builtin-visit.h"
  14#include "qapi/qapi-commands-machine.h"
  15#include "qapi/qmp/qerror.h"
  16#include "qapi/qmp/qobject.h"
  17#include "qapi/qobject-input-visitor.h"
  18#include "qemu/main-loop.h"
  19#include "qom/qom-qobject.h"
  20#include "sysemu/hostmem.h"
  21#include "sysemu/hw_accel.h"
  22#include "sysemu/numa.h"
  23#include "sysemu/runstate.h"
  24
  25static void cpustate_to_cpuinfo_s390(CpuInfoS390 *info, const CPUState *cpu)
  26{
  27#ifdef TARGET_S390X
  28    S390CPU *s390_cpu = S390_CPU(cpu);
  29    CPUS390XState *env = &s390_cpu->env;
  30
  31    info->cpu_state = env->cpu_state;
  32#else
  33    abort();
  34#endif
  35}
  36
  37/*
  38 * fast means: we NEVER interrupt vCPU threads to retrieve
  39 * information from KVM.
  40 */
  41CpuInfoFastList *qmp_query_cpus_fast(Error **errp)
  42{
  43    MachineState *ms = MACHINE(qdev_get_machine());
  44    MachineClass *mc = MACHINE_GET_CLASS(ms);
  45    CpuInfoFastList *head = NULL, **tail = &head;
  46    SysEmuTarget target = qapi_enum_parse(&SysEmuTarget_lookup, TARGET_NAME,
  47                                          -1, &error_abort);
  48    CPUState *cpu;
  49
  50    CPU_FOREACH(cpu) {
  51        CpuInfoFast *value = g_malloc0(sizeof(*value));
  52
  53        value->cpu_index = cpu->cpu_index;
  54        value->qom_path = object_get_canonical_path(OBJECT(cpu));
  55        value->thread_id = cpu->thread_id;
  56
  57        value->has_props = !!mc->cpu_index_to_instance_props;
  58        if (value->has_props) {
  59            CpuInstanceProperties *props;
  60            props = g_malloc0(sizeof(*props));
  61            *props = mc->cpu_index_to_instance_props(ms, cpu->cpu_index);
  62            value->props = props;
  63        }
  64
  65        value->target = target;
  66        if (target == SYS_EMU_TARGET_S390X) {
  67            cpustate_to_cpuinfo_s390(&value->u.s390x, cpu);
  68        }
  69
  70        QAPI_LIST_APPEND(tail, value);
  71    }
  72
  73    return head;
  74}
  75
  76MachineInfoList *qmp_query_machines(Error **errp)
  77{
  78    GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
  79    MachineInfoList *mach_list = NULL;
  80
  81    for (el = machines; el; el = el->next) {
  82        MachineClass *mc = el->data;
  83        MachineInfo *info;
  84
  85        info = g_malloc0(sizeof(*info));
  86        if (mc->is_default) {
  87            info->has_is_default = true;
  88            info->is_default = true;
  89        }
  90
  91        if (mc->alias) {
  92            info->has_alias = true;
  93            info->alias = g_strdup(mc->alias);
  94        }
  95
  96        info->name = g_strdup(mc->name);
  97        info->cpu_max = !mc->max_cpus ? 1 : mc->max_cpus;
  98        info->hotpluggable_cpus = mc->has_hotpluggable_cpus;
  99        info->numa_mem_supported = mc->numa_mem_supported;
 100        info->deprecated = !!mc->deprecation_reason;
 101        if (mc->default_cpu_type) {
 102            info->default_cpu_type = g_strdup(mc->default_cpu_type);
 103            info->has_default_cpu_type = true;
 104        }
 105        if (mc->default_ram_id) {
 106            info->default_ram_id = g_strdup(mc->default_ram_id);
 107            info->has_default_ram_id = true;
 108        }
 109
 110        QAPI_LIST_PREPEND(mach_list, info);
 111    }
 112
 113    g_slist_free(machines);
 114    return mach_list;
 115}
 116
 117CurrentMachineParams *qmp_query_current_machine(Error **errp)
 118{
 119    CurrentMachineParams *params = g_malloc0(sizeof(*params));
 120    params->wakeup_suspend_support = qemu_wakeup_suspend_enabled();
 121
 122    return params;
 123}
 124
 125TargetInfo *qmp_query_target(Error **errp)
 126{
 127    TargetInfo *info = g_malloc0(sizeof(*info));
 128
 129    info->arch = qapi_enum_parse(&SysEmuTarget_lookup, TARGET_NAME, -1,
 130                                 &error_abort);
 131
 132    return info;
 133}
 134
 135HotpluggableCPUList *qmp_query_hotpluggable_cpus(Error **errp)
 136{
 137    MachineState *ms = MACHINE(qdev_get_machine());
 138    MachineClass *mc = MACHINE_GET_CLASS(ms);
 139
 140    if (!mc->has_hotpluggable_cpus) {
 141        error_setg(errp, QERR_FEATURE_DISABLED, "query-hotpluggable-cpus");
 142        return NULL;
 143    }
 144
 145    return machine_query_hotpluggable_cpus(ms);
 146}
 147
 148void qmp_set_numa_node(NumaOptions *cmd, Error **errp)
 149{
 150    if (phase_check(PHASE_MACHINE_INITIALIZED)) {
 151        error_setg(errp, "The command is permitted only before the machine has been created");
 152        return;
 153    }
 154
 155    set_numa_options(MACHINE(qdev_get_machine()), cmd, errp);
 156}
 157
 158static int query_memdev(Object *obj, void *opaque)
 159{
 160    Error *err = NULL;
 161    MemdevList **list = opaque;
 162    Memdev *m;
 163    QObject *host_nodes;
 164    Visitor *v;
 165
 166    if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) {
 167        m = g_malloc0(sizeof(*m));
 168
 169        m->id = g_strdup(object_get_canonical_path_component(obj));
 170        m->has_id = !!m->id;
 171
 172        m->size = object_property_get_uint(obj, "size", &error_abort);
 173        m->merge = object_property_get_bool(obj, "merge", &error_abort);
 174        m->dump = object_property_get_bool(obj, "dump", &error_abort);
 175        m->prealloc = object_property_get_bool(obj, "prealloc", &error_abort);
 176        m->share = object_property_get_bool(obj, "share", &error_abort);
 177        m->reserve = object_property_get_bool(obj, "reserve", &err);
 178        if (err) {
 179            error_free_or_abort(&err);
 180        } else {
 181            m->has_reserve = true;
 182        }
 183        m->policy = object_property_get_enum(obj, "policy", "HostMemPolicy",
 184                                             &error_abort);
 185        host_nodes = object_property_get_qobject(obj,
 186                                                 "host-nodes",
 187                                                 &error_abort);
 188        v = qobject_input_visitor_new(host_nodes);
 189        visit_type_uint16List(v, NULL, &m->host_nodes, &error_abort);
 190        visit_free(v);
 191        qobject_unref(host_nodes);
 192
 193        QAPI_LIST_PREPEND(*list, m);
 194    }
 195
 196    return 0;
 197}
 198
 199MemdevList *qmp_query_memdev(Error **errp)
 200{
 201    Object *obj = object_get_objects_root();
 202    MemdevList *list = NULL;
 203
 204    object_child_foreach(obj, query_memdev, &list);
 205    return list;
 206}
 207