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