[Spice-commits] 71 commits - .gitignore block.c block/mirror.c block/qcow2.c block/raw-aio.h block/raw-posix.c block/sheepdog.c block/win32-aio.c configure cpus.c exec.c gdbstub.c hw/acpi_piix4.c hw/alpha_dp264.c hw/alpha_typhoon.c hw/an5206.c hw/arm_gic.c hw/arm_mptimer.c hw/axis_dev88.c hw/boards.h hw/collie.c hw/dma.c hw/dummy_m68k.c hw/exynos4_boards.c hw/gumstix.c hw/highbank.c hw/ide hw/integratorcp.c hw/kzm.c hw/leon3.c hw/lm32_boards.c hw/mainstone.c hw/mcf5208.c hw/milkymist.c hw/mips_fulong2e.c hw/mips_jazz.c hw/mips_malta.c hw/mips_mipssim.c hw/mips_r4k.c hw/musicpal.c hw/nseries.c hw/null-machine.c hw/omap_sx1.c hw/openpic.c hw/openrisc_sim.c hw/palm.c hw/pc87312.c hw/pc87312.h hw/pc_piix.c hw/petalogix_ml605_mmu.c hw/petalogix_s3adsp1800_mmu.c hw/ppc hw/ppc405_boards.c hw/ppc440_bamboo.c hw/ppc_newworld.c hw/ppc_oldworld.c hw/ppc_prep.c hw/ppce500_spin.c hw/puv3.c hw/pxa.h hw/pxa2xx.c hw/pxa2xx_gpio.c hw/qdev-addr.c hw/qdev-core.h hw/qdev-properties-system.c hw/qdev-pro perties.c hw/qdev.c hw/r2d.c hw/realview.c hw/s390-virtio.c hw/scsi-disk.c hw/shix.c hw/spapr.c hw/spapr_hcall.c hw/spapr_rtas.c hw/spitz.c hw/stellaris.c hw/sun4m.c hw/sun4u.c hw/tosa.c hw/versatilepb.c hw/vexpress.c hw/virtex_ml507.c hw/xen_disk.c hw/xen_machine_pv.c hw/xen_platform.c hw/xics.c hw/xilinx_zynq.c hw/xtensa_lx60.c hw/xtensa_sim.c hw/z2.c include/exec include/qom include/sysemu kvm-all.c kvm-stub.c monitor.c qga/channel-posix.c qga/main.c qga/qapi-schema.json qom/object.c target-alpha/translate.c target-arm/cpu.c target-arm/helper.c target-cris/cpu.c target-i386/cpu.c target-i386/cpu.h target-i386/helper.c target-i386/machine.c target-i386/misc_helper.c target-i386/seg_helper.c target-lm32/cpu.c target-m68k/cpu.c target-microblaze/cpu.c target-mips/cpu.c target-mips/op_helper.c target-mips/translate.c target-openrisc/cpu.c target-ppc/kvm.c target-ppc/kvm_ppc.h target-ppc/translate_init.c target-s390x/cpu.c target-sh4/cpu.c target-sparc/cpu.c ui/sdl_zoom.c ui/s dl_zoom_template.h util/acl.c util/oslib-win32.c vl.c xen-all.c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Tue Jan 15 22:41:48 PST 2013


 .gitignore                    |    1 
 block.c                       |   12 +-
 block/mirror.c                |    2 
 block/qcow2.c                 |    2 
 block/raw-aio.h               |    5 
 block/raw-posix.c             |  125 +++++++++++++++-----
 block/sheepdog.c              |   91 ++++++---------
 block/win32-aio.c             |    2 
 configure                     |   24 +++-
 cpus.c                        |   24 ++--
 exec.c                        |   19 +--
 gdbstub.c                     |    3 
 hw/acpi_piix4.c               |   92 ++++++---------
 hw/alpha_dp264.c              |    1 
 hw/alpha_typhoon.c            |    4 
 hw/an5206.c                   |    1 
 hw/arm_gic.c                  |    3 
 hw/arm_mptimer.c              |    8 -
 hw/axis_dev88.c               |    1 
 hw/boards.h                   |    4 
 hw/collie.c                   |    1 
 hw/dma.c                      |   22 +--
 hw/dummy_m68k.c               |    1 
 hw/exynos4_boards.c           |    2 
 hw/gumstix.c                  |    2 
 hw/highbank.c                 |    1 
 hw/ide/core.c                 |   79 +++++++++----
 hw/integratorcp.c             |    1 
 hw/kzm.c                      |    1 
 hw/leon3.c                    |    1 
 hw/lm32_boards.c              |    6 -
 hw/mainstone.c                |    1 
 hw/mcf5208.c                  |    1 
 hw/milkymist.c                |    3 
 hw/mips_fulong2e.c            |    1 
 hw/mips_jazz.c                |    2 
 hw/mips_malta.c               |   10 +
 hw/mips_mipssim.c             |    1 
 hw/mips_r4k.c                 |    1 
 hw/musicpal.c                 |    1 
 hw/nseries.c                  |    2 
 hw/null-machine.c             |    1 
 hw/omap_sx1.c                 |    2 
 hw/openpic.c                  |    5 
 hw/openrisc_sim.c             |    1 
 hw/palm.c                     |    1 
 hw/pc87312.c                  |   64 ++++++----
 hw/pc87312.h                  |    2 
 hw/pc_piix.c                  |   13 ++
 hw/petalogix_ml605_mmu.c      |    3 
 hw/petalogix_s3adsp1800_mmu.c |    3 
 hw/ppc/e500.c                 |   17 +-
 hw/ppc/e500plat.c             |    1 
 hw/ppc/mpc8544ds.c            |    1 
 hw/ppc405_boards.c            |    1 
 hw/ppc440_bamboo.c            |    1 
 hw/ppc_newworld.c             |    1 
 hw/ppc_oldworld.c             |    1 
 hw/ppc_prep.c                 |    1 
 hw/ppce500_spin.c             |    8 -
 hw/puv3.c                     |    1 
 hw/pxa.h                      |    2 
 hw/pxa2xx.c                   |    4 
 hw/pxa2xx_gpio.c              |    7 -
 hw/qdev-addr.c                |    2 
 hw/qdev-core.h                |   70 ++++++++++-
 hw/qdev-properties-system.c   |    4 
 hw/qdev-properties.c          |   24 ++--
 hw/qdev.c                     |  104 ++++++++++++-----
 hw/r2d.c                      |    1 
 hw/realview.c                 |    4 
 hw/s390-virtio.c              |    1 
 hw/scsi-disk.c                |    4 
 hw/shix.c                     |    1 
 hw/spapr.c                    |   18 ++-
 hw/spapr_hcall.c              |    4 
 hw/spapr_rtas.c               |    8 -
 hw/spitz.c                    |    4 
 hw/stellaris.c                |    2 
 hw/sun4m.c                    |   12 ++
 hw/sun4u.c                    |    3 
 hw/tosa.c                     |    1 
 hw/versatilepb.c              |    2 
 hw/vexpress.c                 |    2 
 hw/virtex_ml507.c             |    1 
 hw/xen_disk.c                 |  208 ++++++++++++++++++++++++++++++----
 hw/xen_machine_pv.c           |    1 
 hw/xen_platform.c             |   21 +--
 hw/xics.c                     |   22 ++-
 hw/xilinx_zynq.c              |    3 
 hw/xtensa_lx60.c              |    2 
 hw/xtensa_sim.c               |    1 
 hw/z2.c                       |    1 
 include/exec/cpu-all.h        |    1 
 include/exec/cpu-defs.h       |    4 
 include/exec/gdbstub.h        |    3 
 include/qom/cpu.h             |   19 +++
 include/qom/object.h          |    2 
 include/sysemu/kvm.h          |   19 ++-
 kvm-all.c                     |   10 +
 kvm-stub.c                    |    2 
 monitor.c                     |   19 ++-
 qga/channel-posix.c           |   13 +-
 qga/main.c                    |   24 +++-
 qga/qapi-schema.json          |    4 
 qom/object.c                  |    2 
 target-alpha/translate.c      |    2 
 target-arm/cpu.c              |    2 
 target-arm/helper.c           |    3 
 target-cris/cpu.c             |    2 
 target-i386/cpu.c             |  252 +++++++++++++++++++++++++-----------------
 target-i386/cpu.h             |   38 +++++-
 target-i386/helper.c          |  102 ++++++++++-------
 target-i386/machine.c         |    5 
 target-i386/misc_helper.c     |   11 +
 target-i386/seg_helper.c      |    9 -
 target-lm32/cpu.c             |    2 
 target-m68k/cpu.c             |    2 
 target-microblaze/cpu.c       |    2 
 target-mips/cpu.c             |    8 +
 target-mips/op_helper.c       |   33 +++--
 target-mips/translate.c       |   17 +-
 target-openrisc/cpu.c         |    2 
 target-ppc/kvm.c              |   12 +-
 target-ppc/kvm_ppc.h          |    4 
 target-ppc/translate_init.c   |   10 +
 target-s390x/cpu.c            |    2 
 target-sh4/cpu.c              |    2 
 target-sparc/cpu.c            |    2 
 ui/sdl_zoom.c                 |    9 -
 ui/sdl_zoom_template.h        |   16 --
 util/acl.c                    |    7 -
 util/oslib-win32.c            |    4 
 vl.c                          |    6 -
 xen-all.c                     |    4 
 135 files changed, 1320 insertions(+), 608 deletions(-)

New commits:
commit 249d41720b7dfbb5951b430b9eefdbee7464f515
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Jan 9 03:58:11 2013 +0100

    qdev: Prepare "realized" property
    
    Introduce the QOM realizefn suggested by Anthony.
    Detailed documentation is supplied in the qdev header.
    
    For now this implements a default DeviceClass::realize callback that
    just wraps DeviceClass::init, which it deprecates.
    Once all devices have been converted to DeviceClass::realize,
    DeviceClass::init is to be removed.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Cc: Anthony Liguori <anthony at codemonkey.ws>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/qdev-core.h b/hw/qdev-core.h
