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