diff options
-rw-r--r-- | check-qdict.c | 2 | ||||
-rw-r--r-- | hw/boards.h | 5 | ||||
-rw-r--r-- | hw/loader.c | 4 | ||||
-rw-r--r-- | hw/pc.c | 10 | ||||
-rw-r--r-- | hw/qdev-properties.c | 9 | ||||
-rw-r--r-- | hw/unin_pci.c | 24 | ||||
-rw-r--r-- | hw/usb-net.c | 78 | ||||
-rw-r--r-- | hw/usb.h | 3 | ||||
-rw-r--r-- | hw/vga-isa.c | 6 | ||||
-rw-r--r-- | hw/vga-pci.c | 7 | ||||
-rw-r--r-- | hw/vga.c | 24 | ||||
-rw-r--r-- | hw/vga_int.h | 5 | ||||
-rw-r--r-- | hw/vmware_vga.c | 43 | ||||
-rw-r--r-- | migration-unix.c | 12 | ||||
-rw-r--r-- | monitor.c | 46 | ||||
-rw-r--r-- | pc-bios/optionrom/linuxboot.S | 20 | ||||
-rw-r--r-- | qdict.c | 3 | ||||
-rw-r--r-- | qemu-config.h | 1 | ||||
-rw-r--r-- | qemu-io.c | 10 | ||||
-rw-r--r-- | qemu-monitor.hx | 2 | ||||
-rw-r--r-- | target-i386/cpu.h | 5 | ||||
-rw-r--r-- | target-i386/kvm.c | 6 | ||||
-rw-r--r-- | target-i386/machine.c | 1 | ||||
-rw-r--r-- | usb-linux.c | 11 | ||||
-rw-r--r-- | vl.c | 57 | ||||
-rw-r--r-- | vnchextile.h | 4 |
26 files changed, 241 insertions, 157 deletions
diff --git a/check-qdict.c b/check-qdict.c index c37d44822..f2b482656 100644 --- a/check-qdict.c +++ b/check-qdict.c @@ -205,6 +205,8 @@ START_TEST(qdict_put_exists_test) value = qdict_get_int(tests_dict, key); fail_unless(value == 2); + + fail_unless(qdict_size(tests_dict) == 1); } END_TEST diff --git a/hw/boards.h b/hw/boards.h index 8fe0fbc8f..e1beda308 100644 --- a/hw/boards.h +++ b/hw/boards.h @@ -22,7 +22,10 @@ typedef struct QEMUMachine { int no_serial:1, no_parallel:1, use_virtcon:1, - no_vga:1; + no_vga:1, + no_floppy:1, + no_cdrom:1, + no_sdcard:1; int is_default; GlobalProperty *compat_props; struct QEMUMachine *next; diff --git a/hw/loader.c b/hw/loader.c index 2d7a2c495..dd4a9a2b1 100644 --- a/hw/loader.c +++ b/hw/loader.c @@ -669,7 +669,7 @@ int rom_load_all(void) "addr 0x" TARGET_FMT_plx ", size 0x%zx, max 0x" TARGET_FMT_plx ")\n", rom->name, addr, rom->romsize, rom->max); - return -1; + continue; } } else { /* fixed address requested */ @@ -718,8 +718,6 @@ int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size) QTAILQ_FOREACH(rom, &roms, next) { if (rom->max) continue; - if (rom->min > addr) - continue; if (rom->min + rom->romsize < addr) continue; if (rom->min > end) @@ -567,19 +567,21 @@ static int load_multiboot(void *fw_cfg, } if (!(flags & 0x00010000)) { /* MULTIBOOT_HEADER_HAS_ADDR */ uint64_t elf_entry; + uint64_t elf_low, elf_high; int kernel_size; fclose(f); - kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL, + kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_low, &elf_high, 0, ELF_MACHINE, 0); if (kernel_size < 0) { fprintf(stderr, "Error while loading elf kernel\n"); exit(1); } - mh_load_addr = mh_entry_addr = elf_entry; - mb_kernel_size = kernel_size; + mh_load_addr = elf_low; + mb_kernel_size = elf_high - elf_low; + mh_entry_addr = elf_entry; mb_kernel_data = qemu_malloc(mb_kernel_size); - if (rom_copy(mb_kernel_data, elf_entry, kernel_size) != kernel_size) { + if (rom_copy(mb_kernel_data, mh_load_addr, mb_kernel_size) != mb_kernel_size) { fprintf(stderr, "Error while fetching elf kernel from rom\n"); exit(1); } diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index fb07279ba..217ddc0b7 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -500,7 +500,12 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value) dev->info->name, name); return -1; } - return prop->info->parse(dev, prop, value); + if (prop->info->parse(dev, prop, value) != 0) { + fprintf(stderr, "property \"%s.%s\": failed to parse \"%s\"\n", + dev->info->name, name, value); + return -1; + } + return 0; } void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type) @@ -619,7 +624,7 @@ void qdev_prop_set_globals(DeviceState *dev) continue; } if (qdev_prop_parse(dev, prop->property, prop->value) != 0) { - abort(); + exit(1); } } } diff --git a/hw/unin_pci.c b/hw/unin_pci.c index f07c96644..3ae4e7a14 100644 --- a/hw/unin_pci.c +++ b/hw/unin_pci.c @@ -148,7 +148,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic) /* Use values found on a real PowerMac */ /* Uninorth main bus */ - dev = qdev_create(NULL, "uni-north-main"); + dev = qdev_create(NULL, "uni-north"); qdev_init_nofail(dev); s = sysbus_from_qdev(dev); d = FROM_SYSBUS(UNINState, s); @@ -157,7 +157,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic) pic, 11 << 3, 4); #if 0 - pci_create_simple(d->host_state.bus, 11 << 3, "uni-north-main"); + pci_create_simple(d->host_state.bus, 11 << 3, "uni-north"); #endif sysbus_mmio_map(s, 0, 0xf2800000); @@ -170,8 +170,8 @@ PCIBus *pci_pmac_init(qemu_irq *pic) #endif /* Uninorth AGP bus */ - pci_create_simple(d->host_state.bus, 11 << 3, "uni-north-AGP"); - dev = qdev_create(NULL, "uni-north-AGP"); + pci_create_simple(d->host_state.bus, 11 << 3, "uni-north-agp"); + dev = qdev_create(NULL, "uni-north-agp"); qdev_init_nofail(dev); s = sysbus_from_qdev(dev); sysbus_mmio_map(s, 0, 0xf0800000); @@ -180,8 +180,8 @@ PCIBus *pci_pmac_init(qemu_irq *pic) /* Uninorth internal bus */ #if 0 /* XXX: not needed for now */ - pci_create_simple(d->host_state.bus, 14 << 3, "uni-north-internal"); - dev = qdev_create(NULL, "uni-north-internal"); + pci_create_simple(d->host_state.bus, 14 << 3, "uni-north-pci"); + dev = qdev_create(NULL, "uni-north-pci"); qdev_init_nofail(dev); s = sysbus_from_qdev(dev); sysbus_mmio_map(s, 0, 0xf4800000); @@ -260,7 +260,7 @@ static int unin_internal_pci_host_init(PCIDevice *d) } static PCIDeviceInfo unin_main_pci_host_info = { - .qdev.name = "uni-north-main", + .qdev.name = "uni-north", .qdev.size = sizeof(PCIDevice), .init = unin_main_pci_host_init, }; @@ -272,29 +272,29 @@ static PCIDeviceInfo dec_21154_pci_host_info = { }; static PCIDeviceInfo unin_agp_pci_host_info = { - .qdev.name = "uni-north-AGP", + .qdev.name = "uni-north-agp", .qdev.size = sizeof(PCIDevice), .init = unin_agp_pci_host_init, }; static PCIDeviceInfo unin_internal_pci_host_info = { - .qdev.name = "uni-north-internal", + .qdev.name = "uni-north-pci", .qdev.size = sizeof(PCIDevice), .init = unin_internal_pci_host_init, }; static void unin_register_devices(void) { - sysbus_register_dev("uni-north-main", sizeof(UNINState), + sysbus_register_dev("uni-north", sizeof(UNINState), pci_unin_main_init_device); pci_qdev_register(&unin_main_pci_host_info); sysbus_register_dev("dec-21154", sizeof(UNINState), pci_dec_21154_init_device); pci_qdev_register(&dec_21154_pci_host_info); - sysbus_register_dev("uni-north-AGP", sizeof(UNINState), + sysbus_register_dev("uni-north-agp", sizeof(UNINState), pci_unin_agp_init_device); pci_qdev_register(&unin_agp_pci_host_info); - sysbus_register_dev("uni-north-internal", sizeof(UNINState), + sysbus_register_dev("uni-north-pci", sizeof(UNINState), pci_unin_internal_init_device); pci_qdev_register(&unin_internal_pci_host_info); } diff --git a/hw/usb-net.c b/hw/usb-net.c index 122a0d849..9744dfa5d 100644 --- a/hw/usb-net.c +++ b/hw/usb-net.c @@ -1420,8 +1420,7 @@ static void usbnet_cleanup(VLANClientState *nc) { USBNetState *s = DO_UPCAST(NICState, nc, nc)->opaque; - rndis_clear_responsequeue(s); - qemu_free(s); + s->nic = NULL; } static void usb_net_handle_destroy(USBDevice *dev) @@ -1429,9 +1428,18 @@ static void usb_net_handle_destroy(USBDevice *dev) USBNetState *s = (USBNetState *) dev; /* TODO: remove the nd_table[] entry */ + rndis_clear_responsequeue(s); qemu_del_vlan_client(&s->nic->nc); } +static NetClientInfo net_usbnet_info = { + .type = NET_CLIENT_TYPE_NIC, + .size = sizeof(NICState), + .can_receive = usbnet_can_receive, + .receive = usbnet_receive, + .cleanup = usbnet_cleanup, +}; + static int usb_net_initfn(USBDevice *dev) { USBNetState *s = DO_UPCAST(USBNetState, dev, dev); @@ -1447,43 +1455,45 @@ static int usb_net_initfn(USBDevice *dev) s->media_state = 0; /* NDIS_MEDIA_STATE_CONNECTED */; s->filter = 0; s->vendorid = 0x1234; + + qemu_macaddr_default_if_unset(&s->conf.macaddr); + s->nic = qemu_new_nic(&net_usbnet_info, &s->conf, + s->dev.qdev.info->name, s->dev.qdev.id, s); + qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); + snprintf(s->usbstring_mac, sizeof(s->usbstring_mac), + "%02x%02x%02x%02x%02x%02x", + 0x40, + s->conf.macaddr.a[1], + s->conf.macaddr.a[2], + s->conf.macaddr.a[3], + s->conf.macaddr.a[4], + s->conf.macaddr.a[5]); + return 0; } -static NetClientInfo net_usbnet_info = { - .type = NET_CLIENT_TYPE_NIC, - .size = sizeof(NICState), - .can_receive = usbnet_can_receive, - .receive = usbnet_receive, - .cleanup = usbnet_cleanup, -}; - -USBDevice *usb_net_init(NICInfo *nd) +static USBDevice *usb_net_init(const char *cmdline) { USBDevice *dev; - USBNetState *s; - - dev = usb_create_simple(NULL /* FIXME */, "usb-net"); - s = DO_UPCAST(USBNetState, dev, dev); + QemuOpts *opts; + int idx; - memcpy(s->conf.macaddr.a, nd->macaddr, sizeof(nd->macaddr)); - s->conf.vlan = nd->vlan; - s->conf.peer = nd->netdev; - - s->nic = qemu_new_nic(&net_usbnet_info, &s->conf, - nd->model, nd->name, s); + opts = qemu_opts_parse(&qemu_net_opts, cmdline, NULL); + if (!opts) { + return NULL; + } + qemu_opt_set(opts, "type", "nic"); + qemu_opt_set(opts, "model", "usb"); - qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); + idx = net_client_init(NULL, opts, 0); + if (idx == -1) { + return NULL; + } - snprintf(s->usbstring_mac, sizeof(s->usbstring_mac), - "%02x%02x%02x%02x%02x%02x", - 0x40, s->conf.macaddr.a[1], s->conf.macaddr.a[2], - s->conf.macaddr.a[3], s->conf.macaddr.a[4], s->conf.macaddr.a[5]); - fprintf(stderr, "usbnet: initialized mac %02x:%02x:%02x:%02x:%02x:%02x\n", - s->conf.macaddr.a[0], s->conf.macaddr.a[1], s->conf.macaddr.a[2], - s->conf.macaddr.a[3], s->conf.macaddr.a[4], s->conf.macaddr.a[5]); - - return (USBDevice *) s; + dev = usb_create(NULL /* FIXME */, "usb-net"); + qdev_set_nic_properties(&dev->qdev, &nd_table[idx]); + qdev_init(&dev->qdev); + return dev; } static struct USBDeviceInfo net_info = { @@ -1496,6 +1506,12 @@ static struct USBDeviceInfo net_info = { .handle_control = usb_net_handle_control, .handle_data = usb_net_handle_data, .handle_destroy = usb_net_handle_destroy, + .usbdevice_name = "net", + .usbdevice_init = usb_net_init, + .qdev.props = (Property[]) { + DEFINE_NIC_PROPERTIES(USBNetState, conf), + DEFINE_PROP_END_OF_LIST(), + } }; static void usb_net_register_devices(void) @@ -258,9 +258,6 @@ void usb_host_info(Monitor *mon); /* usb-hid.c */ void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *)); -/* usb-net.c */ -USBDevice *usb_net_init(NICInfo *nd); - /* usb-bt.c */ USBDevice *usb_bt_init(HCIInfo *hci); diff --git a/hw/vga-isa.c b/hw/vga-isa.c index 5f2990413..793714417 100644 --- a/hw/vga-isa.c +++ b/hw/vga-isa.c @@ -42,11 +42,7 @@ int isa_vga_init(void) s->ds = graphic_console_init(s->update, s->invalidate, s->screen_dump, s->text_update, s); -#ifdef CONFIG_BOCHS_VBE - /* XXX: use optimized standard vga accesses */ - cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, - VGA_RAM_SIZE, s->vram_offset); -#endif + vga_init_vbe(s); /* ROM BIOS */ rom_add_vga(VGABIOS_FILENAME); return 0; diff --git a/hw/vga-pci.c b/hw/vga-pci.c index b7642ec81..9089c9f5d 100644 --- a/hw/vga-pci.c +++ b/hw/vga-pci.c @@ -108,12 +108,7 @@ static int pci_vga_initfn(PCIDevice *dev) PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map); } -#ifdef CONFIG_BOCHS_VBE - /* XXX: use optimized standard vga accesses */ - cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, - VGA_RAM_SIZE, s->vram_offset); -#endif - + vga_init_vbe(s); /* ROM BIOS */ rom_add_vga(VGABIOS_FILENAME); return 0; @@ -1583,6 +1583,14 @@ static void vga_sync_dirty_bitmap(VGACommonState *s) cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa0000, 0xa8000); cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa8000, 0xb0000); } + +#ifdef CONFIG_BOCHS_VBE + if (s->vbe_mapped) { + cpu_physical_sync_dirty_bitmap(VBE_DISPI_LFB_PHYSICAL_ADDRESS, + VBE_DISPI_LFB_PHYSICAL_ADDRESS + s->vram_size); + } +#endif + vga_dirty_log_start(s); } @@ -1626,6 +1634,13 @@ void vga_dirty_log_start(VGACommonState *s) } s2 = 1; } + +#ifdef CONFIG_BOCHS_VBE + if (kvm_enabled() && s->vbe_mapped) { + kvm_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); + } +#endif + } /* @@ -2332,6 +2347,15 @@ void vga_init(VGACommonState *s) qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000); } +void vga_init_vbe(VGACommonState *s) +{ +#ifdef CONFIG_BOCHS_VBE + /* XXX: use optimized standard vga accesses */ + cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, + VGA_RAM_SIZE, s->vram_offset); + s->vbe_mapped = 1; +#endif +} /********************************************************/ /* vga screen dump */ diff --git a/hw/vga_int.h b/hw/vga_int.h index aa6221c24..d2756f78a 100644 --- a/hw/vga_int.h +++ b/hw/vga_int.h @@ -71,8 +71,8 @@ uint16_t vbe_regs[VBE_DISPI_INDEX_NB]; \ uint32_t vbe_start_addr; \ uint32_t vbe_line_offset; \ - uint32_t vbe_bank_mask; - + uint32_t vbe_bank_mask; \ + int vbe_mapped; #else #define VGA_STATE_COMMON_BOCHS_VBE @@ -218,6 +218,7 @@ void vga_draw_cursor_line_32(uint8_t *d1, const uint8_t *src1, unsigned int color_xor); int vga_ioport_invalid(VGACommonState *s, uint32_t addr); +void vga_init_vbe(VGACommonState *s); extern const uint8_t sr_mask[8]; extern const uint8_t gr_mask[16]; diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c index f3e3749e9..07befc85d 100644 --- a/hw/vmware_vga.c +++ b/hw/vmware_vga.c @@ -67,6 +67,11 @@ struct vmsvga_state_s { int syncing; int fb_size; + ram_addr_t fifo_offset; + uint8_t *fifo_ptr; + unsigned int fifo_size; + target_phys_addr_t fifo_base; + union { uint32_t *fifo; struct __attribute__((__packed__)) { @@ -680,7 +685,7 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) return 0x0; case SVGA_REG_VRAM_SIZE: - return s->vga.vram_size - SVGA_FIFO_SIZE; + return s->vga.vram_size; case SVGA_REG_FB_SIZE: return s->fb_size; @@ -701,10 +706,10 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) return caps; case SVGA_REG_MEM_START: - return s->vram_base + s->vga.vram_size - SVGA_FIFO_SIZE; + return s->fifo_base; case SVGA_REG_MEM_SIZE: - return SVGA_FIFO_SIZE; + return s->fifo_size; case SVGA_REG_CONFIG_DONE: return s->config; @@ -790,7 +795,7 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value) case SVGA_REG_CONFIG_DONE: if (value) { - s->fifo = (uint32_t *) &s->vga.vram_ptr[s->vga.vram_size - SVGA_FIFO_SIZE]; + s->fifo = (uint32_t *) s->fifo_ptr; /* Check range and alignment. */ if ((CMD(min) | CMD(max) | CMD(next_cmd) | CMD(stop)) & 3) @@ -1059,7 +1064,7 @@ static int vmsvga_post_load(void *opaque, int version_id) s->invalidated = 1; if (s->config) - s->fifo = (uint32_t *) &s->vga.vram_ptr[s->vga.vram_size - SVGA_FIFO_SIZE]; + s->fifo = (uint32_t *) s->fifo_ptr; return 0; } @@ -1111,6 +1116,10 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size) vmsvga_reset(s); + s->fifo_size = SVGA_FIFO_SIZE; + s->fifo_offset = qemu_ram_alloc(s->fifo_size); + s->fifo_ptr = qemu_get_ram_ptr(s->fifo_offset); + vga_common_init(&s->vga, vga_ram_size); vga_init(&s->vga); vmstate_register(0, &vmstate_vga_common, &s->vga); @@ -1120,12 +1129,8 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size) vmsvga_screen_dump, vmsvga_text_update, s); -#ifdef CONFIG_BOCHS_VBE - /* XXX: use optimized standard vga accesses */ - cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, - vga_ram_size, s->vga.vram_offset); -#endif - rom_add_vga(VGABIOS_FILENAME); + vga_init_vbe(&s->vga); + rom_add_vga(VGABIOS_FILENAME); } static void pci_vmsvga_map_ioport(PCIDevice *pci_dev, int region_num, @@ -1166,6 +1171,19 @@ static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num, iomemtype); } +static void pci_vmsvga_map_fifo(PCIDevice *pci_dev, int region_num, + pcibus_t addr, pcibus_t size, int type) +{ + struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev; + struct vmsvga_state_s *s = &d->chip; + ram_addr_t iomemtype; + + s->fifo_base = addr; + iomemtype = s->fifo_offset | IO_MEM_RAM; + cpu_register_physical_memory(s->fifo_base, s->fifo_size, + iomemtype); +} + static int pci_vmsvga_initfn(PCIDevice *dev) { struct pci_vmsvga_state_s *s = @@ -1189,6 +1207,9 @@ static int pci_vmsvga_initfn(PCIDevice *dev) pci_register_bar(&s->card, 1, VGA_RAM_SIZE, PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_mem); + pci_register_bar(&s->card, 2, SVGA_FIFO_SIZE, + PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_fifo); + vmsvga_init(&s->chip, VGA_RAM_SIZE); return 0; diff --git a/migration-unix.c b/migration-unix.c index 783228b3b..a141dbbbe 100644 --- a/migration-unix.c +++ b/migration-unix.c @@ -112,10 +112,6 @@ MigrationState *unix_start_outgoing_migration(Monitor *mon, socket_set_nonblock(s->fd); - if (!detach) { - migrate_fd_monitor_suspend(s, mon); - } - do { ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr)); if (ret == -1) @@ -128,7 +124,13 @@ MigrationState *unix_start_outgoing_migration(Monitor *mon, if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK) { dprintf("connect failed\n"); goto err_after_open; - } else if (ret >= 0) + } + + if (!detach) { + migrate_fd_monitor_suspend(s, mon); + } + + if (ret >= 0) migrate_fd_connect(s); return &s->mig_state; @@ -143,6 +143,9 @@ static inline int monitor_ctrl_mode(const Monitor *mon) static void monitor_read_command(Monitor *mon, int show_prompt) { + if (!mon->rs) + return; + readline_start(mon->rs, "(qemu) ", 0, monitor_command_cb, NULL); if (show_prompt) readline_show_prompt(mon->rs); @@ -177,9 +180,6 @@ static void monitor_puts(Monitor *mon, const char *str) { char c; - if (!mon) - return; - for(;;) { c = *str++; if (c == '\0') @@ -195,6 +195,9 @@ static void monitor_puts(Monitor *mon, const char *str) void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) { + if (!mon) + return; + if (mon->mc && !mon->mc->print_enabled) { qemu_error_new(QERR_UNDEFINED_ERROR); } else { @@ -894,7 +897,7 @@ static void do_eject(Monitor *mon, const QDict *qdict, QObject **ret_data) { BlockDriverState *bs; int force = qdict_get_int(qdict, "force"); - const char *filename = qdict_get_str(qdict, "filename"); + const char *filename = qdict_get_str(qdict, "device"); bs = bdrv_find(filename); if (!bs) { @@ -2086,14 +2089,34 @@ static void do_info_status(Monitor *mon, QObject **ret_data) vm_running, singlestep); } +static ram_addr_t balloon_get_value(void) +{ + ram_addr_t actual; + + if (kvm_enabled() && !kvm_has_sync_mmu()) { + qemu_error_new(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon"); + return 0; + } + + actual = qemu_balloon_status(); + if (actual == 0) { + qemu_error_new(QERR_DEVICE_NOT_ACTIVE, "balloon"); + return 0; + } + + return actual; +} + /** * do_balloon(): Request VM to change its memory allocation */ static void do_balloon(Monitor *mon, const QDict *qdict, QObject **ret_data) { - int value = qdict_get_int(qdict, "value"); - ram_addr_t target = value; - qemu_balloon(target << 20); + if (balloon_get_value()) { + /* ballooning is active */ + ram_addr_t value = qdict_get_int(qdict, "value"); + qemu_balloon(value << 20); + } } static void monitor_print_balloon(Monitor *mon, const QObject *data) @@ -2121,14 +2144,11 @@ static void do_info_balloon(Monitor *mon, QObject **ret_data) { ram_addr_t actual; - actual = qemu_balloon_status(); - if (kvm_enabled() && !kvm_has_sync_mmu()) - qemu_error_new(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon"); - else if (actual == 0) - qemu_error_new(QERR_DEVICE_NOT_ACTIVE, "balloon"); - else + actual = balloon_get_value(); + if (actual != 0) { *ret_data = qobject_from_jsonf("{ 'balloon': %" PRId64 "}", (int64_t) actual); + } } static qemu_acl *find_acl(Monitor *mon, const char *name) diff --git a/pc-bios/optionrom/linuxboot.S b/pc-bios/optionrom/linuxboot.S index 7f3b1b269..c4c9109b6 100644 --- a/pc-bios/optionrom/linuxboot.S +++ b/pc-bios/optionrom/linuxboot.S @@ -79,24 +79,20 @@ copy_kernel: mode, so let's get into 32 bit mode, write the kernel and jump back again. */ - /* Set DS to SS+SP - 0x10, so we can write our GDT descriptor there */ - mov %ss, %eax - shl $4, %eax - add %esp, %eax - sub $0x10, %eax - shr $4, %eax + /* Reserve space on the stack for our GDT descriptor. */ + mov %esp, %ebp + sub $16, %esp /* Now create the GDT descriptor */ + movw $((3 * 8) - 1), -16(%bp) mov %cs, %eax shl $4, %eax - movw $((3 * 8) - 1), %bx - movw %bx, %gs:0 - movl $gdt, %ebx - add %eax, %ebx - movl %ebx, %gs:2 + addl $gdt, %ebx + movl %ebx, -14(%bp) /* And load the GDT */ - data32 lgdt %gs:0 + data32 lgdt -16(%bp) + mov %ebp, %esp /* Get us to protected mode now */ mov $1, %eax @@ -122,9 +122,8 @@ void qdict_put_obj(QDict *qdict, const char *key, QObject *value) /* allocate a new entry */ entry = alloc_entry(key, value); QLIST_INSERT_HEAD(&qdict->table[hash], entry, next); + qdict->size++; } - - qdict->size++; } /** diff --git a/qemu-config.h b/qemu-config.h index 34dfadc5f..dd89ae468 100644 --- a/qemu-config.h +++ b/qemu-config.h @@ -7,6 +7,7 @@ extern QemuOptsList qemu_device_opts; extern QemuOptsList qemu_netdev_opts; extern QemuOptsList qemu_net_opts; extern QemuOptsList qemu_rtc_opts; +extern QemuOptsList qemu_global_opts; extern QemuOptsList qemu_mon_opts; int qemu_set_option(const char *str); @@ -129,7 +129,8 @@ create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern) { size_t *sizes = calloc(nr_iov, sizeof(size_t)); size_t count = 0; - void *buf, *p; + void *buf = NULL; + void *p; int i; for (i = 0; i < nr_iov; i++) { @@ -139,19 +140,19 @@ create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern) len = cvtnum(arg); if (len < 0) { printf("non-numeric length argument -- %s\n", arg); - return NULL; + goto fail; } /* should be SIZE_T_MAX, but that doesn't exist */ if (len > UINT_MAX) { printf("too large length argument -- %s\n", arg); - return NULL; + goto fail; } if (len & 0x1ff) { printf("length argument %lld is not sector aligned\n", len); - return NULL; + goto fail; } sizes[i] = len; @@ -167,6 +168,7 @@ create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern) p += sizes[i]; } +fail: free(sizes); return buf; } diff --git a/qemu-monitor.hx b/qemu-monitor.hx index de5b9feb4..7b5107037 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -130,7 +130,7 @@ ETEXI { .name = "eject", - .args_type = "force:-f,filename:B", + .args_type = "force:-f,device:B", .params = "[-f] device", .help = "eject a removable medium (use -f to force it)", .user_print = monitor_user_noop, diff --git a/target-i386/cpu.h b/target-i386/cpu.h index eddb4bd69..0df6f1d6c 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -710,6 +710,7 @@ typedef struct CPUX86State { /* For KVM */ uint32_t mp_state; + int32_t exception_injected; int32_t interrupt_injected; uint8_t soft_interrupt; uint8_t nmi_injected; @@ -852,12 +853,12 @@ static inline int hw_breakpoint_enabled(unsigned long dr7, int index) static inline int hw_breakpoint_type(unsigned long dr7, int index) { - return (dr7 >> (DR7_TYPE_SHIFT + (index * 2))) & 3; + return (dr7 >> (DR7_TYPE_SHIFT + (index * 4))) & 3; } static inline int hw_breakpoint_len(unsigned long dr7, int index) { - int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 2))) & 3); + int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 4))) & 3); return (len == 2) ? 8 : len + 1; } diff --git a/target-i386/kvm.c b/target-i386/kvm.c index bb9012a3e..8584507ab 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -726,8 +726,8 @@ static int kvm_put_vcpu_events(CPUState *env) return 0; } - events.exception.injected = (env->exception_index >= 0); - events.exception.nr = env->exception_index; + events.exception.injected = (env->exception_injected >= 0); + events.exception.nr = env->exception_injected; events.exception.has_error_code = env->has_error_code; events.exception.error_code = env->error_code; @@ -761,7 +761,7 @@ static int kvm_get_vcpu_events(CPUState *env) if (ret < 0) { return ret; } - env->exception_index = + env->exception_injected = events.exception.injected ? events.exception.nr : -1; env->has_error_code = events.exception.has_error_code; env->error_code = events.exception.error_code; diff --git a/target-i386/machine.c b/target-i386/machine.c index 804002e66..b9d51f414 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -460,6 +460,7 @@ static const VMStateDescription vmstate_cpu = { VMSTATE_INT32_V(interrupt_injected, CPUState, 9), VMSTATE_UINT32_V(mp_state, CPUState, 9), VMSTATE_UINT64_V(tsc, CPUState, 9), + VMSTATE_INT32_V(exception_injected, CPUState, 11), VMSTATE_UINT8_V(soft_interrupt, CPUState, 11), VMSTATE_UINT8_V(nmi_injected, CPUState, 11), VMSTATE_UINT8_V(nmi_pending, CPUState, 11), diff --git a/usb-linux.c b/usb-linux.c index 105ce88f3..88728e927 100644 --- a/usb-linux.c +++ b/usb-linux.c @@ -1206,7 +1206,8 @@ static int usb_host_read_file(char *line, size_t line_size, const char *device_f ret = 1; #if 0 } else { - monitor_printf(mon, "husb: could not open %s\n", filename); + if (mon) + monitor_printf(mon, "husb: could not open %s\n", filename); #endif } @@ -1339,15 +1340,17 @@ static int usb_host_scan(void *opaque, USBScanFunc *func) } found_devices: if (!usb_fs_type) { - monitor_printf(mon, "husb: unable to access USB devices\n"); + if (mon) + monitor_printf(mon, "husb: unable to access USB devices\n"); return -ENOENT; } /* the module setting (used later for opening devices) */ usb_host_device_path = qemu_mallocz(strlen(devpath)+1); strcpy(usb_host_device_path, devpath); - monitor_printf(mon, "husb: using %s file-system with %s\n", - fs_type[usb_fs_type], usb_host_device_path); + if (mon) + monitor_printf(mon, "husb: using %s file-system with %s\n", + fs_type[usb_fs_type], usb_host_device_path); } switch (usb_fs_type) { @@ -288,7 +288,9 @@ static int default_parallel = 1; static int default_virtcon = 1; static int default_monitor = 1; static int default_vga = 1; -static int default_drive = 1; +static int default_floppy = 1; +static int default_cdrom = 1; +static int default_sdcard = 1; static struct { const char *driver; @@ -296,11 +298,13 @@ static struct { } default_list[] = { { .driver = "isa-serial", .flag = &default_serial }, { .driver = "isa-parallel", .flag = &default_parallel }, + { .driver = "isa-fdc", .flag = &default_floppy }, + { .driver = "ide-drive", .flag = &default_cdrom }, { .driver = "virtio-console-pci", .flag = &default_virtcon }, { .driver = "virtio-console-s390", .flag = &default_virtcon }, { .driver = "VGA", .flag = &default_vga }, - { .driver = "Cirrus VGA", .flag = &default_vga }, - { .driver = "QEMUware SVGA", .flag = &default_vga }, + { .driver = "cirrus-vga", .flag = &default_vga }, + { .driver = "vmware-svga", .flag = &default_vga }, }; static int default_driver_check(QemuOpts *opts, void *opaque) @@ -2058,10 +2062,6 @@ BlockInterfaceErrorAction drive_get_on_error( { DriveInfo *dinfo; - if (is_read) { - return BLOCK_ERR_REPORT; - } - QTAILQ_FOREACH(dinfo, &drives, next) { if (dinfo->bdrv == bdrv) return is_read ? dinfo->on_read_error : dinfo->on_write_error; @@ -2678,24 +2678,6 @@ static int usb_device_add(const char *devname, int is_hotplug) /* the other ones */ if (strstart(devname, "host:", &p)) { dev = usb_host_device_open(p); - } else if (strstart(devname, "net:", &p)) { - QemuOpts *opts; - int idx; - - opts = qemu_opts_parse(&qemu_net_opts, p, NULL); - if (!opts) { - return -1; - } - - qemu_opt_set(opts, "type", "nic"); - qemu_opt_set(opts, "model", "usb"); - - idx = net_client_init(NULL, opts, 0); - if (idx == -1) { - return -1; - } - - dev = usb_net_init(&nd_table[idx]); } else if (!strcmp(devname, "bt") || strstart(devname, "bt:", &p)) { dev = usb_bt_init(devname[2] ? hci_init(p) : bt_new_hci(qemu_find_bt_vlan(0))); @@ -5701,7 +5683,9 @@ int main(int argc, char **argv, char **envp) default_monitor = 0; default_vga = 0; default_net = 0; - default_drive = 0; + default_floppy = 0; + default_cdrom = 0; + default_sdcard = 0; break; #ifndef _WIN32 case QEMU_OPTION_chroot: @@ -5785,6 +5769,7 @@ int main(int argc, char **argv, char **envp) } qemu_opts_foreach(&qemu_device_opts, default_driver_check, NULL, 0); + qemu_opts_foreach(&qemu_global_opts, default_driver_check, NULL, 0); if (machine->no_serial) { default_serial = 0; @@ -5798,6 +5783,15 @@ int main(int argc, char **argv, char **envp) if (machine->no_vga) { default_vga = 0; } + if (machine->no_floppy) { + default_floppy = 0; + } + if (machine->no_cdrom) { + default_cdrom = 0; + } + if (machine->no_sdcard) { + default_sdcard = 0; + } if (display_type == DT_NOGRAPHIC) { if (default_parallel) @@ -5960,13 +5954,17 @@ int main(int argc, char **argv, char **envp) blk_mig_init(); - if (default_drive) { + if (default_cdrom) { /* we always create the cdrom drive, even if no disk is there */ drive_add(NULL, CDROM_ALIAS); + } + if (default_floppy) { /* we always create at least one floppy */ drive_add(NULL, FD_ALIAS, 0); + } + if (default_sdcard) { /* we always create one sd slot, even if no card is in it */ drive_add(NULL, SD_ALIAS); } @@ -6146,7 +6144,10 @@ int main(int argc, char **argv, char **envp) qdev_machine_creation_done(); - rom_load_all(); + if (rom_load_all() != 0) { + fprintf(stderr, "rom loading failed\n"); + exit(1); + } qemu_system_reset(); if (loadvm) { diff --git a/vnchextile.h b/vnchextile.h index c96ede340..432ed89af 100644 --- a/vnchextile.h +++ b/vnchextile.h @@ -73,7 +73,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, *last_bg = bg; } - if (!*has_fg || *last_fg != fg) { + if (n_colors < 3 && (!*has_fg || *last_fg != fg)) { flags |= 0x04; *has_fg = 1; *last_fg = fg; @@ -165,8 +165,6 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, irow += ds_get_linesize(vs->ds) / sizeof(pixel_t); } - /* A SubrectsColoured subtile invalidates the foreground color */ - *has_fg = 0; if (n_data > (w * h * sizeof(pixel_t))) { n_colors = 4; flags = 0x01; |