]> Git Repo - qemu.git/blame - hw/core/machine.c
compat: replace PC_COMPAT_2_12 & HW_COMPAT_2_12 macros
[qemu.git] / hw / core / machine.c
CommitLineData
36d20cb2
MA
1/*
2 * QEMU Machine
3 *
4 * Copyright (C) 2014 Red Hat Inc
5 *
6 * Authors:
7 * Marcel Apfelbaum <[email protected]>
8 *
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
11 */
12
18c86e2b 13#include "qemu/osdep.h"
fc6b3cf9 14#include "qemu/units.h"
36d20cb2 15#include "hw/boards.h"
da34e65c 16#include "qapi/error.h"
9af23989 17#include "qapi/qapi-visit-common.h"
6b1b1440 18#include "qapi/visitor.h"
33cd52b5
AG
19#include "hw/sysbus.h"
20#include "sysemu/sysemu.h"
3bfe5716 21#include "sysemu/numa.h"
33cd52b5 22#include "qemu/error-report.h"
c6ff347c 23#include "sysemu/qtest.h"
6b1b1440 24
abd93cc7
MAL
25GlobalProperty hw_compat_3_1[] = {
26 {
27 .driver = "pcie-root-port",
28 .property = "x-speed",
29 .value = "2_5",
30 },{
31 .driver = "pcie-root-port",
32 .property = "x-width",
33 .value = "1",
34 },
35};
36const size_t hw_compat_3_1_len = G_N_ELEMENTS(hw_compat_3_1);
37
ddb3235d
MAL
38GlobalProperty hw_compat_3_0[] = {};
39const size_t hw_compat_3_0_len = G_N_ELEMENTS(hw_compat_3_0);
40
0d47310b
MAL
41GlobalProperty hw_compat_2_12[] = {
42 {
43 .driver = "migration",
44 .property = "decompress-error-check",
45 .value = "off",
46 },{
47 .driver = "hda-audio",
48 .property = "use-timer",
49 .value = "false",
50 },{
51 .driver = "cirrus-vga",
52 .property = "global-vmstate",
53 .value = "true",
54 },{
55 .driver = "VGA",
56 .property = "global-vmstate",
57 .value = "true",
58 },{
59 .driver = "vmware-svga",
60 .property = "global-vmstate",
61 .value = "true",
62 },{
63 .driver = "qxl-vga",
64 .property = "global-vmstate",
65 .value = "true",
66 },
67};
68const size_t hw_compat_2_12_len = G_N_ELEMENTS(hw_compat_2_12);
69
6b1b1440
MA
70static char *machine_get_accel(Object *obj, Error **errp)
71{
72 MachineState *ms = MACHINE(obj);
73
74 return g_strdup(ms->accel);
75}
76
77static void machine_set_accel(Object *obj, const char *value, Error **errp)
78{
79 MachineState *ms = MACHINE(obj);
80
556068ee 81 g_free(ms->accel);
6b1b1440
MA
82 ms->accel = g_strdup(value);
83}
84
32c18a2d 85static void machine_set_kernel_irqchip(Object *obj, Visitor *v,
d7bce999 86 const char *name, void *opaque,
32c18a2d 87 Error **errp)
6b1b1440 88{
32c18a2d 89 Error *err = NULL;
6b1b1440 90 MachineState *ms = MACHINE(obj);
32c18a2d 91 OnOffSplit mode;
6b1b1440 92
51e72bc1 93 visit_type_OnOffSplit(v, name, &mode, &err);
32c18a2d
MG
94 if (err) {
95 error_propagate(errp, err);
96 return;
97 } else {
98 switch (mode) {
99 case ON_OFF_SPLIT_ON:
100 ms->kernel_irqchip_allowed = true;
101 ms->kernel_irqchip_required = true;
102 ms->kernel_irqchip_split = false;
103 break;
104 case ON_OFF_SPLIT_OFF:
105 ms->kernel_irqchip_allowed = false;
106 ms->kernel_irqchip_required = false;
107 ms->kernel_irqchip_split = false;
108 break;
109 case ON_OFF_SPLIT_SPLIT:
110 ms->kernel_irqchip_allowed = true;
111 ms->kernel_irqchip_required = true;
112 ms->kernel_irqchip_split = true;
113 break;
114 default:
78a39306
GK
115 /* The value was checked in visit_type_OnOffSplit() above. If
116 * we get here, then something is wrong in QEMU.
117 */
32c18a2d
MG
118 abort();
119 }
120 }
6b1b1440
MA
121}
122
123static void machine_get_kvm_shadow_mem(Object *obj, Visitor *v,
d7bce999 124 const char *name, void *opaque,
6b1b1440
MA
125 Error **errp)
126{
127 MachineState *ms = MACHINE(obj);
128 int64_t value = ms->kvm_shadow_mem;
129
51e72bc1 130 visit_type_int(v, name, &value, errp);
6b1b1440
MA
131}
132
133static void machine_set_kvm_shadow_mem(Object *obj, Visitor *v,
d7bce999 134 const char *name, void *opaque,
6b1b1440
MA
135 Error **errp)
136{
137 MachineState *ms = MACHINE(obj);
138 Error *error = NULL;
139 int64_t value;
140
51e72bc1 141 visit_type_int(v, name, &value, &error);
6b1b1440
MA
142 if (error) {
143 error_propagate(errp, error);
144 return;
145 }
146
147 ms->kvm_shadow_mem = value;
148}
149
150static char *machine_get_kernel(Object *obj, Error **errp)
151{
152 MachineState *ms = MACHINE(obj);
153
154 return g_strdup(ms->kernel_filename);
155}
156
157static void machine_set_kernel(Object *obj, const char *value, Error **errp)
158{
159 MachineState *ms = MACHINE(obj);
160
556068ee 161 g_free(ms->kernel_filename);
6b1b1440
MA
162 ms->kernel_filename = g_strdup(value);
163}
164
165static char *machine_get_initrd(Object *obj, Error **errp)
166{
167 MachineState *ms = MACHINE(obj);
168
169 return g_strdup(ms->initrd_filename);
170}
171
172static void machine_set_initrd(Object *obj, const char *value, Error **errp)
173{
174 MachineState *ms = MACHINE(obj);
175
556068ee 176 g_free(ms->initrd_filename);
6b1b1440
MA
177 ms->initrd_filename = g_strdup(value);
178}
179
180static char *machine_get_append(Object *obj, Error **errp)
181{
182 MachineState *ms = MACHINE(obj);
183
184 return g_strdup(ms->kernel_cmdline);
185}
186
187static void machine_set_append(Object *obj, const char *value, Error **errp)
188{
189 MachineState *ms = MACHINE(obj);
190
556068ee 191 g_free(ms->kernel_cmdline);
6b1b1440
MA
192 ms->kernel_cmdline = g_strdup(value);
193}
194
195static char *machine_get_dtb(Object *obj, Error **errp)
196{
197 MachineState *ms = MACHINE(obj);
198
199 return g_strdup(ms->dtb);
200}
201
202static void machine_set_dtb(Object *obj, const char *value, Error **errp)
203{
204 MachineState *ms = MACHINE(obj);
205
556068ee 206 g_free(ms->dtb);
6b1b1440
MA
207 ms->dtb = g_strdup(value);
208}
209
210static char *machine_get_dumpdtb(Object *obj, Error **errp)
211{
212 MachineState *ms = MACHINE(obj);
213
214 return g_strdup(ms->dumpdtb);
215}
216
217static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp)
218{
219 MachineState *ms = MACHINE(obj);
220
556068ee 221 g_free(ms->dumpdtb);
6b1b1440
MA
222 ms->dumpdtb = g_strdup(value);
223}
224
225static void machine_get_phandle_start(Object *obj, Visitor *v,
d7bce999
EB
226 const char *name, void *opaque,
227 Error **errp)
6b1b1440
MA
228{
229 MachineState *ms = MACHINE(obj);
230 int64_t value = ms->phandle_start;
231
51e72bc1 232 visit_type_int(v, name, &value, errp);
6b1b1440
MA
233}
234
235static void machine_set_phandle_start(Object *obj, Visitor *v,
d7bce999
EB
236 const char *name, void *opaque,
237 Error **errp)
6b1b1440
MA
238{
239 MachineState *ms = MACHINE(obj);
240 Error *error = NULL;
241 int64_t value;
242
51e72bc1 243 visit_type_int(v, name, &value, &error);
6b1b1440
MA
244 if (error) {
245 error_propagate(errp, error);
246 return;
247 }
248
249 ms->phandle_start = value;
250}
251
252static char *machine_get_dt_compatible(Object *obj, Error **errp)
253{
254 MachineState *ms = MACHINE(obj);
255
256 return g_strdup(ms->dt_compatible);
257}
258
259static void machine_set_dt_compatible(Object *obj, const char *value, Error **errp)
260{
261 MachineState *ms = MACHINE(obj);
262
556068ee 263 g_free(ms->dt_compatible);
6b1b1440
MA
264 ms->dt_compatible = g_strdup(value);
265}
266
267static bool machine_get_dump_guest_core(Object *obj, Error **errp)
268{
269 MachineState *ms = MACHINE(obj);
270
271 return ms->dump_guest_core;
272}
273
274static void machine_set_dump_guest_core(Object *obj, bool value, Error **errp)
275{
276 MachineState *ms = MACHINE(obj);
277
278 ms->dump_guest_core = value;
279}
280
281static bool machine_get_mem_merge(Object *obj, Error **errp)
282{
283 MachineState *ms = MACHINE(obj);
284
285 return ms->mem_merge;
286}
287
288static void machine_set_mem_merge(Object *obj, bool value, Error **errp)
289{
290 MachineState *ms = MACHINE(obj);
291
292 ms->mem_merge = value;
293}
294
295static bool machine_get_usb(Object *obj, Error **errp)
296{
297 MachineState *ms = MACHINE(obj);
298
299 return ms->usb;
300}
301
302static void machine_set_usb(Object *obj, bool value, Error **errp)
303{
304 MachineState *ms = MACHINE(obj);
305
306 ms->usb = value;
c6e76503 307 ms->usb_disabled = !value;
6b1b1440
MA
308}
309
cfc58cf3
EH
310static bool machine_get_graphics(Object *obj, Error **errp)
311{
312 MachineState *ms = MACHINE(obj);
313
314 return ms->enable_graphics;
315}
316
317static void machine_set_graphics(Object *obj, bool value, Error **errp)
318{
319 MachineState *ms = MACHINE(obj);
320
321 ms->enable_graphics = value;
322}
323
79814179
TC
324static bool machine_get_igd_gfx_passthru(Object *obj, Error **errp)
325{
326 MachineState *ms = MACHINE(obj);
327
328 return ms->igd_gfx_passthru;
329}
330
331static void machine_set_igd_gfx_passthru(Object *obj, bool value, Error **errp)
332{
333 MachineState *ms = MACHINE(obj);
334
335 ms->igd_gfx_passthru = value;
336}
337
6b1b1440
MA
338static char *machine_get_firmware(Object *obj, Error **errp)
339{
340 MachineState *ms = MACHINE(obj);
341
342 return g_strdup(ms->firmware);
343}
344
345static void machine_set_firmware(Object *obj, const char *value, Error **errp)
346{
347 MachineState *ms = MACHINE(obj);
348
556068ee 349 g_free(ms->firmware);
6b1b1440
MA
350 ms->firmware = g_strdup(value);
351}
352
9850c604
AG
353static void machine_set_suppress_vmdesc(Object *obj, bool value, Error **errp)
354{
355 MachineState *ms = MACHINE(obj);
356
357 ms->suppress_vmdesc = value;
358}
359
360static bool machine_get_suppress_vmdesc(Object *obj, Error **errp)
361{
362 MachineState *ms = MACHINE(obj);
363
364 return ms->suppress_vmdesc;
365}
366
902c053d
GK
367static void machine_set_enforce_config_section(Object *obj, bool value,
368 Error **errp)
369{
370 MachineState *ms = MACHINE(obj);
371
91c082ad
TH
372 warn_report("enforce-config-section is deprecated, please use "
373 "-global migration.send-configuration=on|off instead");
374
902c053d
GK
375 ms->enforce_config_section = value;
376}
377
378static bool machine_get_enforce_config_section(Object *obj, Error **errp)
379{
380 MachineState *ms = MACHINE(obj);
381
382 return ms->enforce_config_section;
383}
384
db588194
BS
385static char *machine_get_memory_encryption(Object *obj, Error **errp)
386{
387 MachineState *ms = MACHINE(obj);
388
389 return g_strdup(ms->memory_encryption);
390}
391
392static void machine_set_memory_encryption(Object *obj, const char *value,
393 Error **errp)
394{
395 MachineState *ms = MACHINE(obj);
396
397 g_free(ms->memory_encryption);
398 ms->memory_encryption = g_strdup(value);
399}
400
0bd1909d 401void machine_class_allow_dynamic_sysbus_dev(MachineClass *mc, const char *type)
33cd52b5 402{
0bd1909d
EH
403 strList *item = g_new0(strList, 1);
404
405 item->value = g_strdup(type);
406 item->next = mc->allowed_dynamic_sysbus_devices;
407 mc->allowed_dynamic_sysbus_devices = item;
33cd52b5
AG
408}
409
0bd1909d 410static void validate_sysbus_device(SysBusDevice *sbdev, void *opaque)
33cd52b5 411{
0bd1909d
EH
412 MachineState *machine = opaque;
413 MachineClass *mc = MACHINE_GET_CLASS(machine);
414 bool allowed = false;
415 strList *wl;
33cd52b5 416
0bd1909d
EH
417 for (wl = mc->allowed_dynamic_sysbus_devices;
418 !allowed && wl;
419 wl = wl->next) {
420 allowed |= !!object_dynamic_cast(OBJECT(sbdev), wl->value);
421 }
422
423 if (!allowed) {
424 error_report("Option '-device %s' cannot be handled by this machine",
425 object_class_get_name(object_get_class(OBJECT(sbdev))));
426 exit(1);
33cd52b5 427 }
0bd1909d
EH
428}
429
430static void machine_init_notify(Notifier *notifier, void *data)
431{
432 MachineState *machine = MACHINE(qdev_get_machine());
33cd52b5
AG
433
434 /*
0bd1909d
EH
435 * Loop through all dynamically created sysbus devices and check if they are
436 * all allowed. If a device is not allowed, error out.
33cd52b5 437 */
0bd1909d 438 foreach_dynamic_sysbus_device(validate_sysbus_device, machine);
33cd52b5
AG
439}
440
f2d672c2
IM
441HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine)
442{
443 int i;
f2d672c2 444 HotpluggableCPUList *head = NULL;
d342eb76
IM
445 MachineClass *mc = MACHINE_GET_CLASS(machine);
446
447 /* force board to initialize possible_cpus if it hasn't been done yet */
448 mc->possible_cpu_arch_ids(machine);
f2d672c2 449
f2d672c2 450 for (i = 0; i < machine->possible_cpus->len; i++) {
d342eb76 451 Object *cpu;
f2d672c2
IM
452 HotpluggableCPUList *list_item = g_new0(typeof(*list_item), 1);
453 HotpluggableCPU *cpu_item = g_new0(typeof(*cpu_item), 1);
454
d342eb76 455 cpu_item->type = g_strdup(machine->possible_cpus->cpus[i].type);
f2d672c2
IM
456 cpu_item->vcpus_count = machine->possible_cpus->cpus[i].vcpus_count;
457 cpu_item->props = g_memdup(&machine->possible_cpus->cpus[i].props,
458 sizeof(*cpu_item->props));
459
460 cpu = machine->possible_cpus->cpus[i].cpu;
461 if (cpu) {
462 cpu_item->has_qom_path = true;
463 cpu_item->qom_path = object_get_canonical_path(cpu);
464 }
465 list_item->value = cpu_item;
466 list_item->next = head;
467 head = list_item;
468 }
469 return head;
470}
471
7c88e65d
IM
472/**
473 * machine_set_cpu_numa_node:
474 * @machine: machine object to modify
475 * @props: specifies which cpu objects to assign to
476 * numa node specified by @props.node_id
477 * @errp: if an error occurs, a pointer to an area to store the error
478 *
479 * Associate NUMA node specified by @props.node_id with cpu slots that
480 * match socket/core/thread-ids specified by @props. It's recommended to use
481 * query-hotpluggable-cpus.props values to specify affected cpu slots,
482 * which would lead to exact 1:1 mapping of cpu slots to NUMA node.
483 *
484 * However for CLI convenience it's possible to pass in subset of properties,
485 * which would affect all cpu slots that match it.
486 * Ex for pc machine:
487 * -smp 4,cores=2,sockets=2 -numa node,nodeid=0 -numa node,nodeid=1 \
488 * -numa cpu,node-id=0,socket_id=0 \
489 * -numa cpu,node-id=1,socket_id=1
490 * will assign all child cores of socket 0 to node 0 and
491 * of socket 1 to node 1.
492 *
493 * On attempt of reassigning (already assigned) cpu slot to another NUMA node,
494 * return error.
495 * Empty subset is disallowed and function will return with error in this case.
496 */
497void machine_set_cpu_numa_node(MachineState *machine,
498 const CpuInstanceProperties *props, Error **errp)
499{
500 MachineClass *mc = MACHINE_GET_CLASS(machine);
501 bool match = false;
502 int i;
503
504 if (!mc->possible_cpu_arch_ids) {
505 error_setg(errp, "mapping of CPUs to NUMA node is not supported");
506 return;
507 }
508
509 /* disabling node mapping is not supported, forbid it */
510 assert(props->has_node_id);
511
512 /* force board to initialize possible_cpus if it hasn't been done yet */
513 mc->possible_cpu_arch_ids(machine);
514
515 for (i = 0; i < machine->possible_cpus->len; i++) {
516 CPUArchId *slot = &machine->possible_cpus->cpus[i];
517
518 /* reject unsupported by board properties */
519 if (props->has_thread_id && !slot->props.has_thread_id) {
520 error_setg(errp, "thread-id is not supported");
521 return;
522 }
523
524 if (props->has_core_id && !slot->props.has_core_id) {
525 error_setg(errp, "core-id is not supported");
526 return;
527 }
528
529 if (props->has_socket_id && !slot->props.has_socket_id) {
530 error_setg(errp, "socket-id is not supported");
531 return;
532 }
533
534 /* skip slots with explicit mismatch */
535 if (props->has_thread_id && props->thread_id != slot->props.thread_id) {
536 continue;
537 }
538
539 if (props->has_core_id && props->core_id != slot->props.core_id) {
540 continue;
541 }
542
543 if (props->has_socket_id && props->socket_id != slot->props.socket_id) {
544 continue;
545 }
546
547 /* reject assignment if slot is already assigned, for compatibility
548 * of legacy cpu_index mapping with SPAPR core based mapping do not
549 * error out if cpu thread and matched core have the same node-id */
550 if (slot->props.has_node_id &&
551 slot->props.node_id != props->node_id) {
552 error_setg(errp, "CPU is already assigned to node-id: %" PRId64,
553 slot->props.node_id);
554 return;
555 }
556
557 /* assign slot to node as it's matched '-numa cpu' key */
558 match = true;
559 slot->props.node_id = props->node_id;
560 slot->props.has_node_id = props->has_node_id;
561 }
562
563 if (!match) {
564 error_setg(errp, "no match found");
565 }
566}
567
076b35b5
ND
568static void machine_class_init(ObjectClass *oc, void *data)
569{
570 MachineClass *mc = MACHINE_CLASS(oc);
571
572 /* Default 128 MB as guest ram size */
d23b6caa 573 mc->default_ram_size = 128 * MiB;
71ae9e94 574 mc->rom_file_has_mr = true;
26b81df4 575
55641213
LV
576 /* numa node memory size aligned on 8MB by default.
577 * On Linux, each node's border has to be 8MB aligned
578 */
579 mc->numa_mem_align_shift = 23;
3bfe5716 580 mc->numa_auto_assign_ram = numa_default_auto_assign_ram;
55641213 581
26b81df4
EH
582 object_class_property_add_str(oc, "accel",
583 machine_get_accel, machine_set_accel, &error_abort);
584 object_class_property_set_description(oc, "accel",
585 "Accelerator list", &error_abort);
586
e80200c5 587 object_class_property_add(oc, "kernel-irqchip", "on|off|split",
26b81df4
EH
588 NULL, machine_set_kernel_irqchip,
589 NULL, NULL, &error_abort);
590 object_class_property_set_description(oc, "kernel-irqchip",
591 "Configure KVM in-kernel irqchip", &error_abort);
592
593 object_class_property_add(oc, "kvm-shadow-mem", "int",
594 machine_get_kvm_shadow_mem, machine_set_kvm_shadow_mem,
595 NULL, NULL, &error_abort);
596 object_class_property_set_description(oc, "kvm-shadow-mem",
597 "KVM shadow MMU size", &error_abort);
598
599 object_class_property_add_str(oc, "kernel",
600 machine_get_kernel, machine_set_kernel, &error_abort);
601 object_class_property_set_description(oc, "kernel",
602 "Linux kernel image file", &error_abort);
603
604 object_class_property_add_str(oc, "initrd",
605 machine_get_initrd, machine_set_initrd, &error_abort);
606 object_class_property_set_description(oc, "initrd",
607 "Linux initial ramdisk file", &error_abort);
608
609 object_class_property_add_str(oc, "append",
610 machine_get_append, machine_set_append, &error_abort);
611 object_class_property_set_description(oc, "append",
612 "Linux kernel command line", &error_abort);
613
614 object_class_property_add_str(oc, "dtb",
615 machine_get_dtb, machine_set_dtb, &error_abort);
616 object_class_property_set_description(oc, "dtb",
617 "Linux kernel device tree file", &error_abort);
618
619 object_class_property_add_str(oc, "dumpdtb",
620 machine_get_dumpdtb, machine_set_dumpdtb, &error_abort);
621 object_class_property_set_description(oc, "dumpdtb",
622 "Dump current dtb to a file and quit", &error_abort);
623
624 object_class_property_add(oc, "phandle-start", "int",
625 machine_get_phandle_start, machine_set_phandle_start,
626 NULL, NULL, &error_abort);
627 object_class_property_set_description(oc, "phandle-start",
628 "The first phandle ID we may generate dynamically", &error_abort);
629
630 object_class_property_add_str(oc, "dt-compatible",
631 machine_get_dt_compatible, machine_set_dt_compatible, &error_abort);
632 object_class_property_set_description(oc, "dt-compatible",
633 "Overrides the \"compatible\" property of the dt root node",
634 &error_abort);
635
636 object_class_property_add_bool(oc, "dump-guest-core",
637 machine_get_dump_guest_core, machine_set_dump_guest_core, &error_abort);
638 object_class_property_set_description(oc, "dump-guest-core",
639 "Include guest memory in a core dump", &error_abort);
640
641 object_class_property_add_bool(oc, "mem-merge",
642 machine_get_mem_merge, machine_set_mem_merge, &error_abort);
643 object_class_property_set_description(oc, "mem-merge",
644 "Enable/disable memory merge support", &error_abort);
645
646 object_class_property_add_bool(oc, "usb",
647 machine_get_usb, machine_set_usb, &error_abort);
648 object_class_property_set_description(oc, "usb",
649 "Set on/off to enable/disable usb", &error_abort);
650
651 object_class_property_add_bool(oc, "graphics",
652 machine_get_graphics, machine_set_graphics, &error_abort);
653 object_class_property_set_description(oc, "graphics",
654 "Set on/off to enable/disable graphics emulation", &error_abort);
655
656 object_class_property_add_bool(oc, "igd-passthru",
657 machine_get_igd_gfx_passthru, machine_set_igd_gfx_passthru,
658 &error_abort);
659 object_class_property_set_description(oc, "igd-passthru",
660 "Set on/off to enable/disable igd passthrou", &error_abort);
661
662 object_class_property_add_str(oc, "firmware",
663 machine_get_firmware, machine_set_firmware,
664 &error_abort);
665 object_class_property_set_description(oc, "firmware",
666 "Firmware image", &error_abort);
667
668 object_class_property_add_bool(oc, "suppress-vmdesc",
669 machine_get_suppress_vmdesc, machine_set_suppress_vmdesc,
670 &error_abort);
671 object_class_property_set_description(oc, "suppress-vmdesc",
672 "Set on to disable self-describing migration", &error_abort);
673
674 object_class_property_add_bool(oc, "enforce-config-section",
675 machine_get_enforce_config_section, machine_set_enforce_config_section,
676 &error_abort);
677 object_class_property_set_description(oc, "enforce-config-section",
678 "Set on to enforce configuration section migration", &error_abort);
db588194
BS
679
680 object_class_property_add_str(oc, "memory-encryption",
681 machine_get_memory_encryption, machine_set_memory_encryption,
682 &error_abort);
683 object_class_property_set_description(oc, "memory-encryption",
bfec23a0 684 "Set memory encryption object to use", &error_abort);
076b35b5
ND
685}
686
dcb3d601
EH
687static void machine_class_base_init(ObjectClass *oc, void *data)
688{
689 if (!object_class_is_abstract(oc)) {
98cec76a 690 MachineClass *mc = MACHINE_CLASS(oc);
dcb3d601
EH
691 const char *cname = object_class_get_name(oc);
692 assert(g_str_has_suffix(cname, TYPE_MACHINE_SUFFIX));
98cec76a
EH
693 mc->name = g_strndup(cname,
694 strlen(cname) - strlen(TYPE_MACHINE_SUFFIX));
b66bbee3 695 mc->compat_props = g_ptr_array_new();
dcb3d601
EH
696 }
697}
698
6b1b1440
MA
699static void machine_initfn(Object *obj)
700{
33cd52b5 701 MachineState *ms = MACHINE(obj);
b2fc91db 702 MachineClass *mc = MACHINE_GET_CLASS(obj);
33cd52b5 703
d8870d02 704 ms->kernel_irqchip_allowed = true;
b2fc91db 705 ms->kernel_irqchip_split = mc->default_kernel_irqchip_split;
4689b77b 706 ms->kvm_shadow_mem = -1;
47c8ca53 707 ms->dump_guest_core = true;
75cc7f01 708 ms->mem_merge = true;
cfc58cf3 709 ms->enable_graphics = true;
d8870d02 710
33cd52b5
AG
711 /* Register notifier when init is done for sysbus sanity checks */
712 ms->sysbus_notifier.notify = machine_init_notify;
713 qemu_add_machine_init_done_notifier(&ms->sysbus_notifier);
6b1b1440
MA
714}
715
716static void machine_finalize(Object *obj)
717{
718 MachineState *ms = MACHINE(obj);
719
720 g_free(ms->accel);
721 g_free(ms->kernel_filename);
722 g_free(ms->initrd_filename);
723 g_free(ms->kernel_cmdline);
724 g_free(ms->dtb);
725 g_free(ms->dumpdtb);
726 g_free(ms->dt_compatible);
727 g_free(ms->firmware);
2ff4f67c 728 g_free(ms->device_memory);
6b1b1440 729}
36d20cb2 730
5e97b623
MA
731bool machine_usb(MachineState *machine)
732{
733 return machine->usb;
734}
735
d8870d02
MA
736bool machine_kernel_irqchip_allowed(MachineState *machine)
737{
738 return machine->kernel_irqchip_allowed;
739}
740
741bool machine_kernel_irqchip_required(MachineState *machine)
742{
743 return machine->kernel_irqchip_required;
744}
745
32c18a2d
MG
746bool machine_kernel_irqchip_split(MachineState *machine)
747{
748 return machine->kernel_irqchip_split;
749}
750
4689b77b
MA
751int machine_kvm_shadow_mem(MachineState *machine)
752{
753 return machine->kvm_shadow_mem;
754}
755
6cabe7fa
MA
756int machine_phandle_start(MachineState *machine)
757{
758 return machine->phandle_start;
759}
760
47c8ca53
MA
761bool machine_dump_guest_core(MachineState *machine)
762{
763 return machine->dump_guest_core;
764}
765
75cc7f01
MA
766bool machine_mem_merge(MachineState *machine)
767{
768 return machine->mem_merge;
769}
770
ec78f811
IM
771static char *cpu_slot_to_string(const CPUArchId *cpu)
772{
773 GString *s = g_string_new(NULL);
774 if (cpu->props.has_socket_id) {
775 g_string_append_printf(s, "socket-id: %"PRId64, cpu->props.socket_id);
776 }
777 if (cpu->props.has_core_id) {
778 if (s->len) {
779 g_string_append_printf(s, ", ");
780 }
781 g_string_append_printf(s, "core-id: %"PRId64, cpu->props.core_id);
782 }
783 if (cpu->props.has_thread_id) {
784 if (s->len) {
785 g_string_append_printf(s, ", ");
786 }
787 g_string_append_printf(s, "thread-id: %"PRId64, cpu->props.thread_id);
788 }
789 return g_string_free(s, false);
790}
791
7a3099fc 792static void machine_numa_finish_cpu_init(MachineState *machine)
ec78f811
IM
793{
794 int i;
60bed6a3 795 bool default_mapping;
ec78f811
IM
796 GString *s = g_string_new(NULL);
797 MachineClass *mc = MACHINE_GET_CLASS(machine);
798 const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(machine);
799
800 assert(nb_numa_nodes);
60bed6a3
IM
801 for (i = 0; i < possible_cpus->len; i++) {
802 if (possible_cpus->cpus[i].props.has_node_id) {
803 break;
804 }
805 }
806 default_mapping = (i == possible_cpus->len);
807
ec78f811
IM
808 for (i = 0; i < possible_cpus->len; i++) {
809 const CPUArchId *cpu_slot = &possible_cpus->cpus[i];
810
ec78f811 811 if (!cpu_slot->props.has_node_id) {
d41f3e75
IM
812 /* fetch default mapping from board and enable it */
813 CpuInstanceProperties props = cpu_slot->props;
814
79e07936 815 props.node_id = mc->get_default_cpu_node_id(machine, i);
d41f3e75 816 if (!default_mapping) {
60bed6a3
IM
817 /* record slots with not set mapping,
818 * TODO: make it hard error in future */
819 char *cpu_str = cpu_slot_to_string(cpu_slot);
820 g_string_append_printf(s, "%sCPU %d [%s]",
821 s->len ? ", " : "", i, cpu_str);
822 g_free(cpu_str);
d41f3e75
IM
823
824 /* non mapped cpus used to fallback to node 0 */
825 props.node_id = 0;
60bed6a3 826 }
d41f3e75
IM
827
828 props.has_node_id = true;
829 machine_set_cpu_numa_node(machine, &props, &error_fatal);
ec78f811
IM
830 }
831 }
c6ff347c 832 if (s->len && !qtest_enabled()) {
3dc6f869
AF
833 warn_report("CPU(s) not present in any NUMA nodes: %s",
834 s->str);
835 warn_report("All CPU(s) up to maxcpus should be described "
836 "in NUMA config, ability to start up with partial NUMA "
837 "mappings is obsoleted and will be removed in future");
ec78f811
IM
838 }
839 g_string_free(s, true);
840}
841
482dfe9a
IM
842void machine_run_board_init(MachineState *machine)
843{
844 MachineClass *machine_class = MACHINE_GET_CLASS(machine);
ec78f811 845
7747abf1 846 numa_complete_configuration(machine);
3aeaac8f 847 if (nb_numa_nodes) {
7a3099fc 848 machine_numa_finish_cpu_init(machine);
3aeaac8f 849 }
c9cf636d
AF
850
851 /* If the machine supports the valid_cpu_types check and the user
852 * specified a CPU with -cpu check here that the user CPU is supported.
853 */
854 if (machine_class->valid_cpu_types && machine->cpu_type) {
855 ObjectClass *class = object_class_by_name(machine->cpu_type);
856 int i;
857
858 for (i = 0; machine_class->valid_cpu_types[i]; i++) {
859 if (object_class_dynamic_cast(class,
860 machine_class->valid_cpu_types[i])) {
861 /* The user specificed CPU is in the valid field, we are
862 * good to go.
863 */
864 break;
865 }
866 }
867
868 if (!machine_class->valid_cpu_types[i]) {
869 /* The user specified CPU is not valid */
870 error_report("Invalid CPU type: %s", machine->cpu_type);
871 error_printf("The valid types are: %s",
872 machine_class->valid_cpu_types[0]);
873 for (i = 1; machine_class->valid_cpu_types[i]; i++) {
874 error_printf(", %s", machine_class->valid_cpu_types[i]);
875 }
876 error_printf("\n");
877
878 exit(1);
879 }
880 }
881
482dfe9a
IM
882 machine_class->init(machine);
883}
884
36d20cb2
MA
885static const TypeInfo machine_info = {
886 .name = TYPE_MACHINE,
887 .parent = TYPE_OBJECT,
888 .abstract = true,
889 .class_size = sizeof(MachineClass),
076b35b5 890 .class_init = machine_class_init,
dcb3d601 891 .class_base_init = machine_class_base_init,
36d20cb2 892 .instance_size = sizeof(MachineState),
6b1b1440
MA
893 .instance_init = machine_initfn,
894 .instance_finalize = machine_finalize,
36d20cb2
MA
895};
896
897static void machine_register_types(void)
898{
899 type_register_static(&machine_info);
900}
901
902type_init(machine_register_types)
This page took 0.389955 seconds and 4 git commands to generate.