aboutsummaryrefslogtreecommitdiff
path: root/vl.c
diff options
context:
space:
mode:
authorLinaro Packagers <linaro-pkg@lists.launchpad.net>2013-08-02 06:39:45 +0000
committerFathi Boudra <fathi.boudra@linaro.org>2013-08-05 10:19:57 +0300
commit3ba5745389cb428bf0f99fdde92ed3876ca5e5c8 (patch)
tree06dc0389b02c64ce9cb23cad85382745c0d6177c /vl.c
parentc3565b8703553405641c76a4c40961473d051edd (diff)
parent86342dcc9b73eac8310b9dc5fd1356bbfa5b9c8e (diff)
Imported Debian patch 1.5.0-2013.06+git74+20130802+ef1b0ae-3linaroraring1HEADmaster
Diffstat (limited to 'vl.c')
-rw-r--r--vl.c330
1 files changed, 213 insertions, 117 deletions
diff --git a/vl.c b/vl.c
index 1355f69..59dc0b4 100644
--- a/vl.c
+++ b/vl.c
@@ -117,16 +117,16 @@ int main(int argc, char **argv)
#include "hw/boards.h"
#include "hw/usb.h"
#include "hw/pcmcia.h"
-#include "hw/pc.h"
-#include "hw/isa.h"
-#include "hw/baum.h"
+#include "hw/i386/pc.h"
+#include "hw/isa/isa.h"
#include "hw/bt.h"
-#include "hw/watchdog.h"
-#include "hw/smbios.h"
-#include "hw/xen.h"
+#include "sysemu/watchdog.h"
+#include "hw/i386/smbios.h"
+#include "hw/xen/xen.h"
#include "hw/qdev.h"
#include "hw/loader.h"
-#include "bt/bt.h"
+#include "monitor/qdev.h"
+#include "sysemu/bt.h"
#include "net/net.h"
#include "net/slirp.h"
#include "monitor/monitor.h"
@@ -134,11 +134,12 @@ int main(int argc, char **argv)
#include "sysemu/sysemu.h"
#include "exec/gdbstub.h"
#include "qemu/timer.h"
-#include "char/char.h"
+#include "sysemu/char.h"
#include "qemu/cache-utils.h"
#include "sysemu/blockdev.h"
-#include "hw/block-common.h"
+#include "hw/block/block.h"
#include "migration/block.h"
+#include "sysemu/tpm.h"
#include "sysemu/dma.h"
#include "audio/audio.h"
#include "migration/migration.h"
@@ -178,7 +179,8 @@ int main(int argc, char **argv)
#define MAX_VIRTIO_CONSOLES 1
#define MAX_SCLP_CONSOLES 1
-static const char *data_dir;
+static const char *data_dir[16];
+static int data_dir_idx;
const char *bios_name = NULL;
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
DisplayType display_type = DT_DEFAULT;
@@ -232,6 +234,7 @@ int ctrl_grab = 0;
unsigned int nb_prom_envs = 0;
const char *prom_envs[MAX_PROM_ENVS];
int boot_menu;
+bool boot_strict;
uint8_t *boot_splash_filedata;
size_t boot_splash_filedata_size;
uint8_t qemu_extra_params_fw[2];
@@ -264,7 +267,6 @@ static NotifierList machine_init_done_notifiers =
NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);
static bool tcg_allowed = true;
-bool kvm_allowed;
bool xen_allowed;
uint32_t xen_domid;
enum xen_mode xen_mode = XEN_EMULATE;
@@ -456,6 +458,9 @@ static QemuOptsList qemu_boot_opts = {
}, {
.name = "reboot-timeout",
.type = QEMU_OPT_STRING,
+ }, {
+ .name = "strict",
+ .type = QEMU_OPT_STRING,
},
{ /*End of list */ }
},
@@ -491,6 +496,28 @@ static QemuOptsList qemu_object_opts = {
},
};
+static QemuOptsList qemu_tpmdev_opts = {
+ .name = "tpmdev",
+ .implied_opt_name = "type",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_tpmdev_opts.head),
+ .desc = {
+ /* options are defined in the TPM backends */
+ { /* end of list */ }
+ },
+};
+
+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 */ }
+ },
+};
+
const char *qemu_get_vm_name(void)
{
return qemu_name;
@@ -566,6 +593,7 @@ static const RunStateTransition runstate_transitions_def[] = {
{ RUN_STATE_RUNNING, RUN_STATE_SAVE_VM },
{ RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN },
{ RUN_STATE_RUNNING, RUN_STATE_WATCHDOG },
+ { RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED },
{ RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
@@ -580,6 +608,9 @@ static const RunStateTransition runstate_transitions_def[] = {
{ RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
{ RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
+ { RUN_STATE_GUEST_PANICKED, RUN_STATE_PAUSED },
+ { RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
+
{ RUN_STATE_MAX, RUN_STATE_MAX },
};
@@ -612,7 +643,7 @@ void runstate_set(RunState new_state)
RunState_lookup[new_state]);
abort();
}
-
+ trace_runstate_set(new_state);
current_run_state = new_state;
}
@@ -621,6 +652,13 @@ int runstate_is_running(void)
return runstate_check(RUN_STATE_RUNNING);
}
+bool runstate_needs_reset(void)
+{
+ return runstate_check(RUN_STATE_INTERNAL_ERROR) ||
+ runstate_check(RUN_STATE_SHUTDOWN) ||
+ runstate_check(RUN_STATE_GUEST_PANICKED);
+}
+
StatusInfo *qmp_query_status(Error **errp)
{
StatusInfo *info = g_malloc0(sizeof(*info));
@@ -1178,7 +1216,7 @@ void add_boot_device_path(int32_t bootindex, DeviceState *dev,
node = g_malloc0(sizeof(FWBootEntry));
node->bootindex = bootindex;
- node->suffix = suffix ? g_strdup(suffix) : NULL;
+ node->suffix = g_strdup(suffix);
node->dev = dev;
QTAILQ_FOREACH(i, &fw_boot_order, link) {
@@ -1194,6 +1232,24 @@ void add_boot_device_path(int32_t bootindex, DeviceState *dev,
QTAILQ_INSERT_TAIL(&fw_boot_order, node, link);
}
+DeviceState *get_boot_device(uint32_t position)
+{
+ uint32_t counter = 0;
+ FWBootEntry *i = NULL;
+ DeviceState *res = NULL;
+
+ if (!QTAILQ_EMPTY(&fw_boot_order)) {
+ QTAILQ_FOREACH(i, &fw_boot_order, link) {
+ if (counter == position) {
+ res = i->dev;
+ break;
+ }
+ counter++;
+ }
+ }
+ return res;
+}
+
/*
* This function returns null terminated string that consist of new line
* separated device paths.
@@ -1241,6 +1297,12 @@ char *get_boot_devices_list(size_t *size)
*size = total;
+ if (boot_strict && *size > 0) {
+ list[total-1] = '\n';
+ list = g_realloc(list, total + 5);
+ memcpy(&list[total], "HALT", 5);
+ *size = total + 5;
+ }
return list;
}
@@ -1384,6 +1446,20 @@ static void smp_parse(const char *optarg)
max_cpus = smp_cpus;
}
+static void configure_realtime(QemuOpts *opts)
+{
+ 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");
+ exit(1);
+ }
+ }
+}
+
/***********************************************************/
/* USB devices */
@@ -1427,8 +1503,9 @@ static int usb_device_del(const char *devname)
int bus_num, addr;
const char *p;
- if (strstart(devname, "host:", &p))
- return usb_host_device_close(p);
+ if (strstart(devname, "host:", &p)) {
+ return -1;
+ }
if (!usb_enabled(false)) {
return -1;
@@ -1575,6 +1652,7 @@ MachineInfoList *qmp_query_machines(Error **errp)
}
info->name = g_strdup(m->name);
+ info->cpu_max = !m->max_cpus ? 1 : m->max_cpus;
entry = g_malloc0(sizeof(*entry));
entry->value = info;
@@ -1588,55 +1666,6 @@ MachineInfoList *qmp_query_machines(Error **errp)
/***********************************************************/
/* main execution loop */
-static void gui_update(void *opaque)
-{
- uint64_t interval = GUI_REFRESH_INTERVAL;
- DisplayState *ds = opaque;
- DisplayChangeListener *dcl;
-
- dpy_refresh(ds);
-
- QLIST_FOREACH(dcl, &ds->listeners, next) {
- if (dcl->gui_timer_interval &&
- dcl->gui_timer_interval < interval)
- interval = dcl->gui_timer_interval;
- }
- qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock_ms(rt_clock));
-}
-
-void gui_setup_refresh(DisplayState *ds)
-{
- DisplayChangeListener *dcl;
- bool need_timer = false;
- bool have_gfx = false;
- bool have_text = false;
-
- QLIST_FOREACH(dcl, &ds->listeners, next) {
- if (dcl->dpy_refresh != NULL) {
- need_timer = true;
- }
- if (dcl->dpy_gfx_update != NULL) {
- have_gfx = true;
- }
- if (dcl->dpy_text_update != NULL) {
- have_text = true;
- }
- }
-
- if (need_timer && ds->gui_timer == NULL) {
- ds->gui_timer = qemu_new_timer_ms(rt_clock, gui_update, ds);
- qemu_mod_timer(ds->gui_timer, qemu_get_clock_ms(rt_clock));
- }
- if (!need_timer && ds->gui_timer != NULL) {
- qemu_del_timer(ds->gui_timer);
- qemu_free_timer(ds->gui_timer);
- ds->gui_timer = NULL;
- }
-
- ds->have_gfx = have_gfx;
- ds->have_text = have_text;
-}
-
struct vm_change_state_entry {
VMChangeStateHandler *cb;
void *opaque;
@@ -1965,8 +1994,7 @@ static bool main_loop_should_exit(void)
cpu_synchronize_all_states();
qemu_system_reset(VMRESET_REPORT);
resume_all_vcpus();
- if (runstate_check(RUN_STATE_INTERNAL_ERROR) ||
- runstate_check(RUN_STATE_SHUTDOWN)) {
+ if (runstate_needs_reset()) {
runstate_set(RUN_STATE_PAUSED);
}
}
@@ -2206,6 +2234,13 @@ static DisplayType select_display(const char *p)
fprintf(stderr, "Curses support is disabled\n");
exit(1);
#endif
+ } else if (strstart(p, "gtk", &opts)) {
+#ifdef CONFIG_GTK
+ display = DT_GTK;
+#else
+ fprintf(stderr, "GTK support is disabled\n");
+ exit(1);
+#endif
} else if (strstart(p, "none", &opts)) {
display = DT_NONE;
} else {
@@ -2243,14 +2278,16 @@ static int balloon_parse(const char *arg)
char *qemu_find_file(int type, const char *name)
{
- int len;
+ int i;
const char *subdir;
char *buf;
/* Try the name as a straight path first */
if (access(name, R_OK) == 0) {
+ trace_load_file(name, name);
return g_strdup(name);
}
+
switch (type) {
case QEMU_FILE_TYPE_BIOS:
subdir = "";
@@ -2261,14 +2298,16 @@ char *qemu_find_file(int type, const char *name)
default:
abort();
}
- len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2;
- buf = g_malloc0(len);
- snprintf(buf, len, "%s/%s%s", data_dir, subdir, name);
- if (access(buf, R_OK)) {
+
+ for (i = 0; i < data_dir_idx; i++) {
+ buf = g_strdup_printf("%s/%s%s", data_dir[i], subdir, name);
+ if (access(buf, R_OK) == 0) {
+ trace_load_file(name, buf);
+ return buf;
+ }
g_free(buf);
- return NULL;
}
- return buf;
+ return NULL;
}
static int device_help_func(QemuOpts *opts, void *opaque)
@@ -2343,6 +2382,7 @@ static int mon_init_func(QemuOpts *opts, void *opaque)
exit(1);
}
+ qemu_chr_fe_claim_no_fail(chr);
monitor_init(chr, flags);
return 0;
}
@@ -2492,7 +2532,7 @@ static int virtcon_parse(const char *devname)
qemu_opt_set(bus_opts, "driver", "virtio-serial-s390");
} else {
qemu_opt_set(bus_opts, "driver", "virtio-serial-pci");
- }
+ }
dev_opts = qemu_opts_create_nofail(device);
qemu_opt_set(dev_opts, "driver", "virtconsole");
@@ -2544,7 +2584,7 @@ static int sclp_parse(const char *devname)
}
static int debugcon_parse(const char *devname)
-{
+{
QemuOpts *opts;
if (!qemu_chr_new("debugcon", devname, NULL)) {
@@ -2860,6 +2900,8 @@ int main(int argc, char **argv, char **envp)
qemu_add_opts(&qemu_sandbox_opts);
qemu_add_opts(&qemu_add_fd_opts);
qemu_add_opts(&qemu_object_opts);
+ qemu_add_opts(&qemu_tpmdev_opts);
+ qemu_add_opts(&qemu_realtime_opts);
runstate_init();
@@ -2887,6 +2929,8 @@ int main(int argc, char **argv, char **envp)
nb_numa_nodes = 0;
nb_nics = 0;
+ bdrv_init_with_whitelist();
+
autostart= 1;
/* first pass of option parsing */
@@ -2986,7 +3030,7 @@ int main(int argc, char **argv, char **envp)
drive_add(IF_MTD, -1, optarg, MTD_OPTS);
break;
case QEMU_OPTION_sd:
- drive_add(IF_SD, 0, optarg, SD_OPTS);
+ drive_add(IF_SD, -1, optarg, SD_OPTS);
break;
case QEMU_OPTION_pflash:
drive_add(IF_PFLASH, -1, optarg, PFLASH_OPTS);
@@ -3092,7 +3136,7 @@ int main(int argc, char **argv, char **envp)
static const char * const params[] = {
"order", "once", "menu",
"splash", "splash-time",
- "reboot-timeout", NULL
+ "reboot-timeout", "strict", NULL
};
char buf[sizeof(boot_devices)];
char *standard_boot_devices;
@@ -3135,6 +3179,19 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
}
+ if (get_param_value(buf, sizeof(buf),
+ "strict", optarg)) {
+ if (!strcmp(buf, "on")) {
+ boot_strict = true;
+ } else if (!strcmp(buf, "off")) {
+ boot_strict = false;
+ } else {
+ fprintf(stderr,
+ "qemu: invalid option value '%s'\n",
+ buf);
+ exit(1);
+ }
+ }
if (!qemu_opts_parse(qemu_find_opts("boot-opts"),
optarg, 0)) {
exit(1);
@@ -3184,18 +3241,10 @@ int main(int argc, char **argv, char **envp)
add_device_config(DEV_BT, optarg);
break;
case QEMU_OPTION_audio_help:
- if (!(audio_available())) {
- printf("Option %s not supported for this target\n", popt->name);
- exit(1);
- }
AUD_help ();
exit (0);
break;
case QEMU_OPTION_soundhw:
- if (!(audio_available())) {
- printf("Option %s not supported for this target\n", popt->name);
- exit(1);
- }
select_soundhw (optarg);
break;
case QEMU_OPTION_h:
@@ -3223,6 +3272,13 @@ int main(int argc, char **argv, char **envp)
}
break;
}
+#ifdef CONFIG_TPM
+ case QEMU_OPTION_tpmdev:
+ if (tpm_config_parse(qemu_find_opts("tpmdev"), optarg) < 0) {
+ exit(1);
+ }
+ break;
+#endif
case QEMU_OPTION_mempath:
mem_path = optarg;
break;
@@ -3244,7 +3300,9 @@ int main(int argc, char **argv, char **envp)
add_device_config(DEV_GDB, optarg);
break;
case QEMU_OPTION_L:
- data_dir = optarg;
+ if (data_dir_idx < ARRAY_SIZE(data_dir)) {
+ data_dir[data_dir_idx++] = optarg;
+ }
break;
case QEMU_OPTION_bios:
bios_name = optarg;
@@ -3508,7 +3566,9 @@ int main(int argc, char **argv, char **envp)
break;
}
case QEMU_OPTION_acpitable:
- do_acpitable_option(optarg);
+ opts = qemu_opts_parse(qemu_find_opts("acpi"), optarg, 1);
+ g_assert(opts != NULL);
+ do_acpitable_option(opts);
break;
case QEMU_OPTION_smbios:
do_smbios_option(optarg);
@@ -3656,8 +3716,8 @@ int main(int argc, char **argv, char **envp)
}
p += 8;
os_set_proc_name(p);
- }
- }
+ }
+ }
break;
case QEMU_OPTION_prom_env:
if (nb_prom_envs >= MAX_PROM_ENVS) {
@@ -3759,6 +3819,7 @@ int main(int argc, char **argv, char **envp)
if (!opts) {
exit(1);
}
+ display_remote++;
break;
case QEMU_OPTION_writeconfig:
{
@@ -3806,6 +3867,13 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
break;
+ case QEMU_OPTION_realtime:
+ opts = qemu_opts_parse(qemu_find_opts("realtime"), optarg, 0);
+ if (!opts) {
+ exit(1);
+ }
+ configure_realtime(opts);
+ break;
default:
os_parse_cmd_args(popt->index, optarg);
}
@@ -3864,10 +3932,17 @@ int main(int argc, char **argv, char **envp)
* location or level of logging.
*/
if (log_mask) {
+ int mask;
if (log_file) {
- set_cpu_log_filename(log_file);
+ qemu_set_log_filename(log_file);
}
- set_cpu_log(log_mask);
+
+ mask = qemu_str_to_log_mask(log_mask);
+ if (!mask) {
+ qemu_print_log_usage(stdout);
+ exit(1);
+ }
+ qemu_set_log(mask);
}
if (!trace_backend_init(trace_events, trace_file)) {
@@ -3876,12 +3951,15 @@ int main(int argc, char **argv, char **envp)
/* If no data_dir is specified then try to find it relative to the
executable path. */
- if (!data_dir) {
- data_dir = os_find_datadir(argv[0]);
+ if (data_dir_idx < ARRAY_SIZE(data_dir)) {
+ data_dir[data_dir_idx] = os_find_datadir(argv[0]);
+ if (data_dir[data_dir_idx] != NULL) {
+ data_dir_idx++;
+ }
}
/* If all else fails use the install path specified when building. */
- if (!data_dir) {
- data_dir = CONFIG_QEMU_DATADIR;
+ if (data_dir_idx < ARRAY_SIZE(data_dir)) {
+ data_dir[data_dir_idx++] = CONFIG_QEMU_DATADIR;
}
/*
@@ -3991,6 +4069,25 @@ int main(int argc, char **argv, char **envp)
}
}
+ if (display_type == DT_DEFAULT && !display_remote) {
+#if defined(CONFIG_GTK)
+ display_type = DT_GTK;
+#elif defined(CONFIG_SDL) || defined(CONFIG_COCOA)
+ display_type = DT_SDL;
+#elif defined(CONFIG_VNC)
+ vnc_display = "localhost:0,to=99";
+ show_vnc_port = 1;
+#else
+ display_type = DT_NONE;
+#endif
+ }
+
+#if defined(CONFIG_GTK)
+ if (display_type == DT_GTK) {
+ early_gtk_display_init();
+ }
+#endif
+
socket_init();
if (qemu_opts_foreach(qemu_find_opts("chardev"), chardev_init_func, NULL, 1) != 0)
@@ -4020,6 +4117,10 @@ int main(int argc, char **argv, char **envp)
configure_accelerator();
+ if (!qtest_enabled() && qtest_chrdev) {
+ qtest_init();
+ }
+
machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
if (machine_opts) {
kernel_filename = qemu_opt_get(machine_opts, "kernel");
@@ -4073,6 +4174,12 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
+#ifdef CONFIG_TPM
+ if (tpm_init() < 0) {
+ exit(1);
+ }
+#endif
+
/* init the bluetooth world */
if (foreach_device_config(DEV_BT, bt_parse))
exit(1);
@@ -4087,8 +4194,6 @@ int main(int argc, char **argv, char **envp)
cpu_exec_init_all();
- bdrv_init_with_whitelist();
-
blk_mig_init();
/* open the virtual block devices */
@@ -4198,6 +4303,8 @@ int main(int argc, char **argv, char **envp)
.cpu_model = cpu_model };
machine->init(&args);
+ audio_init();
+
cpu_synchronize_all_post_init();
set_numa_modes();
@@ -4216,22 +4323,7 @@ int main(int argc, char **argv, char **envp)
net_check_clients();
- /* just use the first displaystate for the moment */
- ds = get_displaystate();
-
- if (using_spice)
- display_remote++;
- if (display_type == DT_DEFAULT && !display_remote) {
-#if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
- display_type = DT_SDL;
-#elif defined(CONFIG_VNC)
- vnc_display = "localhost:0,to=99";
- show_vnc_port = 1;
-#else
- display_type = DT_NONE;
-#endif
- }
-
+ ds = init_displaystate();
/* init local displays */
switch (display_type) {
@@ -4251,6 +4343,11 @@ int main(int argc, char **argv, char **envp)
cocoa_display_init(ds, full_screen);
break;
#endif
+#if defined(CONFIG_GTK)
+ case DT_GTK:
+ gtk_display_init(ds);
+ break;
+#endif
default:
break;
}
@@ -4282,9 +4379,6 @@ int main(int argc, char **argv, char **envp)
}
#endif
- /* display setup */
- text_consoles_set_display(ds);
-
if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
exit(1);
}
@@ -4322,11 +4416,13 @@ int main(int argc, char **argv, char **envp)
os_setup_post();
- resume_all_vcpus();
main_loop();
bdrv_close_all();
pause_all_vcpus();
res_free();
+#ifdef CONFIG_TPM
+ tpm_cleanup();
+#endif
return 0;
}