summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--arm-semi.c113
-rw-r--r--block/raw-posix.c14
-rw-r--r--blockdev.c14
-rw-r--r--cpu-common.h12
-rw-r--r--cpu-exec.c4
-rw-r--r--cpus.c12
-rw-r--r--exec-all.h6
-rw-r--r--exec.c205
-rw-r--r--hw/esp.c2
-rw-r--r--hw/hpet.c2
-rw-r--r--hw/ide/core.c50
-rw-r--r--hw/intel-hda.c21
-rw-r--r--hw/msi.c2
-rw-r--r--hw/msix.c2
-rw-r--r--hw/pci_ids.h3
-rw-r--r--hw/piix_pci.c3
-rw-r--r--hw/pl080.c8
-rw-r--r--hw/ppc405_uc.c43
-rw-r--r--hw/qxl-logger.c4
-rw-r--r--hw/qxl.c50
-rw-r--r--hw/s390-virtio-bus.c14
-rw-r--r--hw/s390-virtio-bus.h1
-rw-r--r--hw/s390-virtio.c6
-rw-r--r--hw/spapr.h4
-rw-r--r--hw/spapr_hcall.c12
-rw-r--r--hw/vhost.c1
-rw-r--r--hw/virtio-blk.c29
-rw-r--r--hw/virtio-blk.h2
-rw-r--r--hw/virtio-console.c25
-rw-r--r--hw/virtio-pci.c4
-rw-r--r--hw/virtio-pci.h1
-rw-r--r--hw/virtio-serial-bus.c9
-rw-r--r--hw/virtio.c8
-rw-r--r--hw/virtio.h3
-rw-r--r--hw/xen_platform.c15
-rw-r--r--linux-user/alpha/syscall_nr.h23
-rw-r--r--linux-user/arm/syscall_nr.h13
-rw-r--r--linux-user/cris/syscall_nr.h2
-rw-r--r--linux-user/elfload.c6
-rw-r--r--linux-user/i386/syscall_nr.h12
-rw-r--r--linux-user/ioctls.h13
-rw-r--r--linux-user/m68k/syscall_nr.h16
-rw-r--r--linux-user/main.c33
-rw-r--r--linux-user/microblaze/syscall_nr.h14
-rw-r--r--linux-user/mips/syscall_nr.h13
-rw-r--r--linux-user/mips64/syscall_nr.h13
-rw-r--r--linux-user/mipsn32/syscall_nr.h14
-rw-r--r--linux-user/ppc/syscall_nr.h30
-rw-r--r--linux-user/s390x/syscall_nr.h13
-rw-r--r--linux-user/sh4/syscall_nr.h34
-rw-r--r--linux-user/signal.c30
-rw-r--r--linux-user/sparc/syscall_nr.h12
-rw-r--r--linux-user/sparc64/syscall_nr.h12
-rw-r--r--linux-user/syscall.c153
-rw-r--r--linux-user/syscall_defs.h51
-rw-r--r--linux-user/syscall_types.h20
-rw-r--r--linux-user/x86_64/syscall_nr.h12
-rw-r--r--os-posix.c6
-rw-r--r--qemu-common.h1
-rw-r--r--qemu-img-cmds.hx6
-rw-r--r--qemu-img.c80
-rw-r--r--qemu-img.texi6
-rw-r--r--target-alpha/cpu.h2
-rw-r--r--target-ppc/cpu.h2
-rw-r--r--target-sparc/cpu.h49
-rw-r--r--target-sparc/op_helper.c75
-rw-r--r--target-sparc/translate.c29
-rw-r--r--tcg/README10
-rw-r--r--trace-events11
-rw-r--r--ui/spice-core.c5
-rw-r--r--ui/spice-display.c5
71 files changed, 1212 insertions, 318 deletions
diff --git a/arm-semi.c b/arm-semi.c
index 5a62d03b36..873518a20e 100644
--- a/arm-semi.c
+++ b/arm-semi.c
@@ -34,6 +34,7 @@
 #else
 #include "qemu-common.h"
 #include "gdbstub.h"
+#include "hw/arm-misc.h"
 #endif
 
 #define SYS_OPEN        0x01
@@ -369,68 +370,88 @@ uint32_t do_arm_semihosting(CPUState *env)
         return syscall_err;
 #endif
     case SYS_GET_CMDLINE:
-#ifdef CONFIG_USER_ONLY
-        /* Build a commandline from the original argv.  */
         {
-            char *arm_cmdline_buffer;
-            const char *host_cmdline_buffer;
+            /* Build a command-line from the original argv.
+             *
+             * The inputs are:
+             *     * ARG(0), pointer to a buffer of at least the size
+             *               specified in ARG(1).
+             *     * ARG(1), size of the buffer pointed to by ARG(0) in
+             *               bytes.
+             *
+             * The outputs are:
+             *     * ARG(0), pointer to null-terminated string of the
+             *               command line.
+             *     * ARG(1), length of the string pointed to by ARG(0).
+             */
 
-            unsigned int i;
-            unsigned int arm_cmdline_len = ARG(1);
-            unsigned int host_cmdline_len =
-                ts->info->arg_end-ts->info->arg_start;
+            char *output_buffer;
+            size_t input_size = ARG(1);
+            size_t output_size;
+            int status = 0;
 
-            if (!arm_cmdline_len || host_cmdline_len > arm_cmdline_len) {
-                return -1; /* not enough space to store command line */
-            }
+            /* Compute the size of the output string.  */
+#if !defined(CONFIG_USER_ONLY)
+            output_size = strlen(ts->boot_info->kernel_filename)
+                        + 1  /* Separating space.  */
+                        + strlen(ts->boot_info->kernel_cmdline)
+                        + 1; /* Terminating null byte.  */
+#else
+            unsigned int i;
 
-            if (!host_cmdline_len) {
+            output_size = ts->info->arg_end - ts->info->arg_start;
+            if (!output_size) {
                 /* We special-case the "empty command line" case (argc==0).
                    Just provide the terminating 0. */
-                arm_cmdline_buffer = lock_user(VERIFY_WRITE, ARG(0), 1, 0);
-                arm_cmdline_buffer[0] = 0;
-                unlock_user(arm_cmdline_buffer, ARG(0), 1);
+                output_size = 1;
+            }
+#endif
 
-                /* Adjust the commandline length argument. */
-                SET_ARG(1, 0);
-                return 0;
+            if (output_size > input_size) {
+                 /* Not enough space to store command-line arguments.  */
+                return -1;
             }
 
-            /* lock the buffers on the ARM side */
-            arm_cmdline_buffer =
-                lock_user(VERIFY_WRITE, ARG(0), host_cmdline_len, 0);
-            host_cmdline_buffer =
-                lock_user(VERIFY_READ, ts->info->arg_start,
-                                       host_cmdline_len, 1);
+            /* Adjust the command-line length.  */
+            SET_ARG(1, output_size - 1);
 
-            if (arm_cmdline_buffer && host_cmdline_buffer)
-            {
-                /* the last argument is zero-terminated;
-                   no need for additional termination */
-                memcpy(arm_cmdline_buffer, host_cmdline_buffer,
-                       host_cmdline_len);
+            /* Lock the buffer on the ARM side.  */
+            output_buffer = lock_user(VERIFY_WRITE, ARG(0), output_size, 0);
+            if (!output_buffer) {
+                return -1;
+            }
 
-                /* separate arguments by white spaces */
-                for (i = 0; i < host_cmdline_len-1; i++) {
-                    if (arm_cmdline_buffer[i] == 0) {
-                        arm_cmdline_buffer[i] = ' ';
-                    }
-                }
+            /* Copy the command-line arguments.  */
+#if !defined(CONFIG_USER_ONLY)
+            pstrcpy(output_buffer, output_size, ts->boot_info->kernel_filename);
+            pstrcat(output_buffer, output_size, " ");
+            pstrcat(output_buffer, output_size, ts->boot_info->kernel_cmdline);
+#else
+            if (output_size == 1) {
+                /* Empty command-line.  */
+                output_buffer[0] = '\0';
+                goto out;
+            }
 
-                /* Adjust the commandline length argument. */
-                SET_ARG(1, host_cmdline_len-1);
+            if (copy_from_user(output_buffer, ts->info->arg_start,
+                               output_size)) {
+                status = -1;
+                goto out;
             }
 
-            /* Unlock the buffers on the ARM side.  */
-            unlock_user(arm_cmdline_buffer, ARG(0), host_cmdline_len);
-            unlock_user((void*)host_cmdline_buffer, ts->info->arg_start, 0);
+            /* Separate arguments by white spaces.  */
+            for (i = 0; i < output_size - 1; i++) {
+                if (output_buffer[i] == 0) {
+                    output_buffer[i] = ' ';
+                }
+            }
+        out:
+#endif
+            /* Unlock the buffer on the ARM side.  */
+            unlock_user(output_buffer, ARG(0), output_size);
 
-            /* Return success if we could return a commandline.  */
-            return (arm_cmdline_buffer && host_cmdline_buffer) ? 0 : -1;
+            return status;
         }
-#else
-        return -1;
-#endif
     case SYS_HEAPINFO:
         {
             uint32_t *ptr;
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 4cd7d7afbb..34b64aa205 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -46,6 +46,8 @@
 #include <sys/dkio.h>
 #endif
 #ifdef __linux__
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/param.h>
 #include <linux/cdrom.h>
@@ -1188,6 +1190,7 @@ static int floppy_probe_device(const char *filename)
     int fd, ret;
     int prio = 0;
     struct floppy_struct fdparam;
+    struct stat st;
 
     if (strstart(filename, "/dev/fd", NULL))
         prio = 50;
@@ -1196,12 +1199,17 @@ static int floppy_probe_device(const char *filename)
     if (fd < 0) {
         goto out;
     }
+    ret = fstat(fd, &st);
+    if (ret == -1 || !S_ISBLK(st.st_mode)) {
+        goto outc;
+    }
 
     /* Attempt to detect via a floppy specific ioctl */
     ret = ioctl(fd, FDGETPRM, &fdparam);
     if (ret >= 0)
         prio = 100;
 
+outc:
     close(fd);
 out:
     return prio;
@@ -1290,17 +1298,23 @@ static int cdrom_probe_device(const char *filename)
 {
     int fd, ret;
     int prio = 0;
+    struct stat st;
 
     fd = open(filename, O_RDONLY | O_NONBLOCK);
     if (fd < 0) {
         goto out;
     }
+    ret = fstat(fd, &st);
+    if (ret == -1 || !S_ISBLK(st.st_mode)) {
+        goto outc;
+    }
 
     /* Attempt to detect via a CDROM specific ioctl */
     ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
     if (ret >= 0)
         prio = 100;
 
+outc:
     close(fd);
 out:
     return prio;
diff --git a/blockdev.c b/blockdev.c
index 7d579d6124..a97a801e95 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -240,14 +240,6 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
     int ret;
 
     translation = BIOS_ATA_TRANSLATION_AUTO;
-
-    if (default_to_scsi) {
-        type = IF_SCSI;
-        pstrcpy(devname, sizeof(devname), "scsi");
-    } else {
-        type = IF_IDE;
-        pstrcpy(devname, sizeof(devname), "ide");
-    }
     media = MEDIA_DISK;
 
     /* extract parameters */
@@ -273,7 +265,11 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
             error_report("unsupported bus type '%s'", buf);
             return NULL;
 	}
+    } else {
+        type = default_to_scsi ? IF_SCSI : IF_IDE;
+        pstrcpy(devname, sizeof(devname), if_name[type]);
     }
+
     max_devs = if_max_devs[type];
 
     if (cyls || heads || secs) {
@@ -314,7 +310,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
 	    media = MEDIA_DISK;
 	} else if (!strcmp(buf, "cdrom")) {
             if (cyls || secs || heads) {
-                error_report("'%s' invalid physical CHS format", buf);
+                error_report("CHS can't be set with media=%s", buf);
 	        return NULL;
             }
 	    media = MEDIA_CDROM;
diff --git a/cpu-common.h b/cpu-common.h
index b027e43088..c6a2b5fbb9 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -135,14 +135,26 @@ void qemu_flush_coalesced_mmio_buffer(void);
 
 uint32_t ldub_phys(target_phys_addr_t addr);
 uint32_t lduw_phys(target_phys_addr_t addr);
+uint32_t lduw_le_phys(target_phys_addr_t addr);
+uint32_t lduw_be_phys(target_phys_addr_t addr);
 uint32_t ldl_phys(target_phys_addr_t addr);
+uint32_t ldl_le_phys(target_phys_addr_t addr);
+uint32_t ldl_be_phys(target_phys_addr_t addr);
 uint64_t ldq_phys(target_phys_addr_t addr);
+uint64_t ldq_le_phys(target_phys_addr_t addr);
+uint64_t ldq_be_phys(target_phys_addr_t addr);
 void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val);
 void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val);
 void stb_phys(target_phys_addr_t addr, uint32_t val);
 void stw_phys(target_phys_addr_t addr, uint32_t val);
+void stw_le_phys(target_phys_addr_t addr, uint32_t val);
+void stw_be_phys(target_phys_addr_t addr, uint32_t val);
 void stl_phys(target_phys_addr_t addr, uint32_t val);
+void stl_le_phys(target_phys_addr_t addr, uint32_t val);
+void stl_be_phys(target_phys_addr_t addr, uint32_t val);
 void stq_phys(target_phys_addr_t addr, uint64_t val);
+void stq_le_phys(target_phys_addr_t addr, uint64_t val);
+void stq_be_phys(target_phys_addr_t addr, uint64_t val);
 
 void cpu_physical_memory_write_rom(target_phys_addr_t addr,
                                    const uint8_t *buf, int len);
diff --git a/cpu-exec.c b/cpu-exec.c
index 20e3ec41d7..de0d716da0 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -587,6 +587,10 @@ int cpu_exec(CPUState *env)
                 /* reset soft MMU for next block (it can currently
                    only be set by a memory fault) */
             } /* for(;;) */
+        } else {
+            /* Reload env after longjmp - the compiler may have smashed all
+             * local variables as longjmp is marked 'noreturn'. */
+            env = cpu_single_env;
         }
     } /* for(;;) */
 
diff --git a/cpus.c b/cpus.c
index abd24ab31c..3035314486 100644
--- a/cpus.c
+++ b/cpus.c
@@ -396,12 +396,19 @@ static int qemu_signal_init(void)
     sigaddset(&set, SIGUSR2);
     pthread_sigmask(SIG_UNBLOCK, &set, NULL);
 
+    /*
+     * SIG_IPI must be blocked in the main thread and must not be caught
+     * by sigwait() in the signal thread. Otherwise, the cpu thread will
+     * not catch it reliably.
+     */
+    sigemptyset(&set);
+    sigaddset(&set, SIG_IPI);
+    pthread_sigmask(SIG_BLOCK, &set, NULL);
+
     sigemptyset(&set);
     sigaddset(&set, SIGIO);
     sigaddset(&set, SIGALRM);
-    sigaddset(&set, SIG_IPI);
     sigaddset(&set, SIGBUS);
-    pthread_sigmask(SIG_BLOCK, &set, NULL);
 #else
     sigemptyset(&set);
     sigaddset(&set, SIGBUS);
@@ -414,6 +421,7 @@ static int qemu_signal_init(void)
         sigaddset(&set, SIGALRM);
     }
 #endif
+    pthread_sigmask(SIG_BLOCK, &set, NULL);
 
     sigfd = qemu_signalfd(&set);
     if (sigfd == -1) {
diff --git a/exec-all.h b/exec-all.h
index 21a69d68ad..69acf3b97d 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -44,11 +44,7 @@ struct TranslationBlock;
 typedef struct TranslationBlock TranslationBlock;
 
 /* XXX: make safe guess about sizes */
-#if (HOST_LONG_BITS == 32) && (TARGET_LONG_BITS == 64)
-#define MAX_OP_PER_INSTR 128
-#else
-#define MAX_OP_PER_INSTR 96
-#endif
+#define MAX_OP_PER_INSTR 208
 
 #if HOST_LONG_BITS == 32
 #define MAX_OPC_PARAM_PER_ARG 2
diff --git a/exec.c b/exec.c
index 4c45299906..f1777e6239 100644
--- a/exec.c
+++ b/exec.c
@@ -555,8 +555,8 @@ static void code_gen_alloc(unsigned long tb_size)
 #endif
 #endif /* !USE_STATIC_CODE_GEN_BUFFER */
     map_exec(code_gen_prologue, sizeof(code_gen_prologue));
-    code_gen_buffer_max_size = code_gen_buffer_size - 
-        (TCG_MAX_OP_SIZE * OPC_MAX_SIZE);
+    code_gen_buffer_max_size = code_gen_buffer_size -
+        (TCG_MAX_OP_SIZE * OPC_BUF_SIZE);
     code_gen_max_blocks = code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE;
     tbs = qemu_malloc(code_gen_max_blocks * sizeof(TranslationBlock));
 }
