#include "qemu/sockets.h"
#include "hw/hw.h"
#include "hw/boards.h"
+#include "sysemu/accel.h"
#include "hw/usb.h"
#include "hw/pcmcia.h"
#include "hw/i386/pc.h"
#include "qemu/timer.h"
#include "sysemu/char.h"
#include "qemu/bitmap.h"
-#include "qemu/cache-utils.h"
#include "sysemu/blockdev.h"
#include "hw/block/block.h"
#include "migration/block.h"
ram_addr_t ram_size;
const char *mem_path = NULL;
int mem_prealloc = 0; /* force preallocation of physical target memory */
+bool enable_mlock = false;
int nb_nics;
NICInfo nd_table[MAX_NICS];
int autostart;
size_t boot_splash_filedata_size;
uint8_t qemu_extra_params_fw[2];
+int icount_align_option;
typedef struct FWBootEntry FWBootEntry;
struct FWBootEntry {
QTAILQ_HEAD_INITIALIZER(fw_boot_order);
int nb_numa_nodes;
+int max_numa_nodeid;
NodeInfo numa_info[MAX_NODES];
uint8_t qemu_uuid[16];
static NotifierList machine_init_done_notifiers =
NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);
-static bool tcg_allowed = true;
bool xen_allowed;
uint32_t xen_domid;
enum xen_mode xen_mode = XEN_EMULATE;
-static int tcg_tb_size;
static int has_defaults = 1;
static int default_serial = 1;
.name = "kvm-type",
.type = QEMU_OPT_STRING,
.help = "Specifies the KVM virtualization mode (HV, PR)",
+ },{
+ .name = PC_MACHINE_MAX_RAM_BELOW_4G,
+ .type = QEMU_OPT_SIZE,
+ .help = "maximum ram below the 4G boundary (32bit boundary)",
+ },{
+ .name = "iommu",
+ .type = QEMU_OPT_BOOL,
+ .help = "Set on/off to enable/disable Intel IOMMU (VT-d)",
},
{ /* End of list */ }
},
},
};
+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,
+ }, {
+ .name = "align",
+ .type = QEMU_OPT_BOOL,
+ },
+ { /* end of list */ }
+ },
+};
+
/**
* Get machine options
*
static int drive_enable_snapshot(QemuOpts *opts, void *opaque)
{
- if (NULL == qemu_opt_get(opts, "snapshot")) {
+ if (qemu_opt_get(opts, "snapshot") == NULL) {
qemu_opt_set(opts, "snapshot", "on");
}
return 0;
}
-static void configure_realtime(QemuOpts *opts)
+static void realtime_init(void)
{
- bool enable_mlock;
-
- enable_mlock = qemu_opt_get_bool(opts, "mlock", true);
-
if (enable_mlock) {
if (os_mlock() < 0) {
fprintf(stderr, "qemu: locking memory failed\n");
void vm_state_notify(int running, RunState state)
{
- VMChangeStateEntry *e;
+ VMChangeStateEntry *e, *next;
trace_vm_state_notify(running, state);
- for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
+ QLIST_FOREACH_SAFE(e, &vm_change_state_head, entries, next) {
e->cb(e->opaque, running, state);
}
}
void qemu_system_shutdown_request(void)
{
+ trace_qemu_system_shutdown_request();
shutdown_requested = 1;
qemu_notify_event();
}
void qemu_system_powerdown_request(void)
{
+ trace_qemu_system_powerdown_request();
powerdown_requested = 1;
qemu_notify_event();
}
loc_push_restore(&conf->loc);
rc = func(conf->cmdline);
loc_pop(&conf->loc);
- if (0 != rc)
+ if (rc) {
return rc;
+ }
}
return 0;
}
exit(!name || !is_help_option(name));
}
-static int tcg_init(MachineClass *mc)
-{
- tcg_exec_init(tcg_tb_size * 1024 * 1024);
- return 0;
-}
-
-static struct {
- const char *opt_name;
- const char *name;
- int (*available)(void);
- int (*init)(MachineClass *mc);
- bool *allowed;
-} accel_list[] = {
- { "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed },
- { "xen", "Xen", xen_available, xen_init, &xen_allowed },
- { "kvm", "KVM", kvm_available, kvm_init, &kvm_allowed },
- { "qtest", "QTest", qtest_available, qtest_init_accel, &qtest_allowed },
-};
-
-static int configure_accelerator(MachineClass *mc)
-{
- const char *p;
- char buf[10];
- int i, ret;
- bool accel_initialised = false;
- bool init_failed = false;
-
- p = qemu_opt_get(qemu_get_machine_opts(), "accel");
- if (p == NULL) {
- /* Use the default "accelerator", tcg */
- p = "tcg";
- }
-
- while (!accel_initialised && *p != '\0') {
- if (*p == ':') {
- p++;
- }
- p = get_opt_name(buf, sizeof (buf), p, ':');
- for (i = 0; i < ARRAY_SIZE(accel_list); i++) {
- if (strcmp(accel_list[i].opt_name, buf) == 0) {
- if (!accel_list[i].available()) {
- printf("%s not supported for this target\n",
- accel_list[i].name);
- break;
- }
- *(accel_list[i].allowed) = true;
- ret = accel_list[i].init(mc);
- if (ret < 0) {
- init_failed = true;
- fprintf(stderr, "failed to initialize %s: %s\n",
- accel_list[i].name,
- strerror(-ret));
- *(accel_list[i].allowed) = false;
- } else {
- accel_initialised = true;
- }
- break;
- }
- }
- if (i == ARRAY_SIZE(accel_list)) {
- fprintf(stderr, "\"%s\" accelerator does not exist.\n", buf);
- }
- }
-
- if (!accel_initialised) {
- if (!init_failed) {
- fprintf(stderr, "No accelerator found!\n");
- }
- exit(1);
- }
-
- if (init_failed) {
- fprintf(stderr, "Back to %s accelerator.\n", accel_list[i].name);
- }
-
- return !accel_initialised;
-}
-
void qemu_add_exit_notifier(Notifier *notify)
{
notifier_list_add(&exit_notifiers, notify);
free(mem);
}
-static int object_set_property(const char *name, const char *value, void *opaque)
+static int machine_set_property(const char *name, const char *value,
+ void *opaque)
{
Object *obj = OBJECT(opaque);
StringInputVisitor *siv;
Error *local_err = NULL;
+ char *c, *qom_name;
- if (strcmp(name, "qom-type") == 0 || strcmp(name, "id") == 0 ||
- strcmp(name, "type") == 0) {
+ if (strcmp(name, "type") == 0) {
return 0;
}
+ qom_name = g_strdup(name);
+ c = qom_name;
+ while (*c++) {
+ if (*c == '_') {
+ *c = '-';
+ }
+ }
+
siv = string_input_visitor_new(value);
- object_property_set(obj, string_input_get_visitor(siv), name, &local_err);
+ object_property_set(obj, string_input_get_visitor(siv), qom_name, &local_err);
string_input_visitor_cleanup(siv);
+ g_free(qom_name);
if (local_err) {
qerror_report_err(local_err);
g_free(dummy);
if (err) {
qerror_report_err(err);
+ error_free(err);
return -1;
}
return 0;
{
int i;
int snapshot, linux_boot;
- const char *icount_option = NULL;
const char *initrd_filename;
const char *kernel_filename, *kernel_cmdline;
const char *boot_order;
DisplayState *ds;
int cyls, heads, secs, translation;
- QemuOpts *hda_opts = NULL, *opts, *machine_opts;
+ QemuOpts *hda_opts = NULL, *opts, *machine_opts, *icount_opts = NULL;
QemuOptsList *olist;
int optind;
const char *optarg;
1024 * 1024;
ram_addr_t maxram_size = default_ram_size;
uint64_t ram_slots = 0;
+ FILE *vmstate_dump_file = NULL;
+ Error *main_loop_err = NULL;
atexit(qemu_run_exit_notifiers);
error_set_progname(argv[0]);
qemu_add_opts(&qemu_msg_opts);
qemu_add_opts(&qemu_name_opts);
qemu_add_opts(&qemu_numa_opts);
+ qemu_add_opts(&qemu_icount_opts);
runstate_init();
rtc_clock = QEMU_CLOCK_HOST;
- qemu_init_auxval(envp);
- qemu_cache_utils_init();
-
QLIST_INIT (&vm_change_state_head);
os_setup_early_signal_handling();
for (i = 0; i < MAX_NODES; i++) {
numa_info[i].node_mem = 0;
+ numa_info[i].present = false;
bitmap_zero(numa_info[i].node_cpu, MAX_CPUMASK_BITS);
}
nb_numa_nodes = 0;
+ max_numa_nodeid = 0;
nb_nics = 0;
bdrv_init_with_whitelist();
error_report("ram size too large");
exit(EXIT_FAILURE);
}
+ maxram_size = ram_size;
maxmem_str = qemu_opt_get(opts, "maxmem");
slots_str = qemu_opt_get(opts, "slots");
sz = qemu_opt_get_size(opts, "maxmem", 0);
if (sz < ram_size) {
- fprintf(stderr, "qemu: invalid -m option value: maxmem "
- "(%" PRIu64 ") <= initial memory ("
- RAM_ADDR_FMT ")\n", sz, ram_size);
+ error_report("invalid -m option value: maxmem "
+ "(0x%" PRIx64 ") <= initial memory (0x"
+ RAM_ADDR_FMT ")", sz, ram_size);
exit(EXIT_FAILURE);
}
slots = qemu_opt_get_number(opts, "slots", 0);
if ((sz > ram_size) && !slots) {
- fprintf(stderr, "qemu: invalid -m option value: maxmem "
- "(%" PRIu64 ") more than initial memory ("
+ error_report("invalid -m option value: maxmem "
+ "(0x%" PRIx64 ") more than initial memory (0x"
RAM_ADDR_FMT ") but no hotplug slots where "
- "specified\n", sz, ram_size);
+ "specified", sz, ram_size);
exit(EXIT_FAILURE);
}
if ((sz <= ram_size) && slots) {
- fprintf(stderr, "qemu: invalid -m option value: %"
+ error_report("invalid -m option value: %"
PRIu64 " hotplug slots where specified but "
- "maxmem (%" PRIu64 ") <= initial memory ("
- RAM_ADDR_FMT ")\n", slots, sz, ram_size);
+ "maxmem (0x%" PRIx64 ") <= initial memory (0x"
+ RAM_ADDR_FMT ")", slots, sz, ram_size);
exit(EXIT_FAILURE);
}
maxram_size = sz;
ram_slots = slots;
} else if ((!maxmem_str && slots_str) ||
(maxmem_str && !slots_str)) {
- fprintf(stderr, "qemu: invalid -m option value: missing "
- "'%s' option\n", slots_str ? "maxmem" : "slots");
+ error_report("invalid -m option value: missing "
+ "'%s' option", slots_str ? "maxmem" : "slots");
exit(EXIT_FAILURE);
}
break;
}
break;
case QEMU_OPTION_icount:
- icount_option = optarg;
+ icount_opts = qemu_opts_parse(qemu_find_opts("icount"),
+ optarg, 1);
+ if (!icount_opts) {
+ exit(1);
+ }
break;
case QEMU_OPTION_incoming:
incoming = optarg;
if (!opts) {
exit(1);
}
- configure_realtime(opts);
+ enable_mlock = qemu_opt_get_bool(opts, "mlock", true);
break;
case QEMU_OPTION_msg:
opts = qemu_opts_parse(qemu_find_opts("msg"), optarg, 0);
}
configure_msg(opts);
break;
+ case QEMU_OPTION_dump_vmstate:
+ vmstate_dump_file = fopen(optarg, "w");
+ if (vmstate_dump_file == NULL) {
+ fprintf(stderr, "open %s: %s\n", optarg, strerror(errno));
+ exit(1);
+ }
+ break;
default:
os_parse_cmd_args(popt->index, optarg);
}
os_daemonize();
- if (qemu_init_main_loop()) {
- fprintf(stderr, "qemu_init_main_loop failed\n");
+ if (qemu_init_main_loop(&main_loop_err)) {
+ error_report("%s", error_get_pretty(main_loop_err));
exit(1);
}
exit(1);
}
- cpu_exec_init_all();
-
current_machine = MACHINE(object_new(object_class_get_name(
OBJECT_CLASS(machine_class))));
object_property_add_child(object_get_root(), "machine",
OBJECT(current_machine), &error_abort);
+ cpu_exec_init_all();
if (machine_class->hw_version) {
qemu_set_version(machine_class->hw_version);
}
- if (qemu_opts_foreach(qemu_find_opts("object"),
- object_create, NULL, 0) != 0) {
- exit(1);
- }
-
/* Init CPU def lists, based on config
* - Must be called after all the qemu_read_config_file() calls
* - Must be called before list_cpus()
exit(0);
}
+ if (qemu_opts_foreach(qemu_find_opts("object"),
+ object_create, NULL, 0) != 0) {
+ exit(1);
+ }
+
machine_opts = qemu_get_machine_opts();
- if (qemu_opt_foreach(machine_opts, object_set_property, current_machine,
+ if (qemu_opt_foreach(machine_opts, machine_set_property, current_machine,
1) < 0) {
object_unref(OBJECT(current_machine));
exit(1);
qemu_spice_init();
#endif
- if (icount_option && (kvm_enabled() || xen_enabled())) {
- fprintf(stderr, "-icount is not allowed with kvm or xen\n");
- exit(1);
+ cpu_ticks_init();
+ if (icount_opts) {
+ if (kvm_enabled() || xen_enabled()) {
+ fprintf(stderr, "-icount is not allowed with kvm or xen\n");
+ exit(1);
+ }
+ configure_icount(icount_opts, &error_abort);
+ qemu_opts_del(icount_opts);
}
- configure_icount(icount_option);
/* clean up network at qemu process termination */
atexit(&net_cleanup);
machine_class->init(current_machine);
+ realtime_init();
+
audio_init();
cpu_synchronize_all_post_init();
}
}
- qdev_prop_check_global();
+ qdev_prop_check_globals();
+ if (vmstate_dump_file) {
+ /* dump and exit */
+ dump_vmstate_json_to_file(vmstate_dump_file);
+ return 0;
+ }
if (incoming) {
Error *local_err = NULL;