136d20cb2SMarcel Apfelbaum /* 236d20cb2SMarcel Apfelbaum * QEMU Machine 336d20cb2SMarcel Apfelbaum * 436d20cb2SMarcel Apfelbaum * Copyright (C) 2014 Red Hat Inc 536d20cb2SMarcel Apfelbaum * 636d20cb2SMarcel Apfelbaum * Authors: 736d20cb2SMarcel Apfelbaum * Marcel Apfelbaum <marcel.a@redhat.com> 836d20cb2SMarcel Apfelbaum * 936d20cb2SMarcel Apfelbaum * This work is licensed under the terms of the GNU GPL, version 2 or later. 1036d20cb2SMarcel Apfelbaum * See the COPYING file in the top-level directory. 1136d20cb2SMarcel Apfelbaum */ 1236d20cb2SMarcel Apfelbaum 1318c86e2bSPeter Maydell #include "qemu/osdep.h" 14fc6b3cf9SPhilippe Mathieu-Daudé #include "qemu/units.h" 1536d20cb2SMarcel Apfelbaum #include "hw/boards.h" 16da34e65cSMarkus Armbruster #include "qapi/error.h" 179af23989SMarkus Armbruster #include "qapi/qapi-visit-common.h" 186b1b1440SMarcel Apfelbaum #include "qapi/visitor.h" 1933cd52b5SAlexander Graf #include "hw/sysbus.h" 2033cd52b5SAlexander Graf #include "sysemu/sysemu.h" 213bfe5716SLaurent Vivier #include "sysemu/numa.h" 2233cd52b5SAlexander Graf #include "qemu/error-report.h" 23c6ff347cSIgor Mammedov #include "sysemu/qtest.h" 24edc24ccdSMarc-André Lureau #include "hw/pci/pci.h" 256b1b1440SMarcel Apfelbaum 26abd93cc7SMarc-André Lureau GlobalProperty hw_compat_3_1[] = { 27abd93cc7SMarc-André Lureau { 28abd93cc7SMarc-André Lureau .driver = "pcie-root-port", 29abd93cc7SMarc-André Lureau .property = "x-speed", 30abd93cc7SMarc-André Lureau .value = "2_5", 31abd93cc7SMarc-André Lureau },{ 32abd93cc7SMarc-André Lureau .driver = "pcie-root-port", 33abd93cc7SMarc-André Lureau .property = "x-width", 34abd93cc7SMarc-André Lureau .value = "1", 35abd93cc7SMarc-André Lureau }, 36abd93cc7SMarc-André Lureau }; 37abd93cc7SMarc-André Lureau const size_t hw_compat_3_1_len = G_N_ELEMENTS(hw_compat_3_1); 38abd93cc7SMarc-André Lureau 39ddb3235dSMarc-André Lureau GlobalProperty hw_compat_3_0[] = {}; 40ddb3235dSMarc-André Lureau const size_t hw_compat_3_0_len = G_N_ELEMENTS(hw_compat_3_0); 41ddb3235dSMarc-André Lureau 420d47310bSMarc-André Lureau GlobalProperty hw_compat_2_12[] = { 430d47310bSMarc-André Lureau { 440d47310bSMarc-André Lureau .driver = "migration", 450d47310bSMarc-André Lureau .property = "decompress-error-check", 460d47310bSMarc-André Lureau .value = "off", 470d47310bSMarc-André Lureau },{ 480d47310bSMarc-André Lureau .driver = "hda-audio", 490d47310bSMarc-André Lureau .property = "use-timer", 500d47310bSMarc-André Lureau .value = "false", 510d47310bSMarc-André Lureau },{ 520d47310bSMarc-André Lureau .driver = "cirrus-vga", 530d47310bSMarc-André Lureau .property = "global-vmstate", 540d47310bSMarc-André Lureau .value = "true", 550d47310bSMarc-André Lureau },{ 560d47310bSMarc-André Lureau .driver = "VGA", 570d47310bSMarc-André Lureau .property = "global-vmstate", 580d47310bSMarc-André Lureau .value = "true", 590d47310bSMarc-André Lureau },{ 600d47310bSMarc-André Lureau .driver = "vmware-svga", 610d47310bSMarc-André Lureau .property = "global-vmstate", 620d47310bSMarc-André Lureau .value = "true", 630d47310bSMarc-André Lureau },{ 640d47310bSMarc-André Lureau .driver = "qxl-vga", 650d47310bSMarc-André Lureau .property = "global-vmstate", 660d47310bSMarc-André Lureau .value = "true", 670d47310bSMarc-André Lureau }, 680d47310bSMarc-André Lureau }; 690d47310bSMarc-André Lureau const size_t hw_compat_2_12_len = G_N_ELEMENTS(hw_compat_2_12); 700d47310bSMarc-André Lureau 7143df70a9SMarc-André Lureau GlobalProperty hw_compat_2_11[] = { 7243df70a9SMarc-André Lureau { 7343df70a9SMarc-André Lureau .driver = "hpet", 7443df70a9SMarc-André Lureau .property = "hpet-offset-saved", 7543df70a9SMarc-André Lureau .value = "false", 7643df70a9SMarc-André Lureau },{ 7743df70a9SMarc-André Lureau .driver = "virtio-blk-pci", 7843df70a9SMarc-André Lureau .property = "vectors", 7943df70a9SMarc-André Lureau .value = "2", 8043df70a9SMarc-André Lureau },{ 8143df70a9SMarc-André Lureau .driver = "vhost-user-blk-pci", 8243df70a9SMarc-André Lureau .property = "vectors", 8343df70a9SMarc-André Lureau .value = "2", 8443df70a9SMarc-André Lureau },{ 8543df70a9SMarc-André Lureau .driver = "e1000", 8643df70a9SMarc-André Lureau .property = "migrate_tso_props", 8743df70a9SMarc-André Lureau .value = "off", 8843df70a9SMarc-André Lureau }, 8943df70a9SMarc-André Lureau }; 9043df70a9SMarc-André Lureau const size_t hw_compat_2_11_len = G_N_ELEMENTS(hw_compat_2_11); 9143df70a9SMarc-André Lureau 92503224f4SMarc-André Lureau GlobalProperty hw_compat_2_10[] = { 93503224f4SMarc-André Lureau { 94503224f4SMarc-André Lureau .driver = "virtio-mouse-device", 95503224f4SMarc-André Lureau .property = "wheel-axis", 96503224f4SMarc-André Lureau .value = "false", 97503224f4SMarc-André Lureau },{ 98503224f4SMarc-André Lureau .driver = "virtio-tablet-device", 99503224f4SMarc-André Lureau .property = "wheel-axis", 100503224f4SMarc-André Lureau .value = "false", 101503224f4SMarc-André Lureau }, 102503224f4SMarc-André Lureau }; 103503224f4SMarc-André Lureau const size_t hw_compat_2_10_len = G_N_ELEMENTS(hw_compat_2_10); 104503224f4SMarc-André Lureau 1053e803152SMarc-André Lureau GlobalProperty hw_compat_2_9[] = { 1063e803152SMarc-André Lureau { 1073e803152SMarc-André Lureau .driver = "pci-bridge", 1083e803152SMarc-André Lureau .property = "shpc", 1093e803152SMarc-André Lureau .value = "off", 1103e803152SMarc-André Lureau },{ 1113e803152SMarc-André Lureau .driver = "intel-iommu", 1123e803152SMarc-André Lureau .property = "pt", 1133e803152SMarc-André Lureau .value = "off", 1143e803152SMarc-André Lureau },{ 1153e803152SMarc-André Lureau .driver = "virtio-net-device", 1163e803152SMarc-André Lureau .property = "x-mtu-bypass-backend", 1173e803152SMarc-André Lureau .value = "off", 1183e803152SMarc-André Lureau },{ 1193e803152SMarc-André Lureau .driver = "pcie-root-port", 1203e803152SMarc-André Lureau .property = "x-migrate-msix", 1213e803152SMarc-André Lureau .value = "false", 1223e803152SMarc-André Lureau }, 1233e803152SMarc-André Lureau }; 1243e803152SMarc-André Lureau const size_t hw_compat_2_9_len = G_N_ELEMENTS(hw_compat_2_9); 1253e803152SMarc-André Lureau 126edc24ccdSMarc-André Lureau GlobalProperty hw_compat_2_8[] = { 127edc24ccdSMarc-André Lureau { 128edc24ccdSMarc-André Lureau .driver = "fw_cfg_mem", 129edc24ccdSMarc-André Lureau .property = "x-file-slots", 130edc24ccdSMarc-André Lureau .value = stringify(0x10), 131edc24ccdSMarc-André Lureau },{ 132edc24ccdSMarc-André Lureau .driver = "fw_cfg_io", 133edc24ccdSMarc-André Lureau .property = "x-file-slots", 134edc24ccdSMarc-André Lureau .value = stringify(0x10), 135edc24ccdSMarc-André Lureau },{ 136edc24ccdSMarc-André Lureau .driver = "pflash_cfi01", 137edc24ccdSMarc-André Lureau .property = "old-multiple-chip-handling", 138edc24ccdSMarc-André Lureau .value = "on", 139edc24ccdSMarc-André Lureau },{ 140edc24ccdSMarc-André Lureau .driver = "pci-bridge", 141edc24ccdSMarc-André Lureau .property = "shpc", 142edc24ccdSMarc-André Lureau .value = "on", 143edc24ccdSMarc-André Lureau },{ 144edc24ccdSMarc-André Lureau .driver = TYPE_PCI_DEVICE, 145edc24ccdSMarc-André Lureau .property = "x-pcie-extcap-init", 146edc24ccdSMarc-André Lureau .value = "off", 147edc24ccdSMarc-André Lureau },{ 148edc24ccdSMarc-André Lureau .driver = "virtio-pci", 149edc24ccdSMarc-André Lureau .property = "x-pcie-deverr-init", 150edc24ccdSMarc-André Lureau .value = "off", 151edc24ccdSMarc-André Lureau },{ 152edc24ccdSMarc-André Lureau .driver = "virtio-pci", 153edc24ccdSMarc-André Lureau .property = "x-pcie-lnkctl-init", 154edc24ccdSMarc-André Lureau .value = "off", 155edc24ccdSMarc-André Lureau },{ 156edc24ccdSMarc-André Lureau .driver = "virtio-pci", 157edc24ccdSMarc-André Lureau .property = "x-pcie-pm-init", 158edc24ccdSMarc-André Lureau .value = "off", 159edc24ccdSMarc-André Lureau },{ 160edc24ccdSMarc-André Lureau .driver = "cirrus-vga", 161edc24ccdSMarc-André Lureau .property = "vgamem_mb", 162edc24ccdSMarc-André Lureau .value = "8", 163edc24ccdSMarc-André Lureau },{ 164edc24ccdSMarc-André Lureau .driver = "isa-cirrus-vga", 165edc24ccdSMarc-André Lureau .property = "vgamem_mb", 166edc24ccdSMarc-André Lureau .value = "8", 167edc24ccdSMarc-André Lureau }, 168edc24ccdSMarc-André Lureau }; 169edc24ccdSMarc-André Lureau const size_t hw_compat_2_8_len = G_N_ELEMENTS(hw_compat_2_8); 170edc24ccdSMarc-André Lureau 1715a995064SMarc-André Lureau GlobalProperty hw_compat_2_7[] = { 1725a995064SMarc-André Lureau { 1735a995064SMarc-André Lureau .driver = "virtio-pci", 1745a995064SMarc-André Lureau .property = "page-per-vq", 1755a995064SMarc-André Lureau .value = "on", 1765a995064SMarc-André Lureau },{ 1775a995064SMarc-André Lureau .driver = "virtio-serial-device", 1785a995064SMarc-André Lureau .property = "emergency-write", 1795a995064SMarc-André Lureau .value = "off", 1805a995064SMarc-André Lureau },{ 1815a995064SMarc-André Lureau .driver = "ioapic", 1825a995064SMarc-André Lureau .property = "version", 1835a995064SMarc-André Lureau .value = "0x11", 1845a995064SMarc-André Lureau },{ 1855a995064SMarc-André Lureau .driver = "intel-iommu", 1865a995064SMarc-André Lureau .property = "x-buggy-eim", 1875a995064SMarc-André Lureau .value = "true", 1885a995064SMarc-André Lureau },{ 1895a995064SMarc-André Lureau .driver = "virtio-pci", 1905a995064SMarc-André Lureau .property = "x-ignore-backend-features", 1915a995064SMarc-André Lureau .value = "on", 1925a995064SMarc-André Lureau }, 1935a995064SMarc-André Lureau }; 1945a995064SMarc-André Lureau const size_t hw_compat_2_7_len = G_N_ELEMENTS(hw_compat_2_7); 1955a995064SMarc-André Lureau 196ff8f261fSMarc-André Lureau GlobalProperty hw_compat_2_6[] = { 197ff8f261fSMarc-André Lureau { 198ff8f261fSMarc-André Lureau .driver = "virtio-mmio", 199ff8f261fSMarc-André Lureau .property = "format_transport_address", 200ff8f261fSMarc-André Lureau .value = "off", 201ff8f261fSMarc-André Lureau },{ 202ff8f261fSMarc-André Lureau .driver = "virtio-pci", 203ff8f261fSMarc-André Lureau .property = "disable-modern", 204ff8f261fSMarc-André Lureau .value = "on", 205ff8f261fSMarc-André Lureau },{ 206ff8f261fSMarc-André Lureau .driver = "virtio-pci", 207ff8f261fSMarc-André Lureau .property = "disable-legacy", 208ff8f261fSMarc-André Lureau .value = "off", 209ff8f261fSMarc-André Lureau }, 210ff8f261fSMarc-André Lureau }; 211ff8f261fSMarc-André Lureau const size_t hw_compat_2_6_len = G_N_ELEMENTS(hw_compat_2_6); 212ff8f261fSMarc-André Lureau 213fe759610SMarc-André Lureau GlobalProperty hw_compat_2_5[] = { 214fe759610SMarc-André Lureau { 215fe759610SMarc-André Lureau .driver = "isa-fdc", 216fe759610SMarc-André Lureau .property = "fallback", 217fe759610SMarc-André Lureau .value = "144", 218fe759610SMarc-André Lureau },{ 219fe759610SMarc-André Lureau .driver = "pvscsi", 220fe759610SMarc-André Lureau .property = "x-old-pci-configuration", 221fe759610SMarc-André Lureau .value = "on", 222fe759610SMarc-André Lureau },{ 223fe759610SMarc-André Lureau .driver = "pvscsi", 224fe759610SMarc-André Lureau .property = "x-disable-pcie", 225fe759610SMarc-André Lureau .value = "on", 226fe759610SMarc-André Lureau }, 227fe759610SMarc-André Lureau { 228fe759610SMarc-André Lureau .driver = "vmxnet3", 229fe759610SMarc-André Lureau .property = "x-old-msi-offsets", 230fe759610SMarc-André Lureau .value = "on", 231fe759610SMarc-André Lureau },{ 232fe759610SMarc-André Lureau .driver = "vmxnet3", 233fe759610SMarc-André Lureau .property = "x-disable-pcie", 234fe759610SMarc-André Lureau .value = "on", 235fe759610SMarc-André Lureau }, 236fe759610SMarc-André Lureau }; 237fe759610SMarc-André Lureau const size_t hw_compat_2_5_len = G_N_ELEMENTS(hw_compat_2_5); 238fe759610SMarc-André Lureau 2392f99b9c2SMarc-André Lureau GlobalProperty hw_compat_2_4[] = { 2402f99b9c2SMarc-André Lureau { 2412f99b9c2SMarc-André Lureau .driver = "virtio-blk-device", 2422f99b9c2SMarc-André Lureau .property = "scsi", 2432f99b9c2SMarc-André Lureau .value = "true", 2442f99b9c2SMarc-André Lureau },{ 2452f99b9c2SMarc-André Lureau .driver = "e1000", 2462f99b9c2SMarc-André Lureau .property = "extra_mac_registers", 2472f99b9c2SMarc-André Lureau .value = "off", 2482f99b9c2SMarc-André Lureau },{ 2492f99b9c2SMarc-André Lureau .driver = "virtio-pci", 2502f99b9c2SMarc-André Lureau .property = "x-disable-pcie", 2512f99b9c2SMarc-André Lureau .value = "on", 2522f99b9c2SMarc-André Lureau },{ 2532f99b9c2SMarc-André Lureau .driver = "virtio-pci", 2542f99b9c2SMarc-André Lureau .property = "migrate-extra", 2552f99b9c2SMarc-André Lureau .value = "off", 2562f99b9c2SMarc-André Lureau },{ 2572f99b9c2SMarc-André Lureau .driver = "fw_cfg_mem", 2582f99b9c2SMarc-André Lureau .property = "dma_enabled", 2592f99b9c2SMarc-André Lureau .value = "off", 2602f99b9c2SMarc-André Lureau },{ 2612f99b9c2SMarc-André Lureau .driver = "fw_cfg_io", 2622f99b9c2SMarc-André Lureau .property = "dma_enabled", 2632f99b9c2SMarc-André Lureau .value = "off", 2642f99b9c2SMarc-André Lureau } 2652f99b9c2SMarc-André Lureau }; 2662f99b9c2SMarc-André Lureau const size_t hw_compat_2_4_len = G_N_ELEMENTS(hw_compat_2_4); 2672f99b9c2SMarc-André Lureau 2688995dd90SMarc-André Lureau GlobalProperty hw_compat_2_3[] = { 2698995dd90SMarc-André Lureau { 2708995dd90SMarc-André Lureau .driver = "virtio-blk-pci", 2718995dd90SMarc-André Lureau .property = "any_layout", 2728995dd90SMarc-André Lureau .value = "off", 2738995dd90SMarc-André Lureau },{ 2748995dd90SMarc-André Lureau .driver = "virtio-balloon-pci", 2758995dd90SMarc-André Lureau .property = "any_layout", 2768995dd90SMarc-André Lureau .value = "off", 2778995dd90SMarc-André Lureau },{ 2788995dd90SMarc-André Lureau .driver = "virtio-serial-pci", 2798995dd90SMarc-André Lureau .property = "any_layout", 2808995dd90SMarc-André Lureau .value = "off", 2818995dd90SMarc-André Lureau },{ 2828995dd90SMarc-André Lureau .driver = "virtio-9p-pci", 2838995dd90SMarc-André Lureau .property = "any_layout", 2848995dd90SMarc-André Lureau .value = "off", 2858995dd90SMarc-André Lureau },{ 2868995dd90SMarc-André Lureau .driver = "virtio-rng-pci", 2878995dd90SMarc-André Lureau .property = "any_layout", 2888995dd90SMarc-André Lureau .value = "off", 2898995dd90SMarc-André Lureau },{ 2908995dd90SMarc-André Lureau .driver = TYPE_PCI_DEVICE, 2918995dd90SMarc-André Lureau .property = "x-pcie-lnksta-dllla", 2928995dd90SMarc-André Lureau .value = "off", 2938995dd90SMarc-André Lureau },{ 2948995dd90SMarc-André Lureau .driver = "migration", 2958995dd90SMarc-André Lureau .property = "send-configuration", 2968995dd90SMarc-André Lureau .value = "off", 2978995dd90SMarc-André Lureau },{ 2988995dd90SMarc-André Lureau .driver = "migration", 2998995dd90SMarc-André Lureau .property = "send-section-footer", 3008995dd90SMarc-André Lureau .value = "off", 3018995dd90SMarc-André Lureau },{ 3028995dd90SMarc-André Lureau .driver = "migration", 3038995dd90SMarc-André Lureau .property = "store-global-state", 3048995dd90SMarc-André Lureau .value = "off", 3058995dd90SMarc-André Lureau }, 3068995dd90SMarc-André Lureau }; 3078995dd90SMarc-André Lureau const size_t hw_compat_2_3_len = G_N_ELEMENTS(hw_compat_2_3); 3088995dd90SMarc-André Lureau 309*1c30044eSMarc-André Lureau GlobalProperty hw_compat_2_2[] = {}; 310*1c30044eSMarc-André Lureau const size_t hw_compat_2_2_len = G_N_ELEMENTS(hw_compat_2_2); 311*1c30044eSMarc-André Lureau 3126b1b1440SMarcel Apfelbaum static char *machine_get_accel(Object *obj, Error **errp) 3136b1b1440SMarcel Apfelbaum { 3146b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 3156b1b1440SMarcel Apfelbaum 3166b1b1440SMarcel Apfelbaum return g_strdup(ms->accel); 3176b1b1440SMarcel Apfelbaum } 3186b1b1440SMarcel Apfelbaum 3196b1b1440SMarcel Apfelbaum static void machine_set_accel(Object *obj, const char *value, Error **errp) 3206b1b1440SMarcel Apfelbaum { 3216b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 3226b1b1440SMarcel Apfelbaum 323556068eeSEduardo Habkost g_free(ms->accel); 3246b1b1440SMarcel Apfelbaum ms->accel = g_strdup(value); 3256b1b1440SMarcel Apfelbaum } 3266b1b1440SMarcel Apfelbaum 32732c18a2dSMatt Gingell static void machine_set_kernel_irqchip(Object *obj, Visitor *v, 328d7bce999SEric Blake const char *name, void *opaque, 32932c18a2dSMatt Gingell Error **errp) 3306b1b1440SMarcel Apfelbaum { 33132c18a2dSMatt Gingell Error *err = NULL; 3326b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 33332c18a2dSMatt Gingell OnOffSplit mode; 3346b1b1440SMarcel Apfelbaum 33551e72bc1SEric Blake visit_type_OnOffSplit(v, name, &mode, &err); 33632c18a2dSMatt Gingell if (err) { 33732c18a2dSMatt Gingell error_propagate(errp, err); 33832c18a2dSMatt Gingell return; 33932c18a2dSMatt Gingell } else { 34032c18a2dSMatt Gingell switch (mode) { 34132c18a2dSMatt Gingell case ON_OFF_SPLIT_ON: 34232c18a2dSMatt Gingell ms->kernel_irqchip_allowed = true; 34332c18a2dSMatt Gingell ms->kernel_irqchip_required = true; 34432c18a2dSMatt Gingell ms->kernel_irqchip_split = false; 34532c18a2dSMatt Gingell break; 34632c18a2dSMatt Gingell case ON_OFF_SPLIT_OFF: 34732c18a2dSMatt Gingell ms->kernel_irqchip_allowed = false; 34832c18a2dSMatt Gingell ms->kernel_irqchip_required = false; 34932c18a2dSMatt Gingell ms->kernel_irqchip_split = false; 35032c18a2dSMatt Gingell break; 35132c18a2dSMatt Gingell case ON_OFF_SPLIT_SPLIT: 35232c18a2dSMatt Gingell ms->kernel_irqchip_allowed = true; 35332c18a2dSMatt Gingell ms->kernel_irqchip_required = true; 35432c18a2dSMatt Gingell ms->kernel_irqchip_split = true; 35532c18a2dSMatt Gingell break; 35632c18a2dSMatt Gingell default: 35778a39306SGreg Kurz /* The value was checked in visit_type_OnOffSplit() above. If 35878a39306SGreg Kurz * we get here, then something is wrong in QEMU. 35978a39306SGreg Kurz */ 36032c18a2dSMatt Gingell abort(); 36132c18a2dSMatt Gingell } 36232c18a2dSMatt Gingell } 3636b1b1440SMarcel Apfelbaum } 3646b1b1440SMarcel Apfelbaum 3656b1b1440SMarcel Apfelbaum static void machine_get_kvm_shadow_mem(Object *obj, Visitor *v, 366d7bce999SEric Blake const char *name, void *opaque, 3676b1b1440SMarcel Apfelbaum Error **errp) 3686b1b1440SMarcel Apfelbaum { 3696b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 3706b1b1440SMarcel Apfelbaum int64_t value = ms->kvm_shadow_mem; 3716b1b1440SMarcel Apfelbaum 37251e72bc1SEric Blake visit_type_int(v, name, &value, errp); 3736b1b1440SMarcel Apfelbaum } 3746b1b1440SMarcel Apfelbaum 3756b1b1440SMarcel Apfelbaum static void machine_set_kvm_shadow_mem(Object *obj, Visitor *v, 376d7bce999SEric Blake const char *name, void *opaque, 3776b1b1440SMarcel Apfelbaum Error **errp) 3786b1b1440SMarcel Apfelbaum { 3796b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 3806b1b1440SMarcel Apfelbaum Error *error = NULL; 3816b1b1440SMarcel Apfelbaum int64_t value; 3826b1b1440SMarcel Apfelbaum 38351e72bc1SEric Blake visit_type_int(v, name, &value, &error); 3846b1b1440SMarcel Apfelbaum if (error) { 3856b1b1440SMarcel Apfelbaum error_propagate(errp, error); 3866b1b1440SMarcel Apfelbaum return; 3876b1b1440SMarcel Apfelbaum } 3886b1b1440SMarcel Apfelbaum 3896b1b1440SMarcel Apfelbaum ms->kvm_shadow_mem = value; 3906b1b1440SMarcel Apfelbaum } 3916b1b1440SMarcel Apfelbaum 3926b1b1440SMarcel Apfelbaum static char *machine_get_kernel(Object *obj, Error **errp) 3936b1b1440SMarcel Apfelbaum { 3946b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 3956b1b1440SMarcel Apfelbaum 3966b1b1440SMarcel Apfelbaum return g_strdup(ms->kernel_filename); 3976b1b1440SMarcel Apfelbaum } 3986b1b1440SMarcel Apfelbaum 3996b1b1440SMarcel Apfelbaum static void machine_set_kernel(Object *obj, const char *value, Error **errp) 4006b1b1440SMarcel Apfelbaum { 4016b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 4026b1b1440SMarcel Apfelbaum 403556068eeSEduardo Habkost g_free(ms->kernel_filename); 4046b1b1440SMarcel Apfelbaum ms->kernel_filename = g_strdup(value); 4056b1b1440SMarcel Apfelbaum } 4066b1b1440SMarcel Apfelbaum 4076b1b1440SMarcel Apfelbaum static char *machine_get_initrd(Object *obj, Error **errp) 4086b1b1440SMarcel Apfelbaum { 4096b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 4106b1b1440SMarcel Apfelbaum 4116b1b1440SMarcel Apfelbaum return g_strdup(ms->initrd_filename); 4126b1b1440SMarcel Apfelbaum } 4136b1b1440SMarcel Apfelbaum 4146b1b1440SMarcel Apfelbaum static void machine_set_initrd(Object *obj, const char *value, Error **errp) 4156b1b1440SMarcel Apfelbaum { 4166b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 4176b1b1440SMarcel Apfelbaum 418556068eeSEduardo Habkost g_free(ms->initrd_filename); 4196b1b1440SMarcel Apfelbaum ms->initrd_filename = g_strdup(value); 4206b1b1440SMarcel Apfelbaum } 4216b1b1440SMarcel Apfelbaum 4226b1b1440SMarcel Apfelbaum static char *machine_get_append(Object *obj, Error **errp) 4236b1b1440SMarcel Apfelbaum { 4246b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 4256b1b1440SMarcel Apfelbaum 4266b1b1440SMarcel Apfelbaum return g_strdup(ms->kernel_cmdline); 4276b1b1440SMarcel Apfelbaum } 4286b1b1440SMarcel Apfelbaum 4296b1b1440SMarcel Apfelbaum static void machine_set_append(Object *obj, const char *value, Error **errp) 4306b1b1440SMarcel Apfelbaum { 4316b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 4326b1b1440SMarcel Apfelbaum 433556068eeSEduardo Habkost g_free(ms->kernel_cmdline); 4346b1b1440SMarcel Apfelbaum ms->kernel_cmdline = g_strdup(value); 4356b1b1440SMarcel Apfelbaum } 4366b1b1440SMarcel Apfelbaum 4376b1b1440SMarcel Apfelbaum static char *machine_get_dtb(Object *obj, Error **errp) 4386b1b1440SMarcel Apfelbaum { 4396b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 4406b1b1440SMarcel Apfelbaum 4416b1b1440SMarcel Apfelbaum return g_strdup(ms->dtb); 4426b1b1440SMarcel Apfelbaum } 4436b1b1440SMarcel Apfelbaum 4446b1b1440SMarcel Apfelbaum static void machine_set_dtb(Object *obj, const char *value, Error **errp) 4456b1b1440SMarcel Apfelbaum { 4466b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 4476b1b1440SMarcel Apfelbaum 448556068eeSEduardo Habkost g_free(ms->dtb); 4496b1b1440SMarcel Apfelbaum ms->dtb = g_strdup(value); 4506b1b1440SMarcel Apfelbaum } 4516b1b1440SMarcel Apfelbaum 4526b1b1440SMarcel Apfelbaum static char *machine_get_dumpdtb(Object *obj, Error **errp) 4536b1b1440SMarcel Apfelbaum { 4546b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 4556b1b1440SMarcel Apfelbaum 4566b1b1440SMarcel Apfelbaum return g_strdup(ms->dumpdtb); 4576b1b1440SMarcel Apfelbaum } 4586b1b1440SMarcel Apfelbaum 4596b1b1440SMarcel Apfelbaum static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp) 4606b1b1440SMarcel Apfelbaum { 4616b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 4626b1b1440SMarcel Apfelbaum 463556068eeSEduardo Habkost g_free(ms->dumpdtb); 4646b1b1440SMarcel Apfelbaum ms->dumpdtb = g_strdup(value); 4656b1b1440SMarcel Apfelbaum } 4666b1b1440SMarcel Apfelbaum 4676b1b1440SMarcel Apfelbaum static void machine_get_phandle_start(Object *obj, Visitor *v, 468d7bce999SEric Blake const char *name, void *opaque, 4696b1b1440SMarcel Apfelbaum Error **errp) 4706b1b1440SMarcel Apfelbaum { 4716b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 4726b1b1440SMarcel Apfelbaum int64_t value = ms->phandle_start; 4736b1b1440SMarcel Apfelbaum 47451e72bc1SEric Blake visit_type_int(v, name, &value, errp); 4756b1b1440SMarcel Apfelbaum } 4766b1b1440SMarcel Apfelbaum 4776b1b1440SMarcel Apfelbaum static void machine_set_phandle_start(Object *obj, Visitor *v, 478d7bce999SEric Blake const char *name, void *opaque, 4796b1b1440SMarcel Apfelbaum Error **errp) 4806b1b1440SMarcel Apfelbaum { 4816b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 4826b1b1440SMarcel Apfelbaum Error *error = NULL; 4836b1b1440SMarcel Apfelbaum int64_t value; 4846b1b1440SMarcel Apfelbaum 48551e72bc1SEric Blake visit_type_int(v, name, &value, &error); 4866b1b1440SMarcel Apfelbaum if (error) { 4876b1b1440SMarcel Apfelbaum error_propagate(errp, error); 4886b1b1440SMarcel Apfelbaum return; 4896b1b1440SMarcel Apfelbaum } 4906b1b1440SMarcel Apfelbaum 4916b1b1440SMarcel Apfelbaum ms->phandle_start = value; 4926b1b1440SMarcel Apfelbaum } 4936b1b1440SMarcel Apfelbaum 4946b1b1440SMarcel Apfelbaum static char *machine_get_dt_compatible(Object *obj, Error **errp) 4956b1b1440SMarcel Apfelbaum { 4966b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 4976b1b1440SMarcel Apfelbaum 4986b1b1440SMarcel Apfelbaum return g_strdup(ms->dt_compatible); 4996b1b1440SMarcel Apfelbaum } 5006b1b1440SMarcel Apfelbaum 5016b1b1440SMarcel Apfelbaum static void machine_set_dt_compatible(Object *obj, const char *value, Error **errp) 5026b1b1440SMarcel Apfelbaum { 5036b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 5046b1b1440SMarcel Apfelbaum 505556068eeSEduardo Habkost g_free(ms->dt_compatible); 5066b1b1440SMarcel Apfelbaum ms->dt_compatible = g_strdup(value); 5076b1b1440SMarcel Apfelbaum } 5086b1b1440SMarcel Apfelbaum 5096b1b1440SMarcel Apfelbaum static bool machine_get_dump_guest_core(Object *obj, Error **errp) 5106b1b1440SMarcel Apfelbaum { 5116b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 5126b1b1440SMarcel Apfelbaum 5136b1b1440SMarcel Apfelbaum return ms->dump_guest_core; 5146b1b1440SMarcel Apfelbaum } 5156b1b1440SMarcel Apfelbaum 5166b1b1440SMarcel Apfelbaum static void machine_set_dump_guest_core(Object *obj, bool value, Error **errp) 5176b1b1440SMarcel Apfelbaum { 5186b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 5196b1b1440SMarcel Apfelbaum 5206b1b1440SMarcel Apfelbaum ms->dump_guest_core = value; 5216b1b1440SMarcel Apfelbaum } 5226b1b1440SMarcel Apfelbaum 5236b1b1440SMarcel Apfelbaum static bool machine_get_mem_merge(Object *obj, Error **errp) 5246b1b1440SMarcel Apfelbaum { 5256b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 5266b1b1440SMarcel Apfelbaum 5276b1b1440SMarcel Apfelbaum return ms->mem_merge; 5286b1b1440SMarcel Apfelbaum } 5296b1b1440SMarcel Apfelbaum 5306b1b1440SMarcel Apfelbaum static void machine_set_mem_merge(Object *obj, bool value, Error **errp) 5316b1b1440SMarcel Apfelbaum { 5326b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 5336b1b1440SMarcel Apfelbaum 5346b1b1440SMarcel Apfelbaum ms->mem_merge = value; 5356b1b1440SMarcel Apfelbaum } 5366b1b1440SMarcel Apfelbaum 5376b1b1440SMarcel Apfelbaum static bool machine_get_usb(Object *obj, Error **errp) 5386b1b1440SMarcel Apfelbaum { 5396b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 5406b1b1440SMarcel Apfelbaum 5416b1b1440SMarcel Apfelbaum return ms->usb; 5426b1b1440SMarcel Apfelbaum } 5436b1b1440SMarcel Apfelbaum 5446b1b1440SMarcel Apfelbaum static void machine_set_usb(Object *obj, bool value, Error **errp) 5456b1b1440SMarcel Apfelbaum { 5466b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 5476b1b1440SMarcel Apfelbaum 5486b1b1440SMarcel Apfelbaum ms->usb = value; 549c6e76503SPaolo Bonzini ms->usb_disabled = !value; 5506b1b1440SMarcel Apfelbaum } 5516b1b1440SMarcel Apfelbaum 552cfc58cf3SEduardo Habkost static bool machine_get_graphics(Object *obj, Error **errp) 553cfc58cf3SEduardo Habkost { 554cfc58cf3SEduardo Habkost MachineState *ms = MACHINE(obj); 555cfc58cf3SEduardo Habkost 556cfc58cf3SEduardo Habkost return ms->enable_graphics; 557cfc58cf3SEduardo Habkost } 558cfc58cf3SEduardo Habkost 559cfc58cf3SEduardo Habkost static void machine_set_graphics(Object *obj, bool value, Error **errp) 560cfc58cf3SEduardo Habkost { 561cfc58cf3SEduardo Habkost MachineState *ms = MACHINE(obj); 562cfc58cf3SEduardo Habkost 563cfc58cf3SEduardo Habkost ms->enable_graphics = value; 564cfc58cf3SEduardo Habkost } 565cfc58cf3SEduardo Habkost 56679814179STiejun Chen static bool machine_get_igd_gfx_passthru(Object *obj, Error **errp) 56779814179STiejun Chen { 56879814179STiejun Chen MachineState *ms = MACHINE(obj); 56979814179STiejun Chen 57079814179STiejun Chen return ms->igd_gfx_passthru; 57179814179STiejun Chen } 57279814179STiejun Chen 57379814179STiejun Chen static void machine_set_igd_gfx_passthru(Object *obj, bool value, Error **errp) 57479814179STiejun Chen { 57579814179STiejun Chen MachineState *ms = MACHINE(obj); 57679814179STiejun Chen 57779814179STiejun Chen ms->igd_gfx_passthru = value; 57879814179STiejun Chen } 57979814179STiejun Chen 5806b1b1440SMarcel Apfelbaum static char *machine_get_firmware(Object *obj, Error **errp) 5816b1b1440SMarcel Apfelbaum { 5826b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 5836b1b1440SMarcel Apfelbaum 5846b1b1440SMarcel Apfelbaum return g_strdup(ms->firmware); 5856b1b1440SMarcel Apfelbaum } 5866b1b1440SMarcel Apfelbaum 5876b1b1440SMarcel Apfelbaum static void machine_set_firmware(Object *obj, const char *value, Error **errp) 5886b1b1440SMarcel Apfelbaum { 5896b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 5906b1b1440SMarcel Apfelbaum 591556068eeSEduardo Habkost g_free(ms->firmware); 5926b1b1440SMarcel Apfelbaum ms->firmware = g_strdup(value); 5936b1b1440SMarcel Apfelbaum } 5946b1b1440SMarcel Apfelbaum 5959850c604SAlexander Graf static void machine_set_suppress_vmdesc(Object *obj, bool value, Error **errp) 5969850c604SAlexander Graf { 5979850c604SAlexander Graf MachineState *ms = MACHINE(obj); 5989850c604SAlexander Graf 5999850c604SAlexander Graf ms->suppress_vmdesc = value; 6009850c604SAlexander Graf } 6019850c604SAlexander Graf 6029850c604SAlexander Graf static bool machine_get_suppress_vmdesc(Object *obj, Error **errp) 6039850c604SAlexander Graf { 6049850c604SAlexander Graf MachineState *ms = MACHINE(obj); 6059850c604SAlexander Graf 6069850c604SAlexander Graf return ms->suppress_vmdesc; 6079850c604SAlexander Graf } 6089850c604SAlexander Graf 609902c053dSGreg Kurz static void machine_set_enforce_config_section(Object *obj, bool value, 610902c053dSGreg Kurz Error **errp) 611902c053dSGreg Kurz { 612902c053dSGreg Kurz MachineState *ms = MACHINE(obj); 613902c053dSGreg Kurz 61491c082adSThomas Huth warn_report("enforce-config-section is deprecated, please use " 61591c082adSThomas Huth "-global migration.send-configuration=on|off instead"); 61691c082adSThomas Huth 617902c053dSGreg Kurz ms->enforce_config_section = value; 618902c053dSGreg Kurz } 619902c053dSGreg Kurz 620902c053dSGreg Kurz static bool machine_get_enforce_config_section(Object *obj, Error **errp) 621902c053dSGreg Kurz { 622902c053dSGreg Kurz MachineState *ms = MACHINE(obj); 623902c053dSGreg Kurz 624902c053dSGreg Kurz return ms->enforce_config_section; 625902c053dSGreg Kurz } 626902c053dSGreg Kurz 627db588194SBrijesh Singh static char *machine_get_memory_encryption(Object *obj, Error **errp) 628db588194SBrijesh Singh { 629db588194SBrijesh Singh MachineState *ms = MACHINE(obj); 630db588194SBrijesh Singh 631db588194SBrijesh Singh return g_strdup(ms->memory_encryption); 632db588194SBrijesh Singh } 633db588194SBrijesh Singh 634db588194SBrijesh Singh static void machine_set_memory_encryption(Object *obj, const char *value, 635db588194SBrijesh Singh Error **errp) 636db588194SBrijesh Singh { 637db588194SBrijesh Singh MachineState *ms = MACHINE(obj); 638db588194SBrijesh Singh 639db588194SBrijesh Singh g_free(ms->memory_encryption); 640db588194SBrijesh Singh ms->memory_encryption = g_strdup(value); 641db588194SBrijesh Singh } 642db588194SBrijesh Singh 6430bd1909dSEduardo Habkost void machine_class_allow_dynamic_sysbus_dev(MachineClass *mc, const char *type) 64433cd52b5SAlexander Graf { 6450bd1909dSEduardo Habkost strList *item = g_new0(strList, 1); 6460bd1909dSEduardo Habkost 6470bd1909dSEduardo Habkost item->value = g_strdup(type); 6480bd1909dSEduardo Habkost item->next = mc->allowed_dynamic_sysbus_devices; 6490bd1909dSEduardo Habkost mc->allowed_dynamic_sysbus_devices = item; 6500bd1909dSEduardo Habkost } 6510bd1909dSEduardo Habkost 6520bd1909dSEduardo Habkost static void validate_sysbus_device(SysBusDevice *sbdev, void *opaque) 6530bd1909dSEduardo Habkost { 6540bd1909dSEduardo Habkost MachineState *machine = opaque; 6550bd1909dSEduardo Habkost MachineClass *mc = MACHINE_GET_CLASS(machine); 6560bd1909dSEduardo Habkost bool allowed = false; 6570bd1909dSEduardo Habkost strList *wl; 6580bd1909dSEduardo Habkost 6590bd1909dSEduardo Habkost for (wl = mc->allowed_dynamic_sysbus_devices; 6600bd1909dSEduardo Habkost !allowed && wl; 6610bd1909dSEduardo Habkost wl = wl->next) { 6620bd1909dSEduardo Habkost allowed |= !!object_dynamic_cast(OBJECT(sbdev), wl->value); 6630bd1909dSEduardo Habkost } 6640bd1909dSEduardo Habkost 6650bd1909dSEduardo Habkost if (!allowed) { 66633cd52b5SAlexander Graf error_report("Option '-device %s' cannot be handled by this machine", 66733cd52b5SAlexander Graf object_class_get_name(object_get_class(OBJECT(sbdev)))); 66833cd52b5SAlexander Graf exit(1); 66933cd52b5SAlexander Graf } 6700bd1909dSEduardo Habkost } 67133cd52b5SAlexander Graf 67233cd52b5SAlexander Graf static void machine_init_notify(Notifier *notifier, void *data) 67333cd52b5SAlexander Graf { 6740bd1909dSEduardo Habkost MachineState *machine = MACHINE(qdev_get_machine()); 67533cd52b5SAlexander Graf 67633cd52b5SAlexander Graf /* 6770bd1909dSEduardo Habkost * Loop through all dynamically created sysbus devices and check if they are 6780bd1909dSEduardo Habkost * all allowed. If a device is not allowed, error out. 67933cd52b5SAlexander Graf */ 6800bd1909dSEduardo Habkost foreach_dynamic_sysbus_device(validate_sysbus_device, machine); 68133cd52b5SAlexander Graf } 68233cd52b5SAlexander Graf 683f2d672c2SIgor Mammedov HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine) 684f2d672c2SIgor Mammedov { 685f2d672c2SIgor Mammedov int i; 686f2d672c2SIgor Mammedov HotpluggableCPUList *head = NULL; 687d342eb76SIgor Mammedov MachineClass *mc = MACHINE_GET_CLASS(machine); 688f2d672c2SIgor Mammedov 689d342eb76SIgor Mammedov /* force board to initialize possible_cpus if it hasn't been done yet */ 690d342eb76SIgor Mammedov mc->possible_cpu_arch_ids(machine); 691d342eb76SIgor Mammedov 692f2d672c2SIgor Mammedov for (i = 0; i < machine->possible_cpus->len; i++) { 693d342eb76SIgor Mammedov Object *cpu; 694f2d672c2SIgor Mammedov HotpluggableCPUList *list_item = g_new0(typeof(*list_item), 1); 695f2d672c2SIgor Mammedov HotpluggableCPU *cpu_item = g_new0(typeof(*cpu_item), 1); 696f2d672c2SIgor Mammedov 697d342eb76SIgor Mammedov cpu_item->type = g_strdup(machine->possible_cpus->cpus[i].type); 698f2d672c2SIgor Mammedov cpu_item->vcpus_count = machine->possible_cpus->cpus[i].vcpus_count; 699f2d672c2SIgor Mammedov cpu_item->props = g_memdup(&machine->possible_cpus->cpus[i].props, 700f2d672c2SIgor Mammedov sizeof(*cpu_item->props)); 701f2d672c2SIgor Mammedov 702f2d672c2SIgor Mammedov cpu = machine->possible_cpus->cpus[i].cpu; 703f2d672c2SIgor Mammedov if (cpu) { 704f2d672c2SIgor Mammedov cpu_item->has_qom_path = true; 705f2d672c2SIgor Mammedov cpu_item->qom_path = object_get_canonical_path(cpu); 706f2d672c2SIgor Mammedov } 707f2d672c2SIgor Mammedov list_item->value = cpu_item; 708f2d672c2SIgor Mammedov list_item->next = head; 709f2d672c2SIgor Mammedov head = list_item; 710f2d672c2SIgor Mammedov } 711f2d672c2SIgor Mammedov return head; 712f2d672c2SIgor Mammedov } 713f2d672c2SIgor Mammedov 7147c88e65dSIgor Mammedov /** 7157c88e65dSIgor Mammedov * machine_set_cpu_numa_node: 7167c88e65dSIgor Mammedov * @machine: machine object to modify 7177c88e65dSIgor Mammedov * @props: specifies which cpu objects to assign to 7187c88e65dSIgor Mammedov * numa node specified by @props.node_id 7197c88e65dSIgor Mammedov * @errp: if an error occurs, a pointer to an area to store the error 7207c88e65dSIgor Mammedov * 7217c88e65dSIgor Mammedov * Associate NUMA node specified by @props.node_id with cpu slots that 7227c88e65dSIgor Mammedov * match socket/core/thread-ids specified by @props. It's recommended to use 7237c88e65dSIgor Mammedov * query-hotpluggable-cpus.props values to specify affected cpu slots, 7247c88e65dSIgor Mammedov * which would lead to exact 1:1 mapping of cpu slots to NUMA node. 7257c88e65dSIgor Mammedov * 7267c88e65dSIgor Mammedov * However for CLI convenience it's possible to pass in subset of properties, 7277c88e65dSIgor Mammedov * which would affect all cpu slots that match it. 7287c88e65dSIgor Mammedov * Ex for pc machine: 7297c88e65dSIgor Mammedov * -smp 4,cores=2,sockets=2 -numa node,nodeid=0 -numa node,nodeid=1 \ 7307c88e65dSIgor Mammedov * -numa cpu,node-id=0,socket_id=0 \ 7317c88e65dSIgor Mammedov * -numa cpu,node-id=1,socket_id=1 7327c88e65dSIgor Mammedov * will assign all child cores of socket 0 to node 0 and 7337c88e65dSIgor Mammedov * of socket 1 to node 1. 7347c88e65dSIgor Mammedov * 7357c88e65dSIgor Mammedov * On attempt of reassigning (already assigned) cpu slot to another NUMA node, 7367c88e65dSIgor Mammedov * return error. 7377c88e65dSIgor Mammedov * Empty subset is disallowed and function will return with error in this case. 7387c88e65dSIgor Mammedov */ 7397c88e65dSIgor Mammedov void machine_set_cpu_numa_node(MachineState *machine, 7407c88e65dSIgor Mammedov const CpuInstanceProperties *props, Error **errp) 7417c88e65dSIgor Mammedov { 7427c88e65dSIgor Mammedov MachineClass *mc = MACHINE_GET_CLASS(machine); 7437c88e65dSIgor Mammedov bool match = false; 7447c88e65dSIgor Mammedov int i; 7457c88e65dSIgor Mammedov 7467c88e65dSIgor Mammedov if (!mc->possible_cpu_arch_ids) { 7477c88e65dSIgor Mammedov error_setg(errp, "mapping of CPUs to NUMA node is not supported"); 7487c88e65dSIgor Mammedov return; 7497c88e65dSIgor Mammedov } 7507c88e65dSIgor Mammedov 7517c88e65dSIgor Mammedov /* disabling node mapping is not supported, forbid it */ 7527c88e65dSIgor Mammedov assert(props->has_node_id); 7537c88e65dSIgor Mammedov 7547c88e65dSIgor Mammedov /* force board to initialize possible_cpus if it hasn't been done yet */ 7557c88e65dSIgor Mammedov mc->possible_cpu_arch_ids(machine); 7567c88e65dSIgor Mammedov 7577c88e65dSIgor Mammedov for (i = 0; i < machine->possible_cpus->len; i++) { 7587c88e65dSIgor Mammedov CPUArchId *slot = &machine->possible_cpus->cpus[i]; 7597c88e65dSIgor Mammedov 7607c88e65dSIgor Mammedov /* reject unsupported by board properties */ 7617c88e65dSIgor Mammedov if (props->has_thread_id && !slot->props.has_thread_id) { 7627c88e65dSIgor Mammedov error_setg(errp, "thread-id is not supported"); 7637c88e65dSIgor Mammedov return; 7647c88e65dSIgor Mammedov } 7657c88e65dSIgor Mammedov 7667c88e65dSIgor Mammedov if (props->has_core_id && !slot->props.has_core_id) { 7677c88e65dSIgor Mammedov error_setg(errp, "core-id is not supported"); 7687c88e65dSIgor Mammedov return; 7697c88e65dSIgor Mammedov } 7707c88e65dSIgor Mammedov 7717c88e65dSIgor Mammedov if (props->has_socket_id && !slot->props.has_socket_id) { 7727c88e65dSIgor Mammedov error_setg(errp, "socket-id is not supported"); 7737c88e65dSIgor Mammedov return; 7747c88e65dSIgor Mammedov } 7757c88e65dSIgor Mammedov 7767c88e65dSIgor Mammedov /* skip slots with explicit mismatch */ 7777c88e65dSIgor Mammedov if (props->has_thread_id && props->thread_id != slot->props.thread_id) { 7787c88e65dSIgor Mammedov continue; 7797c88e65dSIgor Mammedov } 7807c88e65dSIgor Mammedov 7817c88e65dSIgor Mammedov if (props->has_core_id && props->core_id != slot->props.core_id) { 7827c88e65dSIgor Mammedov continue; 7837c88e65dSIgor Mammedov } 7847c88e65dSIgor Mammedov 7857c88e65dSIgor Mammedov if (props->has_socket_id && props->socket_id != slot->props.socket_id) { 7867c88e65dSIgor Mammedov continue; 7877c88e65dSIgor Mammedov } 7887c88e65dSIgor Mammedov 7897c88e65dSIgor Mammedov /* reject assignment if slot is already assigned, for compatibility 7907c88e65dSIgor Mammedov * of legacy cpu_index mapping with SPAPR core based mapping do not 7917c88e65dSIgor Mammedov * error out if cpu thread and matched core have the same node-id */ 7927c88e65dSIgor Mammedov if (slot->props.has_node_id && 7937c88e65dSIgor Mammedov slot->props.node_id != props->node_id) { 7947c88e65dSIgor Mammedov error_setg(errp, "CPU is already assigned to node-id: %" PRId64, 7957c88e65dSIgor Mammedov slot->props.node_id); 7967c88e65dSIgor Mammedov return; 7977c88e65dSIgor Mammedov } 7987c88e65dSIgor Mammedov 7997c88e65dSIgor Mammedov /* assign slot to node as it's matched '-numa cpu' key */ 8007c88e65dSIgor Mammedov match = true; 8017c88e65dSIgor Mammedov slot->props.node_id = props->node_id; 8027c88e65dSIgor Mammedov slot->props.has_node_id = props->has_node_id; 8037c88e65dSIgor Mammedov } 8047c88e65dSIgor Mammedov 8057c88e65dSIgor Mammedov if (!match) { 8067c88e65dSIgor Mammedov error_setg(errp, "no match found"); 8077c88e65dSIgor Mammedov } 8087c88e65dSIgor Mammedov } 8097c88e65dSIgor Mammedov 810076b35b5SNikunj A Dadhania static void machine_class_init(ObjectClass *oc, void *data) 811076b35b5SNikunj A Dadhania { 812076b35b5SNikunj A Dadhania MachineClass *mc = MACHINE_CLASS(oc); 813076b35b5SNikunj A Dadhania 814076b35b5SNikunj A Dadhania /* Default 128 MB as guest ram size */ 815d23b6caaSPhilippe Mathieu-Daudé mc->default_ram_size = 128 * MiB; 81671ae9e94SEduardo Habkost mc->rom_file_has_mr = true; 81726b81df4SEduardo Habkost 81855641213SLaurent Vivier /* numa node memory size aligned on 8MB by default. 81955641213SLaurent Vivier * On Linux, each node's border has to be 8MB aligned 82055641213SLaurent Vivier */ 82155641213SLaurent Vivier mc->numa_mem_align_shift = 23; 8223bfe5716SLaurent Vivier mc->numa_auto_assign_ram = numa_default_auto_assign_ram; 82355641213SLaurent Vivier 82426b81df4SEduardo Habkost object_class_property_add_str(oc, "accel", 82526b81df4SEduardo Habkost machine_get_accel, machine_set_accel, &error_abort); 82626b81df4SEduardo Habkost object_class_property_set_description(oc, "accel", 82726b81df4SEduardo Habkost "Accelerator list", &error_abort); 82826b81df4SEduardo Habkost 829e80200c5SAlexey Kardashevskiy object_class_property_add(oc, "kernel-irqchip", "on|off|split", 83026b81df4SEduardo Habkost NULL, machine_set_kernel_irqchip, 83126b81df4SEduardo Habkost NULL, NULL, &error_abort); 83226b81df4SEduardo Habkost object_class_property_set_description(oc, "kernel-irqchip", 83326b81df4SEduardo Habkost "Configure KVM in-kernel irqchip", &error_abort); 83426b81df4SEduardo Habkost 83526b81df4SEduardo Habkost object_class_property_add(oc, "kvm-shadow-mem", "int", 83626b81df4SEduardo Habkost machine_get_kvm_shadow_mem, machine_set_kvm_shadow_mem, 83726b81df4SEduardo Habkost NULL, NULL, &error_abort); 83826b81df4SEduardo Habkost object_class_property_set_description(oc, "kvm-shadow-mem", 83926b81df4SEduardo Habkost "KVM shadow MMU size", &error_abort); 84026b81df4SEduardo Habkost 84126b81df4SEduardo Habkost object_class_property_add_str(oc, "kernel", 84226b81df4SEduardo Habkost machine_get_kernel, machine_set_kernel, &error_abort); 84326b81df4SEduardo Habkost object_class_property_set_description(oc, "kernel", 84426b81df4SEduardo Habkost "Linux kernel image file", &error_abort); 84526b81df4SEduardo Habkost 84626b81df4SEduardo Habkost object_class_property_add_str(oc, "initrd", 84726b81df4SEduardo Habkost machine_get_initrd, machine_set_initrd, &error_abort); 84826b81df4SEduardo Habkost object_class_property_set_description(oc, "initrd", 84926b81df4SEduardo Habkost "Linux initial ramdisk file", &error_abort); 85026b81df4SEduardo Habkost 85126b81df4SEduardo Habkost object_class_property_add_str(oc, "append", 85226b81df4SEduardo Habkost machine_get_append, machine_set_append, &error_abort); 85326b81df4SEduardo Habkost object_class_property_set_description(oc, "append", 85426b81df4SEduardo Habkost "Linux kernel command line", &error_abort); 85526b81df4SEduardo Habkost 85626b81df4SEduardo Habkost object_class_property_add_str(oc, "dtb", 85726b81df4SEduardo Habkost machine_get_dtb, machine_set_dtb, &error_abort); 85826b81df4SEduardo Habkost object_class_property_set_description(oc, "dtb", 85926b81df4SEduardo Habkost "Linux kernel device tree file", &error_abort); 86026b81df4SEduardo Habkost 86126b81df4SEduardo Habkost object_class_property_add_str(oc, "dumpdtb", 86226b81df4SEduardo Habkost machine_get_dumpdtb, machine_set_dumpdtb, &error_abort); 86326b81df4SEduardo Habkost object_class_property_set_description(oc, "dumpdtb", 86426b81df4SEduardo Habkost "Dump current dtb to a file and quit", &error_abort); 86526b81df4SEduardo Habkost 86626b81df4SEduardo Habkost object_class_property_add(oc, "phandle-start", "int", 86726b81df4SEduardo Habkost machine_get_phandle_start, machine_set_phandle_start, 86826b81df4SEduardo Habkost NULL, NULL, &error_abort); 86926b81df4SEduardo Habkost object_class_property_set_description(oc, "phandle-start", 87026b81df4SEduardo Habkost "The first phandle ID we may generate dynamically", &error_abort); 87126b81df4SEduardo Habkost 87226b81df4SEduardo Habkost object_class_property_add_str(oc, "dt-compatible", 87326b81df4SEduardo Habkost machine_get_dt_compatible, machine_set_dt_compatible, &error_abort); 87426b81df4SEduardo Habkost object_class_property_set_description(oc, "dt-compatible", 87526b81df4SEduardo Habkost "Overrides the \"compatible\" property of the dt root node", 87626b81df4SEduardo Habkost &error_abort); 87726b81df4SEduardo Habkost 87826b81df4SEduardo Habkost object_class_property_add_bool(oc, "dump-guest-core", 87926b81df4SEduardo Habkost machine_get_dump_guest_core, machine_set_dump_guest_core, &error_abort); 88026b81df4SEduardo Habkost object_class_property_set_description(oc, "dump-guest-core", 88126b81df4SEduardo Habkost "Include guest memory in a core dump", &error_abort); 88226b81df4SEduardo Habkost 88326b81df4SEduardo Habkost object_class_property_add_bool(oc, "mem-merge", 88426b81df4SEduardo Habkost machine_get_mem_merge, machine_set_mem_merge, &error_abort); 88526b81df4SEduardo Habkost object_class_property_set_description(oc, "mem-merge", 88626b81df4SEduardo Habkost "Enable/disable memory merge support", &error_abort); 88726b81df4SEduardo Habkost 88826b81df4SEduardo Habkost object_class_property_add_bool(oc, "usb", 88926b81df4SEduardo Habkost machine_get_usb, machine_set_usb, &error_abort); 89026b81df4SEduardo Habkost object_class_property_set_description(oc, "usb", 89126b81df4SEduardo Habkost "Set on/off to enable/disable usb", &error_abort); 89226b81df4SEduardo Habkost 89326b81df4SEduardo Habkost object_class_property_add_bool(oc, "graphics", 89426b81df4SEduardo Habkost machine_get_graphics, machine_set_graphics, &error_abort); 89526b81df4SEduardo Habkost object_class_property_set_description(oc, "graphics", 89626b81df4SEduardo Habkost "Set on/off to enable/disable graphics emulation", &error_abort); 89726b81df4SEduardo Habkost 89826b81df4SEduardo Habkost object_class_property_add_bool(oc, "igd-passthru", 89926b81df4SEduardo Habkost machine_get_igd_gfx_passthru, machine_set_igd_gfx_passthru, 90026b81df4SEduardo Habkost &error_abort); 90126b81df4SEduardo Habkost object_class_property_set_description(oc, "igd-passthru", 90226b81df4SEduardo Habkost "Set on/off to enable/disable igd passthrou", &error_abort); 90326b81df4SEduardo Habkost 90426b81df4SEduardo Habkost object_class_property_add_str(oc, "firmware", 90526b81df4SEduardo Habkost machine_get_firmware, machine_set_firmware, 90626b81df4SEduardo Habkost &error_abort); 90726b81df4SEduardo Habkost object_class_property_set_description(oc, "firmware", 90826b81df4SEduardo Habkost "Firmware image", &error_abort); 90926b81df4SEduardo Habkost 91026b81df4SEduardo Habkost object_class_property_add_bool(oc, "suppress-vmdesc", 91126b81df4SEduardo Habkost machine_get_suppress_vmdesc, machine_set_suppress_vmdesc, 91226b81df4SEduardo Habkost &error_abort); 91326b81df4SEduardo Habkost object_class_property_set_description(oc, "suppress-vmdesc", 91426b81df4SEduardo Habkost "Set on to disable self-describing migration", &error_abort); 91526b81df4SEduardo Habkost 91626b81df4SEduardo Habkost object_class_property_add_bool(oc, "enforce-config-section", 91726b81df4SEduardo Habkost machine_get_enforce_config_section, machine_set_enforce_config_section, 91826b81df4SEduardo Habkost &error_abort); 91926b81df4SEduardo Habkost object_class_property_set_description(oc, "enforce-config-section", 92026b81df4SEduardo Habkost "Set on to enforce configuration section migration", &error_abort); 921db588194SBrijesh Singh 922db588194SBrijesh Singh object_class_property_add_str(oc, "memory-encryption", 923db588194SBrijesh Singh machine_get_memory_encryption, machine_set_memory_encryption, 924db588194SBrijesh Singh &error_abort); 925db588194SBrijesh Singh object_class_property_set_description(oc, "memory-encryption", 926bfec23a0SLi Qiang "Set memory encryption object to use", &error_abort); 927076b35b5SNikunj A Dadhania } 928076b35b5SNikunj A Dadhania 929dcb3d601SEduardo Habkost static void machine_class_base_init(ObjectClass *oc, void *data) 930dcb3d601SEduardo Habkost { 931dcb3d601SEduardo Habkost if (!object_class_is_abstract(oc)) { 93298cec76aSEduardo Habkost MachineClass *mc = MACHINE_CLASS(oc); 933dcb3d601SEduardo Habkost const char *cname = object_class_get_name(oc); 934dcb3d601SEduardo Habkost assert(g_str_has_suffix(cname, TYPE_MACHINE_SUFFIX)); 93598cec76aSEduardo Habkost mc->name = g_strndup(cname, 93698cec76aSEduardo Habkost strlen(cname) - strlen(TYPE_MACHINE_SUFFIX)); 937b66bbee3SMarc-André Lureau mc->compat_props = g_ptr_array_new(); 938dcb3d601SEduardo Habkost } 939dcb3d601SEduardo Habkost } 940dcb3d601SEduardo Habkost 9416b1b1440SMarcel Apfelbaum static void machine_initfn(Object *obj) 9426b1b1440SMarcel Apfelbaum { 94333cd52b5SAlexander Graf MachineState *ms = MACHINE(obj); 944b2fc91dbSPeter Xu MachineClass *mc = MACHINE_GET_CLASS(obj); 94533cd52b5SAlexander Graf 946d8870d02SMarcel Apfelbaum ms->kernel_irqchip_allowed = true; 947b2fc91dbSPeter Xu ms->kernel_irqchip_split = mc->default_kernel_irqchip_split; 9484689b77bSMarcel Apfelbaum ms->kvm_shadow_mem = -1; 94947c8ca53SMarcel Apfelbaum ms->dump_guest_core = true; 95075cc7f01SMarcel Apfelbaum ms->mem_merge = true; 951cfc58cf3SEduardo Habkost ms->enable_graphics = true; 952d8870d02SMarcel Apfelbaum 95333cd52b5SAlexander Graf /* Register notifier when init is done for sysbus sanity checks */ 95433cd52b5SAlexander Graf ms->sysbus_notifier.notify = machine_init_notify; 95533cd52b5SAlexander Graf qemu_add_machine_init_done_notifier(&ms->sysbus_notifier); 9566b1b1440SMarcel Apfelbaum } 9576b1b1440SMarcel Apfelbaum 9586b1b1440SMarcel Apfelbaum static void machine_finalize(Object *obj) 9596b1b1440SMarcel Apfelbaum { 9606b1b1440SMarcel Apfelbaum MachineState *ms = MACHINE(obj); 9616b1b1440SMarcel Apfelbaum 9626b1b1440SMarcel Apfelbaum g_free(ms->accel); 9636b1b1440SMarcel Apfelbaum g_free(ms->kernel_filename); 9646b1b1440SMarcel Apfelbaum g_free(ms->initrd_filename); 9656b1b1440SMarcel Apfelbaum g_free(ms->kernel_cmdline); 9666b1b1440SMarcel Apfelbaum g_free(ms->dtb); 9676b1b1440SMarcel Apfelbaum g_free(ms->dumpdtb); 9686b1b1440SMarcel Apfelbaum g_free(ms->dt_compatible); 9696b1b1440SMarcel Apfelbaum g_free(ms->firmware); 9702ff4f67cSDavid Hildenbrand g_free(ms->device_memory); 9716b1b1440SMarcel Apfelbaum } 97236d20cb2SMarcel Apfelbaum 9735e97b623SMarcel Apfelbaum bool machine_usb(MachineState *machine) 9745e97b623SMarcel Apfelbaum { 9755e97b623SMarcel Apfelbaum return machine->usb; 9765e97b623SMarcel Apfelbaum } 9775e97b623SMarcel Apfelbaum 978d8870d02SMarcel Apfelbaum bool machine_kernel_irqchip_allowed(MachineState *machine) 979d8870d02SMarcel Apfelbaum { 980d8870d02SMarcel Apfelbaum return machine->kernel_irqchip_allowed; 981d8870d02SMarcel Apfelbaum } 982d8870d02SMarcel Apfelbaum 983d8870d02SMarcel Apfelbaum bool machine_kernel_irqchip_required(MachineState *machine) 984d8870d02SMarcel Apfelbaum { 985d8870d02SMarcel Apfelbaum return machine->kernel_irqchip_required; 986d8870d02SMarcel Apfelbaum } 987d8870d02SMarcel Apfelbaum 98832c18a2dSMatt Gingell bool machine_kernel_irqchip_split(MachineState *machine) 98932c18a2dSMatt Gingell { 99032c18a2dSMatt Gingell return machine->kernel_irqchip_split; 99132c18a2dSMatt Gingell } 99232c18a2dSMatt Gingell 9934689b77bSMarcel Apfelbaum int machine_kvm_shadow_mem(MachineState *machine) 9944689b77bSMarcel Apfelbaum { 9954689b77bSMarcel Apfelbaum return machine->kvm_shadow_mem; 9964689b77bSMarcel Apfelbaum } 9974689b77bSMarcel Apfelbaum 9986cabe7faSMarcel Apfelbaum int machine_phandle_start(MachineState *machine) 9996cabe7faSMarcel Apfelbaum { 10006cabe7faSMarcel Apfelbaum return machine->phandle_start; 10016cabe7faSMarcel Apfelbaum } 10026cabe7faSMarcel Apfelbaum 100347c8ca53SMarcel Apfelbaum bool machine_dump_guest_core(MachineState *machine) 100447c8ca53SMarcel Apfelbaum { 100547c8ca53SMarcel Apfelbaum return machine->dump_guest_core; 100647c8ca53SMarcel Apfelbaum } 100747c8ca53SMarcel Apfelbaum 100875cc7f01SMarcel Apfelbaum bool machine_mem_merge(MachineState *machine) 100975cc7f01SMarcel Apfelbaum { 101075cc7f01SMarcel Apfelbaum return machine->mem_merge; 101175cc7f01SMarcel Apfelbaum } 101275cc7f01SMarcel Apfelbaum 1013ec78f811SIgor Mammedov static char *cpu_slot_to_string(const CPUArchId *cpu) 1014ec78f811SIgor Mammedov { 1015ec78f811SIgor Mammedov GString *s = g_string_new(NULL); 1016ec78f811SIgor Mammedov if (cpu->props.has_socket_id) { 1017ec78f811SIgor Mammedov g_string_append_printf(s, "socket-id: %"PRId64, cpu->props.socket_id); 1018ec78f811SIgor Mammedov } 1019ec78f811SIgor Mammedov if (cpu->props.has_core_id) { 1020ec78f811SIgor Mammedov if (s->len) { 1021ec78f811SIgor Mammedov g_string_append_printf(s, ", "); 1022ec78f811SIgor Mammedov } 1023ec78f811SIgor Mammedov g_string_append_printf(s, "core-id: %"PRId64, cpu->props.core_id); 1024ec78f811SIgor Mammedov } 1025ec78f811SIgor Mammedov if (cpu->props.has_thread_id) { 1026ec78f811SIgor Mammedov if (s->len) { 1027ec78f811SIgor Mammedov g_string_append_printf(s, ", "); 1028ec78f811SIgor Mammedov } 1029ec78f811SIgor Mammedov g_string_append_printf(s, "thread-id: %"PRId64, cpu->props.thread_id); 1030ec78f811SIgor Mammedov } 1031ec78f811SIgor Mammedov return g_string_free(s, false); 1032ec78f811SIgor Mammedov } 1033ec78f811SIgor Mammedov 10347a3099fcSIgor Mammedov static void machine_numa_finish_cpu_init(MachineState *machine) 1035ec78f811SIgor Mammedov { 1036ec78f811SIgor Mammedov int i; 103760bed6a3SIgor Mammedov bool default_mapping; 1038ec78f811SIgor Mammedov GString *s = g_string_new(NULL); 1039ec78f811SIgor Mammedov MachineClass *mc = MACHINE_GET_CLASS(machine); 1040ec78f811SIgor Mammedov const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(machine); 1041ec78f811SIgor Mammedov 1042ec78f811SIgor Mammedov assert(nb_numa_nodes); 1043ec78f811SIgor Mammedov for (i = 0; i < possible_cpus->len; i++) { 104460bed6a3SIgor Mammedov if (possible_cpus->cpus[i].props.has_node_id) { 104560bed6a3SIgor Mammedov break; 104660bed6a3SIgor Mammedov } 104760bed6a3SIgor Mammedov } 104860bed6a3SIgor Mammedov default_mapping = (i == possible_cpus->len); 104960bed6a3SIgor Mammedov 105060bed6a3SIgor Mammedov for (i = 0; i < possible_cpus->len; i++) { 1051ec78f811SIgor Mammedov const CPUArchId *cpu_slot = &possible_cpus->cpus[i]; 1052ec78f811SIgor Mammedov 1053ec78f811SIgor Mammedov if (!cpu_slot->props.has_node_id) { 105460bed6a3SIgor Mammedov /* fetch default mapping from board and enable it */ 105560bed6a3SIgor Mammedov CpuInstanceProperties props = cpu_slot->props; 1056d41f3e75SIgor Mammedov 105779e07936SIgor Mammedov props.node_id = mc->get_default_cpu_node_id(machine, i); 1058d41f3e75SIgor Mammedov if (!default_mapping) { 105960bed6a3SIgor Mammedov /* record slots with not set mapping, 106060bed6a3SIgor Mammedov * TODO: make it hard error in future */ 1061ec78f811SIgor Mammedov char *cpu_str = cpu_slot_to_string(cpu_slot); 106260bed6a3SIgor Mammedov g_string_append_printf(s, "%sCPU %d [%s]", 106360bed6a3SIgor Mammedov s->len ? ", " : "", i, cpu_str); 1064ec78f811SIgor Mammedov g_free(cpu_str); 1065d41f3e75SIgor Mammedov 1066d41f3e75SIgor Mammedov /* non mapped cpus used to fallback to node 0 */ 1067d41f3e75SIgor Mammedov props.node_id = 0; 1068ec78f811SIgor Mammedov } 1069d41f3e75SIgor Mammedov 1070d41f3e75SIgor Mammedov props.has_node_id = true; 1071d41f3e75SIgor Mammedov machine_set_cpu_numa_node(machine, &props, &error_fatal); 1072ec78f811SIgor Mammedov } 107360bed6a3SIgor Mammedov } 1074c6ff347cSIgor Mammedov if (s->len && !qtest_enabled()) { 10753dc6f869SAlistair Francis warn_report("CPU(s) not present in any NUMA nodes: %s", 1076ec78f811SIgor Mammedov s->str); 10773dc6f869SAlistair Francis warn_report("All CPU(s) up to maxcpus should be described " 1078ec78f811SIgor Mammedov "in NUMA config, ability to start up with partial NUMA " 1079ec78f811SIgor Mammedov "mappings is obsoleted and will be removed in future"); 1080ec78f811SIgor Mammedov } 1081ec78f811SIgor Mammedov g_string_free(s, true); 1082ec78f811SIgor Mammedov } 1083ec78f811SIgor Mammedov 1084482dfe9aSIgor Mammedov void machine_run_board_init(MachineState *machine) 1085482dfe9aSIgor Mammedov { 1086482dfe9aSIgor Mammedov MachineClass *machine_class = MACHINE_GET_CLASS(machine); 1087ec78f811SIgor Mammedov 10887a3099fcSIgor Mammedov numa_complete_configuration(machine); 10893aeaac8fSDou Liyang if (nb_numa_nodes) { 10907a3099fcSIgor Mammedov machine_numa_finish_cpu_init(machine); 10913aeaac8fSDou Liyang } 1092c9cf636dSAlistair Francis 1093c9cf636dSAlistair Francis /* If the machine supports the valid_cpu_types check and the user 1094c9cf636dSAlistair Francis * specified a CPU with -cpu check here that the user CPU is supported. 1095c9cf636dSAlistair Francis */ 1096c9cf636dSAlistair Francis if (machine_class->valid_cpu_types && machine->cpu_type) { 1097c9cf636dSAlistair Francis ObjectClass *class = object_class_by_name(machine->cpu_type); 1098c9cf636dSAlistair Francis int i; 1099c9cf636dSAlistair Francis 1100c9cf636dSAlistair Francis for (i = 0; machine_class->valid_cpu_types[i]; i++) { 1101c9cf636dSAlistair Francis if (object_class_dynamic_cast(class, 1102c9cf636dSAlistair Francis machine_class->valid_cpu_types[i])) { 1103c9cf636dSAlistair Francis /* The user specificed CPU is in the valid field, we are 1104c9cf636dSAlistair Francis * good to go. 1105c9cf636dSAlistair Francis */ 1106c9cf636dSAlistair Francis break; 1107c9cf636dSAlistair Francis } 1108c9cf636dSAlistair Francis } 1109c9cf636dSAlistair Francis 1110c9cf636dSAlistair Francis if (!machine_class->valid_cpu_types[i]) { 1111c9cf636dSAlistair Francis /* The user specified CPU is not valid */ 1112c9cf636dSAlistair Francis error_report("Invalid CPU type: %s", machine->cpu_type); 1113c9cf636dSAlistair Francis error_printf("The valid types are: %s", 1114c9cf636dSAlistair Francis machine_class->valid_cpu_types[0]); 1115c9cf636dSAlistair Francis for (i = 1; machine_class->valid_cpu_types[i]; i++) { 1116c9cf636dSAlistair Francis error_printf(", %s", machine_class->valid_cpu_types[i]); 1117c9cf636dSAlistair Francis } 1118c9cf636dSAlistair Francis error_printf("\n"); 1119c9cf636dSAlistair Francis 1120c9cf636dSAlistair Francis exit(1); 1121c9cf636dSAlistair Francis } 1122c9cf636dSAlistair Francis } 1123c9cf636dSAlistair Francis 1124482dfe9aSIgor Mammedov machine_class->init(machine); 1125482dfe9aSIgor Mammedov } 1126482dfe9aSIgor Mammedov 112736d20cb2SMarcel Apfelbaum static const TypeInfo machine_info = { 112836d20cb2SMarcel Apfelbaum .name = TYPE_MACHINE, 112936d20cb2SMarcel Apfelbaum .parent = TYPE_OBJECT, 113036d20cb2SMarcel Apfelbaum .abstract = true, 113136d20cb2SMarcel Apfelbaum .class_size = sizeof(MachineClass), 1132076b35b5SNikunj A Dadhania .class_init = machine_class_init, 1133dcb3d601SEduardo Habkost .class_base_init = machine_class_base_init, 113436d20cb2SMarcel Apfelbaum .instance_size = sizeof(MachineState), 11356b1b1440SMarcel Apfelbaum .instance_init = machine_initfn, 11366b1b1440SMarcel Apfelbaum .instance_finalize = machine_finalize, 113736d20cb2SMarcel Apfelbaum }; 113836d20cb2SMarcel Apfelbaum 113936d20cb2SMarcel Apfelbaum static void machine_register_types(void) 114036d20cb2SMarcel Apfelbaum { 114136d20cb2SMarcel Apfelbaum type_register_static(&machine_info); 114236d20cb2SMarcel Apfelbaum } 114336d20cb2SMarcel Apfelbaum 114436d20cb2SMarcel Apfelbaum type_init(machine_register_types) 1145