@@ -4127,7 +4127,8 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
 }
 
 /* warning: addr must be aligned */
-uint32_t ldl_phys(target_phys_addr_t addr)
+static inline uint32_t ldl_phys_internal(target_phys_addr_t addr,
+                                         enum device_endian endian)
 {
     int io_index;
     uint8_t *ptr;
@@ -4149,17 +4150,52 @@ uint32_t ldl_phys(target_phys_addr_t addr)
         if (p)
             addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
         val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
+#if defined(TARGET_WORDS_BIGENDIAN)
+        if (endian == DEVICE_LITTLE_ENDIAN) {
+            val = bswap32(val);
+        }
+#else
+        if (endian == DEVICE_BIG_ENDIAN) {
+            val = bswap32(val);
+        }
+#endif
     } else {
         /* RAM case */
         ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
             (addr & ~TARGET_PAGE_MASK);
-        val = ldl_p(ptr);
+        switch (endian) {
+        case DEVICE_LITTLE_ENDIAN:
+            val = ldl_le_p(ptr);
+            break;
+        case DEVICE_BIG_ENDIAN:
+            val = ldl_be_p(ptr);
+            break;
+        default:
+            val = ldl_p(ptr);
+            break;
+        }
     }
     return val;
 }
 
+uint32_t ldl_phys(target_phys_addr_t addr)
+{
+    return ldl_phys_internal(addr, DEVICE_NATIVE_ENDIAN);
+}
+
+uint32_t ldl_le_phys(target_phys_addr_t addr)
+{
+    return ldl_phys_internal(addr, DEVICE_LITTLE_ENDIAN);
+}
+
+uint32_t ldl_be_phys(target_phys_addr_t addr)
+{
+    return ldl_phys_internal(addr, DEVICE_BIG_ENDIAN);
+}
+
 /* warning: addr must be aligned */
-uint64_t ldq_phys(target_phys_addr_t addr)
+static inline uint64_t ldq_phys_internal(target_phys_addr_t addr,
+                                         enum device_endian endian)
 {
     int io_index;
     uint8_t *ptr;
@@ -4180,6 +4216,9 @@ uint64_t ldq_phys(target_phys_addr_t addr)
         io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
         if (p)
             addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+
+        /* XXX This is broken when device endian != cpu endian.
+               Fix and add "endian" variable check */
 #ifdef TARGET_WORDS_BIGENDIAN
         val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) << 32;
         val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4);
@@ -4191,11 +4230,36 @@ uint64_t ldq_phys(target_phys_addr_t addr)
         /* RAM case */
         ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
             (addr & ~TARGET_PAGE_MASK);
-        val = ldq_p(ptr);
+        switch (endian) {
+        case DEVICE_LITTLE_ENDIAN:
+            val = ldq_le_p(ptr);
+            break;
+        case DEVICE_BIG_ENDIAN:
+            val = ldq_be_p(ptr);
+            break;
+        default:
+            val = ldq_p(ptr);
+            break;
+        }
     }
     return val;
 }
 
+uint64_t ldq_phys(target_phys_addr_t addr)
+{
+    return ldq_phys_internal(addr, DEVICE_NATIVE_ENDIAN);
+}
+
+uint64_t ldq_le_phys(target_phys_addr_t addr)
+{
+    return ldq_phys_internal(addr, DEVICE_LITTLE_ENDIAN);
+}
+
+uint64_t ldq_be_phys(target_phys_addr_t addr)
+{
+    return ldq_phys_internal(addr, DEVICE_BIG_ENDIAN);
+}
+
 /* XXX: optimize */
 uint32_t ldub_phys(target_phys_addr_t addr)
 {
@@ -4205,7 +4269,8 @@ uint32_t ldub_phys(target_phys_addr_t addr)
 }
 
 /* warning: addr must be aligned */
-uint32_t lduw_phys(target_phys_addr_t addr)
+static inline uint32_t lduw_phys_internal(target_phys_addr_t addr,
+                                          enum device_endian endian)
 {
     int io_index;
     uint8_t *ptr;
@@ -4227,15 +4292,49 @@ uint32_t lduw_phys(target_phys_addr_t addr)
         if (p)
             addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
         val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
+#if defined(TARGET_WORDS_BIGENDIAN)
+        if (endian == DEVICE_LITTLE_ENDIAN) {
+            val = bswap16(val);
+        }
+#else
+        if (endian == DEVICE_BIG_ENDIAN) {
+            val = bswap16(val);
+        }
+#endif
     } else {
         /* RAM case */
         ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
             (addr & ~TARGET_PAGE_MASK);
-        val = lduw_p(ptr);
+        switch (endian) {
+        case DEVICE_LITTLE_ENDIAN:
+            val = lduw_le_p(ptr);
+            break;
+        case DEVICE_BIG_ENDIAN:
+            val = lduw_be_p(ptr);
+            break;
+        default:
+            val = lduw_p(ptr);
+            break;
+        }
     }
     return val;
 }
 
+uint32_t lduw_phys(target_phys_addr_t addr)
+{
+    return lduw_phys_internal(addr, DEVICE_NATIVE_ENDIAN);
+}
+
+uint32_t lduw_le_phys(target_phys_addr_t addr)
+{
+    return lduw_phys_internal(addr, DEVICE_LITTLE_ENDIAN);
+}
+
+uint32_t lduw_be_phys(target_phys_addr_t addr)
+{
+    return lduw_phys_internal(addr, DEVICE_BIG_ENDIAN);
+}
+
 /* warning: addr must be aligned. The ram page is not masked as dirty
    and the code inside is not invalidated. It is useful if the dirty
    bits are used to track modified PTEs */
@@ -4308,7 +4407,8 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
 }
 
 /* warning: addr must be aligned */
-void stl_phys(target_phys_addr_t addr, uint32_t val)
+static inline void stl_phys_internal(target_phys_addr_t addr, uint32_t val,
+                                     enum device_endian endian)
 {
     int io_index;
     uint8_t *ptr;
@@ -4326,13 +4426,32 @@ void stl_phys(target_phys_addr_t addr, uint32_t val)
         io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
         if (p)
             addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+#if defined(TARGET_WORDS_BIGENDIAN)
+        if (endian == DEVICE_LITTLE_ENDIAN) {
+            val = bswap32(val);
+        }
+#else
+        if (endian == DEVICE_BIG_ENDIAN) {
+            val = bswap32(val);
+        }
+#endif
         io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
     } else {
         unsigned long addr1;
         addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
         /* RAM case */
         ptr = qemu_get_ram_ptr(addr1);
-        stl_p(ptr, val);
+        switch (endian) {
+        case DEVICE_LITTLE_ENDIAN:
+            stl_le_p(ptr, val);
+            break;
+        case DEVICE_BIG_ENDIAN:
+            stl_be_p(ptr, val);
+            break;
+        default:
+            stl_p(ptr, val);
+            break;
+        }
         if (!cpu_physical_memory_is_dirty(addr1)) {
             /* invalidate code */
             tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
@@ -4343,6 +4462,21 @@ void stl_phys(target_phys_addr_t addr, uint32_t val)
     }
 }
 
+void stl_phys(target_phys_addr_t addr, uint32_t val)
+{
+    stl_phys_internal(addr, val, DEVICE_NATIVE_ENDIAN);
+}
+
+void stl_le_phys(target_phys_addr_t addr, uint32_t val)
+{
+    stl_phys_internal(addr, val, DEVICE_LITTLE_ENDIAN);
+}
+
+void stl_be_phys(target_phys_addr_t addr, uint32_t val)
+{
+    stl_phys_internal(addr, val, DEVICE_BIG_ENDIAN);
+}
+
 /* XXX: optimize */
 void stb_phys(target_phys_addr_t addr, uint32_t val)
 {
@@ -4351,7 +4485,8 @@ void stb_phys(target_phys_addr_t addr, uint32_t val)
 }
 
 /* warning: addr must be aligned */
-void stw_phys(target_phys_addr_t addr, uint32_t val)
+static inline void stw_phys_internal(target_phys_addr_t addr, uint32_t val,
+                                     enum device_endian endian)
 {
     int io_index;
     uint8_t *ptr;
@@ -4369,13 +4504,32 @@ void stw_phys(target_phys_addr_t addr, uint32_t val)
         io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
         if (p)
             addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+#if defined(TARGET_WORDS_BIGENDIAN)
+        if (endian == DEVICE_LITTLE_ENDIAN) {
+            val = bswap16(val);
+        }
+#else
+        if (endian == DEVICE_BIG_ENDIAN) {
+            val = bswap16(val);
+        }
+#endif
         io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
     } else {
         unsigned long addr1;
         addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
         /* RAM case */
         ptr = qemu_get_ram_ptr(addr1);
-        stw_p(ptr, val);
+        switch (endian) {
+        case DEVICE_LITTLE_ENDIAN:
+            stw_le_p(ptr, val);
+            break;
+        case DEVICE_BIG_ENDIAN:
+            stw_be_p(ptr, val);
+            break;
+        default:
+            stw_p(ptr, val);
+            break;
+        }
         if (!cpu_physical_memory_is_dirty(addr1)) {
             /* invalidate code */
             tb_invalidate_phys_page_range(addr1, addr1 + 2, 0);
@@ -4386,6 +4540,21 @@ void stw_phys(target_phys_addr_t addr, uint32_t val)
     }
 }
 
+void stw_phys(target_phys_addr_t addr, uint32_t val)
+{
+    stw_phys_internal(addr, val, DEVICE_NATIVE_ENDIAN);
+}
+
+void stw_le_phys(target_phys_addr_t addr, uint32_t val)
+{
+    stw_phys_internal(addr, val, DEVICE_LITTLE_ENDIAN);
+}
+
+void stw_be_phys(target_phys_addr_t addr, uint32_t val)
+{
+    stw_phys_internal(addr, val, DEVICE_BIG_ENDIAN);
+}
+
 /* XXX: optimize */
 void stq_phys(target_phys_addr_t addr, uint64_t val)
 {
@@ -4393,6 +4562,18 @@ void stq_phys(target_phys_addr_t addr, uint64_t val)
     cpu_physical_memory_write(addr, &val, 8);
 }
 
+void stq_le_phys(target_phys_addr_t addr, uint64_t val)
+{
+    val = cpu_to_le64(val);
+    cpu_physical_memory_write(addr, &val, 8);
+}
+
+void stq_be_phys(target_phys_addr_t addr, uint64_t val)
+{
+    val = cpu_to_be64(val);
+    cpu_physical_memory_write(addr, &val, 8);
+}
+
 /* virtual memory access for debug (includes writing to ROM) */
 int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
                         uint8_t *buf, int len, int is_write)
diff --git a/hw/esp.c b/hw/esp.c
index 8e95672f0e..aa50800a56 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -219,7 +219,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
     s->ti_rptr = 0;
     s->ti_wptr = 0;
 
-    if (s->current_dev) {
+    if (s->current_req) {
         /* Started a new command before the old one finished.  Cancel it.  */
         scsi_req_cancel(s->current_req);
         s->async_len = 0;
diff --git a/hw/hpet.c b/hw/hpet.c
index ef9a2a0cad..4eda33d900 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -192,7 +192,7 @@ static void update_irq(struct HPETTimer *timer, int set)
             qemu_irq_lower(s->irqs[route]);
         }
     } else if (timer_fsb_route(timer)) {
-        stl_phys(timer->fsb >> 32, timer->fsb & 0xffffffff);
+        stl_le_phys(timer->fsb >> 32, timer->fsb & 0xffffffff);
     } else if (timer->config & HPET_TN_TYPE_LEVEL) {
         s->isr |= mask;
         qemu_irq_raise(s->irqs[route]);
diff --git a/hw/ide/core.c b/hw/ide/core.c
index ca17a436c0..d145b19b0c 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -56,6 +56,7 @@ static const int smart_attributes[][12] = {
 };
 
 static int ide_handle_rw_error(IDEState *s, int error, int op);
+static void ide_dummy_transfer_stop(IDEState *s);
 
 static void padstr(char *str, const char *src, int len)
 {
@@ -1532,15 +1533,36 @@ void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
     bus->cmd = val;
 }
 
+/*
+ * Returns true if the running PIO transfer is a PIO out (i.e. data is
+ * transferred from the device to the guest), false if it's a PIO in
+ */
+static bool ide_is_pio_out(IDEState *s)
+{
+    if (s->end_transfer_func == ide_sector_write ||
+        s->end_transfer_func == ide_atapi_cmd) {
+        return false;
+    } else if (s->end_transfer_func == ide_sector_read ||
+               s->end_transfer_func == ide_transfer_stop ||
+               s->end_transfer_func == ide_atapi_cmd_reply_end ||
+               s->end_transfer_func == ide_dummy_transfer_stop) {
+        return true;
+    }
+
+    abort();
+}
+
 void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
 {
     IDEBus *bus = opaque;
     IDEState *s = idebus_active_if(bus);
     uint8_t *p;
 
-    /* PIO data access allowed only when DRQ bit is set */
-    if (!(s->status & DRQ_STAT))
+    /* PIO data access allowed only when DRQ bit is set. The result of a write
+     * during PIO out is indeterminate, just ignore it. */
+    if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
         return;
+    }
 
     p = s->data_ptr;
     *(uint16_t *)p = le16_to_cpu(val);
@@ -1557,9 +1579,11 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr)
     uint8_t *p;
     int ret;
 
-    /* PIO data access allowed only when DRQ bit is set */
-    if (!(s->status & DRQ_STAT))
+    /* PIO data access allowed only when DRQ bit is set. The result of a read
+     * during PIO in is indeterminate, return 0 and don't move forward. */
+    if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {
         return 0;
+    }
 
     p = s->data_ptr;
     ret = cpu_to_le16(*(uint16_t *)p);
@@ -1576,9 +1600,11 @@ void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
     IDEState *s = idebus_active_if(bus);
     uint8_t *p;
 
-    /* PIO data access allowed only when DRQ bit is set */
-    if (!(s->status & DRQ_STAT))
+    /* PIO data access allowed only when DRQ bit is set. The result of a write
+     * during PIO out is indeterminate, just ignore it. */
+    if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
         return;
+    }
 
     p = s->data_ptr;
     *(uint32_t *)p = le32_to_cpu(val);
@@ -1595,9 +1621,11 @@ uint32_t ide_data_readl(void *opaque, uint32_t addr)
     uint8_t *p;
     int ret;
 
-    /* PIO data access allowed only when DRQ bit is set */
-    if (!(s->status & DRQ_STAT))
+    /* PIO data access allowed only when DRQ bit is set. The result of a read
+     * during PIO in is indeterminate, return 0 and don't move forward. */
+    if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {
         return 0;
+    }
 
     p = s->data_ptr;
     ret = cpu_to_le32(*(uint32_t *)p);
@@ -1761,9 +1789,13 @@ static void ide_init1(IDEBus *bus, int unit)
     s->unit = unit;
     s->drive_serial = drive_serial++;
     /* we need at least 2k alignment for accessing CDROMs using O_DIRECT */
-    s->io_buffer = qemu_memalign(2048, IDE_DMA_BUF_SECTORS*512 + 4);
     s->io_buffer_total_len = IDE_DMA_BUF_SECTORS*512 + 4;
+    s->io_buffer = qemu_memalign(2048, s->io_buffer_total_len);
+    memset(s->io_buffer, 0, s->io_buffer_total_len);
+
     s->smart_selftest_data = qemu_blockalign(s->bs, 512);
+    memset(s->smart_selftest_data, 0, 512);
+
     s->sector_write_timer = qemu_new_timer_ns(vm_clock,
                                            ide_sector_write_timer_cb, s);
 }
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 0ffffce90e..5a2bc3aaa9 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -224,19 +224,6 @@ static target_phys_addr_t intel_hda_addr(uint32_t lbase, uint32_t ubase)
     return addr;
 }
 
