cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

machine.c (47699B)


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