summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--backends/rng-random.c18
-rw-r--r--block/iscsi.c1
-rwxr-xr-xconfigure2
-rw-r--r--cpus.c16
-rw-r--r--docs/atomics.txt4
-rw-r--r--exec.c64
-rw-r--r--hw/arm/virt.c4
-rw-r--r--hw/core/machine.c31
-rw-r--r--hw/core/nmi.c24
-rw-r--r--hw/display/vga.c50
-rw-r--r--hw/display/vga_int.h1
-rw-r--r--hw/display/virtio-gpu-3d.c5
-rw-r--r--hw/display/virtio-gpu.c28
-rw-r--r--hw/display/virtio-vga.c8
-rw-r--r--hw/i386/kvmvapic.c2
-rw-r--r--hw/i386/pc.c20
-rw-r--r--hw/i386/pc_piix.c13
-rw-r--r--hw/intc/ioapic.c33
-rw-r--r--hw/lm32/milkymist-hw.h4
-rw-r--r--hw/lm32/milkymist.c4
-rw-r--r--hw/net/opencores_eth.c44
-rw-r--r--hw/nvram/fw_cfg.c6
-rw-r--r--hw/ppc/spapr.c4
-rw-r--r--hw/s390x/s390-virtio-ccw.c1
-rw-r--r--hw/scsi/esp.c17
-rw-r--r--hw/sparc/sun4m.c2
-rw-r--r--hw/usb/Makefile.objs4
-rw-r--r--hw/usb/hcd-ohci.c6
-rw-r--r--hw/usb/xen-usb.c1080
-rw-r--r--hw/watchdog/watchdog.c2
-rw-r--r--hw/xen/xen_backend.c63
-rw-r--r--hw/xen/xen_devconfig.c52
-rw-r--r--hw/xenpv/xen_machine_pv.c43
-rw-r--r--include/exec/cpu-common.h4
-rw-r--r--include/exec/memory.h1
-rw-r--r--include/exec/ram_addr.h2
-rw-r--r--include/hw/boards.h12
-rw-r--r--include/hw/i386/ioapic_internal.h5
-rw-r--r--include/hw/i386/pc.h9
-rw-r--r--include/hw/mem/pc-dimm.h4
-rw-r--r--include/hw/nmi.h1
-rw-r--r--include/hw/virtio/virtio-gpu.h6
-rw-r--r--include/hw/virtio/virtio-rng.h2
-rw-r--r--include/hw/xen/xen_backend.h6
-rw-r--r--include/hw/xen/xen_common.h2
-rw-r--r--include/qemu/osdep.h13
-rw-r--r--include/sysemu/rng-random.h4
-rw-r--r--include/sysemu/sysemu.h12
-rw-r--r--include/ui/console.h71
-rw-r--r--include/ui/qemu-spice.h13
-rw-r--r--memory.c46
-rw-r--r--migration/ram.c2
-rw-r--r--migration/savevm.c4
-rw-r--r--qemu-img.c5
-rw-r--r--qemu-io.c5
-rw-r--r--qemu-nbd.c5
-rw-r--r--scripts/cocci-macro-file.h6
-rw-r--r--scripts/signrom.py28
-rw-r--r--target-i386/translate.c5
-rw-r--r--translate-all.c3
-rw-r--r--util/oslib-posix.c13
-rw-r--r--vl.c294
63 files changed, 1716 insertions, 524 deletions
diff --git a/Makefile b/Makefile
index 1d076a9d85..a5d7e62626 100644
--- a/Makefile
+++ b/Makefile
@@ -356,6 +356,7 @@ clean:
 	if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
 	rm -f $$d/qemu-options.def; \
         done
+	rm -f $(SUBDIR_DEVICES_MAK) config-all-devices.mak
 
 VERSION ?= $(shell cat VERSION)
 
diff --git a/backends/rng-random.c b/backends/rng-random.c
index 2e44e25190..e2a49b0571 100644
--- a/backends/rng-random.c
+++ b/backends/rng-random.c
@@ -17,7 +17,7 @@
 #include "qapi/qmp/qerror.h"
 #include "qemu/main-loop.h"
 