-static void stl_phys_le(target_phys_addr_t addr, uint32_t value)
-{
-    uint32_t value_le = cpu_to_le32(value);
-    cpu_physical_memory_write(addr, (uint8_t*)(&value_le), sizeof(value_le));
-}
-
-static uint32_t ldl_phys_le(target_phys_addr_t addr)
-{
-    uint32_t value_le;
-    cpu_physical_memory_read(addr, (uint8_t*)(&value_le), sizeof(value_le));
-    return le32_to_cpu(value_le);
-}
-
 static void intel_hda_update_int_sts(IntelHDAState *d)
 {
     uint32_t sts = 0;
@@ -341,7 +328,7 @@ static void intel_hda_corb_run(IntelHDAState *d)
 
         rp = (d->corb_rp + 1) & 0xff;
         addr = intel_hda_addr(d->corb_lbase, d->corb_ubase);
-        verb = ldl_phys_le(addr + 4*rp);
+        verb = ldl_le_phys(addr + 4*rp);
         d->corb_rp = rp;
 
         dprint(d, 2, "%s: [rp 0x%x] verb 0x%08x\n", __FUNCTION__, rp, verb);
@@ -373,8 +360,8 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res
     ex = (solicited ? 0 : (1 << 4)) | dev->cad;
     wp = (d->rirb_wp + 1) & 0xff;
     addr = intel_hda_addr(d->rirb_lbase, d->rirb_ubase);
-    stl_phys_le(addr + 8*wp, response);
-    stl_phys_le(addr + 8*wp + 4, ex);
+    stl_le_phys(addr + 8*wp, response);
+    stl_le_phys(addr + 8*wp + 4, ex);
     d->rirb_wp = wp;
 
     dprint(d, 2, "%s: [wp 0x%x] response 0x%x, extra 0x%x\n",
@@ -461,7 +448,7 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output,
     }
     if (d->dp_lbase & 0x01) {
         addr = intel_hda_addr(d->dp_lbase & ~0x01, d->dp_ubase);
-        stl_phys_le(addr + 8*s, st->lpib);
+        stl_le_phys(addr + 8*s, st->lpib);
     }
     dprint(d, 3, "dma: --\n");
 
diff --git a/hw/msi.c b/hw/msi.c
index e8c56079aa..f214fcf579 100644
--- a/hw/msi.c
+++ b/hw/msi.c
@@ -249,7 +249,7 @@ void msi_notify(PCIDevice *dev, unsigned int vector)
                    "notify vector 0x%x"
                    " address: 0x%"PRIx64" data: 0x%"PRIx32"\n",
                    vector, address, data);
-    stl_phys(address, data);
+    stl_le_phys(address, data);
 }
 
 /* call this function after updating configs by pci_default_write_config(). */
diff --git a/hw/msix.c b/hw/msix.c
index 03d7becaaf..e67e700a33 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -359,7 +359,7 @@ void msix_notify(PCIDevice *dev, unsigned vector)
 
     address = pci_get_quad(table_entry + PCI_MSIX_ENTRY_LOWER_ADDR);
     data = pci_get_long(table_entry + PCI_MSIX_ENTRY_DATA);
-    stl_phys(address, data);
+    stl_le_phys(address, data);
 }
 
 void msix_reset(PCIDevice *dev)
diff --git a/hw/pci_ids.h b/hw/pci_ids.h
index 927f2b0627..83f38934ec 100644
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@ -118,4 +118,5 @@
 #define PCI_DEVICE_ID_INTEL_82801I_EHCI1 0x293a
 #define PCI_DEVICE_ID_INTEL_82801I_EHCI2 0x293c
 
-#define PCI_VENDOR_ID_XENSOURCE          0x5853
+#define PCI_VENDOR_ID_XEN               0x5853
+#define PCI_DEVICE_ID_XEN_PLATFORM      0x0001
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 26ce90451a..d08b31a266 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -478,6 +478,9 @@ static PCIDeviceInfo i440fx_info[] = {
         .no_hotplug   = 1,
         .init         = piix3_initfn,
         .config_write = piix3_write_config_xen,
+        .vendor_id    = PCI_VENDOR_ID_INTEL,
+        .device_id    = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
+        .class_id     = PCI_CLASS_BRIDGE_ISA,
     },{
         /* end of list */
     }
