vl.c 139 KB
Newer Older
1
/*
2
 * QEMU System Emulator
3
 *
bellard's avatar
bellard committed
4
 * Copyright (c) 2003-2008 Fabrice Bellard
5
 *
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
23
 */
Peter Maydell's avatar
Peter Maydell committed
24
#include "qemu/osdep.h"
25
#include "qemu-version.h"
26 27
#include "qemu/cutils.h"
#include "qemu/help_option.h"
Fam Zheng's avatar
Fam Zheng committed
28
#include "qemu/uuid.h"
blueswir1's avatar
blueswir1 committed
29

30
#ifdef CONFIG_SECCOMP
31
#include "sysemu/seccomp.h"
32
#include "sys/prctl.h"
33 34
#endif

bellard's avatar
bellard committed
35
#ifdef CONFIG_SDL
36
#if defined(__APPLE__) || defined(main)
Stefan Weil's avatar
Stefan Weil committed
37
#include <SDL.h>
malc's avatar
malc committed
38 39 40
int qemu_main(int argc, char **argv, char **envp);
int main(int argc, char **argv)
{
41
    return qemu_main(argc, argv, NULL);
malc's avatar
malc committed
42 43 44
}
#undef main
#define main qemu_main
bellard's avatar
bellard committed
45
#endif
bellard's avatar
bellard committed
46
#endif /* CONFIG_SDL */
47

48 49 50 51 52
#ifdef CONFIG_COCOA
#undef main
#define main qemu_main
#endif /* CONFIG_COCOA */

53

54
#include "qemu/error-report.h"
55
#include "qemu/sockets.h"
56 57
#include "hw/hw.h"
#include "hw/boards.h"
58
#include "sysemu/accel.h"
59
#include "hw/usb.h"
60
#include "hw/isa/isa.h"
61
#include "hw/scsi/scsi.h"
62
#include "hw/display/vga.h"
63
#include "hw/bt.h"
64
#include "sysemu/watchdog.h"
65
#include "hw/smbios/smbios.h"
66
#include "hw/acpi/acpi.h"
67
#include "hw/xen/xen.h"
68
#include "hw/qdev.h"
69
#include "hw/loader.h"
70
#include "monitor/qdev.h"
71
#include "sysemu/bt.h"
Paolo Bonzini's avatar
Paolo Bonzini committed
72
#include "net/net.h"
73
#include "net/slirp.h"
74
#include "monitor/monitor.h"
75
#include "ui/console.h"
76
#include "ui/input.h"
77
#include "sysemu/sysemu.h"
78
#include "sysemu/numa.h"
79
#include "exec/gdbstub.h"
80
#include "qemu/timer.h"
81
#include "chardev/char.h"
Michael Tokarev's avatar
Michael Tokarev committed
82
#include "qemu/bitmap.h"
83
#include "qemu/log.h"
84
#include "sysemu/blockdev.h"
85
#include "hw/block/block.h"
86
#include "migration/misc.h"
87
#include "migration/snapshot.h"
88
#include "migration/global_state.h"
89
#include "sysemu/tpm.h"
90
#include "sysemu/dma.h"
91
#include "hw/audio/soundhw.h"
92
#include "audio/audio.h"
93
#include "sysemu/cpus.h"
94
#include "migration/colo.h"
95
#include "sysemu/kvm.h"
96
#include "sysemu/hax.h"
97 98
#include "qapi/qobject-input-visitor.h"
#include "qapi-visit.h"
99
#include "qapi/qmp/qjson.h"
100 101
#include "qemu/option.h"
#include "qemu/config-file.h"
102
#include "qemu-options.h"
103
#include "qmp-commands.h"
104
#include "qemu/main-loop.h"
105
#ifdef CONFIG_VIRTFS
106 107
#include "fsdev/qemu-fsdev.h"
#endif
108
#include "sysemu/qtest.h"
109

110
#include "disas/disas.h"
bellard's avatar
bellard committed
111

112

Jan Kiszka's avatar
Jan Kiszka committed
113
#include "slirp/libslirp.h"
114

115
#include "trace-root.h"
116
#include "trace/control.h"
117
#include "qemu/queue.h"
118
#include "sysemu/arch_init.h"
119

Gerd Hoffmann's avatar
Gerd Hoffmann committed
120
#include "ui/qemu-spice.h"
121
#include "qapi/string-input-visitor.h"
Paolo Bonzini's avatar
Paolo Bonzini committed
122
#include "qapi/opts-visitor.h"
123 124
#include "qom/object_interfaces.h"
#include "qapi-event.h"
125
#include "exec/semihost.h"
126
#include "crypto/init.h"
Pavel Dovgalyuk's avatar
Pavel Dovgalyuk committed
127
#include "sysemu/replay.h"
128
#include "qapi/qmp/qerror.h"
129
#include "sysemu/iothread.h"
Gerd Hoffmann's avatar
Gerd Hoffmann committed
130

131
#define MAX_VIRTIO_CONSOLES 1
132
#define MAX_SCLP_CONSOLES 1
133