-struct RndRandom
+struct RngRandom
 {
     RngBackend parent;
 
@@ -34,7 +34,7 @@ struct RndRandom
 
 static void entropy_available(void *opaque)
 {
-    RndRandom *s = RNG_RANDOM(opaque);
+    RngRandom *s = RNG_RANDOM(opaque);
 
     while (!QSIMPLEQ_EMPTY(&s->parent.requests)) {
         RngRequest *req = QSIMPLEQ_FIRST(&s->parent.requests);
@@ -57,7 +57,7 @@ static void entropy_available(void *opaque)
 
 static void rng_random_request_entropy(RngBackend *b, RngRequest *req)
 {
-    RndRandom *s = RNG_RANDOM(b);
+    RngRandom *s = RNG_RANDOM(b);
 
     if (QSIMPLEQ_EMPTY(&s->parent.requests)) {
         /* If there are no pending requests yet, we need to
@@ -68,7 +68,7 @@ static void rng_random_request_entropy(RngBackend *b, RngRequest *req)
 
 static void rng_random_opened(RngBackend *b, Error **errp)
 {
-    RndRandom *s = RNG_RANDOM(b);
+    RngRandom *s = RNG_RANDOM(b);
 
     if (s->filename == NULL) {
         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
@@ -83,7 +83,7 @@ static void rng_random_opened(RngBackend *b, Error **errp)
 
 static char *rng_random_get_filename(Object *obj, Error **errp)
 {
-    RndRandom *s = RNG_RANDOM(obj);
+    RngRandom *s = RNG_RANDOM(obj);
 
     return g_strdup(s->filename);
 }
@@ -92,7 +92,7 @@ static void rng_random_set_filename(Object *obj, const char *filename,
                                  Error **errp)
 {
     RngBackend *b = RNG_BACKEND(obj);
-    RndRandom *s = RNG_RANDOM(obj);
+    RngRandom *s = RNG_RANDOM(obj);
 
     if (b->opened) {
         error_setg(errp, QERR_PERMISSION_DENIED);
@@ -105,7 +105,7 @@ static void rng_random_set_filename(Object *obj, const char *filename,
 
 static void rng_random_init(Object *obj)
 {
-    RndRandom *s = RNG_RANDOM(obj);
+    RngRandom *s = RNG_RANDOM(obj);
 
     object_property_add_str(obj, "filename",
                             rng_random_get_filename,
@@ -118,7 +118,7 @@ static void rng_random_init(Object *obj)
 
 static void rng_random_finalize(Object *obj)
 {
-    RndRandom *s = RNG_RANDOM(obj);
+    RngRandom *s = RNG_RANDOM(obj);
 
     if (s->fd != -1) {
         qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
@@ -139,7 +139,7 @@ static void rng_random_class_init(ObjectClass *klass, void *data)
 static const TypeInfo rng_random_info = {
     .name = TYPE_RNG_RANDOM,
     .parent = TYPE_RNG_BACKEND,
-    .instance_size = sizeof(RndRandom),
+    .instance_size = sizeof(RngRandom),
     .class_init = rng_random_class_init,
     .instance_init = rng_random_init,
     .instance_finalize = rng_random_finalize,
diff --git a/block/iscsi.c b/block/iscsi.c
index 10f3906bcc..2ca8e72967 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -761,6 +761,7 @@ iscsi_aio_ioctl_cb(struct iscsi_context *iscsi, int status,
     acb->ioh->driver_status = 0;
     acb->ioh->host_status   = 0;
     acb->ioh->resid         = 0;
+    acb->ioh->status        = status;
 
 #define SG_ERR_DRIVER_SENSE    0x08
 
diff --git a/configure b/configure
index 293639cf6d..b5aab7257b 100755
--- a/configure
+++ b/configure
@@ -2985,7 +2985,7 @@ int main(void) {
 }
 EOF
 
-if ! compile_prog "-Werror $CFLAGS" "$LIBS" ; then
+if ! compile_prog "$CFLAGS" "$LIBS" ; then
     error_exit "sizeof(size_t) doesn't match GLIB_SIZEOF_SIZE_T."\
                "You probably need to set PKG_CONFIG_LIBDIR"\
 	       "to point to the right pkg-config files for your"\
diff --git a/cpus.c b/cpus.c
index eb34b4fe76..e75895a458 100644
--- a/cpus.c
+++ b/cpus.c
@@ -780,7 +780,7 @@ static void sigbus_reraise(void)
         raise(SIGBUS);
         sigemptyset(&set);
         sigaddset(&set, SIGBUS);
-        sigprocmask(SIG_UNBLOCK, &set, NULL);
+        pthread_sigmask(SIG_UNBLOCK, &set, NULL);
     }
     perror("Failed to re-raise SIGBUS!\n");
     abort();
@@ -1693,21 +1693,7 @@ exit:
 
 void qmp_inject_nmi(Error **errp)
 {
-#if defined(TARGET_I386)
-    CPUState *cs;
-
-    CPU_FOREACH(cs) {
-        X86CPU *cpu = X86_CPU(cs);
-
-        if (!cpu->apic_state) {
-            cpu_interrupt(cs, CPU_INTERRUPT_NMI);
-        } else {
-            apic_deliver_nmi(cpu->apic_state);
-        }
-    }
-#else
     nmi_monitor_handle(monitor_get_cpu_index(), errp);
-#endif
 }
 
 void dump_drift_info(FILE *f, fprintf_function cpu_fprintf)
diff --git a/docs/atomics.txt b/docs/atomics.txt
index ef285e3c2a..bba771ecd6 100644
--- a/docs/atomics.txt
+++ b/docs/atomics.txt
@@ -62,7 +62,7 @@ operations:
     typeof(*ptr) atomic_fetch_sub(ptr, val)
     typeof(*ptr) atomic_fetch_and(ptr, val)
     typeof(*ptr) atomic_fetch_or(ptr, val)
-    typeof(*ptr) atomic_xchg(ptr, val
+    typeof(*ptr) atomic_xchg(ptr, val)
     typeof(*ptr) atomic_cmpxchg(ptr, old, new)
 
 all of which return the old value of *ptr.  These operations are
@@ -328,7 +328,7 @@ and memory barriers, and the equivalents in QEMU:
 
 - atomic_read and atomic_set in Linux give no guarantee at all;
   atomic_read and atomic_set in QEMU include a compiler barrier
-  (similar to the ACCESS_ONCE macro in Linux).
+  (similar to the READ_ONCE/WRITE_ONCE macros in Linux).
 
 - most atomic read-modify-write operations in Linux return void;
   in QEMU, all of them return the old value of the variable.
diff --git a/exec.c b/exec.c
index 2e363f06a6..a3a93aeed3 100644
--- a/exec.c
+++ b/exec.c
@@ -1046,8 +1046,7 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu,
 
     if (memory_region_is_ram(section->mr)) {
         /* Normal RAM.  */
-        iotlb = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
-            + xlat;
+        iotlb = memory_region_get_ram_addr(section->mr) + xlat;
         if (!section->readonly) {
             iotlb |= PHYS_SECTION_NOTDIRTY;
         } else {
@@ -1299,7 +1298,7 @@ static void *file_ram_alloc(RAMBlock *block,
     }
 
     page_size = qemu_fd_getpagesize(fd);
-    block->mr->align = page_size;
+    block->mr->align = MAX(page_size, QEMU_VMALLOC_ALIGN);
 
     if (memory < page_size) {
         error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to "
@@ -1320,7 +1319,8 @@ static void *file_ram_alloc(RAMBlock *block,
         perror("ftruncate");
     }
 
-    area = qemu_ram_mmap(fd, memory, page_size, block->flags & RAM_SHARED);
+    area = qemu_ram_mmap(fd, memory, block->mr->align,
+                         block->flags & RAM_SHARED);
     if (area == MAP_FAILED) {
         error_setg_errno(errp, errno,
                          "unable to map backing store for guest RAM");
@@ -1410,34 +1410,16 @@ static void qemu_ram_setup_dump(void *addr, ram_addr_t size)
     }
 }
 
-/* Called within an RCU critical section, or while the ramlist lock
- * is held.
- */
-static RAMBlock *find_ram_block(ram_addr_t addr)
-{
-    RAMBlock *block;
-
-    QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
-        if (block->offset == addr) {
-            return block;
-        }
-    }
-
-    return NULL;
-}
-
 const char *qemu_ram_get_idstr(RAMBlock *rb)
 {
     return rb->idstr;
 }
 
 /* Called with iothread lock held.  */
-void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
+void qemu_ram_set_idstr(RAMBlock *new_block, const char *name, DeviceState *dev)
 {
-    RAMBlock *new_block, *block;
+    RAMBlock *block;
 
-    rcu_read_lock();
-    new_block = find_ram_block(addr);
     assert(new_block);
     assert(!new_block->idstr[0]);
 
@@ -1450,8 +1432,10 @@ void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
     }
     pstrcat(new_block->idstr, sizeof(new_block->idstr), name);
 
+    rcu_read_lock();
     QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
-        if (block != new_block && !strcmp(block->idstr, new_block->idstr)) {
+        if (block != new_block &&
+            !strcmp(block->idstr, new_block->idstr)) {
             fprintf(stderr, "RAMBlock \"%s\" already registered, abort!\n",
                     new_block->idstr);
             abort();
@@ -1461,21 +1445,15 @@ void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
 }
 
 /* Called with iothread lock held.  */
-void qemu_ram_unset_idstr(ram_addr_t addr)
+void qemu_ram_unset_idstr(RAMBlock *block)
 {
-    RAMBlock *block;
-
     /* FIXME: arch_init.c assumes that this is not called throughout
      * migration.  Ignore the problem since hot-unplug during migration
      * does not work anyway.
      */
-
-    rcu_read_lock();
-    block = find_ram_block(addr);
     if (block) {
         memset(block->idstr, 0, sizeof(block->idstr));
     }
-    rcu_read_unlock();
 }
 
 static int memory_try_enable_merging(void *addr, size_t len)
@@ -1495,10 +1473,8 @@ static int memory_try_enable_merging(void *addr, size_t len)
  * resize callback to update device state and/or add assertions to detect
  * misuse, if necessary.
  */
-int qemu_ram_resize(ram_addr_t base, ram_addr_t newsize, Error **errp)
+int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp)
 {
-    RAMBlock *block = find_ram_block(base);
-
     assert(block);
 
     newsize = HOST_PAGE_ALIGN(newsize);
@@ -3102,9 +3078,7 @@ static inline uint32_t address_space_ldl_internal(AddressSpace *as, hwaddr addr,
     } else {
         /* RAM case */
         ptr = qemu_get_ram_ptr(mr->ram_block,
-                               (memory_region_get_ram_addr(mr)
-                                & TARGET_PAGE_MASK)
-                               + addr1);
+                               memory_region_get_ram_addr(mr) + addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             val = ldl_le_p(ptr);
@@ -3198,9 +3172,7 @@ static inline uint64_t address_space_ldq_internal(AddressSpace *as, hwaddr addr,
     } else {
         /* RAM case */
         ptr = qemu_get_ram_ptr(mr->ram_block,
-                               (memory_region_get_ram_addr(mr)
-                                & TARGET_PAGE_MASK)
-                               + addr1);
+                               memory_region_get_ram_addr(mr) + addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             val = ldq_le_p(ptr);
@@ -3314,9 +3286,7 @@ static inline uint32_t address_space_lduw_internal(AddressSpace *as,
     } else {
         /* RAM case */
         ptr = qemu_get_ram_ptr(mr->ram_block,
-                               (memory_region_get_ram_addr(mr)
-                                & TARGET_PAGE_MASK)
-                               + addr1);
+                               memory_region_get_ram_addr(mr) + addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             val = lduw_le_p(ptr);
@@ -3398,7 +3368,7 @@ void address_space_stl_notdirty(AddressSpace *as, hwaddr addr, uint32_t val,
 
         r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
     } else {
-        addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
+        addr1 += memory_region_get_ram_addr(mr);
         ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
         stl_p(ptr, val);
 
@@ -3453,7 +3423,7 @@ static inline void address_space_stl_internal(AddressSpace *as,
         r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
     } else {
         /* RAM case */
-        addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
+        addr1 += memory_region_get_ram_addr(mr);
         ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
@@ -3563,7 +3533,7 @@ static inline void address_space_stw_internal(AddressSpace *as,
         r = memory_region_dispatch_write(mr, addr1, val, 2, attrs);
     } else {
         /* RAM case */
-        addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
+        addr1 += memory_region_get_ram_addr(mr);
         ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index fe6b11d24e..e77ed88afb 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1418,13 +1418,9 @@ static void virt_2_6_instance_init(Object *obj)
 static void virt_2_6_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
-    static GlobalProperty compat_props[] = {
-        { /* end of list */ }
-    };
 
     mc->desc = "QEMU 2.6 ARM Virtual Machine";
     mc->alias = "virt";
-    mc->compat_props = compat_props;
 }
 
 static const TypeInfo machvirt_info = {
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 6dbbc85b97..ccdd5fa3e7 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -257,6 +257,20 @@ static void machine_set_usb(Object *obj, bool value, Error **errp)
     ms->usb_disabled = !value;
 }
 
+static bool machine_get_graphics(Object *obj, Error **errp)
+{
+    MachineState *ms = MACHINE(obj);
+
+    return ms->enable_graphics;
+}
+
+static void machine_set_graphics(Object *obj, bool value, Error **errp)
+{
+    MachineState *ms = MACHINE(obj);
+
+    ms->enable_graphics = value;
+}
+
 static bool machine_get_igd_gfx_passthru(Object *obj, Error **errp)
 {
     MachineState *ms = MACHINE(obj);
@@ -382,6 +396,7 @@ static void machine_initfn(Object *obj)
     ms->kvm_shadow_mem = -1;
     ms->dump_guest_core = true;
     ms->mem_merge = true;
+    ms->enable_graphics = true;
 
     object_property_add_str(obj, "accel",
                             machine_get_accel, machine_set_accel, NULL);
@@ -460,6 +475,12 @@ static void machine_initfn(Object *obj)
     object_property_set_description(obj, "usb",
                                     "Set on/off to enable/disable usb",
                                     NULL);
+    object_property_add_bool(obj, "graphics",
+                             machine_get_graphics,
+                             machine_set_graphics, NULL);
+    object_property_set_description(obj, "graphics",
+                                    "Set on/off to enable/disable graphics emulation",
+                                    NULL);
     object_property_add_bool(obj, "igd-passthru",
                              machine_get_igd_gfx_passthru,
                              machine_set_igd_gfx_passthru, NULL);
@@ -550,6 +571,15 @@ bool machine_mem_merge(MachineState *machine)
     return machine->mem_merge;
 }
 
+static void machine_class_finalize(ObjectClass *klass, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(klass);
+
+    if (mc->compat_props) {
+        g_array_free(mc->compat_props, true);
+    }
+}
+
 static const TypeInfo machine_info = {
     .name = TYPE_MACHINE,
     .parent = TYPE_OBJECT,
@@ -557,6 +587,7 @@ static const TypeInfo machine_info = {
     .class_size = sizeof(MachineClass),
     .class_init    = machine_class_init,
     .class_base_init = machine_class_base_init,
+    .class_finalize = machine_class_finalize,
     .instance_size = sizeof(MachineState),
     .instance_init = machine_initfn,
     .instance_finalize = machine_finalize,
diff --git a/hw/core/nmi.c b/hw/core/nmi.c
index f616a79312..bfd0896daf 100644
--- a/hw/core/nmi.c
+++ b/hw/core/nmi.c
@@ -20,16 +20,11 @@
  */
 
 #include "qemu/osdep.h"
-#include "qom/cpu.h"
 #include "hw/nmi.h"
 #include "qapi/error.h"
 #include "qapi/qmp/qerror.h"
 #include "monitor/monitor.h"
 
-#if defined(TARGET_I386)
-#include "cpu.h"
-#endif
-
 struct do_nmi_s {
     int cpu_index;
     Error *err;
@@ -78,25 +73,6 @@ void nmi_monitor_handle(int cpu_index, Error **errp)
     }
 }
 
-void inject_nmi(void)
-{
-#if defined(TARGET_I386)
-    CPUState *cs;
-
-    CPU_FOREACH(cs) {
-        X86CPU *cpu = X86_CPU(cs);
-
-        if (!cpu->apic_state) {
-            cpu_interrupt(cs, CPU_INTERRUPT_NMI);
-        } else {
-            apic_deliver_nmi(cpu->apic_state);
-        }
-    }
-#else
-    nmi_monitor_handle(0, NULL);
-#endif
-}
-
 static const TypeInfo nmi_info = {
     .name          = TYPE_NMI,
     .parent        = TYPE_INTERFACE,
diff --git a/hw/display/vga.c b/hw/display/vga.c
index 4a55ec6dbb..9ebc54f22b 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -149,6 +149,11 @@ static inline bool vbe_enabled(VGACommonState *s)
     return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED;
 }
 
+static inline uint8_t sr(VGACommonState *s, int idx)
+{
+    return vbe_enabled(s) ? s->sr_vbe[idx] : s->sr[idx];
+}
+
 static void vga_update_memory_access(VGACommonState *s)
 {
     hwaddr base, offset, size;
@@ -163,8 +168,8 @@ static void vga_update_memory_access(VGACommonState *s)
         s->has_chain4_alias = false;
         s->plane_updated = 0xf;
     }
-    if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) ==
-        VGA_SR02_ALL_PLANES && s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
+    if ((sr(s, VGA_SEQ_PLANE_WRITE) & VGA_SR02_ALL_PLANES) ==
+        VGA_SR02_ALL_PLANES && sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) {
         offset = 0;
         switch ((s->gr[VGA_GFX_MISC] >> 2) & 3) {
         case 0:
@@ -234,7 +239,7 @@ static void vga_precise_update_retrace_info(VGACommonState *s)
           ((s->cr[VGA_CRTC_OVERFLOW] >> 6) & 2)) << 8);
     vretr_end_line = s->cr[VGA_CRTC_V_SYNC_END] & 0xf;
 
-    clocking_mode = (s->sr[VGA_SEQ_CLOCK_MODE] >> 3) & 1;
+    clocking_mode = (sr(s, VGA_SEQ_CLOCK_MODE) >> 3) & 1;
     clock_sel = (s->msr >> 2) & 3;
     dots = (s->msr & 1) ? 8 : 9;
 
@@ -486,7 +491,6 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
         printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
 #endif
         s->sr[s->sr_index] = val & sr_mask[s->sr_index];
-        vbe_update_vgaregs(s);
         if (s->sr_index == VGA_SEQ_CLOCK_MODE) {
             s->update_retrace_info(s);
         }
@@ -680,13 +684,13 @@ static void vbe_update_vgaregs(VGACommonState *s)
 
     if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
         shift_control = 0;
-        s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
+        s->sr_vbe[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
     } else {
         shift_control = 2;
         /* set chain 4 mode */
-        s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
+        s->sr_vbe[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
         /* activate all planes */
-        s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
+        s->sr_vbe[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
     }
     s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
         (shift_control << 5);
@@ -836,7 +840,7 @@ uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr)
         break;
     }
 
-    if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
+    if (sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) {
         /* chain 4 mode : simplest access */
         assert(addr < s->vram_size);
         ret = s->vram_ptr[addr];
@@ -904,11 +908,11 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
         break;
     }
 
-    if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
+    if (sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) {
         /* chain 4 mode : simplest access */
         plane = addr & 3;
         mask = (1 << plane);
-        if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
+        if (sr(s, VGA_SEQ_PLANE_WRITE) & mask) {
             assert(addr < s->vram_size);
             s->vram_ptr[addr] = val;
 #ifdef DEBUG_VGA_MEM
@@ -921,7 +925,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
         /* odd/even mode (aka text mode mapping) */
         plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
         mask = (1 << plane);
-        if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
+        if (sr(s, VGA_SEQ_PLANE_WRITE) & mask) {
             addr = ((addr & ~1) << 1) | plane;
             if (addr >= s->vram_size) {
                 return;
@@ -996,7 +1000,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
 
     do_write:
         /* mask data according to sr[2] */
-        mask = s->sr[VGA_SEQ_PLANE_WRITE];
+        mask = sr(s, VGA_SEQ_PLANE_WRITE);
         s->plane_updated |= mask; /* only used to detect font change */
         write_mask = mask16[mask];
         if (addr * sizeof(uint32_t) >= s->vram_size) {
@@ -1152,10 +1156,10 @@ static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight
     /* total width & height */
     cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
     cwidth = 8;
-    if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
+    if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) {
         cwidth = 9;
     }
-    if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
+    if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) {
         cwidth = 16; /* NOTE: no 18 pixel wide */
     }
     width = (s->cr[VGA_CRTC_H_DISP] + 1);
@@ -1197,7 +1201,7 @@ static void vga_draw_text(VGACommonState *s, int full_update)
     int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
 
     /* compute font data address (in plane 2) */
-    v = s->sr[VGA_SEQ_CHARACTER_MAP];
+    v = sr(s, VGA_SEQ_CHARACTER_MAP);
     offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
     if (offset != s->font_offsets[0]) {
         s->font_offsets[0] = offset;
@@ -1506,11 +1510,11 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
     }
 
     if (shift_control == 0) {
-        if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
+        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
             disp_width <<= 1;
         }
     } else if (shift_control == 1) {
-        if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
+        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
             disp_width <<= 1;
         }
     }
@@ -1574,7 +1578,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
 
     if (shift_control == 0) {
         full_update |= update_palette16(s);
-        if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
+        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
             v = VGA_DRAW_LINE4D2;
         } else {
             v = VGA_DRAW_LINE4;
@@ -1582,7 +1586,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
         bits = 4;
     } else if (shift_control == 1) {
         full_update |= update_palette16(s);
-        if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
+        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
             v = VGA_DRAW_LINE2D2;
         } else {
             v = VGA_DRAW_LINE2;
@@ -1629,7 +1633,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
 #if 0
     printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
            width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
-           s->line_compare, s->sr[VGA_SEQ_CLOCK_MODE]);
+           s->line_compare, sr(s, VGA_SEQ_CLOCK_MODE));
 #endif
     addr1 = (s->start_addr * 4);
     bwidth = (width * bits + 7) / 8;
@@ -1781,6 +1785,7 @@ void vga_common_reset(VGACommonState *s)
 {
     s->sr_index = 0;
     memset(s->sr, '\0', sizeof(s->sr));
+    memset(s->sr_vbe, '\0', sizeof(s->sr_vbe));
     s->gr_index = 0;
     memset(s->gr, '\0', sizeof(s->gr));
     s->ar_index = 0;
@@ -1883,10 +1888,10 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
         /* total width & height */
         cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
         cw = 8;
-        if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
+        if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) {
             cw = 9;
         }
-        if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
+        if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) {
             cw = 16; /* NOTE: no 18 pixel wide */
         }
         width = (s->cr[VGA_CRTC_H_DISP] + 1);
@@ -2053,6 +2058,7 @@ static int vga_common_post_load(void *opaque, int version_id)
 
     /* force refresh */
     s->graphic_mode = -1;
+    vbe_update_vgaregs(s);
     return 0;
 }
 
diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
index bdb43a5a34..3ce5544efd 100644
--- a/hw/display/vga_int.h
+++ b/hw/display/vga_int.h
@@ -98,6 +98,7 @@ typedef struct VGACommonState {
     MemoryRegion chain4_alias;
     uint8_t sr_index;
     uint8_t sr[256];
+    uint8_t sr_vbe[256];
     uint8_t gr_index;
     uint8_t gr[256];
     uint8_t ar_index;
diff --git a/hw/display/virtio-gpu-3d.c b/hw/display/virtio-gpu-3d.c
index fa192946a3..433bf93024 100644
--- a/hw/display/virtio-gpu-3d.c
+++ b/hw/display/virtio-gpu-3d.c
@@ -17,6 +17,7 @@
 #include "trace.h"
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/virtio-gpu.h"
+#include "qapi/error.h"
 
 #ifdef CONFIG_VIRGL
 
@@ -127,7 +128,7 @@ static void virgl_cmd_resource_flush(VirtIOGPU *g,
     trace_virtio_gpu_cmd_res_flush(rf.resource_id,
                                    rf.r.width, rf.r.height, rf.r.x, rf.r.y);
 
-    for (i = 0; i < VIRTIO_GPU_MAX_SCANOUT; i++) {
+    for (i = 0; i < g->conf.max_outputs; i++) {
         if (g->scanout[i].resource_id != rf.resource_id) {
             continue;
         }
@@ -146,7 +147,7 @@ static void virgl_cmd_set_scanout(VirtIOGPU *g,
     trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id,
                                      ss.r.width, ss.r.height, ss.r.x, ss.r.y);
 
-    if (ss.scanout_id >= VIRTIO_GPU_MAX_SCANOUT) {
+    if (ss.scanout_id >= g->conf.max_outputs) {
         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",
                       __func__, ss.scanout_id);
         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 91345bd399..f3b0f1419e 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -20,6 +20,7 @@
 #include "hw/virtio/virtio-gpu.h"
 #include "hw/virtio/virtio-bus.h"
 #include "qemu/log.h"
+#include "qapi/error.h"
 
 static struct virtio_gpu_simple_resource*
 virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id);
@@ -465,7 +466,7 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
 
     pixman_region_init_rect(&flush_region,
                             rf.r.x, rf.r.y, rf.r.width, rf.r.height);
-    for (i = 0; i < VIRTIO_GPU_MAX_SCANOUT; i++) {
+    for (i = 0; i < g->conf.max_outputs; i++) {
         struct virtio_gpu_scanout *scanout;
         pixman_region16_t region, finalregion;
         pixman_box16_t *extents;
@@ -508,6 +509,13 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
     trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id,
                                      ss.r.width, ss.r.height, ss.r.x, ss.r.y);
 
+    if (ss.scanout_id >= g->conf.max_outputs) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",
+                      __func__, ss.scanout_id);
+        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
+        return;
+    }
+
     g->enable = 1;
     if (ss.resource_id == 0) {
         scanout = &g->scanout[ss.scanout_id];
@@ -517,8 +525,7 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
                 res->scanout_bitmask &= ~(1 << ss.scanout_id);
             }
         }
-        if (ss.scanout_id == 0 ||
-            ss.scanout_id >= g->conf.max_outputs) {
+        if (ss.scanout_id == 0) {
             qemu_log_mask(LOG_GUEST_ERROR,
                           "%s: illegal scanout id specified %d",
                           __func__, ss.scanout_id);
@@ -533,14 +540,6 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
     }
 
     /* create a surface for this scanout */
-    if (ss.scanout_id >= VIRTIO_GPU_MAX_SCANOUT ||
-        ss.scanout_id >= g->conf.max_outputs) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",
-                      __func__, ss.scanout_id);
-        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
-        return;
-    }
-
     res = virtio_gpu_find_resource(g, ss.resource_id);
     if (!res) {
         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
@@ -880,7 +879,7 @@ static int virtio_gpu_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info)
 {
     VirtIOGPU *g = opaque;
 
-    if (idx > g->conf.max_outputs) {
+    if (idx >= g->conf.max_outputs) {
         return -1;
     }
 
@@ -930,6 +929,11 @@ static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
     bool have_virgl;
     int i;
 
+    if (g->conf.max_outputs > VIRTIO_GPU_MAX_SCANOUTS) {
+        error_setg(errp, "invalid max_outputs > %d", VIRTIO_GPU_MAX_SCANOUTS);
+        return;
+    }
+
     g->config_size = sizeof(struct virtio_gpu_config);
     g->virtio_config.num_scanouts = g->conf.max_outputs;
     virtio_init(VIRTIO_DEVICE(g), "virtio-gpu", VIRTIO_ID_GPU,
diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c
index e58b165ae5..f49f8deee7 100644
--- a/hw/display/virtio-vga.c
+++ b/hw/display/virtio-vga.c
@@ -4,6 +4,7 @@
 #include "ui/console.h"
 #include "vga_int.h"
 #include "hw/virtio/virtio-pci.h"
+#include "qapi/error.h"
 
 /*
  * virtio-vga: This extends VirtioPCIProxy.
@@ -89,6 +90,7 @@ static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
     VirtIOVGA *vvga = VIRTIO_VGA(vpci_dev);
     VirtIOGPU *g = &vvga->vdev;
     VGACommonState *vga = &vvga->vga;
+    Error *err = NULL;
     uint32_t offset;
     int i;
 
@@ -124,7 +126,11 @@ static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
     /* force virtio-1.0 */
     vpci_dev->flags &= ~VIRTIO_PCI_FLAG_DISABLE_MODERN;
     vpci_dev->flags |= VIRTIO_PCI_FLAG_DISABLE_LEGACY;
-    object_property_set_bool(OBJECT(g), true, "realized", errp);
+    object_property_set_bool(OBJECT(g), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
 
     /* add stdvga mmio regions */
     pci_std_vga_mmio_region_init(vga, &vpci_dev->modern_bar,
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 8fd27ba2f4..5b71b1ba46 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -397,7 +397,7 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
     CPUX86State *env = &cpu->env;
     VAPICHandlers *handlers;
     uint8_t opcode[2];
-    uint32_t imm32;
+    uint32_t imm32 = 0;
     target_ulong current_pc = 0;
     target_ulong current_cs_base = 0;
     uint32_t current_flags = 0;
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 99437e0b78..e29ccc8341 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -67,6 +67,7 @@
 #include "qapi/visitor.h"
 #include "qapi-visit.h"
 #include "qom/cpu.h"
+#include "hw/nmi.h"
 
 /* debug PC/ISA interrupts */
 //#define DEBUG_IRQ
@@ -1963,11 +1964,28 @@ static CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *machine)
     return list;
 }
 
+static void x86_nmi(NMIState *n, int cpu_index, Error **errp)
+{
+    /* cpu index isn't used */
+    CPUState *cs;
+
+    CPU_FOREACH(cs) {
+        X86CPU *cpu = X86_CPU(cs);
+
+        if (!cpu->apic_state) {
+            cpu_interrupt(cs, CPU_INTERRUPT_NMI);
+        } else {
+            apic_deliver_nmi(cpu->apic_state);
+        }
+    }
+}
+
 static void pc_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
     PCMachineClass *pcmc = PC_MACHINE_CLASS(oc);
     HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
+    NMIClass *nc = NMI_CLASS(oc);
 
     pcmc->get_hotplug_handler = mc->get_hotplug_handler;
     pcmc->pci_enabled = true;
@@ -1993,6 +2011,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
     hc->plug = pc_machine_device_plug_cb;
     hc->unplug_request = pc_machine_device_unplug_request_cb;
     hc->unplug = pc_machine_device_unplug_cb;
+    nc->nmi_monitor_handler = x86_nmi;
 }
 
 static const TypeInfo pc_machine_info = {
@@ -2005,6 +2024,7 @@ static const TypeInfo pc_machine_info = {
     .class_init = pc_machine_class_init,
     .interfaces = (InterfaceInfo[]) {
          { TYPE_HOTPLUG_HANDLER },
+         { TYPE_NMI },
          { }
     },
 };
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 7f50116bc7..32918bb294 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -582,7 +582,6 @@ DEFINE_I440FX_MACHINE(v1_4, "pc-i440fx-1.4", pc_compat_1_4,
 
 
 #define PC_COMPAT_1_3 \
-        PC_COMPAT_1_4 \
         {\
             .driver   = "usb-tablet",\
             .property = "usb_version",\
@@ -614,7 +613,6 @@ DEFINE_I440FX_MACHINE(v1_3, "pc-1.3", pc_compat_1_3,
 
 
 #define PC_COMPAT_1_2 \
-        PC_COMPAT_1_3 \
         {\
             .driver   = "nec-usb-xhci",\
             .property = "msi",\
@@ -653,7 +651,6 @@ DEFINE_I440FX_MACHINE(v1_2, "pc-1.2", pc_compat_1_2,
 
 
 #define PC_COMPAT_1_1 \
-        PC_COMPAT_1_2 \
         {\
             .driver   = "virtio-scsi-pci",\
             .property = "hotplug",\
@@ -696,7 +693,6 @@ DEFINE_I440FX_MACHINE(v1_1, "pc-1.1", pc_compat_1_2,
 
 
 #define PC_COMPAT_1_0 \
-        PC_COMPAT_1_1 \
         {\
             .driver   = TYPE_ISA_FDC,\
             .property = "check_media_rate",\
@@ -726,14 +722,10 @@ DEFINE_I440FX_MACHINE(v1_0, "pc-1.0", pc_compat_1_2,
                       pc_i440fx_1_0_machine_options);
 
 
-#define PC_COMPAT_0_15 \
-        PC_COMPAT_1_0
-
 static void pc_i440fx_0_15_machine_options(MachineClass *m)
 {
     pc_i440fx_1_0_machine_options(m);
     m->hw_version = "0.15";
-    SET_MACHINE_COMPAT(m, PC_COMPAT_0_15);
 }
 
 DEFINE_I440FX_MACHINE(v0_15, "pc-0.15", pc_compat_1_2,
@@ -741,7 +733,6 @@ DEFINE_I440FX_MACHINE(v0_15, "pc-0.15", pc_compat_1_2,
 
 
 #define PC_COMPAT_0_14 \
-        PC_COMPAT_0_15 \
         {\
             .driver   = "virtio-blk-pci",\
             .property = "event_idx",\
@@ -780,7 +771,6 @@ DEFINE_I440FX_MACHINE(v0_14, "pc-0.14", pc_compat_1_2,
 
 
 #define PC_COMPAT_0_13 \
-        PC_COMPAT_0_14 \
         {\
             .driver   = TYPE_PCI_DEVICE,\
             .property = "command_serr_enable",\
@@ -817,7 +807,6 @@ DEFINE_I440FX_MACHINE(v0_13, "pc-0.13", pc_compat_0_13,
 
 
 #define PC_COMPAT_0_12 \
-        PC_COMPAT_0_13 \
         {\
             .driver   = "virtio-serial-pci",\
             .property = "max_ports",\
@@ -852,7 +841,6 @@ DEFINE_I440FX_MACHINE(v0_12, "pc-0.12", pc_compat_0_13,
 
 
 #define PC_COMPAT_0_11 \
-        PC_COMPAT_0_12 \
         {\
             .driver   = "virtio-blk-pci",\
             .property = "vectors",\
@@ -883,7 +871,6 @@ DEFINE_I440FX_MACHINE(v0_11, "pc-0.11", pc_compat_0_13,
 
 
 #define PC_COMPAT_0_10 \
-    PC_COMPAT_0_11 \
     {\
         .driver   = "virtio-blk-pci",\
         .property = "class",\
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index 4f42b911a2..273bb0854c 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -255,6 +255,34 @@ ioapic_mem_read(void *opaque, hwaddr addr, unsigned int size)
     return val;
 }
 
+/*
+ * This is to satisfy the hack in Linux kernel. One hack of it is to
+ * simulate clearing the Remote IRR bit of IOAPIC entry using the
+ * following:
+ *
+ * "For IO-APIC's with EOI register, we use that to do an explicit EOI.
+ * Otherwise, we simulate the EOI message manually by changing the trigger
+ * mode to edge and then back to level, with RTE being masked during
+ * this."
+ *
+ * (See linux kernel __eoi_ioapic_pin() comment in commit c0205701)
+ *
+ * This is based on the assumption that, Remote IRR bit will be
+ * cleared by IOAPIC hardware when configured as edge-triggered
+ * interrupts.
+ *
+ * Without this, level-triggered interrupts in IR mode might fail to
+ * work correctly.
+ */
+static inline void
+ioapic_fix_edge_remote_irr(uint64_t *entry)
+{
+    if (!(*entry & IOAPIC_LVT_TRIGGER_MODE)) {
+        /* Edge-triggered interrupts, make sure remote IRR is zero */
+        *entry &= ~((uint64_t)IOAPIC_LVT_REMOTE_IRR);
+    }
+}
+
 static void
 ioapic_mem_write(void *opaque, hwaddr addr, uint64_t val,
                  unsigned int size)
@@ -281,6 +309,7 @@ ioapic_mem_write(void *opaque, hwaddr addr, uint64_t val,
         default:
             index = (s->ioregsel - IOAPIC_REG_REDTBL_BASE) >> 1;
             if (index >= 0 && index < IOAPIC_NUM_PINS) {
+                uint64_t ro_bits = s->ioredtbl[index] & IOAPIC_RO_BITS;
                 if (s->ioregsel & 1) {
                     s->ioredtbl[index] &= 0xffffffff;
                     s->ioredtbl[index] |= (uint64_t)val << 32;
@@ -288,6 +317,10 @@ ioapic_mem_write(void *opaque, hwaddr addr, uint64_t val,
                     s->ioredtbl[index] &= ~0xffffffffULL;
                     s->ioredtbl[index] |= val;
                 }
+                /* restore RO bits */
+                s->ioredtbl[index] &= IOAPIC_RW_BITS;
+                s->ioredtbl[index] |= ro_bits;
+                ioapic_fix_edge_remote_irr(&s->ioredtbl[index]);
                 ioapic_service(s);
             }
         }
diff --git a/hw/lm32/milkymist-hw.h b/hw/lm32/milkymist-hw.h
index c8dfb4d2d4..f857d2846f 100644
--- a/hw/lm32/milkymist-hw.h
+++ b/hw/lm32/milkymist-hw.h
@@ -108,10 +108,6 @@ static inline DeviceState *milkymist_tmu2_create(hwaddr base,
     int nelements;
     int ver_major, ver_minor;
 
-    if (display_type == DT_NOGRAPHIC) {
-        return NULL;
-    }
-
     /* check that GLX will work */
     d = XOpenDisplay(NULL);
     if (d == NULL) {
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index 96e6f4dc2e..1abdf6e2e6 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -167,7 +167,9 @@ milkymist_init(MachineState *machine)
     milkymist_memcard_create(0x60004000);
     milkymist_ac97_create(0x60005000, irq[4], irq[5], irq[6], irq[7]);
     milkymist_pfpu_create(0x60006000, irq[8]);
-    milkymist_tmu2_create(0x60007000, irq[9]);
+    if (machine->enable_graphics) {
+        milkymist_tmu2_create(0x60007000, irq[9]);
+    }
     milkymist_minimac2_create(0x60008000, 0x30000000, irq[10], irq[11]);
     milkymist_softusb_create(0x6000f000, irq[15],
             0x20000000, 0x1000, 0x20020000, 0x2000);
diff --git a/hw/net/opencores_eth.c b/hw/net/opencores_eth.c
index c6094fbb56..484d113eb6 100644
--- a/hw/net/opencores_eth.c
+++ b/hw/net/opencores_eth.c
@@ -33,6 +33,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/hw.h"
+#include "hw/net/mii.h"
 #include "hw/sysbus.h"
 #include "net/net.h"
 #include "sysemu/sysemu.h"
@@ -55,12 +56,6 @@
 
 /* PHY MII registers */
 enum {
-    MII_BMCR,
-    MII_BMSR,
-    MII_PHYIDR1,
-    MII_PHYIDR2,
-    MII_ANAR,
-    MII_ANLPAR,
     MII_REG_MAX = 16,
 };
 
@@ -72,10 +67,11 @@ typedef struct Mii {
 static void mii_set_link(Mii *s, bool link_ok)
 {
     if (link_ok) {
-        s->regs[MII_BMSR] |= 0x4;
-        s->regs[MII_ANLPAR] |= 0x01e1;
+        s->regs[MII_BMSR] |= MII_BMSR_LINK_ST;
+        s->regs[MII_ANLPAR] |= MII_ANLPAR_TXFD | MII_ANLPAR_TX |
+            MII_ANLPAR_10FD | MII_ANLPAR_10 | MII_ANLPAR_CSMACD;
     } else {
-        s->regs[MII_BMSR] &= ~0x4;
+        s->regs[MII_BMSR] &= ~MII_BMSR_LINK_ST;
         s->regs[MII_ANLPAR] &= 0x01ff;
     }
     s->link_ok = link_ok;
@@ -84,11 +80,14 @@ static void mii_set_link(Mii *s, bool link_ok)
 static void mii_reset(Mii *s)
 {
     memset(s->regs, 0, sizeof(s->regs));
-    s->regs[MII_BMCR] = 0x1000;
-    s->regs[MII_BMSR] = 0x7868; /* no ext regs */
-    s->regs[MII_PHYIDR1] = 0x2000;
-    s->regs[MII_PHYIDR2] = 0x5c90;
-    s->regs[MII_ANAR] = 0x01e1;
+    s->regs[MII_BMCR] = MII_BMCR_AUTOEN;
+    s->regs[MII_BMSR] = MII_BMSR_100TX_FD | MII_BMSR_100TX_HD |
+        MII_BMSR_10T_FD | MII_BMSR_10T_HD | MII_BMSR_MFPS |
+        MII_BMSR_AN_COMP | MII_BMSR_AUTONEG;
+    s->regs[MII_PHYID1] = 0x2000;
+    s->regs[MII_PHYID2] = 0x5c90;
+    s->regs[MII_ANAR] = MII_ANAR_TXFD | MII_ANAR_TX |
+        MII_ANAR_10FD | MII_ANAR_10 | MII_ANAR_CSMACD;
     mii_set_link(s, s->link_ok);
 }
 
@@ -98,7 +97,7 @@ static void mii_ro(Mii *s, uint16_t v)
 
 static void mii_write_bmcr(Mii *s, uint16_t v)
 {
-    if (v & 0x8000) {
+    if (v & MII_BMCR_RESET) {
         mii_reset(s);
     } else {
         s->regs[MII_BMCR] = v;
@@ -110,8 +109,8 @@ static void mii_write_host(Mii *s, unsigned idx, uint16_t v)
     static void (*reg_write[MII_REG_MAX])(Mii *s, uint16_t v) = {
         [MII_BMCR] = mii_write_bmcr,
         [MII_BMSR] = mii_ro,
-        [MII_PHYIDR1] = mii_ro,
-        [MII_PHYIDR2] = mii_ro,
+        [MII_PHYID1] = mii_ro,
+        [MII_PHYID2] = mii_ro,
     };
 
     if (idx < MII_REG_MAX) {
@@ -483,7 +482,8 @@ static NetClientInfo net_open_eth_info = {
 
 static void open_eth_start_xmit(OpenEthState *s, desc *tx)
 {
-    uint8_t buf[65536];
+    uint8_t *buf = NULL;
+    uint8_t buffer[0x600];
     unsigned len = GET_FIELD(tx->len_flags, TXD_LEN);
     unsigned tx_len = len;
 
@@ -498,6 +498,11 @@ static void open_eth_start_xmit(OpenEthState *s, desc *tx)
 
     trace_open_eth_start_xmit(tx->buf_ptr, len, tx_len);
 
+    if (tx_len > sizeof(buffer)) {
+        buf = g_new(uint8_t, tx_len);
+    } else {
+        buf = buffer;
+    }
     if (len > tx_len) {
         len = tx_len;
     }
@@ -506,6 +511,9 @@ static void open_eth_start_xmit(OpenEthState *s, desc *tx)
         memset(buf + len, 0, tx_len - len);
     }
     qemu_send_packet(qemu_get_queue(s->nic), buf, tx_len);
+    if (tx_len > sizeof(buffer)) {
+        g_free(buf);
+    }
 
     if (tx->len_flags & TXD_WR) {
         s->tx_desc = 0;
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 999f480280..cdbdfb5320 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -25,6 +25,7 @@
 #include "hw/hw.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/dma.h"
+#include "hw/boards.h"
 #include "hw/isa/isa.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/sysbus.h"
@@ -868,16 +869,17 @@ static void fw_cfg_machine_ready(struct Notifier *n, void *data)
 static void fw_cfg_init1(DeviceState *dev)
 {
     FWCfgState *s = FW_CFG(dev);
+    MachineState *machine = MACHINE(qdev_get_machine());
 
     assert(!object_resolve_path(FW_CFG_PATH, NULL));
 
-    object_property_add_child(qdev_get_machine(), FW_CFG_NAME, OBJECT(s), NULL);
+    object_property_add_child(OBJECT(machine), FW_CFG_NAME, OBJECT(s), NULL);
 
     qdev_init_nofail(dev);
 
     fw_cfg_add_bytes(s, FW_CFG_SIGNATURE, (char *)"QEMU", 4);
     fw_cfg_add_bytes(s, FW_CFG_UUID, qemu_uuid, 16);
-    fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)(display_type == DT_NOGRAPHIC));
+    fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)!machine->enable_graphics);
     fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
     fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu);
     fw_cfg_bootsplash(s);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index de1de1d067..add68acfef 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2387,7 +2387,6 @@ DEFINE_SPAPR_MACHINE(2_5, "2.5", false);
  * pseries-2.4
  */
 #define SPAPR_COMPAT_2_4 \
-        SPAPR_COMPAT_2_5 \
         HW_COMPAT_2_4
 
 static void spapr_machine_2_4_instance_options(MachineState *machine)
@@ -2410,7 +2409,6 @@ DEFINE_SPAPR_MACHINE(2_4, "2.4", false);
  * pseries-2.3
  */
 #define SPAPR_COMPAT_2_3 \
-        SPAPR_COMPAT_2_4 \
         HW_COMPAT_2_3 \
         {\
             .driver   = "spapr-pci-host-bridge",\
@@ -2438,7 +2436,6 @@ DEFINE_SPAPR_MACHINE(2_3, "2.3", false);
  */
 
 #define SPAPR_COMPAT_2_2 \
-        SPAPR_COMPAT_2_3 \
         HW_COMPAT_2_2 \
         {\
             .driver   = TYPE_SPAPR_PCI_HOST_BRIDGE,\
@@ -2463,7 +2460,6 @@ DEFINE_SPAPR_MACHINE(2_2, "2.2", false);
  * pseries-2.1
  */
 #define SPAPR_COMPAT_2_1 \
-        SPAPR_COMPAT_2_2 \
         HW_COMPAT_2_1
 
 static void spapr_machine_2_1_instance_options(MachineState *machine)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 18bbbfbbe2..95ff5e35ae 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -330,7 +330,6 @@ static const TypeInfo ccw_machine_info = {
         HW_COMPAT_2_5
 
 #define CCW_COMPAT_2_4 \
-        CCW_COMPAT_2_5 \
         HW_COMPAT_2_4 \
         {\
             .driver   = TYPE_S390_SKEYS,\
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 8961be2f34..591c8172d5 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -82,7 +82,7 @@ void esp_request_cancelled(SCSIRequest *req)
     }
 }
 
-static uint32_t get_cmd(ESPState *s, uint8_t *buf)
+static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
 {
     uint32_t dmalen;
     int target;
@@ -92,6 +92,9 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
         dmalen = s->rregs[ESP_TCLO];
         dmalen |= s->rregs[ESP_TCMID] << 8;
         dmalen |= s->rregs[ESP_TCHI] << 16;
+        if (dmalen > buflen) {
+            return 0;
+        }
         s->dma_memory_read(s->dma_opaque, buf, dmalen);
     } else {
         dmalen = s->ti_size;
@@ -166,7 +169,7 @@ static void handle_satn(ESPState *s)
         s->dma_cb = handle_satn;
         return;
     }
-    len = get_cmd(s, buf);
+    len = get_cmd(s, buf, sizeof(buf));
     if (len)
         do_cmd(s, buf);
 }
@@ -180,7 +183,7 @@ static void handle_s_without_atn(ESPState *s)
         s->dma_cb = handle_s_without_atn;
         return;
     }
-    len = get_cmd(s, buf);
+    len = get_cmd(s, buf, sizeof(buf));
     if (len) {
         do_busid_cmd(s, buf, 0);
     }
@@ -192,7 +195,7 @@ static void handle_satn_stop(ESPState *s)
         s->dma_cb = handle_satn_stop;
         return;
     }
-    s->cmdlen = get_cmd(s, s->cmdbuf);
+    s->cmdlen = get_cmd(s, s->cmdbuf, sizeof(s->cmdbuf));
     if (s->cmdlen) {
         trace_esp_handle_satn_stop(s->cmdlen);
         s->do_cmd = 1;
@@ -448,7 +451,11 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
         break;
     case ESP_FIFO:
         if (s->do_cmd) {
-            s->cmdbuf[s->cmdlen++] = val & 0xff;
+            if (s->cmdlen < TI_BUFSZ) {
+                s->cmdbuf[s->cmdlen++] = val & 0xff;
+            } else {
+                trace_esp_error_fifo_overrun();
+            }
         } else if (s->ti_size == TI_BUFSZ - 1) {
             trace_esp_error_fifo_overrun();
         } else {
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 7bfc00abc2..478fda8209 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -1000,7 +1000,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
     slavio_timer_init_all(hwdef->counter_base, slavio_irq[19], slavio_cpu_irq, smp_cpus);
 
     slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[14],
-                              display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
+                              !machine->enable_graphics, ESCC_CLOCK, 1);
     /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device
        Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */
     escc_init(hwdef->serial_base, slavio_irq[15], slavio_irq[15],
diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
index 2717027d34..98b5c9d273 100644
--- a/hw/usb/Makefile.objs
+++ b/hw/usb/Makefile.objs
@@ -38,3 +38,7 @@ common-obj-$(CONFIG_USB_REDIR) += redirect.o quirks.o
 
 # usb pass-through
 common-obj-y += $(patsubst %,host-%.o,$(HOST_USB))
+
+ifeq ($(CONFIG_USB_LIBUSB),y)
+common-obj-$(CONFIG_XEN_BACKEND) += xen-usb.o
+endif
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index ffab561cf6..16d9ff7b4b 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1848,6 +1848,12 @@ static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
 
     ohci->as = as;
 
+    if (num_ports > OHCI_MAX_PORTS) {
+        error_setg(errp, "OHCI num-ports=%d is too big (limit is %d ports)",
+                   num_ports, OHCI_MAX_PORTS);
+        return;
+    }
+
     if (usb_frame_time == 0) {
 #ifdef OHCI_TIME_WARP
         usb_frame_time = NANOSECONDS_PER_SECOND;
diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c
new file mode 100644
index 0000000000..664df04181
--- /dev/null
+++ b/hw/usb/xen-usb.c
@@ -0,0 +1,1080 @@
+/*
+ *  xen paravirt usb device backend
+ *
+ *  (c) Juergen Gross <jgross@suse.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; under version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ *  Contributions after 2012-01-13 are licensed under the terms of the
+ *  GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#include <libusb.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/config-file.h"
+#include "hw/sysbus.h"
+#include "hw/usb.h"
+#include "hw/xen/xen_backend.h"
+#include "monitor/qdev.h"
+#include "qapi/qmp/qbool.h"
+#include "qapi/qmp/qint.h"
+#include "qapi/qmp/qstring.h"
+#include "sys/user.h"
+
+#include <xen/io/ring.h>
+#include <xen/io/usbif.h>
+
+/*
+ * Check for required support of usbif.h: USBIF_SHORT_NOT_OK was the last
+ * macro added we rely on.
+ */
+#ifdef USBIF_SHORT_NOT_OK
+
+#define TR(xendev, lvl, fmt, args...)                               \
+    {                                                               \
+        struct timeval tv;                                          \
+                                                                    \
+        gettimeofday(&tv, NULL);                                    \
+        xen_be_printf(xendev, lvl, "%8ld.%06ld xen-usb(%s):" fmt,   \
+                      tv.tv_sec, tv.tv_usec, __func__, ##args);     \
+    }
+#define TR_BUS(xendev, fmt, args...) TR(xendev, 2, fmt, ##args)
+#define TR_REQ(xendev, fmt, args...) TR(xendev, 3, fmt, ##args)
+
+#define USBBACK_MAXPORTS        USBIF_PIPE_PORT_MASK
+#define USB_DEV_ADDR_SIZE       (USBIF_PIPE_DEV_MASK + 1)
+
+/* USB wire protocol: structure describing control request parameter. */
+struct usbif_ctrlrequest {
+    uint8_t    bRequestType;
+    uint8_t    bRequest;
+    uint16_t   wValue;
+    uint16_t   wIndex;
+    uint16_t   wLength;
+};
+
+struct usbback_info;
+struct usbback_req;
+
+struct usbback_stub {
+    USBDevice     *dev;
+    USBPort       port;
+    unsigned int  speed;
+    bool          attached;
+    QTAILQ_HEAD(submit_q_head, usbback_req) submit_q;
+};
+
+struct usbback_req {
+    struct usbback_info      *usbif;
+    struct usbback_stub      *stub;
+    struct usbif_urb_request req;
+    USBPacket                packet;
+
+    unsigned int             nr_buffer_segs; /* # of transfer_buffer segments */
+    unsigned int             nr_extra_segs;  /* # of iso_frame_desc segments  */
+
+    QTAILQ_ENTRY(usbback_req) q;
+
+    void                     *buffer;
+    void                     *isoc_buffer;
+    struct libusb_transfer   *xfer;
+};
+
+struct usbback_hotplug {
+    QSIMPLEQ_ENTRY(usbback_hotplug) q;
+    unsigned                 port;
+};
+
+struct usbback_info {
+    struct XenDevice         xendev;  /* must be first */
+    USBBus                   bus;
+    void                     *urb_sring;
+    void                     *conn_sring;
+    struct usbif_urb_back_ring urb_ring;
+    struct usbif_conn_back_ring conn_ring;
+    int                      num_ports;
+    int                      usb_ver;
+    bool                     ring_error;
+    QTAILQ_HEAD(req_free_q_head, usbback_req) req_free_q;
+    QSIMPLEQ_HEAD(hotplug_q_head, usbback_hotplug) hotplug_q;
+    struct usbback_stub      ports[USBBACK_MAXPORTS];
+    struct usbback_stub      *addr_table[USB_DEV_ADDR_SIZE];
+    QEMUBH                   *bh;
+};
+
+static struct usbback_req *usbback_get_req(struct usbback_info *usbif)
+{
+    struct usbback_req *usbback_req;
+
+    if (QTAILQ_EMPTY(&usbif->req_free_q)) {
+        usbback_req = g_new0(struct usbback_req, 1);
+    } else {
+        usbback_req = QTAILQ_FIRST(&usbif->req_free_q);
+        QTAILQ_REMOVE(&usbif->req_free_q, usbback_req, q);
+    }
+    return usbback_req;
+}
+
+static void usbback_put_req(struct usbback_req *usbback_req)
+{
+    struct usbback_info *usbif;
+
+    usbif = usbback_req->usbif;
+    memset(usbback_req, 0, sizeof(*usbback_req));
+    QTAILQ_INSERT_HEAD(&usbif->req_free_q, usbback_req, q);
+}
+
+static int usbback_gnttab_map(struct usbback_req *usbback_req)
+{
+    unsigned int nr_segs, i, prot;
+    uint32_t ref[USBIF_MAX_SEGMENTS_PER_REQUEST];
+    struct usbback_info *usbif = usbback_req->usbif;
+    struct XenDevice *xendev = &usbif->xendev;
+    struct usbif_request_segment *seg;
+    void *addr;
+
+    nr_segs = usbback_req->nr_buffer_segs + usbback_req->nr_extra_segs;
+    if (!nr_segs) {
+        return 0;
+    }
+
+    if (nr_segs > USBIF_MAX_SEGMENTS_PER_REQUEST) {
+        xen_be_printf(xendev, 0, "bad number of segments in request (%d)\n",
+                      nr_segs);
+        return -EINVAL;
+    }
+
+    for (i = 0; i < nr_segs; i++) {
+        if ((unsigned)usbback_req->req.seg[i].offset +
+            (unsigned)usbback_req->req.seg[i].length > PAGE_SIZE) {
+            xen_be_printf(xendev, 0, "segment crosses page boundary\n");
+            return -EINVAL;
+        }
+    }
+
+    if (usbback_req->nr_buffer_segs) {
+        prot = PROT_READ;
+        if (usbif_pipein(usbback_req->req.pipe)) {
+                prot |= PROT_WRITE;
+        }
+        for (i = 0; i < usbback_req->nr_buffer_segs; i++) {
+            ref[i] = usbback_req->req.seg[i].gref;
+        }
+        usbback_req->buffer = xengnttab_map_domain_grant_refs(xendev->gnttabdev,
+            usbback_req->nr_buffer_segs, xendev->dom, ref, prot);
+
+        if (!usbback_req->buffer) {
+            return -ENOMEM;
+        }
+
+        for (i = 0; i < usbback_req->nr_buffer_segs; i++) {
+            seg = usbback_req->req.seg + i;
+            addr = usbback_req->buffer + i * PAGE_SIZE + seg->offset;
+            qemu_iovec_add(&usbback_req->packet.iov, addr, seg->length);
+        }
+    }
+
+    if (!usbif_pipeisoc(usbback_req->req.pipe)) {
+        return 0;
+    }
+
+    /*
+     * Right now isoc requests are not supported.
+     * Prepare supporting those by doing the work needed on the guest
+     * interface side.
+     */
+
+    if (!usbback_req->nr_extra_segs) {
+        xen_be_printf(xendev, 0, "iso request without descriptor segments\n");
+        return -EINVAL;
+    }
+
+    prot = PROT_READ | PROT_WRITE;
+    for (i = 0; i < usbback_req->nr_extra_segs; i++) {
+        ref[i] = usbback_req->req.seg[i + usbback_req->req.nr_buffer_segs].gref;
+    }
+    usbback_req->isoc_buffer = xengnttab_map_domain_grant_refs(
+         xendev->gnttabdev, usbback_req->nr_extra_segs, xendev->dom, ref, prot);
+
+    if (!usbback_req->isoc_buffer) {
+        return -ENOMEM;
+    }
+
+    return 0;
+}
+
+static int usbback_init_packet(struct usbback_req *usbback_req)
+{
+    struct XenDevice *xendev = &usbback_req->usbif->xendev;
+    USBPacket *packet = &usbback_req->packet;
+    USBDevice *dev = usbback_req->stub->dev;
+    USBEndpoint *ep;
+    unsigned int pid, ep_nr;
+    bool sok;
+    int ret = 0;
+
+    qemu_iovec_init(&packet->iov, USBIF_MAX_SEGMENTS_PER_REQUEST);
+    pid = usbif_pipein(usbback_req->req.pipe) ? USB_TOKEN_IN : USB_TOKEN_OUT;
+    ep_nr = usbif_pipeendpoint(usbback_req->req.pipe);
+    sok = !!(usbback_req->req.transfer_flags & USBIF_SHORT_NOT_OK);
+    if (usbif_pipectrl(usbback_req->req.pipe)) {
+        ep_nr = 0;
+        sok = false;
+    }
+    ep = usb_ep_get(dev, pid, ep_nr);
+    usb_packet_setup(packet, pid, ep, 0, 1, sok, true);
+
+    switch (usbif_pipetype(usbback_req->req.pipe)) {
+    case USBIF_PIPE_TYPE_ISOC:
+        TR_REQ(xendev, "iso transfer %s: buflen: %x, %d frames\n",
+               (pid == USB_TOKEN_IN) ? "in" : "out",
+               usbback_req->req.buffer_length,
+               usbback_req->req.u.isoc.nr_frame_desc_segs);
+        ret = -EINVAL;  /* isoc not implemented yet */
+        break;
+
+    case USBIF_PIPE_TYPE_INT:
+        TR_REQ(xendev, "int transfer %s: buflen: %x\n",
+               (pid == USB_TOKEN_IN) ? "in" : "out",
+               usbback_req->req.buffer_length);
+        break;
+
+    case USBIF_PIPE_TYPE_CTRL:
+        packet->parameter = *(uint64_t *)usbback_req->req.u.ctrl;
+        TR_REQ(xendev, "ctrl parameter: %lx, buflen: %x\n", packet->parameter,
+               usbback_req->req.buffer_length);
+        break;
+
+    case USBIF_PIPE_TYPE_BULK:
+        TR_REQ(xendev, "bulk transfer %s: buflen: %x\n",
+               (pid == USB_TOKEN_IN) ? "in" : "out",
+               usbback_req->req.buffer_length);
+        break;
+    default:
+        ret = -EINVAL;
+        break;
+    }
+
+    return ret;
+}
+
+static void usbback_do_response(struct usbback_req *usbback_req, int32_t status,
+                                int32_t actual_length, int32_t error_count)
+{
+    struct usbback_info *usbif;
+    struct usbif_urb_response *res;
+    struct XenDevice *xendev;
+    unsigned int notify;
+
+    usbif = usbback_req->usbif;
+    xendev = &usbif->xendev;
+
+    TR_REQ(xendev, "id %d, status %d, length %d, errcnt %d\n",
+           usbback_req->req.id, status, actual_length, error_count);
+
+    if (usbback_req->packet.iov.iov) {
+        qemu_iovec_destroy(&usbback_req->packet.iov);
+    }
+
+    if (usbback_req->buffer) {
+        xengnttab_unmap(xendev->gnttabdev, usbback_req->buffer,
+                        usbback_req->nr_buffer_segs);
+        usbback_req->buffer = NULL;
+    }
+
+    if (usbback_req->isoc_buffer) {
+        xengnttab_unmap(xendev->gnttabdev, usbback_req->isoc_buffer,
+                        usbback_req->nr_extra_segs);
+        usbback_req->isoc_buffer = NULL;
+    }
+
+    res = RING_GET_RESPONSE(&usbif->urb_ring, usbif->urb_ring.rsp_prod_pvt);
+    res->id = usbback_req->req.id;
+    res->status = status;
+    res->actual_length = actual_length;
+    res->error_count = error_count;
+    res->start_frame = 0;
+    usbif->urb_ring.rsp_prod_pvt++;
+    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&usbif->urb_ring, notify);
+
+    if (notify) {
+        xen_be_send_notify(xendev);
+    }
+
+    usbback_put_req(usbback_req);
+}
+
+static void usbback_do_response_ret(struct usbback_req *usbback_req,
+                                    int32_t status)
+{
+    usbback_do_response(usbback_req, status, 0, 0);
+}
+
+static int32_t usbback_xlat_status(int status)
+{
+    switch (status) {
+    case USB_RET_SUCCESS:
+        return 0;
+    case USB_RET_NODEV:
+        return -ENODEV;
+    case USB_RET_STALL:
+        return -EPIPE;
+    case USB_RET_BABBLE:
+        return -EOVERFLOW;
+    case USB_RET_IOERROR:
+        return -EPROTO;
+    }
+
+    return -ESHUTDOWN;
+}
+
+static void usbback_packet_complete(USBPacket *packet)
+{
+    struct usbback_req *usbback_req;
+    int32_t status;
+
+    usbback_req = container_of(packet, struct usbback_req, packet);
+
+    QTAILQ_REMOVE(&usbback_req->stub->submit_q, usbback_req, q);
+
+    status = usbback_xlat_status(packet->status);
+    usbback_do_response(usbback_req, status, packet->actual_length, 0);
+}
+
+static void usbback_set_address(struct usbback_info *usbif,
+                                struct usbback_stub *stub,
+                                unsigned int cur_addr, unsigned int new_addr)
+{
+    if (cur_addr) {
+        usbif->addr_table[cur_addr] = NULL;
+    }
+    if (new_addr) {
+        usbif->addr_table[new_addr] = stub;
+    }
+}
+
+static bool usbback_cancel_req(struct usbback_req *usbback_req)
+{
+    bool ret = false;
+
+    if (usb_packet_is_inflight(&usbback_req->packet)) {
+        usb_cancel_packet(&usbback_req->packet);
+        ret = true;
+    }
+    return ret;
+}
+
+static void usbback_process_unlink_req(struct usbback_req *usbback_req)
+{
+    struct usbback_info *usbif;
+    struct usbback_req *unlink_req;
+    unsigned int id, devnum;
+    int ret;
+
+    usbif = usbback_req->usbif;
+    ret = 0;
+    id = usbback_req->req.u.unlink.unlink_id;
+    TR_REQ(&usbif->xendev, "unlink id %d\n", id);
+    devnum = usbif_pipedevice(usbback_req->req.pipe);
+    if (unlikely(devnum == 0)) {
+        usbback_req->stub = usbif->ports +
+                            usbif_pipeportnum(usbback_req->req.pipe);
+        if (unlikely(!usbback_req->stub)) {
+            ret = -ENODEV;
+            goto fail_response;
+        }
+    } else {
+        if (unlikely(!usbif->addr_table[devnum])) {
+            ret = -ENODEV;
+            goto fail_response;
+        }
+        usbback_req->stub = usbif->addr_table[devnum];
+    }
+
+    QTAILQ_FOREACH(unlink_req, &usbback_req->stub->submit_q, q) {
+        if (unlink_req->req.id == id) {
+            if (usbback_cancel_req(unlink_req)) {
+                usbback_do_response_ret(unlink_req, -EPROTO);
+            }
+            break;
+        }
+    }
+
+fail_response:
+    usbback_do_response_ret(usbback_req, ret);
+}
+
+/*
+ * Checks whether a request can be handled at once or should be forwarded
+ * to the usb framework.
+ * Return value is:
+ * 0 in case of usb framework is needed
+ * 1 in case of local handling (no error)
+ * The request response has been queued already if return value not 0.
+ */
+static int usbback_check_and_submit(struct usbback_req *usbback_req)
+{
+    struct usbback_info *usbif;
+    unsigned int devnum;
+    struct usbback_stub *stub;
+    struct usbif_ctrlrequest *ctrl;
+    int ret;
+    uint16_t wValue;
+
+    usbif = usbback_req->usbif;
+    stub = NULL;
+    devnum = usbif_pipedevice(usbback_req->req.pipe);
+    ctrl = (struct usbif_ctrlrequest *)usbback_req->req.u.ctrl;
+    wValue = le16_to_cpu(ctrl->wValue);
+
+    /*
+     * When the device is first connected or resetted, USB device has no
+     * address. In this initial state, following requests are sent to device
+     * address (#0),
+     *
+     *  1. GET_DESCRIPTOR (with Descriptor Type is "DEVICE") is sent,
+     *     and OS knows what device is connected to.
+     *
+     *  2. SET_ADDRESS is sent, and then device has its address.
+     *
+     * In the next step, SET_CONFIGURATION is sent to addressed device, and
+     * then the device is finally ready to use.
+     */
+    if (unlikely(devnum == 0)) {
+        stub = usbif->ports + usbif_pipeportnum(usbback_req->req.pipe) - 1;
+        if (!stub->dev || !stub->attached) {
+            ret = -ENODEV;
+            goto do_response;
+        }
+
+        switch (ctrl->bRequest) {
+        case USB_REQ_GET_DESCRIPTOR:
+            /*
+             * GET_DESCRIPTOR request to device #0.
+             * through normal transfer.
+             */
+            TR_REQ(&usbif->xendev, "devnum 0 GET_DESCRIPTOR\n");
+            usbback_req->stub = stub;
+            return 0;
+        case USB_REQ_SET_ADDRESS:
+            /*
+             * SET_ADDRESS request to device #0.
+             * add attached device to addr_table.
+             */
+            TR_REQ(&usbif->xendev, "devnum 0 SET_ADDRESS\n");
+            usbback_set_address(usbif, stub, 0, wValue);
+            ret = 0;
+            break;
+        default:
+            ret = -EINVAL;
+            break;
+        }
+        goto do_response;
+    }
+
+    if (unlikely(!usbif->addr_table[devnum])) {
+            ret = -ENODEV;
+            goto do_response;
+    }
+    usbback_req->stub = usbif->addr_table[devnum];
+
+    /*
+     * Check special request
+     */
+    if (ctrl->bRequest != USB_REQ_SET_ADDRESS) {
+        return 0;
+    }
+
+    /*
+     * SET_ADDRESS request to addressed device.
+     * change addr or remove from addr_table.
+     */
+    usbback_set_address(usbif, usbback_req->stub, devnum, wValue);
+    ret = 0;
+
+do_response:
+    usbback_do_response_ret(usbback_req, ret);
+    return 1;
+}
+
+static void usbback_dispatch(struct usbback_req *usbback_req)
+{
+    int ret;
+    unsigned int devnum;
+    struct usbback_info *usbif;
+
+    usbif = usbback_req->usbif;
+
+    TR_REQ(&usbif->xendev, "start req_id %d pipe %08x\n", usbback_req->req.id,
+           usbback_req->req.pipe);
+
+    /* unlink request */
+    if (unlikely(usbif_pipeunlink(usbback_req->req.pipe))) {
+        usbback_process_unlink_req(usbback_req);
+        return;
+    }
+
+    if (usbif_pipectrl(usbback_req->req.pipe)) {
+        if (usbback_check_and_submit(usbback_req)) {
+            return;
+        }
+    } else {
+        devnum = usbif_pipedevice(usbback_req->req.pipe);
+        usbback_req->stub = usbif->addr_table[devnum];
+
+        if (!usbback_req->stub || !usbback_req->stub->attached) {
+            ret = -ENODEV;
+            goto fail_response;
+        }
+    }
+
+    QTAILQ_INSERT_TAIL(&usbback_req->stub->submit_q, usbback_req, q);
+
+    usbback_req->nr_buffer_segs = usbback_req->req.nr_buffer_segs;
+    usbback_req->nr_extra_segs = usbif_pipeisoc(usbback_req->req.pipe) ?
+                                 usbback_req->req.u.isoc.nr_frame_desc_segs : 0;
+
+    ret = usbback_init_packet(usbback_req);
+    if (ret) {
+        xen_be_printf(&usbif->xendev, 0, "invalid request\n");
+        ret = -ESHUTDOWN;
+        goto fail_free_urb;
+    }
+
+    ret = usbback_gnttab_map(usbback_req);
+    if (ret) {
+        xen_be_printf(&usbif->xendev, 0, "invalid buffer, ret=%d\n", ret);
+        ret = -ESHUTDOWN;
+        goto fail_free_urb;
+    }
+
+    usb_handle_packet(usbback_req->stub->dev, &usbback_req->packet);
+    if (usbback_req->packet.status != USB_RET_ASYNC) {
+        usbback_packet_complete(&usbback_req->packet);
+    }
+    return;
+
+fail_free_urb:
+    QTAILQ_REMOVE(&usbback_req->stub->submit_q, usbback_req, q);
+
+fail_response:
+    usbback_do_response_ret(usbback_req, ret);
+}
+
+static void usbback_hotplug_notify(struct usbback_info *usbif)
+{
+    struct usbif_conn_back_ring *ring = &usbif->conn_ring;
+    struct usbif_conn_request req;
+    struct usbif_conn_response *res;
+    struct usbback_hotplug *usb_hp;
+    unsigned int notify;
+
+    if (!usbif->conn_sring) {
+        return;
+    }
+
+    /* Check for full ring. */
+    if ((RING_SIZE(ring) - ring->rsp_prod_pvt - ring->req_cons) == 0) {
+        xen_be_send_notify(&usbif->xendev);
+        return;
+    }
+
+    usb_hp = QSIMPLEQ_FIRST(&usbif->hotplug_q);
+    QSIMPLEQ_REMOVE_HEAD(&usbif->hotplug_q, q);
+
+    RING_COPY_REQUEST(ring, ring->req_cons, &req);
+    ring->req_cons++;
+    ring->sring->req_event = ring->req_cons + 1;
+
+    res = RING_GET_RESPONSE(ring, ring->rsp_prod_pvt);
+    res->id = req.id;
+    res->portnum = usb_hp->port;
+    res->speed = usbif->ports[usb_hp->port - 1].speed;
+    ring->rsp_prod_pvt++;
+    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(ring, notify);
+
+    if (notify) {
+        xen_be_send_notify(&usbif->xendev);
+    }
+
+    TR_BUS(&usbif->xendev, "hotplug port %d speed %d\n", usb_hp->port,
+           res->speed);
+
+    g_free(usb_hp);
+
+    if (!QSIMPLEQ_EMPTY(&usbif->hotplug_q)) {
+        qemu_bh_schedule(usbif->bh);
+    }
+}
+
+static void usbback_bh(void *opaque)
+{
+    struct usbback_info *usbif;
+    struct usbif_urb_back_ring *urb_ring;
+    struct usbback_req *usbback_req;
+    RING_IDX rc, rp;
+    unsigned int more_to_do;
+
+    usbif = opaque;
+    if (usbif->ring_error) {
+        return;
+    }
+
+    if (!QSIMPLEQ_EMPTY(&usbif->hotplug_q)) {
+        usbback_hotplug_notify(usbif);
+    }
+
+    urb_ring = &usbif->urb_ring;
+    rc = urb_ring->req_cons;
+    rp = urb_ring->sring->req_prod;
+    xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
+
+    if (RING_REQUEST_PROD_OVERFLOW(urb_ring, rp)) {
+        rc = urb_ring->rsp_prod_pvt;
+        xen_be_printf(&usbif->xendev, 0, "domU provided bogus ring requests "
+                      "(%#x - %#x = %u). Halting ring processing.\n",
+                      rp, rc, rp - rc);
+        usbif->ring_error = true;
+        return;
+    }
+
+    while (rc != rp) {
+        if (RING_REQUEST_CONS_OVERFLOW(urb_ring, rc)) {
+            break;
+        }
+        usbback_req = usbback_get_req(usbif);
+
+        RING_COPY_REQUEST(urb_ring, rc, &usbback_req->req);
+        usbback_req->usbif = usbif;
+
+        usbback_dispatch(usbback_req);
+
+        urb_ring->req_cons = ++rc;
+    }
+
+    RING_FINAL_CHECK_FOR_REQUESTS(urb_ring, more_to_do);
+    if (more_to_do) {
+        qemu_bh_schedule(usbif->bh);
+    }
+}
+
+static void usbback_hotplug_enq(struct usbback_info *usbif, unsigned port)
+{
+    struct usbback_hotplug *usb_hp;
+
+    usb_hp = g_new0(struct usbback_hotplug, 1);
+    usb_hp->port = port;
+    QSIMPLEQ_INSERT_TAIL(&usbif->hotplug_q, usb_hp, q);
+    usbback_hotplug_notify(usbif);
+}
+
+static void usbback_portid_remove(struct usbback_info *usbif, unsigned port)
+{
+    USBPort *p;
+
+    if (!usbif->ports[port - 1].dev) {
+        return;
+    }
+
+    p = &(usbif->ports[port - 1].port);
+    snprintf(p->path, sizeof(p->path), "%d", 99);
+
+    object_unparent(OBJECT(usbif->ports[port - 1].dev));
+    usbif->ports[port - 1].dev = NULL;
+    usbif->ports[port - 1].speed = USBIF_SPEED_NONE;
+    usbif->ports[port - 1].attached = false;
+    usbback_hotplug_enq(usbif, port);
+
+    TR_BUS(&usbif->xendev, "port %d removed\n", port);
+}
+
+static void usbback_portid_add(struct usbback_info *usbif, unsigned port,
+                               char *busid)
+{
+    unsigned speed;
+    char *portname;
+    USBPort *p;
+    Error *local_err = NULL;
+    QDict *qdict;
+    QemuOpts *opts;
+
+    if (usbif->ports[port - 1].dev) {
+        return;
+    }
+
+    portname = strchr(busid, '-');
+    if (!portname) {
+        xen_be_printf(&usbif->xendev, 0, "device %s illegal specification\n",
+                      busid);
+        return;
+    }
+    portname++;
+    p = &(usbif->ports[port - 1].port);
+    snprintf(p->path, sizeof(p->path), "%s", portname);
+
+    qdict = qdict_new();
+    qdict_put(qdict, "driver", qstring_from_str("usb-host"));
+    qdict_put(qdict, "hostbus", qint_from_int(atoi(busid)));
+    qdict_put(qdict, "hostport", qstring_from_str(portname));
+    opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
+    if (local_err) {
+        goto err;
+    }
+    usbif->ports[port - 1].dev = USB_DEVICE(qdev_device_add(opts, &local_err));
+    if (!usbif->ports[port - 1].dev) {
+        goto err;
+    }
+    QDECREF(qdict);
+    snprintf(p->path, sizeof(p->path), "%d", port);
+    speed = usbif->ports[port - 1].dev->speed;
+    switch (speed) {
+    case USB_SPEED_LOW:
+        speed = USBIF_SPEED_LOW;
+        break;
+    case USB_SPEED_FULL:
+        speed = USBIF_SPEED_FULL;
+        break;
+    case USB_SPEED_HIGH:
+        speed = (usbif->usb_ver < USB_VER_USB20) ?
+                USBIF_SPEED_NONE : USBIF_SPEED_HIGH;
+        break;
+    default:
+        speed = USBIF_SPEED_NONE;
+        break;
+    }
+    if (speed == USBIF_SPEED_NONE) {
+        xen_be_printf(&usbif->xendev, 0, "device %s wrong speed\n", busid);
+        object_unparent(OBJECT(usbif->ports[port - 1].dev));
+        usbif->ports[port - 1].dev = NULL;
+        return;
+    }
+    usb_device_reset(usbif->ports[port - 1].dev);
+    usbif->ports[port - 1].speed = speed;
+    usbif->ports[port - 1].attached = true;
+    QTAILQ_INIT(&usbif->ports[port - 1].submit_q);
+    usbback_hotplug_enq(usbif, port);
+
+    TR_BUS(&usbif->xendev, "port %d attached\n", port);
+    return;
+
+err:
+    QDECREF(qdict);
+    snprintf(p->path, sizeof(p->path), "%d", 99);
+    xen_be_printf(&usbif->xendev, 0, "device %s could not be opened\n", busid);
+}
+
+static void usbback_process_port(struct usbback_info *usbif, unsigned port)
+{
+    char node[8];
+    char *busid;
+
+    snprintf(node, sizeof(node), "port/%d", port);
+    busid = xenstore_read_be_str(&usbif->xendev, node);
+    if (busid == NULL) {
+        xen_be_printf(&usbif->xendev, 0, "xenstore_read %s failed\n", node);
+        return;
+    }
+
+    /* Remove portid, if the port is not connected.  */
+    if (strlen(busid) == 0) {
+        usbback_portid_remove(usbif, port);
+    } else {
+        usbback_portid_add(usbif, port, busid);
+    }
+
+    g_free(busid);
+}
+
+static void usbback_disconnect(struct XenDevice *xendev)
+{
+    struct usbback_info *usbif;
+    struct usbback_req *req, *tmp;
+    unsigned int i;
+
+    TR_BUS(xendev, "start\n");
+
+    usbif = container_of(xendev, struct usbback_info, xendev);
+
+    xen_be_unbind_evtchn(xendev);
+
+    if (usbif->urb_sring) {
+        xengnttab_unmap(xendev->gnttabdev, usbif->urb_sring, 1);
+        usbif->urb_sring = NULL;
+    }
+    if (usbif->conn_sring) {
+        xengnttab_unmap(xendev->gnttabdev, usbif->conn_sring, 1);
+        usbif->conn_sring = NULL;
+    }
+
+    for (i = 0; i < usbif->num_ports; i++) {
+        if (!usbif->ports[i].dev) {
+            continue;
+        }
+        QTAILQ_FOREACH_SAFE(req, &usbif->ports[i].submit_q, q, tmp) {
+            usbback_cancel_req(req);
+        }
+    }
+
+    TR_BUS(xendev, "finished\n");
+}
+
+static int usbback_connect(struct XenDevice *xendev)
+{
+    struct usbback_info *usbif;
+    struct usbif_urb_sring *urb_sring;
+    struct usbif_conn_sring *conn_sring;
+    int urb_ring_ref;
+    int conn_ring_ref;
+    unsigned int i;
+
+    TR_BUS(xendev, "start\n");
+
+    usbif = container_of(xendev, struct usbback_info, xendev);
+
+    if (xenstore_read_fe_int(xendev, "urb-ring-ref", &urb_ring_ref)) {
+        xen_be_printf(xendev, 0, "error reading urb-ring-ref\n");
+        return -1;
+    }
+    if (xenstore_read_fe_int(xendev, "conn-ring-ref", &conn_ring_ref)) {
+        xen_be_printf(xendev, 0, "error reading conn-ring-ref\n");
+        return -1;
+    }
+    if (xenstore_read_fe_int(xendev, "event-channel", &xendev->remote_port)) {
+        xen_be_printf(xendev, 0, "error reading event-channel\n");
+        return -1;
+    }
+
+    usbif->urb_sring = xengnttab_map_grant_ref(xendev->gnttabdev, xendev->dom,
+                                               urb_ring_ref,
+                                               PROT_READ | PROT_WRITE);
+    usbif->conn_sring = xengnttab_map_grant_ref(xendev->gnttabdev, xendev->dom,
+                                                conn_ring_ref,
+                                                PROT_READ | PROT_WRITE);
+    if (!usbif->urb_sring || !usbif->conn_sring) {
+        xen_be_printf(xendev, 0, "error mapping rings\n");
+        usbback_disconnect(xendev);
+        return -1;
+    }
+
+    urb_sring = usbif->urb_sring;
+    conn_sring = usbif->conn_sring;
+    BACK_RING_INIT(&usbif->urb_ring, urb_sring, XC_PAGE_SIZE);
+    BACK_RING_INIT(&usbif->conn_ring, conn_sring, XC_PAGE_SIZE);
+
+    xen_be_bind_evtchn(xendev);
+
+    xen_be_printf(xendev, 1, "urb-ring-ref %d, conn-ring-ref %d, "
+                  "remote port %d, local port %d\n", urb_ring_ref,
+                  conn_ring_ref, xendev->remote_port, xendev->local_port);
+
+    for (i = 1; i <= usbif->num_ports; i++) {
+        if (usbif->ports[i - 1].dev) {
+            usbback_hotplug_enq(usbif, i);
+        }
+    }
+
+    return 0;
+}
+
+static void usbback_backend_changed(struct XenDevice *xendev, const char *node)
+{
+    struct usbback_info *usbif;
+    unsigned int i;
+
+    TR_BUS(xendev, "path %s\n", node);
+
+    usbif = container_of(xendev, struct usbback_info, xendev);
+    for (i = 1; i <= usbif->num_ports; i++) {
+        usbback_process_port(usbif, i);
+    }
+}
+
+static int usbback_init(struct XenDevice *xendev)
+{
+    struct usbback_info *usbif;
+
+    TR_BUS(xendev, "start\n");
+
+    usbif = container_of(xendev, struct usbback_info, xendev);
+
+    if (xenstore_read_be_int(xendev, "num-ports", &usbif->num_ports) ||
+        usbif->num_ports < 1 || usbif->num_ports > USBBACK_MAXPORTS) {
+        xen_be_printf(xendev, 0, "num-ports not readable or out of bounds\n");
+        return -1;
+    }
+    if (xenstore_read_be_int(xendev, "usb-ver", &usbif->usb_ver) ||
+        (usbif->usb_ver != USB_VER_USB11 && usbif->usb_ver != USB_VER_USB20)) {
+        xen_be_printf(xendev, 0, "usb-ver not readable or out of bounds\n");
+        return -1;
+    }
+
+    usbback_backend_changed(xendev, "port");
+
+    TR_BUS(xendev, "finished\n");
+
+    return 0;
+}
+
+static void xen_bus_attach(USBPort *port)
+{
+    struct usbback_info *usbif;
+
+    usbif = port->opaque;
+    TR_BUS(&usbif->xendev, "\n");
+    usbif->ports[port->index].attached = true;
+    usbback_hotplug_enq(usbif, port->index + 1);
+}
+
+static void xen_bus_detach(USBPort *port)
+{
+    struct usbback_info *usbif;
+
+    usbif = port->opaque;
+    TR_BUS(&usbif->xendev, "\n");
+    usbif->ports[port->index].attached = false;
+    usbback_hotplug_enq(usbif, port->index + 1);
+}
+
+static void xen_bus_child_detach(USBPort *port, USBDevice *child)
+{
+    struct usbback_info *usbif;
+
+    usbif = port->opaque;
+    TR_BUS(&usbif->xendev, "\n");
+}
+
+static void xen_bus_complete(USBPort *port, USBPacket *packet)
+{
+    struct usbback_info *usbif;
+
+    usbif = port->opaque;
+    TR_REQ(&usbif->xendev, "\n");
+    usbback_packet_complete(packet);
+}
+
+static USBPortOps xen_usb_port_ops = {
+    .attach = xen_bus_attach,
+    .detach = xen_bus_detach,
+    .child_detach = xen_bus_child_detach,
+    .complete = xen_bus_complete,
+};
+
+static USBBusOps xen_usb_bus_ops = {
+};
+
+static void usbback_alloc(struct XenDevice *xendev)
+{
+    struct usbback_info *usbif;
+    USBPort *p;
+    unsigned int i, max_grants;
+
+    usbif = container_of(xendev, struct usbback_info, xendev);
+
+    usb_bus_new(&usbif->bus, sizeof(usbif->bus), &xen_usb_bus_ops, xen_sysdev);
+    for (i = 0; i < USBBACK_MAXPORTS; i++) {
+        p = &(usbif->ports[i].port);
+        usb_register_port(&usbif->bus, p, usbif, i, &xen_usb_port_ops,
+                          USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL |
+                          USB_SPEED_MASK_HIGH);
+        snprintf(p->path, sizeof(p->path), "%d", 99);
+    }
+
+    QTAILQ_INIT(&usbif->req_free_q);
+    QSIMPLEQ_INIT(&usbif->hotplug_q);
+    usbif->bh = qemu_bh_new(usbback_bh, usbif);
+
+    /* max_grants: for each request and for the rings (request and connect). */
+    max_grants = USBIF_MAX_SEGMENTS_PER_REQUEST * USB_URB_RING_SIZE + 2;
+    if (xengnttab_set_max_grants(xendev->gnttabdev, max_grants) < 0) {
+        xen_be_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n",
+                      strerror(errno));
+    }
+}
+
+static int usbback_free(struct XenDevice *xendev)
+{
+    struct usbback_info *usbif;
+    struct usbback_req *usbback_req;
+    struct usbback_hotplug *usb_hp;
+    unsigned int i;
+
+    TR_BUS(xendev, "start\n");
+
+    usbback_disconnect(xendev);
+    usbif = container_of(xendev, struct usbback_info, xendev);
+    for (i = 1; i <= usbif->num_ports; i++) {
+        usbback_portid_remove(usbif, i);
+    }
+
+    while (!QTAILQ_EMPTY(&usbif->req_free_q)) {
+        usbback_req = QTAILQ_FIRST(&usbif->req_free_q);
+        QTAILQ_REMOVE(&usbif->req_free_q, usbback_req, q);
+        g_free(usbback_req);
+    }
+    while (!QSIMPLEQ_EMPTY(&usbif->hotplug_q)) {
+        usb_hp = QSIMPLEQ_FIRST(&usbif->hotplug_q);
+        QSIMPLEQ_REMOVE_HEAD(&usbif->hotplug_q, q);
+        g_free(usb_hp);
+    }
+
+    qemu_bh_delete(usbif->bh);
+
+    for (i = 0; i < USBBACK_MAXPORTS; i++) {
+        usb_unregister_port(&usbif->bus, &(usbif->ports[i].port));
+    }
+
+    usb_bus_release(&usbif->bus);
+
+    TR_BUS(xendev, "finished\n");
+
+    return 0;
+}
+
+static void usbback_event(struct XenDevice *xendev)
+{
+    struct usbback_info *usbif;
+
+    usbif = container_of(xendev, struct usbback_info, xendev);
+    qemu_bh_schedule(usbif->bh);
+}
+
+struct XenDevOps xen_usb_ops = {
+    .size            = sizeof(struct usbback_info),
+    .flags           = DEVOPS_FLAG_NEED_GNTDEV,
+    .init            = usbback_init,
+    .alloc           = usbback_alloc,
+    .free            = usbback_free,
+    .backend_changed = usbback_backend_changed,
+    .initialise      = usbback_connect,
+    .disconnect      = usbback_disconnect,
+    .event           = usbback_event,
+};
+
+#else /* USBIF_SHORT_NOT_OK */
+
+static int usbback_not_supported(void)
+{
+    return -EINVAL;
+}
+
+struct XenDevOps xen_usb_ops = {
+    .backend_register = usbback_not_supported,
+};
+
+#endif
diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c
index bbf3646bae..2aeaf1fbc9 100644
--- a/hw/watchdog/watchdog.c
+++ b/hw/watchdog/watchdog.c
@@ -143,7 +143,7 @@ void watchdog_perform_action(void)
     case WDT_NMI:
         qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_INJECT_NMI,
                                  &error_abort);
-        inject_nmi();
+        nmi_monitor_handle(0, NULL);
         break;
     }
 }
diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c
index 60575ad38d..c63f9df38b 100644
--- a/hw/xen/xen_backend.c
+++ b/hw/xen/xen_backend.c
@@ -42,11 +42,36 @@ struct xs_handle *xenstore = NULL;
 const char *xen_protocol;
 
 /* private */
+struct xs_dirs {
+    char *xs_dir;
+    QTAILQ_ENTRY(xs_dirs) list;
+};
+static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup =
+    QTAILQ_HEAD_INITIALIZER(xs_cleanup);
+
 static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs = QTAILQ_HEAD_INITIALIZER(xendevs);
 static int debug = 0;
 
 /* ------------------------------------------------------------- */
 
+static void xenstore_cleanup_dir(char *dir)
+{
+    struct xs_dirs *d;
+
+    d = g_malloc(sizeof(*d));
+    d->xs_dir = dir;
+    QTAILQ_INSERT_TAIL(&xs_cleanup, d, list);
+}
+
+void xen_config_cleanup(void)
+{
+    struct xs_dirs *d;
+
+    QTAILQ_FOREACH(d, &xs_cleanup, list) {
+        xs_rm(xenstore, 0, d->xs_dir);
+    }
+}
+
 int xenstore_write_str(const char *base, const char *node, const char *val)
 {
     char abspath[XEN_BUFSIZE];
@@ -75,6 +100,30 @@ char *xenstore_read_str(const char *base, const char *node)
     return ret;
 }
 
+int xenstore_mkdir(char *path, int p)
+{
+    struct xs_permissions perms[2] = {
+        {
+            .id    = 0, /* set owner: dom0 */
+        }, {
+            .id    = xen_domid,
+            .perms = p,
+        }
+    };
+
+    if (!xs_mkdir(xenstore, 0, path)) {
+        xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", path);
+        return -1;
+    }
+    xenstore_cleanup_dir(g_strdup(path));
+
+    if (!xs_set_permissions(xenstore, 0, path, perms, 2)) {
+        xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", path);
+        return -1;
+    }
+    return 0;
+}
+
 int xenstore_write_int(const char *base, const char *node, int ival)
 {
     char val[12];
@@ -726,6 +775,20 @@ err:
 
 int xen_be_register(const char *type, struct XenDevOps *ops)
 {
+    char path[50];
+    int rc;
+
+    if (ops->backend_register) {
+        rc = ops->backend_register();
+        if (rc) {
+            return rc;
+        }
+    }
+
+    snprintf(path, sizeof(path), "device-model/%u/backends/%s", xen_domid,
+             type);
+    xenstore_mkdir(path, XS_PERM_NONE);
+
     return xenstore_scan(type, xen_domid, ops);
 }
 
diff --git a/hw/xen/xen_devconfig.c b/hw/xen/xen_devconfig.c
index 1f30fe4f5a..b7d290df6c 100644
--- a/hw/xen/xen_devconfig.c
+++ b/hw/xen/xen_devconfig.c
@@ -5,54 +5,6 @@
 
 /* ------------------------------------------------------------- */
 
-struct xs_dirs {
-    char *xs_dir;
-    QTAILQ_ENTRY(xs_dirs) list;
-};
-static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup = QTAILQ_HEAD_INITIALIZER(xs_cleanup);
-
-static void xen_config_cleanup_dir(char *dir)
-{
-    struct xs_dirs *d;
-
-    d = g_malloc(sizeof(*d));
-    d->xs_dir = dir;
-    QTAILQ_INSERT_TAIL(&xs_cleanup, d, list);
-}
-
-void xen_config_cleanup(void)
-{
-    struct xs_dirs *d;
-
-    QTAILQ_FOREACH(d, &xs_cleanup, list) {
-	xs_rm(xenstore, 0, d->xs_dir);
-    }
-}
-
-/* ------------------------------------------------------------- */
-
-static int xen_config_dev_mkdir(char *dev, int p)
-{
-    struct xs_permissions perms[2] = {{
-            .id    = 0, /* set owner: dom0 */
-        },{
-            .id    = xen_domid,
-            .perms = p,
-        }};
-
-    if (!xs_mkdir(xenstore, 0, dev)) {
-	xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", dev);
-	return -1;
-    }
-    xen_config_cleanup_dir(g_strdup(dev));
-
-    if (!xs_set_permissions(xenstore, 0, dev, perms, 2)) {
-	xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", dev);
-	return -1;
-    }
-    return 0;
-}
-
 static int xen_config_dev_dirs(const char *ftype, const char *btype, int vdev,
 			       char *fe, char *be, int len)
 {
@@ -66,8 +18,8 @@ static int xen_config_dev_dirs(const char *ftype, const char *btype, int vdev,
     snprintf(be, len, "%s/backend/%s/%d/%d", dom, btype, xen_domid, vdev);
     free(dom);
 
-    xen_config_dev_mkdir(fe, XS_PERM_READ | XS_PERM_WRITE);
-    xen_config_dev_mkdir(be, XS_PERM_READ);
+    xenstore_mkdir(fe, XS_PERM_READ | XS_PERM_WRITE);
+    xenstore_mkdir(be, XS_PERM_READ);
     return 0;
 }
 
diff --git a/hw/xenpv/xen_machine_pv.c b/hw/xenpv/xen_machine_pv.c
index fc13535992..f68cf48a29 100644
--- a/hw/xenpv/xen_machine_pv.c
+++ b/hw/xenpv/xen_machine_pv.c
@@ -25,10 +25,15 @@
 #include "qemu/osdep.h"
 #include "hw/hw.h"
 #include "hw/boards.h"
+#include "hw/sysbus.h"
 #include "hw/xen/xen_backend.h"
 #include "xen_domainbuild.h"
 #include "sysemu/block-backend.h"
 
+#define TYPE_XENSYSDEV "xensysdev"
+
+DeviceState *xen_sysdev;
+
 static void xen_init_pv(MachineState *machine)
 {
     DriveInfo *dinfo;
@@ -67,11 +72,17 @@ static void xen_init_pv(MachineState *machine)
         break;
     }
 
+    xen_sysdev = qdev_create(NULL, TYPE_XENSYSDEV);
+    qdev_init_nofail(xen_sysdev);
+
     xen_be_register("console", &xen_console_ops);
     xen_be_register("vkbd", &xen_kbdmouse_ops);
     xen_be_register("vfb", &xen_framebuffer_ops);
     xen_be_register("qdisk", &xen_blkdev_ops);
     xen_be_register("qnic", &xen_netdev_ops);
+#ifdef CONFIG_USB_LIBUSB
+    xen_be_register("qusb", &xen_usb_ops);
+#endif
 
     /* configure framebuffer */
     if (xenfb_enabled) {
@@ -101,6 +112,38 @@ static void xen_init_pv(MachineState *machine)
     xen_init_display(xen_domid);
 }
 
+static int xen_sysdev_init(SysBusDevice *dev)
+{
+    return 0;
+}
+
+static Property xen_sysdev_properties[] = {
+    {/* end of property list */},
+};
+
+static void xen_sysdev_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = xen_sysdev_init;
+    dc->props = xen_sysdev_properties;
+}
+
+static const TypeInfo xensysdev_info = {
+    .name          = TYPE_XENSYSDEV,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SysBusDevice),
+    .class_init    = xen_sysdev_class_init,
+};
+
+static void xenpv_register_types(void)
+{
+    type_register_static(&xensysdev_info);
+}
+
+type_init(xenpv_register_types);
+
 static void xenpv_machine_init(MachineClass *mc)
 {
     mc->desc = "Xen Para-virtualized PC";
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 04eade5b7b..a2c3b92742 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -61,8 +61,8 @@ MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
 RAMBlock *qemu_ram_block_by_name(const char *name);
 RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset,
                                    ram_addr_t *ram_addr, ram_addr_t *offset);
-void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev);
-void qemu_ram_unset_idstr(ram_addr_t addr);
+void qemu_ram_set_idstr(RAMBlock *block, const char *name, DeviceState *dev);
+void qemu_ram_unset_idstr(RAMBlock *block);
 const char *qemu_ram_get_idstr(RAMBlock *rb);
 
 void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 7fb9188c0a..f649697ee9 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -187,7 +187,6 @@ struct MemoryRegion {
     MemoryRegion *alias;
     hwaddr alias_offset;
     int32_t priority;
-    bool may_overlap;
     QTAILQ_HEAD(subregions, MemoryRegion) subregions;
     QTAILQ_ENTRY(MemoryRegion) subregions_link;
     QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 5adf7a4fcd..5b6e1b8b86 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -110,7 +110,7 @@ void qemu_set_ram_fd(ram_addr_t addr, int fd);
 void *qemu_get_ram_block_host_ptr(ram_addr_t addr);
 void qemu_ram_free(RAMBlock *block);
 
-int qemu_ram_resize(ram_addr_t base, ram_addr_t newsize, Error **errp);
+int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp);
 
 #define DIRTY_CLIENTS_ALL     ((1 << DIRTY_MEMORY_NUM) - 1)
 #define DIRTY_CLIENTS_NOCODE  (DIRTY_CLIENTS_ALL & ~(1 << DIRTY_MEMORY_CODE))
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 8d4fe56b5f..d268bd00a9 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -114,7 +114,7 @@ struct MachineClass {
     const char *default_machine_opts;
     const char *default_boot_order;
     const char *default_display;
-    GlobalProperty *compat_props;
+    GArray *compat_props;
     const char *hw_version;
     ram_addr_t default_ram_size;
     bool option_rom_has_mr;
@@ -154,6 +154,7 @@ struct MachineState {
     bool iommu;
     bool suppress_vmdesc;
     bool enforce_config_section;
+    bool enable_graphics;
 
     ram_addr_t ram_size;
     ram_addr_t maxram_size;
@@ -185,11 +186,18 @@ struct MachineState {
 
 #define SET_MACHINE_COMPAT(m, COMPAT) \
     do {                              \
+        int i;                        \
         static GlobalProperty props[] = {       \
             COMPAT                              \
             { /* end of list */ }               \
         };                                      \
-        (m)->compat_props = props;              \
+        if (!m->compat_props) { \
+            m->compat_props = g_array_new(false, false, sizeof(void *)); \
+        } \
+        for (i = 0; props[i].driver != NULL; i++) {    \
+            GlobalProperty *prop = &props[i];          \
+            g_array_append_val(m->compat_props, prop); \
+        }                                              \
     } while (0)
 
 #endif
diff --git a/include/hw/i386/ioapic_internal.h b/include/hw/i386/ioapic_internal.h
index 797ed47305..cab9e67ee7 100644
--- a/include/hw/i386/ioapic_internal.h
+++ b/include/hw/i386/ioapic_internal.h
@@ -47,6 +47,11 @@
 #define IOAPIC_LVT_DEST_MODE            (1 << IOAPIC_LVT_DEST_MODE_SHIFT)
 #define IOAPIC_LVT_DELIV_MODE           (7 << IOAPIC_LVT_DELIV_MODE_SHIFT)
 
+/* Bits that are read-only for IOAPIC entry */
+#define IOAPIC_RO_BITS                  (IOAPIC_LVT_REMOTE_IRR | \
+                                         IOAPIC_LVT_DELIV_STATUS)
+#define IOAPIC_RW_BITS                  (~(uint64_t)IOAPIC_RO_BITS)
+
 #define IOAPIC_TRIGGER_EDGE             0
 #define IOAPIC_TRIGGER_LEVEL            1
 
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 96f0b66c77..367b6dbf0e 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -360,7 +360,6 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
     HW_COMPAT_2_5
 
 #define PC_COMPAT_2_4 \
-    PC_COMPAT_2_5 \
     HW_COMPAT_2_4 \
     {\
         .driver   = "Haswell-" TYPE_X86_CPU,\
@@ -431,7 +430,6 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
 
 
 #define PC_COMPAT_2_3 \
-    PC_COMPAT_2_4 \
     HW_COMPAT_2_3 \
     {\
         .driver   = TYPE_X86_CPU,\
@@ -512,7 +510,6 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
     },
 
 #define PC_COMPAT_2_2 \
-    PC_COMPAT_2_3 \
     HW_COMPAT_2_2 \
     {\
         .driver = "kvm64" "-" TYPE_X86_CPU,\
@@ -606,7 +603,6 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
     },
 
 #define PC_COMPAT_2_1 \
-    PC_COMPAT_2_2 \
     HW_COMPAT_2_1 \
     {\
         .driver = "coreduo" "-" TYPE_X86_CPU,\
@@ -620,7 +616,6 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
     },
 
 #define PC_COMPAT_2_0 \
-    PC_COMPAT_2_1 \
     {\
         .driver   = "virtio-scsi-pci",\
         .property = "any_layout",\
@@ -680,7 +675,6 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
     },
 
 #define PC_COMPAT_1_7 \
-    PC_COMPAT_2_0 \
     {\
         .driver   = TYPE_USB_DEVICE,\
         .property = "msos-desc",\
@@ -698,7 +692,6 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
     },
 
 #define PC_COMPAT_1_6 \
-    PC_COMPAT_1_7 \
     {\
         .driver   = "e1000",\
         .property = "mitigation",\
@@ -722,7 +715,6 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
     },
 
 #define PC_COMPAT_1_5 \
-    PC_COMPAT_1_6 \
     {\
         .driver   = "Conroe-" TYPE_X86_CPU,\
         .property = "model",\
@@ -766,7 +758,6 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
     },
 
 #define PC_COMPAT_1_4 \
-    PC_COMPAT_1_5 \
     {\
         .driver   = "scsi-hd",\
         .property = "discard_granularity",\
diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h
index 218dfb0eda..8cdc3266b3 100644
--- a/include/hw/mem/pc-dimm.h
+++ b/include/hw/mem/pc-dimm.h
@@ -20,8 +20,6 @@
 #include "sysemu/hostmem.h"
 #include "hw/qdev.h"
 
-#define DEFAULT_PC_DIMMSIZE (1024*1024*1024)
-
 #define TYPE_PC_DIMM "pc-dimm"
 #define PC_DIMM(obj) \
     OBJECT_CHECK(PCDIMMDevice, (obj), TYPE_PC_DIMM)
@@ -72,7 +70,7 @@ typedef struct PCDIMMDeviceClass {
 
 /**
  * MemoryHotplugState:
- * @base: address in guest RAM address space where hotplug memory
+ * @base: address in guest physical address space where hotplug memory
  * address space begins.
  * @mr: hotplug memory address space container
  */
diff --git a/include/hw/nmi.h b/include/hw/nmi.h
index f4cec6257d..b541772e1d 100644
--- a/include/hw/nmi.h
+++ b/include/hw/nmi.h
@@ -45,6 +45,5 @@ typedef struct NMIClass {
 } NMIClass;
 
 void nmi_monitor_handle(int cpu_index, Error **errp);
-void inject_nmi(void);
 
 #endif /* NMI_H */
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 13b0ab0848..1602a13ba2 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -27,8 +27,6 @@
 
 #define VIRTIO_ID_GPU 16
 
-#define VIRTIO_GPU_MAX_SCANOUT 4
-
 struct virtio_gpu_simple_resource {
     uint32_t resource_id;
     uint32_t width;
@@ -98,8 +96,8 @@ typedef struct VirtIOGPU {
     QTAILQ_HEAD(, virtio_gpu_ctrl_command) cmdq;
     QTAILQ_HEAD(, virtio_gpu_ctrl_command) fenceq;
 
-    struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUT];
-    struct virtio_gpu_requested_state req_state[VIRTIO_GPU_MAX_SCANOUT];
+    struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS];
+    struct virtio_gpu_requested_state req_state[VIRTIO_GPU_MAX_SCANOUTS];
 
     struct virtio_gpu_conf conf;
     int enabled_output_bitmask;
diff --git a/include/hw/virtio/virtio-rng.h b/include/hw/virtio/virtio-rng.h
index 3f07de70c7..2bc1ee5b50 100644
--- a/include/hw/virtio/virtio-rng.h
+++ b/include/hw/virtio/virtio-rng.h
@@ -26,7 +26,7 @@ struct VirtIORNGConf {
     RngBackend *rng;
     uint64_t max_bytes;
     uint32_t period_ms;
-    RndRandom *default_backend;
+    RngRandom *default_backend;
 };
 
 typedef struct VirtIORNG {
diff --git a/include/hw/xen/xen_backend.h b/include/hw/xen/xen_backend.h
index c839eeb489..6e18a46a97 100644
--- a/include/hw/xen/xen_backend.h
+++ b/include/hw/xen/xen_backend.h
@@ -28,6 +28,7 @@ struct XenDevOps {
     int       (*free)(struct XenDevice *xendev);
     void      (*backend_changed)(struct XenDevice *xendev, const char *node);
     void      (*frontend_changed)(struct XenDevice *xendev, const char *node);
+    int       (*backend_register)(void);
 };
 
 struct XenDevice {
@@ -60,8 +61,10 @@ extern xc_interface *xen_xc;
 extern xenforeignmemory_handle *xen_fmem;
 extern struct xs_handle *xenstore;
 extern const char *xen_protocol;
+extern DeviceState *xen_sysdev;
 
 /* xenstore helper functions */
+int xenstore_mkdir(char *path, int p);
 int xenstore_write_str(const char *base, const char *node, const char *val);
 int xenstore_write_int(const char *base, const char *node, int ival);
 int xenstore_write_int64(const char *base, const char *node, int64_t ival);
@@ -98,6 +101,9 @@ extern struct XenDevOps xen_kbdmouse_ops;     /* xen_framebuffer.c */
 extern struct XenDevOps xen_framebuffer_ops;  /* xen_framebuffer.c */
 extern struct XenDevOps xen_blkdev_ops;       /* xen_disk.c        */
 extern struct XenDevOps xen_netdev_ops;       /* xen_nic.c         */
+#ifdef CONFIG_USB_LIBUSB
+extern struct XenDevOps xen_usb_ops;          /* xen-usb.c         */
+#endif
 
 void xen_init_display(int domid);
 
diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
index 7b52e8ffc1..5eabf37328 100644
--- a/include/hw/xen/xen_common.h
+++ b/include/hw/xen/xen_common.h
@@ -49,6 +49,8 @@ typedef xc_gnttab xengnttab_handle;
 #define xengnttab_unmap(h, a, n) xc_gnttab_munmap(h, a, n)
 #define xengnttab_map_grant_refs(h, c, d, r, p) \
     xc_gnttab_map_grant_refs(h, c, d, r, p)
+#define xengnttab_map_domain_grant_refs(h, c, d, r, p) \
+    xc_gnttab_map_domain_grant_refs(h, c, d, r, p)
 
 #define xenforeignmemory_open(l, f) xen_xc
 
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 268ec66958..994bfa023a 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -263,6 +263,19 @@ void qemu_anon_ram_free(void *ptr, size_t size);
 
 #endif
 
+#if defined(__linux__) && \
+    (defined(__x86_64__) || defined(__arm__) || defined(__aarch64__))
+   /* Use 2 MiB alignment so transparent hugepages can be used by KVM.
+      Valgrind does not support alignments larger than 1 MiB,
+      therefore we need special code which handles running on Valgrind. */
+#  define QEMU_VMALLOC_ALIGN (512 * 4096)
+#elif defined(__linux__) && defined(__s390x__)
+   /* Use 1 MiB (segment size) alignment so gmap can be used by KVM. */
+#  define QEMU_VMALLOC_ALIGN (256 * 4096)
+#else
+#  define QEMU_VMALLOC_ALIGN getpagesize()
+#endif
+
 int qemu_madvise(void *addr, size_t len, int advice);
 
 int qemu_open(const char *name, int flags, ...);
diff --git a/include/sysemu/rng-random.h b/include/sysemu/rng-random.h
index 4332772a24..38186fe83d 100644
--- a/include/sysemu/rng-random.h
+++ b/include/sysemu/rng-random.h
@@ -15,8 +15,8 @@
 #include "qom/object.h"
 
 #define TYPE_RNG_RANDOM "rng-random"
-#define RNG_RANDOM(obj) OBJECT_CHECK(RndRandom, (obj), TYPE_RNG_RANDOM)
+#define RNG_RANDOM(obj) OBJECT_CHECK(RngRandom, (obj), TYPE_RNG_RANDOM)
 
-typedef struct RndRandom RndRandom;
+typedef struct RngRandom RngRandom;
 
 #endif
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 38fb3cad35..618169c4d5 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -131,21 +131,12 @@ void qemu_savevm_send_postcopy_ram_discard(QEMUFile *f, const char *name,
 
 int qemu_loadvm_state(QEMUFile *f);
 
-typedef enum DisplayType
-{
-    DT_DEFAULT,
-    DT_CURSES,
-    DT_SDL,
-    DT_GTK,
-    DT_NOGRAPHIC,
-    DT_NONE,
-} DisplayType;
-
 extern int autostart;
 
 typedef enum {
     VGA_NONE, VGA_STD, VGA_CIRRUS, VGA_VMWARE, VGA_XENFB, VGA_QXL,
     VGA_TCX, VGA_CG3, VGA_DEVICE, VGA_VIRTIO,
+    VGA_TYPE_MAX,
 } VGAInterfaceType;
 
 extern int vga_interface_type;
@@ -154,7 +145,6 @@ extern int vga_interface_type;
 extern int graphic_width;
 extern int graphic_height;
 extern int graphic_depth;
-extern DisplayType display_type;
 extern int display_opengl;
 extern const char *keyboard_layout;
 extern int win2k_install_hack;
diff --git a/include/ui/console.h b/include/ui/console.h
index d5a88d93e8..52a5f65673 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -6,6 +6,8 @@
 #include "qapi/qmp/qdict.h"
 #include "qemu/notify.h"
 #include "qapi-types.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
 
 #ifdef CONFIG_OPENGL
 # include <epoxy/gl.h>
@@ -420,20 +422,45 @@ void surface_gl_setup_viewport(ConsoleGLState *gls,
 #endif
 
 /* sdl.c */
+#ifdef CONFIG_SDL
 void sdl_display_early_init(int opengl);
 void sdl_display_init(DisplayState *ds, int full_screen, int no_frame);
+#else
+static inline void sdl_display_early_init(int opengl)
+{
+    /* This must never be called if CONFIG_SDL is disabled */
+    error_report("SDL support is disabled");
+    abort();
+}
+static inline void sdl_display_init(DisplayState *ds, int full_screen,
+                                    int no_frame)
+{
+    /* This must never be called if CONFIG_SDL is disabled */
+    error_report("SDL support is disabled");
+    abort();
+}
+#endif
 
 /* cocoa.m */
+#ifdef CONFIG_COCOA
 void cocoa_display_init(DisplayState *ds, int full_screen);
+#else
+static inline void cocoa_display_init(DisplayState *ds, int full_screen)
+{
+    /* This must never be called if CONFIG_COCOA is disabled */
+    error_report("Cocoa support is disabled");
+    abort();
+}
+#endif
 
 /* vnc.c */
 void vnc_display_init(const char *id);
 void vnc_display_open(const char *id, Error **errp);
 void vnc_display_add_client(const char *id, int csock, bool skipauth);
-char *vnc_display_local_addr(const char *id);
 #ifdef CONFIG_VNC
 int vnc_display_password(const char *id, const char *password);
 int vnc_display_pw_expire(const char *id, time_t expires);
+char *vnc_display_local_addr(const char *id);
 QemuOpts *vnc_parse(const char *str, Error **errp);
 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp);
 #else
@@ -445,16 +472,58 @@ static inline int vnc_display_pw_expire(const char *id, time_t expires)
 {
     return -ENODEV;
 };
+static inline QemuOpts *vnc_parse(const char *str, Error **errp)
+{
+    error_setg(errp, "VNC support is disabled");
+    return NULL;
+}
+static inline int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
+{
+    error_setg(errp, "VNC support is disabled");
+    return -1;
+}
+static inline char *vnc_display_local_addr(const char *id)
+{
+    /* This must never be called if CONFIG_VNC is disabled */
+    error_report("VNC support is disabled");
+    abort();
+}
 #endif
 
 /* curses.c */
+#ifdef CONFIG_CURSES
 void curses_display_init(DisplayState *ds, int full_screen);
+#else
+static inline void curses_display_init(DisplayState *ds, int full_screen)
+{
+    /* This must never be called if CONFIG_CURSES is disabled */
+    error_report("curses support is disabled");
+    abort();
+}
+#endif
 
 /* input.c */
 int index_from_key(const char *key, size_t key_length);
 
 /* gtk.c */
+#ifdef CONFIG_GTK
 void early_gtk_display_init(int opengl);
 void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover);
+#else
+static inline void gtk_display_init(DisplayState *ds, bool full_screen,
+                                    bool grab_on_hover)
+{
+    /* This must never be called if CONFIG_GTK is disabled */
+    error_report("GTK support is disabled");
+    abort();
+}
+
+static inline void early_gtk_display_init(int opengl)
+{
+    /* This must never be called if CONFIG_GTK is disabled */
+    error_report("GTK support is disabled");
+    abort();
+}
+#endif
 
 #endif
diff --git a/include/ui/qemu-spice.h b/include/ui/qemu-spice.h
index aa2436355f..57ac91b921 100644
--- a/include/ui/qemu-spice.h
+++ b/include/ui/qemu-spice.h
@@ -51,6 +51,8 @@ static inline CharDriverState *qemu_chr_open_spice_port(const char *name)
 
 #else  /* CONFIG_SPICE */
 
+#include "qemu/error-report.h"
+
 #define using_spice 0
 #define spice_displays 0
 static inline int qemu_spice_set_passwd(const char *passwd,
@@ -75,6 +77,17 @@ static inline int qemu_spice_display_add_client(int csock, int skipauth,
     return -1;
 }
 
+static inline void qemu_spice_display_init(void)
+{
+    /* This must never be called if CONFIG_SPICE is disabled */
+    error_report("spice support is disabled");
+    abort();
+}
+
+static inline void qemu_spice_init(void)
+{
+}
+
 #endif /* CONFIG_SPICE */
 
 static inline bool qemu_using_spice(Error **errp)
diff --git a/memory.c b/memory.c
index a8ef85261f..4e3cda8a12 100644
--- a/memory.c
+++ b/memory.c
@@ -227,7 +227,6 @@ struct FlatRange {
     hwaddr offset_in_region;
     AddrRange addr;
     uint8_t dirty_log_mask;
-    bool romd_mode;
     bool readonly;
 };
 
@@ -252,7 +251,6 @@ static bool flatrange_equal(FlatRange *a, FlatRange *b)
     return a->mr == b->mr
         && addrrange_equal(a->addr, b->addr)
         && a->offset_in_region == b->offset_in_region
-        && a->romd_mode == b->romd_mode
         && a->readonly == b->readonly;
 }
 
@@ -312,7 +310,6 @@ static bool can_merge(FlatRange *r1, FlatRange *r2)
                                 r1->addr.size),
                      int128_make64(r2->offset_in_region))
         && r1->dirty_log_mask == r2->dirty_log_mask
-        && r1->romd_mode == r2->romd_mode
         && r1->readonly == r2->readonly;
 }
 
@@ -666,7 +663,6 @@ static void render_memory_region(FlatView *view,
 
     fr.mr = mr;
     fr.dirty_log_mask = memory_region_get_dirty_log_mask(mr);
-    fr.romd_mode = mr->romd_mode;
     fr.readonly = readonly;
 
     /* Render the region itself into any gaps left by the current view. */
@@ -1057,13 +1053,6 @@ static void memory_region_get_priority(Object *obj, Visitor *v,
     visit_type_int32(v, name, &value, errp);
 }
 
-static bool memory_region_get_may_overlap(Object *obj, Error **errp)
-{
-    MemoryRegion *mr = MEMORY_REGION(obj);
-
-    return mr->may_overlap;
-}
-
 static void memory_region_get_size(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
@@ -1101,10 +1090,6 @@ static void memory_region_initfn(Object *obj)
                         memory_region_get_priority,
                         NULL, /* memory_region_set_priority */
                         NULL, NULL, &error_abort);
-    object_property_add_bool(OBJECT(mr), "may-overlap",
-                             memory_region_get_may_overlap,
-                             NULL, /* memory_region_set_may_overlap */
-                             &error_abort);
     object_property_add(OBJECT(mr), "size", "uint64",
                         memory_region_get_size,
                         NULL, /* memory_region_set_size, */
@@ -1643,7 +1628,7 @@ int memory_region_get_fd(MemoryRegion *mr)
 
     assert(mr->ram_block);
 
-    return qemu_get_ram_fd(memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK);
+    return qemu_get_ram_fd(memory_region_get_ram_addr(mr));
 }
 
 void *memory_region_get_ram_ptr(MemoryRegion *mr)
@@ -1657,8 +1642,7 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr)
         mr = mr->alias;
     }
     assert(mr->ram_block);
-    ptr = qemu_get_ram_ptr(mr->ram_block,
-                           memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK);
+    ptr = qemu_get_ram_ptr(mr->ram_block, memory_region_get_ram_addr(mr));
     rcu_read_unlock();
 
     return ptr + offset;
@@ -1673,7 +1657,7 @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp
 {
     assert(mr->ram_block);
 
-    qemu_ram_resize(memory_region_get_ram_addr(mr), newsize, errp);
+    qemu_ram_resize(mr->ram_block, newsize, errp);
 }
 
 static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpace *as)
@@ -1864,7 +1848,6 @@ void memory_region_del_eventfd(MemoryRegion *mr,
 
 static void memory_region_update_container_subregions(MemoryRegion *subregion)
 {
-    hwaddr offset = subregion->addr;
     MemoryRegion *mr = subregion->container;
     MemoryRegion *other;
 
@@ -1872,27 +1855,6 @@ static void memory_region_update_container_subregions(MemoryRegion *subregion)
 
     memory_region_ref(subregion);
     QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
-        if (subregion->may_overlap || other->may_overlap) {
-            continue;
-        }
-        if (int128_ge(int128_make64(offset),
-                      int128_add(int128_make64(other->addr), other->size))
-            || int128_le(int128_add(int128_make64(offset), subregion->size),
-                         int128_make64(other->addr))) {
-            continue;
-        }
-#if 0
-        printf("warning: subregion collision %llx/%llx (%s) "
-               "vs %llx/%llx (%s)\n",
-               (unsigned long long)offset,
-               (unsigned long long)int128_get64(subregion->size),
-               subregion->name,
-               (unsigned long long)other->addr,
-               (unsigned long long)int128_get64(other->size),
-               other->name);
-#endif
-    }
-    QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
         if (subregion->priority >= other->priority) {
             QTAILQ_INSERT_BEFORE(other, subregion, subregions_link);
             goto done;
@@ -1918,7 +1880,6 @@ void memory_region_add_subregion(MemoryRegion *mr,
                                  hwaddr offset,
                                  MemoryRegion *subregion)
 {
-    subregion->may_overlap = false;
     subregion->priority = 0;
     memory_region_add_subregion_common(mr, offset, subregion);
 }
@@ -1928,7 +1889,6 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr,
                                          MemoryRegion *subregion,
                                          int priority)
 {
-    subregion->may_overlap = true;
     subregion->priority = priority;
     memory_region_add_subregion_common(mr, offset, subregion);
 }
diff --git a/migration/ram.c b/migration/ram.c
index d1ecb99961..54e215128c 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -2478,7 +2478,7 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
                     if (length != block->used_length) {
                         Error *local_err = NULL;
 
-                        ret = qemu_ram_resize(block->offset, length,
+                        ret = qemu_ram_resize(block, length,
                                               &local_err);
                         if (local_err) {
                             error_report_err(local_err);
diff --git a/migration/savevm.c b/migration/savevm.c
index f8450fd0e9..65ce0c61a3 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2229,13 +2229,13 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
 
 void vmstate_register_ram(MemoryRegion *mr, DeviceState *dev)
 {
-    qemu_ram_set_idstr(memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK,
+    qemu_ram_set_idstr(mr->ram_block,
                        memory_region_name(mr), dev);
 }
 
 void vmstate_unregister_ram(MemoryRegion *mr, DeviceState *dev)
 {
-    qemu_ram_unset_idstr(memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK);
+    qemu_ram_unset_idstr(mr->ram_block);
 }
 
 void vmstate_register_ram_global(MemoryRegion *mr)
diff --git a/qemu-img.c b/qemu-img.c
index 47923663be..7ed8ef21cb 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3492,10 +3492,7 @@ int main(int argc, char **argv)
         exit(EXIT_FAILURE);
     }
 
-    if (qcrypto_init(&local_error) < 0) {
-        error_reportf_err(local_error, "cannot initialize crypto: ");
-        exit(1);
-    }
+    qcrypto_init(&error_fatal);
 
     module_call_init(MODULE_INIT_QOM);
     bdrv_init();
diff --git a/qemu-io.c b/qemu-io.c
index 5ef3ef7f35..d977a6e553 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -466,10 +466,7 @@ int main(int argc, char **argv)
     progname = basename(argv[0]);
     qemu_init_exec_dir(argv[0]);
 
-    if (qcrypto_init(&local_error) < 0) {
-        error_reportf_err(local_error, "cannot initialize crypto: ");
-        exit(1);
-    }
+    qcrypto_init(&error_fatal);
 
     module_call_init(MODULE_INIT_QOM);
     qemu_add_opts(&qemu_object_opts);
diff --git a/qemu-nbd.c b/qemu-nbd.c
index d59b187780..6554f0ab65 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -527,10 +527,7 @@ int main(int argc, char **argv)
     sa_sigterm.sa_handler = termsig_handler;
     sigaction(SIGTERM, &sa_sigterm, NULL);
 
-    if (qcrypto_init(&local_err) < 0) {
-        error_reportf_err(local_err, "cannot initialize crypto: ");
-        exit(1);
-    }
+    qcrypto_init(&error_fatal);
 
     module_call_init(MODULE_INIT_QOM);
     qemu_add_opts(&qemu_object_opts);
diff --git a/scripts/cocci-macro-file.h b/scripts/cocci-macro-file.h
index eceb4be73f..9f2e72e7e1 100644
--- a/scripts/cocci-macro-file.h
+++ b/scripts/cocci-macro-file.h
@@ -117,3 +117,9 @@ struct {                                                                \
         type *tqe_next;       /* next element */                        \
         type **tqe_prev;      /* address of previous next element */    \
 }
+
+/* From glib */
+#define g_assert_cmpint(a, op, b)   g_assert(a op b)
+#define g_assert_cmpuint(a, op, b)   g_assert(a op b)
+#define g_assert_cmphex(a, op, b)   g_assert(a op b)
+#define g_assert_cmpstr(a, op, b)   g_assert(strcmp(a, b) op 0)
diff --git a/scripts/signrom.py b/scripts/signrom.py
index f9c35ccfca..5629bca222 100644
--- a/scripts/signrom.py
+++ b/scripts/signrom.py
@@ -17,11 +17,33 @@ if len(sys.argv) < 3:
 fin = open(sys.argv[1], 'rb')
 fout = open(sys.argv[2], 'wb')
 
-fin.seek(2)
-size = ord(fin.read(1)) * 512 - 1
+magic = fin.read(2)
+if magic != '\x55\xaa':
+    sys.exit("%s: option ROM does not begin with magic 55 aa" % sys.argv[1])
 
+size_byte = ord(fin.read(1))
 fin.seek(0)
-data = fin.read(size)
+
+if size_byte == 0:
+    # If the caller left the size field blank then we will fill it in,
+    # also rounding the whole input to a multiple of 512 bytes.
+    data = fin.read()
+    # +1 because we need a byte to store the checksum.
+    size = len(data) + 1
+    # Round up to next multiple of 512.
+    size += 511
+    size -= size % 512
+    if size >= 65536:
+        sys.exit("%s: option ROM size too large" % sys.argv[1])
+    # size-1 because a final byte is added below to store the checksum.
+    data = data.ljust(size-1, '\0')
+    data = data[:2] + chr(size/512) + data[3:]
+else:
+    # Otherwise the input file specifies the size so use it.
+    # -1 because we overwrite the last byte of the file with the checksum.
+    size = size_byte * 512 - 1
+    data = fin.read(size)
+
 fout.write(data)
 
 checksum = 0
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 8085467945..731b10de06 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -8008,6 +8008,11 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
             }
             /* fallthru */
         case 0xf9 ... 0xff: /* sfence */
+            if (!(s->cpuid_features & CPUID_SSE)
+                || (prefixes & PREFIX_LOCK)) {
+                goto illegal_op;
+            }
+            break;
         case 0xe8 ... 0xef: /* lfence */
         case 0xf0 ... 0xf7: /* mfence */
             if (!(s->cpuid_features & CPUID_SSE2)
diff --git a/translate-all.c b/translate-all.c
index 1c1c85530a..c599dc4d41 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -1555,8 +1555,7 @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
         rcu_read_unlock();
         return;
     }
-    ram_addr = (memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK)
-        + addr;
+    ram_addr = memory_region_get_ram_addr(mr) + addr;
     tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
     rcu_read_unlock();
 }
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 6cc4b8f001..4adde93ac1 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -26,19 +26,6 @@
  * THE SOFTWARE.
  */
 
-#if defined(__linux__) && \
-    (defined(__x86_64__) || defined(__arm__) || defined(__aarch64__))
-   /* Use 2 MiB alignment so transparent hugepages can be used by KVM.
-      Valgrind does not support alignments larger than 1 MiB,
-      therefore we need special code which handles running on Valgrind. */
-#  define QEMU_VMALLOC_ALIGN (512 * 4096)
-#elif defined(__linux__) && defined(__s390x__)
-   /* Use 1 MiB (segment size) alignment so gmap can be used by KVM. */
-#  define QEMU_VMALLOC_ALIGN (256 * 4096)
-#else
-#  define QEMU_VMALLOC_ALIGN getpagesize()
-#endif
-
 #include "qemu/osdep.h"
 #include <termios.h>
 #include <termios.h>
diff --git a/vl.c b/vl.c
index a43a3bad18..2569dbb8d8 100644
--- a/vl.c
+++ b/vl.c
@@ -129,10 +129,8 @@ static const char *data_dir[16];
 static int data_dir_idx;
 const char *bios_name = NULL;
 enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
-DisplayType display_type = DT_DEFAULT;
 int request_opengl = -1;
 int display_opengl;
-static int display_remote;
 const char* keyboard_layout = NULL;
 ram_addr_t ram_size;
 const char *mem_path = NULL;
@@ -148,9 +146,7 @@ int vga_interface_type = VGA_NONE;
 static int full_screen = 0;
 static int no_frame = 0;
 int no_quit = 0;
-#ifdef CONFIG_GTK
 static bool grab_on_hover;
-#endif
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
 CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
@@ -694,6 +690,10 @@ void runstate_set(RunState new_state)
 {
     assert(new_state < RUN_STATE__MAX);
 
+    if (current_run_state == new_state) {
+        return;
+    }
+
     if (!runstate_valid_transitions[current_run_state][new_state]) {
         error_report("invalid runstate transition: '%s' -> '%s'",
                      RunState_lookup[current_run_state],
@@ -892,16 +892,13 @@ static void configure_rtc(QemuOpts *opts)
     value = qemu_opt_get(opts, "driftfix");
     if (value) {
         if (!strcmp(value, "slew")) {
-            static GlobalProperty slew_lost_ticks[] = {
-                {
-                    .driver   = "mc146818rtc",
-                    .property = "lost_tick_policy",
-                    .value    = "slew",
-                },
-                { /* end of list */ }
+            static GlobalProperty slew_lost_ticks = {
+                .driver   = "mc146818rtc",
+                .property = "lost_tick_policy",
+                .value    = "slew",
             };
 
-            qdev_prop_register_global_list(slew_lost_ticks);
+            qdev_prop_register_global(&slew_lost_ticks);
         } else if (!strcmp(value, "none")) {
             /* discard is default */
         } else {
@@ -1981,99 +1978,86 @@ static const QEMUOption qemu_options[] = {
     { NULL },
 };
 
-static bool vga_available(void)
-{
-    return object_class_by_name("VGA") || object_class_by_name("isa-vga");
-}
-
-static bool cirrus_vga_available(void)
-{
-    return object_class_by_name("cirrus-vga")
-           || object_class_by_name("isa-cirrus-vga");
-}
-
-static bool vmware_vga_available(void)
-{
-    return object_class_by_name("vmware-svga");
-}
-
-static bool qxl_vga_available(void)
-{
-    return object_class_by_name("qxl-vga");
-}
-
-static bool tcx_vga_available(void)
-{
-    return object_class_by_name("SUNW,tcx");
-}
+typedef struct VGAInterfaceInfo {
+    const char *opt_name;    /* option name */
+    const char *name;        /* human-readable name */
+    /* Class names indicating that support is available.
+     * If no class is specified, the interface is always available */
+    const char *class_names[2];
+} VGAInterfaceInfo;
+
+static VGAInterfaceInfo vga_interfaces[VGA_TYPE_MAX] = {
+    [VGA_NONE] = {
+        .opt_name = "none",
+    },
+    [VGA_STD] = {
+        .opt_name = "std",
+        .name = "standard VGA",
+        .class_names = { "VGA", "isa-vga" },
+    },
+    [VGA_CIRRUS] = {
+        .opt_name = "cirrus",
+        .name = "Cirrus VGA",
+        .class_names = { "cirrus-vga", "isa-cirrus-vga" },
+    },
+    [VGA_VMWARE] = {
+        .opt_name = "vmware",
+        .name = "VMWare SVGA",
+        .class_names = { "vmware-svga" },
+    },
+    [VGA_VIRTIO] = {
+        .opt_name = "virtio",
+        .name = "Virtio VGA",
+        .class_names = { "virtio-vga" },
+    },
+    [VGA_QXL] = {
+        .opt_name = "qxl",
+        .name = "QXL VGA",
+        .class_names = { "qxl-vga" },
+    },
+    [VGA_TCX] = {
+        .opt_name = "tcx",
+        .name = "TCX framebuffer",
+        .class_names = { "SUNW,tcx" },
+    },
+    [VGA_CG3] = {
+        .opt_name = "cg3",
+        .name = "CG3 framebuffer",
+        .class_names = { "cgthree" },
+    },
+    [VGA_XENFB] = {
+        .opt_name = "xenfb",
+    },
+};
 
-static bool cg3_vga_available(void)
+static bool vga_interface_available(VGAInterfaceType t)
 {
-    return object_class_by_name("cgthree");
-}
+    VGAInterfaceInfo *ti = &vga_interfaces[t];
 
-static bool virtio_vga_available(void)
-{
-    return object_class_by_name("virtio-vga");
+    assert(t < VGA_TYPE_MAX);
+    return !ti->class_names[0] ||
+           object_class_by_name(ti->class_names[0]) ||
+           object_class_by_name(ti->class_names[1]);
 }
 
-static void select_vgahw (const char *p)
+static void select_vgahw(const char *p)
 {
     const char *opts;
+    int t;
 
     assert(vga_interface_type == VGA_NONE);
-    if (strstart(p, "std", &opts)) {
-        if (vga_available()) {
-            vga_interface_type = VGA_STD;
-        } else {
-            error_report("standard VGA not available");
-            exit(0);
-        }
-    } else if (strstart(p, "cirrus", &opts)) {
-        if (cirrus_vga_available()) {
-            vga_interface_type = VGA_CIRRUS;
-        } else {
-            error_report("Cirrus VGA not available");
-            exit(0);
-        }
-    } else if (strstart(p, "vmware", &opts)) {
-        if (vmware_vga_available()) {
-            vga_interface_type = VGA_VMWARE;
-        } else {
-            error_report("VMWare SVGA not available");
-            exit(0);
-        }
-    } else if (strstart(p, "virtio", &opts)) {
-        if (virtio_vga_available()) {
-            vga_interface_type = VGA_VIRTIO;
-        } else {
-            error_report("Virtio VGA not available");
-            exit(0);
-        }
-    } else if (strstart(p, "xenfb", &opts)) {
-        vga_interface_type = VGA_XENFB;
-    } else if (strstart(p, "qxl", &opts)) {
-        if (qxl_vga_available()) {
-            vga_interface_type = VGA_QXL;
-        } else {
-            error_report("QXL VGA not available");
-            exit(0);
-        }
-    } else if (strstart(p, "tcx", &opts)) {
-        if (tcx_vga_available()) {
-            vga_interface_type = VGA_TCX;
-        } else {
-            error_report("TCX framebuffer not available");
-            exit(0);
-        }
-    } else if (strstart(p, "cg3", &opts)) {
-        if (cg3_vga_available()) {
-            vga_interface_type = VGA_CG3;
-        } else {
-            error_report("CG3 framebuffer not available");
-            exit(0);
+    for (t = 0; t < VGA_TYPE_MAX; t++) {
+        VGAInterfaceInfo *ti = &vga_interfaces[t];
+        if (ti->opt_name && strstart(p, ti->opt_name, &opts)) {
+            if (!vga_interface_available(t)) {
+                error_report("%s not available", ti->name);
+                exit(1);
+            }
+            vga_interface_type = t;
+            break;
         }
-    } else if (!strstart(p, "none", &opts)) {
+    }
+    if (t == VGA_TYPE_MAX) {
     invalid_vga:
         error_report("unknown vga type: %s", p);
         exit(1);
@@ -2093,6 +2077,15 @@ static void select_vgahw (const char *p)
     }
 }
 
+typedef enum DisplayType {
+    DT_DEFAULT,
+    DT_CURSES,
+    DT_SDL,
+    DT_COCOA,
+    DT_GTK,
+    DT_NONE,
+} DisplayType;
+
 static DisplayType select_display(const char *p)
 {
     const char *opts;
@@ -2161,21 +2154,12 @@ static DisplayType select_display(const char *p)
         exit(1);
 #endif
     } else if (strstart(p, "vnc", &opts)) {
-#ifdef CONFIG_VNC
         if (*opts == '=') {
-            Error *err = NULL;
-            if (vnc_parse(opts + 1, &err) == NULL) {
-                error_report_err(err);
-                exit(1);
-            }
+            vnc_parse(opts + 1, &error_fatal);
         } else {
             error_report("VNC requires a display argument vnc=<display>");
             exit(1);
         }
-#else
-        error_report("VNC support is disabled");
-        exit(1);
-#endif
     } else if (strstart(p, "curses", &opts)) {
 #ifdef CONFIG_CURSES
         display = DT_CURSES;
@@ -2424,7 +2408,6 @@ static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp)
 static void monitor_parse(const char *optarg, const char *mode, bool pretty)
 {
     static int monitor_device_index = 0;
-    Error *local_err = NULL;
     QemuOpts *opts;
     const char *p;
     char label[32];
@@ -2445,11 +2428,7 @@ static void monitor_parse(const char *optarg, const char *mode, bool pretty)
         }
     }
 
-    opts = qemu_opts_create(qemu_find_opts("mon"), label, 1, &local_err);
-    if (!opts) {
-        error_report_err(local_err);
-        exit(1);
-    }
+    opts = qemu_opts_create(qemu_find_opts("mon"), label, 1, &error_fatal);
     qemu_opt_set(opts, "mode", mode, &error_abort);
     qemu_opt_set(opts, "chardev", label, &error_abort);
     qemu_opt_set_bool(opts, "pretty", pretty, &error_abort);
@@ -2979,11 +2958,12 @@ int main(int argc, char **argv, char **envp)
     const char *qtest_log = NULL;
     const char *pid_file = NULL;
     const char *incoming = NULL;
-#ifdef CONFIG_VNC
     int show_vnc_port = 0;
-#endif
     bool defconfig = true;
     bool userconfig = true;
+    bool nographic = false;
+    DisplayType display_type = DT_DEFAULT;
+    int display_remote = 0;
     const char *log_mask = NULL;
     const char *log_file = NULL;
     char *trace_file = NULL;
@@ -3228,7 +3208,10 @@ int main(int argc, char **argv, char **envp)
                 display_type = select_display(optarg);
                 break;
             case QEMU_OPTION_nographic:
-                display_type = DT_NOGRAPHIC;
+                olist = qemu_find_opts("machine");
+                qemu_opts_parse_noisily(olist, "graphics=off", false);
+                nographic = true;
+                display_type = DT_NONE;
                 break;
             case QEMU_OPTION_curses:
 #ifdef CONFIG_CURSES
@@ -3635,16 +3618,13 @@ int main(int argc, char **argv, char **envp)
                 win2k_install_hack = 1;
                 break;
             case QEMU_OPTION_rtc_td_hack: {
-                static GlobalProperty slew_lost_ticks[] = {
-                    {
-                        .driver   = "mc146818rtc",
-                        .property = "lost_tick_policy",
-                        .value    = "slew",
-                    },
-                    { /* end of list */ }
+                static GlobalProperty slew_lost_ticks = {
+                    .driver   = "mc146818rtc",
+                    .property = "lost_tick_policy",
+                    .value    = "slew",
                 };
 
-                qdev_prop_register_global_list(slew_lost_ticks);
+                qdev_prop_register_global(&slew_lost_ticks);
                 break;
             }
             case QEMU_OPTION_acpitable:
@@ -3691,18 +3671,15 @@ int main(int argc, char **argv, char **envp)
                 break;
             }
             case QEMU_OPTION_no_kvm_pit_reinjection: {
-                static GlobalProperty kvm_pit_lost_tick_policy[] = {
-                    {
-                        .driver   = "kvm-pit",
-                        .property = "lost_tick_policy",
-                        .value    = "discard",
-                    },
-                    { /* end of list */ }
+                static GlobalProperty kvm_pit_lost_tick_policy = {
+                    .driver   = "kvm-pit",
+                    .property = "lost_tick_policy",
+                    .value    = "discard",
                 };
 
                 error_report("warning: deprecated, replaced by "
                              "-global kvm-pit.lost_tick_policy=discard");
-                qdev_prop_register_global_list(kvm_pit_lost_tick_policy);
+                qdev_prop_register_global(&kvm_pit_lost_tick_policy);
                 break;
             }
             case QEMU_OPTION_usb:
@@ -3727,20 +3704,8 @@ int main(int argc, char **argv, char **envp)
                 }
                 break;
             case QEMU_OPTION_vnc:
-            {
-#ifdef CONFIG_VNC
-                Error *local_err = NULL;
-
-                if (vnc_parse(optarg, &local_err) == NULL) {
-                    error_report_err(local_err);
-                    exit(1);
-                }
-#else
-                error_report("VNC support is disabled");
-                exit(1);
-#endif
+                vnc_parse(optarg, &error_fatal);
                 break;
-            }
             case QEMU_OPTION_no_acpi:
                 acpi_enabled = 0;
                 break;
@@ -4194,7 +4159,7 @@ int main(int argc, char **argv, char **envp)
          * -nographic _and_ redirects all ports explicitly - this is valid
          * usage, -nographic is just a no-op in this case.
          */
-        if (display_type == DT_NOGRAPHIC
+        if (nographic
             && (default_parallel || default_serial
                 || default_monitor || default_virtcon)) {
             error_report("-nographic cannot be used with -daemonize");
@@ -4208,7 +4173,7 @@ int main(int argc, char **argv, char **envp)
 #endif
     }
 
-    if (display_type == DT_NOGRAPHIC) {
+    if (nographic) {
         if (default_parallel)
             add_device_config(DEV_PARALLEL, "null");
         if (default_serial && default_monitor) {
@@ -4250,8 +4215,10 @@ int main(int argc, char **argv, char **envp)
     if (display_type == DT_DEFAULT && !display_remote) {
 #if defined(CONFIG_GTK)
         display_type = DT_GTK;
-#elif defined(CONFIG_SDL) || defined(CONFIG_COCOA)
+#elif defined(CONFIG_SDL)
         display_type = DT_SDL;
+#elif defined(CONFIG_COCOA)
+        display_type = DT_COCOA;
 #elif defined(CONFIG_VNC)
         vnc_parse("localhost:0,to=99,id=default", &error_abort);
         show_vnc_port = 1;
@@ -4269,16 +4236,14 @@ int main(int argc, char **argv, char **envp)
                      "ignoring option");
     }
 
-#if defined(CONFIG_GTK)
     if (display_type == DT_GTK) {
         early_gtk_display_init(request_opengl);
     }
-#endif
-#if defined(CONFIG_SDL)
+
     if (display_type == DT_SDL) {
         sdl_display_early_init(request_opengl);
     }
-#endif
+
     if (request_opengl == 1 && display_opengl == 0) {
 #if defined(CONFIG_OPENGL)
         error_report("OpenGL is not supported by the display");
@@ -4387,10 +4352,8 @@ int main(int argc, char **argv, char **envp)
 
     os_set_line_buffering();
 
-#ifdef CONFIG_SPICE
     /* spice needs the timers to be initialized by this point */
     qemu_spice_init();
-#endif
 
     cpu_ticks_init();
     if (icount_opts) {
@@ -4481,9 +4444,9 @@ int main(int argc, char **argv, char **envp)
     if (default_vga) {
         if (machine_class->default_display) {
             vga_model = machine_class->default_display;
-        } else if (cirrus_vga_available()) {
+        } else if (vga_interface_available(VGA_CIRRUS)) {
             vga_model = "cirrus";
-        } else if (vga_available()) {
+        } else if (vga_interface_available(VGA_STD)) {
             vga_model = "std";
         }
     }
@@ -4498,7 +4461,11 @@ int main(int argc, char **argv, char **envp)
     }
 
     if (machine_class->compat_props) {
-        qdev_prop_register_global_list(machine_class->compat_props);
+        GlobalProperty *p;
+        for (i = 0; i < machine_class->compat_props->len; i++) {
+            p = g_array_index(machine_class->compat_props, GlobalProperty *, i);
+            qdev_prop_register_global(p);
+        }
     }
     qemu_add_globals();
 
@@ -4560,28 +4527,18 @@ int main(int argc, char **argv, char **envp)
 
     /* init local displays */
     switch (display_type) {
-    case DT_NOGRAPHIC:
-        (void)ds;	/* avoid warning if no display is configured */
-        break;
-#if defined(CONFIG_CURSES)
     case DT_CURSES:
         curses_display_init(ds, full_screen);
         break;
-#endif
-#if defined(CONFIG_SDL)
     case DT_SDL:
         sdl_display_init(ds, full_screen, no_frame);
         break;
-#elif defined(CONFIG_COCOA)
-    case DT_SDL:
+    case DT_COCOA:
         cocoa_display_init(ds, full_screen);
         break;
-#endif
-#if defined(CONFIG_GTK)
     case DT_GTK:
         gtk_display_init(ds, full_screen, grab_on_hover);
         break;
-#endif
     default:
         break;
     }
@@ -4589,7 +4546,6 @@ int main(int argc, char **argv, char **envp)
     /* must be after terminal init, SDL library changes signal handlers */
     os_setup_signal_handling();
 
-#ifdef CONFIG_VNC
     /* init remote displays */
     qemu_opts_foreach(qemu_find_opts("vnc"),
                       vnc_init_func, NULL, NULL);
@@ -4598,12 +4554,10 @@ int main(int argc, char **argv, char **envp)
         printf("VNC server running on '%s'\n", ret);
         g_free(ret);
     }
-#endif
-#ifdef CONFIG_SPICE
+
     if (using_spice) {
         qemu_spice_display_init();
     }
-#endif
 
     if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
         exit(1);