]> git.proxmox.com Git - mirror_qemu.git/blame - hw/core/machine.c
Merge tag 'pull-target-arm-20220509' of https://git.linaro.org/people/pmaydell/qemu...
[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"
6f479566
LX
14#include "qemu/option.h"
15#include "qapi/qmp/qerror.h"
16#include "sysemu/replay.h"
fc6b3cf9 17#include "qemu/units.h"
36d20cb2 18#include "hw/boards.h"
f66dc873 19#include "hw/loader.h"
da34e65c 20#include "qapi/error.h"
9af23989 21#include "qapi/qapi-visit-common.h"
fe68090e 22#include "qapi/qapi-visit-machine.h"
6b1b1440 23#include "qapi/visitor.h"
33cd52b5 24#include "hw/sysbus.h"
f66dc873 25#include "sysemu/cpus.h"
33cd52b5 26#include "sysemu/sysemu.h"
f66dc873
PB
27#include "sysemu/reset.h"
28#include "sysemu/runstate.h"
3bfe5716 29#include "sysemu/numa.h"
33cd52b5 30#include "qemu/error-report.h"
c6ff347c 31#include "sysemu/qtest.h"
edc24ccd 32#include "hw/pci/pci.h"
f6a0d06b 33#include "hw/mem/nvdimm.h"
f66dc873 34#include "migration/global_state.h"
82b911aa 35#include "migration/vmstate.h"
e0292d7c 36#include "exec/confidential-guest-support.h"
9f88a7a3
DG
37#include "hw/virtio/virtio.h"
38#include "hw/virtio/virtio-pci.h"
6b1b1440 39
0ca70366
CH
40GlobalProperty hw_compat_7_0[] = {};
41const size_t hw_compat_7_0_len = G_N_ELEMENTS(hw_compat_7_0);
42
a83c2844
DDAG
43GlobalProperty hw_compat_6_2[] = {
44 { "PIIX4_PM", "x-not-migrate-acpi-index", "on"},
45};
01854af2
CH
46const size_t hw_compat_6_2_len = G_N_ELEMENTS(hw_compat_6_2);
47
46ce0171
SG
48GlobalProperty hw_compat_6_1[] = {
49 { "vhost-user-vsock-device", "seqpacket", "off" },
916b0f0b 50 { "nvme-ns", "shared", "off" },
46ce0171 51};
52e64f5b
YW
52const size_t hw_compat_6_1_len = G_N_ELEMENTS(hw_compat_6_1);
53
a6091108
PM
54GlobalProperty hw_compat_6_0[] = {
55 { "gpex-pcihost", "allow-unmapped-accesses", "false" },
ff6e1624 56 { "i8042", "extended-state", "false"},
3276dde4 57 { "nvme-ns", "eui64-default", "off"},
a1d7e475 58 { "e1000", "init-vet", "off" },
d8970569 59 { "e1000e", "init-vet", "off" },
d6a9378f 60 { "vhost-vsock-device", "seqpacket", "off" },
a6091108 61};
da7e13c0
CH
62const size_t hw_compat_6_0_len = G_N_ELEMENTS(hw_compat_6_0);
63
6be8cf56
IY
64GlobalProperty hw_compat_5_2[] = {
65 { "ICH9-LPC", "smm-compat", "on"},
66 { "PIIX4_PM", "smm-compat", "on"},
fb0b154c 67 { "virtio-blk-device", "report-discard-granularity", "off" },
3fd641ac 68 { "virtio-net-pci-base", "vectors", "3"},
6be8cf56 69};
576a00bd
CH
70const size_t hw_compat_5_2_len = G_N_ELEMENTS(hw_compat_5_2);
71
6a558822
SH
72GlobalProperty hw_compat_5_1[] = {
73 { "vhost-scsi", "num_queues", "1"},
a4eef071 74 { "vhost-user-blk", "num-queues", "1"},
6a558822 75 { "vhost-user-scsi", "num_queues", "1"},
9445e1e1 76 { "virtio-blk-device", "num-queues", "1"},
6a558822 77 { "virtio-scsi-device", "num_queues", "1"},
6eb7a071 78 { "nvme", "use-intel-id", "on"},
b1b0393c 79 { "pvpanic", "events", "1"}, /* PVPANIC_PANICKED */
e6fa978d 80 { "pl011", "migrate-clk", "off" },
d83f46d1 81 { "virtio-pci", "x-ats-page-aligned", "off"},
6a558822 82};
3ff3c5d3
CH
83const size_t hw_compat_5_1_len = G_N_ELEMENTS(hw_compat_5_1);
84
7483cbba 85GlobalProperty hw_compat_5_0[] = {
2ebc2121 86 { "pci-host-bridge", "x-config-reg-migration-enabled", "off" },
7483cbba 87 { "virtio-balloon-device", "page-poison", "false" },
f983ff95
PB
88 { "vmport", "x-read-set-eax", "off" },
89 { "vmport", "x-signal-unsupported-cmd", "off" },
90 { "vmport", "x-report-vmx-type", "off" },
91 { "vmport", "x-cmds-v2", "off" },
d55f5182 92 { "virtio-device", "x-disable-legacy-check", "true" },
7483cbba 93};
541aaa1d
CH
94const size_t hw_compat_5_0_len = G_N_ELEMENTS(hw_compat_5_0);
95
5f258577 96GlobalProperty hw_compat_4_2[] = {
c9b7d9ec
DP
97 { "virtio-blk-device", "queue-size", "128"},
98 { "virtio-scsi-device", "virtqueue_size", "128"},
5f258577 99 { "virtio-blk-device", "x-enable-wce-if-config-wce", "off" },
1bf8a989
DP
100 { "virtio-blk-device", "seg-max-adjust", "off"},
101 { "virtio-scsi-device", "seg_max_adjust", "off"},
102 { "vhost-blk-device", "seg_max_adjust", "off"},
7bacaf5f 103 { "usb-host", "suppress-remote-wake", "off" },
32187f3d 104 { "usb-redir", "suppress-remote-wake", "off" },
ed71c09f
GH
105 { "qxl", "revision", "4" },
106 { "qxl-vga", "revision", "4" },
394f0f72 107 { "fw_cfg", "acpi-mr-restore", "false" },
c126b4c5 108 { "virtio-device", "use-disabled-flag", "false" },
5f258577
EY
109};
110const size_t hw_compat_4_2_len = G_N_ELEMENTS(hw_compat_4_2);
111
eb1556c4
JS
112GlobalProperty hw_compat_4_1[] = {
113 { "virtio-pci", "x-pcie-flr-init", "off" },
114};
9aec2e52
CH
115const size_t hw_compat_4_1_len = G_N_ELEMENTS(hw_compat_4_1);
116
8e8cbed0 117GlobalProperty hw_compat_4_0[] = {
0a719662
GH
118 { "VGA", "edid", "false" },
119 { "secondary-vga", "edid", "false" },
120 { "bochs-display", "edid", "false" },
121 { "virtio-vga", "edid", "false" },
02501fc3 122 { "virtio-gpu-device", "edid", "false" },
e57f2c31 123 { "virtio-device", "use-started", "false" },
2bbadb08 124 { "virtio-balloon-device", "qemu-4-0-config-size", "true" },
032cfe6a 125 { "pl031", "migrate-tick-offset", "false" },
0a719662 126};
9bf2650b
CH
127const size_t hw_compat_4_0_len = G_N_ELEMENTS(hw_compat_4_0);
128
abd93cc7 129GlobalProperty hw_compat_3_1[] = {
6c36bddf
EH
130 { "pcie-root-port", "x-speed", "2_5" },
131 { "pcie-root-port", "x-width", "1" },
132 { "memory-backend-file", "x-use-canonical-path-for-ramblock-id", "true" },
133 { "memory-backend-memfd", "x-use-canonical-path-for-ramblock-id", "true" },
b6148757
MAL
134 { "tpm-crb", "ppi", "false" },
135 { "tpm-tis", "ppi", "false" },
b63e1050
GH
136 { "usb-kbd", "serial", "42" },
137 { "usb-mouse", "serial", "42" },
442bac16 138 { "usb-tablet", "serial", "42" },
5c81161f
SG
139 { "virtio-blk-device", "discard", "false" },
140 { "virtio-blk-device", "write-zeroes", "false" },
2bbadb08 141 { "virtio-balloon-device", "qemu-4-0-config-size", "false" },
c8557f1b 142 { "pcie-root-port-base", "disable-acs", "true" }, /* Added in 4.1 */
abd93cc7
MAL
143};
144const size_t hw_compat_3_1_len = G_N_ELEMENTS(hw_compat_3_1);
145
ddb3235d
MAL
146GlobalProperty hw_compat_3_0[] = {};
147const size_t hw_compat_3_0_len = G_N_ELEMENTS(hw_compat_3_0);
148
0d47310b 149GlobalProperty hw_compat_2_12[] = {
6c36bddf
EH
150 { "migration", "decompress-error-check", "off" },
151 { "hda-audio", "use-timer", "false" },
152 { "cirrus-vga", "global-vmstate", "true" },
153 { "VGA", "global-vmstate", "true" },
154 { "vmware-svga", "global-vmstate", "true" },
155 { "qxl-vga", "global-vmstate", "true" },
0d47310b
MAL
156};
157const size_t hw_compat_2_12_len = G_N_ELEMENTS(hw_compat_2_12);
158
43df70a9 159GlobalProperty hw_compat_2_11[] = {
6c36bddf
EH
160 { "hpet", "hpet-offset-saved", "false" },
161 { "virtio-blk-pci", "vectors", "2" },
162 { "vhost-user-blk-pci", "vectors", "2" },
163 { "e1000", "migrate_tso_props", "off" },
43df70a9
MAL
164};
165const size_t hw_compat_2_11_len = G_N_ELEMENTS(hw_compat_2_11);
166
503224f4 167GlobalProperty hw_compat_2_10[] = {
6c36bddf
EH
168 { "virtio-mouse-device", "wheel-axis", "false" },
169 { "virtio-tablet-device", "wheel-axis", "false" },
503224f4
MAL
170};
171const size_t hw_compat_2_10_len = G_N_ELEMENTS(hw_compat_2_10);
172
3e803152 173GlobalProperty hw_compat_2_9[] = {
6c36bddf
EH
174 { "pci-bridge", "shpc", "off" },
175 { "intel-iommu", "pt", "off" },
176 { "virtio-net-device", "x-mtu-bypass-backend", "off" },
177 { "pcie-root-port", "x-migrate-msix", "false" },
3e803152
MAL
178};
179const size_t hw_compat_2_9_len = G_N_ELEMENTS(hw_compat_2_9);
180
edc24ccd 181GlobalProperty hw_compat_2_8[] = {
6c36bddf
EH
182 { "fw_cfg_mem", "x-file-slots", "0x10" },
183 { "fw_cfg_io", "x-file-slots", "0x10" },
184 { "pflash_cfi01", "old-multiple-chip-handling", "on" },
185 { "pci-bridge", "shpc", "on" },
186 { TYPE_PCI_DEVICE, "x-pcie-extcap-init", "off" },
187 { "virtio-pci", "x-pcie-deverr-init", "off" },
188 { "virtio-pci", "x-pcie-lnkctl-init", "off" },
189 { "virtio-pci", "x-pcie-pm-init", "off" },
190 { "cirrus-vga", "vgamem_mb", "8" },
191 { "isa-cirrus-vga", "vgamem_mb", "8" },
edc24ccd
MAL
192};
193const size_t hw_compat_2_8_len = G_N_ELEMENTS(hw_compat_2_8);
194
5a995064 195GlobalProperty hw_compat_2_7[] = {
6c36bddf
EH
196 { "virtio-pci", "page-per-vq", "on" },
197 { "virtio-serial-device", "emergency-write", "off" },
198 { "ioapic", "version", "0x11" },
199 { "intel-iommu", "x-buggy-eim", "true" },
200 { "virtio-pci", "x-ignore-backend-features", "on" },
5a995064
MAL
201};
202const size_t hw_compat_2_7_len = G_N_ELEMENTS(hw_compat_2_7);
203
ff8f261f 204GlobalProperty hw_compat_2_6[] = {
6c36bddf 205 { "virtio-mmio", "format_transport_address", "off" },
dd56040d
DDAG
206 /* Optional because not all virtio-pci devices support legacy mode */
207 { "virtio-pci", "disable-modern", "on", .optional = true },
208 { "virtio-pci", "disable-legacy", "off", .optional = true },
ff8f261f
MAL
209};
210const size_t hw_compat_2_6_len = G_N_ELEMENTS(hw_compat_2_6);
211
fe759610 212GlobalProperty hw_compat_2_5[] = {
6c36bddf
EH
213 { "isa-fdc", "fallback", "144" },
214 { "pvscsi", "x-old-pci-configuration", "on" },
215 { "pvscsi", "x-disable-pcie", "on" },
216 { "vmxnet3", "x-old-msi-offsets", "on" },
217 { "vmxnet3", "x-disable-pcie", "on" },
fe759610
MAL
218};
219const size_t hw_compat_2_5_len = G_N_ELEMENTS(hw_compat_2_5);
220
2f99b9c2 221GlobalProperty hw_compat_2_4[] = {
11a18c84
PMD
222 /* Optional because the 'scsi' property is Linux-only */
223 { "virtio-blk-device", "scsi", "true", .optional = true },
6c36bddf
EH
224 { "e1000", "extra_mac_registers", "off" },
225 { "virtio-pci", "x-disable-pcie", "on" },
226 { "virtio-pci", "migrate-extra", "off" },
227 { "fw_cfg_mem", "dma_enabled", "off" },
228 { "fw_cfg_io", "dma_enabled", "off" }
2f99b9c2
MAL
229};
230const size_t hw_compat_2_4_len = G_N_ELEMENTS(hw_compat_2_4);
231
8995dd90 232GlobalProperty hw_compat_2_3[] = {
6c36bddf
EH
233 { "virtio-blk-pci", "any_layout", "off" },
234 { "virtio-balloon-pci", "any_layout", "off" },
235 { "virtio-serial-pci", "any_layout", "off" },
236 { "virtio-9p-pci", "any_layout", "off" },
237 { "virtio-rng-pci", "any_layout", "off" },
238 { TYPE_PCI_DEVICE, "x-pcie-lnksta-dllla", "off" },
239 { "migration", "send-configuration", "off" },
240 { "migration", "send-section-footer", "off" },
241 { "migration", "store-global-state", "off" },
8995dd90
MAL
242};
243const size_t hw_compat_2_3_len = G_N_ELEMENTS(hw_compat_2_3);
244
1c30044e
MAL
245GlobalProperty hw_compat_2_2[] = {};
246const size_t hw_compat_2_2_len = G_N_ELEMENTS(hw_compat_2_2);
247
c4fc5695 248GlobalProperty hw_compat_2_1[] = {
6c36bddf
EH
249 { "intel-hda", "old_msi_addr", "on" },
250 { "VGA", "qemu-extended-regs", "off" },
251 { "secondary-vga", "qemu-extended-regs", "off" },
252 { "virtio-scsi-pci", "any_layout", "off" },
253 { "usb-mouse", "usb_version", "1" },
254 { "usb-kbd", "usb_version", "1" },
255 { "virtio-pci", "virtio-pci-bus-master-bug-migration", "on" },
c4fc5695
MAL
256};
257const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1);
258
c5e3c918
PB
259MachineState *current_machine;
260
6b1b1440
MA
261static char *machine_get_kernel(Object *obj, Error **errp)
262{
263 MachineState *ms = MACHINE(obj);
264
265 return g_strdup(ms->kernel_filename);
266}
267
268static void machine_set_kernel(Object *obj, const char *value, Error **errp)
269{
270 MachineState *ms = MACHINE(obj);
271
556068ee 272 g_free(ms->kernel_filename);
6b1b1440
MA
273 ms->kernel_filename = g_strdup(value);
274}
275
276static char *machine_get_initrd(Object *obj, Error **errp)
277{
278 MachineState *ms = MACHINE(obj);
279
280 return g_strdup(ms->initrd_filename);
281}
282
283static void machine_set_initrd(Object *obj, const char *value, Error **errp)
284{
285 MachineState *ms = MACHINE(obj);
286
556068ee 287 g_free(ms->initrd_filename);
6b1b1440
MA
288 ms->initrd_filename = g_strdup(value);
289}
290
291static char *machine_get_append(Object *obj, Error **errp)
292{
293 MachineState *ms = MACHINE(obj);
294
295 return g_strdup(ms->kernel_cmdline);
296}
297
298static void machine_set_append(Object *obj, const char *value, Error **errp)
299{
300 MachineState *ms = MACHINE(obj);
301
556068ee 302 g_free(ms->kernel_cmdline);
6b1b1440
MA
303 ms->kernel_cmdline = g_strdup(value);
304}
305
306static char *machine_get_dtb(Object *obj, Error **errp)
307{
308 MachineState *ms = MACHINE(obj);
309
310 return g_strdup(ms->dtb);
311}
312
313static void machine_set_dtb(Object *obj, const char *value, Error **errp)
314{
315 MachineState *ms = MACHINE(obj);
316
556068ee 317 g_free(ms->dtb);
6b1b1440
MA
318 ms->dtb = g_strdup(value);
319}
320
321static char *machine_get_dumpdtb(Object *obj, Error **errp)
322{
323 MachineState *ms = MACHINE(obj);
324
325 return g_strdup(ms->dumpdtb);
326}
327
328static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp)
329{
330 MachineState *ms = MACHINE(obj);
331
556068ee 332 g_free(ms->dumpdtb);
6b1b1440
MA
333 ms->dumpdtb = g_strdup(value);
334}
335
336static void machine_get_phandle_start(Object *obj, Visitor *v,
d7bce999
EB
337 const char *name, void *opaque,
338 Error **errp)
6b1b1440
MA
339{
340 MachineState *ms = MACHINE(obj);
341 int64_t value = ms->phandle_start;
342
51e72bc1 343 visit_type_int(v, name, &value, errp);
6b1b1440
MA
344}
345
346static void machine_set_phandle_start(Object *obj, Visitor *v,
d7bce999
EB
347 const char *name, void *opaque,
348 Error **errp)
6b1b1440
MA
349{
350 MachineState *ms = MACHINE(obj);
6b1b1440
MA
351 int64_t value;
352
668f62ec 353 if (!visit_type_int(v, name, &value, errp)) {
6b1b1440
MA
354 return;
355 }
356
357 ms->phandle_start = value;
358}
359
360static char *machine_get_dt_compatible(Object *obj, Error **errp)
361{
362 MachineState *ms = MACHINE(obj);
363
364 return g_strdup(ms->dt_compatible);
365}
366
367static void machine_set_dt_compatible(Object *obj, const char *value, Error **errp)
368{
369 MachineState *ms = MACHINE(obj);
370
556068ee 371 g_free(ms->dt_compatible);
6b1b1440
MA
372 ms->dt_compatible = g_strdup(value);
373}
374
375static bool machine_get_dump_guest_core(Object *obj, Error **errp)
376{
377 MachineState *ms = MACHINE(obj);
378
379 return ms->dump_guest_core;
380}
381
382static void machine_set_dump_guest_core(Object *obj, bool value, Error **errp)
383{
384 MachineState *ms = MACHINE(obj);
385
386 ms->dump_guest_core = value;
387}
388
389static bool machine_get_mem_merge(Object *obj, Error **errp)
390{
391 MachineState *ms = MACHINE(obj);
392
393 return ms->mem_merge;
394}
395
396static void machine_set_mem_merge(Object *obj, bool value, Error **errp)
397{
398 MachineState *ms = MACHINE(obj);
399
400 ms->mem_merge = value;
401}
402
403static bool machine_get_usb(Object *obj, Error **errp)
404{
405 MachineState *ms = MACHINE(obj);
406
407 return ms->usb;
408}
409
410static void machine_set_usb(Object *obj, bool value, Error **errp)
411{
412 MachineState *ms = MACHINE(obj);
413
414 ms->usb = value;
c6e76503 415 ms->usb_disabled = !value;
6b1b1440
MA
416}
417
cfc58cf3
EH
418static bool machine_get_graphics(Object *obj, Error **errp)
419{
420 MachineState *ms = MACHINE(obj);
421
422 return ms->enable_graphics;
423}
424
425static void machine_set_graphics(Object *obj, bool value, Error **errp)
426{
427 MachineState *ms = MACHINE(obj);
428
429 ms->enable_graphics = value;
430}
431
6b1b1440
MA
432static char *machine_get_firmware(Object *obj, Error **errp)
433{
434 MachineState *ms = MACHINE(obj);
435
436 return g_strdup(ms->firmware);
437}
438
439static void machine_set_firmware(Object *obj, const char *value, Error **errp)
440{
441 MachineState *ms = MACHINE(obj);
442
556068ee 443 g_free(ms->firmware);
6b1b1440
MA
444 ms->firmware = g_strdup(value);
445}
446
9850c604
AG
447static void machine_set_suppress_vmdesc(Object *obj, bool value, Error **errp)
448{
449 MachineState *ms = MACHINE(obj);
450
451 ms->suppress_vmdesc = value;
452}
453
454static bool machine_get_suppress_vmdesc(Object *obj, Error **errp)
455{
456 MachineState *ms = MACHINE(obj);
457
458 return ms->suppress_vmdesc;
459}
460
db588194
BS
461static char *machine_get_memory_encryption(Object *obj, Error **errp)
462{
463 MachineState *ms = MACHINE(obj);
464
e0292d7c
DG
465 if (ms->cgs) {
466 return g_strdup(object_get_canonical_path_component(OBJECT(ms->cgs)));
467 }
468
469 return NULL;
db588194
BS
470}
471
472static void machine_set_memory_encryption(Object *obj, const char *value,
473 Error **errp)
474{
e0292d7c
DG
475 Object *cgs =
476 object_resolve_path_component(object_get_objects_root(), value);
477
478 if (!cgs) {
479 error_setg(errp, "No such memory encryption object '%s'", value);
480 return;
481 }
db588194 482
e0292d7c
DG
483 object_property_set_link(obj, "confidential-guest-support", cgs, errp);
484}
485
486static void machine_check_confidential_guest_support(const Object *obj,
487 const char *name,
488 Object *new_target,
489 Error **errp)
490{
491 /*
492 * So far the only constraint is that the target has the
493 * TYPE_CONFIDENTIAL_GUEST_SUPPORT interface, and that's checked
494 * by the QOM core
495 */
db588194
BS
496}
497
f6a0d06b
EA
498static bool machine_get_nvdimm(Object *obj, Error **errp)
499{
500 MachineState *ms = MACHINE(obj);
501
502 return ms->nvdimms_state->is_enabled;
503}
504
505static void machine_set_nvdimm(Object *obj, bool value, Error **errp)
506{
507 MachineState *ms = MACHINE(obj);
508
509 ms->nvdimms_state->is_enabled = value;
510}
511
244b3f44
TX
512static bool machine_get_hmat(Object *obj, Error **errp)
513{
514 MachineState *ms = MACHINE(obj);
515
516 return ms->numa_state->hmat_enabled;
517}
518
519static void machine_set_hmat(Object *obj, bool value, Error **errp)
520{
521 MachineState *ms = MACHINE(obj);
522
523 ms->numa_state->hmat_enabled = value;
524}
525
f6a0d06b
EA
526static char *machine_get_nvdimm_persistence(Object *obj, Error **errp)
527{
528 MachineState *ms = MACHINE(obj);
529
530 return g_strdup(ms->nvdimms_state->persistence_string);
531}
532
533static void machine_set_nvdimm_persistence(Object *obj, const char *value,
534 Error **errp)
535{
536 MachineState *ms = MACHINE(obj);
537 NVDIMMState *nvdimms_state = ms->nvdimms_state;
538
539 if (strcmp(value, "cpu") == 0) {
540 nvdimms_state->persistence = 3;
541 } else if (strcmp(value, "mem-ctrl") == 0) {
542 nvdimms_state->persistence = 2;
543 } else {
544 error_setg(errp, "-machine nvdimm-persistence=%s: unsupported option",
545 value);
546 return;
547 }
548
549 g_free(nvdimms_state->persistence_string);
550 nvdimms_state->persistence_string = g_strdup(value);
551}
552
0bd1909d 553void machine_class_allow_dynamic_sysbus_dev(MachineClass *mc, const char *type)
33cd52b5 554{
54aa3de7 555 QAPI_LIST_PREPEND(mc->allowed_dynamic_sysbus_devices, g_strdup(type));
33cd52b5
AG
556}
557
0fb124db 558bool device_is_dynamic_sysbus(MachineClass *mc, DeviceState *dev)
33cd52b5 559{
0fb124db
PM
560 Object *obj = OBJECT(dev);
561
562 if (!object_dynamic_cast(obj, TYPE_SYS_BUS_DEVICE)) {
563 return false;
564 }
33cd52b5 565
b5fdf410
DH
566 return device_type_is_dynamic_sysbus(mc, object_get_typename(obj));
567}
568
569bool device_type_is_dynamic_sysbus(MachineClass *mc, const char *type)
570{
571 bool allowed = false;
572 strList *wl;
573 ObjectClass *klass = object_class_by_name(type);
574
0bd1909d
EH
575 for (wl = mc->allowed_dynamic_sysbus_devices;
576 !allowed && wl;
577 wl = wl->next) {
b5fdf410 578 allowed |= !!object_class_dynamic_cast(klass, wl->value);
0bd1909d
EH
579 }
580
0fb124db
PM
581 return allowed;
582}
583
aa8b1839
IM
584static char *machine_get_memdev(Object *obj, Error **errp)
585{
586 MachineState *ms = MACHINE(obj);
587
588 return g_strdup(ms->ram_memdev_id);
589}
590
591static void machine_set_memdev(Object *obj, const char *value, Error **errp)
592{
593 MachineState *ms = MACHINE(obj);
594
595 g_free(ms->ram_memdev_id);
596 ms->ram_memdev_id = g_strdup(value);
597}
598
f2d672c2
IM
599HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine)
600{
601 int i;
f2d672c2 602 HotpluggableCPUList *head = NULL;
d342eb76
IM
603 MachineClass *mc = MACHINE_GET_CLASS(machine);
604
605 /* force board to initialize possible_cpus if it hasn't been done yet */
606 mc->possible_cpu_arch_ids(machine);
f2d672c2 607
f2d672c2 608 for (i = 0; i < machine->possible_cpus->len; i++) {
d342eb76 609 Object *cpu;
f2d672c2
IM
610 HotpluggableCPU *cpu_item = g_new0(typeof(*cpu_item), 1);
611
d342eb76 612 cpu_item->type = g_strdup(machine->possible_cpus->cpus[i].type);
f2d672c2
IM
613 cpu_item->vcpus_count = machine->possible_cpus->cpus[i].vcpus_count;
614 cpu_item->props = g_memdup(&machine->possible_cpus->cpus[i].props,
615 sizeof(*cpu_item->props));
616
617 cpu = machine->possible_cpus->cpus[i].cpu;
618 if (cpu) {
619 cpu_item->has_qom_path = true;
620 cpu_item->qom_path = object_get_canonical_path(cpu);
621 }
54aa3de7 622 QAPI_LIST_PREPEND(head, cpu_item);
f2d672c2
IM
623 }
624 return head;
625}
626
7c88e65d
IM
627/**
628 * machine_set_cpu_numa_node:
629 * @machine: machine object to modify
630 * @props: specifies which cpu objects to assign to
631 * numa node specified by @props.node_id
632 * @errp: if an error occurs, a pointer to an area to store the error
633 *
634 * Associate NUMA node specified by @props.node_id with cpu slots that
635 * match socket/core/thread-ids specified by @props. It's recommended to use
636 * query-hotpluggable-cpus.props values to specify affected cpu slots,
637 * which would lead to exact 1:1 mapping of cpu slots to NUMA node.
638 *
639 * However for CLI convenience it's possible to pass in subset of properties,
640 * which would affect all cpu slots that match it.
641 * Ex for pc machine:
642 * -smp 4,cores=2,sockets=2 -numa node,nodeid=0 -numa node,nodeid=1 \
643 * -numa cpu,node-id=0,socket_id=0 \
644 * -numa cpu,node-id=1,socket_id=1
645 * will assign all child cores of socket 0 to node 0 and
646 * of socket 1 to node 1.
647 *
648 * On attempt of reassigning (already assigned) cpu slot to another NUMA node,
649 * return error.
650 * Empty subset is disallowed and function will return with error in this case.
651 */
652void machine_set_cpu_numa_node(MachineState *machine,
653 const CpuInstanceProperties *props, Error **errp)
654{
655 MachineClass *mc = MACHINE_GET_CLASS(machine);
244b3f44 656 NodeInfo *numa_info = machine->numa_state->nodes;
7c88e65d
IM
657 bool match = false;
658 int i;
659
660 if (!mc->possible_cpu_arch_ids) {
661 error_setg(errp, "mapping of CPUs to NUMA node is not supported");
662 return;
663 }
664
665 /* disabling node mapping is not supported, forbid it */
666 assert(props->has_node_id);
667
668 /* force board to initialize possible_cpus if it hasn't been done yet */
669 mc->possible_cpu_arch_ids(machine);
670
671 for (i = 0; i < machine->possible_cpus->len; i++) {
672 CPUArchId *slot = &machine->possible_cpus->cpus[i];
673
674 /* reject unsupported by board properties */
675 if (props->has_thread_id && !slot->props.has_thread_id) {
676 error_setg(errp, "thread-id is not supported");
677 return;
678 }
679
680 if (props->has_core_id && !slot->props.has_core_id) {
681 error_setg(errp, "core-id is not supported");
682 return;
683 }
684
1dcf7001
GS
685 if (props->has_cluster_id && !slot->props.has_cluster_id) {
686 error_setg(errp, "cluster-id is not supported");
687 return;
688 }
689
7c88e65d
IM
690 if (props->has_socket_id && !slot->props.has_socket_id) {
691 error_setg(errp, "socket-id is not supported");
692 return;
693 }
694
176d2cda
LX
695 if (props->has_die_id && !slot->props.has_die_id) {
696 error_setg(errp, "die-id is not supported");
697 return;
698 }
699
7c88e65d
IM
700 /* skip slots with explicit mismatch */
701 if (props->has_thread_id && props->thread_id != slot->props.thread_id) {
702 continue;
703 }
704
705 if (props->has_core_id && props->core_id != slot->props.core_id) {
706 continue;
707 }
708
1dcf7001
GS
709 if (props->has_cluster_id &&
710 props->cluster_id != slot->props.cluster_id) {
711 continue;
712 }
713
176d2cda
LX
714 if (props->has_die_id && props->die_id != slot->props.die_id) {
715 continue;
716 }
717
7c88e65d
IM
718 if (props->has_socket_id && props->socket_id != slot->props.socket_id) {
719 continue;
720 }
721
722 /* reject assignment if slot is already assigned, for compatibility
723 * of legacy cpu_index mapping with SPAPR core based mapping do not
724 * error out if cpu thread and matched core have the same node-id */
725 if (slot->props.has_node_id &&
726 slot->props.node_id != props->node_id) {
727 error_setg(errp, "CPU is already assigned to node-id: %" PRId64,
728 slot->props.node_id);
729 return;
730 }
731
732 /* assign slot to node as it's matched '-numa cpu' key */
733 match = true;
734 slot->props.node_id = props->node_id;
735 slot->props.has_node_id = props->has_node_id;
244b3f44
TX
736
737 if (machine->numa_state->hmat_enabled) {
738 if ((numa_info[props->node_id].initiator < MAX_NODES) &&
739 (props->node_id != numa_info[props->node_id].initiator)) {
740 error_setg(errp, "The initiator of CPU NUMA node %" PRId64
f74d339c
MP
741 " should be itself (got %" PRIu16 ")",
742 props->node_id, numa_info[props->node_id].initiator);
244b3f44
TX
743 return;
744 }
745 numa_info[props->node_id].has_cpu = true;
746 numa_info[props->node_id].initiator = props->node_id;
747 }
7c88e65d
IM
748 }
749
750 if (!match) {
751 error_setg(errp, "no match found");
752 }
753}
754
fe68090e
PB
755static void machine_get_smp(Object *obj, Visitor *v, const char *name,
756 void *opaque, Error **errp)
757{
758 MachineState *ms = MACHINE(obj);
759 SMPConfiguration *config = &(SMPConfiguration){
003f230e 760 .has_cpus = true, .cpus = ms->smp.cpus,
fe68090e
PB
761 .has_sockets = true, .sockets = ms->smp.sockets,
762 .has_dies = true, .dies = ms->smp.dies,
864c3b5c 763 .has_clusters = true, .clusters = ms->smp.clusters,
003f230e 764 .has_cores = true, .cores = ms->smp.cores,
fe68090e 765 .has_threads = true, .threads = ms->smp.threads,
fe68090e
PB
766 .has_maxcpus = true, .maxcpus = ms->smp.max_cpus,
767 };
864c3b5c 768
fe68090e
PB
769 if (!visit_type_SMPConfiguration(v, name, &config, &error_abort)) {
770 return;
771 }
772}
773
774static void machine_set_smp(Object *obj, Visitor *v, const char *name,
775 void *opaque, Error **errp)
776{
fe68090e 777 MachineState *ms = MACHINE(obj);
e7f944bb 778 g_autoptr(SMPConfiguration) config = NULL;
fe68090e
PB
779
780 if (!visit_type_SMPConfiguration(v, name, &config, errp)) {
781 return;
782 }
783
3e2f1498 784 machine_parse_smp_config(ms, config, errp);
fe68090e
PB
785}
786
076b35b5
ND
787static void machine_class_init(ObjectClass *oc, void *data)
788{
789 MachineClass *mc = MACHINE_CLASS(oc);
790
791 /* Default 128 MB as guest ram size */
d23b6caa 792 mc->default_ram_size = 128 * MiB;
71ae9e94 793 mc->rom_file_has_mr = true;
26b81df4 794
55641213
LV
795 /* numa node memory size aligned on 8MB by default.
796 * On Linux, each node's border has to be 8MB aligned
797 */
798 mc->numa_mem_align_shift = 23;
799
26b81df4 800 object_class_property_add_str(oc, "kernel",
d2623129 801 machine_get_kernel, machine_set_kernel);
26b81df4 802 object_class_property_set_description(oc, "kernel",
7eecec7d 803 "Linux kernel image file");
26b81df4
EH
804
805 object_class_property_add_str(oc, "initrd",
d2623129 806 machine_get_initrd, machine_set_initrd);
26b81df4 807 object_class_property_set_description(oc, "initrd",
7eecec7d 808 "Linux initial ramdisk file");
26b81df4
EH
809
810 object_class_property_add_str(oc, "append",
d2623129 811 machine_get_append, machine_set_append);
26b81df4 812 object_class_property_set_description(oc, "append",
7eecec7d 813 "Linux kernel command line");
26b81df4
EH
814
815 object_class_property_add_str(oc, "dtb",
d2623129 816 machine_get_dtb, machine_set_dtb);
26b81df4 817 object_class_property_set_description(oc, "dtb",
7eecec7d 818 "Linux kernel device tree file");
26b81df4
EH
819
820 object_class_property_add_str(oc, "dumpdtb",
d2623129 821 machine_get_dumpdtb, machine_set_dumpdtb);
26b81df4 822 object_class_property_set_description(oc, "dumpdtb",
7eecec7d 823 "Dump current dtb to a file and quit");
26b81df4 824
fe68090e
PB
825 object_class_property_add(oc, "smp", "SMPConfiguration",
826 machine_get_smp, machine_set_smp,
827 NULL, NULL);
828 object_class_property_set_description(oc, "smp",
829 "CPU topology");
830
26b81df4
EH
831 object_class_property_add(oc, "phandle-start", "int",
832 machine_get_phandle_start, machine_set_phandle_start,
d2623129 833 NULL, NULL);
26b81df4 834 object_class_property_set_description(oc, "phandle-start",
7eecec7d 835 "The first phandle ID we may generate dynamically");
26b81df4
EH
836
837 object_class_property_add_str(oc, "dt-compatible",
d2623129 838 machine_get_dt_compatible, machine_set_dt_compatible);
26b81df4 839 object_class_property_set_description(oc, "dt-compatible",
7eecec7d 840 "Overrides the \"compatible\" property of the dt root node");
26b81df4
EH
841
842 object_class_property_add_bool(oc, "dump-guest-core",
d2623129 843 machine_get_dump_guest_core, machine_set_dump_guest_core);
26b81df4 844 object_class_property_set_description(oc, "dump-guest-core",
7eecec7d 845 "Include guest memory in a core dump");
26b81df4
EH
846
847 object_class_property_add_bool(oc, "mem-merge",
d2623129 848 machine_get_mem_merge, machine_set_mem_merge);
26b81df4 849 object_class_property_set_description(oc, "mem-merge",
7eecec7d 850 "Enable/disable memory merge support");
26b81df4
EH
851
852 object_class_property_add_bool(oc, "usb",
d2623129 853 machine_get_usb, machine_set_usb);
26b81df4 854 object_class_property_set_description(oc, "usb",
7eecec7d 855 "Set on/off to enable/disable usb");
26b81df4
EH
856
857 object_class_property_add_bool(oc, "graphics",
d2623129 858 machine_get_graphics, machine_set_graphics);
26b81df4 859 object_class_property_set_description(oc, "graphics",
7eecec7d 860 "Set on/off to enable/disable graphics emulation");
26b81df4 861
26b81df4 862 object_class_property_add_str(oc, "firmware",
d2623129 863 machine_get_firmware, machine_set_firmware);
26b81df4 864 object_class_property_set_description(oc, "firmware",
7eecec7d 865 "Firmware image");
26b81df4
EH
866
867 object_class_property_add_bool(oc, "suppress-vmdesc",
d2623129 868 machine_get_suppress_vmdesc, machine_set_suppress_vmdesc);
26b81df4 869 object_class_property_set_description(oc, "suppress-vmdesc",
7eecec7d 870 "Set on to disable self-describing migration");
26b81df4 871
e0292d7c
DG
872 object_class_property_add_link(oc, "confidential-guest-support",
873 TYPE_CONFIDENTIAL_GUEST_SUPPORT,
874 offsetof(MachineState, cgs),
875 machine_check_confidential_guest_support,
876 OBJ_PROP_LINK_STRONG);
877 object_class_property_set_description(oc, "confidential-guest-support",
878 "Set confidential guest scheme to support");
879
880 /* For compatibility */
db588194 881 object_class_property_add_str(oc, "memory-encryption",
d2623129 882 machine_get_memory_encryption, machine_set_memory_encryption);
db588194 883 object_class_property_set_description(oc, "memory-encryption",
7eecec7d 884 "Set memory encryption object to use");
acd5b054
EH
885
886 object_class_property_add_str(oc, "memory-backend",
887 machine_get_memdev, machine_set_memdev);
888 object_class_property_set_description(oc, "memory-backend",
889 "Set RAM backend"
890 "Valid value is ID of hostmem based backend");
076b35b5
ND
891}
892
dcb3d601
EH
893static void machine_class_base_init(ObjectClass *oc, void *data)
894{
2c920e45
PB
895 MachineClass *mc = MACHINE_CLASS(oc);
896 mc->max_cpus = mc->max_cpus ?: 1;
897 mc->min_cpus = mc->min_cpus ?: 1;
898 mc->default_cpus = mc->default_cpus ?: 1;
899
dcb3d601
EH
900 if (!object_class_is_abstract(oc)) {
901 const char *cname = object_class_get_name(oc);
902 assert(g_str_has_suffix(cname, TYPE_MACHINE_SUFFIX));
98cec76a
EH
903 mc->name = g_strndup(cname,
904 strlen(cname) - strlen(TYPE_MACHINE_SUFFIX));
b66bbee3 905 mc->compat_props = g_ptr_array_new();
dcb3d601
EH
906 }
907}
908
6b1b1440
MA
909static void machine_initfn(Object *obj)
910{
33cd52b5 911 MachineState *ms = MACHINE(obj);
b2fc91db 912 MachineClass *mc = MACHINE_GET_CLASS(obj);
33cd52b5 913
e0d17dfd
PB
914 container_get(obj, "/peripheral");
915 container_get(obj, "/peripheral-anon");
916
47c8ca53 917 ms->dump_guest_core = true;
75cc7f01 918 ms->mem_merge = true;
cfc58cf3 919 ms->enable_graphics = true;
58c91595 920 ms->kernel_cmdline = g_strdup("");
d8870d02 921
f6a0d06b
EA
922 if (mc->nvdimm_supported) {
923 Object *obj = OBJECT(ms);
924
925 ms->nvdimms_state = g_new0(NVDIMMState, 1);
926 object_property_add_bool(obj, "nvdimm",
d2623129 927 machine_get_nvdimm, machine_set_nvdimm);
f6a0d06b
EA
928 object_property_set_description(obj, "nvdimm",
929 "Set on/off to enable/disable "
7eecec7d 930 "NVDIMM instantiation");
f6a0d06b
EA
931
932 object_property_add_str(obj, "nvdimm-persistence",
933 machine_get_nvdimm_persistence,
d2623129 934 machine_set_nvdimm_persistence);
f6a0d06b
EA
935 object_property_set_description(obj, "nvdimm-persistence",
936 "Set NVDIMM persistence"
7eecec7d 937 "Valid values are cpu, mem-ctrl");
f6a0d06b
EA
938 }
939
fcd3f2cc 940 if (mc->cpu_index_to_instance_props && mc->get_default_cpu_node_id) {
aa570207 941 ms->numa_state = g_new0(NumaState, 1);
244b3f44 942 object_property_add_bool(obj, "hmat",
d2623129 943 machine_get_hmat, machine_set_hmat);
244b3f44
TX
944 object_property_set_description(obj, "hmat",
945 "Set on/off to enable/disable "
946 "ACPI Heterogeneous Memory Attribute "
7eecec7d 947 "Table (HMAT)");
aa570207 948 }
f6a0d06b 949
8b0e484c
PB
950 /* default to mc->default_cpus */
951 ms->smp.cpus = mc->default_cpus;
952 ms->smp.max_cpus = mc->default_cpus;
003f230e 953 ms->smp.sockets = 1;
67872eb8 954 ms->smp.dies = 1;
864c3b5c 955 ms->smp.clusters = 1;
003f230e 956 ms->smp.cores = 1;
8b0e484c 957 ms->smp.threads = 1;
6b1b1440
MA
958}
959
960static void machine_finalize(Object *obj)
961{
962 MachineState *ms = MACHINE(obj);
963
6b1b1440
MA
964 g_free(ms->kernel_filename);
965 g_free(ms->initrd_filename);
966 g_free(ms->kernel_cmdline);
967 g_free(ms->dtb);
968 g_free(ms->dumpdtb);
969 g_free(ms->dt_compatible);
970 g_free(ms->firmware);
2ff4f67c 971 g_free(ms->device_memory);
f6a0d06b 972 g_free(ms->nvdimms_state);
aa570207 973 g_free(ms->numa_state);
6b1b1440 974}
36d20cb2 975
5e97b623
MA
976bool machine_usb(MachineState *machine)
977{
978 return machine->usb;
979}
980
6cabe7fa
MA
981int machine_phandle_start(MachineState *machine)
982{
983 return machine->phandle_start;
984}
985
47c8ca53
MA
986bool machine_dump_guest_core(MachineState *machine)
987{
988 return machine->dump_guest_core;
989}
990
75cc7f01
MA
991bool machine_mem_merge(MachineState *machine)
992{
993 return machine->mem_merge;
994}
995
ec78f811
IM
996static char *cpu_slot_to_string(const CPUArchId *cpu)
997{
998 GString *s = g_string_new(NULL);
999 if (cpu->props.has_socket_id) {
1000 g_string_append_printf(s, "socket-id: %"PRId64, cpu->props.socket_id);
1001 }
176d2cda 1002 if (cpu->props.has_die_id) {
3a23a0c0
YW
1003 if (s->len) {
1004 g_string_append_printf(s, ", ");
1005 }
176d2cda
LX
1006 g_string_append_printf(s, "die-id: %"PRId64, cpu->props.die_id);
1007 }
1dcf7001
GS
1008 if (cpu->props.has_cluster_id) {
1009 if (s->len) {
1010 g_string_append_printf(s, ", ");
1011 }
1012 g_string_append_printf(s, "cluster-id: %"PRId64, cpu->props.cluster_id);
1013 }
ec78f811
IM
1014 if (cpu->props.has_core_id) {
1015 if (s->len) {
1016 g_string_append_printf(s, ", ");
1017 }
1018 g_string_append_printf(s, "core-id: %"PRId64, cpu->props.core_id);
1019 }
1020 if (cpu->props.has_thread_id) {
1021 if (s->len) {
1022 g_string_append_printf(s, ", ");
1023 }
1024 g_string_append_printf(s, "thread-id: %"PRId64, cpu->props.thread_id);
1025 }
1026 return g_string_free(s, false);
1027}
1028
244b3f44
TX
1029static void numa_validate_initiator(NumaState *numa_state)
1030{
1031 int i;
1032 NodeInfo *numa_info = numa_state->nodes;
1033
1034 for (i = 0; i < numa_state->num_nodes; i++) {
1035 if (numa_info[i].initiator == MAX_NODES) {
1036 error_report("The initiator of NUMA node %d is missing, use "
1037 "'-numa node,initiator' option to declare it", i);
1038 exit(1);
1039 }
1040
1041 if (!numa_info[numa_info[i].initiator].present) {
1042 error_report("NUMA node %" PRIu16 " is missing, use "
1043 "'-numa node' option to declare it first",
1044 numa_info[i].initiator);
1045 exit(1);
1046 }
1047
1048 if (!numa_info[numa_info[i].initiator].has_cpu) {
1049 error_report("The initiator of NUMA node %d is invalid", i);
1050 exit(1);
1051 }
1052 }
1053}
1054
7a3099fc 1055static void machine_numa_finish_cpu_init(MachineState *machine)
ec78f811
IM
1056{
1057 int i;
60bed6a3 1058 bool default_mapping;
ec78f811
IM
1059 GString *s = g_string_new(NULL);
1060 MachineClass *mc = MACHINE_GET_CLASS(machine);
1061 const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(machine);
1062
aa570207 1063 assert(machine->numa_state->num_nodes);
60bed6a3
IM
1064 for (i = 0; i < possible_cpus->len; i++) {
1065 if (possible_cpus->cpus[i].props.has_node_id) {
1066 break;
1067 }
1068 }
1069 default_mapping = (i == possible_cpus->len);
1070
ec78f811
IM
1071 for (i = 0; i < possible_cpus->len; i++) {
1072 const CPUArchId *cpu_slot = &possible_cpus->cpus[i];
1073
ec78f811 1074 if (!cpu_slot->props.has_node_id) {
d41f3e75
IM
1075 /* fetch default mapping from board and enable it */
1076 CpuInstanceProperties props = cpu_slot->props;
1077
79e07936 1078 props.node_id = mc->get_default_cpu_node_id(machine, i);
d41f3e75 1079 if (!default_mapping) {
60bed6a3
IM
1080 /* record slots with not set mapping,
1081 * TODO: make it hard error in future */
1082 char *cpu_str = cpu_slot_to_string(cpu_slot);
1083 g_string_append_printf(s, "%sCPU %d [%s]",
1084 s->len ? ", " : "", i, cpu_str);
1085 g_free(cpu_str);
d41f3e75
IM
1086
1087 /* non mapped cpus used to fallback to node 0 */
1088 props.node_id = 0;
60bed6a3 1089 }
d41f3e75
IM
1090
1091 props.has_node_id = true;
1092 machine_set_cpu_numa_node(machine, &props, &error_fatal);
ec78f811
IM
1093 }
1094 }
244b3f44
TX
1095
1096 if (machine->numa_state->hmat_enabled) {
1097 numa_validate_initiator(machine->numa_state);
1098 }
1099
c6ff347c 1100 if (s->len && !qtest_enabled()) {
3dc6f869
AF
1101 warn_report("CPU(s) not present in any NUMA nodes: %s",
1102 s->str);
1103 warn_report("All CPU(s) up to maxcpus should be described "
1104 "in NUMA config, ability to start up with partial NUMA "
1105 "mappings is obsoleted and will be removed in future");
ec78f811
IM
1106 }
1107 g_string_free(s, true);
1108}
1109
82b911aa
IM
1110MemoryRegion *machine_consume_memdev(MachineState *machine,
1111 HostMemoryBackend *backend)
1112{
1113 MemoryRegion *ret = host_memory_backend_get_memory(backend);
1114
eef3a7ab 1115 if (host_memory_backend_is_mapped(backend)) {
7a309cc9
MA
1116 error_report("memory backend %s can't be used multiple times.",
1117 object_get_canonical_path_component(OBJECT(backend)));
82b911aa
IM
1118 exit(EXIT_FAILURE);
1119 }
1120 host_memory_backend_set_mapped(backend, true);
1121 vmstate_register_ram_global(ret);
1122 return ret;
1123}
1124
482dfe9a
IM
1125void machine_run_board_init(MachineState *machine)
1126{
1127 MachineClass *machine_class = MACHINE_GET_CLASS(machine);
61ad65d0
RH
1128 ObjectClass *oc = object_class_by_name(machine->cpu_type);
1129 CPUClass *cc;
ec78f811 1130
a3ef9bfb
PB
1131 /* This checkpoint is required by replay to separate prior clock
1132 reading from the other reads, because timer polling functions query
1133 clock values from the log. */
1134 replay_checkpoint(CHECKPOINT_INIT);
1135
82b911aa
IM
1136 if (machine->ram_memdev_id) {
1137 Object *o;
1138 o = object_resolve_path_type(machine->ram_memdev_id,
1139 TYPE_MEMORY_BACKEND, NULL);
1140 machine->ram = machine_consume_memdev(machine, MEMORY_BACKEND(o));
1141 }
1142
fcd3f2cc 1143 if (machine->numa_state) {
aa570207
TX
1144 numa_complete_configuration(machine);
1145 if (machine->numa_state->num_nodes) {
1146 machine_numa_finish_cpu_init(machine);
1147 }
3aeaac8f 1148 }
c9cf636d
AF
1149
1150 /* If the machine supports the valid_cpu_types check and the user
1151 * specified a CPU with -cpu check here that the user CPU is supported.
1152 */
1153 if (machine_class->valid_cpu_types && machine->cpu_type) {
c9cf636d
AF
1154 int i;
1155
1156 for (i = 0; machine_class->valid_cpu_types[i]; i++) {
61ad65d0 1157 if (object_class_dynamic_cast(oc,
c9cf636d
AF
1158 machine_class->valid_cpu_types[i])) {
1159 /* The user specificed CPU is in the valid field, we are
1160 * good to go.
1161 */
1162 break;
1163 }
1164 }
1165
1166 if (!machine_class->valid_cpu_types[i]) {
1167 /* The user specified CPU is not valid */
1168 error_report("Invalid CPU type: %s", machine->cpu_type);
1169 error_printf("The valid types are: %s",
1170 machine_class->valid_cpu_types[0]);
1171 for (i = 1; machine_class->valid_cpu_types[i]; i++) {
1172 error_printf(", %s", machine_class->valid_cpu_types[i]);
1173 }
1174 error_printf("\n");
1175
1176 exit(1);
1177 }
1178 }
1179
61ad65d0
RH
1180 /* Check if CPU type is deprecated and warn if so */
1181 cc = CPU_CLASS(oc);
1182 if (cc && cc->deprecation_note) {
1183 warn_report("CPU model %s is deprecated -- %s", machine->cpu_type,
1184 cc->deprecation_note);
1185 }
1186
e0292d7c 1187 if (machine->cgs) {
6e6a6ca7 1188 /*
e0292d7c 1189 * With confidential guests, the host can't see the real
6e6a6ca7
DG
1190 * contents of RAM, so there's no point in it trying to merge
1191 * areas.
1192 */
1193 machine_set_mem_merge(OBJECT(machine), false, &error_abort);
9f88a7a3
DG
1194
1195 /*
1196 * Virtio devices can't count on directly accessing guest
1197 * memory, so they need iommu_platform=on to use normal DMA
1198 * mechanisms. That requires also disabling legacy virtio
1199 * support for those virtio pci devices which allow it.
1200 */
1201 object_register_sugar_prop(TYPE_VIRTIO_PCI, "disable-legacy",
1202 "on", true);
1203 object_register_sugar_prop(TYPE_VIRTIO_DEVICE, "iommu_platform",
1204 "on", false);
6e6a6ca7
DG
1205 }
1206
92242f34 1207 accel_init_interfaces(ACCEL_GET_CLASS(machine->accelerator));
482dfe9a 1208 machine_class->init(machine);
2f181fbd 1209 phase_advance(PHASE_MACHINE_INITIALIZED);
482dfe9a
IM
1210}
1211
6b21670c
PB
1212static NotifierList machine_init_done_notifiers =
1213 NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);
1214
6b21670c
PB
1215void qemu_add_machine_init_done_notifier(Notifier *notify)
1216{
1217 notifier_list_add(&machine_init_done_notifiers, notify);
2f181fbd 1218 if (phase_check(PHASE_MACHINE_READY)) {
6b21670c
PB
1219 notify->notify(notify, NULL);
1220 }
1221}
1222
1223void qemu_remove_machine_init_done_notifier(Notifier *notify)
1224{
1225 notifier_remove(notify);
1226}
1227
f66dc873 1228void qdev_machine_creation_done(void)
6b21670c 1229{
f66dc873
PB
1230 cpu_synchronize_all_post_init();
1231
1232 if (current_machine->boot_once) {
1233 qemu_boot_set(current_machine->boot_once, &error_fatal);
1234 qemu_register_reset(restore_boot_order, g_strdup(current_machine->boot_order));
1235 }
1236
1237 /*
1238 * ok, initial machine setup is done, starting from now we can
1239 * only create hotpluggable devices
1240 */
2f181fbd 1241 phase_advance(PHASE_MACHINE_READY);
f66dc873
PB
1242 qdev_assert_realized_properly();
1243
1244 /* TODO: once all bus devices are qdevified, this should be done
1245 * when bus is created by qdev.c */
1246 /*
1247 * TODO: If we had a main 'reset container' that the whole system
1248 * lived in, we could reset that using the multi-phase reset
1249 * APIs. For the moment, we just reset the sysbus, which will cause
1250 * all devices hanging off it (and all their child buses, recursively)
1251 * to be reset. Note that this will *not* reset any Device objects
1252 * which are not attached to some part of the qbus tree!
1253 */
1254 qemu_register_reset(resettable_cold_reset_fn, sysbus_get_default());
1255
6b21670c 1256 notifier_list_notify(&machine_init_done_notifiers, NULL);
f66dc873
PB
1257
1258 if (rom_check_and_register_reset() != 0) {
f66dc873
PB
1259 exit(1);
1260 }
1261
1262 replay_start();
1263
1264 /* This checkpoint is required by replay to separate prior clock
1265 reading from the other reads, because timer polling functions query
1266 clock values from the log. */
1267 replay_checkpoint(CHECKPOINT_RESET);
1268 qemu_system_reset(SHUTDOWN_CAUSE_NONE);
1269 register_global_state();
6b21670c
PB
1270}
1271
36d20cb2
MA
1272static const TypeInfo machine_info = {
1273 .name = TYPE_MACHINE,
1274 .parent = TYPE_OBJECT,
1275 .abstract = true,
1276 .class_size = sizeof(MachineClass),
076b35b5 1277 .class_init = machine_class_init,
dcb3d601 1278 .class_base_init = machine_class_base_init,
36d20cb2 1279 .instance_size = sizeof(MachineState),
6b1b1440
MA
1280 .instance_init = machine_initfn,
1281 .instance_finalize = machine_finalize,
36d20cb2
MA
1282};
1283
1284static void machine_register_types(void)
1285{
1286 type_register_static(&machine_info);
1287}
1288
1289type_init(machine_register_types)