Merge tag 'v0.10.6' of git://git.sv.gnu.org/qemu into stable-0.10

* 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>
diff --git a/Changelog b/Changelog
index feef3bb..19a57b2 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 9028ec6..69da6eb 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.10.5
+0.10.6
diff --git a/aio.c b/aio.c
index 11fbb6c..dc9b85d 100644
--- a/aio.c
+++ b/aio.c
@@ -103,11 +103,15 @@
     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 8f510de..3ec4797 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 @@
 
 label__raw_read__success:
 
-    return ret;
+    return  (ret < 0) ? -errno : ret;
 }
 
 /*
diff --git a/block.c b/block.c
index 9a2873f..863897a 100644
--- a/block.c
+++ b/block.c
@@ -1673,11 +1673,15 @@
 /**
  * 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 @@
     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 979781a..e1070e9 100644
--- a/block.h
+++ b/block.h
@@ -132,7 +132,7 @@
 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 29fea72..22f75e5 100644
--- a/exec.c
+++ b/exec.c
@@ -3141,6 +3141,7 @@
     MapClient *client = (MapClient *)_client;
 
     LIST_REMOVE(client, link);
+    qemu_free(client);
 }
 
 static void cpu_notify_map_clients(void)
@@ -3150,7 +3151,7 @@
     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 24ab506..f624550 100644
--- a/hw/device-hotplug.c
+++ b/hw/device-hotplug.c
@@ -63,12 +63,7 @@
         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 10f220a..f7bf37a 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -191,6 +191,13 @@
 }
 
 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 @@
 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 896cffd..6de970a 100644
--- a/hw/eeprom93xx.c
+++ b/hw/eeprom93xx.c
@@ -301,6 +301,7 @@
 {
     /* 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 bfc1926..67568c3 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -594,9 +594,9 @@
 	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 c7945ec..336c731 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -554,6 +554,7 @@
     /* 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 d0cf598..83ab3bc 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -37,6 +37,7 @@
 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 6ad1d08..9b93e7f 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 @@
         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);
             }
-            ide_atapi_cmd_ok(s);
+
+            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;
+            }
         }
         break;
     case GPCMD_MECHANISM_STATUS:
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 1f4f8b7..d4805c4 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -262,6 +262,7 @@
     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 @@
     s->ia = 0;
     s->sbc = 0;
     s->csbc = 0;
+    s->sbr = 0;
 }
 
 static int lsi_dma_40bit(LSIState *s)
@@ -1400,6 +1402,7 @@
     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 @@
         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 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 @@
         }
         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 @@
         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 @@
             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 1ca847b..5394956 100644
--- a/hw/mcf_fec.c
+++ b/hw/mcf_fec.c
@@ -463,9 +463,9 @@
                                            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 e842984..eba60e5 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -261,9 +261,10 @@
     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 9759517..6f24fb7 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -756,9 +756,9 @@
 
     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 fb77005..0915b9f 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -488,9 +488,8 @@
     }
 }
 
-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 @@
     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 @@
     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 @@
 
     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 ac089fc..113829c 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -586,6 +586,8 @@
 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 9e64425..60bddd1 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1457,10 +1457,10 @@
 
     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 b80ad7f..9f5d051 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2768,8 +2768,9 @@
 {
     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 @@
     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 520ad1b..0b3c2ac 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -247,6 +247,7 @@
 
     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 541b200..8e72c6d 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -451,14 +451,13 @@
     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 55625cf..23bb039 100644
--- a/loader.c
+++ b/loader.c
@@ -383,7 +383,7 @@
     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 @@
     }
 
     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 6ed322a..2e7fdc2 100644
--- a/migration-exec.c
+++ b/migration-exec.c
@@ -108,9 +108,27 @@
     return NULL;
 }
 
+static void exec_accept_incoming_migration(void *opaque)
+{
+    QEMUFile *f = opaque;
+    int ret;
+
+    ret = qemu_loadvm_state(f);
+    if (ret < 0) {
+        fprintf(stderr, "load of migration failed\n");
+        goto err;
+    }
+    qemu_announce_self();
+    dprintf("successfully loaded vm state\n");
+    /* we've successfully migrated, close the fd */
+    qemu_set_fd_handler2(qemu_popen_fd(f), NULL, NULL, NULL, NULL);
+
+err:
+    qemu_fclose(f);
+}
+
 int exec_start_incoming_migration(const char *command)
 {
-    int ret;
     QEMUFile *f;
 
     dprintf("Attempting to start an incoming migration\n");
@@ -119,19 +137,10 @@
         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");
-        goto err;
-    }
-    qemu_announce_self();
-    dprintf("successfully loaded vm state\n");
-    vm_start();
-    qemu_fclose(f);
-    return 0;
 
-err:
-    qemu_fclose(f);
-    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 3f5b104..0875c23 100644
--- a/migration-tcp.c
+++ b/migration-tcp.c
@@ -159,7 +159,6 @@
         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 @@
     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 06ea795..86ebbf0 100644
--- a/migration.c
+++ b/migration.c
@@ -213,12 +213,17 @@
     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 @@
 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 ef3a965..fee02b8 100644
--- a/net.c
+++ b/net.c
@@ -1658,7 +1658,7 @@
     }
     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 0740c4d..5bb83bf 100644
--- a/net.h
+++ b/net.h
@@ -73,6 +73,7 @@
     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 7967829..f262344 100644
--- a/qemu-aio.h
+++ b/qemu-aio.h
@@ -24,9 +24,10 @@
  * 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 cd83350..c7bc398 100644
--- a/savevm.c
+++ b/savevm.c
@@ -103,31 +103,46 @@
 
     /* 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_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 @@
     } 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 @@
     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 74f084c..95efe8d 100644
--- a/sdl.c
+++ b/sdl.c
@@ -144,32 +144,35 @@
 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;
+    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);
+        }
+    }
 
-    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) {
+        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 c783d6e..5578f41 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -501,17 +501,23 @@
     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 7379dbc..1774d1c 100644
--- a/vl.c
+++ b/vl.c
@@ -6076,10 +6076,8 @@
     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 783df80..1d8ebe7 100644
--- a/vnc.c
+++ b/vnc.c
@@ -2306,9 +2306,8 @@
 
 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;