aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2009-08-02 12:00:28 +0300
committerAvi Kivity <avi@redhat.com>2009-08-02 12:00:28 +0300
commit5f09a0ae5e1b81890f8945336bf81ac11d2e2e8c (patch)
treeaafb1e17428f8beb3c5691987c6d9c12ca0e190e
parent35f05eb1c81b56c888f7384d6296304360472474 (diff)
parent9eab386edbf8cf002a731f8204a156f243a47a57 (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--Changelog29
-rw-r--r--VERSION2
-rw-r--r--aio.c8
-rw-r--r--block-raw-posix.c6
-rw-r--r--block.c9
-rw-r--r--block.h2
-rw-r--r--exec.c3
-rw-r--r--hw/device-hotplug.c7
-rw-r--r--hw/e1000.c11
-rw-r--r--hw/eeprom93xx.c1
-rw-r--r--hw/etraxfs_eth.c6
-rw-r--r--hw/hpet.c1
-rw-r--r--hw/hw.h1
-rw-r--r--hw/ide.c26
-rw-r--r--hw/lsi53c895a.c16
-rw-r--r--hw/mcf_fec.c6
-rw-r--r--hw/mipsnet.c7
-rw-r--r--hw/ne2000.c6
-rw-r--r--hw/ps2.c38
-rw-r--r--hw/serial.c2
-rw-r--r--hw/usb-net.c8
-rw-r--r--hw/vga.c5
-rw-r--r--hw/virtio-blk.c1
-rw-r--r--kvm-all.c3
-rw-r--r--loader.c4
-rw-r--r--migration-exec.c35
-rw-r--r--migration-tcp.c3
-rw-r--r--migration.c9
-rw-r--r--net.c2
-rw-r--r--net.h1
-rw-r--r--qemu-aio.h7
-rw-r--r--savevm.c48
-rw-r--r--sdl.c39
-rw-r--r--target-i386/helper.c18
-rw-r--r--vl.c4
-rw-r--r--vnc.c3
36 files changed, 268 insertions, 109 deletions
diff --git a/Changelog b/Changelog
index feef3bb18..19a57b223 100644
--- a/Changelog
+++ b/Changelog
@@ -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)
diff --git a/VERSION b/VERSION
index 9028ec636..69da6ebcd 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.10.5
+0.10.6
diff --git a/aio.c b/aio.c
index 11fbb6c0c..dc9b85d16 100644
--- a/aio.c
+++ b/aio.c
@@ -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;
}
/*
diff --git a/block.c b/block.c
index 9a2873f62..863897a76 100644
--- a/block.c
+++ b/block.c
@@ -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)
diff --git a/block.h b/block.h
index 979781a12..e1070e9c3 100644
--- a/block.h
+++ b/block.h
@@ -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);
diff --git a/exec.c b/exec.c
index 29fea725f..22f75e54a 100644
--- a/exec.c
+++ b/exec.c
@@ -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;
diff --git a/hw/hpet.c b/hw/hpet.c
index c7945ecde..336c731bd 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -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,
diff --git a/hw/hw.h b/hw/hw.h
index d0cf59820..83ab3bcca 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -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);
diff --git a/hw/ide.c b/hw/ide.c
index 6ad1d081a..9b93e7f67 100644
--- a/hw/ide.c
+++ b/hw/ide.c
@@ -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);
diff --git a/hw/ps2.c b/hw/ps2.c
index fb7700523..0915b9faf 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -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);
diff --git a/hw/vga.c b/hw/vga.c
index b80ad7f8b..9f5d051fc 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -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);
diff --git a/kvm-all.c b/kvm-all.c
index 541b200e3..8e72c6d5a 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -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);
diff --git a/loader.c b/loader.c
index 55625cf5b..23bb03982 100644
--- a/loader.c
+++ b/loader.c
@@ -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);
}
diff --git a/net.c b/net.c
index ef3a96543..fee02b8c5 100644
--- a/net.c
+++ b/net.c
@@ -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;
diff --git a/net.h b/net.h
index 0740c4df4..5bb83bf6d 100644
--- a/net.h
+++ b/net.h
@@ -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
diff --git a/savevm.c b/savevm.c
index cd833504e..c7bc398d9 100644
--- a/savevm.c
+++ b/savevm.c
@@ -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));
diff --git a/sdl.c b/sdl.c
index 74f084c0f..95efe8df1 100644
--- a/sdl.c
+++ b/sdl.c
@@ -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;
diff --git a/vl.c b/vl.c
index 7379dbcae..1774d1c8b 100644
--- a/vl.c
+++ b/vl.c
@@ -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();
diff --git a/vnc.c b/vnc.c
index 783df8058..1d8ebe7b6 100644
--- a/vnc.c
+++ b/vnc.c
@@ -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;