2 * QMP commands related to machines and CPUs
4 * Copyright (C) 2014 Red Hat Inc
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.
10 #include "qemu/osdep.h"
12 #include "hw/boards.h"
13 #include "qapi/error.h"
14 #include "qapi/qapi-commands-machine.h"
15 #include "qapi/qmp/qerror.h"
16 #include "sysemu/hostmem.h"
17 #include "sysemu/hw_accel.h"
18 #include "sysemu/numa.h"
19 #include "sysemu/sysemu.h"
21 CpuInfoList
*qmp_query_cpus(Error
**errp
)
23 MachineState
*ms
= MACHINE(qdev_get_machine());
24 MachineClass
*mc
= MACHINE_GET_CLASS(ms
);
25 CpuInfoList
*head
= NULL
, *cur_item
= NULL
;
30 #if defined(TARGET_I386)
31 X86CPU
*x86_cpu
= X86_CPU(cpu
);
32 CPUX86State
*env
= &x86_cpu
->env
;
33 #elif defined(TARGET_PPC)
34 PowerPCCPU
*ppc_cpu
= POWERPC_CPU(cpu
);
35 CPUPPCState
*env
= &ppc_cpu
->env
;
36 #elif defined(TARGET_SPARC)
37 SPARCCPU
*sparc_cpu
= SPARC_CPU(cpu
);
38 CPUSPARCState
*env
= &sparc_cpu
->env
;
39 #elif defined(TARGET_RISCV)
40 RISCVCPU
*riscv_cpu
= RISCV_CPU(cpu
);
41 CPURISCVState
*env
= &riscv_cpu
->env
;
42 #elif defined(TARGET_MIPS)
43 MIPSCPU
*mips_cpu
= MIPS_CPU(cpu
);
44 CPUMIPSState
*env
= &mips_cpu
->env
;
45 #elif defined(TARGET_TRICORE)
46 TriCoreCPU
*tricore_cpu
= TRICORE_CPU(cpu
);
47 CPUTriCoreState
*env
= &tricore_cpu
->env
;
48 #elif defined(TARGET_S390X)
49 S390CPU
*s390_cpu
= S390_CPU(cpu
);
50 CPUS390XState
*env
= &s390_cpu
->env
;
53 cpu_synchronize_state(cpu
);
55 info
= g_malloc0(sizeof(*info
));
56 info
->value
= g_malloc0(sizeof(*info
->value
));
57 info
->value
->CPU
= cpu
->cpu_index
;
58 info
->value
->current
= (cpu
== first_cpu
);
59 info
->value
->halted
= cpu
->halted
;
60 info
->value
->qom_path
= object_get_canonical_path(OBJECT(cpu
));
61 info
->value
->thread_id
= cpu
->thread_id
;
62 #if defined(TARGET_I386)
63 info
->value
->arch
= CPU_INFO_ARCH_X86
;
64 info
->value
->u
.x86
.pc
= env
->eip
+ env
->segs
[R_CS
].base
;
65 #elif defined(TARGET_PPC)
66 info
->value
->arch
= CPU_INFO_ARCH_PPC
;
67 info
->value
->u
.ppc
.nip
= env
->nip
;
68 #elif defined(TARGET_SPARC)
69 info
->value
->arch
= CPU_INFO_ARCH_SPARC
;
70 info
->value
->u
.q_sparc
.pc
= env
->pc
;
71 info
->value
->u
.q_sparc
.npc
= env
->npc
;
72 #elif defined(TARGET_MIPS)
73 info
->value
->arch
= CPU_INFO_ARCH_MIPS
;
74 info
->value
->u
.q_mips
.PC
= env
->active_tc
.PC
;
75 #elif defined(TARGET_TRICORE)
76 info
->value
->arch
= CPU_INFO_ARCH_TRICORE
;
77 info
->value
->u
.tricore
.PC
= env
->PC
;
78 #elif defined(TARGET_S390X)
79 info
->value
->arch
= CPU_INFO_ARCH_S390
;
80 info
->value
->u
.s390
.cpu_state
= env
->cpu_state
;
81 #elif defined(TARGET_RISCV)
82 info
->value
->arch
= CPU_INFO_ARCH_RISCV
;
83 info
->value
->u
.riscv
.pc
= env
->pc
;
85 info
->value
->arch
= CPU_INFO_ARCH_OTHER
;
87 info
->value
->has_props
= !!mc
->cpu_index_to_instance_props
;
88 if (info
->value
->has_props
) {
89 CpuInstanceProperties
*props
;
90 props
= g_malloc0(sizeof(*props
));
91 *props
= mc
->cpu_index_to_instance_props(ms
, cpu
->cpu_index
);
92 info
->value
->props
= props
;
95 /* XXX: waiting for the qapi to support GSList */
97 head
= cur_item
= info
;
99 cur_item
->next
= info
;
107 static CpuInfoArch
sysemu_target_to_cpuinfo_arch(SysEmuTarget target
)
110 * The @SysEmuTarget -> @CpuInfoArch mapping below is based on the
111 * TARGET_ARCH -> TARGET_BASE_ARCH mapping in the "configure" script.
114 case SYS_EMU_TARGET_I386
:
115 case SYS_EMU_TARGET_X86_64
:
116 return CPU_INFO_ARCH_X86
;
118 case SYS_EMU_TARGET_PPC
:
119 case SYS_EMU_TARGET_PPC64
:
120 return CPU_INFO_ARCH_PPC
;
122 case SYS_EMU_TARGET_SPARC
:
123 case SYS_EMU_TARGET_SPARC64
:
124 return CPU_INFO_ARCH_SPARC
;
126 case SYS_EMU_TARGET_MIPS
:
127 case SYS_EMU_TARGET_MIPSEL
:
128 case SYS_EMU_TARGET_MIPS64
:
129 case SYS_EMU_TARGET_MIPS64EL
:
130 return CPU_INFO_ARCH_MIPS
;
132 case SYS_EMU_TARGET_TRICORE
:
133 return CPU_INFO_ARCH_TRICORE
;
135 case SYS_EMU_TARGET_S390X
:
136 return CPU_INFO_ARCH_S390
;
138 case SYS_EMU_TARGET_RISCV32
:
139 case SYS_EMU_TARGET_RISCV64
:
140 return CPU_INFO_ARCH_RISCV
;
143 return CPU_INFO_ARCH_OTHER
;
147 static void cpustate_to_cpuinfo_s390(CpuInfoS390
*info
, const CPUState
*cpu
)
150 S390CPU
*s390_cpu
= S390_CPU(cpu
);
151 CPUS390XState
*env
= &s390_cpu
->env
;
153 info
->cpu_state
= env
->cpu_state
;
160 * fast means: we NEVER interrupt vCPU threads to retrieve
161 * information from KVM.
163 CpuInfoFastList
*qmp_query_cpus_fast(Error
**errp
)
165 MachineState
*ms
= MACHINE(qdev_get_machine());
166 MachineClass
*mc
= MACHINE_GET_CLASS(ms
);
167 CpuInfoFastList
*head
= NULL
, *cur_item
= NULL
;
168 SysEmuTarget target
= qapi_enum_parse(&SysEmuTarget_lookup
, TARGET_NAME
,
173 CpuInfoFastList
*info
= g_malloc0(sizeof(*info
));
174 info
->value
= g_malloc0(sizeof(*info
->value
));
176 info
->value
->cpu_index
= cpu
->cpu_index
;
177 info
->value
->qom_path
= object_get_canonical_path(OBJECT(cpu
));
178 info
->value
->thread_id
= cpu
->thread_id
;
180 info
->value
->has_props
= !!mc
->cpu_index_to_instance_props
;
181 if (info
->value
->has_props
) {
182 CpuInstanceProperties
*props
;
183 props
= g_malloc0(sizeof(*props
));
184 *props
= mc
->cpu_index_to_instance_props(ms
, cpu
->cpu_index
);
185 info
->value
->props
= props
;
188 info
->value
->arch
= sysemu_target_to_cpuinfo_arch(target
);
189 info
->value
->target
= target
;
190 if (target
== SYS_EMU_TARGET_S390X
) {
191 cpustate_to_cpuinfo_s390(&info
->value
->u
.s390x
, cpu
);
195 head
= cur_item
= info
;
197 cur_item
->next
= info
;
205 MachineInfoList
*qmp_query_machines(Error
**errp
)
207 GSList
*el
, *machines
= object_class_get_list(TYPE_MACHINE
, false);
208 MachineInfoList
*mach_list
= NULL
;
210 for (el
= machines
; el
; el
= el
->next
) {
211 MachineClass
*mc
= el
->data
;
212 MachineInfoList
*entry
;
215 info
= g_malloc0(sizeof(*info
));
216 if (mc
->is_default
) {
217 info
->has_is_default
= true;
218 info
->is_default
= true;
222 info
->has_alias
= true;
223 info
->alias
= g_strdup(mc
->alias
);
226 info
->name
= g_strdup(mc
->name
);
227 info
->cpu_max
= !mc
->max_cpus
? 1 : mc
->max_cpus
;
228 info
->hotpluggable_cpus
= mc
->has_hotpluggable_cpus
;
229 info
->numa_mem_supported
= mc
->numa_mem_supported
;
230 info
->deprecated
= !!mc
->deprecation_reason
;
232 entry
= g_malloc0(sizeof(*entry
));
234 entry
->next
= mach_list
;
238 g_slist_free(machines
);
242 CurrentMachineParams
*qmp_query_current_machine(Error
**errp
)
244 CurrentMachineParams
*params
= g_malloc0(sizeof(*params
));
245 params
->wakeup_suspend_support
= qemu_wakeup_suspend_enabled();
250 HotpluggableCPUList
*qmp_query_hotpluggable_cpus(Error
**errp
)
252 MachineState
*ms
= MACHINE(qdev_get_machine());
253 MachineClass
*mc
= MACHINE_GET_CLASS(ms
);
255 if (!mc
->has_hotpluggable_cpus
) {
256 error_setg(errp
, QERR_FEATURE_DISABLED
, "query-hotpluggable-cpus");
260 return machine_query_hotpluggable_cpus(ms
);
263 void qmp_cpu_add(int64_t id
, Error
**errp
)
267 mc
= MACHINE_GET_CLASS(current_machine
);
268 if (mc
->hot_add_cpu
) {
269 mc
->hot_add_cpu(current_machine
, id
, errp
);
271 error_setg(errp
, "Not supported");
275 void qmp_set_numa_node(NumaOptions
*cmd
, Error
**errp
)
277 if (!runstate_check(RUN_STATE_PRECONFIG
)) {
278 error_setg(errp
, "The command is permitted only in '%s' state",
279 RunState_str(RUN_STATE_PRECONFIG
));
283 set_numa_options(MACHINE(qdev_get_machine()), cmd
, errp
);
286 static int query_memdev(Object
*obj
, void *opaque
)
288 MemdevList
**list
= opaque
;
289 MemdevList
*m
= NULL
;
291 if (object_dynamic_cast(obj
, TYPE_MEMORY_BACKEND
)) {
292 m
= g_malloc0(sizeof(*m
));
294 m
->value
= g_malloc0(sizeof(*m
->value
));
296 m
->value
->id
= object_get_canonical_path_component(obj
);
297 m
->value
->has_id
= !!m
->value
->id
;
299 m
->value
->size
= object_property_get_uint(obj
, "size",
301 m
->value
->merge
= object_property_get_bool(obj
, "merge",
303 m
->value
->dump
= object_property_get_bool(obj
, "dump",
305 m
->value
->prealloc
= object_property_get_bool(obj
,
308 m
->value
->policy
= object_property_get_enum(obj
,
312 object_property_get_uint16List(obj
, "host-nodes",
313 &m
->value
->host_nodes
,
323 MemdevList
*qmp_query_memdev(Error
**errp
)
325 Object
*obj
= object_get_objects_root();
326 MemdevList
*list
= NULL
;
328 object_child_foreach(obj
, query_memdev
, &list
);