diff --git a/hw/pl080.c b/hw/pl080.c
index 901f04a844..dd8139ba96 100644
--- a/hw/pl080.c
+++ b/hw/pl080.c
@@ -199,10 +199,10 @@ again:
             if (size == 0) {
                 /* Transfer complete.  */
                 if (ch->lli) {
-                    ch->src = ldl_phys(ch->lli);
-                    ch->dest = ldl_phys(ch->lli + 4);
-                    ch->ctrl = ldl_phys(ch->lli + 12);
-                    ch->lli = ldl_phys(ch->lli + 8);
+                    ch->src = ldl_le_phys(ch->lli);
+                    ch->dest = ldl_le_phys(ch->lli + 4);
+                    ch->ctrl = ldl_le_phys(ch->lli + 12);
+                    ch->lli = ldl_le_phys(ch->lli + 8);
                 } else {
                     ch->conf &= ~PL080_CCONF_E;
                 }
diff --git a/hw/ppc405_uc.c b/hw/ppc405_uc.c
index 2ce79ee053..06a053bf07 100644
--- a/hw/ppc405_uc.c
+++ b/hw/ppc405_uc.c
@@ -51,39 +51,42 @@ ram_addr_t ppc405_set_bootinfo (CPUState *env, ppc4xx_bd_info_t *bd,
         bdloc = 0x01000000UL - sizeof(struct ppc4xx_bd_info_t);
     else
         bdloc = bd->bi_memsize - sizeof(struct ppc4xx_bd_info_t);
-    stl_phys(bdloc + 0x00, bd->bi_memstart);
-    stl_phys(bdloc + 0x04, bd->bi_memsize);
-    stl_phys(bdloc + 0x08, bd->bi_flashstart);
-    stl_phys(bdloc + 0x0C, bd->bi_flashsize);
-    stl_phys(bdloc + 0x10, bd->bi_flashoffset);
-    stl_phys(bdloc + 0x14, bd->bi_sramstart);
-    stl_phys(bdloc + 0x18, bd->bi_sramsize);
-    stl_phys(bdloc + 0x1C, bd->bi_bootflags);
-    stl_phys(bdloc + 0x20, bd->bi_ipaddr);
-    for (i = 0; i < 6; i++)
+    stl_be_phys(bdloc + 0x00, bd->bi_memstart);
+    stl_be_phys(bdloc + 0x04, bd->bi_memsize);
+    stl_be_phys(bdloc + 0x08, bd->bi_flashstart);
+    stl_be_phys(bdloc + 0x0C, bd->bi_flashsize);
+    stl_be_phys(bdloc + 0x10, bd->bi_flashoffset);
+    stl_be_phys(bdloc + 0x14, bd->bi_sramstart);
+    stl_be_phys(bdloc + 0x18, bd->bi_sramsize);
+    stl_be_phys(bdloc + 0x1C, bd->bi_bootflags);
+    stl_be_phys(bdloc + 0x20, bd->bi_ipaddr);
+    for (i = 0; i < 6; i++) {
         stb_phys(bdloc + 0x24 + i, bd->bi_enetaddr[i]);
-    stw_phys(bdloc + 0x2A, bd->bi_ethspeed);
-    stl_phys(bdloc + 0x2C, bd->bi_intfreq);
-    stl_phys(bdloc + 0x30, bd->bi_busfreq);
-    stl_phys(bdloc + 0x34, bd->bi_baudrate);
-    for (i = 0; i < 4; i++)
+    }
+    stw_be_phys(bdloc + 0x2A, bd->bi_ethspeed);
+    stl_be_phys(bdloc + 0x2C, bd->bi_intfreq);
+    stl_be_phys(bdloc + 0x30, bd->bi_busfreq);
+    stl_be_phys(bdloc + 0x34, bd->bi_baudrate);
+    for (i = 0; i < 4; i++) {
         stb_phys(bdloc + 0x38 + i, bd->bi_s_version[i]);
+    }
     for (i = 0; i < 32; i++) {
         stb_phys(bdloc + 0x3C + i, bd->bi_r_version[i]);
     }
-    stl_phys(bdloc + 0x5C, bd->bi_plb_busfreq);
-    stl_phys(bdloc + 0x60, bd->bi_pci_busfreq);
-    for (i = 0; i < 6; i++)
+    stl_be_phys(bdloc + 0x5C, bd->bi_plb_busfreq);
+    stl_be_phys(bdloc + 0x60, bd->bi_pci_busfreq);
+    for (i = 0; i < 6; i++) {
         stb_phys(bdloc + 0x64 + i, bd->bi_pci_enetaddr[i]);
+    }
     n = 0x6A;
     if (flags & 0x00000001) {
         for (i = 0; i < 6; i++)
             stb_phys(bdloc + n++, bd->bi_pci_enetaddr2[i]);
     }
-    stl_phys(bdloc + n, bd->bi_opbfreq);
+    stl_be_phys(bdloc + n, bd->bi_opbfreq);
     n += 4;
     for (i = 0; i < 2; i++) {
-        stl_phys(bdloc + n, bd->bi_iic_fast[i]);
+        stl_be_phys(bdloc + n, bd->bi_iic_fast[i]);
         n += 4;
     }
 
diff --git a/hw/qxl-logger.c b/hw/qxl-logger.c
index 76f43e646c..74cadba302 100644
--- a/hw/qxl-logger.c
+++ b/hw/qxl-logger.c
@@ -19,6 +19,7 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "qemu-timer.h"
 #include "qxl.h"
 
 static const char *qxl_type[] = {
@@ -223,7 +224,8 @@ void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext)
     if (!qxl->cmdlog) {
         return;
     }
-    fprintf(stderr, "qxl-%d/%s:", qxl->id, ring);
+    fprintf(stderr, "%ld qxl-%d/%s:", qemu_get_clock_ns(vm_clock),
+            qxl->id, ring);
     fprintf(stderr, " cmd @ 0x%" PRIx64 " %s%s", ext->cmd.data,
             qxl_name(qxl_type, ext->cmd.type),
             compat ? "(compat)" : "");
diff --git a/hw/qxl.c b/hw/qxl.c
index 16316f2bf5..0b9a4c71ec 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -336,6 +336,21 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
     info->n_surfaces = NUM_SURFACES;
 }
 
+static const char *qxl_mode_to_string(int mode)
+{
+    switch (mode) {
+    case QXL_MODE_COMPAT:
+        return "compat";
+    case QXL_MODE_NATIVE:
+        return "native";
+    case QXL_MODE_UNDEFINED:
+        return "undefined";
+    case QXL_MODE_VGA:
+        return "vga";
+    }
+    return "INVALID";
+}
+
 /* called from spice server thread context only */
 static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
 {
@@ -358,18 +373,19 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
         }
         qemu_mutex_unlock(&qxl->ssd.lock);
         if (ret) {
+            dprint(qxl, 2, "%s %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
             qxl_log_command(qxl, "vga", ext);
         }
         return ret;
     case QXL_MODE_COMPAT:
     case QXL_MODE_NATIVE:
     case QXL_MODE_UNDEFINED:
-        dprint(qxl, 2, "%s: %s\n", __FUNCTION__,
-               qxl->cmdflags ? "compat" : "native");
+        dprint(qxl, 4, "%s: %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
         ring = &qxl->ram->cmd_ring;
         if (SPICE_RING_IS_EMPTY(ring)) {
             return false;
         }
+        dprint(qxl, 2, "%s: %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
         SPICE_RING_CONS_ITEM(ring, cmd);
         ext->cmd      = *cmd;
         ext->group_id = MEMSLOT_GROUP_GUEST;
@@ -926,6 +942,8 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
     case QXL_IO_MEMSLOT_ADD:
     case QXL_IO_MEMSLOT_DEL:
     case QXL_IO_CREATE_PRIMARY:
+    case QXL_IO_UPDATE_IRQ:
+    case QXL_IO_LOG:
         break;
     default:
         if (d->mode == QXL_MODE_NATIVE || d->mode == QXL_MODE_COMPAT)
@@ -969,7 +987,8 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
         break;
     case QXL_IO_LOG:
         if (d->guestdebug) {
-            fprintf(stderr, "qxl/guest: %s", d->ram->log_buf);
+            fprintf(stderr, "qxl/guest-%d: %ld: %s", d->id,
+                    qemu_get_clock_ns(vm_clock), d->ram->log_buf);
         }
         break;
     case QXL_IO_RESET:
@@ -993,7 +1012,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
         break;
     case QXL_IO_DESTROY_PRIMARY:
         PANIC_ON(val != 0);
-        dprint(d, 1, "QXL_IO_DESTROY_PRIMARY\n");
+        dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (%s)\n", qxl_mode_to_string(d->mode));
         qxl_destroy_primary(d);
         break;
     case QXL_IO_DESTROY_SURFACE_WAIT:
@@ -1167,11 +1186,14 @@ static void qxl_vm_change_state_handler(void *opaque, int running, int reason)
     qemu_spice_vm_change_state_handler(&qxl->ssd, running, reason);
 
     if (!running && qxl->mode == QXL_MODE_NATIVE) {
-        /* dirty all vram (which holds surfaces) to make sure it is saved */
+        /* dirty all vram (which holds surfaces) and devram (primary surface)
+         * to make sure they are saved */
         /* FIXME #1: should go out during "live" stage */
         /* FIXME #2: we only need to save the areas which are actually used */
-        ram_addr_t addr = qxl->vram_offset;
-        qxl_set_dirty(addr, addr + qxl->vram_size);
+        ram_addr_t vram_addr = qxl->vram_offset;
+        ram_addr_t surface0_addr = qxl->vga.vram_offset + qxl->shadow_rom.draw_area_offset;
+        qxl_set_dirty(vram_addr, vram_addr + qxl->vram_size);
+        qxl_set_dirty(surface0_addr, surface0_addr + qxl->shadow_rom.surface0_area_size);
     }
 }
 
@@ -1207,7 +1229,6 @@ static DisplayChangeListener display_listener = {
 static int qxl_init_common(PCIQXLDevice *qxl)
 {
     uint8_t* config = qxl->pci.config;
-    uint32_t pci_device_id;
     uint32_t pci_device_rev;
     uint32_t io_size;
 
@@ -1218,20 +1239,14 @@ static int qxl_init_common(PCIQXLDevice *qxl)
 
     switch (qxl->revision) {
     case 1: /* spice 0.4 -- qxl-1 */
-        pci_device_id  = QXL_DEVICE_ID_STABLE;
         pci_device_rev = QXL_REVISION_STABLE_V04;
         break;
     case 2: /* spice 0.6 -- qxl-2 */
-        pci_device_id  = QXL_DEVICE_ID_STABLE;
+    default:
         pci_device_rev = QXL_REVISION_STABLE_V06;
         break;
-    default: /* experimental */
-        pci_device_id  = QXL_DEVICE_ID_DEVEL;
-        pci_device_rev = 1;
-        break;
     }
 
-    pci_config_set_device_id(config, pci_device_id);
     pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev);
     pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
 
@@ -1375,7 +1390,8 @@ static int qxl_post_load(void *opaque, int version)
 
     d->modes = (QXLModes*)((uint8_t*)d->rom + d->rom->modes_offset);
 
-    dprint(d, 1, "%s: restore mode\n", __FUNCTION__);
+    dprint(d, 1, "%s: restore mode (%s)\n", __FUNCTION__,
+        qxl_mode_to_string(d->mode));
     newmode = d->mode;
     d->mode = QXL_MODE_UNDEFINED;
     switch (newmode) {
@@ -1492,6 +1508,7 @@ static PCIDeviceInfo qxl_info_primary = {
     .config_write = qxl_write_config,
     .romfile      = "vgabios-qxl.bin",
     .vendor_id    = REDHAT_PCI_VENDOR_ID,
+    .device_id    = QXL_DEVICE_ID_STABLE,
     .class_id     = PCI_CLASS_DISPLAY_VGA,
     .qdev.props = (Property[]) {
         DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024),
@@ -1512,6 +1529,7 @@ static PCIDeviceInfo qxl_info_secondary = {
     .qdev.vmsd    = &qxl_vmstate,
     .init         = qxl_init_secondary,
     .vendor_id    = REDHAT_PCI_VENDOR_ID,
+    .device_id    = QXL_DEVICE_ID_STABLE,
     .class_id     = PCI_CLASS_DISPLAY_OTHER,
     .qdev.props = (Property[]) {
         DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024),
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index d4a12f7531..e2f3e32aca 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -128,7 +128,8 @@ static int s390_virtio_blk_init(VirtIOS390Device *dev)
 {
     VirtIODevice *vdev;
 
-    vdev = virtio_blk_init((DeviceState *)dev, &dev->block);
+    vdev = virtio_blk_init((DeviceState *)dev, &dev->block,
+                           &dev->block_serial);
     if (!vdev) {
         return -1;
     }
@@ -165,7 +166,7 @@ static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq)
                 (vq * VIRTIO_VQCONFIG_LEN) +
                 VIRTIO_VQCONFIG_OFFS_TOKEN;
 
-    return ldq_phys(token_off);
+    return ldq_be_phys(token_off);
 }
 
 static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev)
@@ -219,8 +220,8 @@ void s390_virtio_device_sync(VirtIOS390Device *dev)
         vring = s390_virtio_next_ring(bus);
         virtio_queue_set_addr(dev->vdev, i, vring);
         virtio_queue_set_vector(dev->vdev, i, i);
-        stq_phys(vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring);
-        stw_phys(vq + VIRTIO_VQCONFIG_OFFS_NUM, virtio_queue_get_num(dev->vdev, i));
+        stq_be_phys(vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring);
+        stw_be_phys(vq + VIRTIO_VQCONFIG_OFFS_NUM, virtio_queue_get_num(dev->vdev, i));
     }
 
     cur_offs = dev->dev_offs;
@@ -228,7 +229,7 @@ void s390_virtio_device_sync(VirtIOS390Device *dev)
     cur_offs += num_vq * VIRTIO_VQCONFIG_LEN;
 
     /* Sync feature bitmap */
-    stl_phys(cur_offs, bswap32(dev->host_features));
+    stl_le_phys(cur_offs, dev->host_features);
 
     dev->feat_offs = cur_offs + dev->feat_len;
     cur_offs += dev->feat_len * 2;
@@ -252,7 +253,7 @@ void s390_virtio_device_update_status(VirtIOS390Device *dev)
 
     /* Update guest supported feature bitmap */
 
-    features = bswap32(ldl_phys(dev->feat_offs));
+    features = bswap32(ldl_be_phys(dev->feat_offs));
     if (vdev->set_features) {
         vdev->set_features(vdev, features);
     }
@@ -355,6 +356,7 @@ static VirtIOS390DeviceInfo s390_virtio_blk = {
     .qdev.size = sizeof(VirtIOS390Device),
     .qdev.props = (Property[]) {
         DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, block),
+        DEFINE_PROP_STRING("serial", VirtIOS390Device, block_serial),
         DEFINE_PROP_END_OF_LIST(),
     },
 };
diff --git a/hw/s390-virtio-bus.h b/hw/s390-virtio-bus.h
index 0c412d08e1..f1bece738b 100644
--- a/hw/s390-virtio-bus.h
+++ b/hw/s390-virtio-bus.h
@@ -42,6 +42,7 @@ typedef struct VirtIOS390Device {
     uint8_t feat_len;
     VirtIODevice *vdev;
     BlockConf block;
+    char *block_serial;
     NICConf nic;
     uint32_t host_features;
     virtio_serial_conf serial;
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 3eba7ea1e8..abe954dc88 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -193,7 +193,7 @@ static void s390_init(ram_addr_t my_ram_size,
     if (kernel_filename) {
         kernel_size = load_image(kernel_filename, qemu_get_ram_ptr(0));
 
-        if (lduw_phys(KERN_IMAGE_START) != 0x0dd0) {
+        if (lduw_be_phys(KERN_IMAGE_START) != 0x0dd0) {
             fprintf(stderr, "Specified image is not an s390 boot image\n");
             exit(1);
         }
@@ -232,8 +232,8 @@ static void s390_init(ram_addr_t my_ram_size,
         }
         initrd_size = load_image(initrd_filename, qemu_get_ram_ptr(initrd_offset));
 
-        stq_phys(INITRD_PARM_START, initrd_offset);
-        stq_phys(INITRD_PARM_SIZE, initrd_size);
+        stq_be_phys(INITRD_PARM_START, initrd_offset);
+        stq_be_phys(INITRD_PARM_SIZE, initrd_size);
     }
 
     if (kernel_cmdline) {
diff --git a/hw/spapr.h b/hw/spapr.h
index b52133a4aa..263691b6fb 100644
--- a/hw/spapr.h
+++ b/hw/spapr.h
@@ -280,12 +280,12 @@ target_ulong spapr_hypercall(CPUState *env, target_ulong opcode,
 
 static inline uint32_t rtas_ld(target_ulong phys, int n)
 {
-    return ldl_phys(phys + 4*n);
+    return ldl_be_phys(phys + 4*n);
 }
 
 static inline void rtas_st(target_ulong phys, int n, uint32_t val)
 {
-    stl_phys(phys + 4*n, val);
+    stl_be_phys(phys + 4*n, val);
 }
 
 typedef void (*spapr_rtas_fn)(sPAPREnvironment *spapr, uint32_t token,
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index 84da8fc69c..5cd8d8f5ae 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -278,7 +278,7 @@ static target_ulong register_vpa(CPUState *env, target_ulong vpa)
     }
     /* FIXME: bounds check the address */
 
-    size = lduw_phys(vpa + 0x4);
+    size = lduw_be_phys(vpa + 0x4);
 
     if (size < VPA_MIN_SIZE) {
         return H_PARAMETER;
@@ -321,7 +321,7 @@ static target_ulong register_slb_shadow(CPUState *env, target_ulong addr)
         return H_HARDWARE;
     }
 
-    size = ldl_phys(addr + 0x4);
+    size = ldl_be_phys(addr + 0x4);
     if (size < 0x8) {
         return H_PARAMETER;
     }
@@ -354,7 +354,7 @@ static target_ulong register_dtl(CPUState *env, target_ulong addr)
         return H_HARDWARE;
     }
 
-    size = ldl_phys(addr + 0x4);
+    size = ldl_be_phys(addr + 0x4);
 
     if (size < 48) {
         return H_PARAMETER;
@@ -441,9 +441,9 @@ static target_ulong h_rtas(CPUState *env, sPAPREnvironment *spapr,
                            target_ulong opcode, target_ulong *args)
 {
     target_ulong rtas_r3 = args[0];
-    uint32_t token = ldl_phys(rtas_r3);
-    uint32_t nargs = ldl_phys(rtas_r3 + 4);
-    uint32_t nret = ldl_phys(rtas_r3 + 8);
+    uint32_t token = ldl_be_phys(rtas_r3);
+    uint32_t nargs = ldl_be_phys(rtas_r3 + 4);
+    uint32_t nret = ldl_be_phys(rtas_r3 + 8);
 
     return spapr_rtas_call(spapr, token, nargs, rtas_r3 + 12,
                            nret, rtas_r3 + 12 + 4*nargs);
diff --git a/hw/vhost.c b/hw/vhost.c
index 80f771e448..c3d88214fe 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -784,5 +784,6 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
 
     hdev->started = false;
     qemu_free(hdev->log);
+    hdev->log = NULL;
     hdev->log_size = 0;
 }
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 91e0394af9..6471ac85ab 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -28,8 +28,8 @@ typedef struct VirtIOBlock
     void *rq;
     QEMUBH *bh;
     BlockConf *conf;
+    char *serial;
     unsigned short sector_mask;
-    char sn[BLOCK_SERIAL_STRLEN];
     DeviceState *qdev;
 } VirtIOBlock;
 
@@ -362,8 +362,13 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req,
     } else if (type & VIRTIO_BLK_T_GET_ID) {
         VirtIOBlock *s = req->dev;
 
-        memcpy(req->elem.in_sg[0].iov_base, s->sn,
-               MIN(req->elem.in_sg[0].iov_len, sizeof(s->sn)));
+        /*
+         * NB: per existing s/n string convention the string is
+         * terminated by '\0' only when shorter than buffer.
+         */
+        strncpy(req->elem.in_sg[0].iov_base,
+                s->serial ? s->serial : "",
+                MIN(req->elem.in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES));
         virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
     } else if (type & VIRTIO_BLK_T_OUT) {
         qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
@@ -531,7 +536,8 @@ static void virtio_blk_change_cb(void *opaque, int reason)
     }
 }
 
-VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
+VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
+                              char **serial)
 {
     VirtIOBlock *s;
     int cylinders, heads, secs;
@@ -547,6 +553,14 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
         return NULL;
     }
 
+    if (!*serial) {
+        /* try to fall back to value set with legacy -drive serial=... */
+        dinfo = drive_get_by_blockdev(conf->bs);
+        if (*dinfo->serial) {
+            *serial = strdup(dinfo->serial);
+        }
+    }
+
     s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
                                           sizeof(struct virtio_blk_config),
                                           sizeof(VirtIOBlock));
@@ -556,16 +570,11 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
     s->vdev.reset = virtio_blk_reset;
     s->bs = conf->bs;
     s->conf = conf;
+    s->serial = *serial;
     s->rq = NULL;
     s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
     bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
 
-    /* NB: per existing s/n string convention the string is terminated
-     * by '\0' only when less than sizeof (s->sn)
-     */
-    dinfo = drive_get_by_blockdev(s->bs);
-    strncpy(s->sn, dinfo->serial, sizeof (s->sn));
-
     s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
 
     qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
diff --git a/hw/virtio-blk.h b/hw/virtio-blk.h
index fff46da7db..5645d2bf3c 100644
--- a/hw/virtio-blk.h
+++ b/hw/virtio-blk.h
@@ -34,6 +34,8 @@
 #define VIRTIO_BLK_F_WCACHE     9       /* write cache enabled */
 #define VIRTIO_BLK_F_TOPOLOGY   10      /* Topology information is available */
 
+#define VIRTIO_BLK_ID_BYTES     20      /* ID string length */
+
 struct virtio_blk_config
 {
     uint64_t capacity;
diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index b076331d37..7ebfa26516 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -12,6 +12,7 @@
 
 #include "qemu-char.h"
 #include "qemu-error.h"
+#include "trace.h"
 #include "virtio-serial.h"
 
 typedef struct VirtConsole {
@@ -24,8 +25,26 @@ typedef struct VirtConsole {
 static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
 {
     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
-
-    return qemu_chr_write(vcon->chr, buf, len);
+    ssize_t ret;
+
+    ret = qemu_chr_write(vcon->chr, buf, len);
+    trace_virtio_console_flush_buf(port->id, len, ret);
+
+    if (ret < 0) {
+        /*
+         * Ideally we'd get a better error code than just -1, but
+         * that's what the chardev interface gives us right now.  If
+         * we had a finer-grained message, like -EPIPE, we could close
+         * this connection.  Absent such error messages, the most we
+         * can do is to return 0 here.
+         *
+         * This will prevent stray -1 values to go to
+         * virtio-serial-bus.c and cause abort()s in
+         * do_flush_queued_data().
+         */
+        ret = 0;
+    }
+    return ret;
 }
 
 /* Callback function that's called when the guest opens the port */
@@ -57,6 +76,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
 {
     VirtConsole *vcon = opaque;
 
+    trace_virtio_console_chr_read(vcon->port.id, size);
     virtio_serial_write(&vcon->port, buf, size);
 }
 
@@ -64,6 +84,7 @@ static void chr_event(void *opaque, int event)
 {
     VirtConsole *vcon = opaque;
 
+    trace_virtio_console_chr_event(vcon->port.id, event);
     switch (event) {
     case CHR_EVENT_OPENED:
         virtio_serial_open(&vcon->port);
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index b3e7ba5d12..d685243728 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -700,7 +700,8 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev)
         proxy->class_code != PCI_CLASS_STORAGE_OTHER)
         proxy->class_code = PCI_CLASS_STORAGE_SCSI;
 
-    vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block);
+    vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block,
+                           &proxy->block_serial);
     if (!vdev) {
         return -1;
     }
@@ -805,6 +806,7 @@ static PCIDeviceInfo virtio_info[] = {
         .qdev.props = (Property[]) {
             DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
             DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
+            DEFINE_PROP_STRING("serial", VirtIOPCIProxy, block_serial),
             DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
                             VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
             DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
index b5189172de..1f0de5684d 100644
--- a/hw/virtio-pci.h
+++ b/hw/virtio-pci.h
@@ -26,6 +26,7 @@ typedef struct {
     uint32_t class_code;
     uint32_t nvectors;
     BlockConf block;
+    char *block_serial;
     NICConf nic;
     uint32_t host_features;
 #ifdef CONFIG_LINUX
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 7f6db7bffe..6d73386441 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -19,6 +19,7 @@
 #include "monitor.h"
 #include "qemu-queue.h"
 #include "sysbus.h"
+#include "trace.h"
 #include "virtio-serial.h"
 
 /* The virtio-serial bus on top of which the ports will ride as devices */
@@ -221,6 +222,7 @@ static size_t send_control_event(VirtIOSerialPort *port, uint16_t event,
     stw_p(&cpkt.event, event);
     stw_p(&cpkt.value, value);
 
+    trace_virtio_serial_send_control_event(port->id, event, value);
     return send_control_msg(port, &cpkt, sizeof(cpkt));
 }
 
@@ -302,6 +304,7 @@ void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle)
         return;
     }
 
+    trace_virtio_serial_throttle_port(port->id, throttle);
     port->throttled = throttle;
     if (throttle) {
         return;
@@ -328,6 +331,8 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
     cpkt.event = lduw_p(&gcpkt->event);
     cpkt.value = lduw_p(&gcpkt->value);
 
+    trace_virtio_serial_handle_control_message(cpkt.event, cpkt.value);
+
     if (cpkt.event == VIRTIO_CONSOLE_DEVICE_READY) {
         if (!cpkt.value) {
             error_report("virtio-serial-bus: Guest failure in adding device %s",
@@ -346,11 +351,13 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
 
     port = find_port_by_id(vser, ldl_p(&gcpkt->id));
     if (!port) {
-        error_report("virtio-serial-bus: Unexpected port id %u for device %s\n",
+        error_report("virtio-serial-bus: Unexpected port id %u for device %s",
                      ldl_p(&gcpkt->id), vser->bus.qbus.name);
         return;
     }
 
+    trace_virtio_serial_handle_control_message_port(port->id);
+
     info = DO_UPCAST(VirtIOSerialPortInfo, qdev, port->dev.info);
 
     switch(cpkt.event) {
diff --git a/hw/virtio.c b/hw/virtio.c
index cc47a06a4e..a8f4940da2 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -449,9 +449,17 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
         struct iovec *sg;
 
         if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_WRITE) {
+            if (elem->in_num >= ARRAY_SIZE(elem->in_sg)) {
+                error_report("Too many write descriptors in indirect table");
+                exit(1);
+            }
             elem->in_addr[elem->in_num] = vring_desc_addr(desc_pa, i);
             sg = &elem->in_sg[elem->in_num++];
         } else {
+            if (elem->out_num >= ARRAY_SIZE(elem->out_sg)) {
+                error_report("Too many read descriptors in indirect table");
+                exit(1);
+            }
             elem->out_addr[elem->out_num] = vring_desc_addr(desc_pa, i);
             sg = &elem->out_sg[elem->out_num++];
         }
diff --git a/hw/virtio.h b/hw/virtio.h
index 69e6bb1a4e..0fd0bb0ac5 100644
--- a/hw/virtio.h
+++ b/hw/virtio.h
@@ -197,7 +197,8 @@ void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
                         void *opaque);
 
 /* Base devices.  */
-VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf);
+VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
+                              char **serial);
 struct virtio_net_conf;
 VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
                               struct virtio_net_conf *net);
diff --git a/hw/xen_platform.c b/hw/xen_platform.c
index b167eee1ff..f43e175b4e 100644
--- a/hw/xen_platform.c
+++ b/hw/xen_platform.c
@@ -290,18 +290,10 @@ static int xen_platform_initfn(PCIDevice *dev)
 
     pci_conf = d->pci_dev.config;
 
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_XENSOURCE);
-    pci_config_set_device_id(pci_conf, 0x0001);
-    pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_XENSOURCE);
-    pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0001);
-
     pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
 
-    pci_config_set_revision(pci_conf, 1);
     pci_config_set_prog_interface(pci_conf, 0);
 
-    pci_config_set_class(pci_conf, PCI_CLASS_OTHERS << 8 | 0x80);
-
     pci_conf[PCI_INTERRUPT_PIN] = 1;
 
     pci_register_bar(&d->pci_dev, 0, 0x100,
@@ -330,6 +322,13 @@ static PCIDeviceInfo xen_platform_info = {
     .qdev.size = sizeof(PCIXenPlatformState),
     .qdev.vmsd = &vmstate_xen_platform,
     .qdev.reset = platform_reset,
+
+    .vendor_id    =  PCI_VENDOR_ID_XEN,
+    .device_id    = PCI_DEVICE_ID_XEN_PLATFORM,
+    .class_id     = PCI_CLASS_OTHERS << 8 | 0x80,
+    .subsystem_vendor_id = PCI_VENDOR_ID_XEN,
+    .subsystem_id = PCI_DEVICE_ID_XEN_PLATFORM,
+    .revision = 1,
 };
 
 static void xen_platform_register(void)
diff --git a/linux-user/alpha/syscall_nr.h b/linux-user/alpha/syscall_nr.h
index e3127df4ac..f6284db22f 100644
--- a/linux-user/alpha/syscall_nr.h
+++ b/linux-user/alpha/syscall_nr.h
@@ -411,4 +411,25 @@
 #define TARGET_NR_signalfd			476
 #define TARGET_NR_timerfd			477
 #define TARGET_NR_eventfd			478
-
+#define TARGET_NR_recvmmsg                      479
+#define TARGET_NR_fallocate                     480
+#define TARGET_NR_timerfd_create                481
+#define TARGET_NR_timerfd_settime               482
+#define TARGET_NR_timerfd_gettime               483
+#define TARGET_NR_signalfd4                     484
+#define TARGET_NR_eventfd2                      485
+#define TARGET_NR_epoll_create1                 486
+#define TARGET_NR_dup3                          487
+#define TARGET_NR_pipe2                         488
+#define TARGET_NR_inotify_init1                 489
+#define TARGET_NR_preadv                        490
+#define TARGET_NR_pwritev                       491
+#define TARGET_NR_rt_tgsigqueueinfo             492
+#define TARGET_NR_perf_event_open               493
+#define TARGET_NR_fanotify_init                 494
+#define TARGET_NR_fanotify_mark                 495
+#define TARGET_NR_prlimit64                     496
+#define TARGET_NR_name_to_handle_at             497
+#define TARGET_NR_open_by_handle_at             498
+#define TARGET_NR_clock_adjtime                 499
+#define TARGET_NR_syncfs                        500
diff --git a/linux-user/arm/syscall_nr.h b/linux-user/arm/syscall_nr.h
index 79a216a137..7f05879ea3 100644
--- a/linux-user/arm/syscall_nr.h
+++ b/linux-user/arm/syscall_nr.h
@@ -365,3 +365,16 @@
 #define TARGET_NR_dup3				(358)
 #define TARGET_NR_pipe2			(359)
 #define TARGET_NR_inotify_init1		(360)
+#define TARGET_NR_preadv                       (361)
+#define TARGET_NR_pwritev                      (362)
+#define TARGET_NR_rt_tgsigqueueinfo            (363)
+#define TARGET_NR_perf_event_open              (364)
+#define TARGET_NR_recvmmsg                     (365)
+#define TARGET_NR_accept4                      (366)
+#define TARGET_NR_fanotify_init                (367)
+#define TARGET_NR_fanotify_mark                (368)
+#define TARGET_NR_prlimit64                    (369)
+#define TARGET_NR_name_to_handle_at            (370)
+#define TARGET_NR_open_by_handle_at            (371)
+#define TARGET_NR_clock_adjtime                (372)
+#define TARGET_NR_syncfs                       (373)
diff --git a/linux-user/cris/syscall_nr.h b/linux-user/cris/syscall_nr.h
index 6132817105..98f1a0b415 100644
--- a/linux-user/cris/syscall_nr.h
+++ b/linux-user/cris/syscall_nr.h
@@ -333,3 +333,5 @@
 #define TARGET_NR_dup3               330
 #define TARGET_NR_pipe2              331
 #define TARGET_NR_inotify_init1      332
+#define TARGET_NR_preadv             333
+#define TARGET_NR_pwritev            334
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index b2746f2558..443d246ada 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -417,7 +417,8 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
 #ifdef TARGET_SPARC64
 
 #define ELF_START_MMAP 0x80000000
-
+#define ELF_HWCAP  (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | HWCAP_SPARC_SWAP \
+                    | HWCAP_SPARC_MULDIV | HWCAP_SPARC_V9)
 #ifndef TARGET_ABI32
 #define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS )
 #else
@@ -450,7 +451,8 @@ static inline void init_thread(struct target_pt_regs *regs,
 
 #else
 #define ELF_START_MMAP 0x80000000
-
+#define ELF_HWCAP  (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | HWCAP_SPARC_SWAP \
+                    | HWCAP_SPARC_MULDIV)
 #define elf_check_arch(x) ( (x) == EM_SPARC )
 
 #define ELF_CLASS   ELFCLASS32
diff --git a/linux-user/i386/syscall_nr.h b/linux-user/i386/syscall_nr.h
index 3ef71ce004..74abfcacb4 100644
--- a/linux-user/i386/syscall_nr.h
+++ b/linux-user/i386/syscall_nr.h
@@ -335,3 +335,15 @@
 #define TARGET_NR_dup3			330
 #define TARGET_NR_pipe2		331
 #define TARGET_NR_inotify_init1	332
+#define TARGET_NR_preadv                333
+#define TARGET_NR_pwritev               334
+#define TARGET_NR_rt_tgsigqueueinfo     335
+#define TARGET_NR_perf_event_open       336
+#define TARGET_NR_recvmmsg              337
+#define TARGET_NR_fanotify_init         338
+#define TARGET_NR_fanotify_mark         339
+#define TARGET_NR_prlimit64             340
+#define TARGET_NR_name_to_handle_at     341
+#define TARGET_NR_open_by_handle_at     342
+#define TARGET_NR_clock_adjtime         343
+#define TARGET_NR_syncfs                344
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 42b3ae3725..6514502dc4 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -59,6 +59,10 @@
      IOCTL(KDSKBMODE, 0, TYPE_INT)
      IOCTL(KDGKBENT, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_kbentry)))
      IOCTL(KDGKBSENT, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_kbsentry)))