134 135
static const char *data_dir[16];
static int data_dir_idx;
136
const char *bios_name = NULL;
137
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
138
int request_opengl = -1;
139
int display_opengl;
140
const char* keyboard_layout = NULL;
141
ram_addr_t ram_size;
142 143
const char *mem_path = NULL;
int mem_prealloc = 0; /* force preallocation of physical target memory */
144
bool enable_mlock = false;
145
int nb_nics;
bellard's avatar
bellard committed
146
NICInfo nd_table[MAX_NICS];
Paolo Bonzini's avatar
Paolo Bonzini committed
147
int autostart;
148 149
static int rtc_utc = 1;
static int rtc_date_offset = -1; /* -1 means no change */
150
QEMUClockType rtc_clock;
151
int vga_interface_type = VGA_NONE;
blueswir1's avatar
blueswir1 committed
152 153
static int full_screen = 0;
static int no_frame = 0;
154
int no_quit = 0;
155
static bool grab_on_hover;
156 157 158 159
Chardev *serial_hds[MAX_SERIAL_PORTS];
Chardev *parallel_hds[MAX_PARALLEL_PORTS];
Chardev *virtcon_hds[MAX_VIRTIO_CONSOLES];
Chardev *sclp_hds[MAX_SCLP_CONSOLES];
160
int win2k_install_hack = 0;
161
int singlestep = 0;
162 163
int smp_cpus;
unsigned int max_cpus;
164 165
int smp_cores = 1;
int smp_threads = 1;
bellard's avatar
bellard committed
166
int acpi_enabled = 1;
167
int no_hpet = 0;
168
int fd_bootchk = 1;
Blue Swirl's avatar
Blue Swirl committed
169
static int no_reboot;
aurel32's avatar
aurel32 committed
170
int no_shutdown = 0;
171
int cursor_hide = 1;
172
int graphic_rotate = 0;
173
const char *watchdog;
174
QEMUOptionRom option_rom[MAX_OPTION_ROMS];
175
int nb_option_roms;
176
int old_param = 0;
177
const char *qemu_name;
178
int alt_grab = 0;
179
int ctrl_grab = 0;
180 181
unsigned int nb_prom_envs = 0;
const char *prom_envs[MAX_PROM_ENVS];
182
int boot_menu;
183
bool boot_strict;
184
uint8_t *boot_splash_filedata;
185
size_t boot_splash_filedata_size;
186
uint8_t qemu_extra_params_fw[2];
187

188
int icount_align_option;
189

190
/* The bytes in qemu_uuid are in the order specified by RFC4122, _not_ in the
191 192
 * little-endian "wire format" described in the SMBIOS 2.6 specification.
 */
193
QemuUUID qemu_uuid;
194
bool qemu_uuid_set;
195

Gerd Hoffmann's avatar
Gerd Hoffmann committed
196 197 198
static NotifierList exit_notifiers =
    NOTIFIER_LIST_INITIALIZER(exit_notifiers);

199 200 201
static NotifierList machine_init_done_notifiers =
    NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);

202
bool xen_allowed;
203 204
uint32_t xen_domid;
enum xen_mode xen_mode = XEN_EMULATE;
205
bool xen_domid_restrict;
206

207
static int has_defaults = 1;
208
static int default_serial = 1;
209
static int default_parallel = 1;
210
static int default_virtcon = 1;
211
static int default_sclp = 1;
212
static int default_monitor = 1;
213 214 215
static int default_floppy = 1;
static int default_cdrom = 1;
static int default_sdcard = 1;
216
static int default_vga = 1;
217
static int default_net = 1;
218 219 220 221 222

static struct {
    const char *driver;
    int *flag;
} default_list[] = {
223 224
    { .driver = "isa-serial",           .flag = &default_serial    },
    { .driver = "isa-parallel",         .flag = &default_parallel  },
225
    { .driver = "isa-fdc",              .flag = &default_floppy    },
226
    { .driver = "floppy",               .flag = &default_floppy    },
227 228
    { .driver = "ide-cd",               .flag = &default_cdrom     },
    { .driver = "ide-hd",               .flag = &default_cdrom     },
229
    { .driver = "ide-drive",            .flag = &default_cdrom     },
230
    { .driver = "scsi-cd",              .flag = &default_cdrom     },
231
    { .driver = "scsi-hd",              .flag = &default_cdrom     },
232 233
    { .driver = "virtio-serial-pci",    .flag = &default_virtcon   },
    { .driver = "virtio-serial",        .flag = &default_virtcon   },
234 235 236 237 238 239
    { .driver = "VGA",                  .flag = &default_vga       },
    { .driver = "isa-vga",              .flag = &default_vga       },
    { .driver = "cirrus-vga",           .flag = &default_vga       },
    { .driver = "isa-cirrus-vga",       .flag = &default_vga       },
    { .driver = "vmware-svga",          .flag = &default_vga       },
    { .driver = "qxl-vga",              .flag = &default_vga       },
240
    { .driver = "virtio-vga",           .flag = &default_vga       },
241 242
};

243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
static QemuOptsList qemu_rtc_opts = {
    .name = "rtc",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head),
    .desc = {
        {
            .name = "base",
            .type = QEMU_OPT_STRING,
        },{
            .name = "clock",
            .type = QEMU_OPT_STRING,
        },{
            .name = "driftfix",
            .type = QEMU_OPT_STRING,
        },
        { /* end of list */ }
    },
};

static QemuOptsList qemu_sandbox_opts = {
    .name = "sandbox",
    .implied_opt_name = "enable",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_sandbox_opts.head),
    .desc = {
        {
            .name = "enable",
            .type = QEMU_OPT_BOOL,
        },
270 271 272 273
        {
            .name = "obsolete",
            .type = QEMU_OPT_STRING,
        },
274 275 276 277
        {
            .name = "elevateprivileges",
            .type = QEMU_OPT_STRING,
        },
278 279 280 281
        {
            .name = "spawn",
            .type = QEMU_OPT_STRING,
        },
282 283 284 285
        {
            .name = "resourcecontrol",
            .type = QEMU_OPT_STRING,
        },
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
        { /* end of list */ }
    },
};

static QemuOptsList qemu_option_rom_opts = {
    .name = "option-rom",
    .implied_opt_name = "romfile",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_option_rom_opts.head),
    .desc = {
        {
            .name = "bootindex",
            .type = QEMU_OPT_NUMBER,
        }, {
            .name = "romfile",
            .type = QEMU_OPT_STRING,
        },
        { /* end of list */ }
    },
};

static QemuOptsList qemu_machine_opts = {
    .name = "machine",
    .implied_opt_name = "type",
    .merge_lists = true,
    .head = QTAILQ_HEAD_INITIALIZER(qemu_machine_opts.head),
    .desc = {
312 313 314 315 316 317
        /*
         * no elements => accept any
         * sanity checking will happen later
         * when setting machine properties
         */
        { }
318 319 320
    },
};