index cb6b30b..3d75ae2 100644
--- a/hw/qdev-core.h
+++ b/hw/qdev-core.h
@@ -20,11 +20,59 @@ enum {
 typedef int (*qdev_initfn)(DeviceState *dev);
 typedef int (*qdev_event)(DeviceState *dev);
 typedef void (*qdev_resetfn)(DeviceState *dev);
+typedef void (*DeviceRealize)(DeviceState *dev, Error **errp);
+typedef void (*DeviceUnrealize)(DeviceState *dev, Error **errp);
 
 struct VMStateDescription;
 
+/**
+ * DeviceClass:
+ * @props: Properties accessing state fields.
+ * @realize: Callback function invoked when the #DeviceState:realized
+ * property is changed to %true. The default invokes @init if not %NULL.
+ * @unrealize: Callback function invoked when the #DeviceState:realized
+ * property is changed to %false.
+ * @init: Callback function invoked when the #DeviceState::realized property
+ * is changed to %true. Deprecated, new types inheriting directly from
+ * TYPE_DEVICE should use @realize instead, new leaf types should consult
+ * their respective parent type.
+ *
+ * # Realization #
+ * Devices are constructed in two stages,
+ * 1) object instantiation via object_initialize() and
+ * 2) device realization via #DeviceState:realized property.
+ * The former may not fail (it might assert or exit), the latter may return
+ * error information to the caller and must be re-entrant.
+ * Trivial field initializations should go into #TypeInfo.instance_init.
+ * Operations depending on @props static properties should go into @realize.
+ * After successful realization, setting static properties will fail.
+ *
+ * As an interim step, the #DeviceState:realized property is set by deprecated
+ * functions qdev_init() and qdev_init_nofail().
+ * In the future, devices will propagate this state change to their children
+ * and along busses they expose.
+ * The point in time will be deferred to machine creation, so that values
+ * set in @realize will not be introspectable beforehand. Therefore devices
+ * must not create children during @realize; they should initialize them via
+ * object_initialize() in their own #TypeInfo.instance_init and forward the
+ * realization events appropriately.
+ *
+ * The @init callback is considered private to a particular bus implementation
+ * (immediate abstract child types of TYPE_DEVICE). Derived leaf types set an
+ * "init" callback on their parent class instead.
+ * Any type may override the @realize and/or @unrealize callbacks but needs
+ * to call (and thus save) the parent type's implementation if so desired.
+ * Usually this means storing the previous value of, e.g., @realized inside
+ * the type's class structure and overwriting it with a function that first
+ * invokes the stored callback, then performs any additional steps.
+ * If a type derived directly from TYPE_DEVICE implements @realize, it does
+ * not need to implement @init and therefore does not need to store and call
+ * #DeviceClass' default @realize callback.
+ */
 typedef struct DeviceClass {
+    /*< private >*/
     ObjectClass parent_class;
+    /*< public >*/
 
     const char *fw_name;
     const char *desc;
@@ -33,12 +81,14 @@ typedef struct DeviceClass {
 
     /* callbacks */
     void (*reset)(DeviceState *dev);
+    DeviceRealize realize;
+    DeviceUnrealize unrealize;
 
     /* device state */
     const struct VMStateDescription *vmsd;
 
     /* Private to qdev / bus.  */
-    qdev_initfn init;
+    qdev_initfn init; /* TODO remove, once users are converted to realize */
     qdev_event unplug;
     qdev_event exit;
     const char *bus_type;
diff --git a/hw/qdev.c b/hw/qdev.c
index 37a083d..9761016 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -148,37 +148,30 @@ DeviceState *qdev_try_create(BusState *bus, const char *type)
    Return 0 on success.  */
 int qdev_init(DeviceState *dev)
 {
-    DeviceClass *dc = DEVICE_GET_CLASS(dev);
-    int rc;
+    Error *local_err = NULL;
 
     assert(!dev->realized);
 
-    rc = dc->init(dev);
-    if (rc < 0) {
+    object_property_set_bool(OBJECT(dev), true, "realized", &local_err);
+    if (local_err != NULL) {
+        error_free(local_err);
         qdev_free(dev);
-        return rc;
+        return -1;
     }
+    return 0;
+}
 
-    if (!OBJECT(dev)->parent) {
-        static int unattached_count = 0;
-        gchar *name = g_strdup_printf("device[%d]", unattached_count++);
-
-        object_property_add_child(container_get(qdev_get_machine(),
-                                                "/unattached"),
-                                  name, OBJECT(dev), NULL);
-        g_free(name);
-    }
+static void device_realize(DeviceState *dev, Error **err)
+{
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
 
-    if (qdev_get_vmsd(dev)) {
-        vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
-                                       dev->instance_id_alias,
-                                       dev->alias_required_for_version);
-    }
-    dev->realized = true;
-    if (dev->hotplugged) {
-        device_reset(dev);
+    if (dc->init) {
+        int rc = dc->init(dev);
+        if (rc < 0) {
+            error_setg(err, "Device initialization failed.");
+            return;
+        }
     }
-    return 0;
 }
 
 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
@@ -641,6 +634,55 @@ void qdev_property_add_static(DeviceState *dev, Property *prop,
     assert_no_error(local_err);
 }
 
+static bool device_get_realized(Object *obj, Error **err)
+{
+    DeviceState *dev = DEVICE(obj);
+    return dev->realized;
+}
+
+static void device_set_realized(Object *obj, bool value, Error **err)
+{
+    DeviceState *dev = DEVICE(obj);
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+    Error *local_err = NULL;
+
+    if (value && !dev->realized) {
+        if (dc->realize) {
+            dc->realize(dev, &local_err);
+        }
+
+        if (!obj->parent && local_err == NULL) {
+            static int unattached_count;
+            gchar *name = g_strdup_printf("device[%d]", unattached_count++);
+
+            object_property_add_child(container_get(qdev_get_machine(),
+                                                    "/unattached"),
+                                      name, obj, &local_err);
+            g_free(name);
+        }
+
+        if (qdev_get_vmsd(dev) && local_err == NULL) {
+            vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
+                                           dev->instance_id_alias,
+                                           dev->alias_required_for_version);
+        }
+        if (dev->hotplugged && local_err == NULL) {
+            device_reset(dev);
+        }
+    } else if (!value && dev->realized) {
+        if (dc->unrealize) {
+            dc->unrealize(dev, &local_err);
+        }
+    }
+
+    if (local_err != NULL) {
+        error_propagate(err, local_err);
+        return;
+    }
+
+    dev->realized = value;
+}
+
 static void device_initfn(Object *obj)
 {
     DeviceState *dev = DEVICE(obj);
@@ -655,6 +697,9 @@ static void device_initfn(Object *obj)
     dev->instance_id_alias = -1;
     dev->realized = false;
 
+    object_property_add_bool(obj, "realized",
+                             device_get_realized, device_set_realized, NULL);
+
     class = object_get_class(OBJECT(dev));
     do {
         for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
@@ -714,7 +759,10 @@ static void device_unparent(Object *obj)
 
 static void device_class_init(ObjectClass *class, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(class);
+
     class->unparent = device_unparent;
+    dc->realize = device_realize;
 }
 
 void device_reset(DeviceState *dev)
commit 7983c8a335dd09fec49f99a44d4404aa87828c0a
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Jan 9 03:58:10 2013 +0100

    qdev: Fold state enum into bool realized
    
    Whether the device was initialized or not is QOM-level information and
    currently unused. Drop it from device. This leaves the boolean state of
    whether or not DeviceClass::init was called or not, a.k.a. "realized".
    
    Suggested-by: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c
index 3bfe101..b4388f6 100644
--- a/hw/qdev-addr.c
+++ b/hw/qdev-addr.c
@@ -40,7 +40,7 @@ static void set_taddr(Object *obj, Visitor *v, void *opaque,
     Error *local_err = NULL;
     int64_t value;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (dev->realized) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
diff --git a/hw/qdev-core.h b/hw/qdev-core.h
index 853bd08..cb6b30b 100644
--- a/hw/qdev-core.h
+++ b/hw/qdev-core.h
@@ -8,11 +8,6 @@
 #include "hw/irq.h"
 #include "qapi/error.h"
 
-enum DevState {
-    DEV_STATE_CREATED = 1,
-    DEV_STATE_INITIALIZED,
-};
-
 enum {
     DEV_NVECTORS_UNSPECIFIED = -1,
 };
@@ -49,13 +44,20 @@ typedef struct DeviceClass {
     const char *bus_type;
 } DeviceClass;
 
-/* This structure should not be accessed directly.  We declare it here
-   so that it can be embedded in individual device state structures.  */
+/**
+ * DeviceState:
+ * @realized: Indicates whether the device has been fully constructed.
+ *
+ * This structure should not be accessed directly.  We declare it here
+ * so that it can be embedded in individual device state structures.
+ */
 struct DeviceState {
+    /*< private >*/
     Object parent_obj;
+    /*< public >*/
 
     const char *id;
-    enum DevState state;
+    bool realized;
     QemuOpts *opts;
     int hotplugged;
     BusState *parent_bus;
diff --git a/hw/qdev-properties-system.c b/hw/qdev-properties-system.c
index c73c713..ce0f793 100644
--- a/hw/qdev-properties-system.c
+++ b/hw/qdev-properties-system.c
@@ -42,7 +42,7 @@ static void set_pointer(Object *obj, Visitor *v, Property *prop,
     char *str;
     int ret;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (dev->realized) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -254,7 +254,7 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque,
     int32_t id;
     NetClientState *hubport;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (dev->realized) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index f724357..a8a31f5 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -32,7 +32,7 @@ static void set_enum(Object *obj, Visitor *v, void *opaque,
     Property *prop = opaque;
     int *ptr = qdev_get_prop_ptr(dev, prop);
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (dev->realized) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -85,7 +85,7 @@ static void set_bit(Object *obj, Visitor *v, void *opaque,
     Error *local_err = NULL;
     bool value;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (dev->realized) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -125,7 +125,7 @@ static void set_uint8(Object *obj, Visitor *v, void *opaque,
     Property *prop = opaque;
     uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (dev->realized) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -192,7 +192,7 @@ static void set_uint16(Object *obj, Visitor *v, void *opaque,
     Property *prop = opaque;
     uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (dev->realized) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -225,7 +225,7 @@ static void set_uint32(Object *obj, Visitor *v, void *opaque,
     Property *prop = opaque;
     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (dev->realized) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -250,7 +250,7 @@ static void set_int32(Object *obj, Visitor *v, void *opaque,
     Property *prop = opaque;
     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (dev->realized) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -323,7 +323,7 @@ static void set_uint64(Object *obj, Visitor *v, void *opaque,
     Property *prop = opaque;
     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (dev->realized) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -413,7 +413,7 @@ static void set_string(Object *obj, Visitor *v, void *opaque,
     Error *local_err = NULL;
     char *str;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (dev->realized) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -477,7 +477,7 @@ static void set_mac(Object *obj, Visitor *v, void *opaque,
     int i, pos;
     char *str, *p;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (dev->realized) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -569,7 +569,7 @@ static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
     Error *local_err = NULL;
     char *str;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (dev->realized) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -640,7 +640,7 @@ static void set_blocksize(Object *obj, Visitor *v, void *opaque,
     const int64_t min = 512;
     const int64_t max = 32768;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (dev->realized) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -708,7 +708,7 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
     unsigned long dom = 0, bus = 0;
     unsigned int slot = 0, func = 0;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (dev->realized) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
diff --git a/hw/qdev.c b/hw/qdev.c
index 1b68d02..37a083d 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -151,7 +151,7 @@ int qdev_init(DeviceState *dev)
     DeviceClass *dc = DEVICE_GET_CLASS(dev);
     int rc;
 
-    assert(dev->state == DEV_STATE_CREATED);
+    assert(!dev->realized);
 
     rc = dc->init(dev);
     if (rc < 0) {
@@ -174,7 +174,7 @@ int qdev_init(DeviceState *dev)
                                        dev->instance_id_alias,
                                        dev->alias_required_for_version);
     }
-    dev->state = DEV_STATE_INITIALIZED;
+    dev->realized = true;
     if (dev->hotplugged) {
         device_reset(dev);
     }
@@ -184,7 +184,7 @@ int qdev_init(DeviceState *dev)
 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
                                  int required_for_version)
 {
-    assert(dev->state == DEV_STATE_CREATED);
+    assert(!dev->realized);
     dev->instance_id_alias = alias_id;
     dev->alias_required_for_version = required_for_version;
 }
@@ -546,7 +546,7 @@ static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
     char *ptr = NULL;
     int ret;
 
-    if (dev->state != DEV_STATE_CREATED) {
+    if (dev->realized) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
@@ -653,7 +653,7 @@ static void device_initfn(Object *obj)
     }
 
     dev->instance_id_alias = -1;
-    dev->state = DEV_STATE_CREATED;
+    dev->realized = false;
 
     class = object_get_class(OBJECT(dev));
     do {
@@ -676,7 +676,7 @@ static void device_finalize(Object *obj)
     BusState *bus;
     DeviceClass *dc = DEVICE_GET_CLASS(dev);
 
-    if (dev->state == DEV_STATE_INITIALIZED) {
+    if (dev->realized) {
         while (dev->num_child_bus) {
             bus = QLIST_FIRST(&dev->child_bus);
             qbus_free(bus);
commit 2c9ee0291f8ca7e18f8e96a34e8f4be7867219d2
Author: Avik Sil <aviksil at linux.vnet.ibm.com>
Date:   Tue Jan 8 12:36:31 2013 +0530

    pseries: set no default boot order
    
    This patch removes the default boot order for pseries machine. This allows
    the machine to handle a NULL boot order in case no -boot option is provided.
    Thus it helps SLOF firmware to verify if boot order is specified in command
    line or not. If no boot order is provided SLOF tries to boot from the
    device set in the nvram.
    
    Reviewed-by: Anthony Liguori <aliguori at us.ibm.com>
    Acked-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Avik Sil <aviksil at linux.vnet.ibm.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/spapr.c b/hw/spapr.c
index 6476598..21c261b 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -287,7 +287,9 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
 
         _FDT((fdt_property(fdt, "qemu,boot-kernel", &kprop, sizeof(kprop))));
     }
-    _FDT((fdt_property_string(fdt, "qemu,boot-device", boot_device)));
+    if (boot_device) {
+        _FDT((fdt_property_string(fdt, "qemu,boot-device", boot_device)));
+    }
     _FDT((fdt_property_cell(fdt, "qemu,graphic-width", graphic_width)));
     _FDT((fdt_property_cell(fdt, "qemu,graphic-height", graphic_height)));
     _FDT((fdt_property_cell(fdt, "qemu,graphic-depth", graphic_depth)));
@@ -964,7 +966,7 @@ static QEMUMachine spapr_machine = {
     .block_default_type = IF_SCSI,
     .max_cpus = MAX_CPUS,
     .no_parallel = 1,
-    DEFAULT_MACHINE_OPTIONS,
+    .boot_order = NULL,
 };
 
 static void spapr_machine_init(void)
commit e4ada29e909787f629626660b1561f6a680187d3
Author: Avik Sil <aviksil at linux.vnet.ibm.com>
Date:   Tue Jan 8 12:36:30 2013 +0530

    Make default boot order machine specific
    
    This patch makes default boot order machine specific instead of
    set globally. The default boot order can be set per machine in
    QEMUMachine boot_order. This also allows a machine to receive a
    NULL boot order when -boot isn't used and take an appropriate action
    accordingly. This helps machine boots from the devices as set in
    guest's non-volatile memory location in case no boot order is
    provided by the user.
    
    Reviewed-by: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Avik Sil <aviksil at linux.vnet.ibm.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/alpha_dp264.c b/hw/alpha_dp264.c
index e2980e9..1cd549c 100644
--- a/hw/alpha_dp264.c
+++ b/hw/alpha_dp264.c
@@ -171,6 +171,7 @@ static QEMUMachine clipper_machine = {
     .init = clipper_init,
     .max_cpus = 4,
     .is_default = 1,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void clipper_machine_init(void)
diff --git a/hw/an5206.c b/hw/an5206.c
index dcfe34b..750115a 100644
--- a/hw/an5206.c
+++ b/hw/an5206.c
@@ -86,6 +86,7 @@ static QEMUMachine an5206_machine = {
     .name = "an5206",
     .desc = "Arnewsh 5206",
     .init = an5206_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void an5206_machine_init(void)
diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index 2ca606b..9418981 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -355,6 +355,7 @@ static QEMUMachine axisdev88_machine = {
     .desc = "AXIS devboard 88",
     .init = axisdev88_init,
     .is_default = 1,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void axisdev88_machine_init(void)
diff --git a/hw/boards.h b/hw/boards.h
index 4540e95..3ff9665 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -6,6 +6,9 @@
 #include "sysemu/blockdev.h"
 #include "qdev.h"
 
+#define DEFAULT_MACHINE_OPTIONS \
+    .boot_order = "cad"
+
 typedef struct QEMUMachineInitArgs {
     ram_addr_t ram_size;
     const char *boot_device;
@@ -35,6 +38,7 @@ typedef struct QEMUMachine {
         no_sdcard:1;
     int is_default;
     const char *default_machine_opts;
+    const char *boot_order;
     GlobalProperty *compat_props;
     struct QEMUMachine *next;
     const char *hw_version;
diff --git a/hw/collie.c b/hw/collie.c
index 804d61a..d19db59 100644
--- a/hw/collie.c
+++ b/hw/collie.c
@@ -62,6 +62,7 @@ static QEMUMachine collie_machine = {
     .name = "collie",
     .desc = "Collie PDA (SA-1110)",
     .init = collie_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void collie_machine_init(void)
diff --git a/hw/dummy_m68k.c b/hw/dummy_m68k.c
index 7878cc3..3a88805 100644
--- a/hw/dummy_m68k.c
+++ b/hw/dummy_m68k.c
@@ -73,6 +73,7 @@ static QEMUMachine dummy_m68k_machine = {
     .name = "dummy",
     .desc = "Dummy board",
     .init = dummy_m68k_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void dummy_m68k_machine_init(void)
diff --git a/hw/exynos4_boards.c b/hw/exynos4_boards.c
index b267968..968bcc3 100644
--- a/hw/exynos4_boards.c
+++ b/hw/exynos4_boards.c
@@ -150,12 +150,14 @@ static QEMUMachine exynos4_machines[EXYNOS4_NUM_OF_BOARDS] = {
         .desc = "Samsung NURI board (Exynos4210)",
         .init = nuri_init,
         .max_cpus = EXYNOS4210_NCPUS,
+        DEFAULT_MACHINE_OPTIONS,
     },
     [EXYNOS4_BOARD_SMDKC210] = {
         .name = "smdkc210",
         .desc = "Samsung SMDKC210 board (Exynos4210)",
         .init = smdkc210_init,
         .max_cpus = EXYNOS4210_NCPUS,
+        DEFAULT_MACHINE_OPTIONS,
     },
 };
 
diff --git a/hw/gumstix.c b/hw/gumstix.c
index 6fb0683..bea1605 100644
--- a/hw/gumstix.c
+++ b/hw/gumstix.c
@@ -122,12 +122,14 @@ static QEMUMachine connex_machine = {
     .name = "connex",
     .desc = "Gumstix Connex (PXA255)",
     .init = connex_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine verdex_machine = {
     .name = "verdex",
     .desc = "Gumstix Verdex (PXA270)",
     .init = verdex_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void gumstix_machine_init(void)
diff --git a/hw/highbank.c b/hw/highbank.c
index 98deca8..7bc6b44 100644
--- a/hw/highbank.c
+++ b/hw/highbank.c
@@ -331,6 +331,7 @@ static QEMUMachine highbank_machine = {
     .init = highbank_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 4,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void highbank_machine_init(void)
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index 6c824dc..9e3630a 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -512,6 +512,7 @@ static QEMUMachine integratorcp_machine = {
     .desc = "ARM Integrator/CP (ARM926EJ-S)",
     .init = integratorcp_init,
     .is_default = 1,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void integratorcp_machine_init(void)
diff --git a/hw/kzm.c b/hw/kzm.c
index fd00af9..fb33165 100644
--- a/hw/kzm.c
+++ b/hw/kzm.c
@@ -146,6 +146,7 @@ static QEMUMachine kzm_machine = {
     .name = "kzm",
     .desc = "ARM KZM Emulation Baseboard (ARM1136)",
     .init = kzm_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void kzm_machine_init(void)
diff --git a/hw/leon3.c b/hw/leon3.c
index 79b3a41..f16a8bb 100644
--- a/hw/leon3.c
+++ b/hw/leon3.c
@@ -212,6 +212,7 @@ static QEMUMachine leon3_generic_machine = {
     .name     = "leon3_generic",
     .desc     = "Leon-3 generic",
     .init     = leon3_generic_hw_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void leon3_machine_init(void)
diff --git a/hw/lm32_boards.c b/hw/lm32_boards.c
index 42e8b6b..2bc06d7 100644
--- a/hw/lm32_boards.c
+++ b/hw/lm32_boards.c
@@ -287,14 +287,16 @@ static QEMUMachine lm32_evr_machine = {
     .name = "lm32-evr",
     .desc = "LatticeMico32 EVR32 eval system",
     .init = lm32_evr_init,
-    .is_default = 1
+    .is_default = 1,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine lm32_uclinux_machine = {
     .name = "lm32-uclinux",
     .desc = "lm32 platform for uClinux and u-boot by Theobroma Systems",
     .init = lm32_uclinux_init,
-    .is_default = 0
+    .is_default = 0,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void lm32_machine_init(void)
diff --git a/hw/mainstone.c b/hw/mainstone.c
index a5ddbef..d1ff6e7 100644
--- a/hw/mainstone.c
+++ b/hw/mainstone.c
@@ -179,6 +179,7 @@ static QEMUMachine mainstone2_machine = {
     .name = "mainstone",
     .desc = "Mainstone II (PXA27x)",
     .init = mainstone_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void mainstone_machine_init(void)
diff --git a/hw/mcf5208.c b/hw/mcf5208.c
index c1816cc..2c9a5dc 100644
--- a/hw/mcf5208.c
+++ b/hw/mcf5208.c
@@ -292,6 +292,7 @@ static QEMUMachine mcf5208evb_machine = {
     .desc = "MCF5206EVB",
     .init = mcf5208evb_init,
     .is_default = 1,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void mcf5208evb_machine_init(void)
diff --git a/hw/milkymist.c b/hw/milkymist.c
index 0c23b67..c04eb35 100644
--- a/hw/milkymist.c
+++ b/hw/milkymist.c
@@ -206,7 +206,8 @@ static QEMUMachine milkymist_machine = {
     .name = "milkymist",
     .desc = "Milkymist One",
     .init = milkymist_init,
-    .is_default = 0
+    .is_default = 0,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void milkymist_machine_init(void)
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
index 4d8ee8c..8b532e1 100644
--- a/hw/mips_fulong2e.c
+++ b/hw/mips_fulong2e.c
@@ -400,6 +400,7 @@ static QEMUMachine mips_fulong2e_machine = {
     .name = "fulong2e",
     .desc = "Fulong 2e mini pc",
     .init = mips_fulong2e_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void mips_fulong2e_machine_init(void)
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index 63df2a7..72f70ca 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -325,6 +325,7 @@ static QEMUMachine mips_magnum_machine = {
     .desc = "MIPS Magnum",
     .init = mips_magnum_init,
     .block_default_type = IF_SCSI,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine mips_pica61_machine = {
@@ -332,6 +333,7 @@ static QEMUMachine mips_pica61_machine = {
     .desc = "Acer Pica 61",
     .init = mips_pica61_init,
     .block_default_type = IF_SCSI,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void mips_jazz_machine_init(void)
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 771d125..2a150df 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -1020,6 +1020,7 @@ static QEMUMachine mips_malta_machine = {
     .init = mips_malta_init,
     .max_cpus = 16,
     .is_default = 1,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void mips_malta_register_types(void)
diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c
index 67066c0..8fd6692 100644
--- a/hw/mips_mipssim.c
+++ b/hw/mips_mipssim.c
@@ -229,6 +229,7 @@ static QEMUMachine mips_mipssim_machine = {
     .name = "mipssim",
     .desc = "MIPS MIPSsim platform",
     .init = mips_mipssim_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void mips_mipssim_machine_init(void)
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 59c43e5..5df7eb4 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -302,6 +302,7 @@ static QEMUMachine mips_machine = {
     .name = "mips",
     .desc = "mips r4k platform",
     .init = mips_r4k_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void mips_machine_init(void)
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 24a1722..035865f 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1658,6 +1658,7 @@ static QEMUMachine musicpal_machine = {
     .name = "musicpal",
     .desc = "Marvell 88w8618 / MusicPal (ARM926EJ-S)",
     .init = musicpal_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void musicpal_machine_init(void)
diff --git a/hw/nseries.c b/hw/nseries.c
index d96b750..6b717cf 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -1411,12 +1411,14 @@ static QEMUMachine n800_machine = {
     .name = "n800",
     .desc = "Nokia N800 tablet aka. RX-34 (OMAP2420)",
     .init = n800_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine n810_machine = {
     .name = "n810",
     .desc = "Nokia N810 tablet aka. RX-44 (OMAP2420)",
     .init = n810_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void nseries_machine_init(void)
diff --git a/hw/null-machine.c b/hw/null-machine.c
index d813c08..bdf109f 100644
--- a/hw/null-machine.c
+++ b/hw/null-machine.c
@@ -24,6 +24,7 @@ static QEMUMachine machine_none = {
     .desc = "empty machine",
     .init = machine_none_init,
     .max_cpus = 0,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void register_machines(void)
diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c
index 0f03121..30998c5 100644
--- a/hw/omap_sx1.c
+++ b/hw/omap_sx1.c
@@ -219,12 +219,14 @@ static QEMUMachine sx1_machine_v2 = {
     .name = "sx1",
     .desc = "Siemens SX1 (OMAP310) V2",
     .init = sx1_init_v2,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine sx1_machine_v1 = {
     .name = "sx1-v1",
     .desc = "Siemens SX1 (OMAP310) V1",
     .init = sx1_init_v1,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void sx1_machine_init(void)
diff --git a/hw/openrisc_sim.c b/hw/openrisc_sim.c
index d2b2379..fb47cdc 100644
--- a/hw/openrisc_sim.c
+++ b/hw/openrisc_sim.c
@@ -139,6 +139,7 @@ static QEMUMachine openrisc_sim_machine = {
     .init = openrisc_sim_init,
     .max_cpus = 1,
     .is_default = 1,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void openrisc_sim_machine_init(void)
diff --git a/hw/palm.c b/hw/palm.c
index 5219e37..a633dfc 100644
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -280,6 +280,7 @@ static QEMUMachine palmte_machine = {
     .name = "cheetah",
     .desc = "Palm Tungsten|E aka. Cheetah PDA (OMAP310)",
     .init = palmte_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void palmte_machine_init(void)
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index e630aea..0a6923d 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -289,6 +289,7 @@ static QEMUMachine pc_i440fx_machine_v1_4 = {
     .init = pc_init_pci_1_3,
     .max_cpus = 255,
     .is_default = 1,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_1_3 \
@@ -307,6 +308,7 @@ static QEMUMachine pc_machine_v1_3 = {
         PC_COMPAT_1_3,
         { /* end of list */ }
     },
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_1_2 \
@@ -346,6 +348,7 @@ static QEMUMachine pc_machine_v1_2 = {
         PC_COMPAT_1_2,
         { /* end of list */ }
     },
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_1_1 \
@@ -389,6 +392,7 @@ static QEMUMachine pc_machine_v1_1 = {
         PC_COMPAT_1_1,
         { /* end of list */ }
     },
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_1_0 \
@@ -425,6 +429,7 @@ static QEMUMachine pc_machine_v1_0 = {
         { /* end of list */ }
     },
     .hw_version = "1.0",
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_0_15 \
@@ -440,6 +445,7 @@ static QEMUMachine pc_machine_v0_15 = {
         { /* end of list */ }
     },
     .hw_version = "0.15",
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_0_14 \
@@ -481,6 +487,7 @@ static QEMUMachine pc_machine_v0_14 = {
         { /* end of list */ }
     },
     .hw_version = "0.14",
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_0_13 \
@@ -518,6 +525,7 @@ static QEMUMachine pc_machine_v0_13 = {
         { /* end of list */ }
     },
     .hw_version = "0.13",
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_0_12 \
@@ -551,6 +559,7 @@ static QEMUMachine pc_machine_v0_12 = {
         { /* end of list */ }
     },
     .hw_version = "0.12",
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_0_11 \
@@ -584,6 +593,7 @@ static QEMUMachine pc_machine_v0_11 = {
         { /* end of list */ }
     },
     .hw_version = "0.11",
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine pc_machine_v0_10 = {
@@ -617,6 +627,7 @@ static QEMUMachine pc_machine_v0_10 = {
         { /* end of list */ }
     },
     .hw_version = "0.10",
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine isapc_machine = {
@@ -632,6 +643,7 @@ static QEMUMachine isapc_machine = {
         },
         { /* end of list */ }
     },
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 #ifdef CONFIG_XEN
@@ -641,6 +653,7 @@ static QEMUMachine xenfv_machine = {
     .init = pc_xen_hvm_init,
     .max_cpus = HVM_MAX_VCPUS,
     .default_machine_opts = "accel=xen",
+    DEFAULT_MACHINE_OPTIONS,
 };
 #endif
 
diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c
index 1cfdb2f..9cad074 100644
--- a/hw/petalogix_ml605_mmu.c
+++ b/hw/petalogix_ml605_mmu.c
@@ -173,7 +173,8 @@ static QEMUMachine petalogix_ml605_machine = {
     .name = "petalogix-ml605",
     .desc = "PetaLogix linux refdesign for xilinx ml605 little endian",
     .init = petalogix_ml605_init,
-    .is_default = 0
+    .is_default = 0,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void petalogix_ml605_machine_init(void)
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index 27ecfe7..8605fb8 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -115,7 +115,8 @@ static QEMUMachine petalogix_s3adsp1800_machine = {
     .name = "petalogix-s3adsp1800",
     .desc = "PetaLogix linux refdesign for xilinx Spartan 3ADSP1800",
     .init = petalogix_s3adsp1800_init,
-    .is_default = 1
+    .is_default = 1,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void petalogix_s3adsp1800_machine_init(void)
diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c
index 4deb02a..2dcc4a9 100644
--- a/hw/ppc/e500plat.c
+++ b/hw/ppc/e500plat.c
@@ -54,6 +54,7 @@ static QEMUMachine e500plat_machine = {
     .desc = "generic paravirt e500 platform",
     .init = e500plat_init,
     .max_cpus = 15,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void e500plat_machine_init(void)
diff --git a/hw/ppc/mpc8544ds.c b/hw/ppc/mpc8544ds.c
index f9ae20f..8e05e55 100644
--- a/hw/ppc/mpc8544ds.c
+++ b/hw/ppc/mpc8544ds.c
@@ -54,6 +54,7 @@ static QEMUMachine ppce500_machine = {
     .desc = "mpc8544ds",
     .init = mpc8544ds_init,
     .max_cpus = 15,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void ppce500_machine_init(void)
diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c
index 8f7f0d0..45ed376 100644
--- a/hw/ppc405_boards.c
+++ b/hw/ppc405_boards.c
@@ -649,6 +649,7 @@ static QEMUMachine taihu_machine = {
     .name = "taihu",
     .desc = "taihu",
     .init = taihu_405ep_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void ppc405_machine_init(void)
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index d1e4f0e..73b5ac7 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -295,6 +295,7 @@ static QEMUMachine bamboo_machine = {
     .name = "bamboo",
     .desc = "bamboo",
     .init = bamboo_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void bamboo_machine_init(void)
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index fabcc08..7a465a7 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -442,6 +442,7 @@ static QEMUMachine core99_machine = {
 #ifdef TARGET_PPC64
     .is_default = 1,
 #endif
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void core99_machine_init(void)
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index fff5129..de34e75 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -341,6 +341,7 @@ static QEMUMachine heathrow_machine = {
 #ifndef TARGET_PPC64
     .is_default = 1,
 #endif
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void heathrow_machine_init(void)
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 417583a..a35fbed 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -669,6 +669,7 @@ static QEMUMachine prep_machine = {
     .desc = "PowerPC PREP platform",
     .init = ppc_prep_init,
     .max_cpus = MAX_CPUS,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void prep_machine_init(void)
diff --git a/hw/puv3.c b/hw/puv3.c
index 7814bc5..c722510 100644
--- a/hw/puv3.c
+++ b/hw/puv3.c
@@ -124,6 +124,7 @@ static QEMUMachine puv3_machine = {
     .desc = "PKUnity Version-3 based on UniCore32",
     .init = puv3_init,
     .is_default = 1,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void puv3_machine_init(void)
diff --git a/hw/r2d.c b/hw/r2d.c
index 7cf1893..72b593f 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -347,6 +347,7 @@ static QEMUMachine r2d_machine = {
     .name = "r2d",
     .desc = "r2d-plus board",
     .init = r2d_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void r2d_machine_init(void)
diff --git a/hw/realview.c b/hw/realview.c
index 872b3b4..cecb67e 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -365,6 +365,7 @@ static QEMUMachine realview_eb_machine = {
     .desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)",
     .init = realview_eb_init,
     .block_default_type = IF_SCSI,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine realview_eb_mpcore_machine = {
@@ -373,12 +374,14 @@ static QEMUMachine realview_eb_mpcore_machine = {
     .init = realview_eb_mpcore_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 4,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine realview_pb_a8_machine = {
     .name = "realview-pb-a8",
     .desc = "ARM RealView Platform Baseboard for Cortex-A8",
     .init = realview_pb_a8_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine realview_pbx_a9_machine = {
@@ -387,6 +390,7 @@ static QEMUMachine realview_pbx_a9_machine = {
     .init = realview_pbx_a9_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 4,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void realview_machine_init(void)
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 2082776..0e93cc3 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -330,6 +330,7 @@ static QEMUMachine s390_machine = {
     .use_virtcon = 1,
     .max_cpus = 255,
     .is_default = 1,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void s390_machine_init(void)
diff --git a/hw/shix.c b/hw/shix.c
index 86d703a..6f2d55a 100644
--- a/hw/shix.c
+++ b/hw/shix.c
@@ -92,6 +92,7 @@ static QEMUMachine shix_machine = {
     .desc = "shix card",
     .init = shix_init,
     .is_default = 1,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void shix_machine_init(void)
diff --git a/hw/spapr.c b/hw/spapr.c
index 76aa09b..6476598 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -964,6 +964,7 @@ static QEMUMachine spapr_machine = {
     .block_default_type = IF_SCSI,
     .max_cpus = MAX_CPUS,
     .no_parallel = 1,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void spapr_machine_init(void)
diff --git a/hw/spitz.c b/hw/spitz.c
index f1659c4..ab7ca80 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -959,24 +959,28 @@ static QEMUMachine akitapda_machine = {
     .name = "akita",
     .desc = "Akita PDA (PXA270)",
     .init = akita_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine spitzpda_machine = {
     .name = "spitz",
     .desc = "Spitz PDA (PXA270)",
     .init = spitz_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine borzoipda_machine = {
     .name = "borzoi",
     .desc = "Borzoi PDA (PXA270)",
     .init = borzoi_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine terrierpda_machine = {
     .name = "terrier",
     .desc = "Terrier PDA (PXA270)",
     .init = terrier_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void spitz_machine_init(void)
diff --git a/hw/stellaris.c b/hw/stellaris.c
index 12e4568..b5e78ff 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -1331,12 +1331,14 @@ static QEMUMachine lm3s811evb_machine = {
     .name = "lm3s811evb",
     .desc = "Stellaris LM3S811EVB",
     .init = lm3s811evb_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine lm3s6965evb_machine = {
     .name = "lm3s6965evb",
     .desc = "Stellaris LM3S6965EVB",
     .init = lm3s6965evb_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void stellaris_machine_init(void)
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 5925d29..6f5de44 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -1428,6 +1428,7 @@ static QEMUMachine ss5_machine = {
     .init = ss5_init,
     .block_default_type = IF_SCSI,
     .is_default = 1,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine ss10_machine = {
@@ -1436,6 +1437,7 @@ static QEMUMachine ss10_machine = {
     .init = ss10_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 4,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine ss600mp_machine = {
@@ -1444,6 +1446,7 @@ static QEMUMachine ss600mp_machine = {
     .init = ss600mp_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 4,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine ss20_machine = {
@@ -1452,6 +1455,7 @@ static QEMUMachine ss20_machine = {
     .init = ss20_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 4,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine voyager_machine = {
@@ -1459,6 +1463,7 @@ static QEMUMachine voyager_machine = {
     .desc = "Sun4m platform, SPARCstation Voyager",
     .init = vger_init,
     .block_default_type = IF_SCSI,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine ss_lx_machine = {
@@ -1466,6 +1471,7 @@ static QEMUMachine ss_lx_machine = {
     .desc = "Sun4m platform, SPARCstation LX",
     .init = ss_lx_init,
     .block_default_type = IF_SCSI,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine ss4_machine = {
@@ -1473,6 +1479,7 @@ static QEMUMachine ss4_machine = {
     .desc = "Sun4m platform, SPARCstation 4",
     .init = ss4_init,
     .block_default_type = IF_SCSI,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine scls_machine = {
@@ -1480,6 +1487,7 @@ static QEMUMachine scls_machine = {
     .desc = "Sun4m platform, SPARCClassic",
     .init = scls_init,
     .block_default_type = IF_SCSI,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine sbook_machine = {
@@ -1487,6 +1495,7 @@ static QEMUMachine sbook_machine = {
     .desc = "Sun4m platform, SPARCbook",
     .init = sbook_init,
     .block_default_type = IF_SCSI,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static const struct sun4d_hwdef sun4d_hwdefs[] = {
@@ -1711,6 +1720,7 @@ static QEMUMachine ss1000_machine = {
     .init = ss1000_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 8,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine ss2000_machine = {
@@ -1719,6 +1729,7 @@ static QEMUMachine ss2000_machine = {
     .init = ss2000_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 20,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static const struct sun4c_hwdef sun4c_hwdefs[] = {
@@ -1897,6 +1908,7 @@ static QEMUMachine ss2_machine = {
     .desc = "Sun4c platform, SPARCstation 2",
     .init = ss2_init,
     .block_default_type = IF_SCSI,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void sun4m_register_types(void)
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 3a06d70..cb75d03 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -978,6 +978,7 @@ static QEMUMachine sun4u_machine = {
     .init = sun4u_init,
     .max_cpus = 1, // XXX for now
     .is_default = 1,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine sun4v_machine = {
@@ -985,6 +986,7 @@ static QEMUMachine sun4v_machine = {
     .desc = "Sun4v platform",
     .init = sun4v_init,
     .max_cpus = 1, // XXX for now
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine niagara_machine = {
@@ -992,6 +994,7 @@ static QEMUMachine niagara_machine = {
     .desc = "Sun4v platform, Niagara",
     .init = niagara_init,
     .max_cpus = 1, // XXX for now
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void sun4u_register_types(void)
diff --git a/hw/tosa.c b/hw/tosa.c
index 7048b79..efea109 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -251,6 +251,7 @@ static QEMUMachine tosapda_machine = {
     .name = "tosa",
     .desc = "Tosa PDA (PXA255)",
     .init = tosa_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void tosapda_machine_init(void)
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index bf72ebb..7a1b20b 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -359,6 +359,7 @@ static QEMUMachine versatilepb_machine = {
     .desc = "ARM Versatile/PB (ARM926EJ-S)",
     .init = vpb_init,
     .block_default_type = IF_SCSI,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine versatileab_machine = {
@@ -366,6 +367,7 @@ static QEMUMachine versatileab_machine = {
     .desc = "ARM Versatile/AB (ARM926EJ-S)",
     .init = vab_init,
     .block_default_type = IF_SCSI,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void versatile_machine_init(void)
diff --git a/hw/vexpress.c b/hw/vexpress.c
index 93c3176..6bbe8c3 100644
--- a/hw/vexpress.c
+++ b/hw/vexpress.c
@@ -479,6 +479,7 @@ static QEMUMachine vexpress_a9_machine = {
     .init = vexpress_a9_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 4,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine vexpress_a15_machine = {
@@ -487,6 +488,7 @@ static QEMUMachine vexpress_a15_machine = {
     .init = vexpress_a15_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 4,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void vexpress_machine_init(void)
diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c
index 78450d7..8c4e8e4 100644
--- a/hw/virtex_ml507.c
+++ b/hw/virtex_ml507.c
@@ -263,6 +263,7 @@ static QEMUMachine virtex_machine = {
     .name = "virtex-ml507",
     .desc = "Xilinx Virtex ML507 reference design",
     .init = virtex_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void virtex_machine_init(void)
diff --git a/hw/xen_machine_pv.c b/hw/xen_machine_pv.c
index 9feecd5..66e8981 100644
--- a/hw/xen_machine_pv.c
+++ b/hw/xen_machine_pv.c
@@ -115,6 +115,7 @@ static QEMUMachine xenpv_machine = {
     .init = xen_init_pv,
     .max_cpus = 1,
     .default_machine_opts = "accel=xen",
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void xenpv_machine_init(void)
diff --git a/hw/xilinx_zynq.c b/hw/xilinx_zynq.c
index da0a7d0..8dede9f 100644
--- a/hw/xilinx_zynq.c
+++ b/hw/xilinx_zynq.c
@@ -203,7 +203,8 @@ static QEMUMachine zynq_machine = {
     .init = zynq_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 1,
-    .no_sdcard = 1
+    .no_sdcard = 1,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void zynq_machine_init(void)
diff --git a/hw/xtensa_lx60.c b/hw/xtensa_lx60.c
index 0b9a528..a85fe9b 100644
--- a/hw/xtensa_lx60.c
+++ b/hw/xtensa_lx60.c
@@ -295,6 +295,7 @@ static QEMUMachine xtensa_lx60_machine = {
     .desc = "lx60 EVB (" XTENSA_DEFAULT_CPU_MODEL ")",
     .init = xtensa_lx60_init,
     .max_cpus = 4,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine xtensa_lx200_machine = {
@@ -302,6 +303,7 @@ static QEMUMachine xtensa_lx200_machine = {
     .desc = "lx200 EVB (" XTENSA_DEFAULT_CPU_MODEL ")",
     .init = xtensa_lx200_init,
     .max_cpus = 4,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void xtensa_lx_machines_init(void)
diff --git a/hw/xtensa_sim.c b/hw/xtensa_sim.c
index 14fe85b..864e57c 100644
--- a/hw/xtensa_sim.c
+++ b/hw/xtensa_sim.c
@@ -106,6 +106,7 @@ static QEMUMachine xtensa_sim_machine = {
     .is_default = true,
     .init = xtensa_sim_init,
     .max_cpus = 4,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void xtensa_sim_machine_init(void)
diff --git a/hw/z2.c b/hw/z2.c
index 496e47d..731550f 100644
--- a/hw/z2.c
+++ b/hw/z2.c
@@ -373,6 +373,7 @@ static QEMUMachine z2_machine = {
     .name = "z2",
     .desc = "Zipit Z2 (PXA27x)",
     .init = z2_init,
+    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void z2_machine_init(void)
diff --git a/vl.c b/vl.c
index 59ce063..15e0280 100644
--- a/vl.c
+++ b/vl.c
@@ -2712,7 +2712,7 @@ int main(int argc, char **argv, char **envp)
     const char *icount_option = NULL;
     const char *initrd_filename;
     const char *kernel_filename, *kernel_cmdline;
-    char boot_devices[33] = "cad"; /* default to HD->floppy->CD-ROM */
+    char boot_devices[33] = "";
     DisplayState *ds;
     int cyls, heads, secs, translation;
     QemuOpts *hda_opts = NULL, *opts, *machine_opts;
@@ -4084,7 +4084,9 @@ int main(int argc, char **argv, char **envp)
     qdev_machine_init();
 
     QEMUMachineInitArgs args = { .ram_size = ram_size,
-                                 .boot_device = boot_devices,
+                                 .boot_device = (boot_devices[0] == '\0') ?
+                                                machine->boot_order :
+                                                boot_devices,
                                  .kernel_filename = kernel_filename,
                                  .kernel_cmdline = kernel_cmdline,
                                  .initrd_filename = initrd_filename,
commit 038794cfe1c0eece8968418077e4af601acd5aff
Author: Markus Armbruster <armbru at redhat.com>
Date:   Tue Jan 15 15:24:16 2013 +0100

    acl: Free memory allocated with g_malloc() with g_free()
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/util/acl.c b/util/acl.c
index 21b2205..a7f33ff 100644
--- a/util/acl.c
+++ b/util/acl.c
@@ -103,8 +103,8 @@ void qemu_acl_reset(qemu_acl *acl)
     acl->defaultDeny = 1;
     QTAILQ_FOREACH_SAFE(entry, &acl->entries, next, next_entry) {
         QTAILQ_REMOVE(&acl->entries, entry, next);
-        free(entry->match);
-        free(entry);
+        g_free(entry->match);
+        g_free(entry);
     }
     acl->nentries = 0;
 }
commit c23c15d30b901bb447cdcada96cae64c0046d146
Author: Markus Armbruster <armbru at redhat.com>
Date:   Tue Jan 15 15:24:15 2013 +0100

    acl: Fix acl_remove not to mess up the ACL
    
    It leaks memory and fails to adjust qemu_acl member nentries.  Future
    acl_add become confused: can misreport the position, and can silently
    fail to add.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/util/acl.c b/util/acl.c
index 81ac255..21b2205 100644
--- a/util/acl.c
+++ b/util/acl.c
@@ -168,6 +168,9 @@ int qemu_acl_remove(qemu_acl *acl,
         i++;
         if (strcmp(entry->match, match) == 0) {
             QTAILQ_REMOVE(&acl->entries, entry, next);
+            acl->nentries--;
+            g_free(entry->match);
+            g_free(entry);
             return i;
         }
     }
commit cc69bda6c97a1c193348eb381f4bffdfd1c8a948
Author: Markus Armbruster <armbru at redhat.com>
Date:   Tue Jan 15 15:42:32 2013 +0100

    sdl: Fix heap smash in sdl_zoom_rgb{16,32} for int > 32 bits
    
    Careless use of malloc(): allocate Uint32[N], assign to int *, use
    int[N].
    
    Fix by converting to g_new().
    
    Functions can't fail anymore, so make them return void.  Caller
    ignored the value anyway.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/ui/sdl_zoom.c b/ui/sdl_zoom.c
index 122027c..2625c45 100644
--- a/ui/sdl_zoom.c
+++ b/ui/sdl_zoom.c
@@ -13,13 +13,14 @@
 
 #include "sdl_zoom.h"
 #include "qemu/osdep.h"
+#include <glib.h>
 #include <stdint.h>
 #include <stdio.h>
 
-static int sdl_zoom_rgb16(SDL_Surface *src, SDL_Surface *dst, int smooth,
-                          SDL_Rect *dst_rect);
-static int sdl_zoom_rgb32(SDL_Surface *src, SDL_Surface *dst, int smooth,
-                          SDL_Rect *dst_rect);
+static void sdl_zoom_rgb16(SDL_Surface *src, SDL_Surface *dst, int smooth,
+                           SDL_Rect *dst_rect);
+static void sdl_zoom_rgb32(SDL_Surface *src, SDL_Surface *dst, int smooth,
+                           SDL_Rect *dst_rect);
 
 #define BPP 32
 #include  "sdl_zoom_template.h"
diff --git a/ui/sdl_zoom_template.h b/ui/sdl_zoom_template.h
index 64bbca8..3bb508b 100644
--- a/ui/sdl_zoom_template.h
+++ b/ui/sdl_zoom_template.h
@@ -51,7 +51,7 @@
               (((a) & (dpf->Amask >> dpf->Ashift)) << dpf->Ashift); \
 } while (0);
 
-static int glue(sdl_zoom_rgb, BPP)(SDL_Surface *src, SDL_Surface *dst, int smooth,
+static void glue(sdl_zoom_rgb, BPP)(SDL_Surface *src, SDL_Surface *dst, int smooth,
                                    SDL_Rect *dst_rect)
 {
     int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep, sstep_jump;
@@ -71,13 +71,8 @@ static int glue(sdl_zoom_rgb, BPP)(SDL_Surface *src, SDL_Surface *dst, int smoot
         sy = (int) (65536.0 * (float) src->h / (float) dst->h);
     }
 
-    if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) {
-        return (-1);
-    }
-    if ((say = (int *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) {
-        free(sax);
-        return (-1);
-    }
+    sax = g_new(int, dst->w + 1);
+    say = g_new(int, dst->h + 1);
 
     sp = csp = (SDL_TYPE *) src->pixels;
     dp = (SDL_TYPE *) (dst->pixels + dst_rect->y * dst->pitch +
@@ -216,9 +211,8 @@ static int glue(sdl_zoom_rgb, BPP)(SDL_Surface *src, SDL_Surface *dst, int smoot
         }
     }
 
-    free(sax);
-    free(say);
-    return (0);
+    g_free(sax);
+    g_free(say);
 }
 
 #undef SDL_TYPE
commit dabe3143e0f36a78a65c0dce1e298e31df1be6c4
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Tue Jan 15 19:50:13 2013 +0200

    kvm: add stub for kvm_irqchip_update_msi_route
    
    ppc64 build needs this stub to build with virtio enabled.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Tested-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/kvm-all.c b/kvm-all.c
index 6e2164b..6278d61 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1181,6 +1181,11 @@ static int kvm_irqchip_assign_irqfd(KVMState *s, int fd, int virq, bool assign)
 {
     abort();
 }
+
+int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg)
+{
+    return -ENOSYS;
+}
 #endif /* !KVM_CAP_IRQ_ROUTING */
 
 int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n, int virq)
commit 8ec12ec734da08a945a05e2b0f89d2639048c771
Merge: 58a864d c3a2980
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Jan 15 16:54:41 2013 -0600

    Merge remote-tracking branch 'afaerber/memory-ioport' into staging
    
    * afaerber/memory-ioport:
      acpi_piix4: Do not use old_portio-style callbacks
      xen_platform: Do not use old_portio-style callbacks
      hw/dma.c: Fix conversion of ioport_register* to MemoryRegion
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 58a864dec23f9052a5379a3ce81566e065c14afa
Merge: b9f84ac ecbe251
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Jan 15 16:53:10 2013 -0600

    Merge remote-tracking branch 'stefanha/trivial-patches' into staging
    
    * stefanha/trivial-patches:
      configure: try pkg-config for curses
      qom: Make object_resolve_path_component() path argument const
      Add libcacard/trace/generated-tracers.c to .gitignore
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit b9f84ac0fa81315bf4efa8db64f0705273b7499a
Merge: c94bf1c 7191bf3
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Jan 15 16:52:56 2013 -0600

    Merge remote-tracking branch 'stefanha/block' into staging
    
    * stefanha/block:
      block: Fix how mirror_run() frees its buffer
      win32-aio: Fix how win32_aio_process_completion() frees buffer
      scsi-disk: qemu_vfree(NULL) is fine, simplify
      w32: Make qemu_vfree() accept NULL like the POSIX implementation
      sheepdog: clean up sd_aio_setup()
      sheepdog: multiplex the rw FD to flush cache
      block: clear dirty bitmap when discarding
      ide: issue discard asynchronously but serialize the pieces
      ide: fix TRIM with empty range entry
      block: make discard asynchronous
      raw: support discard on block devices
      raw-posix: remember whether discard failed
      raw-posix: support discard on more filesystems
      block: fix initialization in bdrv_io_limits_enable()
      qcow2: Fix segfault on zero-length write
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit c94bf1c107df6623e54d48b90fb439a1281a36de
Merge: bdb8872 e175bce
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Jan 15 16:52:39 2013 -0600

    Merge remote-tracking branch 'afaerber/qom-cpu' into staging
    
    * afaerber/qom-cpu:
      target-i386: Use switch in check_hw_breakpoints()
      target-i386: Avoid goto in hw_breakpoint_insert()
      target-i386: Introduce hw_{local,global}_breakpoint_enabled()
      target-i386: Define DR7 bit field constants
      target-i386: Move kvm_check_features_against_host() check to realize time
      target-i386: cpu_x86_register() consolidate freeing resources
      target-i386: Move setting defaults out of cpu_x86_parse_featurestr()
      target-i386: check/enforce: Check all feature words
      target-i386/cpu.c: Add feature name array for ext4_features
      target-i386: kvm_check_features_against_host(): Use feature_word_info
      target-i386/cpu: Introduce FeatureWord typedefs
      target-i386: Disable kvm_mmu by default
      kvm: Add fake KVM constants to avoid #ifdefs on KVM-specific code
      exec: Return CPUState from qemu_get_cpu()
      xen: Simplify halting of first CPU
      kvm: Pass CPUState to kvm_init_vcpu()
      cpu: Move cpu_index field to CPUState
      cpu: Move numa_node field to CPUState
      target-mips: Clean up mips_cpu_map_tc() documentation
      cpu: Move nr_{cores,threads} fields to CPUState
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit bdb8872cc14684557db4bef112b02eeb68f4410b
Merge: 2fd3402 08bb4a7
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Jan 15 16:52:10 2013 -0600

    Merge remote-tracking branch 'afaerber-or/prep-up' into staging
    
    * afaerber-or/prep-up:
      pc87312: Avoid define conflict on mingw32
      pc87312: Replace register_ioport_*() with MemoryRegion
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 2fd3402d9242dec06bb1ca5680c1ddf421932b08
Merge: dd25f93 01b87f6
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Jan 15 16:50:04 2013 -0600

    Merge remote-tracking branch 'mdroth/qga-pull-1-14-2013-2' into staging
    
    * mdroth/qga-pull-1-14-2013-2:
      qga: add missing commas in json docs
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit dd25f938203eac51ef2ec9f4a545645ff49bda70
Merge: 5e72179 7868181
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Jan 15 16:49:48 2013 -0600

    Merge remote-tracking branch 'mdroth/qga-pull-1-14-2013' into staging
    
    * mdroth/qga-pull-1-14-2013:
      qemu-ga: Handle errors uniformely in ga_channel_open()
      qemu-ga: Plug fd leak on ga_channel_open() error paths
      qemu-ga: Plug fd leak on ga_channel_listen_accept() error path
      qemu-ga: Plug file descriptor leak on ga_open_pidfile() error path
      qemu-ga: Drop pointless lseek() from ga_open_pidfile()
      qemu-ga: Document intentional fall through in channel_event_cb()
      qemu-ga: add ga_open_logfile()
      qemu-ga: ga_open_pidfile(): use qemu_open()
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 5e72179b8f16e05a33fea5f63856aa16dbb29048
Merge: cf7c3f0 7e7b7cb
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Jan 15 16:49:18 2013 -0600

    Merge remote-tracking branch 'sstabellini/xen-2013-01-14' into staging
    
    * sstabellini/xen-2013-01-14:
      xen_disk: implement BLKIF_OP_FLUSH_DISKCACHE, remove BLKIF_OP_WRITE_BARRIER
      xen_disk: add persistent grant support to xen_disk backend
      xen_disk: fix memory leak
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit c3a29809e4d8924a0cfffd7f1af3c2f3c46f5889
Author: Hervé Poussineau <hpoussin at reactos.org>
Date:   Fri Jan 4 22:29:41 2013 +0100

    acpi_piix4: Do not use old_portio-style callbacks
    
    Signed-off-by: Hervé Poussineau <hpoussin at reactos.org>
    [AF: Used HWADDR_PRIx for hwaddr PIIX4_DPRINTF()]
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 2f84b4e..0d33849 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -531,68 +531,58 @@ static const MemoryRegionOps piix4_gpe_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static uint32_t pci_up_read(void *opaque, uint32_t addr)
+static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
 {
     PIIX4PMState *s = opaque;
-    uint32_t val;
-
-    /* Manufacture an "up" value to cause a device check on any hotplug
-     * slot with a device.  Extra device checks are harmless. */
-    val = s->pci0_slot_device_present & s->pci0_hotplug_enable;
-
-    PIIX4_DPRINTF("pci_up_read %x\n", val);
-    return val;
-}
-
-static uint32_t pci_down_read(void *opaque, uint32_t addr)
-{
-    PIIX4PMState *s = opaque;
-    uint32_t val = s->pci0_status.down;
+    uint32_t val = 0;
+
+    switch (addr) {
+    case PCI_UP_BASE - PCI_HOTPLUG_ADDR:
+        /* Manufacture an "up" value to cause a device check on any hotplug
+         * slot with a device.  Extra device checks are harmless. */
+        val = s->pci0_slot_device_present & s->pci0_hotplug_enable;
+        PIIX4_DPRINTF("pci_up_read %x\n", val);
+        break;
+    case PCI_DOWN_BASE - PCI_HOTPLUG_ADDR:
+        val = s->pci0_status.down;
+        PIIX4_DPRINTF("pci_down_read %x\n", val);
+        break;
+    case PCI_EJ_BASE - PCI_HOTPLUG_ADDR:
+        /* No feature defined yet */
+        PIIX4_DPRINTF("pci_features_read %x\n", val);
+        break;
+    case PCI_RMV_BASE - PCI_HOTPLUG_ADDR:
+        val = s->pci0_hotplug_enable;
+        break;
+    default:
+        break;
+    }
 
-    PIIX4_DPRINTF("pci_down_read %x\n", val);
     return val;
 }
 
-static uint32_t pci_features_read(void *opaque, uint32_t addr)
+static void pci_write(void *opaque, hwaddr addr, uint64_t data,
+                      unsigned int size)
 {
-    /* No feature defined yet */
-    PIIX4_DPRINTF("pci_features_read %x\n", 0);
-    return 0;
-}
-
-static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
-{
-    acpi_piix_eject_slot(opaque, val);
-
-    PIIX4_DPRINTF("pciej write %x <== %d\n", addr, val);
-}
-
-static uint32_t pcirmv_read(void *opaque, uint32_t addr)
-{
-    PIIX4PMState *s = opaque;
-
-    return s->pci0_hotplug_enable;
+    switch (addr) {
+    case PCI_EJ_BASE - PCI_HOTPLUG_ADDR:
+        acpi_piix_eject_slot(opaque, (uint32_t)data);
+        PIIX4_DPRINTF("pciej write %" HWADDR_PRIx " <== % " PRIu64 "\n",
+                      addr, data);
+        break;
+    default:
+        break;
+    }
 }
 
 static const MemoryRegionOps piix4_pci_ops = {
-    .old_portio = (MemoryRegionPortio[]) {
-        {
-            .offset = PCI_UP_BASE - PCI_HOTPLUG_ADDR,   .len = 4, .size = 4,
-            .read = pci_up_read,
-        },{
-            .offset = PCI_DOWN_BASE - PCI_HOTPLUG_ADDR, .len = 4, .size = 4,
-            .read = pci_down_read,
-        },{
-            .offset = PCI_EJ_BASE - PCI_HOTPLUG_ADDR,   .len = 4, .size = 4,
-            .read = pci_features_read,
-            .write = pciej_write,
-        },{
-            .offset = PCI_RMV_BASE - PCI_HOTPLUG_ADDR,  .len = 4, .size = 4,
-            .read = pcirmv_read,
-        },
-        PORTIO_END_OF_LIST()
-    },
+    .read = pci_read,
+    .write = pci_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
 };
 
 static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
commit 7a652efa1b55ea671125696aabf8f1bd6e9a97f7
Author: Hervé Poussineau <hpoussin at reactos.org>
Date:   Fri Jan 4 22:29:40 2013 +0100

    xen_platform: Do not use old_portio-style callbacks
    
    Signed-off-by: Hervé Poussineau <hpoussin at reactos.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/xen_platform.c b/hw/xen_platform.c
index ca66047..8866468 100644
--- a/hw/xen_platform.c
+++ b/hw/xen_platform.c
@@ -279,7 +279,8 @@ static void platform_fixed_ioport_init(PCIXenPlatformState* s)
 
 /* Xen Platform PCI Device */
 
-static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)
+static uint64_t xen_platform_ioport_readb(void *opaque, hwaddr addr,
+                                          unsigned int size)
 {
     if (addr == 0) {
         return platform_fixed_ioport_readb(opaque, 0);
@@ -288,30 +289,28 @@ static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)
     }
 }
 
-static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+static void xen_platform_ioport_writeb(void *opaque, hwaddr addr,
+                                       uint64_t val, unsigned int size)
 {
     PCIXenPlatformState *s = opaque;
 
     switch (addr) {
     case 0: /* Platform flags */
-        platform_fixed_ioport_writeb(opaque, 0, val);
+        platform_fixed_ioport_writeb(opaque, 0, (uint32_t)val);
         break;
     case 8:
-        log_writeb(s, val);
+        log_writeb(s, (uint32_t)val);
         break;
     default:
         break;
     }
 }
 
-static MemoryRegionPortio xen_pci_portio[] = {
-    { 0, 0x100, 1, .read = xen_platform_ioport_readb, },
-    { 0, 0x100, 1, .write = xen_platform_ioport_writeb, },
-    PORTIO_END_OF_LIST()
-};
-
 static const MemoryRegionOps xen_pci_io_ops = {
-    .old_portio = xen_pci_portio,
+    .read  = xen_platform_ioport_readb,
+    .write = xen_platform_ioport_writeb,
+    .impl.min_access_size = 1,
+    .impl.max_access_size = 1,
 };
 
 static void platform_ioport_bar_setup(PCIXenPlatformState *d)
commit ecd584b836937eb45f7e7e487595002486a09cb7
Author: Julien Grall <julien.grall at citrix.com>
Date:   Wed Dec 19 12:09:21 2012 +0000

    hw/dma.c: Fix conversion of ioport_register* to MemoryRegion
    
    The commit 582299336879504353e60c7937fbc70fea93f3da introduced a 1-shift for
    some offset in DMA emulation.
    
    Before the previous commit, which converted ioport_register_* to
    MemoryRegion, the DMA controller registered 8 ioports with the following
    formula:
    base + ((8 + i) << d->shift) where 0 <= i < 8
    When an IO occured within a Memory Region, DMA callback receives an
    offset relative to the start address. Here the start address is:
    base + (8 << d->shift).
    The offset should be: (i << d->shift). After the shift is reverted, the
    offsets are 0..7 not 1..8.
    
    Fixes LP#1089996.
    
    Reported-by: Andreas Gustafsson <gson at gson.org>
    Signed-off-by: Julien Grall <julien.grall at citrix.com>
    Tested-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/dma.c b/hw/dma.c
index 0634baa..5bdf435 100644
--- a/hw/dma.c
+++ b/hw/dma.c
@@ -201,7 +201,7 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data,
 
     iport = (nport >> d->dshift) & 0x0f;
     switch (iport) {
-    case 0x01:                  /* command */
+    case 0x00:                  /* command */
         if ((data != 0) && (data & CMD_NOT_SUPPORTED)) {
             dolog("command %"PRIx64" not supported\n", data);
             return;
@@ -209,7 +209,7 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data,
         d->command = data;
         break;
 
-    case 0x02:
+    case 0x01:
         ichan = data & 3;
         if (data & 4) {
             d->status |= 1 << (ichan + 4);
@@ -221,7 +221,7 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data,
         DMA_run();
         break;
 
-    case 0x03:                  /* single mask */
+    case 0x02:                  /* single mask */
         if (data & 4)
             d->mask |= 1 << (data & 3);
         else
@@ -229,7 +229,7 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data,
         DMA_run();
         break;
 
-    case 0x04:                  /* mode */
+    case 0x03:                  /* mode */
         {
             ichan = data & 3;
 #ifdef DEBUG_DMA
@@ -248,23 +248,23 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data,
             break;
         }
 
-    case 0x05:                  /* clear flip flop */
+    case 0x04:                  /* clear flip flop */
         d->flip_flop = 0;
         break;
 
-    case 0x06:                  /* reset */
+    case 0x05:                  /* reset */
         d->flip_flop = 0;
         d->mask = ~0;
         d->status = 0;
         d->command = 0;
         break;
 
-    case 0x07:                  /* clear mask for all channels */
+    case 0x06:                  /* clear mask for all channels */
         d->mask = 0;
         DMA_run();
         break;
 
-    case 0x08:                  /* write mask for all channels */
+    case 0x07:                  /* write mask for all channels */
         d->mask = data;
         DMA_run();
         break;
@@ -289,11 +289,11 @@ static uint64_t read_cont(void *opaque, hwaddr nport, unsigned size)
 
     iport = (nport >> d->dshift) & 0x0f;
     switch (iport) {
-    case 0x08:                  /* status */
+    case 0x00:                  /* status */
         val = d->status;
         d->status &= 0xf0;
         break;
-    case 0x0f:                  /* mask */
+    case 0x01:                  /* mask */
         val = d->mask;
         break;
     default:
@@ -468,7 +468,7 @@ void DMA_schedule(int nchan)
 static void dma_reset(void *opaque)
 {
     struct dma_cont *d = opaque;
-    write_cont(d, (0x06 << d->dshift), 0, 1);
+    write_cont(d, (0x05 << d->dshift), 0, 1);
 }
 
 static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len)
commit ecbe251fa0eb4905c4a82c887e37057243b9fbad
Author: Vadim Evard <v.e.evard at gmail.com>
Date:   Tue Jan 15 16:17:24 2013 +0400

    configure: try pkg-config for curses
    
    Static linkikng against ncurses may require explicit -ltinfo.
    In case -lcurses and -lncurses both didn't work give pkg-config a
    chance.
    
    Fixes #1094786 for me.
    
    Signed-off-by: Vadim Evard <v.e.evard at gmail.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/configure b/configure
index c908f66..40473a9 100755
--- a/configure
+++ b/configure
@@ -2039,7 +2039,7 @@ fi
 if test "$mingw32" = "yes" ; then
     curses_list="-lpdcurses"
 else
-    curses_list="-lncurses -lcurses"
+    curses_list="-lncurses:-lcurses:$($pkg_config --libs ncurses)"
 fi
 
 if test "$curses" != "no" ; then
@@ -2052,13 +2052,16 @@ int main(void) {
   return s != 0;
 }
 EOF
+  IFS=:
   for curses_lib in $curses_list; do
+    unset IFS
     if compile_prog "" "$curses_lib" ; then
       curses_found=yes
       libs_softmmu="$curses_lib $libs_softmmu"
       break
     fi
   done
+  unset IFS
   if test "$curses_found" = "yes" ; then
     curses=yes
   else
commit 7191bf311ea9722cdcc3b2229788eff69d896bd0
Author: Markus Armbruster <armbru at redhat.com>
Date:   Tue Jan 15 15:29:10 2013 +0100

    block: Fix how mirror_run() frees its buffer
    
    It allocates with qemu_blockalign(), therefore it must free with
    qemu_vfree(), not g_free().
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/mirror.c b/block/mirror.c
index 8aeacbf..6180aa3 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -225,7 +225,7 @@ static void coroutine_fn mirror_run(void *opaque)
     }
 
 immediate_exit:
-    g_free(s->buf);
+    qemu_vfree(s->buf);
     bdrv_set_dirty_tracking(bs, false);
     bdrv_iostatus_disable(s->target);
     if (s->should_complete && ret == 0) {
commit 7479acdbce2ecf6cbd0b7d72b81608c8fc51b1ae
Author: Markus Armbruster <armbru at redhat.com>
Date:   Tue Jan 15 14:23:39 2013 +0100

    win32-aio: Fix how win32_aio_process_completion() frees buffer
    
    win32_aio_submit() allocates it with qemu_blockalign(), therefore it
    must be freed with qemu_vfree(), not g_free().
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/win32-aio.c b/block/win32-aio.c
index 46a5db7..0383370 100644
--- a/block/win32-aio.c
+++ b/block/win32-aio.c
@@ -87,7 +87,7 @@ static void win32_aio_process_completion(QEMUWin32AIOState *s,
                 memcpy(p, qiov->iov[i].iov_base, qiov->iov[i].iov_len);
                 p += qiov->iov[i].iov_len;
             }
-            g_free(waiocb->buf);
+            qemu_vfree(waiocb->buf);
         }
     }
 
commit db4c34c3df5107ec4900ff07f70c540479a7eeca
Author: Markus Armbruster <armbru at redhat.com>
Date:   Tue Jan 15 14:23:38 2013 +0100

    scsi-disk: qemu_vfree(NULL) is fine, simplify
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Acked-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index f8d7ef3..96db9a7 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -85,9 +85,7 @@ static void scsi_free_request(SCSIRequest *req)
 {
     SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
 
-    if (r->iov.iov_base) {
-        qemu_vfree(r->iov.iov_base);
-    }
+    qemu_vfree(r->iov.iov_base);
 }
 
 /* Helper function for command completion with sense.  */
commit 94c8ff3a01d9bd1005f066a0ee3fe43c842a43b7
Author: Markus Armbruster <armbru at redhat.com>
Date:   Tue Jan 15 14:23:37 2013 +0100

    w32: Make qemu_vfree() accept NULL like the POSIX implementation
    
    On POSIX, qemu_vfree() accepts NULL, because it's merely wrapper
    around free().  As far as I can tell, the Windows implementation
    doesn't.  Breeds bugs that bite only under Windows.
    
    Make the Windows implementation behave like the POSIX implementation.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index e7e283e..640194c 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -71,7 +71,9 @@ void *qemu_vmalloc(size_t size)
 void qemu_vfree(void *ptr)
 {
     trace_qemu_vfree(ptr);
-    VirtualFree(ptr, 0, MEM_RELEASE);
+    if (ptr) {
+        VirtualFree(ptr, 0, MEM_RELEASE);
+    }
 }
 
 /* FIXME: add proper locking */
commit f700f8e3463b5d61383121fa6f79564d6132b10d
Author: Liu Yuan <tailai.ly at taobao.com>
Date:   Mon Jan 14 14:01:03 2013 +0800

    sheepdog: clean up sd_aio_setup()
    
    The last two parameters of sd_aio_setup() are never used, so remove them.
    
    Cc: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
    Cc: Kevin Wolf <kwolf at redhat.com>
    Cc: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/sheepdog.c b/block/sheepdog.c
index 04661da..3e49bb8 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -427,12 +427,11 @@ static const AIOCBInfo sd_aiocb_info = {
 };
 
 static SheepdogAIOCB *sd_aio_setup(BlockDriverState *bs, QEMUIOVector *qiov,
-                                   int64_t sector_num, int nb_sectors,
-                                   BlockDriverCompletionFunc *cb, void *opaque)
+                                   int64_t sector_num, int nb_sectors)
 {
     SheepdogAIOCB *acb;
 
-    acb = qemu_aio_get(&sd_aiocb_info, bs, cb, opaque);
+    acb = qemu_aio_get(&sd_aiocb_info, bs, NULL, NULL);
 
     acb->qiov = qiov;
 
@@ -1672,7 +1671,7 @@ static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
         bs->total_sectors = sector_num + nb_sectors;
     }
 
-    acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors, NULL, NULL);
+    acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors);
     acb->aio_done_func = sd_write_done;
     acb->aiocb_type = AIOCB_WRITE_UDATA;
 
@@ -1693,7 +1692,7 @@ static coroutine_fn int sd_co_readv(BlockDriverState *bs, int64_t sector_num,
     SheepdogAIOCB *acb;
     int ret;
 
-    acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors, NULL, NULL);
+    acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors);
     acb->aiocb_type = AIOCB_READ_UDATA;
     acb->aio_done_func = sd_finish_aiocb;
 
@@ -1719,7 +1718,7 @@ static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs)
         return 0;
     }
 
-    acb = sd_aio_setup(bs, NULL, 0, 0, NULL, NULL);
+    acb = sd_aio_setup(bs, NULL, 0, 0);
     acb->aiocb_type = AIOCB_FLUSH_CACHE;
     acb->aio_done_func = sd_finish_aiocb;
 
commit 477830727821e4bc337f4ac1fd222ffe0b900e1a
Author: Liu Yuan <tailai.ly at taobao.com>
Date:   Tue Jan 15 16:28:55 2013 +0800

    sheepdog: multiplex the rw FD to flush cache
    
    This will reduce sockfds connected to the sheep server to one, which simply the
    future hacks.
    
    Cc: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
    Cc: Kevin Wolf <kwolf at redhat.com>
    Cc: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/sheepdog.c b/block/sheepdog.c
index 462c4b2..04661da 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -266,6 +266,7 @@ typedef struct AIOReq {
 enum AIOCBState {
     AIOCB_WRITE_UDATA,
     AIOCB_READ_UDATA,
+    AIOCB_FLUSH_CACHE,
 };
 
 struct SheepdogAIOCB {
@@ -299,7 +300,6 @@ typedef struct BDRVSheepdogState {
     char *addr;
     char *port;
     int fd;
-    int flush_fd;
 
     CoMutex lock;
     Coroutine *co_send;
@@ -736,6 +736,13 @@ static void coroutine_fn aio_read_response(void *opaque)
             goto out;
         }
         break;
+    case AIOCB_FLUSH_CACHE:
+        if (rsp.result == SD_RES_INVALID_PARMS) {
+            dprintf("disable cache since the server doesn't support it\n");
+            s->cache_flags = SD_FLAG_CMD_DIRECT;
+            rsp.result = SD_RES_SUCCESS;
+        }
+        break;
     }
 
     if (rsp.result != SD_RES_SUCCESS) {
@@ -950,7 +957,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
 {
     int nr_copies = s->inode.nr_copies;
     SheepdogObjReq hdr;
-    unsigned int wlen;
+    unsigned int wlen = 0;
     int ret;
     uint64_t oid = aio_req->oid;
     unsigned int datalen = aio_req->data_len;
@@ -964,18 +971,23 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
 
     memset(&hdr, 0, sizeof(hdr));
 
-    if (aiocb_type == AIOCB_READ_UDATA) {
-        wlen = 0;
+    switch (aiocb_type) {
+    case AIOCB_FLUSH_CACHE:
+        hdr.opcode = SD_OP_FLUSH_VDI;
+        break;
+    case AIOCB_READ_UDATA:
         hdr.opcode = SD_OP_READ_OBJ;
         hdr.flags = flags;
-    } else if (create) {
-        wlen = datalen;
-        hdr.opcode = SD_OP_CREATE_AND_WRITE_OBJ;
-        hdr.flags = SD_FLAG_CMD_WRITE | flags;
-    } else {
+        break;
+    case AIOCB_WRITE_UDATA:
+        if (create) {
+            hdr.opcode = SD_OP_CREATE_AND_WRITE_OBJ;
+        } else {
+            hdr.opcode = SD_OP_WRITE_OBJ;
+        }
         wlen = datalen;
-        hdr.opcode = SD_OP_WRITE_OBJ;
         hdr.flags = SD_FLAG_CMD_WRITE | flags;
+        break;
     }
 
     if (s->cache_flags) {
@@ -1127,15 +1139,6 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
         s->cache_flags = SD_FLAG_CMD_DIRECT;
     }
 
-    if (s->cache_flags == SD_FLAG_CMD_CACHE) {
-        s->flush_fd = connect_to_sdog(s->addr, s->port);
-        if (s->flush_fd < 0) {
-            error_report("failed to connect");
-            ret = s->flush_fd;
-            goto out;
-        }
-    }
-
     if (snapid || tag[0] != '\0') {
         dprintf("%" PRIx32 " snapshot inode was open.\n", vid);
         s->is_snapshot = true;
@@ -1397,9 +1400,6 @@ static void sd_close(BlockDriverState *bs)
 
     qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL);
     closesocket(s->fd);
-    if (s->cache_flags) {
-        closesocket(s->flush_fd);
-    }
     g_free(s->addr);
 }
 
@@ -1711,39 +1711,31 @@ static coroutine_fn int sd_co_readv(BlockDriverState *bs, int64_t sector_num,
 static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs)
 {
     BDRVSheepdogState *s = bs->opaque;
-    SheepdogObjReq hdr = { 0 };
-    SheepdogObjRsp *rsp = (SheepdogObjRsp *)&hdr;
-    SheepdogInode *inode = &s->inode;
+    SheepdogAIOCB *acb;
+    AIOReq *aio_req;
     int ret;
-    unsigned int wlen = 0, rlen = 0;
 
     if (s->cache_flags != SD_FLAG_CMD_CACHE) {
         return 0;
     }
 
-    hdr.opcode = SD_OP_FLUSH_VDI;
-    hdr.oid = vid_to_vdi_oid(inode->vdi_id);
+    acb = sd_aio_setup(bs, NULL, 0, 0, NULL, NULL);
+    acb->aiocb_type = AIOCB_FLUSH_CACHE;
+    acb->aio_done_func = sd_finish_aiocb;
 
-    ret = do_req(s->flush_fd, (SheepdogReq *)&hdr, NULL, &wlen, &rlen);
-    if (ret) {
-        error_report("failed to send a request to the sheep");
+    aio_req = alloc_aio_req(s, acb, vid_to_vdi_oid(s->inode.vdi_id),
+                            0, 0, 0, 0, 0);
+    QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
+    ret = add_aio_request(s, aio_req, NULL, 0, false, acb->aiocb_type);
+    if (ret < 0) {
+        error_report("add_aio_request is failed");
+        free_aio_req(s, aio_req);
+        qemu_aio_release(acb);
         return ret;
     }
 
-    if (rsp->result == SD_RES_INVALID_PARMS) {
-        dprintf("disable write cache since the server doesn't support it\n");
-
-        s->cache_flags = SD_FLAG_CMD_DIRECT;
-        closesocket(s->flush_fd);
-        return 0;
-    }
-
-    if (rsp->result != SD_RES_SUCCESS) {
-        error_report("%s", sd_strerror(rsp->result));
-        return -EIO;
-    }
-
-    return 0;
+    qemu_coroutine_yield();
+    return acb->ret;
 }
 
 static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
commit 3e84b4832180db2aa6187b6b971054bc3ca68be0
Author: Andreas Färber <afaerber at suse.de>
Date:   Tue Jan 15 02:55:10 2013 +0100

    qom: Make object_resolve_path_component() path argument const
    
    A usage with a hardcoded partial path such as
    
      object_resolve_path_component(obj, "foo")
    
    is totally valid but currently leads to a compilation error. Fix this.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/include/qom/object.h b/include/qom/object.h
index d43b289..1ef2f0e 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -900,7 +900,7 @@ Object *object_resolve_path_type(const char *path, const char *typename,
  *
  * Returns: The resolved object or NULL on path lookup failure.
  */
-Object *object_resolve_path_component(Object *parent, gchar *part);
+Object *object_resolve_path_component(Object *parent, const gchar *part);
 
 /**
  * object_property_add_child:
diff --git a/qom/object.c b/qom/object.c
index 351b88c..03e6f24 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1017,7 +1017,7 @@ gchar *object_get_canonical_path(Object *obj)
     return newpath;
 }
 
-Object *object_resolve_path_component(Object *parent, gchar *part)
+Object *object_resolve_path_component(Object *parent, const gchar *part)
 {
     ObjectProperty *prop = object_property_find(parent, part, NULL);
     if (prop == NULL) {
commit a87eec766d99c33fc49ecc6dbce40f304168ac3f
Author: Alex Rozenman <Alex_Rozenman at mentor.com>
Date:   Tue Jan 8 01:28:02 2013 +0200

    Add libcacard/trace/generated-tracers.c to .gitignore
    
    Signed-off-by: Alex Rozenman <Alex_Rozenman at mentor.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/.gitignore b/.gitignore
index 5fea65d..53fe9c3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@ trace/generated-tracers.h
 trace/generated-tracers.c
 trace/generated-tracers-dtrace.h
 trace/generated-tracers-dtrace.dtrace
+libcacard/trace/generated-tracers.c
 *-timestamp
 *-softmmu
 *-darwin-user
commit df702c9b4c1d049b12d7cf2f2ee607ff32f766cb
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Jan 14 16:26:58 2013 +0100

    block: clear dirty bitmap when discarding
    
    Note that resetting bits in the dirty bitmap is done _before_ actually
    processing the request.  Writes, instead, set bits after the request
    is completed.
    
    This way, when there are concurrent write and discard requests, the
    outcome will always be that the blocks are marked dirty.  This scenario
    should never happen, but it is safer to do it this way.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block.c b/block.c
index 4a90dd1..6fa7c90 100644
--- a/block.c
+++ b/block.c
@@ -4170,7 +4170,13 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
         return -EIO;
     } else if (bs->read_only) {
         return -EROFS;
-    } else if (bs->drv->bdrv_co_discard) {
+    }
+
+    if (bs->dirty_bitmap) {
+        set_dirty_bitmap(bs, sector_num, nb_sectors, 0);
+    }
+
+    if (bs->drv->bdrv_co_discard) {
         return bs->drv->bdrv_co_discard(bs, sector_num, nb_sectors);
     } else if (bs->drv->bdrv_aio_discard) {
         BlockDriverAIOCB *acb;
commit 501378c3af16e8e83a9dd500c11e594f4d1dbe79
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Jan 14 16:26:57 2013 +0100

    ide: issue discard asynchronously but serialize the pieces
    
    Now that discard can take a long time, make it asynchronous.
    Each LBA range entry is processed separately because discard
    can be an expensive operation.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/ide/core.c b/hw/ide/core.c
index cb77dfc..14ad079 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -325,14 +325,26 @@ typedef struct TrimAIOCB {
     BlockDriverAIOCB common;
     QEMUBH *bh;
     int ret;
+    QEMUIOVector *qiov;
+    BlockDriverAIOCB *aiocb;
+    int i, j;
 } TrimAIOCB;
 
 static void trim_aio_cancel(BlockDriverAIOCB *acb)
 {
     TrimAIOCB *iocb = container_of(acb, TrimAIOCB, common);
 
+    /* Exit the loop in case bdrv_aio_cancel calls ide_issue_trim_cb again.  */
+    iocb->j = iocb->qiov->niov - 1;
+    iocb->i = (iocb->qiov->iov[iocb->j].iov_len / 8) - 1;
+
+    /* Tell ide_issue_trim_cb not to trigger the completion, too.  */
     qemu_bh_delete(iocb->bh);
     iocb->bh = NULL;
+
+    if (iocb->aiocb) {
+        bdrv_aio_cancel(iocb->aiocb);
+    }
     qemu_aio_release(iocb);
 }
 
@@ -349,43 +361,60 @@ static void ide_trim_bh_cb(void *opaque)
 
     qemu_bh_delete(iocb->bh);
     iocb->bh = NULL;
-
     qemu_aio_release(iocb);
 }
 
+static void ide_issue_trim_cb(void *opaque, int ret)
+{
+    TrimAIOCB *iocb = opaque;
+    if (ret >= 0) {
+        while (iocb->j < iocb->qiov->niov) {
+            int j = iocb->j;
+            while (++iocb->i < iocb->qiov->iov[j].iov_len / 8) {
+                int i = iocb->i;
+                uint64_t *buffer = iocb->qiov->iov[j].iov_base;
+
+                /* 6-byte LBA + 2-byte range per entry */
+                uint64_t entry = le64_to_cpu(buffer[i]);
+                uint64_t sector = entry & 0x0000ffffffffffffULL;
+                uint16_t count = entry >> 48;
+
+                if (count == 0) {
+                    continue;
+                }
+
+                /* Got an entry! Submit and exit.  */
+                iocb->aiocb = bdrv_aio_discard(iocb->common.bs, sector, count,
+                                               ide_issue_trim_cb, opaque);
+                return;
+            }
+
+            iocb->j++;
+            iocb->i = -1;
+        }
+    } else {
+        iocb->ret = ret;
+    }
+
+    iocb->aiocb = NULL;
+    if (iocb->bh) {
+        qemu_bh_schedule(iocb->bh);
+    }
+}
+
 BlockDriverAIOCB *ide_issue_trim(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
         BlockDriverCompletionFunc *cb, void *opaque)
 {
     TrimAIOCB *iocb;
-    int i, j, ret;
 
     iocb = qemu_aio_get(&trim_aiocb_info, bs, cb, opaque);
     iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb);
     iocb->ret = 0;
-
-    for (j = 0; j < qiov->niov; j++) {
-        uint64_t *buffer = qiov->iov[j].iov_base;
-
-        for (i = 0; i < qiov->iov[j].iov_len / 8; i++) {
-            /* 6-byte LBA + 2-byte range per entry */
-            uint64_t entry = le64_to_cpu(buffer[i]);
-            uint64_t sector = entry & 0x0000ffffffffffffULL;
-            uint16_t count = entry >> 48;
-
-            if (count == 0) {
-                continue;
-            }
-
-            ret = bdrv_discard(bs, sector, count);
-            if (!iocb->ret) {
-                iocb->ret = ret;
-            }
-        }
-    }
-
-    qemu_bh_schedule(iocb->bh);
-
+    iocb->qiov = qiov;
+    iocb->i = -1;
+    iocb->j = 0;
+    ide_issue_trim_cb(iocb, 0);
     return &iocb->common;
 }
 
commit 80bc2e8d807939bee89d1a5ca0dbe89946d39ed1
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Jan 14 16:26:56 2013 +0100

    ide: fix TRIM with empty range entry
    
    ATA-ACS-3 says "If the two byte range length is zero, then the LBA
    Range Entry shall be discarded as padding."  iovecs are used as if
    they are linearized, so it is incorrect to discard the rest of
    this iovec.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 6f1938a..cb77dfc 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -374,7 +374,7 @@ BlockDriverAIOCB *ide_issue_trim(BlockDriverState *bs,
             uint16_t count = entry >> 48;
 
             if (count == 0) {
-                break;
+                continue;
             }
 
             ret = bdrv_discard(bs, sector, count);
commit 8238010b265886249f9f3d45e890788319b7736e
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Jan 14 16:26:55 2013 +0100

    block: make discard asynchronous
    
    This is easy with the thread pool, because we can use s->is_xfs and
    s->has_discard from the worker function.
    
    QEMU has a widespread assumption that each I/O operation writes less
    than 2^32 bytes.  This patch doesn't fix it throughout of course,
    but it starts correcting struct RawPosixAIOData so that there is
    no regression with respect to the synchronous discard implementation.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/raw-aio.h b/block/raw-aio.h
index e77f361..c61f159 100644
--- a/block/raw-aio.h
+++ b/block/raw-aio.h
@@ -20,11 +20,14 @@
 #define QEMU_AIO_WRITE        0x0002
 #define QEMU_AIO_IOCTL        0x0004
 #define QEMU_AIO_FLUSH        0x0008
+#define QEMU_AIO_DISCARD      0x0010
 #define QEMU_AIO_TYPE_MASK \
-	(QEMU_AIO_READ|QEMU_AIO_WRITE|QEMU_AIO_IOCTL|QEMU_AIO_FLUSH)
+        (QEMU_AIO_READ|QEMU_AIO_WRITE|QEMU_AIO_IOCTL|QEMU_AIO_FLUSH| \
+         QEMU_AIO_DISCARD)
 
 /* AIO flags */
 #define QEMU_AIO_MISALIGNED   0x1000
+#define QEMU_AIO_BLKDEV       0x2000
 
 
 /* linux-aio.c - Linux native implementation */
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 1d32139..679fcc5 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -163,7 +163,7 @@ typedef struct RawPosixAIOData {
         void *aio_ioctl_buf;
     };
     int aio_niov;
-    size_t aio_nbytes;
+    uint64_t aio_nbytes;
 #define aio_ioctl_cmd   aio_nbytes /* for QEMU_AIO_IOCTL */
     off_t aio_offset;
     int aio_type;
@@ -623,6 +623,72 @@ static ssize_t handle_aiocb_rw(RawPosixAIOData *aiocb)
     return nbytes;
 }
 
+#ifdef CONFIG_XFS
+static int xfs_discard(BDRVRawState *s, int64_t offset, uint64_t bytes)
+{
+    struct xfs_flock64 fl;
+
+    memset(&fl, 0, sizeof(fl));
+    fl.l_whence = SEEK_SET;
+    fl.l_start = offset;
+    fl.l_len = bytes;
+
+    if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) {
+        DEBUG_BLOCK_PRINT("cannot punch hole (%s)\n", strerror(errno));
+        return -errno;
+    }
+
+    return 0;
+}
+#endif
+
+static ssize_t handle_aiocb_discard(RawPosixAIOData *aiocb)
+{
+    int ret = -EOPNOTSUPP;
+    BDRVRawState *s = aiocb->bs->opaque;
+
+    if (s->has_discard == 0) {
+        return 0;
+    }
+
+    if (aiocb->aio_type & QEMU_AIO_BLKDEV) {
+#ifdef BLKDISCARD
+        do {
+            uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes };
+            if (ioctl(aiocb->aio_fildes, BLKDISCARD, range) == 0) {
+                return 0;
+            }
+        } while (errno == EINTR);
+
+        ret = -errno;
+#endif
+    } else {
+#ifdef CONFIG_XFS
+        if (s->is_xfs) {
+            return xfs_discard(s, aiocb->aio_offset, aiocb->aio_nbytes);
+        }
+#endif
+
+#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
+        do {
+            if (fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
+                          aiocb->aio_offset, aiocb->aio_nbytes) == 0) {
+                return 0;
+            }
+        } while (errno == EINTR);
+
+        ret = -errno;
+#endif
+    }
+
+    if (ret == -ENODEV || ret == -ENOSYS || ret == -EOPNOTSUPP ||
+        ret == -ENOTTY) {
+        s->has_discard = 0;
+        ret = 0;
+    }
+    return ret;
+}
+
 static int aio_worker(void *arg)
 {
     RawPosixAIOData *aiocb = arg;
@@ -657,6 +723,9 @@ static int aio_worker(void *arg)
     case QEMU_AIO_IOCTL:
         ret = handle_aiocb_ioctl(aiocb);
         break;
+    case QEMU_AIO_DISCARD:
+        ret = handle_aiocb_discard(aiocb);
+        break;
     default:
         fprintf(stderr, "invalid aio request (0x%x)\n", aiocb->aio_type);
         ret = -EINVAL;
@@ -1057,57 +1126,14 @@ static int coroutine_fn raw_co_is_allocated(BlockDriverState *bs,
     }
 }
 
-#ifdef CONFIG_XFS
-static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors)
-{
-    struct xfs_flock64 fl;
-
-    memset(&fl, 0, sizeof(fl));
-    fl.l_whence = SEEK_SET;
-    fl.l_start = sector_num << 9;
-    fl.l_len = (int64_t)nb_sectors << 9;
-
-    if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) {
-        DEBUG_BLOCK_PRINT("cannot punch hole (%s)\n", strerror(errno));
-        return -errno;
-    }
-
-    return 0;
-}
-#endif
-
-static coroutine_fn int raw_co_discard(BlockDriverState *bs,
-    int64_t sector_num, int nb_sectors)
+static coroutine_fn BlockDriverAIOCB *raw_aio_discard(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors,
+    BlockDriverCompletionFunc *cb, void *opaque)
 {
-    int ret = -EOPNOTSUPP;
     BDRVRawState *s = bs->opaque;
 
-    if (!s->has_discard) {
-        return 0;
-    }
-
-#ifdef CONFIG_XFS
-    if (s->is_xfs) {
-        return xfs_discard(s, sector_num, nb_sectors);
-    }
-#endif
-
-#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
-    do {
-        if (fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
-                      sector_num << BDRV_SECTOR_BITS,
-                      (int64_t)nb_sectors << BDRV_SECTOR_BITS) == 0) {
-            return 0;
-        }
-    } while (errno == EINTR);
-
-    ret = -errno;
-#endif
-
-    if (ret == -EOPNOTSUPP) {
-        return 0;
-    }
-    return ret;
+    return paio_submit(bs, s->fd, sector_num, NULL, nb_sectors,
+                       cb, opaque, QEMU_AIO_DISCARD);
 }
 
 static QEMUOptionParameter raw_create_options[] = {
@@ -1130,12 +1156,12 @@ static BlockDriver bdrv_file = {
     .bdrv_reopen_abort = raw_reopen_abort,
     .bdrv_close = raw_close,
     .bdrv_create = raw_create,
-    .bdrv_co_discard = raw_co_discard,
     .bdrv_co_is_allocated = raw_co_is_allocated,
 
     .bdrv_aio_readv = raw_aio_readv,
     .bdrv_aio_writev = raw_aio_writev,
     .bdrv_aio_flush = raw_aio_flush,
+    .bdrv_aio_discard = raw_aio_discard,
 
     .bdrv_truncate = raw_truncate,
     .bdrv_getlength = raw_getlength,
@@ -1345,38 +1371,17 @@ static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
     return thread_pool_submit_aio(aio_worker, acb, cb, opaque);
 }
 
-static coroutine_fn int hdev_co_discard(BlockDriverState *bs,
-    int64_t sector_num, int nb_sectors)
+static coroutine_fn BlockDriverAIOCB *hdev_aio_discard(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors,
+    BlockDriverCompletionFunc *cb, void *opaque)
 {
     BDRVRawState *s = bs->opaque;
-    int ret;
-
-    if (s->has_discard == 0) {
-        return 0;
-    }
-    ret = fd_open(bs);
-    if (ret < 0) {
-        return ret;
-    }
 
-    ret = -EOPNOTSUPP;
-#ifdef BLKDISCARD
-    do {
-        uint64_t range[2] = { sector_num * 512, (uint64_t)nb_sectors * 512 };
-        if (ioctl(s->fd, BLKDISCARD, range) == 0) {
-            return 0;
-        }
-    } while (errno == EINTR);
-
-    ret = -errno;
-#endif
-    if (ret == -ENODEV || ret == -ENOSYS || ret == -EOPNOTSUPP ||
-        ret == -ENOTTY) {
-        s->has_discard = 0;
-        ret = 0;
+    if (fd_open(bs) < 0) {
+        return NULL;
     }
-    return ret;
-
+    return paio_submit(bs, s->fd, sector_num, NULL, nb_sectors,
+                       cb, opaque, QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV);
 }
 
 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
@@ -1447,11 +1452,10 @@ static BlockDriver bdrv_host_device = {
     .create_options     = raw_create_options,
     .bdrv_has_zero_init = hdev_has_zero_init,
 
-    .bdrv_co_discard    = hdev_co_discard,
-
     .bdrv_aio_readv	= raw_aio_readv,
     .bdrv_aio_writev	= raw_aio_writev,
     .bdrv_aio_flush	= raw_aio_flush,
+    .bdrv_aio_discard   = hdev_aio_discard,
 
     .bdrv_truncate      = raw_truncate,
     .bdrv_getlength	= raw_getlength,
commit fcd9d4555252c47a337357dfce0806e5dde99d96
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Jan 14 16:26:54 2013 +0100

    raw: support discard on block devices
    
    Block devices use a ioctl instead of fallocate, so add a separate
    implementation.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/raw-posix.c b/block/raw-posix.c
index b647cfb..1d32139 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1345,6 +1345,40 @@ static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
     return thread_pool_submit_aio(aio_worker, acb, cb, opaque);
 }
 
+static coroutine_fn int hdev_co_discard(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors)
+{
+    BDRVRawState *s = bs->opaque;
+    int ret;
+
+    if (s->has_discard == 0) {
+        return 0;
+    }
+    ret = fd_open(bs);
+    if (ret < 0) {
+        return ret;
+    }
+
+    ret = -EOPNOTSUPP;
+#ifdef BLKDISCARD
+    do {
+        uint64_t range[2] = { sector_num * 512, (uint64_t)nb_sectors * 512 };
+        if (ioctl(s->fd, BLKDISCARD, range) == 0) {
+            return 0;
+        }
+    } while (errno == EINTR);
+
+    ret = -errno;
+#endif
+    if (ret == -ENODEV || ret == -ENOSYS || ret == -EOPNOTSUPP ||
+        ret == -ENOTTY) {
+        s->has_discard = 0;
+        ret = 0;
+    }
+    return ret;
+
+}
+
 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 static int fd_open(BlockDriverState *bs)
 {
@@ -1413,6 +1447,8 @@ static BlockDriver bdrv_host_device = {
     .create_options     = raw_create_options,
     .bdrv_has_zero_init = hdev_has_zero_init,
 
+    .bdrv_co_discard    = hdev_co_discard,
+
     .bdrv_aio_readv	= raw_aio_readv,
     .bdrv_aio_writev	= raw_aio_writev,
     .bdrv_aio_flush	= raw_aio_flush,
commit c85191e5c9e14d65cc4281ef3b31f480227aa6dd
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Jan 14 16:26:53 2013 +0100

    raw-posix: remember whether discard failed
    
    Avoid sending system calls repeatedly if they shall fail.  This
    does not apply to XFS: if the filesystem-specific ioctl fails,
    something weird is happening.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/raw-posix.c b/block/raw-posix.c
index e8d79af..b647cfb 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -141,6 +141,7 @@ typedef struct BDRVRawState {
 #ifdef CONFIG_XFS
     bool is_xfs : 1;
 #endif
+    bool has_discard : 1;
 } BDRVRawState;
 
 typedef struct BDRVRawReopenState {
@@ -292,6 +293,7 @@ static int raw_open_common(BlockDriverState *bs, const char *filename,
     }
 #endif
 
+    s->has_discard = 1;
 #ifdef CONFIG_XFS
     if (platform_test_xfs_fd(s->fd)) {
         s->is_xfs = 1;
@@ -1078,10 +1080,12 @@ static coroutine_fn int raw_co_discard(BlockDriverState *bs,
     int64_t sector_num, int nb_sectors)
 {
     int ret = -EOPNOTSUPP;
-
-#if defined(CONFIG_FALLOCATE_PUNCH_HOLE) || defined(CONFIG_XFS)
     BDRVRawState *s = bs->opaque;
 
+    if (!s->has_discard) {
+        return 0;
+    }
+
 #ifdef CONFIG_XFS
     if (s->is_xfs) {
         return xfs_discard(s, sector_num, nb_sectors);
@@ -1099,7 +1103,6 @@ static coroutine_fn int raw_co_discard(BlockDriverState *bs,
 
     ret = -errno;
 #endif
-#endif
 
     if (ret == -EOPNOTSUPP) {
         return 0;
commit 3d4fa43e648f3b169e7ab5dd4e21312e510805d7
Author: Kusanagi Kouichi <slash at ac.auone-net.jp>
Date:   Mon Jan 14 16:26:52 2013 +0100

    raw-posix: support discard on more filesystems
    
    Linux 2.6.38 introduced the filesystem independent interface to
    deallocate part of a file. As of Linux 3.7, btrfs, ext4, ocfs2,
    tmpfs and xfs support it.
    
    Even though the system calls here are in practice issued on Linux,
    the code is structured to allow plugging in alternatives for other Unix
    variants.  EOPNOTSUPP is used unconditionally in this patch, but it is
    supported in both OpenBSD and Mac OS X since forever (see for example
    http://lists.debian.org/debian-glibc/2006/02/msg00337.html).
    
    Signed-off-by: Kusanagi Kouichi <slash at ac.auone-net.jp>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/raw-posix.c b/block/raw-posix.c
index c3d7fda..e8d79af 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -59,6 +59,9 @@
 #ifdef CONFIG_FIEMAP
 #include <linux/fiemap.h>
 #endif
+#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
+#include <linux/falloc.h>
+#endif
 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
 #include <sys/disk.h>
 #include <sys/cdio.h>
@@ -1074,15 +1077,34 @@ static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors)
 static coroutine_fn int raw_co_discard(BlockDriverState *bs,
     int64_t sector_num, int nb_sectors)
 {
-#ifdef CONFIG_XFS
+    int ret = -EOPNOTSUPP;
+
+#if defined(CONFIG_FALLOCATE_PUNCH_HOLE) || defined(CONFIG_XFS)
     BDRVRawState *s = bs->opaque;
 
+#ifdef CONFIG_XFS
     if (s->is_xfs) {
         return xfs_discard(s, sector_num, nb_sectors);
     }
 #endif
 
-    return 0;
+#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
+    do {
+        if (fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
+                      sector_num << BDRV_SECTOR_BITS,
+                      (int64_t)nb_sectors << BDRV_SECTOR_BITS) == 0) {
+            return 0;
+        }
+    } while (errno == EINTR);
+
+    ret = -errno;
+#endif
+#endif
+
+    if (ret == -EOPNOTSUPP) {
+        return 0;
+    }
+    return ret;
 }
 
 static QEMUOptionParameter raw_create_options[] = {
diff --git a/configure b/configure
index c908f66..40d250c 100755
--- a/configure
+++ b/configure
@@ -2581,6 +2581,22 @@ if compile_prog "" "" ; then
   fallocate=yes
 fi
 
+# check for fallocate hole punching
+fallocate_punch_hole=no
+cat > $TMPC << EOF
+#include <fcntl.h>
+#include <linux/falloc.h>
+
+int main(void)
+{
+    fallocate(0, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, 0);
+    return 0;
+}
+EOF
+if compile_prog "" "" ; then
+  fallocate_punch_hole=yes
+fi
+
 # check for sync_file_range
 sync_file_range=no
 cat > $TMPC << EOF
@@ -3490,6 +3506,9 @@ fi
 if test "$fallocate" = "yes" ; then
   echo "CONFIG_FALLOCATE=y" >> $config_host_mak
 fi
+if test "$fallocate_punch_hole" = "yes" ; then
+  echo "CONFIG_FALLOCATE_PUNCH_HOLE=y" >> $config_host_mak
+fi
 if test "$sync_file_range" = "yes" ; then
   echo "CONFIG_SYNC_FILE_RANGE=y" >> $config_host_mak
 fi
commit 029d091e4975af60ff9622717af19c5910f2f4e9
Author: Peter Lieven <pl at dlhnet.de>
Date:   Fri Jan 11 13:29:55 2013 +0100

    block: fix initialization in bdrv_io_limits_enable()
    
    bdrv_io_limits_enable() starts a new slice, but does not set io_base
    correctly for that slice.
    
    Here is how io_base is used:
    
        bytes_base  = bs->nr_bytes[is_write] - bs->io_base.bytes[is_write];
        bytes_res   = (unsigned) nb_sectors * BDRV_SECTOR_SIZE;
    
        if (bytes_base + bytes_res <= bytes_limit) {
            /* no wait */
        } else {
            /* operation needs to be throttled */
        }
    
    As a result, any I/O operations that are triggered between now and
    bs->slice_end are incorrectly limited.  If 10 MB of data has been
    written since the VM was started, QEMU thinks that 10 MB of data has
    been written in this slice. This leads to a I/O lockup in the guest.
    
    We fix this by delaying the start of a new slice to the next
    call of bdrv_exceed_io_limits().
    
    Signed-off-by: Peter Lieven <pl at kamp.de>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block.c b/block.c
index b5e64ec..4a90dd1 100644
--- a/block.c
+++ b/block.c
@@ -155,10 +155,6 @@ void bdrv_io_limits_enable(BlockDriverState *bs)
 {
     qemu_co_queue_init(&bs->throttled_reqs);
     bs->block_timer = qemu_new_timer_ns(vm_clock, bdrv_block_timer, bs);
-    bs->slice_time  = 5 * BLOCK_IO_SLICE_TIME;
-    bs->slice_start = qemu_get_clock_ns(vm_clock);
-    bs->slice_end   = bs->slice_start + bs->slice_time;
-    memset(&bs->io_base, 0, sizeof(bs->io_base));
     bs->io_limits_enabled = true;
 }
 
commit e175bce587936bf479889881488821ea8d61c89c
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Tue Jan 15 13:39:56 2013 +0800

    target-i386: Use switch in check_hw_breakpoints()
    
    Replace an if statement using magic numbers for breakpoint type with a
    more explicit switch statement. This is to aid readability.
    
    Change the return type and force_dr6_update argument type to bool.
    
    While at it, fix Coding Style issues (missing braces).
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 1e850a7..4e091cd 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1043,7 +1043,7 @@ static inline int hw_breakpoint_len(unsigned long dr7, int index)
 
 void hw_breakpoint_insert(CPUX86State *env, int index);
 void hw_breakpoint_remove(CPUX86State *env, int index);
-int check_hw_breakpoints(CPUX86State *env, int force_dr6_update);
+bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update);
 void breakpoint_handler(CPUX86State *env);
 
 /* will be suppressed */
diff --git a/target-i386/helper.c b/target-i386/helper.c
index a10b562..547c25e 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1017,26 +1017,45 @@ void hw_breakpoint_remove(CPUX86State *env, int index)
     }
 }
 
-int check_hw_breakpoints(CPUX86State *env, int force_dr6_update)
+bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update)
 {
     target_ulong dr6;
-    int reg, type;
-    int hit_enabled = 0;
+    int reg;
+    bool hit_enabled = false;
 
     dr6 = env->dr[6] & ~0xf;
     for (reg = 0; reg < DR7_MAX_BP; reg++) {
-        type = hw_breakpoint_type(env->dr[7], reg);
-        if ((type == 0 && env->dr[reg] == env->eip) ||
-            ((type & 1) && env->cpu_watchpoint[reg] &&
-             (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
+        bool bp_match = false;
+        bool wp_match = false;
+
+        switch (hw_breakpoint_type(env->dr[7], reg)) {
+        case DR7_TYPE_BP_INST:
+            if (env->dr[reg] == env->eip) {
+                bp_match = true;
+            }
+            break;
+        case DR7_TYPE_DATA_WR:
+        case DR7_TYPE_DATA_RW:
+            if (env->cpu_watchpoint[reg] &&
+                env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT) {
+                wp_match = true;
+            }
+            break;
+        case DR7_TYPE_IO_RW:
+            break;
+        }
+        if (bp_match || wp_match) {
             dr6 |= 1 << reg;
             if (hw_breakpoint_enabled(env->dr[7], reg)) {
-                hit_enabled = 1;
+                hit_enabled = true;
             }
         }
     }
-    if (hit_enabled || force_dr6_update)
+
+    if (hit_enabled || force_dr6_update) {
         env->dr[6] = dr6;
+    }
+
     return hit_enabled;
 }
 
@@ -1047,16 +1066,17 @@ void breakpoint_handler(CPUX86State *env)
     if (env->watchpoint_hit) {
         if (env->watchpoint_hit->flags & BP_CPU) {
             env->watchpoint_hit = NULL;
-            if (check_hw_breakpoints(env, 0))
+            if (check_hw_breakpoints(env, false)) {
                 raise_exception(env, EXCP01_DB);
-            else
+            } else {
                 cpu_resume_from_signal(env, NULL);
+            }
         }
     } else {
         QTAILQ_FOREACH(bp, &env->breakpoints, entry)
             if (bp->pc == env->eip) {
                 if (bp->flags & BP_CPU) {
-                    check_hw_breakpoints(env, 1);
+                    check_hw_breakpoints(env, true);
                     raise_exception(env, EXCP01_DB);
                 }
                 break;
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index b3f4e4f..b6d5740 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -110,7 +110,7 @@ void helper_into(CPUX86State *env, int next_eip_addend)
 void helper_single_step(CPUX86State *env)
 {
 #ifndef CONFIG_USER_ONLY
-    check_hw_breakpoints(env, 1);
+    check_hw_breakpoints(env, true);
     env->dr[6] |= DR6_BS;
 #endif
     raise_exception(env, EXCP01_DB);
commit 1cc21a180b9ea9204e99ad5c58604cb458e572a9
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Tue Jan 15 08:24:02 2013 +0100

    target-i386: Avoid goto in hw_breakpoint_insert()
    
      "Go To Statement Considered Harmful" -- E. Dijkstra
    
    To avoid an unnecessary goto within the switch statement, move
    watchpoint insertion out of the switch statement. Improves readability.
    
    While at it, fix Coding Style issues (missing braces, indentation).
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/helper.c b/target-i386/helper.c
index ebdd6a5..a10b562 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -966,7 +966,7 @@ hwaddr cpu_get_phys_page_debug(CPUX86State *env, target_ulong addr)
 
 void hw_breakpoint_insert(CPUX86State *env, int index)
 {
-    int type, err = 0;
+    int type = 0, err = 0;
 
     switch (hw_breakpoint_type(env->dr[7], index)) {
     case DR7_TYPE_BP_INST:
@@ -977,20 +977,24 @@ void hw_breakpoint_insert(CPUX86State *env, int index)
         break;
     case DR7_TYPE_DATA_WR:
         type = BP_CPU | BP_MEM_WRITE;
-        goto insert_wp;
+        break;
     case DR7_TYPE_IO_RW:
-         /* No support for I/O watchpoints yet */
+        /* No support for I/O watchpoints yet */
         break;
     case DR7_TYPE_DATA_RW:
         type = BP_CPU | BP_MEM_ACCESS;
-    insert_wp:
+        break;
+    }
+
+    if (type != 0) {
         err = cpu_watchpoint_insert(env, env->dr[index],
                                     hw_breakpoint_len(env->dr[7], index),
                                     type, &env->cpu_watchpoint[index]);
-        break;
     }
-    if (err)
+
+    if (err) {
         env->cpu_breakpoint[index] = NULL;
+    }
 }
 
 void hw_breakpoint_remove(CPUX86State *env, int index)
commit 5902564ac983d67d7d898356971698b50b8f0b91
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Tue Jan 15 08:01:07 2013 +0100

    target-i386: Introduce hw_{local,global}_breakpoint_enabled()
    
    hw_breakpoint_enabled() returned a bit field indicating whether a local
    breakpoint and/or global breakpoint was enabled. Avoid this number magic
    by using explicit boolean helper functions hw_local_breakpoint_enabled()
    and hw_global_breakpoint_enabled(), to aid readability.
    
    Reuse them for the hw_breakpoint_enabled() implementation and change
    its return type to bool.
    
    While at it, fix Coding Style issues (missing braces).
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 6682022..1e850a7 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1014,9 +1014,20 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
 #define cpu_handle_mmu_fault cpu_x86_handle_mmu_fault
 void cpu_x86_set_a20(CPUX86State *env, int a20_state);
 
-static inline int hw_breakpoint_enabled(unsigned long dr7, int index)
+static inline bool hw_local_breakpoint_enabled(unsigned long dr7, int index)
 {
-    return (dr7 >> (index * 2)) & 3;
+    return (dr7 >> (index * 2)) & 1;
+}
+
+static inline bool hw_global_breakpoint_enabled(unsigned long dr7, int index)
+{
+    return (dr7 >> (index * 2)) & 2;
+
+}
+static inline bool hw_breakpoint_enabled(unsigned long dr7, int index)
+{
+    return hw_global_breakpoint_enabled(dr7, index) ||
+           hw_local_breakpoint_enabled(dr7, index);
 }
 
 static inline int hw_breakpoint_type(unsigned long dr7, int index)
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 1fceb91..ebdd6a5 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -970,9 +970,10 @@ void hw_breakpoint_insert(CPUX86State *env, int index)
 
     switch (hw_breakpoint_type(env->dr[7], index)) {
     case DR7_TYPE_BP_INST:
-        if (hw_breakpoint_enabled(env->dr[7], index))
+        if (hw_breakpoint_enabled(env->dr[7], index)) {
             err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
                                         &env->cpu_breakpoint[index]);
+        }
         break;
     case DR7_TYPE_DATA_WR:
         type = BP_CPU | BP_MEM_WRITE;
@@ -998,8 +999,9 @@ void hw_breakpoint_remove(CPUX86State *env, int index)
         return;
     switch (hw_breakpoint_type(env->dr[7], index)) {
     case DR7_TYPE_BP_INST:
-        if (hw_breakpoint_enabled(env->dr[7], index))
+        if (hw_breakpoint_enabled(env->dr[7], index)) {
             cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
+        }
         break;
     case DR7_TYPE_DATA_WR:
     case DR7_TYPE_DATA_RW:
@@ -1024,8 +1026,9 @@ int check_hw_breakpoints(CPUX86State *env, int force_dr6_update)
             ((type & 1) && env->cpu_watchpoint[reg] &&
              (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
             dr6 |= 1 << reg;
-            if (hw_breakpoint_enabled(env->dr[7], reg))
+            if (hw_breakpoint_enabled(env->dr[7], reg)) {
                 hit_enabled = 1;
+            }
         }
     }
     if (hit_enabled || force_dr6_update)
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index c40bd96..3247dee 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -467,7 +467,8 @@ static void switch_tss(CPUX86State *env, int tss_selector,
     /* reset local breakpoints */
     if (env->dr[7] & DR7_LOCAL_BP_MASK) {
         for (i = 0; i < DR7_MAX_BP; i++) {
-            if (hw_breakpoint_enabled(env->dr[7], i) == 0x1) {
+            if (hw_local_breakpoint_enabled(env->dr[7], i) &&
+                !hw_global_breakpoint_enabled(env->dr[7], i)) {
                 hw_breakpoint_remove(env, i);
             }
         }
commit 428065ce50643a56bff043501809b62b035f0b17
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Tue Jan 15 13:39:55 2013 +0800

    target-i386: Define DR7 bit field constants
    
    Implicit use of dr7 bit field is a little hard to understand,
    so define constants for them and use them consistently.
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index e4a7c50..6682022 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -231,6 +231,12 @@
 #define DR7_TYPE_SHIFT  16
 #define DR7_LEN_SHIFT   18
 #define DR7_FIXED_1     0x00000400
+#define DR7_LOCAL_BP_MASK    0x55
+#define DR7_MAX_BP           4
+#define DR7_TYPE_BP_INST     0x0
+#define DR7_TYPE_DATA_WR     0x1
+#define DR7_TYPE_IO_RW       0x2
+#define DR7_TYPE_DATA_RW     0x3
 
 #define PG_PRESENT_BIT	0
 #define PG_RW_BIT	1
diff --git a/target-i386/helper.c b/target-i386/helper.c
index fa622e1..1fceb91 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -969,18 +969,18 @@ void hw_breakpoint_insert(CPUX86State *env, int index)
     int type, err = 0;
 
     switch (hw_breakpoint_type(env->dr[7], index)) {
-    case 0:
+    case DR7_TYPE_BP_INST:
         if (hw_breakpoint_enabled(env->dr[7], index))
             err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
                                         &env->cpu_breakpoint[index]);
         break;
-    case 1:
+    case DR7_TYPE_DATA_WR:
         type = BP_CPU | BP_MEM_WRITE;
         goto insert_wp;
-    case 2:
+    case DR7_TYPE_IO_RW:
          /* No support for I/O watchpoints yet */
         break;
-    case 3:
+    case DR7_TYPE_DATA_RW:
         type = BP_CPU | BP_MEM_ACCESS;
     insert_wp:
         err = cpu_watchpoint_insert(env, env->dr[index],
@@ -997,15 +997,15 @@ void hw_breakpoint_remove(CPUX86State *env, int index)
     if (!env->cpu_breakpoint[index])
         return;
     switch (hw_breakpoint_type(env->dr[7], index)) {
-    case 0:
+    case DR7_TYPE_BP_INST:
         if (hw_breakpoint_enabled(env->dr[7], index))
             cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
         break;
-    case 1:
-    case 3:
+    case DR7_TYPE_DATA_WR:
+    case DR7_TYPE_DATA_RW:
         cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
         break;
-    case 2:
+    case DR7_TYPE_IO_RW:
         /* No support for I/O watchpoints yet */
         break;
     }
@@ -1018,7 +1018,7 @@ int check_hw_breakpoints(CPUX86State *env, int force_dr6_update)
     int hit_enabled = 0;
 
     dr6 = env->dr[6] & ~0xf;
-    for (reg = 0; reg < 4; reg++) {
+    for (reg = 0; reg < DR7_MAX_BP; reg++) {
         type = hw_breakpoint_type(env->dr[7], reg);
         if ((type == 0 && env->dr[reg] == env->eip) ||
             ((type & 1) && env->cpu_watchpoint[reg] &&
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 8354572..8df6a6b 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -265,10 +265,11 @@ static int cpu_post_load(void *opaque, int version_id)
 
     cpu_breakpoint_remove_all(env, BP_CPU);
     cpu_watchpoint_remove_all(env, BP_CPU);
-    for (i = 0; i < 4; i++)
+    for (i = 0; i < DR7_MAX_BP; i++) {
         hw_breakpoint_insert(env, i);
-
+    }
     tlb_flush(env, 1);
+
     return 0;
 }
 
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index 719cacd..b3f4e4f 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -197,11 +197,11 @@ void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0)
         env->dr[reg] = t0;
         hw_breakpoint_insert(env, reg);
     } else if (reg == 7) {
-        for (i = 0; i < 4; i++) {
+        for (i = 0; i < DR7_MAX_BP; i++) {
             hw_breakpoint_remove(env, i);
         }
         env->dr[7] = t0;
-        for (i = 0; i < 4; i++) {
+        for (i = 0; i < DR7_MAX_BP; i++) {
             hw_breakpoint_insert(env, i);
         }
     } else {
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index c2a99ee..c40bd96 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -465,13 +465,13 @@ static void switch_tss(CPUX86State *env, int tss_selector,
 
 #ifndef CONFIG_USER_ONLY
     /* reset local breakpoints */
-    if (env->dr[7] & 0x55) {
-        for (i = 0; i < 4; i++) {
+    if (env->dr[7] & DR7_LOCAL_BP_MASK) {
+        for (i = 0; i < DR7_MAX_BP; i++) {
             if (hw_breakpoint_enabled(env->dr[7], i) == 0x1) {
                 hw_breakpoint_remove(env, i);
             }
         }
-        env->dr[7] &= ~0x55;
+        env->dr[7] &= ~DR7_LOCAL_BP_MASK;
     }
 #endif
 }
commit 8d2497c3552e19a60e7a75d20976471ecb2a8e2b
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Mon Jan 14 17:31:31 2013 +0100

    qcow2: Fix segfault on zero-length write
    
    One of the recent refactoring patches (commit f50f88b9) didn't take care
    to initialise l2meta properly, so with zero-length writes, which don't
    even enter the write loop, qemu just segfaulted.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/qcow2.c b/block/qcow2.c
index d603f98..f6abff6 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -759,7 +759,7 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
     QEMUIOVector hd_qiov;
     uint64_t bytes_done = 0;
     uint8_t *cluster_data = NULL;
-    QCowL2Meta *l2meta;
+    QCowL2Meta *l2meta = NULL;
 
     trace_qcow2_writev_start_req(qemu_coroutine_self(), sector_num,
                                  remaining_sectors);
commit 5ec01c2e96910e1588d1a0de8609b9dda7618c7f
Author: Igor Mammedov <imammedo at redhat.com>
Date:   Fri Jan 11 03:10:17 2013 +0100

    target-i386: Move kvm_check_features_against_host() check to realize time
    
    kvm_check_features_against_host() should be called when features can't
    be changed, and when features are converted to properties it would be
    possible to change them until realize time, so correct way is to call
    kvm_check_features_against_host() in x86_cpu_realize().
    
    Signed-off-by: Igor Mammedov <imammedo at redhat.com>
    Reviewed-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 3a68470..333745b 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1022,27 +1022,28 @@ static int unavailable_host_feature(FeatureWordInfo *f, uint32_t mask)
  *
  * This function may be called only if KVM is enabled.
  */
-static int kvm_check_features_against_host(x86_def_t *guest_def)
+static int kvm_check_features_against_host(X86CPU *cpu)
 {
+    CPUX86State *env = &cpu->env;
     x86_def_t host_def;
     uint32_t mask;
     int rv, i;
     struct model_features_t ft[] = {
-        {&guest_def->features, &host_def.features,
+        {&env->cpuid_features, &host_def.features,
             FEAT_1_EDX },
-        {&guest_def->ext_features, &host_def.ext_features,
+        {&env->cpuid_ext_features, &host_def.ext_features,
             FEAT_1_ECX },
-        {&guest_def->ext2_features, &host_def.ext2_features,
+        {&env->cpuid_ext2_features, &host_def.ext2_features,
             FEAT_8000_0001_EDX },
-        {&guest_def->ext3_features, &host_def.ext3_features,
+        {&env->cpuid_ext3_features, &host_def.ext3_features,
             FEAT_8000_0001_ECX },
-        {&guest_def->ext4_features, &host_def.ext4_features,
+        {&env->cpuid_ext4_features, &host_def.ext4_features,
             FEAT_C000_0001_EDX },
-        {&guest_def->cpuid_7_0_ebx_features, &host_def.cpuid_7_0_ebx_features,
+        {&env->cpuid_7_0_ebx_features, &host_def.cpuid_7_0_ebx_features,
             FEAT_7_0_EBX },
-        {&guest_def->svm_features, &host_def.svm_features,
+        {&env->cpuid_svm_features, &host_def.svm_features,
             FEAT_SVM },
-        {&guest_def->kvm_features, &host_def.kvm_features,
+        {&env->cpuid_kvm_features, &host_def.kvm_features,
             FEAT_KVM },
     };
 
@@ -1471,10 +1472,6 @@ static int cpu_x86_parse_featurestr(x86_def_t *x86_cpu_def, char *features)
     x86_cpu_def->kvm_features &= ~minus_features[FEAT_KVM];
     x86_cpu_def->svm_features &= ~minus_features[FEAT_SVM];
     x86_cpu_def->cpuid_7_0_ebx_features &= ~minus_features[FEAT_7_0_EBX];
-    if (check_cpuid && kvm_enabled()) {
-        if (kvm_check_features_against_host(x86_cpu_def) && enforce_cpuid)
-            goto error;
-    }
     return 0;
 
 error:
@@ -2177,6 +2174,11 @@ void x86_cpu_realize(Object *obj, Error **errp)
 #ifdef CONFIG_KVM
         filter_features_for_kvm(cpu);
 #endif
+        if (check_cpuid && kvm_check_features_against_host(cpu)
+            && enforce_cpuid) {
+            error_setg(errp, "Host's CPU doesn't support requested features");
+            return;
+        }
     }
 
 #ifndef CONFIG_USER_ONLY
commit fa2db3c494270c1892365eef370d06a4559619e0
Author: Igor Mammedov <imammedo at redhat.com>
Date:   Fri Jan 11 03:10:16 2013 +0100

    target-i386: cpu_x86_register() consolidate freeing resources
    
    Freeing resources in one place would require setting 'error'
    to not NULL, so add some more error reporting before jumping to
    exit branch.
    
    Signed-off-by: Igor Mammedov <imammedo at redhat.com>
    Reviewed-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index e75b293..3a68470 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1594,20 +1594,23 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
 
     model_pieces = g_strsplit(cpu_model, ",", 2);
     if (!model_pieces[0]) {
-        goto error;
+        error_setg(&error, "Invalid/empty CPU model name");
+        goto out;
     }
     name = model_pieces[0];
     features = model_pieces[1];
 
     if (cpu_x86_find_by_name(def, name) < 0) {
-        goto error;
+        error_setg(&error, "Unable to find CPU definition: %s", name);
+        goto out;
     }
 
     def->kvm_features |= kvm_default_features;
     def->ext_features |= CPUID_EXT_HYPERVISOR;
 
     if (cpu_x86_parse_featurestr(def, features) < 0) {
-        goto error;
+        error_setg(&error, "Invalid cpu_model string format: %s", cpu_model);
+        goto out;
     }
     assert(def->vendor1);
     env->cpuid_vendor1 = def->vendor1;
@@ -1632,17 +1635,15 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
                             "tsc-frequency", &error);
 
     object_property_set_str(OBJECT(cpu), def->model_id, "model-id", &error);
+
+out:
+    g_strfreev(model_pieces);
     if (error) {
         fprintf(stderr, "%s\n", error_get_pretty(error));
         error_free(error);
-        goto error;
+        return -1;
     }
-
-    g_strfreev(model_pieces);
     return 0;
-error:
-    g_strfreev(model_pieces);
-    return -1;
 }
 
 #if !defined(CONFIG_USER_ONLY)
commit 077c68c32897ea02b88c9a919627d93d3878ef15
Author: Igor Mammedov <imammedo at redhat.com>
Date:   Fri Jan 11 03:10:15 2013 +0100

    target-i386: Move setting defaults out of cpu_x86_parse_featurestr()
    
    No functional change, needed for simplifying conversion to properties.
    
    Signed-off-by: Igor Mammedov <imammedo at redhat.com>
    Reviewed-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 9a48e3f..e75b293 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1343,15 +1343,11 @@ static int cpu_x86_parse_featurestr(x86_def_t *x86_cpu_def, char *features)
     unsigned int i;
     char *featurestr; /* Single 'key=value" string being parsed */
     /* Features to be added */
-    FeatureWordArray plus_features = {
-        [FEAT_KVM] = kvm_default_features,
-    };
+    FeatureWordArray plus_features = { 0 };
     /* Features to be removed */
     FeatureWordArray minus_features = { 0 };
     uint32_t numvalue;
 
-    add_flagname_to_bitmaps("hypervisor", plus_features);
-
     featurestr = features ? strtok(features, ",") : NULL;
 
     while (featurestr) {
@@ -1607,6 +1603,9 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
         goto error;
     }
 
+    def->kvm_features |= kvm_default_features;
+    def->ext_features |= CPUID_EXT_HYPERVISOR;
+
     if (cpu_x86_parse_featurestr(def, features) < 0) {
         goto error;
     }
commit 07ca59450c9a0c5df65665ce46aa8487af59a1dd
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Mon Jan 7 16:20:48 2013 -0200

    target-i386: check/enforce: Check all feature words
    
    This adds the following feature words to the list of flags to be checked
    by kvm_check_features_against_host():
    
     - cpuid_7_0_ebx_features
     - ext4_features
     - kvm_features
     - svm_features
    
    This will ensure the "enforce" flag works as it should: it won't allow
    QEMU to be started unless every flag that was requested by the user or
    defined in the CPU model is supported by the host.
    
    This patch may cause existing configurations where "enforce" wasn't
    preventing QEMU from being started to abort QEMU. But that's exactly the
    point of this patch: if a flag was not supported by the host and QEMU
    wasn't aborting, it was a bug in the "enforce" code.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Gleb Natapov <gleb at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 8ec9929..9a48e3f 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1016,8 +1016,9 @@ static int unavailable_host_feature(FeatureWordInfo *f, uint32_t mask)
     return 0;
 }
 
-/* best effort attempt to inform user requested cpu flags aren't making
- * their way to the guest.
+/* Check if all requested cpu flags are making their way to the guest
+ *
+ * Returns 0 if all flags are supported by the host, non-zero otherwise.
  *
  * This function may be called only if KVM is enabled.
  */
@@ -1035,6 +1036,14 @@ static int kvm_check_features_against_host(x86_def_t *guest_def)
             FEAT_8000_0001_EDX },
         {&guest_def->ext3_features, &host_def.ext3_features,
             FEAT_8000_0001_ECX },
+        {&guest_def->ext4_features, &host_def.ext4_features,
+            FEAT_C000_0001_EDX },
+        {&guest_def->cpuid_7_0_ebx_features, &host_def.cpuid_7_0_ebx_features,
+            FEAT_7_0_EBX },
+        {&guest_def->svm_features, &host_def.svm_features,
+            FEAT_SVM },
+        {&guest_def->kvm_features, &host_def.kvm_features,
+            FEAT_KVM },
     };
 
     assert(kvm_enabled());
commit 89e49c8bea9ec81d2cca25f81f5e15c3a1d8b69c
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Mon Jan 7 16:20:47 2013 -0200

    target-i386/cpu.c: Add feature name array for ext4_features
    
    Feature names were taken from the X86_FEATURE_* constants in the Linux
    kernel code.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Gleb Natapov <gleb at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 0e531f9..8ec9929 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -95,6 +95,17 @@ static const char *ext3_feature_name[] = {
     NULL, NULL, NULL, NULL,
 };
 
+static const char *ext4_feature_name[] = {
+    NULL, NULL, "xstore", "xstore-en",
+    NULL, NULL, "xcrypt", "xcrypt-en",
+    "ace2", "ace2-en", "phe", "phe-en",
+    "pmm", "pmm-en", NULL, NULL,
+    NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+};
+
 static const char *kvm_feature_name[] = {
     "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock",
     "kvm_asyncpf", "kvm_steal_time", "kvm_pv_eoi", NULL,
@@ -147,6 +158,10 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
         .feat_names = ext3_feature_name,
         .cpuid_eax = 0x80000001, .cpuid_reg = R_ECX,
     },
+    [FEAT_C000_0001_EDX] = {
+        .feat_names = ext4_feature_name,
+        .cpuid_eax = 0xC0000001, .cpuid_reg = R_EDX,
+    },
     [FEAT_KVM] = {
         .feat_names = kvm_feature_name,
         .cpuid_eax = KVM_CPUID_FEATURES, .cpuid_reg = R_EAX,
@@ -1439,6 +1454,7 @@ static int cpu_x86_parse_featurestr(x86_def_t *x86_cpu_def, char *features)
     x86_cpu_def->ext_features |= plus_features[FEAT_1_ECX];
     x86_cpu_def->ext2_features |= plus_features[FEAT_8000_0001_EDX];
     x86_cpu_def->ext3_features |= plus_features[FEAT_8000_0001_ECX];
+    x86_cpu_def->ext4_features |= plus_features[FEAT_C000_0001_EDX];
     x86_cpu_def->kvm_features |= plus_features[FEAT_KVM];
     x86_cpu_def->svm_features |= plus_features[FEAT_SVM];
     x86_cpu_def->cpuid_7_0_ebx_features |= plus_features[FEAT_7_0_EBX];
@@ -1446,6 +1462,7 @@ static int cpu_x86_parse_featurestr(x86_def_t *x86_cpu_def, char *features)
     x86_cpu_def->ext_features &= ~minus_features[FEAT_1_ECX];
     x86_cpu_def->ext2_features &= ~minus_features[FEAT_8000_0001_EDX];
     x86_cpu_def->ext3_features &= ~minus_features[FEAT_8000_0001_ECX];
+    x86_cpu_def->ext4_features &= ~minus_features[FEAT_C000_0001_EDX];
     x86_cpu_def->kvm_features &= ~minus_features[FEAT_KVM];
     x86_cpu_def->svm_features &= ~minus_features[FEAT_SVM];
     x86_cpu_def->cpuid_7_0_ebx_features &= ~minus_features[FEAT_7_0_EBX];
commit bffd67b01d96d3a59bf74a2d38f00e59d4b9c774
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Mon Jan 7 16:20:46 2013 -0200

    target-i386: kvm_check_features_against_host(): Use feature_word_info
    
    Instead of carrying the CPUID leaf/register and feature name array on
    the model_features_t struct, move that information into
    feature_word_info so it can be reused by other functions.
    
    The goal is to eventually kill model_features_t entirely, but to do that
    we have to either convert x86_def_t.features to an array or use
    offsetof() inside FeatureWordInfo (to replace the pointers inside
    model_features_t). So by now just move most of the model_features_t
    fields to FeatureWordInfo except for the two pointers to local
    arguments.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Gleb Natapov <gleb at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index e17709c..0e531f9 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -126,16 +126,39 @@ static const char *cpuid_7_0_ebx_feature_name[] = {
 
 typedef struct FeatureWordInfo {
     const char **feat_names;
+    uint32_t cpuid_eax; /* Input EAX for CPUID */
+    int cpuid_reg;      /* R_* register constant */
 } FeatureWordInfo;
 
 static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
-    [FEAT_1_EDX] = { .feat_names = feature_name },
-    [FEAT_1_ECX] = { .feat_names = ext_feature_name },
-    [FEAT_8000_0001_EDX] = { .feat_names = ext2_feature_name },
-    [FEAT_8000_0001_ECX] = { .feat_names = ext3_feature_name },
-    [FEAT_KVM]   = { .feat_names = kvm_feature_name },
-    [FEAT_SVM]   = { .feat_names = svm_feature_name },
-    [FEAT_7_0_EBX] = { .feat_names = cpuid_7_0_ebx_feature_name },
+    [FEAT_1_EDX] = {
+        .feat_names = feature_name,
+        .cpuid_eax = 1, .cpuid_reg = R_EDX,
+    },
+    [FEAT_1_ECX] = {
+        .feat_names = ext_feature_name,
+        .cpuid_eax = 1, .cpuid_reg = R_ECX,
+    },
+    [FEAT_8000_0001_EDX] = {
+        .feat_names = ext2_feature_name,
+        .cpuid_eax = 0x80000001, .cpuid_reg = R_EDX,
+    },
+    [FEAT_8000_0001_ECX] = {
+        .feat_names = ext3_feature_name,
+        .cpuid_eax = 0x80000001, .cpuid_reg = R_ECX,
+    },
+    [FEAT_KVM] = {
+        .feat_names = kvm_feature_name,
+        .cpuid_eax = KVM_CPUID_FEATURES, .cpuid_reg = R_EAX,
+    },
+    [FEAT_SVM] = {
+        .feat_names = svm_feature_name,
+        .cpuid_eax = 0x8000000A, .cpuid_reg = R_EDX,
+    },
+    [FEAT_7_0_EBX] = {
+        .feat_names = cpuid_7_0_ebx_feature_name,
+        .cpuid_eax = 7, .cpuid_reg = R_EBX,
+    },
 };
 
 const char *get_register_name_32(unsigned int reg)
@@ -162,9 +185,7 @@ const char *get_register_name_32(unsigned int reg)
 typedef struct model_features_t {
     uint32_t *guest_feat;
     uint32_t *host_feat;
-    const char **flag_names;
-    uint32_t cpuid;
-    int reg;
+    FeatureWord feat_word;
 } model_features_t;
 
 int check_cpuid = 0;
@@ -962,19 +983,19 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
 #endif /* CONFIG_KVM */
 }
 
-static int unavailable_host_feature(struct model_features_t *f, uint32_t mask)
+static int unavailable_host_feature(FeatureWordInfo *f, uint32_t mask)
 {
     int i;
 
     for (i = 0; i < 32; ++i)
         if (1 << i & mask) {
-            const char *reg = get_register_name_32(f->reg);
+            const char *reg = get_register_name_32(f->cpuid_reg);
             assert(reg);
             fprintf(stderr, "warning: host doesn't support requested feature: "
                 "CPUID.%02XH:%s%s%s [bit %d]\n",
-                f->cpuid, reg,
-                f->flag_names[i] ? "." : "",
-                f->flag_names[i] ? f->flag_names[i] : "", i);
+                f->cpuid_eax, reg,
+                f->feat_names[i] ? "." : "",
+                f->feat_names[i] ? f->feat_names[i] : "", i);
             break;
         }
     return 0;
@@ -992,25 +1013,29 @@ static int kvm_check_features_against_host(x86_def_t *guest_def)
     int rv, i;
     struct model_features_t ft[] = {
         {&guest_def->features, &host_def.features,
-            feature_name, 0x00000001, R_EDX},
+            FEAT_1_EDX },
         {&guest_def->ext_features, &host_def.ext_features,
-            ext_feature_name, 0x00000001, R_ECX},
+            FEAT_1_ECX },
         {&guest_def->ext2_features, &host_def.ext2_features,
-            ext2_feature_name, 0x80000001, R_EDX},
+            FEAT_8000_0001_EDX },
         {&guest_def->ext3_features, &host_def.ext3_features,
-            ext3_feature_name, 0x80000001, R_ECX}
+            FEAT_8000_0001_ECX },
     };
 
     assert(kvm_enabled());
 
     kvm_cpu_fill_host(&host_def);
-    for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i)
-        for (mask = 1; mask; mask <<= 1)
+    for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i) {
+        FeatureWord w = ft[i].feat_word;
+        FeatureWordInfo *wi = &feature_word_info[w];
+        for (mask = 1; mask; mask <<= 1) {
             if (*ft[i].guest_feat & mask &&
                 !(*ft[i].host_feat & mask)) {
-                    unavailable_host_feature(&ft[i], mask);
-                    rv = 1;
-                }
+                unavailable_host_feature(wi, mask);
+                rv = 1;
+            }
+        }
+    }
     return rv;
 }
 
commit 5ef5787627c07d053c2628fe720e814561fbfbe3
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Mon Jan 7 16:20:45 2013 -0200

    target-i386/cpu: Introduce FeatureWord typedefs
    
    This introduces a FeatureWord enum, FeatureWordInfo struct (with
    generation information about a feature word), and a FeatureWordArray
    typedef, and changes add_flagname_to_bitmaps() code and
    cpu_x86_parse_featurestr() to use the new typedefs instead of separate
    variables for each feature word.
    
    This will help us keep the code at kvm_check_features_against_host(),
    cpu_x86_parse_featurestr() and add_flagname_to_bitmaps() sane while
    adding new feature name arrays.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Gleb Natapov <gleb at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index cb385fb..e17709c 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -124,6 +124,20 @@ static const char *cpuid_7_0_ebx_feature_name[] = {
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 };
 
+typedef struct FeatureWordInfo {
+    const char **feat_names;
+} FeatureWordInfo;
+
+static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+    [FEAT_1_EDX] = { .feat_names = feature_name },
+    [FEAT_1_ECX] = { .feat_names = ext_feature_name },
+    [FEAT_8000_0001_EDX] = { .feat_names = ext2_feature_name },
+    [FEAT_8000_0001_ECX] = { .feat_names = ext3_feature_name },
+    [FEAT_KVM]   = { .feat_names = kvm_feature_name },
+    [FEAT_SVM]   = { .feat_names = svm_feature_name },
+    [FEAT_7_0_EBX] = { .feat_names = cpuid_7_0_ebx_feature_name },
+};
+
 const char *get_register_name_32(unsigned int reg)
 {
     static const char *reg_names[CPU_NB_REGS32] = {
@@ -271,23 +285,20 @@ static bool lookup_feature(uint32_t *pval, const char *s, const char *e,
     return found;
 }
 
-static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
-                                    uint32_t *ext_features,
-                                    uint32_t *ext2_features,
-                                    uint32_t *ext3_features,
-                                    uint32_t *kvm_features,
-                                    uint32_t *svm_features,
-                                    uint32_t *cpuid_7_0_ebx_features)
+static void add_flagname_to_bitmaps(const char *flagname,
+                                    FeatureWordArray words)
 {
-    if (!lookup_feature(features, flagname, NULL, feature_name) &&
-        !lookup_feature(ext_features, flagname, NULL, ext_feature_name) &&
-        !lookup_feature(ext2_features, flagname, NULL, ext2_feature_name) &&
-        !lookup_feature(ext3_features, flagname, NULL, ext3_feature_name) &&
-        !lookup_feature(kvm_features, flagname, NULL, kvm_feature_name) &&
-        !lookup_feature(svm_features, flagname, NULL, svm_feature_name) &&
-        !lookup_feature(cpuid_7_0_ebx_features, flagname, NULL,
-                        cpuid_7_0_ebx_feature_name))
-            fprintf(stderr, "CPU feature %s not found\n", flagname);
+    FeatureWord w;
+    for (w = 0; w < FEATURE_WORDS; w++) {
+        FeatureWordInfo *wi = &feature_word_info[w];
+        if (wi->feat_names &&
+            lookup_feature(&words[w], flagname, NULL, wi->feat_names)) {
+            break;
+        }
+    }
+    if (w == FEATURE_WORDS) {
+        fprintf(stderr, "CPU feature %s not found\n", flagname);
+    }
 }
 
 typedef struct x86_def_t {
@@ -1283,35 +1294,23 @@ static int cpu_x86_parse_featurestr(x86_def_t *x86_cpu_def, char *features)
     unsigned int i;
     char *featurestr; /* Single 'key=value" string being parsed */
     /* Features to be added */
-    uint32_t plus_features = 0, plus_ext_features = 0;
-    uint32_t plus_ext2_features = 0, plus_ext3_features = 0;
-    uint32_t plus_kvm_features = kvm_default_features, plus_svm_features = 0;
-    uint32_t plus_7_0_ebx_features = 0;
+    FeatureWordArray plus_features = {
+        [FEAT_KVM] = kvm_default_features,
+    };
     /* Features to be removed */
-    uint32_t minus_features = 0, minus_ext_features = 0;
-    uint32_t minus_ext2_features = 0, minus_ext3_features = 0;
-    uint32_t minus_kvm_features = 0, minus_svm_features = 0;
-    uint32_t minus_7_0_ebx_features = 0;
+    FeatureWordArray minus_features = { 0 };
     uint32_t numvalue;
 
-    add_flagname_to_bitmaps("hypervisor", &plus_features,
-            &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
-            &plus_kvm_features, &plus_svm_features,  &plus_7_0_ebx_features);
+    add_flagname_to_bitmaps("hypervisor", plus_features);
 
     featurestr = features ? strtok(features, ",") : NULL;
 
     while (featurestr) {
         char *val;
         if (featurestr[0] == '+') {
-            add_flagname_to_bitmaps(featurestr + 1, &plus_features,
-                            &plus_ext_features, &plus_ext2_features,
-                            &plus_ext3_features, &plus_kvm_features,
-                            &plus_svm_features, &plus_7_0_ebx_features);
+            add_flagname_to_bitmaps(featurestr + 1, plus_features);
         } else if (featurestr[0] == '-') {
-            add_flagname_to_bitmaps(featurestr + 1, &minus_features,
-                            &minus_ext_features, &minus_ext2_features,
-                            &minus_ext3_features, &minus_kvm_features,
-                            &minus_svm_features, &minus_7_0_ebx_features);
+            add_flagname_to_bitmaps(featurestr + 1, minus_features);
         } else if ((val = strchr(featurestr, '='))) {
             *val = 0; val++;
             if (!strcmp(featurestr, "family")) {
@@ -1411,20 +1410,20 @@ static int cpu_x86_parse_featurestr(x86_def_t *x86_cpu_def, char *features)
         }
         featurestr = strtok(NULL, ",");
     }
-    x86_cpu_def->features |= plus_features;
-    x86_cpu_def->ext_features |= plus_ext_features;
-    x86_cpu_def->ext2_features |= plus_ext2_features;
-    x86_cpu_def->ext3_features |= plus_ext3_features;
-    x86_cpu_def->kvm_features |= plus_kvm_features;
-    x86_cpu_def->svm_features |= plus_svm_features;
-    x86_cpu_def->cpuid_7_0_ebx_features |= plus_7_0_ebx_features;
-    x86_cpu_def->features &= ~minus_features;
-    x86_cpu_def->ext_features &= ~minus_ext_features;
-    x86_cpu_def->ext2_features &= ~minus_ext2_features;
-    x86_cpu_def->ext3_features &= ~minus_ext3_features;
-    x86_cpu_def->kvm_features &= ~minus_kvm_features;
-    x86_cpu_def->svm_features &= ~minus_svm_features;
-    x86_cpu_def->cpuid_7_0_ebx_features &= ~minus_7_0_ebx_features;
+    x86_cpu_def->features |= plus_features[FEAT_1_EDX];
+    x86_cpu_def->ext_features |= plus_features[FEAT_1_ECX];
+    x86_cpu_def->ext2_features |= plus_features[FEAT_8000_0001_EDX];
+    x86_cpu_def->ext3_features |= plus_features[FEAT_8000_0001_ECX];
+    x86_cpu_def->kvm_features |= plus_features[FEAT_KVM];
+    x86_cpu_def->svm_features |= plus_features[FEAT_SVM];
+    x86_cpu_def->cpuid_7_0_ebx_features |= plus_features[FEAT_7_0_EBX];
+    x86_cpu_def->features &= ~minus_features[FEAT_1_EDX];
+    x86_cpu_def->ext_features &= ~minus_features[FEAT_1_ECX];
+    x86_cpu_def->ext2_features &= ~minus_features[FEAT_8000_0001_EDX];
+    x86_cpu_def->ext3_features &= ~minus_features[FEAT_8000_0001_ECX];
+    x86_cpu_def->kvm_features &= ~minus_features[FEAT_KVM];
+    x86_cpu_def->svm_features &= ~minus_features[FEAT_SVM];
+    x86_cpu_def->cpuid_7_0_ebx_features &= ~minus_features[FEAT_7_0_EBX];
     if (check_cpuid && kvm_enabled()) {
         if (kvm_check_features_against_host(x86_cpu_def) && enforce_cpuid)
             goto error;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index e56921b..e4a7c50 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -361,6 +361,21 @@
 
 #define MSR_VM_HSAVE_PA                 0xc0010117
 
+/* CPUID feature words */
+typedef enum FeatureWord {
+    FEAT_1_EDX,         /* CPUID[1].EDX */
+    FEAT_1_ECX,         /* CPUID[1].ECX */
+    FEAT_7_0_EBX,       /* CPUID[EAX=7,ECX=0].EBX */
+    FEAT_8000_0001_EDX, /* CPUID[8000_0001].EDX */
+    FEAT_8000_0001_ECX, /* CPUID[8000_0001].ECX */
+    FEAT_C000_0001_EDX, /* CPUID[C000_0001].EDX */
+    FEAT_KVM,           /* CPUID[4000_0001].EAX (KVM_CPUID_FEATURES) */
+    FEAT_SVM,           /* CPUID[8000_000A].EDX */
+    FEATURE_WORDS,
+} FeatureWord;
+
+typedef uint32_t FeatureWordArray[FEATURE_WORDS];
+
 /* cpuid_features bits */
 #define CPUID_FP87 (1 << 0)
 #define CPUID_VME  (1 << 1)
commit 6a4784ce6b95b013a13504ead9ab62975faf6eff
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Mon Jan 7 16:20:44 2013 -0200

    target-i386: Disable kvm_mmu by default
    
    KVM_CAP_PV_MMU capability reporting was removed from the kernel since
    v2.6.33 (see commit a68a6a7282373), and was completely removed from the
    kernel since v3.3 (see commit fb92045843). It doesn't make sense to keep
    it enabled by default, as it would cause unnecessary hassle when using
    the "enforce" flag.
    
    This disables kvm_mmu on all machine-types. With this fix, the possible
    scenarios when migrating from QEMU <= 1.3 to QEMU 1.4 are:
    
    ------------+----------+----------------------------------------------------
     src kernel | dst kern.| Result
    ------------+----------+----------------------------------------------------
     >= 2.6.33  | any      | kvm_mmu was already disabled and will stay disabled
     <= 2.6.32  | >= 3.3   | correct live migration is impossible
     <= 2.6.32  | <= 3.2   | kvm_mmu will be disabled on next guest reboot *
    ------------+----------+----------------------------------------------------
    
     * If they are running kernel <= 2.6.32 and want kvm_mmu to be kept
       enabled on guest reboot, they can explicitly add +kvm_mmu to the QEMU
       command-line. Using 2.6.33 and higher, it is not possible to enable
       kvm_mmu explicitly anymore.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Gleb Natapov <gleb at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 992b614..cb385fb 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -159,7 +159,6 @@ int enforce_cpuid = 0;
 #if defined(CONFIG_KVM)
 static uint32_t kvm_default_features = (1 << KVM_FEATURE_CLOCKSOURCE) |
         (1 << KVM_FEATURE_NOP_IO_DELAY) |
-        (1 << KVM_FEATURE_MMU_OP) |
         (1 << KVM_FEATURE_CLOCKSOURCE2) |
         (1 << KVM_FEATURE_ASYNC_PF) |
         (1 << KVM_FEATURE_STEAL_TIME) |
commit 9ca5892328a40bfa9c24c847441761c4729ae3f3
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Mon Jan 7 16:20:42 2013 -0200

    kvm: Add fake KVM constants to avoid #ifdefs on KVM-specific code
    
    Any KVM-specific code that use these constants must check if
    kvm_enabled() is true before using them.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Gleb Natapov <gleb at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 2fe8f8a..6bdd513 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -22,6 +22,20 @@
 #ifdef CONFIG_KVM
 #include <linux/kvm.h>
 #include <linux/kvm_para.h>
+#else
+/* These constants must never be used at runtime if kvm_enabled() is false.
+ * They exist so we don't need #ifdefs around KVM-specific code that already
+ * checks kvm_enabled() properly.
+ */
+#define KVM_CPUID_SIGNATURE      0
+#define KVM_CPUID_FEATURES       0
+#define KVM_FEATURE_CLOCKSOURCE  0
+#define KVM_FEATURE_NOP_IO_DELAY 0
+#define KVM_FEATURE_MMU_OP       0
+#define KVM_FEATURE_CLOCKSOURCE2 0
+#define KVM_FEATURE_ASYNC_PF     0
+#define KVM_FEATURE_STEAL_TIME   0
+#define KVM_FEATURE_PV_EOI       0
 #endif
 
 extern int kvm_allowed;
commit 38d8f5c84e7c02f2523005dddc31939ca18232dd
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Dec 17 19:47:15 2012 +0100

    exec: Return CPUState from qemu_get_cpu()
    
    Move the declaration to qemu/cpu.h and add documentation.
    The implementation still depends on CPUArchState for CPU iteration.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/exec.c b/exec.c
index e5265e6..5689613 100644
--- a/exec.c
+++ b/exec.c
@@ -247,10 +247,10 @@ static const VMStateDescription vmstate_cpu_common = {
 };
 #endif
 
-CPUArchState *qemu_get_cpu(int index)
+CPUState *qemu_get_cpu(int index)
 {
     CPUArchState *env = first_cpu;
-    CPUState *cpu;
+    CPUState *cpu = NULL;
 
     while (env) {
         cpu = ENV_GET_CPU(env);
@@ -260,7 +260,7 @@ CPUArchState *qemu_get_cpu(int index)
         env = env->next_cpu;
     }
 
-    return env;
+    return cpu;
 }
 
 void cpu_exec_init(CPUArchState *env)
diff --git a/hw/pxa2xx_gpio.c b/hw/pxa2xx_gpio.c
index c02c295..eec2ea3 100644
--- a/hw/pxa2xx_gpio.c
+++ b/hw/pxa2xx_gpio.c
@@ -277,7 +277,7 @@ static int pxa2xx_gpio_initfn(SysBusDevice *dev)
 
     s = FROM_SYSBUS(PXA2xxGPIOInfo, dev);
 
-    s->cpu = arm_env_get_cpu(qemu_get_cpu(s->ncpu));
+    s->cpu = ARM_CPU(qemu_get_cpu(s->ncpu));
 
     qdev_init_gpio_in(&dev->qdev, pxa2xx_gpio_set, s->lines);
     qdev_init_gpio_out(&dev->qdev, s->handler, s->lines);
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 439e88d..249e046 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -354,7 +354,6 @@ int page_check_range(target_ulong start, target_ulong len, int flags);
 #endif
 
 CPUArchState *cpu_copy(CPUArchState *env);
-CPUArchState *qemu_get_cpu(int cpu);
 
 #define CPU_DUMP_CODE 0x00010000
 #define CPU_DUMP_FPU 0x00020000 /* dump FPU register state, not just integer */
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index d5e0a40..773caf9 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -156,5 +156,15 @@ bool cpu_is_stopped(CPUState *cpu);
  */
 void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data);
 
+/**
+ * qemu_get_cpu:
+ * @index: The CPUState at cpu_index value of the CPU to obtain.
+ *
+ * Gets a CPU matching @index.
+ *
+ * Returns: The CPU or %NULL if there is no matching CPU.
+ */
+CPUState *qemu_get_cpu(int index);
+
 
 #endif
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 1816a0e..1bca4a1 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -585,8 +585,9 @@ static inline void mips_tc_sleep(MIPSCPU *cpu, int tc)
           walking the list of CPUMIPSStates.  */
 static CPUMIPSState *mips_cpu_map_tc(CPUMIPSState *env, int *tc)
 {
+    MIPSCPU *cpu;
     CPUState *cs;
-    CPUMIPSState *other;
+    CPUState *other_cs;
     int vpe_idx;
     int tc_idx = *tc;
 
@@ -599,8 +600,12 @@ static CPUMIPSState *mips_cpu_map_tc(CPUMIPSState *env, int *tc)
     cs = CPU(mips_env_get_cpu(env));
     vpe_idx = tc_idx / cs->nr_threads;
     *tc = tc_idx % cs->nr_threads;
-    other = qemu_get_cpu(vpe_idx);
-    return other ? other : env;
+    other_cs = qemu_get_cpu(vpe_idx);
+    if (other_cs == NULL) {
+        return env;
+    }
+    cpu = MIPS_CPU(other_cs);
+    return &cpu->env;
 }
 
 /* The per VPE CP0_Status register shares some fields with the per TC
commit 4a1e40b5091bcff5f8ea3fe9963eaa8e76b16389
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Dec 17 19:39:30 2012 +0100

    xen: Simplify halting of first CPU
    
    Use the global first_cpu variable to halt the CPU rather than using a
    local first_cpu initialized from qemu_get_cpu(0).
    
    This will allow to change qemu_get_cpu() return type to CPUState
    despite use of the CPU_COMMON halted field in the reset handler.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/xen-all.c b/xen-all.c
index 19bcfd1..110f958 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -585,9 +585,7 @@ static void xen_reset_vcpu(void *opaque)
 
 void xen_vcpu_init(void)
 {
-    CPUArchState *first_cpu;
-
-    if ((first_cpu = qemu_get_cpu(0))) {
+    if (first_cpu != NULL) {
         qemu_register_reset(xen_reset_vcpu, first_cpu);
         xen_reset_vcpu(first_cpu);
     }
commit 504134d27f15aa94f6d2b5c45eaa804a8dfb5a4c
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Dec 17 06:38:45 2012 +0100

    kvm: Pass CPUState to kvm_init_vcpu()
    
    CPUArchState is no longer needed, and it thereby no longer depends on
    NEED_CPU_H.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/cpus.c b/cpus.c
index bbb8961..a4390c3 100644
--- a/cpus.c
+++ b/cpus.c
@@ -742,7 +742,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
     cpu->thread_id = qemu_get_thread_id();
     cpu_single_env = env;
 
-    r = kvm_init_vcpu(env);
+    r = kvm_init_vcpu(cpu);
     if (r < 0) {
         fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r));
         exit(1);
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 3db19ff..2fe8f8a 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -17,6 +17,7 @@
 #include <errno.h>
 #include "config-host.h"
 #include "qemu/queue.h"
+#include "qom/cpu.h"
 
 #ifdef CONFIG_KVM
 #include <linux/kvm.h>
@@ -120,9 +121,9 @@ int kvm_has_many_ioeventfds(void);
 int kvm_has_gsi_routing(void);
 int kvm_has_intx_set_mask(void);
 
-#ifdef NEED_CPU_H
-int kvm_init_vcpu(CPUArchState *env);
+int kvm_init_vcpu(CPUState *cpu);
 
+#ifdef NEED_CPU_H
 int kvm_cpu_exec(CPUArchState *env);
 
 #if !defined(CONFIG_USER_ONLY)
diff --git a/kvm-all.c b/kvm-all.c
index 4ba77de..6e2164b 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -214,9 +214,8 @@ static void kvm_reset_vcpu(void *opaque)
     kvm_arch_reset_vcpu(cpu);
 }
 
-int kvm_init_vcpu(CPUArchState *env)
+int kvm_init_vcpu(CPUState *cpu)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
     KVMState *s = kvm_state;
     long mmap_size;
     int ret;
diff --git a/kvm-stub.c b/kvm-stub.c
index 81f8967..47f8dca 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -24,7 +24,7 @@ bool kvm_irqfds_allowed;
 bool kvm_msi_via_irqfd_allowed;
 bool kvm_gsi_routing_allowed;
 
-int kvm_init_vcpu(CPUArchState *env)
+int kvm_init_vcpu(CPUState *cpu)
 {
     return -ENOSYS;
 }
commit 55e5c2850293547203874098f7cec148ffd12dfa
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Dec 17 06:18:02 2012 +0100

    cpu: Move cpu_index field to CPUState
    
    Note that target-alpha accesses this field from TCG, now using a
    negative offset. Therefore the field is placed last in CPUState.
    
    Pass PowerPCCPU to [kvm]ppc_fixup_cpu() to facilitate this change.
    
    Move common parts of mips cpu_state_reset() to mips_cpu_reset().
    
    Acked-by: Richard Henderson <rth at twiddle.net> (for alpha)
    [AF: Rebased onto ppc CPU subclasses and openpic changes]
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/cpus.c b/cpus.c
index d68231a..bbb8961 100644
--- a/cpus.c
+++ b/cpus.c
@@ -390,13 +390,15 @@ void hw_error(const char *fmt, ...)
 {
     va_list ap;
     CPUArchState *env;
+    CPUState *cpu;
 
     va_start(ap, fmt);
     fprintf(stderr, "qemu: hardware error: ");
     vfprintf(stderr, fmt, ap);
     fprintf(stderr, "\n");
-    for(env = first_cpu; env != NULL; env = env->next_cpu) {
-        fprintf(stderr, "CPU #%d:\n", env->cpu_index);
+    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        cpu = ENV_GET_CPU(env);
+        fprintf(stderr, "CPU #%d:\n", cpu->cpu_index);
         cpu_dump_state(env, stderr, fprintf, CPU_DUMP_FPU);
     }
     va_end(ap);
@@ -1166,7 +1168,7 @@ void set_numa_modes(void)
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
         cpu = ENV_GET_CPU(env);
         for (i = 0; i < nb_numa_nodes; i++) {
-            if (test_bit(env->cpu_index, node_cpumask[i])) {
+            if (test_bit(cpu->cpu_index, node_cpumask[i])) {
                 cpu->numa_node = i;
             }
         }
@@ -1215,7 +1217,7 @@ CpuInfoList *qmp_query_cpus(Error **errp)
 
         info = g_malloc0(sizeof(*info));
         info->value = g_malloc0(sizeof(*info->value));
-        info->value->CPU = env->cpu_index;
+        info->value->CPU = cpu->cpu_index;
         info->value->current = (env == first_cpu);
         info->value->halted = env->halted;
         info->value->thread_id = cpu->thread_id;
@@ -1253,6 +1255,7 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
     FILE *f;
     uint32_t l;
     CPUArchState *env;
+    CPUState *cpu;
     uint8_t buf[1024];
 
     if (!has_cpu) {
@@ -1260,7 +1263,8 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
     }
 
     for (env = first_cpu; env; env = env->next_cpu) {
-        if (cpu_index == env->cpu_index) {
+        cpu = ENV_GET_CPU(env);
+        if (cpu_index == cpu->cpu_index) {
             break;
         }
     }
diff --git a/exec.c b/exec.c
index de5b27d..e5265e6 100644
--- a/exec.c
+++ b/exec.c
@@ -247,13 +247,16 @@ static const VMStateDescription vmstate_cpu_common = {
 };
 #endif
 
-CPUArchState *qemu_get_cpu(int cpu)
+CPUArchState *qemu_get_cpu(int index)
 {
     CPUArchState *env = first_cpu;
+    CPUState *cpu;
 
     while (env) {
-        if (env->cpu_index == cpu)
+        cpu = ENV_GET_CPU(env);
+        if (cpu->cpu_index == index) {
             break;
+        }
         env = env->next_cpu;
     }
 
@@ -276,7 +279,7 @@ void cpu_exec_init(CPUArchState *env)
         penv = &(*penv)->next_cpu;
         cpu_index++;
     }
-    env->cpu_index = cpu_index;
+    cpu->cpu_index = cpu_index;
     cpu->numa_node = 0;
     QTAILQ_INIT(&env->breakpoints);
     QTAILQ_INIT(&env->watchpoints);
@@ -529,7 +532,6 @@ CPUArchState *cpu_copy(CPUArchState *env)
 {
     CPUArchState *new_env = cpu_init(env->cpu_model_str);
     CPUArchState *next_cpu = new_env->next_cpu;
-    int cpu_index = new_env->cpu_index;
 #if defined(TARGET_HAS_ICE)
     CPUBreakpoint *bp;
     CPUWatchpoint *wp;
@@ -537,9 +539,8 @@ CPUArchState *cpu_copy(CPUArchState *env)
 
     memcpy(new_env, env, sizeof(CPUArchState));
 
-    /* Preserve chaining and index. */
+    /* Preserve chaining. */
     new_env->next_cpu = next_cpu;
-    new_env->cpu_index = cpu_index;
 
     /* Clone all break/watchpoints.
        Note: Once we support ptrace with hw-debug register access, make sure
diff --git a/gdbstub.c b/gdbstub.c
index e62dc79..6cd26f1 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2401,9 +2401,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             thread = strtoull(p+16, (char **)&p, 16);
             env = find_cpu(thread);
             if (env != NULL) {
+                CPUState *cpu = ENV_GET_CPU(env);
                 cpu_synchronize_state(env);
                 len = snprintf((char *)mem_buf, sizeof(mem_buf),
-                               "CPU#%d [%s]", env->cpu_index,
+                               "CPU#%d [%s]", cpu->cpu_index,
                                env->halted ? "halted " : "running");
                 memtohex(buf, mem_buf, len);
                 put_packet(s, buf);
diff --git a/hw/alpha_typhoon.c b/hw/alpha_typhoon.c
index dafb35d..bf9aabf 100644
--- a/hw/alpha_typhoon.c
+++ b/hw/alpha_typhoon.c
@@ -75,6 +75,7 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
 {
     CPUAlphaState *env = cpu_single_env;
     TyphoonState *s = opaque;
+    CPUState *cpu;
     uint64_t ret = 0;
 
     if (addr & 4) {
@@ -95,7 +96,8 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
 
     case 0x0080:
         /* MISC: Miscellaneous Register.  */
-        ret = s->cchip.misc | (env->cpu_index & 3);
+        cpu = ENV_GET_CPU(env);
+        ret = s->cchip.misc | (cpu->cpu_index & 3);
         break;
 
     case 0x00c0:
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 466dbf7..90e43d0 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -39,7 +39,8 @@ static const uint8_t gic_id[] = {
 static inline int gic_get_current_cpu(GICState *s)
 {
     if (s->num_cpu > 1) {
-        return cpu_single_env->cpu_index;
+        CPUState *cpu = ENV_GET_CPU(cpu_single_env);
+        return cpu->cpu_index;
     }
     return 0;
 }
diff --git a/hw/arm_mptimer.c b/hw/arm_mptimer.c
index 0cd3853..cdfd623 100644
--- a/hw/arm_mptimer.c
+++ b/hw/arm_mptimer.c
@@ -49,11 +49,13 @@ typedef struct {
 
 static inline int get_current_cpu(arm_mptimer_state *s)
 {
-    if (cpu_single_env->cpu_index >= s->num_cpu) {
+    CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
+
+    if (cpu_single_cpu->cpu_index >= s->num_cpu) {
         hw_error("arm_mptimer: num-cpu %d but this cpu is %d!\n",
-                 s->num_cpu, cpu_single_env->cpu_index);
+                 s->num_cpu, cpu_single_cpu->cpu_index);
     }
-    return cpu_single_env->cpu_index;
+    return cpu_single_cpu->cpu_index;
 }
 
 static inline void timerblock_update_irq(timerblock *tb)
diff --git a/hw/openpic.c b/hw/openpic.c
index 23fa8f9..f6cc07b 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -153,11 +153,14 @@ static const int debug_openpic = 0;
 
 static int get_current_cpu(void)
 {
+    CPUState *cpu_single_cpu;
+
     if (!cpu_single_env) {
         return -1;
     }
 
-    return cpu_single_env->cpu_index;
+    cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
+    return cpu_single_cpu->cpu_index;
 }
 
 static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 3a9e1c7..7b3e2e6 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -239,25 +239,28 @@ static int ppce500_load_device_tree(CPUPPCState *env,
     /* We need to generate the cpu nodes in reverse order, so Linux can pick
        the first node as boot node and be happy */
     for (i = smp_cpus - 1; i >= 0; i--) {
+        CPUState *cpu = NULL;
         char cpu_name[128];
         uint64_t cpu_release_addr = MPC8544_SPIN_BASE + (i * 0x20);
 
         for (env = first_cpu; env != NULL; env = env->next_cpu) {
-            if (env->cpu_index == i) {
+            cpu = ENV_GET_CPU(env);
+            if (cpu->cpu_index == i) {
                 break;
             }
         }
 
-        if (!env) {
+        if (cpu == NULL) {
             continue;
         }
 
-        snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x", env->cpu_index);
+        snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x",
+                 cpu->cpu_index);
         qemu_devtree_add_subnode(fdt, cpu_name);
         qemu_devtree_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq);
         qemu_devtree_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);
         qemu_devtree_setprop_string(fdt, cpu_name, "device_type", "cpu");
-        qemu_devtree_setprop_cell(fdt, cpu_name, "reg", env->cpu_index);
+        qemu_devtree_setprop_cell(fdt, cpu_name, "reg", cpu->cpu_index);
         qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-line-size",
                                   env->dcache_line_size);
         qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-line-size",
@@ -265,7 +268,7 @@ static int ppce500_load_device_tree(CPUPPCState *env,
         qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-size", 0x8000);
         qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-size", 0x8000);
         qemu_devtree_setprop_cell(fdt, cpu_name, "bus-frequency", 0);
-        if (env->cpu_index) {
+        if (cpu->cpu_index) {
             qemu_devtree_setprop_string(fdt, cpu_name, "status", "disabled");
             qemu_devtree_setprop_string(fdt, cpu_name, "enable-method", "spin-table");
             qemu_devtree_setprop_u64(fdt, cpu_name, "cpu-release-addr",
@@ -479,6 +482,7 @@ void ppce500_init(PPCE500Params *params)
     irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
     for (i = 0; i < smp_cpus; i++) {
         PowerPCCPU *cpu;
+        CPUState *cs;
         qemu_irq *input;
 
         cpu = cpu_ppc_init(params->cpu_model);
@@ -487,6 +491,7 @@ void ppce500_init(PPCE500Params *params)
             exit(1);
         }
         env = &cpu->env;
+        cs = CPU(cpu);
 
         if (!firstenv) {
             firstenv = env;
@@ -496,7 +501,7 @@ void ppce500_init(PPCE500Params *params)
         input = (qemu_irq *)env->irq_inputs;
         irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT];
         irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT];
-        env->spr[SPR_BOOKE_PIR] = env->cpu_index = i;
+        env->spr[SPR_BOOKE_PIR] = cs->cpu_index = i;
         env->mpic_iack = MPC8544_CCSRBAR_BASE +
                          MPC8544_MPIC_REGS_OFFSET + 0x200A0;
 
diff --git a/hw/ppce500_spin.c b/hw/ppce500_spin.c
index 1b2c34f..4c206e2 100644
--- a/hw/ppce500_spin.c
+++ b/hw/ppce500_spin.c
@@ -124,21 +124,23 @@ static void spin_write(void *opaque, hwaddr addr, uint64_t value,
     SpinState *s = opaque;
     int env_idx = addr / sizeof(SpinInfo);
     CPUPPCState *env;
+    CPUState *cpu = NULL;
     SpinInfo *curspin = &s->spin[env_idx];
     uint8_t *curspin_p = (uint8_t*)curspin;
 
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        if (env->cpu_index == env_idx) {
+        cpu = CPU(ppc_env_get_cpu(env));
+        if (cpu->cpu_index == env_idx) {
             break;
         }
     }
 
-    if (!env) {
+    if (cpu == NULL) {
         /* Unknown CPU */
         return;
     }
 
-    if (!env->cpu_index) {
+    if (cpu->cpu_index == 0) {
         /* primary CPU doesn't spin */
         return;
     }
diff --git a/hw/pxa.h b/hw/pxa.h
index c2577d1..668232c 100644
--- a/hw/pxa.h
+++ b/hw/pxa.h
@@ -69,7 +69,7 @@ DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu);
 
 /* pxa2xx_gpio.c */
 DeviceState *pxa2xx_gpio_init(hwaddr base,
-                CPUARMState *env, DeviceState *pic, int lines);
+                              ARMCPU *cpu, DeviceState *pic, int lines);
 void pxa2xx_gpio_read_notifier(DeviceState *dev, qemu_irq handler);
 
 /* pxa2xx_dma.c */
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index f3dffef..492805f 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -2045,7 +2045,7 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
                     qdev_get_gpio_in(s->pic, PXA27X_PIC_OST_4_11),
                     NULL);
 
-    s->gpio = pxa2xx_gpio_init(0x40e00000, &s->cpu->env, s->pic, 121);
+    s->gpio = pxa2xx_gpio_init(0x40e00000, s->cpu, s->pic, 121);
 
     dinfo = drive_get(IF_SD, 0, 0);
     if (!dinfo) {
@@ -2176,7 +2176,7 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
                     qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 3),
                     NULL);
 
-    s->gpio = pxa2xx_gpio_init(0x40e00000, &s->cpu->env, s->pic, 85);
+    s->gpio = pxa2xx_gpio_init(0x40e00000, s->cpu, s->pic, 85);
 
     dinfo = drive_get(IF_SD, 0, 0);
     if (!dinfo) {
diff --git a/hw/pxa2xx_gpio.c b/hw/pxa2xx_gpio.c
index 016833d..c02c295 100644
--- a/hw/pxa2xx_gpio.c
+++ b/hw/pxa2xx_gpio.c
@@ -250,13 +250,14 @@ static const MemoryRegionOps pxa_gpio_ops = {
 };
 
 DeviceState *pxa2xx_gpio_init(hwaddr base,
-                CPUARMState *env, DeviceState *pic, int lines)
+                              ARMCPU *cpu, DeviceState *pic, int lines)
 {
+    CPUState *cs = CPU(cpu);
     DeviceState *dev;
 
     dev = qdev_create(NULL, "pxa2xx-gpio");
     qdev_prop_set_int32(dev, "lines", lines);
-    qdev_prop_set_int32(dev, "ncpu", env->cpu_index);
+    qdev_prop_set_int32(dev, "ncpu", cs->cpu_index);
     qdev_init_nofail(dev);
 
     sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
diff --git a/hw/spapr.c b/hw/spapr.c
index a61c71e..76aa09b 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -148,20 +148,20 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)
     assert(spapr->cpu_model);
 
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        cpu = ENV_GET_CPU(env);
+        cpu = CPU(ppc_env_get_cpu(env));
         uint32_t associativity[] = {cpu_to_be32(0x5),
                                     cpu_to_be32(0x0),
                                     cpu_to_be32(0x0),
                                     cpu_to_be32(0x0),
                                     cpu_to_be32(cpu->numa_node),
-                                    cpu_to_be32(env->cpu_index)};
+                                    cpu_to_be32(cpu->cpu_index)};
 
-        if ((env->cpu_index % smt) != 0) {
+        if ((cpu->cpu_index % smt) != 0) {
             continue;
         }
 
         snprintf(cpu_model, 32, "/cpus/%s@%x", spapr->cpu_model,
-                 env->cpu_index);
+                 cpu->cpu_index);
 
         offset = fdt_path_offset(fdt, cpu_model);
         if (offset < 0) {
@@ -310,7 +310,8 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
     spapr->cpu_model = g_strdup(modelname);
 
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        int index = env->cpu_index;
+        CPUState *cpu = CPU(ppc_env_get_cpu(env));
+        int index = cpu->cpu_index;
         uint32_t servers_prop[smp_threads];
         uint32_t gservers_prop[smp_threads * 2];
         char *nodename;
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index afb1297..2889742 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -467,9 +467,11 @@ static target_ulong h_register_vpa(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     target_ulong vpa = args[2];
     target_ulong ret = H_PARAMETER;
     CPUPPCState *tenv;
+    CPUState *tcpu;
 
     for (tenv = first_cpu; tenv; tenv = tenv->next_cpu) {
-        if (tenv->cpu_index == procno) {
+        tcpu = CPU(ppc_env_get_cpu(tenv));
+        if (tcpu->cpu_index == procno) {
             break;
         }
     }
diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c
index 81eecd0..5ec787f 100644
--- a/hw/spapr_rtas.c
+++ b/hw/spapr_rtas.c
@@ -131,6 +131,7 @@ static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr,
 {
     target_ulong id;
     CPUPPCState *env;
+    CPUState *cpu;
 
     if (nargs != 1 || nret != 2) {
         rtas_st(rets, 0, -3);
@@ -139,7 +140,8 @@ static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr,
 
     id = rtas_ld(args, 0);
     for (env = first_cpu; env; env = env->next_cpu) {
-        if (env->cpu_index != id) {
+        cpu = CPU(ppc_env_get_cpu(env));
+        if (cpu->cpu_index != id) {
             continue;
         }
 
@@ -176,9 +178,9 @@ static void rtas_start_cpu(sPAPREnvironment *spapr,
     r3 = rtas_ld(args, 2);
 
     for (env = first_cpu; env; env = env->next_cpu) {
-        cpu = ENV_GET_CPU(env);
+        cpu = CPU(ppc_env_get_cpu(env));
 
-        if (env->cpu_index != id) {
+        if (cpu->cpu_index != id) {
             continue;
         }
 
diff --git a/hw/xics.c b/hw/xics.c
index 55899ce..9ef0d61 100644
--- a/hw/xics.c
+++ b/hw/xics.c
@@ -357,10 +357,10 @@ void xics_set_irq_type(struct icp_state *icp, int irq, bool lsi)
 static target_ulong h_cppr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                            target_ulong opcode, target_ulong *args)
 {
-    CPUPPCState *env = &cpu->env;
+    CPUState *cs = CPU(cpu);
     target_ulong cppr = args[0];
 
-    icp_set_cppr(spapr->icp, env->cpu_index, cppr);
+    icp_set_cppr(spapr->icp, cs->cpu_index, cppr);
     return H_SUCCESS;
 }
 
@@ -376,14 +376,13 @@ static target_ulong h_ipi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
 
     icp_set_mfrr(spapr->icp, server, mfrr);
     return H_SUCCESS;
-
 }
 
 static target_ulong h_xirr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                            target_ulong opcode, target_ulong *args)
 {
-    CPUPPCState *env = &cpu->env;
-    uint32_t xirr = icp_accept(spapr->icp->ss + env->cpu_index);
+    CPUState *cs = CPU(cpu);
+    uint32_t xirr = icp_accept(spapr->icp->ss + cs->cpu_index);
 
     args[0] = xirr;
     return H_SUCCESS;
@@ -392,10 +391,10 @@ static target_ulong h_xirr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
 static target_ulong h_eoi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                           target_ulong opcode, target_ulong *args)
 {
-    CPUPPCState *env = &cpu->env;
+    CPUState *cs = CPU(cpu);
     target_ulong xirr = args[0];
 
-    icp_eoi(spapr->icp, env->cpu_index, xirr);
+    icp_eoi(spapr->icp, cs->cpu_index, xirr);
     return H_SUCCESS;
 }
 
@@ -525,14 +524,16 @@ static void xics_reset(void *opaque)
 struct icp_state *xics_system_init(int nr_irqs)
 {
     CPUPPCState *env;
+    CPUState *cpu;
     int max_server_num;
     struct icp_state *icp;
     struct ics_state *ics;
 
     max_server_num = -1;
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        if (env->cpu_index > max_server_num) {
-            max_server_num = env->cpu_index;
+        cpu = CPU(ppc_env_get_cpu(env));
+        if (cpu->cpu_index > max_server_num) {
+            max_server_num = cpu->cpu_index;
         }
     }
 
@@ -541,7 +542,8 @@ struct icp_state *xics_system_init(int nr_irqs)
     icp->ss = g_malloc0(icp->nr_servers*sizeof(struct icp_server_state));
 
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        struct icp_server_state *ss = &icp->ss[env->cpu_index];
+        cpu = CPU(ppc_env_get_cpu(env));
+        struct icp_server_state *ss = &icp->ss[cpu->cpu_index];
 
         switch (PPC_INPUT(env)) {
         case PPC_FLAGS_INPUT_POWER7:
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index ce178ea..d0cf85a 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -193,7 +193,6 @@ typedef struct CPUWatchpoint {
     int exception_index;                                                \
                                                                         \
     CPUArchState *next_cpu; /* next CPU sharing TB cache */                 \
-    int cpu_index; /* CPU index (informative) */                        \
     uint32_t host_tid; /* host thread ID */                             \
     int running; /* Nonzero if cpu is currently running(usermode).  */  \
     /* user data */                                                     \
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index 668de66..49231fe 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -35,7 +35,8 @@ static inline int cpu_index(CPUArchState *env)
 #if defined(CONFIG_USER_ONLY) && defined(CONFIG_USE_NPTL)
     return env->host_tid;
 #else
-    return env->cpu_index + 1;
+    CPUState *cpu = ENV_GET_CPU(env);
+    return cpu->cpu_index + 1;
 #endif
 }
 
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 30d1e0c..d5e0a40 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -57,6 +57,7 @@ struct kvm_run;
 
 /**
  * CPUState:
+ * @cpu_index: CPU index (informative).
  * @nr_cores: Number of cores within this CPU package.
  * @nr_threads: Number of threads within this CPU.
  * @numa_node: NUMA node this CPU is belonging to.
@@ -96,6 +97,7 @@ struct CPUState {
     struct kvm_run *kvm_run;
 
     /* TODO Move common fields from CPUArchState here. */
+    int cpu_index; /* used by alpha TCG */
 };
 
 
diff --git a/kvm-all.c b/kvm-all.c
index fc0c6e7..4ba77de 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -223,7 +223,7 @@ int kvm_init_vcpu(CPUArchState *env)
 
     DPRINTF("kvm_init_vcpu\n");
 
-    ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, env->cpu_index);
+    ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, cpu->cpu_index);
     if (ret < 0) {
         DPRINTF("kvm_create_vcpu failed\n");
         goto err;
diff --git a/monitor.c b/monitor.c
index 016910d..77ac451 100644
--- a/monitor.c
+++ b/monitor.c
@@ -872,9 +872,11 @@ EventInfoList *qmp_query_events(Error **errp)
 int monitor_set_cpu(int cpu_index)
 {
     CPUArchState *env;
+    CPUState *cpu;
 
-    for(env = first_cpu; env != NULL; env = env->next_cpu) {
-        if (env->cpu_index == cpu_index) {
+    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        cpu = ENV_GET_CPU(env);
+        if (cpu->cpu_index == cpu_index) {
             cur_mon->mon_cpu = env;
             return 0;
         }
@@ -893,7 +895,8 @@ static CPUArchState *mon_get_cpu(void)
 
 int monitor_get_cpu_index(void)
 {
-    return mon_get_cpu()->cpu_index;
+    CPUState *cpu = ENV_GET_CPU(mon_get_cpu());
+    return cpu->cpu_index;
 }
 
 static void do_info_registers(Monitor *mon)
@@ -1791,7 +1794,7 @@ static void do_info_numa(Monitor *mon)
         for (env = first_cpu; env != NULL; env = env->next_cpu) {
             cpu = ENV_GET_CPU(env);
             if (cpu->numa_node == i) {
-                monitor_printf(mon, " %d", env->cpu_index);
+                monitor_printf(mon, " %d", cpu->cpu_index);
             }
         }
         monitor_printf(mon, "\n");
@@ -1993,6 +1996,7 @@ static void do_inject_mce(Monitor *mon, const QDict *qdict)
 {
     X86CPU *cpu;
     CPUX86State *cenv;
+    CPUState *cs;
     int cpu_index = qdict_get_int(qdict, "cpu_index");
     int bank = qdict_get_int(qdict, "bank");
     uint64_t status = qdict_get_int(qdict, "status");
@@ -2006,7 +2010,8 @@ static void do_inject_mce(Monitor *mon, const QDict *qdict)
     }
     for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
         cpu = x86_env_get_cpu(cenv);
-        if (cenv->cpu_index == cpu_index) {
+        cs = CPU(cpu);
+        if (cs->cpu_index == cpu_index) {
             cpu_x86_inject_mce(mon, cpu, bank, status, mcg_status, addr, misc,
                                flags);
             break;
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 5cb40b7..f687b95 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1579,7 +1579,7 @@ static ExitStatus gen_call_pal(DisasContext *ctx, int palcode)
         case 0x3C:
             /* WHAMI */
             tcg_gen_ld32s_i64(cpu_ir[IR_V0], cpu_env,
-                              offsetof(CPUAlphaState, cpu_index));
+                -offsetof(AlphaCPU, env) + offsetof(CPUState, cpu_index));
             break;
 
         default:
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 94536bb..07588a1 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -64,7 +64,7 @@ static void arm_cpu_reset(CPUState *s)
     CPUARMState *env = &cpu->env;
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
         log_cpu_state(env, 0);
     }
 
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 66ab78e..37c34a1 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -902,7 +902,8 @@ static const ARMCPRegInfo strongarm_cp_reginfo[] = {
 static int mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri,
                       uint64_t *value)
 {
-    uint32_t mpidr = env->cpu_index;
+    CPUState *cs = CPU(arm_env_get_cpu(env));
+    uint32_t mpidr = cs->cpu_index;
     /* We don't support setting cluster ID ([8..11])
      * so these bits always RAZ.
      */
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index c596609..3f64a57 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -35,7 +35,7 @@ static void cris_cpu_reset(CPUState *s)
     uint32_t vr;
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
         log_cpu_state(env, 0);
     }
 
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 9f98a41..992b614 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1936,7 +1936,7 @@ static void x86_cpu_reset(CPUState *s)
     int i;
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
         log_cpu_state(env, CPU_DUMP_FPU | CPU_DUMP_CCOP);
     }
 
@@ -2010,7 +2010,7 @@ static void x86_cpu_reset(CPUState *s)
 
 #if !defined(CONFIG_USER_ONLY)
     /* We hard-wire the BSP to the first CPU. */
-    if (env->cpu_index == 0) {
+    if (s->cpu_index == 0) {
         apic_designate_bsp(env->apic_state);
     }
 
@@ -2148,6 +2148,7 @@ void x86_cpu_realize(Object *obj, Error **errp)
 
 static void x86_cpu_initfn(Object *obj)
 {
+    CPUState *cs = CPU(obj);
     X86CPU *cpu = X86_CPU(obj);
     CPUX86State *env = &cpu->env;
     static int inited;
@@ -2179,7 +2180,7 @@ static void x86_cpu_initfn(Object *obj)
                         x86_cpuid_get_tsc_freq,
                         x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
 
-    env->cpuid_apic_id = env->cpu_index;
+    env->cpuid_apic_id = cs->cpu_index;
 
     /* init various static tables used in TCG mode */
     if (tcg_enabled() && !inited) {
diff --git a/target-i386/helper.c b/target-i386/helper.c
index dca1360..fa622e1 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1059,7 +1059,7 @@ void breakpoint_handler(CPUX86State *env)
 
 typedef struct MCEInjectionParams {
     Monitor *mon;
-    CPUX86State *env;
+    X86CPU *cpu;
     int bank;
     uint64_t status;
     uint64_t mcg_status;
@@ -1071,7 +1071,8 @@ typedef struct MCEInjectionParams {
 static void do_inject_x86_mce(void *data)
 {
     MCEInjectionParams *params = data;
-    CPUX86State *cenv = params->env;
+    CPUX86State *cenv = &params->cpu->env;
+    CPUState *cpu = CPU(params->cpu);
     uint64_t *banks = cenv->mce_banks + 4 * params->bank;
 
     cpu_synchronize_state(cenv);
@@ -1094,7 +1095,7 @@ static void do_inject_x86_mce(void *data)
         if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
             monitor_printf(params->mon,
                            "CPU %d: Uncorrected error reporting disabled\n",
-                           cenv->cpu_index);
+                           cpu->cpu_index);
             return;
         }
 
@@ -1106,7 +1107,7 @@ static void do_inject_x86_mce(void *data)
             monitor_printf(params->mon,
                            "CPU %d: Uncorrected error reporting disabled for"
                            " bank %d\n",
-                           cenv->cpu_index, params->bank);
+                           cpu->cpu_index, params->bank);
             return;
         }
 
@@ -1115,7 +1116,7 @@ static void do_inject_x86_mce(void *data)
             monitor_printf(params->mon,
                            "CPU %d: Previous MCE still in progress, raising"
                            " triple fault\n",
-                           cenv->cpu_index);
+                           cpu->cpu_index);
             qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
             qemu_system_reset_request();
             return;
@@ -1148,7 +1149,7 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
     CPUX86State *cenv = &cpu->env;
     MCEInjectionParams params = {
         .mon = mon,
-        .env = cenv,
+        .cpu = cpu,
         .bank = bank,
         .status = status,
         .mcg_status = mcg_status,
@@ -1188,7 +1189,7 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
             if (cenv == env) {
                 continue;
             }
-            params.env = env;
+            params.cpu = x86_env_get_cpu(env);
             run_on_cpu(CPU(cpu), do_inject_x86_mce, &params);
         }
     }
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index db3126b..719cacd 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -580,14 +580,17 @@ void helper_monitor(CPUX86State *env, target_ulong ptr)
 
 void helper_mwait(CPUX86State *env, int next_eip_addend)
 {
+    CPUState *cpu;
+
     if ((uint32_t)ECX != 0) {
         raise_exception(env, EXCP0D_GPF);
     }
     cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0);
     EIP += next_eip_addend;
 
+    cpu = CPU(x86_env_get_cpu(env));
     /* XXX: not complete but not completely erroneous */
-    if (env->cpu_index != 0 || env->next_cpu != NULL) {
+    if (cpu->cpu_index != 0 || env->next_cpu != NULL) {
         /* more than one CPU: do not sleep because another CPU may
            wake this one */
     } else {
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index caa4834..eca2dca 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -30,7 +30,7 @@ static void lm32_cpu_reset(CPUState *s)
     CPULM32State *env = &cpu->env;
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
         log_cpu_state(env, 0);
     }
 
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index 3e70bb0..ce89674 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -35,7 +35,7 @@ static void m68k_cpu_reset(CPUState *s)
     CPUM68KState *env = &cpu->env;
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
         log_cpu_state(env, 0);
     }
 
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index 34b3a9b..0f858fd 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -32,7 +32,7 @@ static void mb_cpu_reset(CPUState *s)
     CPUMBState *env = &cpu->env;
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
         log_cpu_state(env, 0);
     }
 
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 0044062..10ff46d 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -29,8 +29,16 @@ static void mips_cpu_reset(CPUState *s)
     MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(cpu);
     CPUMIPSState *env = &cpu->env;
 
+    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
+        log_cpu_state(env, 0);
+    }
+
     mcc->parent_reset(s);
 
+    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
+    tlb_flush(env, 1);
+
     cpu_state_reset(env);
 }
 
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 6281e70..206ba83 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15878,13 +15878,10 @@ MIPSCPU *cpu_mips_init(const char *cpu_model)
 
 void cpu_state_reset(CPUMIPSState *env)
 {
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
-        log_cpu_state(env, 0);
-    }
-
-    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
-    tlb_flush(env, 1);
+#ifndef CONFIG_USER_ONLY
+    MIPSCPU *cpu = mips_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
+#endif
 
     /* Reset registers to their default values */
     env->CP0_PRid = env->cpu_model->CP0_PRid;
@@ -15953,7 +15950,7 @@ void cpu_state_reset(CPUMIPSState *env)
     env->CP0_Random = env->tlb->nb_tlb - 1;
     env->tlb->tlb_in_use = env->tlb->nb_tlb;
     env->CP0_Wired = 0;
-    env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
+    env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
     /* vectored interrupts not implemented, timer on int 7,
        no performance counters. */
@@ -15976,13 +15973,13 @@ void cpu_state_reset(CPUMIPSState *env)
 
         /* Only TC0 on VPE 0 starts as active.  */
         for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
-            env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
+            env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
             env->tcs[i].CP0_TCHalt = 1;
         }
         env->active_tc.CP0_TCHalt = 1;
         env->halted = 1;
 
-        if (!env->cpu_index) {
+        if (cs->cpu_index == 0) {
             /* VPE0 starts up enabled.  */
             env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
             env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index ba35b17..56544d8 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -27,7 +27,7 @@ static void openrisc_cpu_reset(CPUState *s)
     OpenRISCCPUClass *occ = OPENRISC_CPU_GET_CLASS(cpu);
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", cpu->env.cpu_index);
+        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
         log_cpu_state(&cpu->env, 0);
     }
 
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 4846acf..19e9f25 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -766,8 +766,9 @@ void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
 
         dprintf("injected interrupt %d\n", irq);
         r = kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &irq);
-        if (r < 0)
-            printf("cpu %d fail inject %x\n", env->cpu_index, irq);
+        if (r < 0) {
+            printf("cpu %d fail inject %x\n", cs->cpu_index, irq);
+        }
 
         /* Always wake up soon in case the interrupt was level based */
         qemu_mod_timer(idle_timer, qemu_get_clock_ns(vm_clock) +
@@ -1275,14 +1276,15 @@ static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data)
     }
 }
 
-int kvmppc_fixup_cpu(CPUPPCState *env)
+int kvmppc_fixup_cpu(PowerPCCPU *cpu)
 {
+    CPUState *cs = CPU(cpu);
     int smt;
 
     /* Adjust cpu index for SMT */
     smt = kvmppc_smt_threads();
-    env->cpu_index = (env->cpu_index / smp_threads) * smt
-        + (env->cpu_index % smp_threads);
+    cs->cpu_index = (cs->cpu_index / smp_threads) * smt
+        + (cs->cpu_index % smp_threads);
 
     return 0;
 }
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 4b21723..3db21fc 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -33,7 +33,7 @@ int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size);
 int kvmppc_reset_htab(int shift_hint);
 uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift);
 #endif /* !CONFIG_USER_ONLY */
-int kvmppc_fixup_cpu(CPUPPCState *env);
+int kvmppc_fixup_cpu(PowerPCCPU *cpu);
 
 #else
 
@@ -122,7 +122,7 @@ static inline int kvmppc_update_sdr1(CPUPPCState *env)
 
 #endif /* !CONFIG_USER_ONLY */
 
-static inline int kvmppc_fixup_cpu(CPUPPCState *env)
+static inline int kvmppc_fixup_cpu(PowerPCCPU *cpu)
 {
     return -1;
 }
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 2b03756..3f199c4 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -10005,8 +10005,10 @@ static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
     return 0;
 }
 
-static int ppc_fixup_cpu(CPUPPCState *env)
+static int ppc_fixup_cpu(PowerPCCPU *cpu)
 {
+    CPUPPCState *env = &cpu->env;
+
     /* TCG doesn't (yet) emulate some groups of instructions that
      * are implemented on some otherwise supported CPUs (e.g. VSX
      * and decimal floating point instructions on POWER7).  We
@@ -10036,12 +10038,12 @@ static void ppc_cpu_realize(Object *obj, Error **errp)
     Error *local_err = NULL;
 
     if (kvm_enabled()) {
-        if (kvmppc_fixup_cpu(env) != 0) {
+        if (kvmppc_fixup_cpu(cpu) != 0) {
             error_setg(errp, "Unable to virtualize selected CPU with KVM");
             return;
         }
     } else {
-        if (ppc_fixup_cpu(env) != 0) {
+        if (ppc_fixup_cpu(cpu) != 0) {
             error_setg(errp, "Unable to emulate selected CPU with TCG");
             return;
         }
@@ -10460,7 +10462,7 @@ static void ppc_cpu_reset(CPUState *s)
     target_ulong msr;
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
         log_cpu_state(env, 0);
     }
 
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 249f063..2ed2312 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -33,7 +33,7 @@ static void s390_cpu_reset(CPUState *s)
     CPUS390XState *env = &cpu->env;
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
         log_cpu_state(env, 0);
     }
 
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index a1a177f..e4858a0 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -31,7 +31,7 @@ static void superh_cpu_reset(CPUState *s)
     CPUSH4State *env = &cpu->env;
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
         log_cpu_state(env, 0);
     }
 
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 882d306..f404aa8 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -31,7 +31,7 @@ static void sparc_cpu_reset(CPUState *s)
     CPUSPARCState *env = &cpu->env;
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
         log_cpu_state(env, 0);
     }
 
commit 1b1ed8dc40635d60dd95c04658989af63542fcbf
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Dec 17 04:22:03 2012 +0100

    cpu: Move numa_node field to CPUState
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/cpus.c b/cpus.c
index 6aee15e..d68231a 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1160,12 +1160,14 @@ static void tcg_exec_all(void)
 void set_numa_modes(void)
 {
     CPUArchState *env;
+    CPUState *cpu;
     int i;
 
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        cpu = ENV_GET_CPU(env);
         for (i = 0; i < nb_numa_nodes; i++) {
             if (test_bit(env->cpu_index, node_cpumask[i])) {
-                env->numa_node = i;
+                cpu->numa_node = i;
             }
         }
     }
diff --git a/exec.c b/exec.c
index 34353f7..de5b27d 100644
--- a/exec.c
+++ b/exec.c
@@ -262,9 +262,7 @@ CPUArchState *qemu_get_cpu(int cpu)
 
 void cpu_exec_init(CPUArchState *env)
 {
-#ifndef CONFIG_USER_ONLY
     CPUState *cpu = ENV_GET_CPU(env);
-#endif
     CPUArchState **penv;
     int cpu_index;
 
@@ -279,7 +277,7 @@ void cpu_exec_init(CPUArchState *env)
         cpu_index++;
     }
     env->cpu_index = cpu_index;
-    env->numa_node = 0;
+    cpu->numa_node = 0;
     QTAILQ_INIT(&env->breakpoints);
     QTAILQ_INIT(&env->watchpoints);
 #ifndef CONFIG_USER_ONLY
diff --git a/hw/spapr.c b/hw/spapr.c
index b5e15b8..a61c71e 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -140,6 +140,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)
 {
     int ret = 0, offset;
     CPUPPCState *env;
+    CPUState *cpu;
     char cpu_model[32];
     int smt = kvmppc_smt_threads();
     uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
@@ -147,11 +148,12 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)
     assert(spapr->cpu_model);
 
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        cpu = ENV_GET_CPU(env);
         uint32_t associativity[] = {cpu_to_be32(0x5),
                                     cpu_to_be32(0x0),
                                     cpu_to_be32(0x0),
                                     cpu_to_be32(0x0),
-                                    cpu_to_be32(env->numa_node),
+                                    cpu_to_be32(cpu->numa_node),
                                     cpu_to_be32(env->cpu_index)};
 
         if ((env->cpu_index % smt) != 0) {
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index c02687b..ce178ea 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -195,7 +195,6 @@ typedef struct CPUWatchpoint {
     CPUArchState *next_cpu; /* next CPU sharing TB cache */                 \
     int cpu_index; /* CPU index (informative) */                        \
     uint32_t host_tid; /* host thread ID */                             \
-    int numa_node; /* NUMA node this cpu is belonging to  */            \
     int running; /* Nonzero if cpu is currently running(usermode).  */  \
     /* user data */                                                     \
     void *opaque;                                                       \
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 806b01a..30d1e0c 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -59,6 +59,7 @@ struct kvm_run;
  * CPUState:
  * @nr_cores: Number of cores within this CPU package.
  * @nr_threads: Number of threads within this CPU.
+ * @numa_node: NUMA node this CPU is belonging to.
  * @created: Indicates whether the CPU thread has been successfully created.
  * @stop: Indicates a pending stop request.
  * @stopped: Indicates the CPU has been artificially stopped.
@@ -73,6 +74,7 @@ struct CPUState {
 
     int nr_cores;
     int nr_threads;
+    int numa_node;
 
     struct QemuThread *thread;
 #ifdef _WIN32
diff --git a/monitor.c b/monitor.c
index b7ac3a3..016910d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1783,12 +1783,14 @@ static void do_info_numa(Monitor *mon)
 {
     int i;
     CPUArchState *env;
+    CPUState *cpu;
 
     monitor_printf(mon, "%d nodes\n", nb_numa_nodes);
     for (i = 0; i < nb_numa_nodes; i++) {
         monitor_printf(mon, "node %d cpus:", i);
         for (env = first_cpu; env != NULL; env = env->next_cpu) {
-            if (env->numa_node == i) {
+            cpu = ENV_GET_CPU(env);
+            if (cpu->numa_node == i) {
                 monitor_printf(mon, " %d", env->cpu_index);
             }
         }
commit 66afd1ad5a7a25e573577ac45979d8a3213796c3
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Dec 17 20:36:30 2012 +0100

    target-mips: Clean up mips_cpu_map_tc() documentation
    
    This function will be touched again soon, so a good understanding of env
    vs. other helps. Adopt gtk-doc style.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Eric Johnson <ericj at mips.com>

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index fb63d9e..1816a0e 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -572,11 +572,15 @@ static inline void mips_tc_sleep(MIPSCPU *cpu, int tc)
     }
 }
 
-/* tc should point to an int with the value of the global TC index.
-   This function will transform it into a local index within the
-   returned CPUMIPSState.
-
-   FIXME: This code assumes that all VPEs have the same number of TCs,
+/**
+ * mips_cpu_map_tc:
+ * @env: CPU from which mapping is performed.
+ * @tc: Should point to an int with the value of the global TC index.
+ *
+ * This function will transform @tc into a local index within the
+ * returned #CPUMIPSState.
+ */
+/* FIXME: This code assumes that all VPEs have the same number of TCs,
           which depends on runtime setup. Can probably be fixed by
           walking the list of CPUMIPSStates.  */
 static CPUMIPSState *mips_cpu_map_tc(CPUMIPSState *env, int *tc)
commit ce3960ebe57d0601a3628b64adac6fd23c901f70
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Dec 17 03:27:07 2012 +0100

    cpu: Move nr_{cores,threads} fields to CPUState
    
    To facilitate the field movements, pass MIPSCPU to malta_mips_config();
    avoid that for mips_cpu_map_tc() since callers only access MIPS Thread
    Contexts, inside TCG helpers.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/cpus.c b/cpus.c
index 4a7782a..6aee15e 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1041,8 +1041,8 @@ void qemu_init_vcpu(void *_env)
     CPUArchState *env = _env;
     CPUState *cpu = ENV_GET_CPU(env);
 
-    env->nr_cores = smp_cores;
-    env->nr_threads = smp_threads;
+    cpu->nr_cores = smp_cores;
+    cpu->nr_threads = smp_threads;
     cpu->stopped = true;
     if (kvm_enabled()) {
         qemu_kvm_start_vcpu(env);
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 2250e67..771d125 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -743,10 +743,13 @@ static int64_t load_kernel (void)
     return kernel_entry;
 }
 
-static void malta_mips_config(CPUMIPSState *env)
+static void malta_mips_config(MIPSCPU *cpu)
 {
+    CPUMIPSState *env = &cpu->env;
+    CPUState *cs = CPU(cpu);
+
     env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) |
-                         ((smp_cpus * env->nr_threads - 1) << CP0MVPC0_PTC);
+                         ((smp_cpus * cs->nr_threads - 1) << CP0MVPC0_PTC);
 }
 
 static void main_cpu_reset(void *opaque)
@@ -763,7 +766,7 @@ static void main_cpu_reset(void *opaque)
         env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
     }
 
-    malta_mips_config(env);
+    malta_mips_config(cpu);
 }
 
 static void cpu_request_exit(void *opaque, int irq, int level)
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index b22b4c6..c02687b 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -196,8 +196,6 @@ typedef struct CPUWatchpoint {
     int cpu_index; /* CPU index (informative) */                        \
     uint32_t host_tid; /* host thread ID */                             \
     int numa_node; /* NUMA node this cpu is belonging to  */            \
-    int nr_cores;  /* number of cores within this CPU package */        \
-    int nr_threads;/* number of threads within this CPU */              \
     int running; /* Nonzero if cpu is currently running(usermode).  */  \
     /* user data */                                                     \
     void *opaque;                                                       \
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index fbacb27..806b01a 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -57,6 +57,8 @@ struct kvm_run;
 
 /**
  * CPUState:
+ * @nr_cores: Number of cores within this CPU package.
+ * @nr_threads: Number of threads within this CPU.
  * @created: Indicates whether the CPU thread has been successfully created.
  * @stop: Indicates a pending stop request.
  * @stopped: Indicates the CPU has been artificially stopped.
@@ -69,6 +71,9 @@ struct CPUState {
     DeviceState parent_obj;
     /*< public >*/
 
+    int nr_cores;
+    int nr_threads;
+
     struct QemuThread *thread;
 #ifdef _WIN32
     HANDLE hThread;
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 78bd61e..9f98a41 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1691,8 +1691,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
         *ecx = env->cpuid_ext_features;
         *edx = env->cpuid_features;
-        if (env->nr_cores * env->nr_threads > 1) {
-            *ebx |= (env->nr_cores * env->nr_threads) << 16;
+        if (cs->nr_cores * cs->nr_threads > 1) {
+            *ebx |= (cs->nr_cores * cs->nr_threads) << 16;
             *edx |= 1 << 28;    /* HTT bit */
         }
         break;
@@ -1705,8 +1705,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         break;
     case 4:
         /* cache info: needed for Core compatibility */
-        if (env->nr_cores > 1) {
-            *eax = (env->nr_cores - 1) << 26;
+        if (cs->nr_cores > 1) {
+            *eax = (cs->nr_cores - 1) << 26;
         } else {
             *eax = 0;
         }
@@ -1725,8 +1725,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
                 break;
             case 2: /* L2 cache info */
                 *eax |= 0x0000143;
-                if (env->nr_threads > 1) {
-                    *eax |= (env->nr_threads - 1) << 14;
+                if (cs->nr_threads > 1) {
+                    *eax |= (cs->nr_threads - 1) << 14;
                 }
                 *ebx = 0x3c0003f;
                 *ecx = 0x0000fff;
@@ -1830,7 +1830,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
          * discards multiple thread information if it is set.
          * So dont set it here for Intel to make Linux guests happy.
          */
-        if (env->nr_cores * env->nr_threads > 1) {
+        if (cs->nr_cores * cs->nr_threads > 1) {
             uint32_t tebx, tecx, tedx;
             get_cpuid_vendor(env, &tebx, &tecx, &tedx);
             if (tebx != CPUID_VENDOR_INTEL_1 ||
@@ -1878,8 +1878,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         *ebx = 0;
         *ecx = 0;
         *edx = 0;
-        if (env->nr_cores * env->nr_threads > 1) {
-            *ecx |= (env->nr_cores * env->nr_threads) - 1;
+        if (cs->nr_cores * cs->nr_threads > 1) {
+            *ecx |= (cs->nr_cores * cs->nr_threads) - 1;
         }
         break;
     case 0x8000000A:
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index d5c61e8..fb63d9e 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -581,8 +581,9 @@ static inline void mips_tc_sleep(MIPSCPU *cpu, int tc)
           walking the list of CPUMIPSStates.  */
 static CPUMIPSState *mips_cpu_map_tc(CPUMIPSState *env, int *tc)
 {
+    CPUState *cs;
     CPUMIPSState *other;
-    int vpe_idx, nr_threads = env->nr_threads;
+    int vpe_idx;
     int tc_idx = *tc;
 
     if (!(env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))) {
@@ -591,8 +592,9 @@ static CPUMIPSState *mips_cpu_map_tc(CPUMIPSState *env, int *tc)
         return env;
     }
 
-    vpe_idx = tc_idx / nr_threads;
-    *tc = tc_idx % nr_threads;
+    cs = CPU(mips_env_get_cpu(env));
+    vpe_idx = tc_idx / cs->nr_threads;
+    *tc = tc_idx % cs->nr_threads;
     other = qemu_get_cpu(vpe_idx);
     return other ? other : env;
 }
commit 08bb4a7c9bb9c12746bce9b3a1f031dd4192afc1
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Jan 13 08:12:45 2013 +0000

    pc87312: Avoid define conflict on mingw32
    
    Mingw32 headers define FAR, causing this warning:
    /src/qemu/hw/pc87312.c:38:0: warning: "FAR" redefined [enabled by default]
    In file included from /usr/local/lib/gcc/i686-mingw32msvc/4.7.0/../../../../i686-mingw32msvc/include/windows.h:48:0,
                     from /src/qemu/include/sysemu/os-win32.h:29,
                     from /src/qemu/include/qemu-common.h:46,
                     from /src/qemu/include/exec/ioport.h:27,
                     from /src/qemu/hw/isa.h:6,
                     from /src/qemu/hw/pc87312.h:28,
                     from /src/qemu/hw/pc87312.c:26:
    /usr/local/lib/gcc/i686-mingw32msvc/4.7.0/../../../../i686-mingw32msvc/include/windef.h:34:0: note: this is the location of the previous definition
    
    Avoid the warning by expanding the macros.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
    Acked-by: Hervé Poussineau <hpoussin at reactos.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/hw/pc87312.c b/hw/pc87312.c
index 97fabfa..38af4c1 100644
--- a/hw/pc87312.c
+++ b/hw/pc87312.c
@@ -34,10 +34,6 @@
 #define REG_FAR 1
 #define REG_PTR 2
 
-#define FER regs[REG_FER]
-#define FAR regs[REG_FAR]
-#define PTR regs[REG_PTR]
-
 #define FER_PARALLEL_EN   0x01
 #define FER_UART1_EN      0x02
 #define FER_UART2_EN      0x04
@@ -66,14 +62,14 @@
 
 static inline bool is_parallel_enabled(PC87312State *s)
 {
-    return s->FER & FER_PARALLEL_EN;
+    return s->regs[REG_FER] & FER_PARALLEL_EN;
 }
 
 static const uint32_t parallel_base[] = { 0x378, 0x3bc, 0x278, 0x00 };
 
 static inline uint32_t get_parallel_iobase(PC87312State *s)
 {
-    return parallel_base[s->FAR & FAR_PARALLEL_ADDR];
+    return parallel_base[s->regs[REG_FAR] & FAR_PARALLEL_ADDR];
 }
 
 static const uint32_t parallel_irq[] = { 5, 7, 5, 0 };
@@ -81,9 +77,9 @@ static const uint32_t parallel_irq[] = { 5, 7, 5, 0 };
 static inline uint32_t get_parallel_irq(PC87312State *s)
 {
     int idx;
-    idx = (s->FAR & FAR_PARALLEL_ADDR);
+    idx = (s->regs[REG_FAR] & FAR_PARALLEL_ADDR);
     if (idx == 0) {
-        return (s->PTR & PTR_IRQ_5_7) ? 7 : 5;
+        return (s->regs[REG_PTR] & PTR_IRQ_5_7) ? 7 : 5;
     } else {
         return parallel_irq[idx];
     }
@@ -91,7 +87,7 @@ static inline uint32_t get_parallel_irq(PC87312State *s)
 
 static inline bool is_parallel_epp(PC87312State *s)
 {
-    return s->PTR & PTR_EPP_MODE;
+    return s->regs[REG_PTR] & PTR_EPP_MODE;
 }
 
 
@@ -105,26 +101,26 @@ static const uint32_t uart_base[2][4] = {
 static inline uint32_t get_uart_iobase(PC87312State *s, int i)
 {
     int idx;
-    idx = (s->FAR >> (2 * i + 2)) & 0x3;
+    idx = (s->regs[REG_FAR] >> (2 * i + 2)) & 0x3;
     if (idx == 0) {
         return 0x3f8;
     } else if (idx == 1) {
         return 0x2f8;
     } else {
-        return uart_base[idx & 1][(s->FAR & FAR_UART_3_4) >> 6];
+        return uart_base[idx & 1][(s->regs[REG_FAR] & FAR_UART_3_4) >> 6];
     }
 }
 
 static inline uint32_t get_uart_irq(PC87312State *s, int i)
 {
     int idx;
-    idx = (s->FAR >> (2 * i + 2)) & 0x3;
+    idx = (s->regs[REG_FAR] >> (2 * i + 2)) & 0x3;
     return (idx & 1) ? 3 : 4;
 }
 
 static inline bool is_uart_enabled(PC87312State *s, int i)
 {
-    return s->FER & (FER_UART1_EN << i);
+    return s->regs[REG_FER] & (FER_UART1_EN << i);
 }
 
 
@@ -132,12 +128,12 @@ static inline bool is_uart_enabled(PC87312State *s, int i)
 
 static inline bool is_fdc_enabled(PC87312State *s)
 {
-    return s->FER & FER_FDC_EN;
+    return s->regs[REG_FER] & FER_FDC_EN;
 }
 
 static inline uint32_t get_fdc_iobase(PC87312State *s)
 {
-    return (s->FER & FER_FDC_ADDR) ? 0x370 : 0x3f0;
+    return (s->regs[REG_FER] & FER_FDC_ADDR) ? 0x370 : 0x3f0;
 }
 
 
@@ -145,19 +141,19 @@ static inline uint32_t get_fdc_iobase(PC87312State *s)
 
 static inline bool is_ide_enabled(PC87312State *s)
 {
-    return s->FER & FER_IDE_EN;
+    return s->regs[REG_FER] & FER_IDE_EN;
 }
 
 static inline uint32_t get_ide_iobase(PC87312State *s)
 {
-    return (s->FER & FER_IDE_ADDR) ? 0x170 : 0x1f0;
+    return (s->regs[REG_FER] & FER_IDE_ADDR) ? 0x170 : 0x1f0;
 }
 
 
 static void reconfigure_devices(PC87312State *s)
 {
     error_report("pc87312: unsupported device reconfiguration (%02x %02x %02x)",
-                 s->FER, s->FAR, s->PTR);
+                 s->regs[REG_FER], s->regs[REG_FAR], s->regs[REG_PTR]);
 }
 
 static void pc87312_soft_reset(PC87312State *s)
@@ -184,9 +180,9 @@ static void pc87312_soft_reset(PC87312State *s)
     s->read_id_step = 0;
     s->selected_index = REG_FER;
 
-    s->FER = fer_init[s->config & 0x1f];
-    s->FAR = far_init[s->config & 0x1f];
-    s->PTR = ptr_init[s->config & 0x1f];
+    s->regs[REG_FER] = fer_init[s->config & 0x1f];
+    s->regs[REG_FAR] = far_init[s->config & 0x1f];
+    s->regs[REG_PTR] = ptr_init[s->config & 0x1f];
 }
 
 static void pc87312_hard_reset(PC87312State *s)
commit 328c24a97b9cde975bc8b12caa4c6c067fff83c6
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Fri Jan 11 21:11:20 2013 +0100

    pc87312: Replace register_ioport_*() with MemoryRegion
    
    Prepare an instance_init function for the MemoryRegion init.
    
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>
    Tested-by: Hervé Poussineau <hpoussin at reactos.org>

diff --git a/hw/pc87312.c b/hw/pc87312.c
index 6a17afd..97fabfa 100644
--- a/hw/pc87312.c
+++ b/hw/pc87312.c
@@ -194,7 +194,8 @@ static void pc87312_hard_reset(PC87312State *s)
     pc87312_soft_reset(s);
 }
 
-static void pc87312_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void pc87312_io_write(void *opaque, hwaddr addr, uint64_t val,
+                             unsigned int size)
 {
     PC87312State *s = opaque;
 
@@ -213,7 +214,7 @@ static void pc87312_ioport_write(void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
-static uint32_t pc87312_ioport_read(void *opaque, uint32_t addr)
+static uint64_t pc87312_io_read(void *opaque, hwaddr addr, unsigned int size)
 {
     PC87312State *s = opaque;
     uint32_t val;
@@ -241,6 +242,16 @@ static uint32_t pc87312_ioport_read(void *opaque, uint32_t addr)
     return val;
 }
 
+static const MemoryRegionOps pc87312_io_ops = {
+    .read  = pc87312_io_read,
+    .write = pc87312_io_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
 static int pc87312_post_load(void *opaque, int version_id)
 {
     PC87312State *s = opaque;
@@ -270,6 +281,7 @@ static int pc87312_init(ISADevice *dev)
     s = PC87312(dev);
     bus = isa_bus_from_device(dev);
     pc87312_hard_reset(s);
+    isa_register_ioport(dev, &s->io, s->iobase);
 
     if (is_parallel_enabled(s)) {
         chr = parallel_hds[0];
@@ -337,11 +349,16 @@ static int pc87312_init(ISADevice *dev)
         trace_pc87312_info_ide(get_ide_iobase(s));
     }
 
-    register_ioport_write(s->iobase, 2, 1, pc87312_ioport_write, s);
-    register_ioport_read(s->iobase, 2, 1, pc87312_ioport_read, s);
     return 0;
 }
 
+static void pc87312_initfn(Object *obj)
+{
+    PC87312State *s = PC87312(obj);
+
+    memory_region_init_io(&s->io, &pc87312_io_ops, s, "pc87312", 2);
+}
+
 static const VMStateDescription vmstate_pc87312 = {
     .name = "pc87312",
     .version_id = 1,
@@ -376,6 +393,7 @@ static const TypeInfo pc87312_type_info = {
     .name          = TYPE_PC87312,
     .parent        = TYPE_ISA_DEVICE,
     .instance_size = sizeof(PC87312State),
+    .instance_init = pc87312_initfn,
     .class_init    = pc87312_class_init,
 };
 
diff --git a/hw/pc87312.h b/hw/pc87312.h
index 7ca7912..7b9e6f6 100644
--- a/hw/pc87312.h
+++ b/hw/pc87312.h
@@ -56,6 +56,8 @@ typedef struct PC87312State {
         uint32_t base;
     } ide;
 
+    MemoryRegion io;
+
     uint8_t read_id_step;
     uint8_t selected_index;
 
commit 01b87f6d217ed05d5948562f74f5cf7b511a9c6c
Author: Eric Blake <eblake at redhat.com>
Date:   Wed Jan 2 09:15:11 2013 -0700

    qga: add missing commas in json docs
    
    * qga/qapi-schema.json: Use valid JSON.
    
    Signed-off-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index ed0eb69..d91d903 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -31,7 +31,7 @@
 #
 # Since: 1.1
 # ##
-{ 'command': 'guest-sync-delimited'
+{ 'command': 'guest-sync-delimited',
   'data':    { 'id': 'int' },
   'returns': 'int' }
 
@@ -69,7 +69,7 @@
 #
 # Since: 0.15.0
 ##
-{ 'command': 'guest-sync'
+{ 'command': 'guest-sync',
   'data':    { 'id': 'int' },
   'returns': 'int' }
 
commit 7e7b7cba16faa7b721b822fa9ed8bebafa35700f
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date:   Mon Jan 14 18:30:30 2013 +0000

    xen_disk: implement BLKIF_OP_FLUSH_DISKCACHE, remove BLKIF_OP_WRITE_BARRIER
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index 9ee72a0..7fea871 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -243,12 +243,11 @@ static int ioreq_parse(struct ioreq *ioreq)
     case BLKIF_OP_READ:
         ioreq->prot = PROT_WRITE; /* to memory */
         break;
-    case BLKIF_OP_WRITE_BARRIER:
+    case BLKIF_OP_FLUSH_DISKCACHE:
+        ioreq->presync = 1;
         if (!ioreq->req.nr_segments) {
-            ioreq->presync = 1;
             return 0;
         }
-        ioreq->presync = ioreq->postsync = 1;
         /* fall through */
     case BLKIF_OP_WRITE:
         ioreq->prot = PROT_READ; /* from memory */
@@ -509,7 +508,7 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
                        qemu_aio_complete, ioreq);
         break;
     case BLKIF_OP_WRITE:
-    case BLKIF_OP_WRITE_BARRIER:
+    case BLKIF_OP_FLUSH_DISKCACHE:
         if (!ioreq->req.nr_segments) {
             break;
         }
@@ -794,7 +793,7 @@ static int blk_init(struct XenDevice *xendev)
                   blkdev->file_size, blkdev->file_size >> 20);
 
     /* fill info */
-    xenstore_write_be_int(&blkdev->xendev, "feature-barrier", 1);
+    xenstore_write_be_int(&blkdev->xendev, "feature-flush-cache", 1);
     xenstore_write_be_int(&blkdev->xendev, "feature-persistent", 1);
     xenstore_write_be_int(&blkdev->xendev, "info",            info);
     xenstore_write_be_int(&blkdev->xendev, "sector-size",     blkdev->file_blk);
commit 9e496d7458bb01b717afe22db10a724db57d53fd
Author: Roger Pau Monne <roger.pau at citrix.com>
Date:   Mon Jan 14 18:28:19 2013 +0000

    xen_disk: add persistent grant support to xen_disk backend
    
    This protocol extension reuses the same set of grant pages for all
    transactions between the front/back drivers, avoiding expensive tlb
    flushes, grant table lock contention and switches between userspace
    and kernel space. The full description of the protocol can be found in
    the public blkif.h header.
    
    http://xenbits.xen.org/gitweb/?p=xen.git;a=blob_plain;f=xen/include/public/io/blkif.h
    
    Speed improvement with 15 guests performing I/O is ~450%.
    
    Signed-off-by: Roger Pau Monné <roger.pau at citrix.com>
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index b7c7977..9ee72a0 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -51,6 +51,13 @@ static int max_requests = 32;
 #define BLOCK_SIZE  512
 #define IOCB_COUNT  (BLKIF_MAX_SEGMENTS_PER_REQUEST + 2)
 
+struct PersistentGrant {
+    void *page;
+    struct XenBlkDev *blkdev;
+};
+
+typedef struct PersistentGrant PersistentGrant;
+
 struct ioreq {
     blkif_request_t     req;
     int16_t             status;
@@ -68,6 +75,7 @@ struct ioreq {
     int                 prot;
     void                *page[BLKIF_MAX_SEGMENTS_PER_REQUEST];
     void                *pages;
+    int                 num_unmap;
 
     /* aio status */
     int                 aio_inflight;
@@ -104,6 +112,12 @@ struct XenBlkDev {
     int                 requests_inflight;
     int                 requests_finished;
 
+    /* Persistent grants extension */
+    gboolean            feature_persistent;
+    GTree               *persistent_gnts;
+    unsigned int        persistent_gnt_count;
+    unsigned int        max_grants;
+
     /* qemu block driver */
     DriveInfo           *dinfo;
     BlockDriverState    *bs;
@@ -137,6 +151,29 @@ static void ioreq_reset(struct ioreq *ioreq)
     qemu_iovec_reset(&ioreq->v);
 }
 
+static gint int_cmp(gconstpointer a, gconstpointer b, gpointer user_data)
+{
+    uint ua = GPOINTER_TO_UINT(a);
+    uint ub = GPOINTER_TO_UINT(b);
+    return (ua > ub) - (ua < ub);
+}
+
+static void destroy_grant(gpointer pgnt)
+{
+    PersistentGrant *grant = pgnt;
+    XenGnttab gnt = grant->blkdev->xendev.gnttabdev;
+
+    if (xc_gnttab_munmap(gnt, grant->page, 1) != 0) {
+        xen_be_printf(&grant->blkdev->xendev, 0,
+                      "xc_gnttab_munmap failed: %s\n",
+                      strerror(errno));
+    }
+    grant->blkdev->persistent_gnt_count--;
+    xen_be_printf(&grant->blkdev->xendev, 3,
+                  "unmapped grant %p\n", grant->page);
+    g_free(grant);
+}
+
 static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
 {
     struct ioreq *ioreq = NULL;
@@ -265,21 +302,21 @@ static void ioreq_unmap(struct ioreq *ioreq)
     XenGnttab gnt = ioreq->blkdev->xendev.gnttabdev;
     int i;
 
-    if (ioreq->v.niov == 0 || ioreq->mapped == 0) {
+    if (ioreq->num_unmap == 0 || ioreq->mapped == 0) {
         return;
     }
     if (batch_maps) {
         if (!ioreq->pages) {
             return;
         }
-        if (xc_gnttab_munmap(gnt, ioreq->pages, ioreq->v.niov) != 0) {
+        if (xc_gnttab_munmap(gnt, ioreq->pages, ioreq->num_unmap) != 0) {
             xen_be_printf(&ioreq->blkdev->xendev, 0, "xc_gnttab_munmap failed: %s\n",
                           strerror(errno));
         }
-        ioreq->blkdev->cnt_map -= ioreq->v.niov;
+        ioreq->blkdev->cnt_map -= ioreq->num_unmap;
         ioreq->pages = NULL;
     } else {
-        for (i = 0; i < ioreq->v.niov; i++) {
+        for (i = 0; i < ioreq->num_unmap; i++) {
             if (!ioreq->page[i]) {
                 continue;
             }
@@ -297,41 +334,120 @@ static void ioreq_unmap(struct ioreq *ioreq)
 static int ioreq_map(struct ioreq *ioreq)
 {
     XenGnttab gnt = ioreq->blkdev->xendev.gnttabdev;
-    int i;
+    uint32_t domids[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+    uint32_t refs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+    void *page[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+    int i, j, new_maps = 0;
+    PersistentGrant *grant;
+    /* domids and refs variables will contain the information necessary
+     * to map the grants that are needed to fulfill this request.
+     *
+     * After mapping the needed grants, the page array will contain the
+     * memory address of each granted page in the order specified in ioreq
+     * (disregarding if it's a persistent grant or not).
+     */
 
     if (ioreq->v.niov == 0 || ioreq->mapped == 1) {
         return 0;
     }
-    if (batch_maps) {
+    if (ioreq->blkdev->feature_persistent) {
+        for (i = 0; i < ioreq->v.niov; i++) {
+            grant = g_tree_lookup(ioreq->blkdev->persistent_gnts,
+                                    GUINT_TO_POINTER(ioreq->refs[i]));
+
+            if (grant != NULL) {
+                page[i] = grant->page;
+                xen_be_printf(&ioreq->blkdev->xendev, 3,
+                              "using persistent-grant %" PRIu32 "\n",
+                              ioreq->refs[i]);
+            } else {
+                    /* Add the grant to the list of grants that
+                     * should be mapped
+                     */
+                    domids[new_maps] = ioreq->domids[i];
+                    refs[new_maps] = ioreq->refs[i];
+                    page[i] = NULL;
+                    new_maps++;
+            }
+        }
+        /* Set the protection to RW, since grants may be reused later
+         * with a different protection than the one needed for this request
+         */
+        ioreq->prot = PROT_WRITE | PROT_READ;
+    } else {
+        /* All grants in the request should be mapped */
+        memcpy(refs, ioreq->refs, sizeof(refs));
+        memcpy(domids, ioreq->domids, sizeof(domids));
+        memset(page, 0, sizeof(page));
+        new_maps = ioreq->v.niov;
+    }
+
+    if (batch_maps && new_maps) {
         ioreq->pages = xc_gnttab_map_grant_refs
-            (gnt, ioreq->v.niov, ioreq->domids, ioreq->refs, ioreq->prot);
+            (gnt, new_maps, domids, refs, ioreq->prot);
         if (ioreq->pages == NULL) {
             xen_be_printf(&ioreq->blkdev->xendev, 0,
                           "can't map %d grant refs (%s, %d maps)\n",
-                          ioreq->v.niov, strerror(errno), ioreq->blkdev->cnt_map);
+                          new_maps, strerror(errno), ioreq->blkdev->cnt_map);
             return -1;
         }
-        for (i = 0; i < ioreq->v.niov; i++) {
-            ioreq->v.iov[i].iov_base = ioreq->pages + i * XC_PAGE_SIZE +
-                (uintptr_t)ioreq->v.iov[i].iov_base;
+        for (i = 0, j = 0; i < ioreq->v.niov; i++) {
+            if (page[i] == NULL) {
+                page[i] = ioreq->pages + (j++) * XC_PAGE_SIZE;
+            }
         }
-        ioreq->blkdev->cnt_map += ioreq->v.niov;
-    } else  {
-        for (i = 0; i < ioreq->v.niov; i++) {
+        ioreq->blkdev->cnt_map += new_maps;
+    } else if (new_maps)  {
+        for (i = 0; i < new_maps; i++) {
             ioreq->page[i] = xc_gnttab_map_grant_ref
-                (gnt, ioreq->domids[i], ioreq->refs[i], ioreq->prot);
+                (gnt, domids[i], refs[i], ioreq->prot);
             if (ioreq->page[i] == NULL) {
                 xen_be_printf(&ioreq->blkdev->xendev, 0,
                               "can't map grant ref %d (%s, %d maps)\n",
-                              ioreq->refs[i], strerror(errno), ioreq->blkdev->cnt_map);
+                              refs[i], strerror(errno), ioreq->blkdev->cnt_map);
                 ioreq_unmap(ioreq);
                 return -1;
             }
-            ioreq->v.iov[i].iov_base = ioreq->page[i] + (uintptr_t)ioreq->v.iov[i].iov_base;
             ioreq->blkdev->cnt_map++;
         }
+        for (i = 0, j = 0; i < ioreq->v.niov; i++) {
+            if (page[i] == NULL) {
+                page[i] = ioreq->page[j++];
+            }
+        }
+    }
+    if (ioreq->blkdev->feature_persistent) {
+        while ((ioreq->blkdev->persistent_gnt_count < ioreq->blkdev->max_grants)
+              && new_maps) {
+            /* Go through the list of newly mapped grants and add as many
+             * as possible to the list of persistently mapped grants.
+             *
+             * Since we start at the end of ioreq->page(s), we only need
+             * to decrease new_maps to prevent this granted pages from
+             * being unmapped in ioreq_unmap.
+             */
+            grant = g_malloc0(sizeof(*grant));
+            new_maps--;
+            if (batch_maps) {
+                grant->page = ioreq->pages + (new_maps) * XC_PAGE_SIZE;
+            } else {
+                grant->page = ioreq->page[new_maps];
+            }
+            grant->blkdev = ioreq->blkdev;
+            xen_be_printf(&ioreq->blkdev->xendev, 3,
+                          "adding grant %" PRIu32 " page: %p\n",
+                          refs[new_maps], grant->page);
+            g_tree_insert(ioreq->blkdev->persistent_gnts,
+                          GUINT_TO_POINTER(refs[new_maps]),
+                          grant);
+            ioreq->blkdev->persistent_gnt_count++;
+        }
+    }
+    for (i = 0; i < ioreq->v.niov; i++) {
+        ioreq->v.iov[i].iov_base += (uintptr_t)page[i];
     }
     ioreq->mapped = 1;
+    ioreq->num_unmap = new_maps;
     return 0;
 }
 
@@ -679,6 +795,7 @@ static int blk_init(struct XenDevice *xendev)
 
     /* fill info */
     xenstore_write_be_int(&blkdev->xendev, "feature-barrier", 1);
+    xenstore_write_be_int(&blkdev->xendev, "feature-persistent", 1);
     xenstore_write_be_int(&blkdev->xendev, "info",            info);
     xenstore_write_be_int(&blkdev->xendev, "sector-size",     blkdev->file_blk);
     xenstore_write_be_int(&blkdev->xendev, "sectors",
@@ -702,6 +819,7 @@ out_error:
 static int blk_connect(struct XenDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
+    int pers;
 
     if (xenstore_read_fe_int(&blkdev->xendev, "ring-ref", &blkdev->ring_ref) == -1) {
         return -1;
@@ -710,6 +828,11 @@ static int blk_connect(struct XenDevice *xendev)
                              &blkdev->xendev.remote_port) == -1) {
         return -1;
     }
+    if (xenstore_read_fe_int(&blkdev->xendev, "feature-persistent", &pers)) {
+        blkdev->feature_persistent = FALSE;
+    } else {
+        blkdev->feature_persistent = !!pers;
+    }
 
     blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
     if (blkdev->xendev.protocol) {
@@ -753,6 +876,15 @@ static int blk_connect(struct XenDevice *xendev)
     }
     }
 
+    if (blkdev->feature_persistent) {
+        /* Init persistent grants */
+        blkdev->max_grants = max_requests * BLKIF_MAX_SEGMENTS_PER_REQUEST;
+        blkdev->persistent_gnts = g_tree_new_full((GCompareDataFunc)int_cmp,
+                                             NULL, NULL,
+                                             (GDestroyNotify)destroy_grant);
+        blkdev->persistent_gnt_count = 0;
+    }
+
     xen_be_bind_evtchn(&blkdev->xendev);
 
     xen_be_printf(&blkdev->xendev, 1, "ok: proto %s, ring-ref %d, "
@@ -793,6 +925,11 @@ static int blk_free(struct XenDevice *xendev)
         blk_disconnect(xendev);
     }
 
+    /* Free persistent grants */
+    if (blkdev->feature_persistent) {
+        g_tree_destroy(blkdev->persistent_gnts);
+    }
+
     while (!QLIST_EMPTY(&blkdev->freelist)) {
         ioreq = QLIST_FIRST(&blkdev->freelist);
         QLIST_REMOVE(ioreq, list);
commit 282c6a2f292705f823554447ca0b7731b6f81a97
Author: Roger Pau Monne <roger.pau at citrix.com>
Date:   Mon Jan 14 18:26:53 2013 +0000

    xen_disk: fix memory leak
    
    On ioreq_release the full ioreq was memset to 0, loosing all the data
    and memory allocations inside the QEMUIOVector, which leads to a
    memory leak. Create a new function to specifically reset ioreq.
    
    Reported-by: Maik Wessler <maik.wessler at yahoo.com>
    Signed-off-by: Roger Pau Monné <roger.pau at citrix.com>
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index a6a64a2..b7c7977 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -112,6 +112,31 @@ struct XenBlkDev {
 
 /* ------------------------------------------------------------- */
 
+static void ioreq_reset(struct ioreq *ioreq)
+{
+    memset(&ioreq->req, 0, sizeof(ioreq->req));
+    ioreq->status = 0;
+    ioreq->start = 0;
+    ioreq->presync = 0;
+    ioreq->postsync = 0;
+    ioreq->mapped = 0;
+
+    memset(ioreq->domids, 0, sizeof(ioreq->domids));
+    memset(ioreq->refs, 0, sizeof(ioreq->refs));
+    ioreq->prot = 0;
+    memset(ioreq->page, 0, sizeof(ioreq->page));
+    ioreq->pages = NULL;
+
+    ioreq->aio_inflight = 0;
+    ioreq->aio_errors = 0;
+
+    ioreq->blkdev = NULL;
+    memset(&ioreq->list, 0, sizeof(ioreq->list));
+    memset(&ioreq->acct, 0, sizeof(ioreq->acct));
+
+    qemu_iovec_reset(&ioreq->v);
+}
+
 static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
 {
     struct ioreq *ioreq = NULL;
@@ -129,7 +154,6 @@ static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
         /* get one from freelist */
         ioreq = QLIST_FIRST(&blkdev->freelist);
         QLIST_REMOVE(ioreq, list);
-        qemu_iovec_reset(&ioreq->v);
     }
     QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list);
     blkdev->requests_inflight++;
@@ -153,7 +177,7 @@ static void ioreq_release(struct ioreq *ioreq, bool finish)
     struct XenBlkDev *blkdev = ioreq->blkdev;
 
     QLIST_REMOVE(ioreq, list);
-    memset(ioreq, 0, sizeof(*ioreq));
+    ioreq_reset(ioreq);
     ioreq->blkdev = blkdev;
     QLIST_INSERT_HEAD(&blkdev->freelist, ioreq, list);
     if (finish) {
commit 7868181f98ff1fbcd7f7034153eec5e03615d023
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Jan 11 11:25:02 2013 +0100

    qemu-ga: Handle errors uniformely in ga_channel_open()
    
    We detect errors in several places.  One reports with g_error(), which
    calls abort(), the others report with g_critical().  Three of them
    exit(), three return false.
    
    Always report with g_critical(), and return false.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Reviewed-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
    
    *minor fix-up of commit msg
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/qga/channel-posix.c b/qga/channel-posix.c
index 05e8386..e65dda3 100644
--- a/qga/channel-posix.c
+++ b/qga/channel-posix.c
@@ -141,14 +141,15 @@ static gboolean ga_channel_open(GAChannel *c, const gchar *path, GAChannelMethod
                            );
         if (fd == -1) {
             g_critical("error opening channel: %s", strerror(errno));
-            exit(EXIT_FAILURE);
+            return false;
         }
 #ifdef CONFIG_SOLARIS
         ret = ioctl(fd, I_SETSIG, S_OUTPUT | S_INPUT | S_HIPRI);
         if (ret == -1) {
             g_critical("error setting event mask for channel: %s",
                        strerror(errno));
-            exit(EXIT_FAILURE);
+            close(fd);
+            return false;
         }
 #endif
         ret = ga_channel_client_add(c, fd);
@@ -164,7 +165,7 @@ static gboolean ga_channel_open(GAChannel *c, const gchar *path, GAChannelMethod
         int fd = qemu_open(path, O_RDWR | O_NOCTTY | O_NONBLOCK);
         if (fd == -1) {
             g_critical("error opening channel: %s", strerror(errno));
-            exit(EXIT_FAILURE);
+            return false;
         }
         tcgetattr(fd, &tio);
         /* set up serial port for non-canonical, dumb byte streaming */
@@ -184,7 +185,9 @@ static gboolean ga_channel_open(GAChannel *c, const gchar *path, GAChannelMethod
         tcsetattr(fd, TCSANOW, &tio);
         ret = ga_channel_client_add(c, fd);
         if (ret) {
-            g_error("error adding channel to main loop");
+            g_critical("error adding channel to main loop");
+            close(fd);
+            return false;
         }
         break;
     }
commit d4f4a3efdf0a71621ae5351176f5f15b522d0026
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Jan 11 11:25:01 2013 +0100

    qemu-ga: Plug fd leak on ga_channel_open() error paths
    
    Spotted by Coverity.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Reviewed-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/qga/channel-posix.c b/qga/channel-posix.c
index 9a5c05d..05e8386 100644
--- a/qga/channel-posix.c
+++ b/qga/channel-posix.c
@@ -154,6 +154,7 @@ static gboolean ga_channel_open(GAChannel *c, const gchar *path, GAChannelMethod
         ret = ga_channel_client_add(c, fd);
         if (ret) {
             g_critical("error adding channel to main loop");
+            close(fd);
             return false;
         }
         break;
commit 32c16620dda8ba16f6d6bcd20efefdec8975af77
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Jan 11 11:25:00 2013 +0100

    qemu-ga: Plug fd leak on ga_channel_listen_accept() error path
    
    Spotted by Coverity.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Reviewed-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/qga/channel-posix.c b/qga/channel-posix.c
index ca9e4aa..9a5c05d 100644
--- a/qga/channel-posix.c
+++ b/qga/channel-posix.c
@@ -46,6 +46,7 @@ static gboolean ga_channel_listen_accept(GIOChannel *channel,
     ret = ga_channel_client_add(c, client_fd);
     if (ret) {
         g_warning("error setting up connection");
+        close(client_fd);
         goto out;
     }
     accepted = true;
commit 03ac10f166b790cb66804e512abec6d002cd8481
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Jan 11 11:24:59 2013 +0100

    qemu-ga: Plug file descriptor leak on ga_open_pidfile() error path
    
    Spotted by Coverity.  Also document why we keep it open on success.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Reviewed-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/qga/main.c b/qga/main.c
index 96d3cfa..db281a5 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -299,10 +299,12 @@ static bool ga_open_pidfile(const char *pidfile)
         goto fail;
     }
 
+    /* keep pidfile open & locked forever */
     return true;
 
 fail:
     unlink(pidfile);
+    close(pidfd);
     return false;
 }
 #else /* _WIN32 */
commit 5d27f9ce3de424207883d84352d76150e9707394
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Jan 11 11:24:58 2013 +0100

    qemu-ga: Drop pointless lseek() from ga_open_pidfile()
    
    After open(), the file offset is already zero, and neither lockf() nor
    ftruncate() change it.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Reviewed-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/qga/main.c b/qga/main.c
index e8a9a9e..96d3cfa 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -289,7 +289,7 @@ static bool ga_open_pidfile(const char *pidfile)
         return false;
     }
 
-    if (ftruncate(pidfd, 0) || lseek(pidfd, 0, SEEK_SET)) {
+    if (ftruncate(pidfd, 0)) {
         g_critical("Failed to truncate pid file");
         goto fail;
     }
commit f5b795787864ddde1104a4f7c061dcb0e58e45c0
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Jan 11 11:24:57 2013 +0100

    qemu-ga: Document intentional fall through in channel_event_cb()
    
    For clarity, and to hush up Coverity.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Reviewed-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/qga/main.c b/qga/main.c
index bd70ead..e8a9a9e 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -618,6 +618,7 @@ static gboolean channel_event_cb(GIOCondition condition, gpointer data)
         if (!s->virtio) {
             return false;
         }
+        /* fall through */
     case G_IO_STATUS_AGAIN:
         /* virtio causes us to spin here when no process is attached to
          * host-side chardev. sleep a bit to mitigate this
commit 9e92f6d46233171898fc7d0487a04e5b78e44234
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Tue Jan 8 19:26:26 2013 -0200

    qemu-ga: add ga_open_logfile()
    
    This function sets O_CLOEXEC on the log file fd so that it isn't
    leaked to executed processes.
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Acked-by: Amos Kong <akong at redhat.com>
    Tested-by: Amos Kong <akong at redhat.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/qga/main.c b/qga/main.c
index 4239150..bd70ead 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -261,6 +261,19 @@ void ga_set_response_delimited(GAState *s)
     s->delimit_response = true;
 }
 
+static FILE *ga_open_logfile(const char *logfile)
+{
+    FILE *f;
+
+    f = fopen(logfile, "a");
+    if (!f) {
+        return NULL;
+    }
+
+    qemu_set_cloexec(fileno(f));
+    return f;
+}
+
 #ifndef _WIN32
 static bool ga_open_pidfile(const char *pidfile)
 {
@@ -402,7 +415,7 @@ void ga_unset_frozen(GAState *s)
      * in a frozen state at start up, do it now
      */
     if (s->deferred_options.log_filepath) {
-        s->log_file = fopen(s->deferred_options.log_filepath, "a");
+        s->log_file = ga_open_logfile(s->deferred_options.log_filepath);
         if (!s->log_file) {
             s->log_file = stderr;
         }
@@ -884,7 +897,7 @@ int main(int argc, char **argv)
             become_daemon(pid_filepath);
         }
         if (log_filepath) {
-            FILE *log_file = fopen(log_filepath, "a");
+            FILE *log_file = ga_open_logfile(log_filepath);
             if (!log_file) {
                 g_critical("unable to open specified log file: %s",
                            strerror(errno));
commit 6ffacc5d3ddf2e3227aae2a8cc5c15627265f727
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Tue Jan 8 19:26:25 2013 -0200

    qemu-ga: ga_open_pidfile(): use qemu_open()
    
    This ensures that O_CLOEXEC is passed to open(), this way the
    pid file fd is not leaked to executed processes.
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Acked-by: Amos Kong <akong at redhat.com>
    Tested-by: Amos Kong <akong at redhat.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/qga/main.c b/qga/main.c
index a9b968c..4239150 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -267,7 +267,7 @@ static bool ga_open_pidfile(const char *pidfile)
     int pidfd;
     char pidstr[32];
 
-    pidfd = open(pidfile, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
+    pidfd = qemu_open(pidfile, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
     if (pidfd == -1 || lockf(pidfd, F_TLOCK, 0)) {
         g_critical("Cannot lock pid file, %s", strerror(errno));
         if (pidfd != -1) {


More information about the Spice-commits mailing list