+     IOCTL(KDGKBLED, 0, TYPE_INT)
+     IOCTL(KDSKBLED, 0, TYPE_INT)
+     IOCTL(KDGETLED, 0, TYPE_INT)
+     IOCTL(KDSETLED, 0, TYPE_INT)
 
      IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT))
      IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT))
@@ -325,6 +329,11 @@
   IOCTL(FBIOGET_FSCREENINFO, IOC_R, MK_PTR(MK_STRUCT(STRUCT_fb_fix_screeninfo)))
   IOCTL(FBIOGET_VSCREENINFO, IOC_R, MK_PTR(MK_STRUCT(STRUCT_fb_var_screeninfo)))
   IOCTL(FBIOPUT_VSCREENINFO, IOC_W, MK_PTR(MK_STRUCT(STRUCT_fb_var_screeninfo)))
+  IOCTL(FBIOGETCMAP,        IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_cmap)))
+  IOCTL(FBIOPUTCMAP,        IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_cmap)))
+  IOCTL(FBIOPAN_DISPLAY,    IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_var_screeninfo)))
+  IOCTL(FBIOGET_CON2FBMAP,  IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_con2fbmap)))
+  IOCTL(FBIOPUT_CON2FBMAP,  IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_con2fbmap)))
 
   IOCTL(VT_OPENQRY, IOC_R, MK_PTR(TYPE_INT))
   IOCTL(VT_GETSTATE, IOC_R, MK_PTR(MK_STRUCT(STRUCT_vt_stat)))
@@ -332,3 +341,7 @@
   IOCTL(VT_WAITACTIVE, 0, TYPE_INT)
   IOCTL(VT_LOCKSWITCH, 0, TYPE_INT)
   IOCTL(VT_UNLOCKSWITCH, 0, TYPE_INT)
+  IOCTL(VT_GETMODE, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_vt_mode)))
+  IOCTL(VT_SETMODE, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_vt_mode)))
+  IOCTL(VT_RELDISP, 0, TYPE_INT)
+  IOCTL(VT_DISALLOCATE, 0, TYPE_INT)
diff --git a/linux-user/m68k/syscall_nr.h b/linux-user/m68k/syscall_nr.h
index 1c0ba07bfb..4d0937e505 100644
--- a/linux-user/m68k/syscall_nr.h
+++ b/linux-user/m68k/syscall_nr.h
@@ -328,3 +328,19 @@
 #define TARGET_NR_dup3			326
 #define TARGET_NR_pipe2		327
 #define TARGET_NR_inotify_init1	328
+#define TARGET_NR_inotify_init1         328
+#define TARGET_NR_preadv                329
+#define TARGET_NR_pwritev               330
+#define TARGET_NR_rt_tgsigqueueinfo     331
+#define TARGET_NR_perf_event_open       332
+#define TARGET_NR_get_thread_area       333
+#define TARGET_NR_set_thread_area       334
+#define TARGET_NR_atomic_cmpxchg_32     335
+#define TARGET_NR_atomic_barrier        336
+#define TARGET_NR_fanotify_init         337
+#define TARGET_NR_fanotify_mark         338
+#define TARGET_NR_prlimit64             339
+#define TARGET_NR_name_to_handle_at     340
+#define TARGET_NR_open_by_handle_at     341
+#define TARGET_NR_clock_adjtime         342
+#define TARGET_NR_syncfs                343
diff --git a/linux-user/main.c b/linux-user/main.c
index 289054b0b7..2135b9c714 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1875,7 +1875,7 @@ static const uint8_t mips_syscall_args[] = {
 	MIPS_SYS(sys_getcwd	, 2)
 	MIPS_SYS(sys_capget	, 2)
 	MIPS_SYS(sys_capset	, 2)	/* 4205 */
-	MIPS_SYS(sys_sigaltstack	, 0)
+	MIPS_SYS(sys_sigaltstack	, 2)
 	MIPS_SYS(sys_sendfile	, 4)
 	MIPS_SYS(sys_ni_syscall	, 0)
 	MIPS_SYS(sys_ni_syscall	, 0)
@@ -1985,6 +1985,33 @@ static const uint8_t mips_syscall_args[] = {
 	MIPS_SYS(sys_epoll_pwait, 6)
 	MIPS_SYS(sys_ioprio_set, 3)
 	MIPS_SYS(sys_ioprio_get, 2)
+        MIPS_SYS(sys_utimensat, 4)
+        MIPS_SYS(sys_signalfd, 3)
+        MIPS_SYS(sys_ni_syscall, 0)     /* was timerfd */
+        MIPS_SYS(sys_eventfd, 1)
+        MIPS_SYS(sys_fallocate, 6)      /* 4320 */
+        MIPS_SYS(sys_timerfd_create, 2)
+        MIPS_SYS(sys_timerfd_gettime, 2)
+        MIPS_SYS(sys_timerfd_settime, 4)
+        MIPS_SYS(sys_signalfd4, 4)
+        MIPS_SYS(sys_eventfd2, 2)       /* 4325 */
+        MIPS_SYS(sys_epoll_create1, 1)
+        MIPS_SYS(sys_dup3, 3)
+        MIPS_SYS(sys_pipe2, 2)
+        MIPS_SYS(sys_inotify_init1, 1)
+        MIPS_SYS(sys_preadv, 6)         /* 4330 */
+        MIPS_SYS(sys_pwritev, 6)
+        MIPS_SYS(sys_rt_tgsigqueueinfo, 4)
+        MIPS_SYS(sys_perf_event_open, 5)
+        MIPS_SYS(sys_accept4, 4)
+        MIPS_SYS(sys_recvmmsg, 5)       /* 4335 */
+        MIPS_SYS(sys_fanotify_init, 2)
+        MIPS_SYS(sys_fanotify_mark, 6)
+        MIPS_SYS(sys_prlimit64, 4)
+        MIPS_SYS(sys_name_to_handle_at, 5)
+        MIPS_SYS(sys_open_by_handle_at, 3) /* 4340 */
+        MIPS_SYS(sys_clock_adjtime, 2)
+        MIPS_SYS(sys_syncfs, 1)
 };
 
 #undef MIPS_SYS
@@ -2053,7 +2080,7 @@ void cpu_loop(CPUMIPSState *env)
             syscall_num = env->active_tc.gpr[2] - 4000;
             env->active_tc.PC += 4;
             if (syscall_num >= sizeof(mips_syscall_args)) {
-                ret = -ENOSYS;
+                ret = -TARGET_ENOSYS;
             } else {
                 int nb_args;
                 abi_ulong sp_reg;
@@ -2093,6 +2120,8 @@ void cpu_loop(CPUMIPSState *env)
             break;
         case EXCP_TLBL:
         case EXCP_TLBS:
+        case EXCP_AdEL:
+        case EXCP_AdES:
             info.si_signo = TARGET_SIGSEGV;
             info.si_errno = 0;
             /* XXX: check env->error_code */
diff --git a/linux-user/microblaze/syscall_nr.h b/linux-user/microblaze/syscall_nr.h
index 3e641cdb4d..f1fe0e7d8f 100644
--- a/linux-user/microblaze/syscall_nr.h
+++ b/linux-user/microblaze/syscall_nr.h
@@ -364,6 +364,16 @@
 #define TARGET_NR_sendmsg		360 /* new */
 #define TARGET_NR_recvmsg		361 /* new */
 #define TARGET_NR_accept04		362 /* new */
-
-#define TARGET_NR_syscalls		363
+#define TARGET_NR_preadv                363 /* new */
+#define TARGET_NR_pwritev               364 /* new */
+#define TARGET_NR_rt_tgsigqueueinfo     365 /* new */
+#define TARGET_NR_perf_event_open       366 /* new */
+#define TARGET_NR_recvmmsg              367 /* new */
+#define TARGET_NR_fanotify_init         368
+#define TARGET_NR_fanotify_mark         369
+#define TARGET_NR_prlimit64             370
+#define TARGET_NR_name_to_handle_at     371
+#define TARGET_NR_open_by_handle_at     372
+#define TARGET_NR_clock_adjtime         373
+#define TARGET_NR_syncfs                374
 
diff --git a/linux-user/mips/syscall_nr.h b/linux-user/mips/syscall_nr.h
index 059530801b..fbdc348ffc 100644
--- a/linux-user/mips/syscall_nr.h
+++ b/linux-user/mips/syscall_nr.h
@@ -332,3 +332,16 @@
 #define TARGET_NR_dup3			(TARGET_NR_Linux + 327)
 #define TARGET_NR_pipe2		(TARGET_NR_Linux + 328)
 #define TARGET_NR_inotify_init1	(TARGET_NR_Linux + 329)
+#define TARGET_NR_preadv                (TARGET_NR_Linux + 330)
+#define TARGET_NR_pwritev               (TARGET_NR_Linux + 331)
+#define TARGET_NR_rt_tgsigqueueinfo     (TARGET_NR_Linux + 332)
+#define TARGET_NR_perf_event_open       (TARGET_NR_Linux + 333)
+#define TARGET_NR_accept4               (TARGET_NR_Linux + 334)
+#define TARGET_NR_recvmmsg              (TARGET_NR_Linux + 335)
+#define TARGET_NR_fanotify_init         (TARGET_NR_Linux + 336)
+#define TARGET_NR_fanotify_mark         (TARGET_NR_Linux + 337)
+#define TARGET_NR_prlimit64             (TARGET_NR_Linux + 338)
+#define TARGET_NR_name_to_handle_at     (TARGET_NR_Linux + 339)
+#define TARGET_NR_open_by_handle_at     (TARGET_NR_Linux + 340)
+#define TARGET_NR_clock_adjtime         (TARGET_NR_Linux + 341)
+#define TARGET_NR_syncfs                (TARGET_NR_Linux + 342)
diff --git a/linux-user/mips64/syscall_nr.h b/linux-user/mips64/syscall_nr.h
index ee1d134146..36d27b5159 100644
--- a/linux-user/mips64/syscall_nr.h
+++ b/linux-user/mips64/syscall_nr.h
@@ -291,3 +291,16 @@
 #define TARGET_NR_dup3				(TARGET_NR_Linux + 286)
 #define TARGET_NR_pipe2			(TARGET_NR_Linux + 287)
 #define TARGET_NR_inotify_init1		(TARGET_NR_Linux + 288)
+#define TARGET_NR_preadv                        (TARGET_NR_Linux + 289)
+#define TARGET_NR_pwritev                       (TARGET_NR_Linux + 290)
+#define TARGET_NR_rt_tgsigqueueinfo             (TARGET_NR_Linux + 291)
+#define TARGET_NR_perf_event_open               (TARGET_NR_Linux + 292)
+#define TARGET_NR_accept4                       (TARGET_NR_Linux + 293)
+#define TARGET_NR_recvmmsg                      (TARGET_NR_Linux + 294)
+#define TARGET_NR_fanotify_init                 (TARGET_NR_Linux + 295)
+#define TARGET_NR_fanotify_mark                 (TARGET_NR_Linux + 296)
+#define TARGET_NR_prlimit64                     (TARGET_NR_Linux + 297)
+#define TARGET_NR_name_to_handle_at             (TARGET_NR_Linux + 298)
+#define TARGET_NR_open_by_handle_at             (TARGET_NR_Linux + 299)
+#define TARGET_NR_clock_adjtime                 (TARGET_NR_Linux + 300)
+#define TARGET_NR_syncfs                        (TARGET_NR_Linux + 301)
diff --git a/linux-user/mipsn32/syscall_nr.h b/linux-user/mipsn32/syscall_nr.h
index 60a99ddf6e..4e1aca3a9b 100644
--- a/linux-user/mipsn32/syscall_nr.h
+++ b/linux-user/mipsn32/syscall_nr.h
@@ -295,3 +295,17 @@
 #define TARGET_NR_dup3				(TARGET_NR_Linux + 290)
 #define TARGET_NR_pipe2			(TARGET_NR_Linux + 291)
 #define TARGET_NR_inotify_init1		(TARGET_NR_Linux + 292)
+#define TARGET_NR_preadv                        (TARGET_NR_Linux + 293)
+#define TARGET_NR_pwritev                       (TARGET_NR_Linux + 294)
+#define TARGET_NR_rt_tgsigqueueinfo             (TARGET_NR_Linux + 295)
+#define TARGET_NR_perf_event_open               (TARGET_NR_Linux + 296)
+#define TARGET_NR_accept4                       (TARGET_NR_Linux + 297)
+#define TARGET_NR_recvmmsg                      (TARGET_NR_Linux + 298)
+#define TARGET_NR_getdents64                    (TARGET_NR_Linux + 299)
+#define TARGET_NR_fanotify_init                 (TARGET_NR_Linux + 300)
+#define TARGET_NR_fanotify_mark                 (TARGET_NR_Linux + 301)
+#define TARGET_NR_prlimit64                     (TARGET_NR_Linux + 302)
+#define TARGET_NR_name_to_handle_at             (TARGET_NR_Linux + 303)
+#define TARGET_NR_open_by_handle_at             (TARGET_NR_Linux + 304)
+#define TARGET_NR_clock_adjtime                 (TARGET_NR_Linux + 305)
+#define TARGET_NR_syncfs                        (TARGET_NR_Linux + 306)
diff --git a/linux-user/ppc/syscall_nr.h b/linux-user/ppc/syscall_nr.h
index cc84a4c04d..0673b7d169 100644
--- a/linux-user/ppc/syscall_nr.h
+++ b/linux-user/ppc/syscall_nr.h
@@ -332,3 +332,33 @@
 #define TARGET_NR_dup3			316
 #define TARGET_NR_pipe2		317
 #define TARGET_NR_inotify_init1	318
+#define TARGET_NR_perf_event_open       319
+#define TARGET_NR_preadv                320
+#define TARGET_NR_pwritev               321
+#define TARGET_NR_rt_tgsigqueueinfo     322
+#define TARGET_NR_fanotify_init         323
+#define TARGET_NR_fanotify_mark         324
+#define TARGET_NR_prlimit64             325
+#define TARGET_NR_socket                326
+#define TARGET_NR_bind                  327
+#define TARGET_NR_connect               328
+#define TARGET_NR_listen                329
+#define TARGET_NR_accept                330
+#define TARGET_NR_getsockname           331
+#define TARGET_NR_getpeername           332
+#define TARGET_NR_socketpair            333
+#define TARGET_NR_send                  334
+#define TARGET_NR_sendto                335
+#define TARGET_NR_recv                  336
+#define TARGET_NR_recvfrom              337
+#define TARGET_NR_shutdown              338
+#define TARGET_NR_setsockopt            339
+#define TARGET_NR_getsockopt            340
+#define TARGET_NR_sendmsg               341
+#define TARGET_NR_recvmsg               342
+#define TARGET_NR_recvmmsg              343
+#define TARGET_NR_accept4               344
+#define TARGET_NR_name_to_handle_at     345
+#define TARGET_NR_open_by_handle_at     346
+#define TARGET_NR_clock_adjtime         347
+#define TARGET_NR_syncfs                348
diff --git a/linux-user/s390x/syscall_nr.h b/linux-user/s390x/syscall_nr.h
index 7cc6db2e1b..d4529ac03c 100644
--- a/linux-user/s390x/syscall_nr.h
+++ b/linux-user/s390x/syscall_nr.h
@@ -254,8 +254,17 @@
 #define TARGET_NR_pipe2		325
 #define TARGET_NR_dup3		326
 #define TARGET_NR_epoll_create1	327
-#undef NR_syscalls
-#define NR_syscalls 328
+#define TARGET_NR_preadv                328
+#define TARGET_NR_pwritev               329
+#define TARGET_NR_rt_tgsigqueueinfo     330
+#define TARGET_NR_perf_event_open       331
+#define TARGET_NR_fanotify_init         332
+#define TARGET_NR_fanotify_mark         333
+#define TARGET_NR_prlimit64             334
+#define TARGET_NR_name_to_handle_at     335
+#define TARGET_NR_open_by_handle_at     336
+#define TARGET_NR_clock_adjtime         337
+#define TARGET_NR_syncfs                338
 
 /*
  * There are some system calls that are not present on 64 bit, some
diff --git a/linux-user/sh4/syscall_nr.h b/linux-user/sh4/syscall_nr.h
index 262b236333..365db586c7 100644
--- a/linux-user/sh4/syscall_nr.h
+++ b/linux-user/sh4/syscall_nr.h
@@ -125,7 +125,7 @@
 #define TARGET_NR_clone		120
 #define TARGET_NR_setdomainname	121
 #define TARGET_NR_uname		122
-#define TARGET_NR_modify_ldt		123
+#define TARGET_NR_cacheflush		123
 #define TARGET_NR_adjtimex		124
 #define TARGET_NR_mprotect		125
 #define TARGET_NR_sigprocmask	126
@@ -334,3 +334,35 @@
 #define TARGET_NR_dup3			330
 #define TARGET_NR_pipe2		331
 #define TARGET_NR_inotify_init1	332
+#define TARGET_NR_preadv                333
+#define TARGET_NR_pwritev               334
+#define TARGET_NR_rt_tgsigqueueinfo     335
+#define TARGET_NR_perf_event_open       336
+#define TARGET_NR_fanotify_init         337
+#define TARGET_NR_fanotify_mark         338
+#define TARGET_NR_prlimit64             339
+
+/* Non-multiplexed socket family */
+#define TARGET_NR_socket                340
+#define TARGET_NR_bind                  341
+#define TARGET_NR_connect               342
+#define TARGET_NR_listen                343
+#define TARGET_NR_accept                344
+#define TARGET_NR_getsockname           345
+#define TARGET_NR_getpeername           346
+#define TARGET_NR_socketpair            347
+#define TARGET_NR_send                  348
+#define TARGET_NR_sendto                349
+#define TARGET_NR_recv                  350
+#define TARGET_NR_recvfrom              351
+#define TARGET_NR_shutdown              352
+#define TARGET_NR_setsockopt            353
+#define TARGET_NR_getsockopt            354
+#define TARGET_NR_sendmsg               355
+#define TARGET_NR_recvmsg               356
+#define TARGET_NR_recvmmsg              357
+#define TARGET_NR_accept4               358
+#define TARGET_NR_name_to_handle_at     359
+#define TARGET_NR_open_by_handle_at     360
+#define TARGET_NR_clock_adjtime         361
+#define TARGET_NR_syncfs                362
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 7d168e100f..07ad07a58f 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -3662,11 +3662,11 @@ typedef struct {
 } sigframe;
 
 struct target_ucontext {
-    target_ulong uc_flags;
-    struct target_ucontext *uc_link;
-    target_stack_t uc_stack;
-    target_sigregs uc_mcontext;
-    target_sigset_t uc_sigmask;   /* mask last for extensibility */
+    target_ulong tuc_flags;
+    struct target_ucontext *tuc_link;
+    target_stack_t tuc_stack;
+    target_sigregs tuc_mcontext;
+    target_sigset_t tuc_sigmask;   /* mask last for extensibility */
 };
 
 typedef struct {
@@ -3814,16 +3814,16 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
     }
 
     /* Create the ucontext.  */
-    __put_user(0, &frame->uc.uc_flags);
-    __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.uc_link);
-    __put_user(target_sigaltstack_used.ss_sp, &frame->uc.uc_stack.ss_sp);
+    __put_user(0, &frame->uc.tuc_flags);
+    __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link);
+    __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
     __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
