.type = QEMU_OPT_STRING,
.help = "Sets the name of the file from which\n"
"the fw_cfg blob will be loaded",
+ }, {
+ .name = "string",
+ .type = QEMU_OPT_STRING,
+ .help = "Sets content of the blob to be inserted from a string",
},
{ /* end of list */ }
},
static void res_free(void)
{
- if (boot_splash_filedata != NULL) {
- g_free(boot_splash_filedata);
- boot_splash_filedata = NULL;
- }
+ g_free(boot_splash_filedata);
+ boot_splash_filedata = NULL;
}
static int default_driver_check(void *opaque, QemuOpts *opts, Error **errp)
{ RUN_STATE_INMIGRATE, RUN_STATE_SUSPENDED },
{ RUN_STATE_INMIGRATE, RUN_STATE_WATCHDOG },
{ RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED },
+ { RUN_STATE_INMIGRATE, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED },
{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE },
exit(1);
}
- max_cpus = qemu_opt_get_number(opts, "maxcpus", 0);
+ max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus);
+ if (sockets * cores * threads > max_cpus) {
+ fprintf(stderr, "cpu topology: error: "
+ "sockets (%u) * cores (%u) * threads (%u) > maxcpus (%u)\n",
+ sockets, cores, threads, max_cpus);
+ exit(1);
+ }
smp_cpus = cpus;
smp_cores = cores > 0 ? cores : 1;
MachineState *current_machine;
-/*
- * Transitional class registration/init used for converting from
- * legacy QEMUMachine to MachineClass.
- */
-static void qemu_machine_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
- QEMUMachine *qm = data;
- mc->name = qm->name;
- mc->desc = qm->desc;
- mc->init = qm->init;
- mc->kvm_type = qm->kvm_type;
- mc->block_default_type = qm->block_default_type;
- mc->max_cpus = qm->max_cpus;
- mc->no_sdcard = qm->no_sdcard;
- mc->has_dynamic_sysbus = qm->has_dynamic_sysbus;
- mc->is_default = qm->is_default;
- mc->default_machine_opts = qm->default_machine_opts;
- mc->default_boot_order = qm->default_boot_order;
-}
-
-int qemu_register_machine(QEMUMachine *m)
-{
- char *name = g_strconcat(m->name, TYPE_MACHINE_SUFFIX, NULL);
- TypeInfo ti = {
- .name = name,
- .parent = TYPE_MACHINE,
- .class_init = qemu_machine_class_init,
- .class_data = (void *)m,
- };
-
- type_register(&ti);
- g_free(name);
-
- return 0;
-}
-
static MachineClass *find_machine(const char *name)
{
GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
cpu_synchronize_all_post_reset();
}
+void qemu_system_guest_panicked(void)
+{
+ if (current_cpu) {
+ current_cpu->crash_occurred = true;
+ }
+ qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, &error_abort);
+ vm_stop(RUN_STATE_GUEST_PANICKED);
+}
+
void qemu_system_reset_request(void)
{
if (no_reboot) {
return NULL;
}
+static inline bool nonempty_str(const char *str)
+{
+ return str && *str;
+}
+
static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
{
gchar *buf;
size_t size;
- const char *name, *file;
+ const char *name, *file, *str;
if (opaque == NULL) {
error_report("fw_cfg device not available");
}
name = qemu_opt_get(opts, "name");
file = qemu_opt_get(opts, "file");
- if (name == NULL || *name == '\0' || file == NULL || *file == '\0') {
- error_report("invalid argument value");
+ str = qemu_opt_get(opts, "string");
+
+ /* we need name and either a file or the content string */
+ if (!(nonempty_str(name) && (nonempty_str(file) || nonempty_str(str)))) {
+ error_report("invalid argument(s)");
+ return -1;
+ }
+ if (nonempty_str(file) && nonempty_str(str)) {
+ error_report("file and string are mutually exclusive");
return -1;
}
if (strlen(name) > FW_CFG_MAX_FILE_PATH - 1) {
error_report("WARNING: externally provided fw_cfg item names "
"should be prefixed with \"opt/\"!");
}
- if (!g_file_get_contents(file, &buf, &size, NULL)) {
- error_report("can't load %s", file);
- return -1;
+ if (nonempty_str(str)) {
+ size = strlen(str); /* NUL terminator NOT included in fw_cfg blob */
+ buf = g_memdup(str, size);
+ } else {
+ if (!g_file_get_contents(file, &buf, &size, NULL)) {
+ error_report("can't load %s", file);
+ return -1;
+ }
}
fw_cfg_add_file((FWCfgState *)opaque, name, buf, size);
return 0;
return popt;
}
-static gpointer malloc_and_trace(gsize n_bytes)
-{
- void *ptr = malloc(n_bytes);
- trace_g_malloc(n_bytes, ptr);
- return ptr;
-}
-
-static gpointer realloc_and_trace(gpointer mem, gsize n_bytes)
-{
- void *ptr = realloc(mem, n_bytes);
- trace_g_realloc(mem, n_bytes, ptr);
- return ptr;
-}
-
-static void free_and_trace(gpointer mem)
-{
- trace_g_free(mem);
- free(mem);
-}
-
static int machine_set_property(void *opaque,
const char *name, const char *value,
Error **errp)
if (g_str_equal(type, "rng-egd")) {
return false;
}
+
+ if (g_str_equal(type, "filter-buffer")) {
+ return false;
+ }
+
return true;
}
/*
* The remainder of object creation happens after the
- * creation of chardev, fsdev and device data types.
+ * creation of chardev, fsdev, net clients and device data types.
*/
static bool object_create_delayed(const char *type)
{
bool userconfig = true;
const char *log_mask = NULL;
const char *log_file = NULL;
- GMemVTable mem_trace = {
- .malloc = malloc_and_trace,
- .realloc = realloc_and_trace,
- .free = free_and_trace,
- };
const char *trace_events = NULL;
const char *trace_file = NULL;
ram_addr_t maxram_size;
error_set_progname(argv[0]);
qemu_init_exec_dir(argv[0]);
- g_mem_set_vtable(&mem_trace);
-
module_call_init(MODULE_INIT_QOM);
qemu_add_opts(&qemu_drive_opts);
exit(0);
}
- if (qemu_opts_foreach(qemu_find_opts("object"),
- object_create,
- object_create_delayed, NULL)) {
- exit(1);
- }
-
machine_opts = qemu_get_machine_opts();
if (qemu_opt_foreach(machine_opts, machine_set_property, current_machine,
NULL)) {
exit(1);
}
+ if (qemu_opts_foreach(qemu_find_opts("object"),
+ object_create,
+ object_create_delayed, NULL)) {
+ exit(1);
+ }
+
#ifdef CONFIG_TPM
if (tpm_init() < 0) {
exit(1);