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