-                      &frame->uc.uc_stack.ss_flags);
-    __put_user(target_sigaltstack_used.ss_size, &frame->uc.uc_stack.ss_size);
-    save_sigregs(env, &frame->uc.uc_mcontext);
+                      &frame->uc.tuc_stack.ss_flags);
+    __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
+    save_sigregs(env, &frame->uc.tuc_mcontext);
     for (i = 0; i < TARGET_NSIG_WORDS; i++) {
         __put_user((abi_ulong)set->sig[i],
-        (abi_ulong *)&frame->uc.uc_sigmask.sig[i]);
+        (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]);
     }
 
     /* Set up to return from userspace.  If provided, use a stub
@@ -3928,15 +3928,15 @@ long do_rt_sigreturn(CPUState *env)
     if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
         goto badframe;
     }
-    target_to_host_sigset(&set, &frame->uc.uc_sigmask);
+    target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
 
     sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
 
-    if (restore_sigregs(env, &frame->uc.uc_mcontext)) {
+    if (restore_sigregs(env, &frame->uc.tuc_mcontext)) {
         goto badframe;
     }
 
-    if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.uc_stack), 0,
+    if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.tuc_stack), 0,
                        get_sp_from_cpustate(env)) == -EFAULT) {
         goto badframe;
     }
diff --git a/linux-user/sparc/syscall_nr.h b/linux-user/sparc/syscall_nr.h
index 5d1ac21ac9..be503f23dd 100644
--- a/linux-user/sparc/syscall_nr.h
+++ b/linux-user/sparc/syscall_nr.h
@@ -285,3 +285,15 @@
 #define TARGET_NR_pipe2		321
 #define TARGET_NR_inotify_init1	322
 #define TARGET_NR_accept4		323
+#define TARGET_NR_preadv                324
+#define TARGET_NR_pwritev               325
+#define TARGET_NR_rt_tgsigqueueinfo     326
+#define TARGET_NR_perf_event_open       327
+#define TARGET_NR_recvmmsg              328
+#define TARGET_NR_fanotify_init         329
+#define TARGET_NR_fanotify_mark         330
+#define TARGET_NR_prlimit64             331
+#define TARGET_NR_name_to_handle_at     332
+#define TARGET_NR_open_by_handle_at     333
+#define TARGET_NR_clock_adjtime         334
+#define TARGET_NR_syncfs                335
diff --git a/linux-user/sparc64/syscall_nr.h b/linux-user/sparc64/syscall_nr.h
index bdca2a7331..70988b2ec9 100644
--- a/linux-user/sparc64/syscall_nr.h
+++ b/linux-user/sparc64/syscall_nr.h
@@ -322,3 +322,15 @@
 #define TARGET_NR_pipe2		321
 #define TARGET_NR_inotify_init1	322
 #define TARGET_NR_accept4		323
+#define TARGET_NR_preadv                324
+#define TARGET_NR_pwritev               325
+#define TARGET_NR_rt_tgsigqueueinfo     326
+#define TARGET_NR_perf_event_open       327
+#define TARGET_NR_recvmmsg              328
+#define TARGET_NR_fanotify_init         329
+#define TARGET_NR_fanotify_mark         330
+#define TARGET_NR_prlimit64             331
+#define TARGET_NR_name_to_handle_at     332
+#define TARGET_NR_open_by_handle_at     333
+#define TARGET_NR_clock_adjtime         334
+#define TARGET_NR_syncfs                335
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index fed7a8fe0f..1dd7aad43c 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -559,12 +559,38 @@ _syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds,
           fd_set *, exceptfds, struct timespec *, timeout, void *, sig);
 #endif
 
+#if defined(TARGET_NR_prlimit64)
+#ifndef __NR_prlimit64
+# define __NR_prlimit64 -1
+#endif
+#define __NR_sys_prlimit64 __NR_prlimit64
+/* The glibc rlimit structure may not be that used by the underlying syscall */
+struct host_rlimit64 {
+    uint64_t rlim_cur;
+    uint64_t rlim_max;
+};
+_syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
+          const struct host_rlimit64 *, new_limit,
+          struct host_rlimit64 *, old_limit)
+#endif
+
 extern int personality(int);
 extern int flock(int, int);
 extern int setfsuid(int);
 extern int setfsgid(int);
 extern int setgroups(int, gid_t *);
 