321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
static QemuOptsList qemu_accel_opts = {
    .name = "accel",
    .implied_opt_name = "accel",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_accel_opts.head),
    .merge_lists = true,
    .desc = {
        {
            .name = "accel",
            .type = QEMU_OPT_STRING,
            .help = "Select the type of accelerator",
        },
        {
            .name = "thread",
            .type = QEMU_OPT_STRING,
            .help = "Enable/disable multi-threaded TCG",
        },
        { /* end of list */ }
    },
};

341 342
static QemuOptsList qemu_boot_opts = {
    .name = "boot-opts",
343 344
    .implied_opt_name = "order",
    .merge_lists = true,
345 346 347 348 349 350 351 352 353 354
    .head = QTAILQ_HEAD_INITIALIZER(qemu_boot_opts.head),
    .desc = {
        {
            .name = "order",
            .type = QEMU_OPT_STRING,
        }, {
            .name = "once",
            .type = QEMU_OPT_STRING,
        }, {
            .name = "menu",
355
            .type = QEMU_OPT_BOOL,
356 357 358 359 360 361 362 363 364
        }, {
            .name = "splash",
            .type = QEMU_OPT_STRING,
        }, {
            .name = "splash-time",
            .type = QEMU_OPT_STRING,
        }, {
            .name = "reboot-timeout",
            .type = QEMU_OPT_STRING,
365 366
        }, {
            .name = "strict",
367
            .type = QEMU_OPT_BOOL,
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
        },
        { /*End of list */ }
    },
};

static QemuOptsList qemu_add_fd_opts = {
    .name = "add-fd",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_add_fd_opts.head),
    .desc = {
        {
            .name = "fd",
            .type = QEMU_OPT_NUMBER,
            .help = "file descriptor of which a duplicate is added to fd set",
        },{
            .name = "set",
            .type = QEMU_OPT_NUMBER,
            .help = "ID of the fd set to add fd to",
        },{
            .name = "opaque",
            .type = QEMU_OPT_STRING,
            .help = "free-form string used to describe fd",
        },
        { /* end of list */ }
    },
};

static QemuOptsList qemu_object_opts = {
    .name = "object",
    .implied_opt_name = "qom-type",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
    .desc = {
        { }
    },
};

403 404 405 406 407
static QemuOptsList qemu_tpmdev_opts = {
    .name = "tpmdev",
    .implied_opt_name = "type",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_tpmdev_opts.head),
    .desc = {
408
        /* options are defined in the TPM backends */
409 410 411 412
        { /* end of list */ }
    },
};

413 414 415 416 417 418 419 420 421 422 423 424
static QemuOptsList qemu_realtime_opts = {
    .name = "realtime",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_realtime_opts.head),
    .desc = {
        {
            .name = "mlock",
            .type = QEMU_OPT_BOOL,
        },
        { /* end of list */ }
    },
};

425 426 427 428 429 430 431 432 433 434 435 436
static QemuOptsList qemu_msg_opts = {
    .name = "msg",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_msg_opts.head),
    .desc = {
        {
            .name = "timestamp",
            .type = QEMU_OPT_BOOL,
        },
        { /* end of list */ }
    },
};

437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
static QemuOptsList qemu_name_opts = {
    .name = "name",
    .implied_opt_name = "guest",
    .merge_lists = true,
    .head = QTAILQ_HEAD_INITIALIZER(qemu_name_opts.head),
    .desc = {
        {
            .name = "guest",
            .type = QEMU_OPT_STRING,
            .help = "Sets the name of the guest.\n"
                    "This name will be displayed in the SDL window caption.\n"
                    "The name will also be used for the VNC server",
        }, {
            .name = "process",
            .type = QEMU_OPT_STRING,
            .help = "Sets the name of the QEMU process, as shown in top etc",
453 454 455 456 457 458
        }, {
            .name = "debug-threads",
            .type = QEMU_OPT_BOOL,
            .help = "When enabled, name the individual threads; defaults off.\n"
                    "NOTE: The thread names are for debugging and not a\n"
                    "stable API.",
459 460 461 462 463
        },
        { /* End of list */ }
    },
};

464 465 466 467 468 469 470 471 472 473
static QemuOptsList qemu_mem_opts = {
    .name = "memory",
    .implied_opt_name = "size",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_mem_opts.head),
    .merge_lists = true,
    .desc = {
        {
            .name = "size",
            .type = QEMU_OPT_SIZE,
        },
474 475 476 477 478 479 480 481
        {
            .name = "slots",
            .type = QEMU_OPT_NUMBER,
        },
        {
            .name = "maxmem",
            .type = QEMU_OPT_SIZE,
        },
482 483 484 485
        { /* end of list */ }
    },
};

486 487 488 489 490 491 492 493 494
static QemuOptsList qemu_icount_opts = {
    .name = "icount",
    .implied_opt_name = "shift",
    .merge_lists = true,
    .head = QTAILQ_HEAD_INITIALIZER(qemu_icount_opts.head),
    .desc = {
        {
            .name = "shift",
            .type = QEMU_OPT_STRING,
495 496 497
        }, {
            .name = "align",
            .type = QEMU_OPT_BOOL,
498 499 500
        }, {
            .name = "sleep",
            .type = QEMU_OPT_BOOL,
501 502 503 504 505 506
        }, {
            .name = "rr",
            .type = QEMU_OPT_STRING,
        }, {
            .name = "rrfile",
            .type = QEMU_OPT_STRING,
507 508 509
        }, {
            .name = "rrsnapshot",
            .type = QEMU_OPT_STRING,
510 511 512 513 514
        },
        { /* end of list */ }
    },
};

