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