X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=vl.c;h=a89428573bc0fcaf33f54def45e45373855faea6;hb=2191dffcf6ba7df884ac902e829415d55a0b2b68;hp=2152f6ae53a7b707a9e11b4cb28a9e9a78d2c840;hpb=6be68d7eb9037fa3b8ef18901e5c02c120463efd;p=qemu diff --git a/vl.c b/vl.c index 2152f6a..a894285 100644 --- a/vl.c +++ b/vl.c @@ -29,7 +29,7 @@ #include #include -/* Needed early for HOST_BSD etc. */ +/* Needed early for CONFIG_BSD etc. */ #include "config-host.h" /* Needed early to override system queue definitions on BSD */ #include "sys-queue.h" @@ -56,7 +56,7 @@ #include #include #include -#ifdef HOST_BSD +#ifdef CONFIG_BSD #include #if defined(__FreeBSD__) || defined(__DragonFly__) #include @@ -108,11 +108,7 @@ #ifdef _WIN32 #include -#include -#include #include -#define getopt_long_only getopt_long -#define memalign(align, size) malloc(size) #endif #ifdef CONFIG_SDL @@ -162,6 +158,7 @@ int main(int argc, char **argv) #include "kvm.h" #include "balloon.h" #include "qemu-option.h" +#include "qemu-config.h" #include "disas.h" @@ -191,13 +188,10 @@ ram_addr_t ram_size; int nb_nics; NICInfo nd_table[MAX_NICS]; int vm_running; -static int autostart; +int autostart; static int rtc_utc = 1; static int rtc_date_offset = -1; /* -1 means no change */ -int cirrus_vga_enabled = 1; -int std_vga_enabled = 0; -int vmsvga_enabled = 0; -int xenfb_enabled = 0; +int vga_interface_type = VGA_CIRRUS; #ifdef TARGET_SPARC int graphic_width = 1024; int graphic_height = 768; @@ -223,21 +217,21 @@ int usb_enabled = 0; int singlestep = 0; int smp_cpus = 1; int max_cpus = 0; +int smp_cores = 1; +int smp_threads = 1; const char *vnc_display; int acpi_enabled = 1; int no_hpet = 0; -int virtio_balloon = 1; -const char *virtio_balloon_devaddr; int fd_bootchk = 1; int no_reboot = 0; int no_shutdown = 0; int cursor_hide = 1; int graphic_rotate = 0; +uint8_t irq0override = 1; #ifndef _WIN32 int daemonize = 0; #endif -WatchdogTimerModel *watchdog = NULL; -int watchdog_action = WDT_RESET; +const char *watchdog; const char *option_rom[MAX_OPTION_ROMS]; int nb_option_roms; int semihosting_enabled = 0; @@ -304,7 +298,7 @@ void hw_error(const char *fmt, ...) static void set_proc_name(const char *s) { -#ifdef __linux__ +#if defined(__linux__) && defined(PR_SET_NAME) char name[16]; if (!s) return; @@ -510,7 +504,7 @@ uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) union { uint64_t ll; struct { -#ifdef WORDS_BIGENDIAN +#ifdef HOST_WORDS_BIGENDIAN uint32_t high, low; #else uint32_t low, high; @@ -995,7 +989,7 @@ int qemu_timer_pending(QEMUTimer *ts) return 0; } -static inline int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time) +int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time) { if (!timer_head) return 0; @@ -1144,11 +1138,6 @@ static void host_alarm_handler(int host_signum) if (next_cpu) { /* stop the currently executing cpu because a timer occured */ cpu_exit(next_cpu); -#ifdef CONFIG_KQEMU - if (next_cpu->kqemu_enabled) { - kqemu_cpu_interrupt(next_cpu); - } -#endif } #endif timer_alarm_pending = 1; @@ -1801,75 +1790,6 @@ static int bt_parse(const char *opt) #define MTD_ALIAS "if=mtd" #define SD_ALIAS "index=0,if=sd" -static QemuOptsList drive_opt_list = { - .name = "drive", - .head = TAILQ_HEAD_INITIALIZER(drive_opt_list.head), - .desc = { - { - .name = "bus", - .type = QEMU_OPT_NUMBER, - .help = "bus number", - },{ - .name = "unit", - .type = QEMU_OPT_NUMBER, - .help = "unit number (i.e. lun for scsi)", - },{ - .name = "if", - .type = QEMU_OPT_STRING, - .help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)", - },{ - .name = "index", - .type = QEMU_OPT_NUMBER, - },{ - .name = "cyls", - .type = QEMU_OPT_NUMBER, - .help = "number of cylinders (ide disk geometry)", - },{ - .name = "heads", - .type = QEMU_OPT_NUMBER, - .help = "number of heads (ide disk geometry)", - },{ - .name = "secs", - .type = QEMU_OPT_NUMBER, - .help = "number of sectors (ide disk geometry)", - },{ - .name = "trans", - .type = QEMU_OPT_STRING, - .help = "chs translation (auto, lba. none)", - },{ - .name = "media", - .type = QEMU_OPT_STRING, - .help = "media type (disk, cdrom)", - },{ - .name = "snapshot", - .type = QEMU_OPT_BOOL, - },{ - .name = "file", - .type = QEMU_OPT_STRING, - .help = "disk image", - },{ - .name = "cache", - .type = QEMU_OPT_STRING, - .help = "host cache usage (none, writeback, writethrough)", - },{ - .name = "format", - .type = QEMU_OPT_STRING, - .help = "disk format (raw, qcow2, ...)", - },{ - .name = "serial", - .type = QEMU_OPT_STRING, - },{ - .name = "werror", - .type = QEMU_OPT_STRING, - },{ - .name = "addr", - .type = QEMU_OPT_STRING, - .help = "pci address (virtio only)", - }, - { /* end if list */ } - }, -}; - QemuOpts *drive_add(const char *file, const char *fmt, ...) { va_list ap; @@ -1880,7 +1800,7 @@ QemuOpts *drive_add(const char *file, const char *fmt, ...) vsnprintf(optstr, sizeof(optstr), fmt, ap); va_end(ap); - opts = qemu_opts_parse(&drive_opt_list, optstr, NULL); + opts = qemu_opts_parse(&qemu_drive_opts, optstr, NULL); if (!opts) { fprintf(stderr, "%s: huh? duplicate? (%s)\n", __FUNCTION__, optstr); @@ -1907,7 +1827,7 @@ DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit) return NULL; } -DriveInfo *drive_get_by_id(char *id) +DriveInfo *drive_get_by_id(const char *id) { DriveInfo *dinfo; @@ -1993,6 +1913,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque, int max_devs; int index; int cache; + int aio = 0; int bdrv_flags, onerror; const char *devaddr; DriveInfo *dinfo; @@ -2054,6 +1975,9 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque, } else if (!strcmp(buf, "xen")) { type = IF_XEN; max_devs = 0; + } else if (!strcmp(buf, "none")) { + type = IF_NONE; + max_devs = 0; } else { fprintf(stderr, "qemu: unsupported bus type '%s'\n", buf); return NULL; @@ -2123,6 +2047,19 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque, } } +#ifdef CONFIG_LINUX_AIO + if ((buf = qemu_opt_get(opts, "aio")) != NULL) { + if (!strcmp(buf, "threads")) + aio = 0; + else if (!strcmp(buf, "native")) + aio = 1; + else { + fprintf(stderr, "qemu: invalid aio option\n"); + return NULL; + } + } +#endif + if ((buf = qemu_opt_get(opts, "format")) != NULL) { if (strcmp(buf, "?") == 0) { fprintf(stderr, "qemu: Supported formats:"); @@ -2217,7 +2154,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque, /* init */ dinfo = qemu_mallocz(sizeof(*dinfo)); - if ((buf = qemu_opt_get(opts, "id")) != NULL) { + if ((buf = qemu_opts_id(opts)) != NULL) { dinfo->id = qemu_strdup(buf); } else { /* no id supplied -> create one */ @@ -2266,7 +2203,15 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque, break; case IF_PFLASH: case IF_MTD: + case IF_NONE: + break; case IF_VIRTIO: + /* add virtio block device */ + opts = qemu_opts_create(&qemu_device_opts, NULL, 0); + qemu_opt_set(opts, "driver", "virtio-blk-pci"); + qemu_opt_set(opts, "drive", dinfo->id); + if (devaddr) + qemu_opt_set(opts, "addr", devaddr); break; case IF_COUNT: abort(); @@ -2284,11 +2229,19 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque, bdrv_flags |= BDRV_O_NOCACHE; else if (cache == 2) /* write-back */ bdrv_flags |= BDRV_O_CACHE_WB; + + if (aio == 1) { + bdrv_flags |= BDRV_O_NATIVE_AIO; + } else { + bdrv_flags &= ~BDRV_O_NATIVE_AIO; + } + if (bdrv_open2(dinfo->bdrv, file, bdrv_flags, drv) < 0) { fprintf(stderr, "qemu: could not open disk image %s\n", file); return NULL; } + if (bdrv_key_required(dinfo->bdrv)) autostart = 0; *fatal_error = 0; @@ -2424,6 +2377,56 @@ static void numa_add(const char *optarg) return; } +static void smp_parse(const char *optarg) +{ + int smp, sockets = 0, threads = 0, cores = 0; + char *endptr; + char option[128]; + + smp = strtoul(optarg, &endptr, 10); + if (endptr != optarg) { + if (*endptr == ',') { + endptr++; + } + } + if (get_param_value(option, 128, "sockets", endptr) != 0) + sockets = strtoull(option, NULL, 10); + if (get_param_value(option, 128, "cores", endptr) != 0) + cores = strtoull(option, NULL, 10); + if (get_param_value(option, 128, "threads", endptr) != 0) + threads = strtoull(option, NULL, 10); + if (get_param_value(option, 128, "maxcpus", endptr) != 0) + max_cpus = strtoull(option, NULL, 10); + + /* compute missing values, prefer sockets over cores over threads */ + if (smp == 0 || sockets == 0) { + sockets = sockets > 0 ? sockets : 1; + cores = cores > 0 ? cores : 1; + threads = threads > 0 ? threads : 1; + if (smp == 0) { + smp = cores * threads * sockets; + } else { + sockets = smp / (cores * threads); + } + } else { + if (cores == 0) { + threads = threads > 0 ? threads : 1; + cores = smp / (sockets * threads); + } else { + if (sockets == 0) { + sockets = smp / (cores * threads); + } else { + threads = smp / (cores * sockets); + } + } + } + smp_cpus = smp; + smp_cores = cores > 0 ? cores : 1; + smp_threads = threads > 0 ? threads : 1; + if (max_cpus == 0) + max_cpus = smp_cpus; +} + /***********************************************************/ /* USB devices */ @@ -3633,6 +3636,8 @@ void qemu_init_vcpu(void *_env) if (kvm_enabled()) kvm_init_vcpu(env); + env->nr_cores = smp_cores; + env->nr_threads = smp_threads; return; } @@ -3660,11 +3665,7 @@ void qemu_notify_event(void) if (env) { cpu_exit(env); -#ifdef USE_KQEMU - if (env->kqemu_enabled) - kqemu_cpu_interrupt(env); -#endif - } + } } #define qemu_mutex_lock_iothread() do { } while (0) @@ -3960,6 +3961,8 @@ void qemu_init_vcpu(void *_env) kvm_start_vcpu(env); else tcg_init_vcpu(env); + env->nr_cores = smp_cores; + env->nr_threads = smp_threads; } void qemu_notify_event(void) @@ -4285,6 +4288,8 @@ static int vm_can_run(void) return 1; } +qemu_irq qemu_system_powerdown; + static void main_loop(void) { int r; @@ -4325,8 +4330,9 @@ static void main_loop(void) qemu_system_reset(); resume_all_vcpus(); } - if (qemu_powerdown_requested()) - qemu_system_powerdown(); + if (qemu_powerdown_requested()) { + qemu_irq_raise(qemu_system_powerdown); + } if ((r = qemu_vmstop_requested())) vm_stop(r); } @@ -4546,18 +4552,15 @@ static void select_vgahw (const char *p) { const char *opts; - cirrus_vga_enabled = 0; - std_vga_enabled = 0; - vmsvga_enabled = 0; - xenfb_enabled = 0; + vga_interface_type = VGA_NONE; if (strstart(p, "std", &opts)) { - std_vga_enabled = 1; + vga_interface_type = VGA_STD; } else if (strstart(p, "cirrus", &opts)) { - cirrus_vga_enabled = 1; + vga_interface_type = VGA_CIRRUS; } else if (strstart(p, "vmware", &opts)) { - vmsvga_enabled = 1; + vga_interface_type = VGA_VMWARE; } else if (strstart(p, "xenfb", &opts)) { - xenfb_enabled = 1; + vga_interface_type = VGA_XENFB; } else if (!strstart(p, "none", &opts)) { invalid_vga: fprintf(stderr, "Unknown vga type: %s\n", p); @@ -4581,23 +4584,27 @@ static void select_vgahw (const char *p) #ifdef TARGET_I386 static int balloon_parse(const char *arg) { - char buf[128]; - const char *p; + QemuOpts *opts; - if (!strcmp(arg, "none")) { - virtio_balloon = 0; - } else if (!strncmp(arg, "virtio", 6)) { - virtio_balloon = 1; - if (arg[6] == ',') { - p = arg + 7; - if (get_param_value(buf, sizeof(buf), "addr", p)) { - virtio_balloon_devaddr = strdup(buf); - } + if (strcmp(arg, "none") == 0) { + return 0; + } + + if (!strncmp(arg, "virtio", 6)) { + if (arg[6] == ',') { + /* have params -> parse them */ + opts = qemu_opts_parse(&qemu_device_opts, arg+7, NULL); + if (!opts) + return -1; + } else { + /* create empty opts */ + opts = qemu_opts_create(&qemu_device_opts, NULL, 0); } - } else { - return -1; + qemu_opt_set(opts, "driver", "virtio-balloon-pci"); + return 0; } - return 0; + + return -1; } #endif @@ -4785,9 +4792,18 @@ char *qemu_find_file(int type, const char *name) return buf; } +static int device_init_func(QemuOpts *opts, void *opaque) +{ + DeviceState *dev; + + dev = qdev_device_add(opts); + if (!dev) + return -1; + return 0; +} + struct device_config { enum { - DEV_GENERIC, /* -device */ DEV_USB, /* -usbdevice */ DEV_BT, /* -bt */ } type; @@ -4821,16 +4837,6 @@ static int foreach_device_config(int type, int (*func)(const char *cmdline)) return 0; } -static int generic_parse(const char *cmdline) -{ - DeviceState *dev; - - dev = qdev_device_add(cmdline); - if (!dev) - return -1; - return 0; -} - int main(int argc, char **argv, char **envp) { const char *gdbstub_dev = NULL; @@ -4845,7 +4851,7 @@ int main(int argc, char **argv, char **envp) int cyls, heads, secs, translation; const char *net_clients[MAX_NET_CLIENTS]; int nb_net_clients; - QemuOpts *hda_opts = NULL; + QemuOpts *hda_opts = NULL, *opts; int optind; const char *r, *optarg; CharDriverState *monitor_hd = NULL; @@ -4874,6 +4880,7 @@ int main(int argc, char **argv, char **envp) CPUState *env; int show_vnc_port = 0; + qemu_errors_to_file(stderr); qemu_cache_utils_init(envp); LIST_INIT (&vm_change_state_head); @@ -4945,8 +4952,6 @@ int main(int argc, char **argv, char **envp) tb_size = 0; autostart= 1; - register_watchdogs(); - optind = 1; for(;;) { if (optind >= argc) @@ -5035,6 +5040,10 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_drive: drive_add(NULL, "%s", optarg); break; + case QEMU_OPTION_set: + if (qemu_set_option(optarg) != 0) + exit(1); + break; case QEMU_OPTION_mtdblock: drive_add(optarg, MTD_ALIAS); break; @@ -5242,11 +5251,7 @@ int main(int argc, char **argv, char **envp) } /* On 32-bit hosts, QEMU is limited by virtual address space */ - if (value > (2047 << 20) -#ifndef CONFIG_KQEMU - && HOST_LONG_BITS == 32 -#endif - ) { + if (value > (2047 << 20) && HOST_LONG_BITS == 32) { fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n"); exit(1); } @@ -5358,9 +5363,12 @@ int main(int argc, char **argv, char **envp) serial_device_index++; break; case QEMU_OPTION_watchdog: - i = select_watchdog(optarg); - if (i > 0) - exit (i == 1 ? 1 : 0); + if (watchdog) { + fprintf(stderr, + "qemu: only one watchdog option may be given\n"); + return 1; + } + watchdog = optarg; break; case QEMU_OPTION_watchdog_action: if (select_watchdog_action(optarg) == -1) { @@ -5427,20 +5435,9 @@ int main(int argc, char **argv, char **envp) } break; #endif -#ifdef CONFIG_KQEMU - case QEMU_OPTION_enable_kqemu: - kqemu_allowed = 1; - break; - case QEMU_OPTION_kernel_kqemu: - kqemu_allowed = 2; - break; -#endif #ifdef CONFIG_KVM case QEMU_OPTION_enable_kvm: kvm_allowed = 1; -#ifdef CONFIG_KQEMU - kqemu_allowed = 0; -#endif break; #endif case QEMU_OPTION_usb: @@ -5451,21 +5448,18 @@ int main(int argc, char **argv, char **envp) add_device_config(DEV_USB, optarg); break; case QEMU_OPTION_device: - add_device_config(DEV_GENERIC, optarg); + opts = qemu_opts_parse(&qemu_device_opts, optarg, "driver"); + if (!opts) { + fprintf(stderr, "parse error: %s\n", optarg); + exit(1); + } break; case QEMU_OPTION_smp: - { - char *p; - char option[128]; - smp_cpus = strtol(optarg, &p, 10); + smp_parse(optarg); if (smp_cpus < 1) { fprintf(stderr, "Invalid number of CPUs\n"); exit(1); } - if (*p++ != ',') - break; - if (get_param_value(option, 128, "maxcpus", p)) - max_cpus = strtol(option, NULL, 0); if (max_cpus < smp_cpus) { fprintf(stderr, "maxcpus must be equal to or greater than " "smp\n"); @@ -5476,7 +5470,6 @@ int main(int argc, char **argv, char **envp) exit(1); } break; - } case QEMU_OPTION_vnc: display_type = DT_VNC; vnc_display = optarg; @@ -5649,14 +5642,6 @@ int main(int argc, char **argv, char **envp) data_dir = CONFIG_QEMU_SHAREDIR; } -#if defined(CONFIG_KVM) && defined(CONFIG_KQEMU) - if (kvm_allowed && kqemu_allowed) { - fprintf(stderr, - "You can not enable both KVM and kqemu at the same time\n"); - exit(1); - } -#endif - /* * Default to max_cpus = smp_cpus, in case the user doesn't * specify a max_cpus value. @@ -5735,10 +5720,6 @@ int main(int argc, char **argv, char **envp) } #endif -#ifdef CONFIG_KQEMU - if (smp_cpus > 1) - kqemu_allowed = 0; -#endif if (qemu_init_main_loop()) { fprintf(stderr, "qemu_init_main_loop failed\n"); exit(1); @@ -5755,7 +5736,10 @@ int main(int argc, char **argv, char **envp) exit(1); } +#ifndef _WIN32 + /* Win32 doesn't support line-buffering and requires size >= 2 */ setvbuf(stdout, NULL, _IOLBF, 0); +#endif init_timers(); if (init_timer_alarm() < 0) { @@ -5801,19 +5785,6 @@ int main(int argc, char **argv, char **envp) if (ram_size == 0) ram_size = DEFAULT_RAM_SIZE * 1024 * 1024; -#ifdef CONFIG_KQEMU - /* FIXME: This is a nasty hack because kqemu can't cope with dynamic - guest ram allocation. It needs to go away. */ - if (kqemu_allowed) { - kqemu_phys_ram_size = ram_size + 8 * 1024 * 1024 + 4 * 1024 * 1024; - kqemu_phys_ram_base = qemu_vmalloc(kqemu_phys_ram_size); - if (!kqemu_phys_ram_base) { - fprintf(stderr, "Could not allocate physical memory\n"); - exit(1); - } - } -#endif - /* init the dynamic translator */ cpu_exec_init_all(tb_size * 1024 * 1024); @@ -5830,8 +5801,8 @@ int main(int argc, char **argv, char **envp) /* open the virtual block devices */ if (snapshot) - qemu_opts_foreach(&drive_opt_list, drive_enable_snapshot, NULL, 0); - if (qemu_opts_foreach(&drive_opt_list, drive_init_func, machine, 1) != 0) + qemu_opts_foreach(&qemu_drive_opts, drive_enable_snapshot, NULL, 0); + if (qemu_opts_foreach(&qemu_drive_opts, drive_init_func, machine, 1) != 0) exit(1); register_savevm("timer", 0, 2, timer_save, timer_load, NULL); @@ -5961,6 +5932,12 @@ int main(int argc, char **argv, char **envp) module_call_init(MODULE_INIT_DEVICE); + if (watchdog) { + i = select_watchdog(watchdog); + if (i > 0) + exit (i == 1 ? 1 : 0); + } + if (machine->compat_props) { qdev_prop_register_compat(machine->compat_props); } @@ -5984,7 +5961,7 @@ int main(int argc, char **argv, char **envp) } /* init generic devices */ - if (foreach_device_config(DEV_GENERIC, generic_parse)) + if (qemu_opts_foreach(&qemu_device_opts, device_init_func, NULL, 1) != 0) exit(1); if (!display_state) @@ -6084,14 +6061,17 @@ int main(int argc, char **argv, char **envp) exit(1); } - if (loadvm) - do_loadvm(cur_mon, loadvm); + if (loadvm) { + if (load_vmstate(cur_mon, loadvm) < 0) { + autostart = 0; + } + } - if (incoming) + if (incoming) { qemu_start_incoming_migration(incoming); - - if (autostart) + } else if (autostart) { vm_start(); + } #ifndef _WIN32 if (daemonize) {