515 516 517 518 519 520 521 522 523 524 525
static QemuOptsList qemu_semihosting_config_opts = {
    .name = "semihosting-config",
    .implied_opt_name = "enable",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_semihosting_config_opts.head),
    .desc = {
        {
            .name = "enable",
            .type = QEMU_OPT_BOOL,
        }, {
            .name = "target",
            .type = QEMU_OPT_STRING,
526 527 528
        }, {
            .name = "arg",
            .type = QEMU_OPT_STRING,
529 530 531 532 533
        },
        { /* end of list */ }
    },
};

534 535 536 537 538 539 540 541 542 543 544 545 546 547
static QemuOptsList qemu_fw_cfg_opts = {
    .name = "fw_cfg",
    .implied_opt_name = "name",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_fw_cfg_opts.head),
    .desc = {
        {
            .name = "name",
            .type = QEMU_OPT_STRING,
            .help = "Sets the fw_cfg name of the blob to be inserted",
        }, {
            .name = "file",
            .type = QEMU_OPT_STRING,
            .help = "Sets the name of the file from which\n"
                    "the fw_cfg blob will be loaded",
548 549 550 551
        }, {
            .name = "string",
            .type = QEMU_OPT_STRING,
            .help = "Sets content of the blob to be inserted from a string",
552 553 554 555 556
        },
        { /* end of list */ }
    },
};

557 558 559 560 561 562 563
/**
 * Get machine options
 *
 * Returns: machine options (never null).
 */
QemuOpts *qemu_get_machine_opts(void)
{
564
    return qemu_find_opts_singleton("machine");
565 566
}

567 568 569 570 571
const char *qemu_get_vm_name(void)
{
    return qemu_name;
}

572 573
static void res_free(void)
{
574 575
    g_free(boot_splash_filedata);
    boot_splash_filedata = NULL;
576 577
}

578
static int default_driver_check(void *opaque, QemuOpts *opts, Error **errp)
579 580 581 582 583 584 585 586 587 588 589 590 591 592
{
    const char *driver = qemu_opt_get(opts, "driver");
    int i;

    if (!driver)
        return 0;
    for (i = 0; i < ARRAY_SIZE(default_list); i++) {
        if (strcmp(default_list[i].driver, driver) != 0)
            continue;
        *(default_list[i].flag) = 0;
    }
    return 0;
}

593 594 595
/***********************************************************/
/* QEMU state */

596
static RunState current_run_state = RUN_STATE_PRELAUNCH;
597

598 599
/* We use RUN_STATE__MAX but any invalid value will do */
static RunState vmstop_requested = RUN_STATE__MAX;
600 601
static QemuMutex vmstop_lock;

602 603 604 605 606 607 608
typedef struct {
    RunState from;
    RunState to;
} RunStateTransition;

static const RunStateTransition runstate_transitions_def[] = {
    /*     from      ->     to      */
609
    { RUN_STATE_DEBUG, RUN_STATE_RUNNING },
610
    { RUN_STATE_DEBUG, RUN_STATE_FINISH_MIGRATE },
611
    { RUN_STATE_DEBUG, RUN_STATE_PRELAUNCH },
612

613 614
    { RUN_STATE_INMIGRATE, RUN_STATE_INTERNAL_ERROR },
    { RUN_STATE_INMIGRATE, RUN_STATE_IO_ERROR },
615
    { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED },
616 617 618 619 620
    { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING },
    { RUN_STATE_INMIGRATE, RUN_STATE_SHUTDOWN },
    { RUN_STATE_INMIGRATE, RUN_STATE_SUSPENDED },
    { RUN_STATE_INMIGRATE, RUN_STATE_WATCHDOG },
    { RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED },
621
    { RUN_STATE_INMIGRATE, RUN_STATE_FINISH_MIGRATE },
622 623
    { RUN_STATE_INMIGRATE, RUN_STATE_PRELAUNCH },
    { RUN_STATE_INMIGRATE, RUN_STATE_POSTMIGRATE },
624
    { RUN_STATE_INMIGRATE, RUN_STATE_COLO },
625

626
    { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED },
627
    { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE },
628
    { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PRELAUNCH },
629

630
    { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING },
631
    { RUN_STATE_IO_ERROR, RUN_STATE_FINISH_MIGRATE },
632
    { RUN_STATE_IO_ERROR, RUN_STATE_PRELAUNCH },
633

634
    { RUN_STATE_PAUSED, RUN_STATE_RUNNING },
635
    { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE },
636
    { RUN_STATE_PAUSED, RUN_STATE_POSTMIGRATE },
637
    { RUN_STATE_PAUSED, RUN_STATE_PRELAUNCH },
638
    { RUN_STATE_PAUSED, RUN_STATE_COLO},
639

640
    { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING },
641
    { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE },
642
    { RUN_STATE_POSTMIGRATE, RUN_STATE_PRELAUNCH },
643

644
    { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING },
645
    { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE },
646
    { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
647

648
    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_RUNNING },
649
    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_PAUSED },
650
    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE },
651
    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_PRELAUNCH },
652
    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_COLO},
653

654
    { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING },
655
    { RUN_STATE_RESTORE_VM, RUN_STATE_PRELAUNCH },
656

657 658
    { RUN_STATE_COLO, RUN_STATE_RUNNING },

659 660 661 662 663 664 665 666 667
    { RUN_STATE_RUNNING, RUN_STATE_DEBUG },
    { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },
    { RUN_STATE_RUNNING, RUN_STATE_IO_ERROR },
    { RUN_STATE_RUNNING, RUN_STATE_PAUSED },
    { RUN_STATE_RUNNING, RUN_STATE_FINISH_MIGRATE },
    { RUN_STATE_RUNNING, RUN_STATE_RESTORE_VM },
    { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM },
    { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN },
    { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG },
668
    { RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED },
669
    { RUN_STATE_RUNNING, RUN_STATE_COLO},
670