+/* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
+#ifdef TARGET_ARM 
+static inline int regpairs_aligned(void *cpu_env) {
+    return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
+}
+#elif defined(TARGET_MIPS)
+static inline int regpairs_aligned(void *cpu_env) { return 1; }
+#else
+static inline int regpairs_aligned(void *cpu_env) { return 0; }
+#endif
+
 #define ERRNO_TABLE_SIZE 1200
 
 /* target_to_host_errno_table[] is initialized from
@@ -919,18 +945,68 @@ static inline abi_long host_to_target_rusage(abi_ulong target_addr,
 
 static inline rlim_t target_to_host_rlim(target_ulong target_rlim)
 {
-    if (target_rlim == TARGET_RLIM_INFINITY)
-        return RLIM_INFINITY;
+    target_ulong target_rlim_swap;
+    rlim_t result;
+    
+    target_rlim_swap = tswapl(target_rlim);
+    if (target_rlim_swap == TARGET_RLIM_INFINITY || target_rlim_swap != (rlim_t)target_rlim_swap)
+        result = RLIM_INFINITY;
     else
-        return tswapl(target_rlim);
+        result = target_rlim_swap;
+    
+    return result;
 }
 
 static inline target_ulong host_to_target_rlim(rlim_t rlim)
 {
+    target_ulong target_rlim_swap;
+    target_ulong result;
+    
     if (rlim == RLIM_INFINITY || rlim != (target_long)rlim)
-        return TARGET_RLIM_INFINITY;
+        target_rlim_swap = TARGET_RLIM_INFINITY;
     else
-        return tswapl(rlim);
+        target_rlim_swap = rlim;
+    result = tswapl(target_rlim_swap);
+    
+    return result;
+}
+
+static inline int target_to_host_resource(int code)
+{
+    switch (code) {
+    case TARGET_RLIMIT_AS:
+        return RLIMIT_AS;
+    case TARGET_RLIMIT_CORE:
+        return RLIMIT_CORE;
+    case TARGET_RLIMIT_CPU:
+        return RLIMIT_CPU;
+    case TARGET_RLIMIT_DATA:
+        return RLIMIT_DATA;
+    case TARGET_RLIMIT_FSIZE:
+        return RLIMIT_FSIZE;
+    case TARGET_RLIMIT_LOCKS:
+        return RLIMIT_LOCKS;
+    case TARGET_RLIMIT_MEMLOCK:
+        return RLIMIT_MEMLOCK;
+    case TARGET_RLIMIT_MSGQUEUE:
+        return RLIMIT_MSGQUEUE;
+    case TARGET_RLIMIT_NICE:
+        return RLIMIT_NICE;
+    case TARGET_RLIMIT_NOFILE:
+        return RLIMIT_NOFILE;
+    case TARGET_RLIMIT_NPROC:
+        return RLIMIT_NPROC;
+    case TARGET_RLIMIT_RSS:
+        return RLIMIT_RSS;
+    case TARGET_RLIMIT_RTPRIO:
+        return RLIMIT_RTPRIO;
+    case TARGET_RLIMIT_SIGPENDING:
+        return RLIMIT_SIGPENDING;
+    case TARGET_RLIMIT_STACK:
+        return RLIMIT_STACK;
+    default:
+        return code;
+    }
 }
 
 static inline abi_long copy_from_user_timeval(struct timeval *tv,
@@ -4310,13 +4386,10 @@ static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
                                          abi_long arg3,
                                          abi_long arg4)
 {
-#ifdef TARGET_ARM
-    if (((CPUARMState *)cpu_env)->eabi)
-      {
+    if (regpairs_aligned(cpu_env)) {
         arg2 = arg3;
         arg3 = arg4;
-      }
-#endif
+    }
     return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
 }
 #endif
@@ -4327,13 +4400,10 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
                                           abi_long arg3,
                                           abi_long arg4)
 {
-#ifdef TARGET_ARM
-    if (((CPUARMState *)cpu_env)->eabi)
-      {
+    if (regpairs_aligned(cpu_env)) {
         arg2 = arg3;
         arg3 = arg4;
-      }
-#endif
+    }
     return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
 }
 #endif
@@ -5543,7 +5613,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
     case TARGET_NR_setrlimit:
         {
-            int resource = arg1;
+            int resource = target_to_host_resource(arg1);
             struct target_rlimit *target_rlim;
             struct rlimit rlim;
             if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
@@ -5556,7 +5626,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
     case TARGET_NR_getrlimit:
         {
-            int resource = arg1;
+            int resource = target_to_host_resource(arg1);
             struct target_rlimit *target_rlim;
             struct rlimit rlim;
 
@@ -5684,6 +5754,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 
                 if (arg_sigset) {
                     sig.set = &set;
+                    if (arg_sigsize != sizeof(*target_sigset)) {
+                        /* Like the kernel, we enforce correct size sigsets */
+                        ret = -TARGET_EINVAL;
+                        goto fail;
+                    }
                     target_sigset = lock_user(VERIFY_READ, arg_sigset,
                                               sizeof(*target_sigset), 1);
                     if (!target_sigset) {
@@ -6787,20 +6862,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_pread
     case TARGET_NR_pread:
-#ifdef TARGET_ARM
-        if (((CPUARMState *)cpu_env)->eabi)
+        if (regpairs_aligned(cpu_env))
             arg4 = arg5;
-#endif
         if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
             goto efault;
         ret = get_errno(pread(arg1, p, arg3, arg4));
         unlock_user(p, arg2, ret);
         break;
     case TARGET_NR_pwrite:
-#ifdef TARGET_ARM
-        if (((CPUARMState *)cpu_env)->eabi)
+        if (regpairs_aligned(cpu_env))
             arg4 = arg5;
-#endif
         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
             goto efault;
         ret = get_errno(pwrite(arg1, p, arg3, arg4));
@@ -6860,7 +6931,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_ugetrlimit:
     {
 	struct rlimit rlim;
-	ret = get_errno(getrlimit(arg1, &rlim));
+	int resource = target_to_host_resource(arg1);
+	ret = get_errno(getrlimit(resource, &rlim));
 	if (!is_error(ret)) {
 	    struct target_rlimit *target_rlim;
             if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
@@ -7550,14 +7622,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_readahead
     case TARGET_NR_readahead:
 #if TARGET_ABI_BITS == 32
-#ifdef TARGET_ARM
-        if (((CPUARMState *)cpu_env)->eabi)
-        {
+        if (regpairs_aligned(cpu_env)) {
             arg2 = arg3;
             arg3 = arg4;
             arg4 = arg5;
         }
-#endif
         ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
 #else
         ret = get_errno(readahead(arg1, arg2, arg3));
@@ -7990,6 +8059,34 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     }
 #endif
 #endif
+#ifdef TARGET_NR_prlimit64
+    case TARGET_NR_prlimit64:
+    {
+        /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
+        struct target_rlimit64 *target_rnew, *target_rold;
+        struct host_rlimit64 rnew, rold, *rnewp = 0;
+        if (arg3) {
+            if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
+                goto efault;
+            }
+            rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
+            rnew.rlim_max = tswap64(target_rnew->rlim_max);
+            unlock_user_struct(target_rnew, arg3, 0);
+            rnewp = &rnew;
+        }
+
+        ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0));
+        if (!is_error(ret) && arg4) {
+            if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
+                goto efault;
+            }
+            target_rold->rlim_cur = tswap64(rold.rlim_cur);
+            target_rold->rlim_max = tswap64(rold.rlim_max);
+            unlock_user_struct(target_rold, arg4, 1);
+        }
+        break;
+    }
+#endif
     default:
     unimplemented:
         gemu_log("qemu: Unsupported syscall: %d\n", num);
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 04c268de7c..a117407d84 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -693,6 +693,40 @@ struct target_rlimit {
 #define TARGET_RLIM_INFINITY	((target_ulong)~0UL)
 #endif
 
+#if defined(TARGET_MIPS)
+#define TARGET_RLIMIT_CPU		0
+#define TARGET_RLIMIT_FSIZE		1
+#define TARGET_RLIMIT_DATA		2
+#define TARGET_RLIMIT_STACK		3
+#define TARGET_RLIMIT_CORE		4
+#define TARGET_RLIMIT_RSS		7
+#define TARGET_RLIMIT_NPROC		8
+#define TARGET_RLIMIT_NOFILE		5
+#define TARGET_RLIMIT_MEMLOCK		9
+#define TARGET_RLIMIT_AS		6
+#define TARGET_RLIMIT_LOCKS		10
+#define TARGET_RLIMIT_SIGPENDING	11
+#define TARGET_RLIMIT_MSGQUEUE		12
+#define TARGET_RLIMIT_NICE		13
+#define TARGET_RLIMIT_RTPRIO		14
+#else
+#define TARGET_RLIMIT_CPU		0
+#define TARGET_RLIMIT_FSIZE		1
+#define TARGET_RLIMIT_DATA		2
+#define TARGET_RLIMIT_STACK		3
+#define TARGET_RLIMIT_CORE		4
+#define TARGET_RLIMIT_RSS		5
+#define TARGET_RLIMIT_NPROC		6
+#define TARGET_RLIMIT_NOFILE		7
+#define TARGET_RLIMIT_MEMLOCK		8
+#define TARGET_RLIMIT_AS		9
+#define TARGET_RLIMIT_LOCKS		10
+#define TARGET_RLIMIT_SIGPENDING	11
+#define TARGET_RLIMIT_MSGQUEUE		12
+#define TARGET_RLIMIT_NICE		13
+#define TARGET_RLIMIT_RTPRIO		14
+#endif
+
 struct target_pollfd {
     int fd;           /* file descriptor */
     short events;     /* requested events */
@@ -708,6 +742,10 @@ struct target_pollfd {
 #define TARGET_KDSKBMODE       0x4b45
 #define TARGET_KDGKBENT	       0x4B46	/* gets one entry in translation table */
 #define TARGET_KDGKBSENT       0x4B48	/* gets one function key string entry */
+#define TARGET_KDGKBLED        0x4B64	/* get led flags (not lights) */
+#define TARGET_KDSKBLED        0x4B65	/* set led flags (not lights) */
+#define TARGET_KDGETLED        0x4B31	/* return current led state */
+#define TARGET_KDSETLED        0x4B32	/* set led state [lights, not flags] */
 
 #define TARGET_SIOCATMARK      0x8905
 
@@ -928,6 +966,11 @@ struct target_pollfd {
 #define TARGET_FBIOGET_VSCREENINFO    0x4600
 #define TARGET_FBIOPUT_VSCREENINFO    0x4601
 #define TARGET_FBIOGET_FSCREENINFO    0x4602
+#define TARGET_FBIOGETCMAP            0x4604
+#define TARGET_FBIOPUTCMAP            0x4605
+#define TARGET_FBIOPAN_DISPLAY        0x4606
+#define TARGET_FBIOGET_CON2FBMAP      0x460F
+#define TARGET_FBIOPUT_CON2FBMAP      0x4610
 
 /* vt ioctls */
 #define TARGET_VT_OPENQRY             0x5600
@@ -936,6 +979,10 @@ struct target_pollfd {
 #define TARGET_VT_WAITACTIVE          0x5607
 #define TARGET_VT_LOCKSWITCH          0x560b
 #define TARGET_VT_UNLOCKSWITCH        0x560c
+#define TARGET_VT_GETMODE             0x5601
+#define TARGET_VT_SETMODE             0x5602
+#define TARGET_VT_RELDISP             0x5605
+#define TARGET_VT_DISALLOCATE         0x5608
 
 /* from asm/termbits.h */
 
@@ -2280,3 +2327,7 @@ struct target_epoll_event {
     target_epoll_data_t data;
 };
 #endif
+struct target_rlimit64 {
+    uint64_t rlim_cur;
+    uint64_t rlim_max;
+};
diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
index 0e67cd8f30..c370125170 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -161,11 +161,31 @@ STRUCT(fb_var_screeninfo,
        TYPE_INT, /* rotate */
        MK_ARRAY(TYPE_INT, 5)) /* reserved */
 
+STRUCT(fb_cmap,
+       TYPE_INT, /* start  */
+       TYPE_INT, /* len    */
+       TYPE_PTRVOID, /* red    */
+       TYPE_PTRVOID, /* green  */
+       TYPE_PTRVOID, /* blue   */
+       TYPE_PTRVOID) /* transp */
+
+STRUCT(fb_con2fbmap,
+       TYPE_INT, /* console     */
+       TYPE_INT) /* framebuffer */
+
+
 STRUCT(vt_stat,
        TYPE_SHORT, /* v_active */
        TYPE_SHORT, /* v_signal */
        TYPE_SHORT) /* v_state */
 
+STRUCT(vt_mode,
+       TYPE_CHAR,  /* mode   */
+       TYPE_CHAR,  /* waitv  */
+       TYPE_SHORT, /* relsig */
+       TYPE_SHORT, /* acqsig */
+       TYPE_SHORT) /* frsig  */
+
 STRUCT(fiemap_extent,
        TYPE_ULONGLONG, /* fe_logical */
        TYPE_ULONGLONG, /* fe_physical */
diff --git a/linux-user/x86_64/syscall_nr.h b/linux-user/x86_64/syscall_nr.h
index 568a901d71..947e961ce4 100644
--- a/linux-user/x86_64/syscall_nr.h
+++ b/linux-user/x86_64/syscall_nr.h
@@ -293,3 +293,15 @@
 #define TARGET_NR_dup3			292
 #define TARGET_NR_pipe2		293
 #define TARGET_NR_inotify_init1	294
+#define TARGET_NR_preadv                295
+#define TARGET_NR_pwritev               296
+#define TARGET_NR_rt_tgsigqueueinfo     297
+#define TARGET_NR_perf_event_open       298
+#define TARGET_NR_recvmmsg              299
+#define TARGET_NR_fanotify_init         300
+#define TARGET_NR_fanotify_mark         301
+#define TARGET_NR_prlimit64             302
+#define TARGET_NR_name_to_handle_at     303
+#define TARGET_NR_open_by_handle_at     304
+#define TARGET_NR_clock_adjtime         305
+#define TARGET_NR_syncfs                306
diff --git a/os-posix.c b/os-posix.c
index 7dfb27836b..6f8d4886ea 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -31,6 +31,7 @@
 /*needed for MAP_POPULATE before including qemu-options.h */
 #include <sys/mman.h>
 #include <pwd.h>
+#include <grp.h>
 #include <libgen.h>
 
 /* Needed early for CONFIG_BSD etc. */
@@ -199,6 +200,11 @@ static void change_process_uid(void)
             fprintf(stderr, "Failed to setgid(%d)\n", user_pwd->pw_gid);
             exit(1);
         }
+        if (initgroups(user_pwd->pw_name, user_pwd->pw_gid) < 0) {
+            fprintf(stderr, "Failed to initgroups(\"%s\", %d)\n",
+                    user_pwd->pw_name, user_pwd->pw_gid);
+            exit(1);
+        }
         if (setuid(user_pwd->pw_uid) < 0) {
             fprintf(stderr, "Failed to setuid(%d)\n", user_pwd->pw_uid);
             exit(1);
diff --git a/qemu-common.h b/qemu-common.h
index abd7a75b72..c2b79bd60e 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -117,7 +117,6 @@ static inline char *realpath(const char *path, char *resolved_path)
 /* FIXME: Remove NEED_CPU_H.  */
 #ifndef NEED_CPU_H
 
-#include <setjmp.h>
 #include "osdep.h"
 #include "bswap.h"
 
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 3072d383cf..2b70618c70 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -22,13 +22,13 @@ STEXI
 ETEXI
 
 DEF("commit", img_commit,
-    "commit [-f fmt] filename")
+    "commit [-f fmt] [-t cache] filename")
 STEXI
 @item commit [-f @var{fmt}] @var{filename}
 ETEXI
 
 DEF("convert", img_convert,
-    "convert [-c] [-p] [-f fmt] [-O output_fmt] [-o options] [-s snapshot_name] filename [filename2 [...]] output_filename")
+    "convert [-c] [-p] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_name] filename [filename2 [...]] output_filename")
 STEXI
 @item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
@@ -46,7 +46,7 @@ STEXI
 ETEXI
 
 DEF("rebase", img_rebase,
-    "rebase [-f fmt] [-p] [-u] -b backing_file [-F backing_fmt] filename")
+    "rebase [-f fmt] [-t cache] [-p] [-u] -b backing_file [-F backing_fmt] filename")
 STEXI
 @item rebase [-f @var{fmt}] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
 ETEXI
diff --git a/qemu-img.c b/qemu-img.c
index 32628b3110..54137a4e92 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -40,6 +40,7 @@ typedef struct img_cmd_t {
 
 /* Default to cache=writeback as data integrity is not important for qemu-tcg. */
 #define BDRV_O_FLAGS BDRV_O_CACHE_WB
+#define BDRV_DEFAULT_CACHE "writeback"
 
 static void format_print(void *opaque, const char *name)
 {
@@ -64,6 +65,8 @@ static void help(void)
            "Command parameters:\n"
            "  'filename' is a disk image filename\n"
            "  'fmt' is the disk image format. It is guessed automatically in most cases\n"
+           "  'cache' is the cache mode used to write the output disk image, the valid\n"
+           "    options are: 'none', 'writeback' (default), 'writethrough' and 'unsafe'\n"
            "  'size' is the disk image size in bytes. Optional suffixes\n"
            "    'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
            "    and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
@@ -180,6 +183,27 @@ static int read_password(char *buf, int buf_size)
 }
 #endif
 
+static int set_cache_flag(const char *mode, int *flags)
+{
+    *flags &= ~BDRV_O_CACHE_MASK;
+
+    if (!strcmp(mode, "none") || !strcmp(mode, "off")) {
+        *flags |= BDRV_O_CACHE_WB;
+        *flags |= BDRV_O_NOCACHE;
+    } else if (!strcmp(mode, "writeback")) {
+        *flags |= BDRV_O_CACHE_WB;
+    } else if (!strcmp(mode, "unsafe")) {
+        *flags |= BDRV_O_CACHE_WB;
+        *flags |= BDRV_O_NO_FLUSH;
+    } else if (!strcmp(mode, "writethrough")) {
+        /* this is the default */
+    } else {
+        return -1;
+    }
+
+    return 0;
+}
+
 static int print_block_option_help(const char *filename, const char *fmt)
 {
     BlockDriver *drv, *proto_drv;
@@ -441,13 +465,14 @@ static int img_check(int argc, char **argv)
 
 static int img_commit(int argc, char **argv)
 {
-    int c, ret;
-    const char *filename, *fmt;
+    int c, ret, flags;
+    const char *filename, *fmt, *cache;
     BlockDriverState *bs;
 
     fmt = NULL;
+    cache = BDRV_DEFAULT_CACHE;
     for(;;) {
-        c = getopt(argc, argv, "f:h");
+        c = getopt(argc, argv, "f:ht:");
         if (c == -1) {
             break;
         }
@@ -459,6 +484,9 @@ static int img_commit(int argc, char **argv)
         case 'f':
             fmt = optarg;
             break;
+        case 't':
+            cache = optarg;
+            break;
         }
     }
     if (optind >= argc) {
@@ -466,7 +494,14 @@ static int img_commit(int argc, char **argv)
     }
     filename = argv[optind++];
 
-    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
+    flags = BDRV_O_RDWR;
+    ret = set_cache_flag(cache, &flags);
+    if (ret < 0) {
+        error_report("Invalid cache option: %s", cache);
+        return -1;
+    }
+
+    bs = bdrv_new_open(filename, fmt, flags);
     if (!bs) {
         return 1;
     }
@@ -591,8 +626,8 @@ static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
 static int img_convert(int argc, char **argv)
 {
     int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
-    int progress = 0;
-    const char *fmt, *out_fmt, *out_baseimg, *out_filename;
+    int progress = 0, flags;
+    const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
     BlockDriver *drv, *proto_drv;
     BlockDriverState **bs = NULL, *out_bs = NULL;
     int64_t total_sectors, nb_sectors, sector_num, bs_offset;
@@ -608,10 +643,11 @@ static int img_convert(int argc, char **argv)
 
     fmt = NULL;
     out_fmt = "raw";
+    cache = "unsafe";
     out_baseimg = NULL;
     compress = 0;
     for(;;) {
-        c = getopt(argc, argv, "f:O:B:s:hce6o:p");
+        c = getopt(argc, argv, "f:O:B:s:hce6o:pt:");
         if (c == -1) {
             break;
         }
@@ -649,6 +685,9 @@ static int img_convert(int argc, char **argv)
         case 'p':
             progress = 1;
             break;
+        case 't':
+            cache = optarg;
+            break;
         }
     }
 
@@ -779,8 +818,14 @@ static int img_convert(int argc, char **argv)
         goto out;
     }
 
-    out_bs = bdrv_new_open(out_filename, out_fmt,
-        BDRV_O_FLAGS | BDRV_O_RDWR | BDRV_O_NO_FLUSH);
+    flags = BDRV_O_RDWR;
+    ret = set_cache_flag(cache, &flags);
+    if (ret < 0) {
+        error_report("Invalid cache option: %s", cache);
+        return -1;
+    }
+
+    out_bs = bdrv_new_open(out_filename, out_fmt, flags);
     if (!out_bs) {
         ret = -1;
         goto out;
@@ -1225,18 +1270,18 @@ static int img_rebase(int argc, char **argv)
     BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
     BlockDriver *old_backing_drv, *new_backing_drv;
     char *filename;
-    const char *fmt, *out_basefmt, *out_baseimg;
+    const char *fmt, *cache, *out_basefmt, *out_baseimg;
     int c, flags, ret;
     int unsafe = 0;
     int progress = 0;
 
     /* Parse commandline parameters */
     fmt = NULL;
+    cache = BDRV_DEFAULT_CACHE;
     out_baseimg = NULL;
     out_basefmt = NULL;
-
     for(;;) {
-        c = getopt(argc, argv, "uhf:F:b:p");
+        c = getopt(argc, argv, "uhf:F:b:pt:");
         if (c == -1) {
             break;
         }
@@ -1260,6 +1305,9 @@ static int img_rebase(int argc, char **argv)
         case 'p':
             progress = 1;
             break;
+        case 't':
+            cache = optarg;
+            break;
         }
     }
 
@@ -1271,13 +1319,19 @@ static int img_rebase(int argc, char **argv)
     qemu_progress_init(progress, 2.0);
     qemu_progress_print(0, 100);
 
+    flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
+    ret = set_cache_flag(cache, &flags);
+    if (ret < 0) {
+        error_report("Invalid cache option: %s", cache);
+        return -1;
+    }
+
     /*
      * Open the images.
      *
      * Ignore the old backing file for unsafe rebase in case we want to correct
      * the reference to a renamed or moved backing file.
      */
-    flags = BDRV_O_FLAGS | BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
     bs = bdrv_new_open(filename, fmt, flags);
     if (!bs) {
         return 1;
diff --git a/qemu-img.texi b/qemu-img.texi
index ced64a40ed..526474c112 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -173,12 +173,6 @@ Linux or NTFS on Windows), then only the written sectors will reserve
 space. Use @code{qemu-img info} to know the real size used by the
 image or @code{ls -ls} on Unix/Linux.
 
-@item host_device
-
-Host device format. This format should be used instead of raw when
-converting to block devices or other devices where "holes" are not
-supported.
-
 @item qcow2
 QEMU image format, the most versatile format. Use it to have smaller
 images (useful if your filesystem does not supports holes, for example
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 411bd55328..78caa796b6 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -28,8 +28,6 @@
 
 #include "cpu-defs.h"
 
-#include <setjmp.h>
-
 #include "softfloat.h"
 
 #define TARGET_HAS_ICE 1
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 84f8ff6748..d90336634d 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -75,8 +75,6 @@
 
 #include "cpu-defs.h"
 
-#include <setjmp.h>
-
 #include "softfloat.h"
 
 #define TARGET_HAS_ICE 1
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 4edae78ca3..22ee2743d7 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -606,17 +606,6 @@ static inline int cpu_pil_allowed(CPUState *env1, int pil)
 #endif
 }
 
-static inline int cpu_fpu_enabled(CPUState *env1)
-{
-#if defined(CONFIG_USER_ONLY)
-    return 1;
-#elif !defined(TARGET_SPARC64)
-    return env1->psref;
-#else
-    return ((env1->pstate & PS_PEF) != 0) && ((env1->fprs & FPRS_FEF) != 0);
-#endif
-}
-
 #if defined(CONFIG_USER_ONLY)
 static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
 {
@@ -639,6 +628,9 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit);
 trap_state* cpu_tsptr(CPUState* env);
 #endif
 
+#define TB_FLAG_FPU_ENABLED (1 << 4)
+#define TB_FLAG_AM_ENABLED (1 << 5)
+
 static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
 {
@@ -646,16 +638,41 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
     *cs_base = env->npc;
 #ifdef TARGET_SPARC64
     // AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
-    *flags = ((env->pstate & PS_AM) << 2)          /* 5 */
-        | (((env->pstate & PS_PEF) >> 1)           /* 3 */
-        | ((env->fprs & FPRS_FEF) << 2))           /* 4 */
-        | (env->pstate & PS_PRIV)                  /* 2 */
+    *flags = (env->pstate & PS_PRIV)               /* 2 */
         | ((env->lsu & (DMMU_E | IMMU_E)) >> 2)    /* 1, 0 */
         | ((env->tl & 0xff) << 8)
         | (env->dmmu.mmu_primary_context << 16);   /* 16... */
+    if (env->pstate & PS_AM) {
+        *flags |= TB_FLAG_AM_ENABLED;
+    }
+    if ((env->def->features & CPU_FEATURE_FLOAT) && (env->pstate & PS_PEF)
+        && (env->fprs & FPRS_FEF)) {
+        *flags |= TB_FLAG_FPU_ENABLED;
+    }
 #else
     // FPU enable . Supervisor
-    *flags = (env->psref << 4) | env->psrs;
+    *flags = env->psrs;
+    if ((env->def->features & CPU_FEATURE_FLOAT) && env->psref) {
+        *flags |= TB_FLAG_FPU_ENABLED;
+    }
+#endif
+}
+
+static inline bool tb_fpu_enabled(int tb_flags)
+{
+#if defined(CONFIG_USER_ONLY)
+    return true;
+#else
+    return tb_flags & TB_FLAG_FPU_ENABLED;
+#endif
+}
+
+static inline bool tb_am_enabled(int tb_flags)
+{
+#ifndef TARGET_SPARC64
+    return false;
+#else
+    return tb_flags & TB_FLAG_AM_ENABLED;
 #endif
 }
 
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index fd0cfbdb73..15af27ba1f 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -3331,16 +3331,16 @@ void helper_ldda_asi(target_ulong addr, int asi, int rd)
 void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
 {
     unsigned int i;
-    target_ulong val;
+    CPU_DoubleU u;
 
     helper_check_align(addr, 3);
     addr = asi_address_mask(env, asi, addr);
 
     switch (asi) {
-    case 0xf0: // Block load primary
-    case 0xf1: // Block load secondary
-    case 0xf8: // Block load primary LE
-    case 0xf9: // Block load secondary LE
+    case 0xf0: /* UA2007/JPS1 Block load primary */
+    case 0xf1: /* UA2007/JPS1 Block load secondary */
+    case 0xf8: /* UA2007/JPS1 Block load primary LE */
+    case 0xf9: /* UA2007/JPS1 Block load secondary LE */
         if (rd & 7) {
             raise_exception(TT_ILL_INSN);
             return;
@@ -3353,15 +3353,21 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
         }
 
         return;
-    case 0x70: // Block load primary, user privilege
-    case 0x71: // Block load secondary, user privilege
+    case 0x16: /* UA2007 Block load primary, user privilege */
+    case 0x17: /* UA2007 Block load secondary, user privilege */
+    case 0x1e: /* UA2007 Block load primary LE, user privilege */
+    case 0x1f: /* UA2007 Block load secondary LE, user privilege */
+    case 0x70: /* JPS1 Block load primary, user privilege */
+    case 0x71: /* JPS1 Block load secondary, user privilege */
+    case 0x78: /* JPS1 Block load primary LE, user privilege */
+    case 0x79: /* JPS1 Block load secondary LE, user privilege */
         if (rd & 7) {
             raise_exception(TT_ILL_INSN);
             return;
         }
         helper_check_align(addr, 0x3f);
         for (i = 0; i < 16; i++) {
-            *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x1f, 4,
+            *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x19, 4,
                                                          0);
             addr += 4;
         }
@@ -3371,17 +3377,23 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
         break;
     }
 
-    val = helper_ld_asi(addr, asi, size, 0);
     switch(size) {
     default:
     case 4:
-        *((uint32_t *)&env->fpr[rd]) = val;
+        *((uint32_t *)&env->fpr[rd]) = helper_ld_asi(addr, asi, size, 0);
         break;
     case 8:
-        *((int64_t *)&DT0) = val;
+        u.ll = helper_ld_asi(addr, asi, size, 0);
+        *((uint32_t *)&env->fpr[rd++]) = u.l.upper;
+        *((uint32_t *)&env->fpr[rd++]) = u.l.lower;
         break;
     case 16:
-        // XXX
+        u.ll = helper_ld_asi(addr, asi, 8, 0);
+        *((uint32_t *)&env->fpr[rd++]) = u.l.upper;
+        *((uint32_t *)&env->fpr[rd++]) = u.l.lower;
+        u.ll = helper_ld_asi(addr + 8, asi, 8, 0);
+        *((uint32_t *)&env->fpr[rd++]) = u.l.upper;
+        *((uint32_t *)&env->fpr[rd++]) = u.l.lower;
         break;
     }
 }
@@ -3390,17 +3402,18 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
 {
     unsigned int i;
     target_ulong val = 0;
+    CPU_DoubleU u;
 
     helper_check_align(addr, 3);
     addr = asi_address_mask(env, asi, addr);
 
     switch (asi) {
-    case 0xe0: // UA2007 Block commit store primary (cache flush)
-    case 0xe1: // UA2007 Block commit store secondary (cache flush)
-    case 0xf0: // Block store primary
-    case 0xf1: // Block store secondary
-    case 0xf8: // Block store primary LE
-    case 0xf9: // Block store secondary LE
+    case 0xe0: /* UA2007/JPS1 Block commit store primary (cache flush) */
+    case 0xe1: /* UA2007/JPS1 Block commit store secondary (cache flush) */
+    case 0xf0: /* UA2007/JPS1 Block store primary */
+    case 0xf1: /* UA2007/JPS1 Block store secondary */
+    case 0xf8: /* UA2007/JPS1 Block store primary LE */
+    case 0xf9: /* UA2007/JPS1 Block store secondary LE */
         if (rd & 7) {
             raise_exception(TT_ILL_INSN);
             return;
@@ -3413,8 +3426,14 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
         }
 
         return;
-    case 0x70: // Block store primary, user privilege
-    case 0x71: // Block store secondary, user privilege
+    case 0x16: /* UA2007 Block load primary, user privilege */
+    case 0x17: /* UA2007 Block load secondary, user privilege */
+    case 0x1e: /* UA2007 Block load primary LE, user privilege */
+    case 0x1f: /* UA2007 Block load secondary LE, user privilege */
+    case 0x70: /* JPS1 Block store primary, user privilege */
+    case 0x71: /* JPS1 Block store secondary, user privilege */
+    case 0x78: /* JPS1 Block load primary LE, user privilege */
+    case 0x79: /* JPS1 Block load secondary LE, user privilege */
         if (rd & 7) {
             raise_exception(TT_ILL_INSN);
             return;
@@ -3422,7 +3441,7 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
         helper_check_align(addr, 0x3f);
         for (i = 0; i < 16; i++) {
             val = *(uint32_t *)&env->fpr[rd++];
-            helper_st_asi(addr, val, asi & 0x1f, 4);
+            helper_st_asi(addr, val, asi & 0x19, 4);
             addr += 4;
         }
 
@@ -3434,16 +3453,22 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
     switch(size) {
     default:
     case 4:
-        val = *((uint32_t *)&env->fpr[rd]);
+        helper_st_asi(addr, *(uint32_t *)&env->fpr[rd], asi, size);
         break;
     case 8:
-        val = *((int64_t *)&DT0);
+        u.l.upper = *(uint32_t *)&env->fpr[rd++];
+        u.l.lower = *(uint32_t *)&env->fpr[rd++];
+        helper_st_asi(addr, u.ll, asi, size);
         break;
     case 16:
-        // XXX
+        u.l.upper = *(uint32_t *)&env->fpr[rd++];
+        u.l.lower = *(uint32_t *)&env->fpr[rd++];
+        helper_st_asi(addr, u.ll, asi, 8);
+        u.l.upper = *(uint32_t *)&env->fpr[rd++];
+        u.l.lower = *(uint32_t *)&env->fpr[rd++];
+        helper_st_asi(addr + 8, u.ll, asi, 8);
         break;
     }
-    helper_st_asi(addr, val, asi, size);
 }
 
 target_ulong helper_cas_asi(target_ulong addr, target_ulong val1,
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index f32a674f35..27c2cf98e8 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -4484,10 +4484,16 @@ static void disas_sparc_insn(DisasContext * dc)
                 case 0x2d: /* V9 prefetch, no effect */
                     goto skip_move;
                 case 0x30: /* V9 ldfa */
+                    if (gen_trap_ifnofpu(dc, cpu_cond)) {
+                        goto jmp_insn;
+                    }
                     save_state(dc, cpu_cond);
                     gen_ldf_asi(cpu_addr, insn, 4, rd);
                     goto skip_move;
                 case 0x33: /* V9 lddfa */
+                    if (gen_trap_ifnofpu(dc, cpu_cond)) {
+                        goto jmp_insn;
+                    }
                     save_state(dc, cpu_cond);
                     gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
                     goto skip_move;
@@ -4495,6 +4501,9 @@ static void disas_sparc_insn(DisasContext * dc)
                     goto skip_move;
                 case 0x32: /* V9 ldqfa */
                     CHECK_FPU_FEATURE(dc, FLOAT128);
+                    if (gen_trap_ifnofpu(dc, cpu_cond)) {
+                        goto jmp_insn;
+                    }
                     save_state(dc, cpu_cond);
                     gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
                     goto skip_move;
@@ -4723,6 +4732,9 @@ static void disas_sparc_insn(DisasContext * dc)
                 switch (xop) {
 #ifdef TARGET_SPARC64
                 case 0x34: /* V9 stfa */
+                    if (gen_trap_ifnofpu(dc, cpu_cond)) {
+                        goto jmp_insn;
+                    }
                     gen_stf_asi(cpu_addr, insn, 4, rd);
                     break;
                 case 0x36: /* V9 stqfa */
@@ -4730,15 +4742,19 @@ static void disas_sparc_insn(DisasContext * dc)
                         TCGv_i32 r_const;
 
                         CHECK_FPU_FEATURE(dc, FLOAT128);
+                        if (gen_trap_ifnofpu(dc, cpu_cond)) {
+                            goto jmp_insn;
+                        }
                         r_const = tcg_const_i32(7);
                         gen_helper_check_align(cpu_addr, r_const);
                         tcg_temp_free_i32(r_const);
-                        gen_op_load_fpr_QT0(QFPREG(rd));
                         gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
                     }
                     break;
                 case 0x37: /* V9 stdfa */
-                    gen_op_load_fpr_DT0(DFPREG(rd));
+                    if (gen_trap_ifnofpu(dc, cpu_cond)) {
+                        goto jmp_insn;
+                    }
                     gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
                     break;
                 case 0x3c: /* V9 casa */
@@ -4863,13 +4879,8 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
     dc->cc_op = CC_OP_DYNAMIC;
     dc->mem_idx = cpu_mmu_index(env);
     dc->def = env->def;
-    if ((dc->def->features & CPU_FEATURE_FLOAT))
-        dc->fpu_enabled = cpu_fpu_enabled(env);
-    else
-        dc->fpu_enabled = 0;
-#ifdef TARGET_SPARC64
-    dc->address_mask_32bit = env->pstate & PS_AM;
-#endif
+    dc->fpu_enabled = tb_fpu_enabled(tb->flags);
+    dc->address_mask_32bit = tb_am_enabled(tb->flags);
     dc->singlestep = (env->singlestep_enabled || singlestep);
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
 
diff --git a/tcg/README b/tcg/README
index 660012281f..cfdfd96d09 100644
--- a/tcg/README
+++ b/tcg/README
@@ -504,7 +504,15 @@ register.
 - Don't hesitate to use helpers for complicated or seldom used target
   instructions. There is little performance advantage in using TCG to
   implement target instructions taking more than about twenty TCG
-  instructions.
+  instructions. Note that this rule of thumb is more applicable to
+  helpers doing complex logic or arithmetic, where the C compiler has
+  scope to do a good job of optimisation; it is less relevant where
+  the instruction is mostly doing loads and stores, and in those cases
+  inline TCG may still be faster for longer sequences.
+
+- The hard limit on the number of TCG instructions you can generate
+  per target instruction is set by MAX_OP_PER_INSTR in exec-all.h --
+  you cannot exceed this without risking a buffer overrun.
 
 - Use the 'discard' instruction if you know that TCG won't be able to
   prove that a given global is "dead" at a given program point. The
diff --git a/trace-events b/trace-events
index bebf612fe9..765a15ed77 100644
--- a/trace-events
+++ b/trace-events
@@ -46,6 +46,17 @@ disable virtio_queue_notify(void *vdev, int n, void *vq) "vdev %p n %d vq %p"
 disable virtio_irq(void *vq) "vq %p"
 disable virtio_notify(void *vdev, void *vq) "vdev %p vq %p"
 
+# hw/virtio-serial-bus.c
+disable virtio_serial_send_control_event(unsigned int port, uint16_t event, uint16_t value) "port %u, event %u, value %u"
+disable virtio_serial_throttle_port(unsigned int port, bool throttle) "port %u, throttle %d"
+disable virtio_serial_handle_control_message(uint16_t event, uint16_t value) "event %u, value %u"
+disable virtio_serial_handle_control_message_port(unsigned int port) "port %u"
+
+# hw/virtio-console.c
+disable virtio_console_flush_buf(unsigned int port, size_t len, ssize_t ret) "port %u, in_len %zu, out_len %zd"
+disable virtio_console_chr_read(unsigned int port, int size) "port %u, size %d"
+disable virtio_console_chr_event(unsigned int port, int event) "port %u, event %d"
+
 # block.c
 disable multiwrite_cb(void *mcb, int ret) "mcb %p ret %d"
 disable bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) "mcb %p num_callbacks %d num_reqs %d"
diff --git a/ui/spice-core.c b/ui/spice-core.c
index dd9905be36..e142452bb6 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -602,7 +602,10 @@ void qemu_spice_init(void)
 
     qemu_opt_foreach(opts, add_channel, NULL, 0);
 
-    spice_server_init(spice_server, &core_interface);
+    if (0 != spice_server_init(spice_server, &core_interface)) {
+        fprintf(stderr, "failed to initialize spice server");
+        exit(1);
+    };
     using_spice = 1;
 
     migration_state.notify = migration_state_notifier;
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 15f0704eaf..feeee73dcc 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -70,6 +70,7 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
     QXLCommand *cmd;
     uint8_t *src, *dst;
     int by, bw, bh;
+    struct timespec time_space;
 
     if (qemu_spice_rect_is_empty(&ssd->dirty)) {
         return NULL;
@@ -96,6 +97,10 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
     drawable->surfaces_dest[0] = -1;
     drawable->surfaces_dest[1] = -1;
     drawable->surfaces_dest[2] = -1;
+    clock_gettime(CLOCK_MONOTONIC, &time_space);
+    /* time in milliseconds from epoch. */
+    drawable->mm_time = time_space.tv_sec * 1000
+                      + time_space.tv_nsec / 1000 / 1000;
 
     drawable->u.copy.rop_descriptor  = SPICE_ROPD_OP_PUT;
     drawable->u.copy.src_bitmap      = (intptr_t)image;