diff options
author | Avi Kivity <avi@redhat.com> | 2009-08-02 12:00:28 +0300 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-08-02 12:00:28 +0300 |
commit | 5f09a0ae5e1b81890f8945336bf81ac11d2e2e8c (patch) | |
tree | aafb1e17428f8beb3c5691987c6d9c12ca0e190e | |
parent | 35f05eb1c81b56c888f7384d6296304360472474 (diff) | |
parent | 9eab386edbf8cf002a731f8204a156f243a47a57 (diff) |
Merge tag 'v0.10.6' of git://git.sv.gnu.org/qemu into stable-0.10qemu-kvm-0.10.6
* tag 'v0.10.6' of git://git.sv.gnu.org/qemu: (34 commits)
Update changelot for 0.10.6 release
Initialize PS2 keyboard / mouse state on reset
Reset HPET config register on hpet_reset
honor -S on incoming migration
Update for 0.10.6 release
Revert "Make sure to use SDL_CFLAGS everywhere we include SDL headers"
flush pending aio requests
Make sure to only vm_start() a failed migration if we were running to begin
Unregister savevm callback in eeprom93xx_free()
Don't leak VLANClientState on PCI hot remove
Substitute O_DSYNC with O_SYNC or O_FSYNC when needed.
sdl: Fix memory leakage
cpu_unregister_map_client: fix memory leak.
Fix vga_screen_dump_blank() PPM generation
Prevent CD-ROM media eject while device is locked
kvm: Fix IRQ injection into full queue
QEMU KVM: i386: Fix the cpu reset state
virtio blk: fix warning.
lsi53c895a: Implement write access to DMA Byte Counter
lsi53c895a: Implement read and write access to DMA Next Address
...
Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r-- | Changelog | 29 | ||||
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | aio.c | 8 | ||||
-rw-r--r-- | block-raw-posix.c | 6 | ||||
-rw-r--r-- | block.c | 9 | ||||
-rw-r--r-- | block.h | 2 | ||||
-rw-r--r-- | exec.c | 3 | ||||
-rw-r--r-- | hw/device-hotplug.c | 7 | ||||
-rw-r--r-- | hw/e1000.c | 11 | ||||
-rw-r--r-- | hw/eeprom93xx.c | 1 | ||||
-rw-r--r-- | hw/etraxfs_eth.c | 6 | ||||
-rw-r--r-- | hw/hpet.c | 1 | ||||
-rw-r--r-- | hw/hw.h | 1 | ||||
-rw-r--r-- | hw/ide.c | 26 | ||||
-rw-r--r-- | hw/lsi53c895a.c | 16 | ||||
-rw-r--r-- | hw/mcf_fec.c | 6 | ||||
-rw-r--r-- | hw/mipsnet.c | 7 | ||||
-rw-r--r-- | hw/ne2000.c | 6 | ||||
-rw-r--r-- | hw/ps2.c | 38 | ||||
-rw-r--r-- | hw/serial.c | 2 | ||||
-rw-r--r-- | hw/usb-net.c | 8 | ||||
-rw-r--r-- | hw/vga.c | 5 | ||||
-rw-r--r-- | hw/virtio-blk.c | 1 | ||||
-rw-r--r-- | kvm-all.c | 3 | ||||
-rw-r--r-- | loader.c | 4 | ||||
-rw-r--r-- | migration-exec.c | 35 | ||||
-rw-r--r-- | migration-tcp.c | 3 | ||||
-rw-r--r-- | migration.c | 9 | ||||
-rw-r--r-- | net.c | 2 | ||||
-rw-r--r-- | net.h | 1 | ||||
-rw-r--r-- | qemu-aio.h | 7 | ||||
-rw-r--r-- | savevm.c | 48 | ||||
-rw-r--r-- | sdl.c | 39 | ||||
-rw-r--r-- | target-i386/helper.c | 18 | ||||
-rw-r--r-- | vl.c | 4 | ||||
-rw-r--r-- | vnc.c | 3 |
36 files changed, 268 insertions, 109 deletions
@@ -1,3 +1,32 @@ +version 0.10.6: + - e1000: ignore reset command (Kevin Wolf) + - fix VNC memory allocation (Stefan Weil) + - fix raw_pread_aligned return value (Christoph Hellwig) + - allow monitor interaction when using -incoming exec: (Chris Lalancette) + - fix -net socket,listen (Jan Kiszka) + - live migration: don't send gratuitous packets all at once (Gleb Natapov) + - serial: fix lost characters after sysrq (Jason Wessel) + - Fix prototype of zfree (Stefan Weil) + - Handle EINTR with exec: migration (Uri Lublin) + - Delete io-handler before closing fd after migration (Uri Lublin) + - Fix qemu_aio_flush (Andrea Arcangeli) + - lsi53c895a: Implement additional registers (Sebastian Herbszt) + - virtio-blk: fix warning (Gerd Hoffman) + - i386: fix cpu reset (Nitin Kamble) + - kvm: fix irq injection into full queue (Jan Kiszka) + - Prevent CD-ROM eject while device is locked (Mark McLoughlin) + - Fix screen dump with blank screen (Eduardo Habkost) + - Fix memory leak with cpu_unregister_map_client (Isaku Yamahata) + - Fix memory leak in SDL (Jan Kiszka) + - Fix build on OS X 10.4 (John Arbuckle) + - Fix leak of vlan clients after hot remove (Mark McLoughlin) + - Fix migration after hot remove with eepro100 (Mark McLoughlin) + - Don't start a VM after failed migration if stopped (Anthony Liguori) + - Fix live migration under heavy IO load (Glauber Costa) + - Honor -S on incoming migration (Paolo Bonzini) + - Reset HPET config register on reset (Beth Kon) + - Reset PS2 keyboard/mouse on reset (Dinesh Subraveti) + version 0.10.5: - kvm: trim unsupported cpu features from cpuid (Avi Kivity) - kvm: provide a better error message for -smp > 1 (Mark McLoughlin) @@ -1 +1 @@ -0.10.5 +0.10.6 @@ -103,11 +103,15 @@ void qemu_aio_flush(void) do { ret = 0; + /* + * If there are pending emulated aio start them now so flush + * will be able to return 1. + */ + qemu_aio_wait(); + LIST_FOREACH(node, &aio_handlers, node) { ret |= node->io_flush(node->opaque); } - - qemu_aio_wait(); } while (ret > 0); } diff --git a/block-raw-posix.c b/block-raw-posix.c index 8f510deeb..3ec479727 100644 --- a/block-raw-posix.c +++ b/block-raw-posix.c @@ -76,7 +76,11 @@ /* OS X does not have O_DSYNC */ #ifndef O_DSYNC +#ifdef O_SYNC #define O_DSYNC O_SYNC +#elif defined(O_FSYNC) +#define O_DSYNC O_FSYNC +#endif #endif /* Approximate O_DIRECT with O_DSYNC if O_DIRECT isn't available */ @@ -235,7 +239,7 @@ static int raw_pread_aligned(BlockDriverState *bs, int64_t offset, label__raw_read__success: - return ret; + return (ret < 0) ? -errno : ret; } /* @@ -1673,11 +1673,15 @@ int bdrv_media_changed(BlockDriverState *bs) /** * If eject_flag is TRUE, eject the media. Otherwise, close the tray */ -void bdrv_eject(BlockDriverState *bs, int eject_flag) +int bdrv_eject(BlockDriverState *bs, int eject_flag) { BlockDriver *drv = bs->drv; int ret; + if (bs->locked) { + return -EBUSY; + } + if (!drv || !drv->bdrv_eject) { ret = -ENOTSUP; } else { @@ -1686,7 +1690,10 @@ void bdrv_eject(BlockDriverState *bs, int eject_flag) if (ret == -ENOTSUP) { if (eject_flag) bdrv_close(bs); + ret = 0; } + + return ret; } int bdrv_is_locked(BlockDriverState *bs) @@ -132,7 +132,7 @@ int bdrv_is_inserted(BlockDriverState *bs); int bdrv_media_changed(BlockDriverState *bs); int bdrv_is_locked(BlockDriverState *bs); void bdrv_set_locked(BlockDriverState *bs, int locked); -void bdrv_eject(BlockDriverState *bs, int eject_flag); +int bdrv_eject(BlockDriverState *bs, int eject_flag); void bdrv_set_change_cb(BlockDriverState *bs, void (*change_cb)(void *opaque), void *opaque); void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size); @@ -3141,6 +3141,7 @@ void cpu_unregister_map_client(void *_client) MapClient *client = (MapClient *)_client; LIST_REMOVE(client, link); + qemu_free(client); } static void cpu_notify_map_clients(void) @@ -3150,7 +3151,7 @@ static void cpu_notify_map_clients(void) while (!LIST_EMPTY(&map_client_list)) { client = LIST_FIRST(&map_client_list); client->callback(client->opaque); - LIST_REMOVE(client, link); + cpu_unregister_map_client(client); } } diff --git a/hw/device-hotplug.c b/hw/device-hotplug.c index 24ab5065a..f6245508a 100644 --- a/hw/device-hotplug.c +++ b/hw/device-hotplug.c @@ -63,12 +63,7 @@ void destroy_nic(dev_match_fn *match_fn, void *arg) nic = &nd_table[i]; if (nic->used) { if (nic->private && match_fn(nic->private, arg)) { - if (nic->vlan) { - VLANClientState *vc; - vc = qemu_find_vlan_client(nic->vlan, nic->private); - if (vc) - qemu_del_vlan_client(vc); - } + qemu_del_vlan_client(nic->vc); net_client_uninit(nic); } } diff --git a/hw/e1000.c b/hw/e1000.c index 10f220a64..f7bf37a58 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -191,6 +191,13 @@ rxbufsize(uint32_t v) } static void +set_ctrl(E1000State *s, int index, uint32_t val) +{ + /* RST is self clearing */ + s->mac_reg[CTRL] = val & ~E1000_CTRL_RST; +} + +static void set_rx_control(E1000State *s, int index, uint32_t val) { s->mac_reg[RCTL] = val; @@ -784,12 +791,12 @@ enum { NREADOPS = ARRAY_SIZE(macreg_readops) }; static void (*macreg_writeops[])(E1000State *, int, uint32_t) = { putreg(PBA), putreg(EERD), putreg(SWSM), putreg(WUFC), putreg(TDBAL), putreg(TDBAH), putreg(TXDCTL), putreg(RDBAH), - putreg(RDBAL), putreg(LEDCTL), putreg(CTRL), putreg(VET), + putreg(RDBAL), putreg(LEDCTL), putreg(VET), [TDLEN] = set_dlen, [RDLEN] = set_dlen, [TCTL] = set_tctl, [TDT] = set_tctl, [MDIC] = set_mdic, [ICS] = set_ics, [TDH] = set_16bit, [RDH] = set_16bit, [RDT] = set_rdt, [IMC] = set_imc, [IMS] = set_ims, [ICR] = set_icr, - [EECD] = set_eecd, [RCTL] = set_rx_control, + [EECD] = set_eecd, [RCTL] = set_rx_control, [CTRL] = set_ctrl, [RA ... RA+31] = &mac_writereg, [MTA ... MTA+127] = &mac_writereg, [VFTA ... VFTA+127] = &mac_writereg, diff --git a/hw/eeprom93xx.c b/hw/eeprom93xx.c index 896cffd44..6de970adf 100644 --- a/hw/eeprom93xx.c +++ b/hw/eeprom93xx.c @@ -301,6 +301,7 @@ void eeprom93xx_free(eeprom_t *eeprom) { /* Destroy EEPROM. */ logout("eeprom = 0x%p\n", eeprom); + unregister_savevm("eeprom", eeprom); qemu_free(eeprom); } diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c index bfc19262f..67568c35c 100644 --- a/hw/etraxfs_eth.c +++ b/hw/etraxfs_eth.c @@ -594,9 +594,9 @@ void *etraxfs_eth_init(NICInfo *nd, CPUState *env, eth->ethregs = cpu_register_io_memory(0, eth_read, eth_write, eth); cpu_register_physical_memory (base, 0x5c, eth->ethregs); - eth->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, - eth_receive, eth_can_receive, - eth_cleanup, eth); + eth->vc = nd->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, + eth_receive, eth_can_receive, + eth_cleanup, eth); eth->vc->opaque = eth; eth->vc->link_status_changed = eth_set_link; @@ -554,6 +554,7 @@ static void hpet_reset(void *opaque) { /* 64-bit main counter; 3 timers supported; LegacyReplacementRoute. */ s->capability = 0x8086a201ULL; s->capability |= ((HPET_CLK_PERIOD) << 32); + s->config = 0ULL; if (count > 0) /* we don't enable pit when hpet_reset is first called (by hpet_init) * because hpet is taking over for pit here. On subsequent invocations, @@ -37,6 +37,7 @@ QEMUFile *qemu_fopen(const char *filename, const char *mode); QEMUFile *qemu_fopen_socket(int fd); QEMUFile *qemu_popen(FILE *popen_file, const char *mode); QEMUFile *qemu_popen_cmd(const char *command, const char *mode); +int qemu_popen_fd(QEMUFile *f); void qemu_fflush(QEMUFile *f); int qemu_fclose(QEMUFile *f); void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size); @@ -359,6 +359,7 @@ #define ASC_INCOMPATIBLE_FORMAT 0x30 #define ASC_MEDIUM_NOT_PRESENT 0x3a #define ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39 +#define ASC_MEDIA_REMOVAL_PREVENTED 0x53 #define CFA_NO_ERROR 0x00 #define CFA_MISC_ERROR 0x09 @@ -1818,18 +1819,27 @@ static void ide_atapi_cmd(IDEState *s) break; case GPCMD_START_STOP_UNIT: { - int start, eject; + int start, eject, err = 0; start = packet[4] & 1; eject = (packet[4] >> 1) & 1; - if (eject && !start) { - /* eject the disk */ - bdrv_eject(s->bs, 1); - } else if (eject && start) { - /* close the tray */ - bdrv_eject(s->bs, 0); + if (eject) { + err = bdrv_eject(s->bs, !start); + } + + switch (err) { + case 0: + ide_atapi_cmd_ok(s); + break; + case -EBUSY: + ide_atapi_cmd_error(s, SENSE_NOT_READY, + ASC_MEDIA_REMOVAL_PREVENTED); + break; + default: + ide_atapi_cmd_error(s, SENSE_NOT_READY, + ASC_MEDIUM_NOT_PRESENT); + break; } - ide_atapi_cmd_ok(s); } break; case GPCMD_MECHANISM_STATUS: diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index 1f4f8b7ef..d4805c421 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -262,6 +262,7 @@ typedef struct { uint32_t sbc; uint32_t csbc; uint32_t scratch[18]; /* SCRATCHA-SCRATCHR */ + uint8_t sbr; /* Script ram is stored as 32-bit words in host byteorder. */ uint32_t script_ram[2048]; @@ -330,6 +331,7 @@ static void lsi_soft_reset(LSIState *s) s->ia = 0; s->sbc = 0; s->csbc = 0; + s->sbr = 0; } static int lsi_dma_40bit(LSIState *s) @@ -1400,6 +1402,7 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset) CASE_GET_REG24(dbc, 0x24) case 0x27: /* DCMD */ return s->dcmd; + CASE_GET_REG32(dnad, 0x28) CASE_GET_REG32(dsp, 0x2c) CASE_GET_REG32(dsps, 0x30) CASE_GET_REG32(scratch[0], 0x34) @@ -1407,6 +1410,8 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset) return s->dmode; case 0x39: /* DIEN */ return s->dien; + case 0x3a: /* SBR */ + return s->sbr; case 0x3b: /* DCNTL */ return s->dcntl; case 0x40: /* SIEN0 */ @@ -1486,6 +1491,11 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset) static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val) { +#define CASE_SET_REG24(name, addr) \ + case addr : s->name &= 0xffffff00; s->name |= val; break; \ + case addr + 1: s->name &= 0xffff00ff; s->name |= val << 8; break; \ + case addr + 2: s->name &= 0xff00ffff; s->name |= val << 16; break; + #define CASE_SET_REG32(name, addr) \ case addr : s->name &= 0xffffff00; s->name |= val; break; \ case addr + 1: s->name &= 0xffff00ff; s->name |= val << 8; break; \ @@ -1590,6 +1600,8 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val) } s->ctest5 = val; break; + CASE_SET_REG24(dbc, 0x24) + CASE_SET_REG32(dnad, 0x28) case 0x2c: /* DSP[0:7] */ s->dsp &= 0xffffff00; s->dsp |= val; @@ -1621,6 +1633,9 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val) s->dien = val; lsi_update_irq(s); break; + case 0x3a: /* SBR */ + s->sbr = val; + break; case 0x3b: /* DCNTL */ s->dcntl = val & ~(LSI_DCNTL_PFF | LSI_DCNTL_STD); if ((val & LSI_DCNTL_STD) && (s->istat1 & LSI_ISTAT1_SRUN) == 0) @@ -1700,6 +1715,7 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val) BADF("Unhandled writeb 0x%x = 0x%x\n", offset, val); } } +#undef CASE_SET_REG24 #undef CASE_SET_REG32 } diff --git a/hw/mcf_fec.c b/hw/mcf_fec.c index 1ca847b22..539495615 100644 --- a/hw/mcf_fec.c +++ b/hw/mcf_fec.c @@ -463,9 +463,9 @@ void mcf_fec_init(NICInfo *nd, target_phys_addr_t base, qemu_irq *irq) mcf_fec_writefn, s); cpu_register_physical_memory(base, 0x400, s->mmio_index); - s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, - mcf_fec_receive, mcf_fec_can_receive, - mcf_fec_cleanup, s); + s->vc = nd->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, + mcf_fec_receive, mcf_fec_can_receive, + mcf_fec_cleanup, s); memcpy(s->macaddr, nd->macaddr, 6); qemu_format_nic_info_str(s->vc, s->macaddr); } diff --git a/hw/mipsnet.c b/hw/mipsnet.c index e84298421..eba60e554 100644 --- a/hw/mipsnet.c +++ b/hw/mipsnet.c @@ -261,9 +261,10 @@ void mipsnet_init (int base, qemu_irq irq, NICInfo *nd) s->io_base = base; s->irq = irq; if (nd && nd->vlan) { - s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, - mipsnet_receive, mipsnet_can_receive, - mipsnet_cleanup, s); + s->vc = nd->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, + mipsnet_receive, + mipsnet_can_receive, + mipsnet_cleanup, s); } else { s->vc = NULL; } diff --git a/hw/ne2000.c b/hw/ne2000.c index 975951755..6f24fb71d 100644 --- a/hw/ne2000.c +++ b/hw/ne2000.c @@ -756,9 +756,9 @@ void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd) ne2000_reset(s); - s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, - ne2000_receive, ne2000_can_receive, - isa_ne2000_cleanup, s); + s->vc = nd->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, + ne2000_receive, ne2000_can_receive, + isa_ne2000_cleanup, s); qemu_format_nic_info_str(s->vc, s->macaddr); @@ -488,9 +488,8 @@ void ps2_write_mouse(void *opaque, int val) } } -static void ps2_reset(void *opaque) +static void ps2_common_reset(PS2State *s) { - PS2State *s = (PS2State *)opaque; PS2Queue *q; s->write_cmd = -1; q = &s->queue; @@ -500,6 +499,33 @@ static void ps2_reset(void *opaque) s->update_irq(s->update_arg, 0); } +static void ps2_kbd_reset(void *opaque) +{ + PS2KbdState *s = (PS2KbdState *) opaque; + + ps2_common_reset(&s->common); + s->scan_enabled = 0; + s->translate = 0; + s->scancode_set = 0; +} + +static void ps2_mouse_reset(void *opaque) +{ + PS2MouseState *s = (PS2MouseState *) opaque; + + ps2_common_reset(&s->common); + s->mouse_status = 0; + s->mouse_resolution = 0; + s->mouse_sample_rate = 0; + s->mouse_wrap = 0; + s->mouse_type = 0; + s->mouse_detect_state = 0; + s->mouse_dx = 0; + s->mouse_dy = 0; + s->mouse_dz = 0; + s->mouse_buttons = 0; +} + static void ps2_common_save (QEMUFile *f, PS2State *s) { qemu_put_be32 (f, s->write_cmd); @@ -590,10 +616,10 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg) s->common.update_irq = update_irq; s->common.update_arg = update_arg; s->scancode_set = 2; - ps2_reset(&s->common); + ps2_kbd_reset(s); register_savevm("ps2kbd", 0, 3, ps2_kbd_save, ps2_kbd_load, s); qemu_add_kbd_event_handler(ps2_put_keycode, s); - qemu_register_reset(ps2_reset, &s->common); + qemu_register_reset(ps2_kbd_reset, s); return s; } @@ -603,9 +629,9 @@ void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg) s->common.update_irq = update_irq; s->common.update_arg = update_arg; - ps2_reset(&s->common); + ps2_mouse_reset(s); register_savevm("ps2mouse", 0, 2, ps2_mouse_save, ps2_mouse_load, s); qemu_add_mouse_event_handler(ps2_mouse_event, s, 0, "QEMU PS/2 Mouse"); - qemu_register_reset(ps2_reset, &s->common); + qemu_register_reset(ps2_mouse_reset, s); return s; } diff --git a/hw/serial.c b/hw/serial.c index ac089fce6..113829c20 100644 --- a/hw/serial.c +++ b/hw/serial.c @@ -586,6 +586,8 @@ static int serial_can_receive(SerialState *s) static void serial_receive_break(SerialState *s) { s->rbr = 0; + /* When the LSR_DR is set a null byte is pushed into the fifo */ + fifo_put(s, RECV_FIFO, '\0'); s->lsr |= UART_LSR_BI | UART_LSR_DR; serial_update_irq(s); } diff --git a/hw/usb-net.c b/hw/usb-net.c index 9e6442506..60bddd1af 100644 --- a/hw/usb-net.c +++ b/hw/usb-net.c @@ -1457,10 +1457,10 @@ USBDevice *usb_net_init(NICInfo *nd) pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Network Interface"); - s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, - usbnet_receive, - usbnet_can_receive, - usbnet_cleanup, s); + s->vc = nd->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, + usbnet_receive, + usbnet_can_receive, + usbnet_cleanup, s); qemu_format_nic_info_str(s->vc, s->mac); @@ -2768,8 +2768,9 @@ static void vga_screen_dump_blank(VGAState *s, const char *filename) { FILE *f; unsigned int y, x, w, h; + unsigned char blank_sample[3] = { 0, 0, 0 }; - w = s->last_scr_width * sizeof(uint32_t); + w = s->last_scr_width; h = s->last_scr_height; f = fopen(filename, "wb"); @@ -2778,7 +2779,7 @@ static void vga_screen_dump_blank(VGAState *s, const char *filename) fprintf(f, "P6\n%d %d\n%d\n", w, h, 255); for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { - fputc(0, f); + fwrite(blank_sample, 3, 1, f); } } fclose(f); diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index 520ad1bf2..0b3c2ac62 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -247,6 +247,7 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config) bdrv_get_geometry(s->bs, &capacity); bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs); + memset(&blkcfg, 0, sizeof(blkcfg)); stq_raw(&blkcfg.capacity, capacity); stl_raw(&blkcfg.seg_max, 128 - 2); stw_raw(&blkcfg.cylinders, cylinders); @@ -451,14 +451,13 @@ int kvm_cpu_exec(CPUState *env) dprintf("kvm_cpu_exec()\n"); do { - kvm_arch_pre_run(env, run); - if (env->exit_request) { dprintf("interrupt exit requested\n"); ret = 0; break; } + kvm_arch_pre_run(env, run); ret = kvm_vcpu_ioctl(env, KVM_RUN, 0); kvm_arch_post_run(env, run); @@ -383,7 +383,7 @@ static void *zalloc(void *x, unsigned items, unsigned size) return (p); } -static void zfree(void *x, void *addr, unsigned nb) +static void zfree(void *x, void *addr) { qemu_free(addr); } @@ -431,7 +431,7 @@ static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src, } s.zalloc = zalloc; - s.zfree = (free_func)zfree; + s.zfree = zfree; r = inflateInit2(&s, -MAX_WBITS); if (r != Z_OK) { diff --git a/migration-exec.c b/migration-exec.c index 6ed322a98..2e7fdc21d 100644 --- a/migration-exec.c +++ b/migration-exec.c @@ -108,18 +108,11 @@ err_after_alloc: return NULL; } -int exec_start_incoming_migration(const char *command) +static void exec_accept_incoming_migration(void *opaque) { + QEMUFile *f = opaque; int ret; - QEMUFile *f; - dprintf("Attempting to start an incoming migration\n"); - f = qemu_popen_cmd(command, "r"); - if(f == NULL) { - dprintf("Unable to apply qemu wrapper to popen file\n"); - return -errno; - } - vm_stop(0); /* just in case */ ret = qemu_loadvm_state(f); if (ret < 0) { fprintf(stderr, "load of migration failed\n"); @@ -127,11 +120,27 @@ int exec_start_incoming_migration(const char *command) } qemu_announce_self(); dprintf("successfully loaded vm state\n"); - vm_start(); - qemu_fclose(f); - return 0; + /* we've successfully migrated, close the fd */ + qemu_set_fd_handler2(qemu_popen_fd(f), NULL, NULL, NULL, NULL); err: qemu_fclose(f); - return -errno; +} + +int exec_start_incoming_migration(const char *command) +{ + QEMUFile *f; + + dprintf("Attempting to start an incoming migration\n"); + f = qemu_popen_cmd(command, "r"); + if(f == NULL) { + dprintf("Unable to apply qemu wrapper to popen file\n"); + return -errno; + } + + qemu_set_fd_handler2(qemu_popen_fd(f), NULL, + exec_accept_incoming_migration, NULL, + (void *)(unsigned long)f); + + return 0; } diff --git a/migration-tcp.c b/migration-tcp.c index 3f5b1049c..0875c23c9 100644 --- a/migration-tcp.c +++ b/migration-tcp.c @@ -159,7 +159,6 @@ static void tcp_accept_incoming_migration(void *opaque) goto out; } - vm_stop(0); /* just in case */ ret = qemu_loadvm_state(f); if (ret < 0) { fprintf(stderr, "load of migration failed\n"); @@ -172,8 +171,6 @@ static void tcp_accept_incoming_migration(void *opaque) qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); close(s); - vm_start(); - out_fopen: qemu_fclose(f); out: diff --git a/migration.c b/migration.c index 06ea795cf..86ebbf0a2 100644 --- a/migration.c +++ b/migration.c @@ -213,12 +213,17 @@ void migrate_fd_put_ready(void *opaque) dprintf("iterate\n"); if (qemu_savevm_state_iterate(s->file) == 1) { int state; + int old_vm_running = vm_running; + dprintf("done iterating\n"); vm_stop(0); + qemu_aio_flush(); bdrv_flush_all(); if ((qemu_savevm_state_complete(s->file)) < 0) { - vm_start(); + if (old_vm_running) { + vm_start(); + } state = MIG_STATE_ERROR; } else { state = MIG_STATE_COMPLETED; @@ -283,5 +288,7 @@ void migrate_fd_wait_for_unfreeze(void *opaque) int migrate_fd_close(void *opaque) { FdMigrationState *s = opaque; + + qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); return s->close(s); } @@ -1658,7 +1658,7 @@ static int net_socket_listen_init(VLANState *vlan, } s->vlan = vlan; s->model = strdup(model); - s->name = strdup(name); + s->name = name ? strdup(name) : NULL; s->fd = fd; qemu_set_fd_handler(fd, net_socket_accept, NULL, s); return 0; @@ -73,6 +73,7 @@ struct NICInfo { const char *model; const char *name; VLANState *vlan; + VLANClientState *vc; void *private; int used; }; diff --git a/qemu-aio.h b/qemu-aio.h index 79678293e..f262344af 100644 --- a/qemu-aio.h +++ b/qemu-aio.h @@ -24,9 +24,10 @@ typedef int (AioFlushHandler)(void *opaque); * outstanding AIO operations have been completed or cancelled. */ void qemu_aio_flush(void); -/* Wait for a single AIO completion to occur. This function will until a - * single AIO opeartion has completed. It is intended to be used as a looping - * primative when simulating synchronous IO based on asynchronous IO. */ +/* Wait for a single AIO completion to occur. This function will wait + * until a single AIO event has completed and it will ensure something + * has moved before returning. This can issue new pending aio as + * result of executing I/O completion or bh callbacks. */ void qemu_aio_wait(void); /* Register a file descriptor and associated callbacks. Behaves very similarly @@ -103,31 +103,46 @@ static int announce_self_create(uint8_t *buf, /* FIXME: should we send a different packet (arp/rarp/ping)? */ + memset(buf, 0, 64); memset(buf, 0xff, 6); /* h_dst */ memcpy(buf + 6, mac_addr, 6); /* h_src */ memcpy(buf + 12, &proto, 2); /* h_proto */ memcpy(buf + 14, &magic, 4); /* magic */ - return 18; /* len */ + return 64; /* len */ } -void qemu_announce_self(void) +static void qemu_announce_self_once(void *opaque) { - int i, j, len; + int i, len; VLANState *vlan; VLANClientState *vc; uint8_t buf[256]; + static int count = SELF_ANNOUNCE_ROUNDS; + QEMUTimer *timer = *(QEMUTimer **)opaque; for (i = 0; i < MAX_NICS; i++) { if (!nd_table[i].used) continue; len = announce_self_create(buf, nd_table[i].macaddr); vlan = nd_table[i].vlan; - for(vc = vlan->first_client; vc != NULL; vc = vc->next) { - for (j=0; j < SELF_ANNOUNCE_ROUNDS; j++) - vc->fd_read(vc->opaque, buf, len); + for(vc = vlan->first_client; vc != NULL; vc = vc->next) { + vc->fd_read(vc->opaque, buf, len); } } + if (count--) { + qemu_mod_timer(timer, qemu_get_clock(rt_clock) + 100); + } else { + qemu_del_timer(timer); + qemu_free_timer(timer); + } +} + +void qemu_announce_self(void) +{ + static QEMUTimer *timer; + timer = qemu_new_timer(rt_clock, qemu_announce_self_once, &timer); + qemu_announce_self_once(&timer); } /***********************************************************/ @@ -195,7 +210,14 @@ static int popen_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int s static int popen_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size) { QEMUFilePopen *s = opaque; - return fread(buf, 1, size, s->popen_file); + FILE *fp = s->popen_file; + int bytes; + + do { + clearerr(fp); + bytes = fread(buf, 1, size, fp); + } while ((bytes == 0) && ferror(fp) && (errno == EINTR)); + return bytes; } static int popen_close(void *opaque) @@ -224,7 +246,6 @@ QEMUFile *qemu_popen(FILE *popen_file, const char *mode) } else { s->file = qemu_fopen_ops(s, popen_put_buffer, NULL, popen_close, NULL); } - fprintf(stderr, "qemu_popen: returning result of qemu_fopen_ops\n"); return s->file; } @@ -240,6 +261,17 @@ QEMUFile *qemu_popen_cmd(const char *command, const char *mode) return qemu_popen(popen_file, mode); } +int qemu_popen_fd(QEMUFile *f) +{ + QEMUFilePopen *p; + int fd; + + p = (QEMUFilePopen *)f->opaque; + fd = fileno(p->popen_file); + + return fd; +} + QEMUFile *qemu_fopen_socket(int fd) { QEMUFileSocket *s = qemu_mallocz(sizeof(QEMUFileSocket)); @@ -144,32 +144,35 @@ static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev) static int check_for_evdev(void) { SDL_SysWMinfo info; - XkbDescPtr desc; + XkbDescPtr desc = NULL; int has_evdev = 0; - const char *keycodes; + char *keycodes = NULL; SDL_VERSION(&info.version); - if (!SDL_GetWMInfo(&info)) + if (!SDL_GetWMInfo(&info)) { return 0; - + } desc = XkbGetKeyboard(info.info.x11.display, XkbGBN_AllComponentsMask, XkbUseCoreKbd); - if (desc == NULL || desc->names == NULL) - return 0; - - keycodes = XGetAtomName(info.info.x11.display, desc->names->keycodes); - if (keycodes == NULL) - fprintf(stderr, "could not lookup keycode name\n"); - else if (strstart(keycodes, "evdev", NULL)) - has_evdev = 1; - else if (!strstart(keycodes, "xfree86", NULL)) - fprintf(stderr, - "unknown keycodes `%s', please report to qemu-devel@nongnu.org\n", - keycodes); - - XkbFreeClientMap(desc, XkbGBN_AllComponentsMask, True); + if (desc && desc->names) { + keycodes = XGetAtomName(info.info.x11.display, desc->names->keycodes); + if (keycodes == NULL) { + fprintf(stderr, "could not lookup keycode name\n"); + } else if (strstart(keycodes, "evdev", NULL)) { + has_evdev = 1; + } else if (!strstart(keycodes, "xfree86", NULL)) { + fprintf(stderr, "unknown keycodes `%s', please report to " + "qemu-devel@nongnu.org\n", keycodes); + } + } + if (desc) { + XkbFreeKeyboard(desc, XkbGBN_AllComponentsMask, True); + } + if (keycodes) { + XFree(keycodes); + } return has_evdev; } #else diff --git a/target-i386/helper.c b/target-i386/helper.c index c783d6e71..5578f4169 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -501,17 +501,23 @@ void cpu_reset(CPUX86State *env) env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT); cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff, - DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK | DESC_R_MASK); + DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK | + DESC_R_MASK | DESC_A_MASK); cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff, - DESC_P_MASK | DESC_S_MASK | DESC_W_MASK); + DESC_P_MASK | DESC_S_MASK | DESC_W_MASK | + DESC_A_MASK); cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff, - DESC_P_MASK | DESC_S_MASK | DESC_W_MASK); + DESC_P_MASK | DESC_S_MASK | DESC_W_MASK | + DESC_A_MASK); cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff, - DESC_P_MASK | DESC_S_MASK | DESC_W_MASK); + DESC_P_MASK | DESC_S_MASK | DESC_W_MASK | + DESC_A_MASK); cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff, - DESC_P_MASK | DESC_S_MASK | DESC_W_MASK); + DESC_P_MASK | DESC_S_MASK | DESC_W_MASK | + DESC_A_MASK); cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff, - DESC_P_MASK | DESC_S_MASK | DESC_W_MASK); + DESC_P_MASK | DESC_S_MASK | DESC_W_MASK | + DESC_A_MASK); env->eip = 0xfff0; env->regs[R_EDX] = env->cpuid_version; @@ -6076,10 +6076,8 @@ int main(int argc, char **argv, char **envp) if (loadvm) do_loadvm(loadvm); - if (incoming) { - autostart = 0; /* fixme how to deal with -daemonize */ + if (incoming) qemu_start_incoming_migration(incoming); - } if (autostart) vm_start(); @@ -2306,9 +2306,8 @@ static void vnc_listen_read(void *opaque) void vnc_display_init(DisplayState *ds) { - VncDisplay *vs; + VncDisplay *vs = qemu_mallocz(sizeof(*vs)); - vs = qemu_mallocz(sizeof(VncState)); dcl = qemu_mallocz(sizeof(DisplayChangeListener)); ds->opaque = vs; |