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