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 "qemu/main-loop.h"
17 #include "sysemu/hostmem.h"
18 #include "sysemu/hw_accel.h"
19 #include "sysemu/numa.h"
20 #include "sysemu/runstate.h"
21 #include "sysemu/sysemu.h"
23 CpuInfoList
*qmp_query_cpus(Error
**errp
)
25 MachineState
*ms
= MACHINE(qdev_get_machine());
26 MachineClass
*mc
= MACHINE_GET_CLASS(ms
);
27 CpuInfoList
*head
= NULL
, *cur_item
= NULL
;
32 #if defined(TARGET_I386)
33 X86CPU
*x86_cpu
= X86_CPU(cpu
);
34 CPUX86State
*env
= &x86_cpu
->env
;
35 #elif defined(TARGET_PPC)
36 PowerPCCPU
*ppc_cpu
= POWERPC_CPU(cpu
);
37 CPUPPCState
*env
= &ppc_cpu
->env
;
38 #elif defined(TARGET_SPARC)
39 SPARCCPU
*sparc_cpu
= SPARC_CPU(cpu
);
40 CPUSPARCState
*env
= &sparc_cpu
->env
;
41 #elif defined(TARGET_RISCV)
42 RISCVCPU
*riscv_cpu
= RISCV_CPU(cpu
);
43 CPURISCVState
*env
= &riscv_cpu
->env
;
44 #elif defined(TARGET_MIPS)
45 MIPSCPU
*mips_cpu
= MIPS_CPU(cpu
);
46 CPUMIPSState
*env
= &mips_cpu
->env
;
47 #elif defined(TARGET_TRICORE)
48 TriCoreCPU
*tricore_cpu
= TRICORE_CPU(cpu
);
49 CPUTriCoreState
*env
= &tricore_cpu
->env
;
50 #elif defined(TARGET_S390X)
51 S390CPU
*s390_cpu
= S390_CPU(cpu
);
52 CPUS390XState
*env
= &s390_cpu
->env
;
55 cpu_synchronize_state(cpu
);
57 info
= g_malloc0(sizeof(*info
));
58 info
->value
= g_malloc0(sizeof(*info
->value
));
59 info
->value
->CPU
= cpu
->cpu_index
;
60 info
->value
->current
= (cpu
== first_cpu
);
61 info
->value
->halted
= cpu
->halted
;
62 info
->value
->qom_path
= object_get_canonical_path(OBJECT(cpu
));
63 info
->value
->thread_id
= cpu
->thread_id
;
64 #if defined(TARGET_I386)
65 info
->value
->arch
= CPU_INFO_ARCH_X86
;
66 info
->value
->u
.x86
.pc
= env
->eip
+ env
->segs
[R_CS
].base
;
67 #elif defined(TARGET_PPC)
68 info
->value
->arch
= CPU_INFO_ARCH_PPC
;
69 info
->value
->u
.ppc
.nip
= env
->nip
;
70 #elif defined(TARGET_SPARC)
71 info
->value
->arch
= CPU_INFO_ARCH_SPARC
;
72 info
->value
->u
.q_sparc
.pc
= env
->pc
;
73 info
->value
->u
.q_sparc
.npc
= env
->npc
;
74 #elif defined(TARGET_MIPS)
75 info
->value
->arch
= CPU_INFO_ARCH_MIPS
;
76 info
->value
->u
.q_mips
.PC
= env
->active_tc
.PC
;
77 #elif defined(TARGET_TRICORE)
78 info
->value
->arch
= CPU_INFO_ARCH_TRICORE
;
79 info
->value
->u
.tricore
.PC
= env
->PC
;
80 #elif defined(TARGET_S390X)
81 info
->value
->arch
= CPU_INFO_ARCH_S390
;
82 info
->value
->u
.s390
.cpu_state
= env
->cpu_state
;
83 #elif defined(TARGET_RISCV)
84 info
->value
->arch
= CPU_INFO_ARCH_RISCV
;
85 info
->value
->u
.riscv
.pc
= env
->pc
;
87 info
->value
->arch
= CPU_INFO_ARCH_OTHER
;
89 info
->value
->has_props
= !!mc
->cpu_index_to_instance_props
;
90 if (info
->value
->has_props
) {
91 CpuInstanceProperties
*props
;
92 props
= g_malloc0(sizeof(*props
));
93 *props
= mc
->cpu_index_to_instance_props(ms
, cpu
->cpu_index
);
94 info
->value
->props
= props
;
97 /* XXX: waiting for the qapi to support GSList */
99 head
= cur_item
= info
;
101 cur_item
->next
= info
;
109 static CpuInfoArch
sysemu_target_to_cpuinfo_arch(SysEmuTarget target
)
112 * The @SysEmuTarget -> @CpuInfoArch mapping below is based on the
113 * TARGET_ARCH -> TARGET_BASE_ARCH mapping in the "configure" script.
116 case SYS_EMU_TARGET_I386
:
117 case SYS_EMU_TARGET_X86_64
:
118 return CPU_INFO_ARCH_X86
;
120 case SYS_EMU_TARGET_PPC
:
121 case SYS_EMU_TARGET_PPC64
:
122 return CPU_INFO_ARCH_PPC
;
124 case SYS_EMU_TARGET_SPARC
:
125 case SYS_EMU_TARGET_SPARC64
:
126 return CPU_INFO_ARCH_SPARC
;
128 case SYS_EMU_TARGET_MIPS
:
129 case SYS_EMU_TARGET_MIPSEL
:
130 case SYS_EMU_TARGET_MIPS64
:
131 case SYS_EMU_TARGET_MIPS64EL
:
132 return CPU_INFO_ARCH_MIPS
;
134 case SYS_EMU_TARGET_TRICORE
:
135 return CPU_INFO_ARCH_TRICORE
;
137 case SYS_EMU_TARGET_S390X
:
138 return CPU_INFO_ARCH_S390
;
140 case SYS_EMU_TARGET_RISCV32
:
141 case SYS_EMU_TARGET_RISCV64
:
142 return CPU_INFO_ARCH_RISCV
;
145 return CPU_INFO_ARCH_OTHER
;
149 static void cpustate_to_cpuinfo_s390(CpuInfoS390
*info
, const CPUState
*cpu
)
152 S390CPU
*s390_cpu
= S390_CPU(cpu
);
153 CPUS390XState
*env
= &s390_cpu
->env
;
155 info
->cpu_state
= env
->cpu_state
;
162 * fast means: we NEVER interrupt vCPU threads to retrieve
163 * information from KVM.
165 CpuInfoFastList
*qmp_query_cpus_fast(Error
**errp
)
167 MachineState
*ms
= MACHINE(qdev_get_machine());
168 MachineClass
*mc
= MACHINE_GET_CLASS(ms
);
169 CpuInfoFastList
*head
= NULL
, *cur_item
= NULL
;
170 SysEmuTarget target
= qapi_enum_parse(&SysEmuTarget_lookup
, TARGET_NAME
,
175 CpuInfoFastList
*info
= g_malloc0(sizeof(*info
));
176 info
->value
= g_malloc0(sizeof(*info
->value
));
178 info
->value
->cpu_index
= cpu
->cpu_index
;
179 info
->value
->qom_path
= object_get_canonical_path(OBJECT(cpu
));
180 info
->value
->thread_id
= cpu
->thread_id
;
182 info
->value
->has_props
= !!mc
->cpu_index_to_instance_props
;
183 if (info
->value
->has_props
) {
184 CpuInstanceProperties
*props
;
185 props
= g_malloc0(sizeof(*props
));
186 *props
= mc
->cpu_index_to_instance_props(ms
, cpu
->cpu_index
);
187 info
->value
->props
= props
;
190 info
->value
->arch
= sysemu_target_to_cpuinfo_arch(target
);
191 info
->value
->target
= target
;
192 if (target
== SYS_EMU_TARGET_S390X
) {
193 cpustate_to_cpuinfo_s390(&info
->value
->u
.s390x
, cpu
);
197 head
= cur_item
= info
;
199 cur_item
->next
= info
;
207 MachineInfoList
*qmp_query_machines(Error
**errp
)
209 GSList
*el
, *machines
= object_class_get_list(TYPE_MACHINE
, false);
210 MachineInfoList
*mach_list
= NULL
;
212 for (el
= machines
; el
; el
= el
->next
) {
213 MachineClass
*mc
= el
->data
;
214 MachineInfoList
*entry
;
217 info
= g_malloc0(sizeof(*info
));
218 if (mc
->is_default
) {
219 info
->has_is_default
= true;
220 info
->is_default
= true;
224 info
->has_alias
= true;
225 info
->alias
= g_strdup(mc
->alias
);
228 info
->name
= g_strdup(mc
->name
);
229 info
->cpu_max
= !mc
->max_cpus
? 1 : mc
->max_cpus
;
230 info
->hotpluggable_cpus
= mc
->has_hotpluggable_cpus
;
231 info
->numa_mem_supported
= mc
->numa_mem_supported
;
232 info
->deprecated
= !!mc
->deprecation_reason
;
234 entry
= g_malloc0(sizeof(*entry
));
236 entry
->next
= mach_list
;
240 g_slist_free(machines
);
244 CurrentMachineParams
*qmp_query_current_machine(Error
**errp
)
246 CurrentMachineParams
*params
= g_malloc0(sizeof(*params
));
247 params
->wakeup_suspend_support
= qemu_wakeup_suspend_enabled();
252 HotpluggableCPUList
*qmp_query_hotpluggable_cpus(Error
**errp
)
254 MachineState
*ms
= MACHINE(qdev_get_machine());
255 MachineClass
*mc
= MACHINE_GET_CLASS(ms
);
257 if (!mc
->has_hotpluggable_cpus
) {
258 error_setg(errp
, QERR_FEATURE_DISABLED
, "query-hotpluggable-cpus");
262 return machine_query_hotpluggable_cpus(ms
);
265 void qmp_cpu_add(int64_t id
, Error
**errp
)
269 mc
= MACHINE_GET_CLASS(current_machine
);
270 if (mc
->hot_add_cpu
) {
271 mc
->hot_add_cpu(current_machine
, id
, errp
);
273 error_setg(errp
, "Not supported");
277 void qmp_set_numa_node(NumaOptions
*cmd
, Error
**errp
)
279 if (!runstate_check(RUN_STATE_PRECONFIG
)) {
280 error_setg(errp
, "The command is permitted only in '%s' state",
281 RunState_str(RUN_STATE_PRECONFIG
));
285 set_numa_options(MACHINE(qdev_get_machine()), cmd
, errp
);
288 static int query_memdev(Object
*obj
, void *opaque
)
290 MemdevList
**list
= opaque
;
291 MemdevList
*m
= NULL
;
293 if (object_dynamic_cast(obj
, TYPE_MEMORY_BACKEND
)) {
294 m
= g_malloc0(sizeof(*m
));
296 m
->value
= g_malloc0(sizeof(*m
->value
));
298 m
->value
->id
= object_get_canonical_path_component(obj
);
299 m
->value
->has_id
= !!m
->value
->id
;
301 m
->value
->size
= object_property_get_uint(obj
, "size",
303 m
->value
->merge
= object_property_get_bool(obj
, "merge",
305 m
->value
->dump
= object_property_get_bool(obj
, "dump",
307 m
->value
->prealloc
= object_property_get_bool(obj
,
310 m
->value
->policy
= object_property_get_enum(obj
,
314 object_property_get_uint16List(obj
, "host-nodes",
315 &m
->value
->host_nodes
,
325 MemdevList
*qmp_query_memdev(Error
**errp
)
327 Object
*obj
= object_get_objects_root();
328 MemdevList
*list
= NULL
;
330 object_child_foreach(obj
, query_memdev
, &list
);