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