671
    { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
672

673
    { RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
674
    { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
675
    { RUN_STATE_SHUTDOWN, RUN_STATE_PRELAUNCH },
676

677 678 679 680
    { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
    { RUN_STATE_RUNNING, RUN_STATE_SUSPENDED },
    { RUN_STATE_SUSPENDED, RUN_STATE_RUNNING },
    { RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE },
681
    { RUN_STATE_SUSPENDED, RUN_STATE_PRELAUNCH },
682
    { RUN_STATE_SUSPENDED, RUN_STATE_COLO},
683

684
    { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
685
    { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
686
    { RUN_STATE_WATCHDOG, RUN_STATE_PRELAUNCH },
687
    { RUN_STATE_WATCHDOG, RUN_STATE_COLO},
688

689
    { RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING },
690
    { RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
691
    { RUN_STATE_GUEST_PANICKED, RUN_STATE_PRELAUNCH },
692

693
    { RUN_STATE__MAX, RUN_STATE__MAX },
694 695
};

696
static bool runstate_valid_transitions[RUN_STATE__MAX][RUN_STATE__MAX];
697

698 699 700 701 702
bool runstate_check(RunState state)
{
    return current_run_state == state;
}

703 704
bool runstate_store(char *str, size_t size)
{
705
    const char *state = RunState_str(current_run_state);
706 707 708 709 710 711 712 713 714
    size_t len = strlen(state) + 1;

    if (len > size) {
        return false;
    }
    memcpy(str, state, len);
    return true;
}

Blue Swirl's avatar
Blue Swirl committed
715
static void runstate_init(void)
716 717 718 719
{
    const RunStateTransition *p;

    memset(&runstate_valid_transitions, 0, sizeof(runstate_valid_transitions));
720
    for (p = &runstate_transitions_def[0]; p->from != RUN_STATE__MAX; p++) {
721 722
        runstate_valid_transitions[p->from][p->to] = true;
    }
723 724

    qemu_mutex_init(&vmstop_lock);
725 726 727
}

/* This function will abort() on invalid state transitions */
728 729
void runstate_set(RunState new_state)
{
730
    assert(new_state < RUN_STATE__MAX);
731

732 733 734 735
    if (current_run_state == new_state) {
        return;
    }

736
    if (!runstate_valid_transitions[current_run_state][new_state]) {
737
        error_report("invalid runstate transition: '%s' -> '%s'",
738 739
                     RunState_str(current_run_state),
                     RunState_str(new_state));
740 741
        abort();
    }
742
    trace_runstate_set(new_state);
743 744 745
    current_run_state = new_state;
}

746
int runstate_is_running(void)
747
{
748
    return runstate_check(RUN_STATE_RUNNING);
749 750
}

751 752 753
bool runstate_needs_reset(void)
{
    return runstate_check(RUN_STATE_INTERNAL_ERROR) ||
754
        runstate_check(RUN_STATE_SHUTDOWN);
755 756
}

757
StatusInfo *qmp_query_status(Error **errp)
758
{
759 760 761 762 763 764 765
    StatusInfo *info = g_malloc0(sizeof(*info));

    info->running = runstate_is_running();
    info->singlestep = singlestep;
    info->status = current_run_state;

    return info;
766 767
}

768
bool qemu_vmstop_requested(RunState *r)
769 770 771
{
    qemu_mutex_lock(&vmstop_lock);
    *r = vmstop_requested;
772
    vmstop_requested = RUN_STATE__MAX;
773
    qemu_mutex_unlock(&vmstop_lock);
774
    return *r < RUN_STATE__MAX;
775 776 777 778 779 780 781 782 783 784 785 786 787 788
}

void qemu_system_vmstop_request_prepare(void)
{
    qemu_mutex_lock(&vmstop_lock);
}

void qemu_system_vmstop_request(RunState state)
{
    vmstop_requested = state;
    qemu_mutex_unlock(&vmstop_lock);
    qemu_notify_event();
}

789 790
/***********************************************************/
/* real time host monotonic timer */
791

792 793 794 795 796
static time_t qemu_time(void)
{
    return qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000;
}

797 798 799 800
/***********************************************************/
/* host time/date access */
void qemu_get_timedate(struct tm *tm, int offset)
{
801
    time_t ti = qemu_time();
802 803 804 805

    ti += offset;
    if (rtc_date_offset == -1) {
        if (rtc_utc)
806
            gmtime_r(&ti, tm);
807
        else
808
            localtime_r(&ti, tm);
809 810
    } else {
        ti -= rtc_date_offset;
811
        gmtime_r(&ti, tm);
812 813 814 815 816 817 818 819 820 821
    }
}

int qemu_timedate_diff(struct tm *tm)
{
    time_t seconds;

    if (rtc_date_offset == -1)
        if (rtc_utc)
            seconds = mktimegm(tm);
822 823 824 825 826
        else {
            struct tm tmp = *tm;
            tmp.tm_isdst = -1; /* use timezone to figure it out */
            seconds = mktime(&tmp);
	}
827 828 829
    else
        seconds = mktimegm(tm) + rtc_date_offset;

830
    return seconds - qemu_time();
831 832
}

833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863
static void configure_rtc_date_offset(const char *startdate, int legacy)
{
    time_t rtc_start_date;
    struct tm tm;

    if (!strcmp(startdate, "now") && legacy) {
        rtc_date_offset = -1;
    } else {
        if (sscanf(startdate, "%d-%d-%dT%d:%d:%d",
                   &tm.tm_year,
                   &tm.tm_mon,
                   &tm.tm_mday,
                   &tm.tm_hour,
                   &tm.tm_min,
                   &tm.tm_sec) == 6) {
            /* OK */
        } else if (sscanf(startdate, "%d-%d-%d",
                          &tm.tm_year,
                          &tm.tm_mon,
                          &tm.tm_mday) == 3) {
            tm.tm_hour = 0;
            tm.tm_min = 0;
            tm.tm_sec = 0;
        } else {
            goto date_fail;
        }
        tm.tm_year -= 1900;
        tm.tm_mon--;
        rtc_start_date = mktimegm(&tm);
        if (rtc_start_date == -1) {
        date_fail:
864 865 866
            error_report("invalid date format");
            error_printf("valid formats: "
                         "'2006-06-17T16:01:21' or '2006-06-17'\n");
867 868
            exit(1);
        }
869
        rtc_date_offset = qemu_time() - rtc_start_date;
870 871 872 873 874 875 876 877 878 879 880 881
    }
}

static void configure_rtc(QemuOpts *opts)
{
    const char *value;

    value = qemu_opt_get(opts, "base");
    if (value) {
        if (!strcmp(value, "utc")) {
            rtc_utc = 1;
        } else if (!strcmp(value, "localtime")) {
882
            Error *blocker = NULL;
883
            rtc_utc = 0;
884 885 886
            error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED,
                      "-rtc base=localtime");
            replay_add_blocker(blocker);
887 888 889 890
        } else {
            configure_rtc_date_offset(value, 0);
        }
    }
Jan Kiszka's avatar
Jan Kiszka committed
891 892 893
    value = qemu_opt_get(opts, "clock");
    if (value) {
        if (!strcmp(value, "host")) {
894
            rtc_clock = QEMU_CLOCK_HOST;
Paolo Bonzini's avatar
Paolo Bonzini committed
895
        } else if (!strcmp(value, "rt")) {
896
            rtc_clock = QEMU_CLOCK_REALTIME;
Jan Kiszka's avatar
Jan Kiszka committed
897
        } else if (!strcmp(value, "vm")) {
898
            rtc_clock = QEMU_CLOCK_VIRTUAL;
Jan Kiszka's avatar
Jan Kiszka committed
899
        } else {
900
            error_report("invalid option value '%s'", value);
Jan Kiszka's avatar
Jan Kiszka committed
901 902 903
            exit(1);
        }
    }
904 905
    value = qemu_opt_get(opts, "driftfix");
    if (value) {
Blue Swirl's avatar
Blue Swirl committed
906
        if (!strcmp(value, "slew")) {
907 908 909 910
            static GlobalProperty slew_lost_ticks = {
                .driver   = "mc146818rtc",
                .property = "lost_tick_policy",
                .value    = "slew",
911 912
            };

913
            qdev_prop_register_global(&slew_lost_ticks);
Blue Swirl's avatar
Blue Swirl committed
914
        } else if (!strcmp(value, "none")) {
915
            /* discard is default */
916
        } else {
917
            error_report("invalid option value '%s'", value);
918 919 920 921 922
            exit(1);
        }
    }
}

923 924 925 926 927
/***********************************************************/
/* Bluetooth support */
static int nb_hcis;
static int cur_hci;
static struct HCIInfo *hci_table[MAX_NICS];
928

929 930 931 932 933 934 935 936
struct HCIInfo *qemu_next_hci(void)
{
    if (cur_hci == nb_hcis)
        return &null_hci;

    return hci_table[cur_hci++];
}

937 938 939
static int bt_hci_parse(const char *str)
{
    struct HCIInfo *hci;
940
    bdaddr_t bdaddr;
941 942

    if (nb_hcis >= MAX_NICS) {
943
        error_report("too many bluetooth HCIs (max %i)", MAX_NICS);
944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968
        return -1;
    }

    hci = hci_init(str);
    if (!hci)
        return -1;

    bdaddr.b[0] = 0x52;
    bdaddr.b[1] = 0x54;
    bdaddr.b[2] = 0x00;
    bdaddr.b[3] = 0x12;
    bdaddr.b[4] = 0x34;
    bdaddr.b[5] = 0x56 + nb_hcis;
    hci->bdaddr_set(hci, bdaddr.b);

    hci_table[nb_hcis++] = hci;

    return 0;
}

static void bt_vhci_add(int vlan_id)
{
    struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id);

    if (!vlan->slave)
969 970
        warn_report("adding a VHCI to an empty scatternet %i",
                    vlan_id);
971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987

    bt_vhci_init(bt_new_hci(vlan));
}

static struct bt_device_s *bt_device_add(const char *opt)
{
    struct bt_scatternet_s *vlan;
    int vlan_id = 0;
    char *endp = strstr(opt, ",vlan=");
    int len = (endp ? endp - opt : strlen(opt)) + 1;
    char devname[10];

    pstrcpy(devname, MIN(sizeof(devname), len), opt);

    if (endp) {
        vlan_id = strtol(endp + 6, &endp, 0);
        if (*endp) {
988
            error_report("unrecognised bluetooth vlan Id");
989 990 991 992 993 994 995
            return 0;
        }
    }

    vlan = qemu_find_bt_vlan(vlan_id);

    if (!vlan->slave)
996 997
        warn_report("adding a slave device to an empty scatternet %i",
                    vlan_id);
998 999 1000 1001

    if (!strcmp(devname, "keyboard"))
        return bt_keyboard_init(vlan);

1002
    error_report("unsupported bluetooth device '%s'", devname);
1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
    return 0;
}

static int bt_parse(const char *opt)
{
    const char *endp, *p;
    int vlan;

    if (strstart(opt, "hci", &endp)) {
        if (!*endp || *endp == ',') {
            if (*endp)
                if (!strstart(endp, ",vlan=", 0))
                    opt = endp + 1;

            return bt_hci_parse(opt);
       }
    } else if (strstart(opt, "vhci", &endp)) {
        if (!*endp || *endp == ',') {
            if (*endp) {
                if (strstart(endp, ",vlan=", &p)) {
                    vlan = strtol(p, (char **) &endp, 0);
                    if (*endp) {
1025
                        error_report("bad scatternet '%s'", p);
1026 1027 1028
                        return 1;
                    }
                } else {
1029
                    error_report("bad parameter '%s'", endp + 1);
1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040
                    return 1;
                }
            } else
                vlan = 0;

            bt_vhci_add(vlan);
            return 0;
        }
    } else if (strstart(opt, "device:", &endp))
        return !bt_device_add(endp);

1041
    error_report("bad bluetooth parameter '%s'", opt);
1042 1043 1044
    return 1;
}

1045
static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp)
1046 1047 1048
{
    if (qemu_opt_get_bool(opts, "enable", false)) {
#ifdef CONFIG_SECCOMP
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066
        uint32_t seccomp_opts = QEMU_SECCOMP_SET_DEFAULT
                | QEMU_SECCOMP_SET_OBSOLETE;
        const char *value = NULL;

        value = qemu_opt_get(opts, "obsolete");
        if (value) {
            if (g_str_equal(value, "allow")) {
                seccomp_opts &= ~QEMU_SECCOMP_SET_OBSOLETE;
            } else if (g_str_equal(value, "deny")) {
                /* this is the default option, this if is here
                 * to provide a little bit of consistency for
                 * the command line */
            } else {
                error_report("invalid argument for obsolete");
                return -1;
            }
        }

1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088
        value = qemu_opt_get(opts, "elevateprivileges");
        if (value) {
            if (g_str_equal(value, "deny")) {
                seccomp_opts |= QEMU_SECCOMP_SET_PRIVILEGED;
            } else if (g_str_equal(value, "children")) {
                seccomp_opts |= QEMU_SECCOMP_SET_PRIVILEGED;

                /* calling prctl directly because we're
                 * not sure if host has CAP_SYS_ADMIN set*/
                if (prctl(PR_SET_NO_NEW_PRIVS, 1)) {
                    error_report("failed to set no_new_privs "
                                 "aborting");
                    return -1;
                }
            } else if (g_str_equal(value, "allow")) {
                /* default value */
            } else {
                error_report("invalid argument for elevateprivileges");
                return -1;
            }
        }

1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100
        value = qemu_opt_get(opts, "spawn");
        if (value) {
            if (g_str_equal(value, "deny")) {
                seccomp_opts |= QEMU_SECCOMP_SET_SPAWN;
            } else if (g_str_equal(value, "allow")) {
                /* default value */
            } else {
                error_report("invalid argument for spawn");
                return -1;
            }
        }

1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112
        value = qemu_opt_get(opts, "resourcecontrol");
        if (value) {
            if (g_str_equal(value, "deny")) {
                seccomp_opts |= QEMU_SECCOMP_SET_RESOURCECTL;
            } else if (g_str_equal(value, "allow")) {
                /* default value */
            } else {
                error_report("invalid argument for resourcecontrol");
                return -1;
            }
        }

1113
        if (seccomp_start(seccomp_opts) < 0) {
1114 1115
            error_report("failed to install seccomp syscall filter "
                         "in the kernel");
1116 1117 1118
            return -1;
        }
#else
1119
        error_report("seccomp support is disabled");
1120 1121 1122 1123 1124 1125 1126
        return -1;
#endif
    }

    return 0;
}

1127
static int parse_name(void *opaque, QemuOpts *opts, Error **errp)
1128 1129 1130
{
    const char *proc_name;

1131 1132 1133
    if (qemu_opt_get(opts, "debug-threads")) {
        qemu_thread_naming(qemu_opt_get_bool(opts, "debug-threads", false));
    }
1134 1135 1136 1137 1138 1139
    qemu_name = qemu_opt_get(opts, "guest");

    proc_name = qemu_opt_get(opts, "process");
    if (proc_name) {
        os_set_proc_name(proc_name);
    }
1140 1141

    return 0;
1142 1143
}

1144 1145 1146 1147 1148
bool defaults_enabled(void)
{
    return has_defaults;
}

1149
#ifndef _WIN32
1150
static int parse_add_fd(void *opaque, QemuOpts *opts, Error **errp)
1151 1152 1153 1154
{
    int fd, dupfd, flags;
    int64_t fdset_id;
    const char *fd_opaque = NULL;
1155
    AddfdInfo *fdinfo;
1156 1157 1158 1159 1160 1161

    fd = qemu_opt_get_number(opts, "fd", -1);
    fdset_id = qemu_opt_get_number(opts, "set", -1);
    fd_opaque = qemu_opt_get(opts, "opaque");

    if (fd < 0) {
1162
        error_report("fd option is required and must be non-negative");
1163 1164 1165 1166
        return -1;
    }

    if (fd <= STDERR_FILENO) {
1167
        error_report("fd cannot be a standard I/O stream");
1168 1169 1170 1171 1172 1173 1174 1175 1176
        return -1;
    }

    /*
     * All fds inherited across exec() necessarily have FD_CLOEXEC
     * clear, while qemu sets FD_CLOEXEC on all other fds used internally.
     */
    flags = fcntl(fd, F_GETFD);
    if (flags == -1 || (flags & FD_CLOEXEC)) {
1177
        error_report("fd is not valid or already in use");
1178 1179 1180 1181
        return -1;
    }

    if (fdset_id < 0) {
1182
        error_report("set option is required and must be non-negative");
1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194
        return -1;
    }

#ifdef F_DUPFD_CLOEXEC
    dupfd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
#else
    dupfd = dup(fd);
    if (dupfd != -1) {
        qemu_set_cloexec(dupfd);
    }
#endif
    if (dupfd == -1) {
1195
        error_report("error duplicating fd: %s", strerror(errno));
1196 1197 1198 1199
        return -1;
    }

    /* add the duplicate fd, and optionally the opaque string, to the fd set */
1200 1201 1202
    fdinfo = monitor_fdset_add_fd(dupfd, true, fdset_id, !!fd_opaque, fd_opaque,
                                  &error_abort);
    g_free(fdinfo);
1203 1204 1205 1206

    return 0;
}

1207
static int cleanup_add_fd(void *opaque, QemuOpts *opts, Error **errp)
1208 1209 1210 1211 1212 1213 1214 1215 1216 1217
{
    int fd;

    fd = qemu_opt_get_number(opts, "fd", -1);
    close(fd);

    return 0;
}
#endif

1218 1219 1220
/***********************************************************/
/* QEMU Block devices */

1221 1222 1223 1224 1225 1226
#define HD_OPTS "media=disk"
#define CDROM_OPTS "media=cdrom"
#define FD_OPTS ""
#define PFLASH_OPTS ""
#define MTD_OPTS ""
#define SD_OPTS ""
1227

1228
static int drive_init_func(void *opaque, QemuOpts *opts, Error **errp)
1229
{
1230
    BlockInterfaceType *block_default_type = opaque;
1231

1232
    return drive_new(opts, *block_default_type) == NULL;
1233 1234
}

1235
static int drive_enable_snapshot(void *opaque, QemuOpts *opts, Error **errp)
1236
{
1237
    if (qemu_opt_get(opts, "snapshot") == NULL) {
1238
        qemu_opt_set(opts, "snapshot", "on", &error_abort);
1239 1240 1241 1242
    }
    return 0;
}

1243 1244
static void default_drive(int enable, int snapshot, BlockInterfaceType type,
                          int index, const char *optstr)
1245 1246
{
    QemuOpts *opts;
1247
    DriveInfo *dinfo;
1248 1249 1250 1251 1252 1253 1254

    if (!enable || drive_get_by_index(type, index)) {
        return;
    }

    opts = drive_add(type, index, NULL, optstr);
    if (snapshot) {
1255
        drive_enable_snapshot(NULL, opts, NULL);
1256
    }
1257 1258 1259

    dinfo = drive_new(opts, type);
    if (!dinfo) {
1260 1261
        exit(1);
    }
1262 1263
    dinfo->is_default = true;

1264 1265
}

1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292
static QemuOptsList qemu_smp_opts = {
    .name = "smp-opts",
    .implied_opt_name = "cpus",
    .merge_lists = true,
    .head = QTAILQ_HEAD_INITIALIZER(qemu_smp_opts.head),
    .desc = {
        {
            .name = "cpus",
            .type = QEMU_OPT_NUMBER,
        }, {
            .name = "sockets",
            .type = QEMU_OPT_NUMBER,
        }, {
            .name = "cores",
            .type = QEMU_OPT_NUMBER,
        }, {
            .name = "threads",
            .type = QEMU_OPT_NUMBER,
        }, {
            .name = "maxcpus",
            .type = QEMU_OPT_NUMBER,
        },
        { /*End of list */ }
    },
};

static void smp_parse(QemuOpts *opts)
1293
{
1294 1295 1296 1297 1298 1299 1300 1301 1302 1303
    if (opts) {
        unsigned cpus    = qemu_opt_get_number(opts, "cpus", 0);
        unsigned sockets = qemu_opt_get_number(opts, "sockets", 0);
        unsigned cores   = qemu_opt_get_number(opts, "cores", 0);
        unsigned threads = qemu_opt_get_number(opts, "threads", 0);

        /* compute missing values, prefer sockets over cores over threads */
        if (cpus == 0 || sockets == 0) {
            sockets = sockets > 0 ? sockets : 1;
            cores = cores > 0 ? cores : 1;
1304
            threads = threads > 0 ? threads : 1;
1305 1306 1307
            if (cpus == 0) {
                cpus = cores * threads * sockets;
            }
1308 1309 1310
        } else if (cores == 0) {
            threads = threads > 0 ? threads : 1;
            cores = cpus / (sockets * threads);
1311
            cores = cores > 0 ? cores : 1;
1312
        } else if (threads == 0) {
1313
            threads = cpus / (cores * sockets);
1314
            threads = threads > 0 ? threads : 1;
1315
        } else if (sockets * cores * threads < cpus) {
1316 1317 1318 1319
            error_report("cpu topology: "
                         "sockets (%u) * cores (%u) * threads (%u) < "
                         "smp_cpus (%u)",
                         sockets, cores, threads, cpus);
1320
            exit(1);
1321
        }
1322

1323
        max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus);
Andrew Jones's avatar
Andrew Jones committed
1324 1325 1326 1327 1328 1329

        if (max_cpus < cpus) {
            error_report("maxcpus must be equal to or greater than smp");
            exit(1);
        }

1330
        if (sockets * cores * threads > max_cpus) {
1331 1332 1333 1334
            error_report("cpu topology: "
                         "sockets (%u) * cores (%u) * threads (%u) > "
                         "maxcpus (%u)",
                         sockets, cores, threads, max_cpus);
1335 1336
            exit(1);
        }
1337 1338

        smp_cpus = cpus;
Andrew Jones's avatar
Andrew Jones committed
1339 1340
        smp_cores = cores;
        smp_threads = threads;
1341 1342
    }

Andrew Jones's avatar
Andrew Jones committed
1343
    if (smp_cpus > 1) {
1344 1345 1346 1347
        Error *blocker = NULL;
        error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp");
        replay_add_blocker(blocker);
    }
1348 1349
}

1350
static void realtime_init(void)
1351 1352 1353
{
    if (enable_mlock) {
        if (os_mlock() < 0) {
1354
            error_report("locking memory failed");
1355 1356 1357 1358 1359
            exit(1);
        }
    }
}

1360 1361 1362 1363 1364 1365

static void configure_msg(QemuOpts *opts)
{
    enable_timestamp_msg = qemu_opt_get_bool(opts, "timestamp", true);
}

1366 1367 1368 1369 1370 1371
/***********************************************************/
/* Semihosting */

typedef struct SemihostingConfig {
    bool enabled;
    SemihostingTarget target;
1372 1373 1374
    const char **argv;
    int argc;
    const char *cmdline; /* concatenated argv */
1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388
} SemihostingConfig;

static SemihostingConfig semihosting;

bool semihosting_enabled(void)
{
    return semihosting.enabled;
}

SemihostingTarget semihosting_get_target(void)
{
    return semihosting.target;