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