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/units.h" 15 #include "hw/boards.h" 16 #include "qapi/error.h" 17 #include "qapi/qapi-visit-common.h" 18 #include "qapi/visitor.h" 19 #include "hw/sysbus.h" 20 #include "sysemu/sysemu.h" 21 #include "sysemu/numa.h" 22 #include "qemu/error-report.h" 23 #include "sysemu/qtest.h" 24 25 GlobalProperty hw_compat_3_1[] = { 26 { 27 .driver = "pcie-root-port", 28 .property = "x-speed", 29 .value = "2_5", 30 },{ 31 .driver = "pcie-root-port", 32 .property = "x-width", 33 .value = "1", 34 }, 35 }; 36 const size_t hw_compat_3_1_len = G_N_ELEMENTS(hw_compat_3_1); 37 38 GlobalProperty hw_compat_3_0[] = {}; 39 const size_t hw_compat_3_0_len = G_N_ELEMENTS(hw_compat_3_0); 40 41 GlobalProperty hw_compat_2_12[] = { 42 { 43 .driver = "migration", 44 .property = "decompress-error-check", 45 .value = "off", 46 },{ 47 .driver = "hda-audio", 48 .property = "use-timer", 49 .value = "false", 50 },{ 51 .driver = "cirrus-vga", 52 .property = "global-vmstate", 53 .value = "true", 54 },{ 55 .driver = "VGA", 56 .property = "global-vmstate", 57 .value = "true", 58 },{ 59 .driver = "vmware-svga", 60 .property = "global-vmstate", 61 .value = "true", 62 },{ 63 .driver = "qxl-vga", 64 .property = "global-vmstate", 65 .value = "true", 66 }, 67 }; 68 const size_t hw_compat_2_12_len = G_N_ELEMENTS(hw_compat_2_12); 69 70 GlobalProperty hw_compat_2_11[] = { 71 { 72 .driver = "hpet", 73 .property = "hpet-offset-saved", 74 .value = "false", 75 },{ 76 .driver = "virtio-blk-pci", 77 .property = "vectors", 78 .value = "2", 79 },{ 80 .driver = "vhost-user-blk-pci", 81 .property = "vectors", 82 .value = "2", 83 },{ 84 .driver = "e1000", 85 .property = "migrate_tso_props", 86 .value = "off", 87 }, 88 }; 89 const size_t hw_compat_2_11_len = G_N_ELEMENTS(hw_compat_2_11); 90 91 GlobalProperty hw_compat_2_10[] = { 92 { 93 .driver = "virtio-mouse-device", 94 .property = "wheel-axis", 95 .value = "false", 96 },{ 97 .driver = "virtio-tablet-device", 98 .property = "wheel-axis", 99 .value = "false", 100 }, 101 }; 102 const size_t hw_compat_2_10_len = G_N_ELEMENTS(hw_compat_2_10); 103 104 static char *machine_get_accel(Object *obj, Error **errp) 105 { 106 MachineState *ms = MACHINE(obj); 107 108 return g_strdup(ms->accel); 109 } 110 111 static void machine_set_accel(Object *obj, const char *value, Error **errp) 112 { 113 MachineState *ms = MACHINE(obj); 114 115 g_free(ms->accel); 116 ms->accel = g_strdup(value); 117 } 118 119 static void machine_set_kernel_irqchip(Object *obj, Visitor *v, 120 const char *name, void *opaque, 121 Error **errp) 122 { 123 Error *err = NULL; 124 MachineState *ms = MACHINE(obj); 125 OnOffSplit mode; 126 127 visit_type_OnOffSplit(v, name, &mode, &err); 128 if (err) { 129 error_propagate(errp, err); 130 return; 131 } else { 132 switch (mode) { 133 case ON_OFF_SPLIT_ON: 134 ms->kernel_irqchip_allowed = true; 135 ms->kernel_irqchip_required = true; 136 ms->kernel_irqchip_split = false; 137 break; 138 case ON_OFF_SPLIT_OFF: 139 ms->kernel_irqchip_allowed = false; 140 ms->kernel_irqchip_required = false; 141 ms->kernel_irqchip_split = false; 142 break; 143 case ON_OFF_SPLIT_SPLIT: 144 ms->kernel_irqchip_allowed = true; 145 ms->kernel_irqchip_required = true; 146 ms->kernel_irqchip_split = true; 147 break; 148 default: 149 /* The value was checked in visit_type_OnOffSplit() above. If 150 * we get here, then something is wrong in QEMU. 151 */ 152 abort(); 153 } 154 } 155 } 156 157 static void machine_get_kvm_shadow_mem(Object *obj, Visitor *v, 158 const char *name, void *opaque, 159 Error **errp) 160 { 161 MachineState *ms = MACHINE(obj); 162 int64_t value = ms->kvm_shadow_mem; 163 164 visit_type_int(v, name, &value, errp); 165 } 166 167 static void machine_set_kvm_shadow_mem(Object *obj, Visitor *v, 168 const char *name, void *opaque, 169 Error **errp) 170 { 171 MachineState *ms = MACHINE(obj); 172 Error *error = NULL; 173 int64_t value; 174 175 visit_type_int(v, name, &value, &error); 176 if (error) { 177 error_propagate(errp, error); 178 return; 179 } 180 181 ms->kvm_shadow_mem = value; 182 } 183 184 static char *machine_get_kernel(Object *obj, Error **errp) 185 { 186 MachineState *ms = MACHINE(obj); 187 188 return g_strdup(ms->kernel_filename); 189 } 190 191 static void machine_set_kernel(Object *obj, const char *value, Error **errp) 192 { 193 MachineState *ms = MACHINE(obj); 194 195 g_free(ms->kernel_filename); 196 ms->kernel_filename = g_strdup(value); 197 } 198 199 static char *machine_get_initrd(Object *obj, Error **errp) 200 { 201 MachineState *ms = MACHINE(obj); 202 203 return g_strdup(ms->initrd_filename); 204 } 205 206 static void machine_set_initrd(Object *obj, const char *value, Error **errp) 207 { 208 MachineState *ms = MACHINE(obj); 209 210 g_free(ms->initrd_filename); 211 ms->initrd_filename = g_strdup(value); 212 } 213 214 static char *machine_get_append(Object *obj, Error **errp) 215 { 216 MachineState *ms = MACHINE(obj); 217 218 return g_strdup(ms->kernel_cmdline); 219 } 220 221 static void machine_set_append(Object *obj, const char *value, Error **errp) 222 { 223 MachineState *ms = MACHINE(obj); 224 225 g_free(ms->kernel_cmdline); 226 ms->kernel_cmdline = g_strdup(value); 227 } 228 229 static char *machine_get_dtb(Object *obj, Error **errp) 230 { 231 MachineState *ms = MACHINE(obj); 232 233 return g_strdup(ms->dtb); 234 } 235 236 static void machine_set_dtb(Object *obj, const char *value, Error **errp) 237 { 238 MachineState *ms = MACHINE(obj); 239 240 g_free(ms->dtb); 241 ms->dtb = g_strdup(value); 242 } 243 244 static char *machine_get_dumpdtb(Object *obj, Error **errp) 245 { 246 MachineState *ms = MACHINE(obj); 247 248 return g_strdup(ms->dumpdtb); 249 } 250 251 static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp) 252 { 253 MachineState *ms = MACHINE(obj); 254 255 g_free(ms->dumpdtb); 256 ms->dumpdtb = g_strdup(value); 257 } 258 259 static void machine_get_phandle_start(Object *obj, Visitor *v, 260 const char *name, void *opaque, 261 Error **errp) 262 { 263 MachineState *ms = MACHINE(obj); 264 int64_t value = ms->phandle_start; 265 266 visit_type_int(v, name, &value, errp); 267 } 268 269 static void machine_set_phandle_start(Object *obj, Visitor *v, 270 const char *name, void *opaque, 271 Error **errp) 272 { 273 MachineState *ms = MACHINE(obj); 274 Error *error = NULL; 275 int64_t value; 276 277 visit_type_int(v, name, &value, &error); 278 if (error) { 279 error_propagate(errp, error); 280 return; 281 } 282 283 ms->phandle_start = value; 284 } 285 286 static char *machine_get_dt_compatible(Object *obj, Error **errp) 287 { 288 MachineState *ms = MACHINE(obj); 289 290 return g_strdup(ms->dt_compatible); 291 } 292 293 static void machine_set_dt_compatible(Object *obj, const char *value, Error **errp) 294 { 295 MachineState *ms = MACHINE(obj); 296 297 g_free(ms->dt_compatible); 298 ms->dt_compatible = g_strdup(value); 299 } 300 301 static bool machine_get_dump_guest_core(Object *obj, Error **errp) 302 { 303 MachineState *ms = MACHINE(obj); 304 305 return ms->dump_guest_core; 306 } 307 308 static void machine_set_dump_guest_core(Object *obj, bool value, Error **errp) 309 { 310 MachineState *ms = MACHINE(obj); 311 312 ms->dump_guest_core = value; 313 } 314 315 static bool machine_get_mem_merge(Object *obj, Error **errp) 316 { 317 MachineState *ms = MACHINE(obj); 318 319 return ms->mem_merge; 320 } 321 322 static void machine_set_mem_merge(Object *obj, bool value, Error **errp) 323 { 324 MachineState *ms = MACHINE(obj); 325 326 ms->mem_merge = value; 327 } 328 329 static bool machine_get_usb(Object *obj, Error **errp) 330 { 331 MachineState *ms = MACHINE(obj); 332 333 return ms->usb; 334 } 335 336 static void machine_set_usb(Object *obj, bool value, Error **errp) 337 { 338 MachineState *ms = MACHINE(obj); 339 340 ms->usb = value; 341 ms->usb_disabled = !value; 342 } 343 344 static bool machine_get_graphics(Object *obj, Error **errp) 345 { 346 MachineState *ms = MACHINE(obj); 347 348 return ms->enable_graphics; 349 } 350 351 static void machine_set_graphics(Object *obj, bool value, Error **errp) 352 { 353 MachineState *ms = MACHINE(obj); 354 355 ms->enable_graphics = value; 356 } 357 358 static bool machine_get_igd_gfx_passthru(Object *obj, Error **errp) 359 { 360 MachineState *ms = MACHINE(obj); 361 362 return ms->igd_gfx_passthru; 363 } 364 365 static void machine_set_igd_gfx_passthru(Object *obj, bool value, Error **errp) 366 { 367 MachineState *ms = MACHINE(obj); 368 369 ms->igd_gfx_passthru = value; 370 } 371 372 static char *machine_get_firmware(Object *obj, Error **errp) 373 { 374 MachineState *ms = MACHINE(obj); 375 376 return g_strdup(ms->firmware); 377 } 378 379 static void machine_set_firmware(Object *obj, const char *value, Error **errp) 380 { 381 MachineState *ms = MACHINE(obj); 382 383 g_free(ms->firmware); 384 ms->firmware = g_strdup(value); 385 } 386 387 static void machine_set_suppress_vmdesc(Object *obj, bool value, Error **errp) 388 { 389 MachineState *ms = MACHINE(obj); 390 391 ms->suppress_vmdesc = value; 392 } 393 394 static bool machine_get_suppress_vmdesc(Object *obj, Error **errp) 395 { 396 MachineState *ms = MACHINE(obj); 397 398 return ms->suppress_vmdesc; 399 } 400 401 static void machine_set_enforce_config_section(Object *obj, bool value, 402 Error **errp) 403 { 404 MachineState *ms = MACHINE(obj); 405 406 warn_report("enforce-config-section is deprecated, please use " 407 "-global migration.send-configuration=on|off instead"); 408 409 ms->enforce_config_section = value; 410 } 411 412 static bool machine_get_enforce_config_section(Object *obj, Error **errp) 413 { 414 MachineState *ms = MACHINE(obj); 415 416 return ms->enforce_config_section; 417 } 418 419 static char *machine_get_memory_encryption(Object *obj, Error **errp) 420 { 421 MachineState *ms = MACHINE(obj); 422 423 return g_strdup(ms->memory_encryption); 424 } 425 426 static void machine_set_memory_encryption(Object *obj, const char *value, 427 Error **errp) 428 { 429 MachineState *ms = MACHINE(obj); 430 431 g_free(ms->memory_encryption); 432 ms->memory_encryption = g_strdup(value); 433 } 434 435 void machine_class_allow_dynamic_sysbus_dev(MachineClass *mc, const char *type) 436 { 437 strList *item = g_new0(strList, 1); 438 439 item->value = g_strdup(type); 440 item->next = mc->allowed_dynamic_sysbus_devices; 441 mc->allowed_dynamic_sysbus_devices = item; 442 } 443 444 static void validate_sysbus_device(SysBusDevice *sbdev, void *opaque) 445 { 446 MachineState *machine = opaque; 447 MachineClass *mc = MACHINE_GET_CLASS(machine); 448 bool allowed = false; 449 strList *wl; 450 451 for (wl = mc->allowed_dynamic_sysbus_devices; 452 !allowed && wl; 453 wl = wl->next) { 454 allowed |= !!object_dynamic_cast(OBJECT(sbdev), wl->value); 455 } 456 457 if (!allowed) { 458 error_report("Option '-device %s' cannot be handled by this machine", 459 object_class_get_name(object_get_class(OBJECT(sbdev)))); 460 exit(1); 461 } 462 } 463 464 static void machine_init_notify(Notifier *notifier, void *data) 465 { 466 MachineState *machine = MACHINE(qdev_get_machine()); 467 468 /* 469 * Loop through all dynamically created sysbus devices and check if they are 470 * all allowed. If a device is not allowed, error out. 471 */ 472 foreach_dynamic_sysbus_device(validate_sysbus_device, machine); 473 } 474 475 HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine) 476 { 477 int i; 478 HotpluggableCPUList *head = NULL; 479 MachineClass *mc = MACHINE_GET_CLASS(machine); 480 481 /* force board to initialize possible_cpus if it hasn't been done yet */ 482 mc->possible_cpu_arch_ids(machine); 483 484 for (i = 0; i < machine->possible_cpus->len; i++) { 485 Object *cpu; 486 HotpluggableCPUList *list_item = g_new0(typeof(*list_item), 1); 487 HotpluggableCPU *cpu_item = g_new0(typeof(*cpu_item), 1); 488 489 cpu_item->type = g_strdup(machine->possible_cpus->cpus[i].type); 490 cpu_item->vcpus_count = machine->possible_cpus->cpus[i].vcpus_count; 491 cpu_item->props = g_memdup(&machine->possible_cpus->cpus[i].props, 492 sizeof(*cpu_item->props)); 493 494 cpu = machine->possible_cpus->cpus[i].cpu; 495 if (cpu) { 496 cpu_item->has_qom_path = true; 497 cpu_item->qom_path = object_get_canonical_path(cpu); 498 } 499 list_item->value = cpu_item; 500 list_item->next = head; 501 head = list_item; 502 } 503 return head; 504 } 505 506 /** 507 * machine_set_cpu_numa_node: 508 * @machine: machine object to modify 509 * @props: specifies which cpu objects to assign to 510 * numa node specified by @props.node_id 511 * @errp: if an error occurs, a pointer to an area to store the error 512 * 513 * Associate NUMA node specified by @props.node_id with cpu slots that 514 * match socket/core/thread-ids specified by @props. It's recommended to use 515 * query-hotpluggable-cpus.props values to specify affected cpu slots, 516 * which would lead to exact 1:1 mapping of cpu slots to NUMA node. 517 * 518 * However for CLI convenience it's possible to pass in subset of properties, 519 * which would affect all cpu slots that match it. 520 * Ex for pc machine: 521 * -smp 4,cores=2,sockets=2 -numa node,nodeid=0 -numa node,nodeid=1 \ 522 * -numa cpu,node-id=0,socket_id=0 \ 523 * -numa cpu,node-id=1,socket_id=1 524 * will assign all child cores of socket 0 to node 0 and 525 * of socket 1 to node 1. 526 * 527 * On attempt of reassigning (already assigned) cpu slot to another NUMA node, 528 * return error. 529 * Empty subset is disallowed and function will return with error in this case. 530 */ 531 void machine_set_cpu_numa_node(MachineState *machine, 532 const CpuInstanceProperties *props, Error **errp) 533 { 534 MachineClass *mc = MACHINE_GET_CLASS(machine); 535 bool match = false; 536 int i; 537 538 if (!mc->possible_cpu_arch_ids) { 539 error_setg(errp, "mapping of CPUs to NUMA node is not supported"); 540 return; 541 } 542 543 /* disabling node mapping is not supported, forbid it */ 544 assert(props->has_node_id); 545 546 /* force board to initialize possible_cpus if it hasn't been done yet */ 547 mc->possible_cpu_arch_ids(machine); 548 549 for (i = 0; i < machine->possible_cpus->len; i++) { 550 CPUArchId *slot = &machine->possible_cpus->cpus[i]; 551 552 /* reject unsupported by board properties */ 553 if (props->has_thread_id && !slot->props.has_thread_id) { 554 error_setg(errp, "thread-id is not supported"); 555 return; 556 } 557 558 if (props->has_core_id && !slot->props.has_core_id) { 559 error_setg(errp, "core-id is not supported"); 560 return; 561 } 562 563 if (props->has_socket_id && !slot->props.has_socket_id) { 564 error_setg(errp, "socket-id is not supported"); 565 return; 566 } 567 568 /* skip slots with explicit mismatch */ 569 if (props->has_thread_id && props->thread_id != slot->props.thread_id) { 570 continue; 571 } 572 573 if (props->has_core_id && props->core_id != slot->props.core_id) { 574 continue; 575 } 576 577 if (props->has_socket_id && props->socket_id != slot->props.socket_id) { 578 continue; 579 } 580 581 /* reject assignment if slot is already assigned, for compatibility 582 * of legacy cpu_index mapping with SPAPR core based mapping do not 583 * error out if cpu thread and matched core have the same node-id */ 584 if (slot->props.has_node_id && 585 slot->props.node_id != props->node_id) { 586 error_setg(errp, "CPU is already assigned to node-id: %" PRId64, 587 slot->props.node_id); 588 return; 589 } 590 591 /* assign slot to node as it's matched '-numa cpu' key */ 592 match = true; 593 slot->props.node_id = props->node_id; 594 slot->props.has_node_id = props->has_node_id; 595 } 596 597 if (!match) { 598 error_setg(errp, "no match found"); 599 } 600 } 601 602 static void machine_class_init(ObjectClass *oc, void *data) 603 { 604 MachineClass *mc = MACHINE_CLASS(oc); 605 606 /* Default 128 MB as guest ram size */ 607 mc->default_ram_size = 128 * MiB; 608 mc->rom_file_has_mr = true; 609 610 /* numa node memory size aligned on 8MB by default. 611 * On Linux, each node's border has to be 8MB aligned 612 */ 613 mc->numa_mem_align_shift = 23; 614 mc->numa_auto_assign_ram = numa_default_auto_assign_ram; 615 616 object_class_property_add_str(oc, "accel", 617 machine_get_accel, machine_set_accel, &error_abort); 618 object_class_property_set_description(oc, "accel", 619 "Accelerator list", &error_abort); 620 621 object_class_property_add(oc, "kernel-irqchip", "on|off|split", 622 NULL, machine_set_kernel_irqchip, 623 NULL, NULL, &error_abort); 624 object_class_property_set_description(oc, "kernel-irqchip", 625 "Configure KVM in-kernel irqchip", &error_abort); 626 627 object_class_property_add(oc, "kvm-shadow-mem", "int", 628 machine_get_kvm_shadow_mem, machine_set_kvm_shadow_mem, 629 NULL, NULL, &error_abort); 630 object_class_property_set_description(oc, "kvm-shadow-mem", 631 "KVM shadow MMU size", &error_abort); 632 633 object_class_property_add_str(oc, "kernel", 634 machine_get_kernel, machine_set_kernel, &error_abort); 635 object_class_property_set_description(oc, "kernel", 636 "Linux kernel image file", &error_abort); 637 638 object_class_property_add_str(oc, "initrd", 639 machine_get_initrd, machine_set_initrd, &error_abort); 640 object_class_property_set_description(oc, "initrd", 641 "Linux initial ramdisk file", &error_abort); 642 643 object_class_property_add_str(oc, "append", 644 machine_get_append, machine_set_append, &error_abort); 645 object_class_property_set_description(oc, "append", 646 "Linux kernel command line", &error_abort); 647 648 object_class_property_add_str(oc, "dtb", 649 machine_get_dtb, machine_set_dtb, &error_abort); 650 object_class_property_set_description(oc, "dtb", 651 "Linux kernel device tree file", &error_abort); 652 653 object_class_property_add_str(oc, "dumpdtb", 654 machine_get_dumpdtb, machine_set_dumpdtb, &error_abort); 655 object_class_property_set_description(oc, "dumpdtb", 656 "Dump current dtb to a file and quit", &error_abort); 657 658 object_class_property_add(oc, "phandle-start", "int", 659 machine_get_phandle_start, machine_set_phandle_start, 660 NULL, NULL, &error_abort); 661 object_class_property_set_description(oc, "phandle-start", 662 "The first phandle ID we may generate dynamically", &error_abort); 663 664 object_class_property_add_str(oc, "dt-compatible", 665 machine_get_dt_compatible, machine_set_dt_compatible, &error_abort); 666 object_class_property_set_description(oc, "dt-compatible", 667 "Overrides the \"compatible\" property of the dt root node", 668 &error_abort); 669 670 object_class_property_add_bool(oc, "dump-guest-core", 671 machine_get_dump_guest_core, machine_set_dump_guest_core, &error_abort); 672 object_class_property_set_description(oc, "dump-guest-core", 673 "Include guest memory in a core dump", &error_abort); 674 675 object_class_property_add_bool(oc, "mem-merge", 676 machine_get_mem_merge, machine_set_mem_merge, &error_abort); 677 object_class_property_set_description(oc, "mem-merge", 678 "Enable/disable memory merge support", &error_abort); 679 680 object_class_property_add_bool(oc, "usb", 681 machine_get_usb, machine_set_usb, &error_abort); 682 object_class_property_set_description(oc, "usb", 683 "Set on/off to enable/disable usb", &error_abort); 684 685 object_class_property_add_bool(oc, "graphics", 686 machine_get_graphics, machine_set_graphics, &error_abort); 687 object_class_property_set_description(oc, "graphics", 688 "Set on/off to enable/disable graphics emulation", &error_abort); 689 690 object_class_property_add_bool(oc, "igd-passthru", 691 machine_get_igd_gfx_passthru, machine_set_igd_gfx_passthru, 692 &error_abort); 693 object_class_property_set_description(oc, "igd-passthru", 694 "Set on/off to enable/disable igd passthrou", &error_abort); 695 696 object_class_property_add_str(oc, "firmware", 697 machine_get_firmware, machine_set_firmware, 698 &error_abort); 699 object_class_property_set_description(oc, "firmware", 700 "Firmware image", &error_abort); 701 702 object_class_property_add_bool(oc, "suppress-vmdesc", 703 machine_get_suppress_vmdesc, machine_set_suppress_vmdesc, 704 &error_abort); 705 object_class_property_set_description(oc, "suppress-vmdesc", 706 "Set on to disable self-describing migration", &error_abort); 707 708 object_class_property_add_bool(oc, "enforce-config-section", 709 machine_get_enforce_config_section, machine_set_enforce_config_section, 710 &error_abort); 711 object_class_property_set_description(oc, "enforce-config-section", 712 "Set on to enforce configuration section migration", &error_abort); 713 714 object_class_property_add_str(oc, "memory-encryption", 715 machine_get_memory_encryption, machine_set_memory_encryption, 716 &error_abort); 717 object_class_property_set_description(oc, "memory-encryption", 718 "Set memory encryption object to use", &error_abort); 719 } 720 721 static void machine_class_base_init(ObjectClass *oc, void *data) 722 { 723 if (!object_class_is_abstract(oc)) { 724 MachineClass *mc = MACHINE_CLASS(oc); 725 const char *cname = object_class_get_name(oc); 726 assert(g_str_has_suffix(cname, TYPE_MACHINE_SUFFIX)); 727 mc->name = g_strndup(cname, 728 strlen(cname) - strlen(TYPE_MACHINE_SUFFIX)); 729 mc->compat_props = g_ptr_array_new(); 730 } 731 } 732 733 static void machine_initfn(Object *obj) 734 { 735 MachineState *ms = MACHINE(obj); 736 MachineClass *mc = MACHINE_GET_CLASS(obj); 737 738 ms->kernel_irqchip_allowed = true; 739 ms->kernel_irqchip_split = mc->default_kernel_irqchip_split; 740 ms->kvm_shadow_mem = -1; 741 ms->dump_guest_core = true; 742 ms->mem_merge = true; 743 ms->enable_graphics = true; 744 745 /* Register notifier when init is done for sysbus sanity checks */ 746 ms->sysbus_notifier.notify = machine_init_notify; 747 qemu_add_machine_init_done_notifier(&ms->sysbus_notifier); 748 } 749 750 static void machine_finalize(Object *obj) 751 { 752 MachineState *ms = MACHINE(obj); 753 754 g_free(ms->accel); 755 g_free(ms->kernel_filename); 756 g_free(ms->initrd_filename); 757 g_free(ms->kernel_cmdline); 758 g_free(ms->dtb); 759 g_free(ms->dumpdtb); 760 g_free(ms->dt_compatible); 761 g_free(ms->firmware); 762 g_free(ms->device_memory); 763 } 764 765 bool machine_usb(MachineState *machine) 766 { 767 return machine->usb; 768 } 769 770 bool machine_kernel_irqchip_allowed(MachineState *machine) 771 { 772 return machine->kernel_irqchip_allowed; 773 } 774 775 bool machine_kernel_irqchip_required(MachineState *machine) 776 { 777 return machine->kernel_irqchip_required; 778 } 779 780 bool machine_kernel_irqchip_split(MachineState *machine) 781 { 782 return machine->kernel_irqchip_split; 783 } 784 785 int machine_kvm_shadow_mem(MachineState *machine) 786 { 787 return machine->kvm_shadow_mem; 788 } 789 790 int machine_phandle_start(MachineState *machine) 791 { 792 return machine->phandle_start; 793 } 794 795 bool machine_dump_guest_core(MachineState *machine) 796 { 797 return machine->dump_guest_core; 798 } 799 800 bool machine_mem_merge(MachineState *machine) 801 { 802 return machine->mem_merge; 803 } 804 805 static char *cpu_slot_to_string(const CPUArchId *cpu) 806 { 807 GString *s = g_string_new(NULL); 808 if (cpu->props.has_socket_id) { 809 g_string_append_printf(s, "socket-id: %"PRId64, cpu->props.socket_id); 810 } 811 if (cpu->props.has_core_id) { 812 if (s->len) { 813 g_string_append_printf(s, ", "); 814 } 815 g_string_append_printf(s, "core-id: %"PRId64, cpu->props.core_id); 816 } 817 if (cpu->props.has_thread_id) { 818 if (s->len) { 819 g_string_append_printf(s, ", "); 820 } 821 g_string_append_printf(s, "thread-id: %"PRId64, cpu->props.thread_id); 822 } 823 return g_string_free(s, false); 824 } 825 826 static void machine_numa_finish_cpu_init(MachineState *machine) 827 { 828 int i; 829 bool default_mapping; 830 GString *s = g_string_new(NULL); 831 MachineClass *mc = MACHINE_GET_CLASS(machine); 832 const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(machine); 833 834 assert(nb_numa_nodes); 835 for (i = 0; i < possible_cpus->len; i++) { 836 if (possible_cpus->cpus[i].props.has_node_id) { 837 break; 838 } 839 } 840 default_mapping = (i == possible_cpus->len); 841 842 for (i = 0; i < possible_cpus->len; i++) { 843 const CPUArchId *cpu_slot = &possible_cpus->cpus[i]; 844 845 if (!cpu_slot->props.has_node_id) { 846 /* fetch default mapping from board and enable it */ 847 CpuInstanceProperties props = cpu_slot->props; 848 849 props.node_id = mc->get_default_cpu_node_id(machine, i); 850 if (!default_mapping) { 851 /* record slots with not set mapping, 852 * TODO: make it hard error in future */ 853 char *cpu_str = cpu_slot_to_string(cpu_slot); 854 g_string_append_printf(s, "%sCPU %d [%s]", 855 s->len ? ", " : "", i, cpu_str); 856 g_free(cpu_str); 857 858 /* non mapped cpus used to fallback to node 0 */ 859 props.node_id = 0; 860 } 861 862 props.has_node_id = true; 863 machine_set_cpu_numa_node(machine, &props, &error_fatal); 864 } 865 } 866 if (s->len && !qtest_enabled()) { 867 warn_report("CPU(s) not present in any NUMA nodes: %s", 868 s->str); 869 warn_report("All CPU(s) up to maxcpus should be described " 870 "in NUMA config, ability to start up with partial NUMA " 871 "mappings is obsoleted and will be removed in future"); 872 } 873 g_string_free(s, true); 874 } 875 876 void machine_run_board_init(MachineState *machine) 877 { 878 MachineClass *machine_class = MACHINE_GET_CLASS(machine); 879 880 numa_complete_configuration(machine); 881 if (nb_numa_nodes) { 882 machine_numa_finish_cpu_init(machine); 883 } 884 885 /* If the machine supports the valid_cpu_types check and the user 886 * specified a CPU with -cpu check here that the user CPU is supported. 887 */ 888 if (machine_class->valid_cpu_types && machine->cpu_type) { 889 ObjectClass *class = object_class_by_name(machine->cpu_type); 890 int i; 891 892 for (i = 0; machine_class->valid_cpu_types[i]; i++) { 893 if (object_class_dynamic_cast(class, 894 machine_class->valid_cpu_types[i])) { 895 /* The user specificed CPU is in the valid field, we are 896 * good to go. 897 */ 898 break; 899 } 900 } 901 902 if (!machine_class->valid_cpu_types[i]) { 903 /* The user specified CPU is not valid */ 904 error_report("Invalid CPU type: %s", machine->cpu_type); 905 error_printf("The valid types are: %s", 906 machine_class->valid_cpu_types[0]); 907 for (i = 1; machine_class->valid_cpu_types[i]; i++) { 908 error_printf(", %s", machine_class->valid_cpu_types[i]); 909 } 910 error_printf("\n"); 911 912 exit(1); 913 } 914 } 915 916 machine_class->init(machine); 917 } 918 919 static const TypeInfo machine_info = { 920 .name = TYPE_MACHINE, 921 .parent = TYPE_OBJECT, 922 .abstract = true, 923 .class_size = sizeof(MachineClass), 924 .class_init = machine_class_init, 925 .class_base_init = machine_class_base_init, 926 .instance_size = sizeof(MachineState), 927 .instance_init = machine_initfn, 928 .instance_finalize = machine_finalize, 929 }; 930 931 static void machine_register_types(void) 932 { 933 type_register_static(&machine_info); 934 } 935 936 type_init(machine_register_types) 937