[Spice-commits] 58 commits - Makefile aio-posix.c aio-win32.c block/commit.c block/raw-posix.c block/win32-aio.c exec.c hmp-commands.hx hmp.c hmp.h hw/dataplane hw/fw_cfg.c hw/fw_cfg.h hw/i8259.c hw/ide hw/lm32_pic.c hw/lm32_pic.h hw/loader.c hw/loader.h hw/openpic.c hw/pc.c hw/pc.h hw/pcmcia.h hw/ppc hw/ppc.c hw/ppc.h hw/qdev-core.h hw/qdev-monitor.c hw/qdev-monitor.h hw/s390-virtio.c hw/s390-virtio.h hw/s390x hw/sun4m.c hw/sun4m.h hw/sun4u.c hw/usb hw/usb.h hw/virtio-blk.c hw/virtio-pci.c include/block include/exec include/net include/qemu include/qom include/sysemu linux-headers/asm-powerpc linux-headers/linux linux-user/syscall.c linux-user/syscall_defs.h monitor.c net/net.c net/slirp.c qga/commands-posix.c savevm.c target-ppc/kvm.c target-ppc/kvm_ppc.h target-ppc/translate_init.c target-s390x/cpu.c target-s390x/cpu.h target-s390x/kvm.c target-s390x/misc_helper.c tcg/arm tcg/optimize.c tests/test-aio.c trace-events util/path.c vl.c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Mon Jan 21 00:09:02 PST 2013


 Makefile                        |    2 
 aio-posix.c                     |    3 
 aio-win32.c                     |    3 
 block/commit.c                  |    7 -
 block/raw-posix.c               |   26 ++---
 block/win32-aio.c               |   19 ---
 exec.c                          |    8 -
 hmp-commands.hx                 |    3 
 hmp.c                           |   36 +++----
 hmp.h                           |   36 +++----
 hw/dataplane/virtio-blk.c       |    9 +
 hw/fw_cfg.c                     |   86 +++++++----------
 hw/fw_cfg.h                     |   17 +--
 hw/i8259.c                      |    4 
 hw/ide/pci.c                    |    1 
 hw/lm32_pic.c                   |    4 
 hw/lm32_pic.h                   |    4 
 hw/loader.c                     |    2 
 hw/loader.h                     |    3 
 hw/openpic.c                    |   40 ++++----
 hw/pc.c                         |   21 +---
 hw/pc.h                         |    4 
 hw/pcmcia.h                     |    2 
 hw/ppc.c                        |   17 +++
 hw/ppc.h                        |    2 
 hw/ppc/e500.c                   |   17 ++-
 hw/qdev-core.h                  |   14 ++
 hw/qdev-monitor.c               |    4 
 hw/qdev-monitor.h               |    4 
 hw/s390-virtio.c                |  194 ++++++++++++--------------------------
 hw/s390-virtio.h                |   22 ++++
 hw/s390x/Makefile.objs          |    2 
 hw/s390x/ipl.c                  |  174 ++++++++++++++++++++++++++++++++++
 hw/s390x/s390-virtio-hcall.c    |   36 +++++++
 hw/sun4m.c                      |   16 +--
 hw/sun4m.h                      |    4 
 hw/sun4u.c                      |    4 
 hw/usb.h                        |    2 
 hw/usb/bus.c                    |    2 
 hw/usb/host-bsd.c               |    2 
 hw/usb/host-linux.c             |    2 
 hw/usb/host-stub.c              |    2 
 hw/virtio-blk.c                 |    3 
 hw/virtio-pci.c                 |    6 -
 include/block/aio.h             |    6 -
 include/exec/cpu-defs.h         |    2 
 include/exec/exec-all.h         |    8 -
 include/net/net.h               |    2 
 include/net/slirp.h             |    2 
 include/qemu/bswap.h            |   20 ++--
 include/qom/object.h            |  104 ++++++++++++++++++++
 include/sysemu/sysemu.h         |    6 -
 linux-headers/asm-powerpc/kvm.h |    6 +
 linux-headers/linux/kvm.h       |   27 +++++
 linux-user/syscall.c            |   40 +++++---
 linux-user/syscall_defs.h       |   18 +++
 monitor.c                       |  200 ++++++++++++++++++++--------------------
 net/net.c                       |    2 
 net/slirp.c                     |    2 
 qga/commands-posix.c            |   13 +-
 savevm.c                        |    2 
 target-ppc/kvm.c                |   21 ++++
 target-ppc/kvm_ppc.h            |    5 +
 target-ppc/translate_init.c     |    4 
 target-s390x/cpu.c              |   71 +++++++++++++-
 target-s390x/cpu.h              |   91 +-----------------
 target-s390x/kvm.c              |   17 ++-
 target-s390x/misc_helper.c      |   83 ++++++++++++++++
 tcg/arm/tcg-target.c            |    4 
 tcg/optimize.c                  |  177 ++++++++++++++++++++++++++++++-----
 tests/test-aio.c                |    4 
 trace-events                    |    7 +
 util/path.c                     |    5 -
 vl.c                            |    8 -
 74 files changed, 1197 insertions(+), 629 deletions(-)

New commits:
commit 8b17ed4caa7e015324a4ecbe3c863e32458d840a
Merge: b54c287 cf13938
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Sun Jan 20 11:01:10 2013 -0600

    Merge remote-tracking branch 'stefanha/block' into staging
    
    # By Kevin Wolf (4) and others
    # Via Stefan Hajnoczi
    * stefanha/block:
      dataplane: support viostor virtio-pci status bit setting
      dataplane: avoid reentrancy during virtio_blk_data_plane_stop()
      win32-aio: use iov utility functions instead of open-coding them
      win32-aio: Fix memory leak
      win32-aio: Fix vectored reads
      aio: Fix return value of aio_poll()
      ide: Remove wrong assertion
      block: fix null-pointer bug on error case in block commit

commit b54c2873e731dd6fc81a4591cab909633b5a9eab
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Jan 19 20:23:51 2013 +0100

    tci: Fix broken build (regression)
    
    s390x-linux-user now also uses GETPC. Instead of adding it to the list of
    targets which use GETPC, the macro is now defined unconditionally.
    
    This avoids future build regressions like this one:
    
      CC    s390x-linux-user/target-s390x/int_helper.o
    cc1: warnings being treated as errors
    qemu/target-s390x/int_helper.c: In function ‘helper_divs32’:
    qemu/target-s390x/int_helper.c:47: error: implicit declaration of function ‘GETPC’
    qemu/target-s390x/int_helper.c:47: error: nested extern declaration of ‘GETPC’
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 46dca74..d235ef8 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -284,14 +284,8 @@ extern int tb_invalidated_flag;
 /* The return address may point to the start of the next instruction.
    Subtracting one gets us the call instruction itself.  */
 #if defined(CONFIG_TCG_INTERPRETER)
-/* Softmmu, Alpha, MIPS, SH4 and SPARC user mode emulations call GETPC().
-   For all others, GETPC remains undefined (which makes TCI a little faster. */
-# if defined(CONFIG_SOFTMMU) || \
-    defined(TARGET_ALPHA) || defined(TARGET_MIPS) || \
-    defined(TARGET_SH4) || defined(TARGET_SPARC)
 extern uintptr_t tci_tb_ptr;
-#  define GETPC() tci_tb_ptr
-# endif
+# define GETPC() tci_tb_ptr
 #elif defined(__s390__) && !defined(__s390x__)
 # define GETPC() \
     (((uintptr_t)__builtin_return_address(0) & 0x7fffffffUL) - 1)
commit c36dd8a09fd8811ebcda453d80dc5f52402d691c
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Fri Jan 18 16:43:35 2013 +0100

    block/raw-posix: Make hdev_aio_discard() available outside Linux
    
    Fixes the build on OpenBSD among others.
    
    Suggested-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>
    Cc: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 679fcc5..657af95 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1371,19 +1371,6 @@ static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
     return thread_pool_submit_aio(aio_worker, acb, cb, opaque);
 }
 
-static coroutine_fn BlockDriverAIOCB *hdev_aio_discard(BlockDriverState *bs,
-    int64_t sector_num, int nb_sectors,
-    BlockDriverCompletionFunc *cb, void *opaque)
-{
-    BDRVRawState *s = bs->opaque;
-
-    if (fd_open(bs) < 0) {
-        return NULL;
-    }
-    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__)
 static int fd_open(BlockDriverState *bs)
 {
@@ -1403,6 +1390,19 @@ static int fd_open(BlockDriverState *bs)
 
 #endif /* !linux && !FreeBSD */
 
+static coroutine_fn BlockDriverAIOCB *hdev_aio_discard(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors,
+    BlockDriverCompletionFunc *cb, void *opaque)
+{
+    BDRVRawState *s = bs->opaque;
+
+    if (fd_open(bs) < 0) {
+        return NULL;
+    }
+    return paio_submit(bs, s->fd, sector_num, NULL, nb_sectors,
+                       cb, opaque, QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV);
+}
+
 static int hdev_create(const char *filename, QEMUOptionParameter *options)
 {
     int fd;
commit c1db29199e3caf5cd56daad08b8926ffa97da136
Author: Stefan Weil <sw at weilnetz.de>
Date:   Fri Jan 18 23:48:10 2013 +0100

    usb: Fix compilation for MinGW (regression)
    
    84f2d0ea added an argument to function usb_host_info.
    The stub function must match the declaration in usb.h.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/usb/host-stub.c b/hw/usb/host-stub.c
index 58423a0..8affba7 100644
--- a/hw/usb/host-stub.c
+++ b/hw/usb/host-stub.c
@@ -35,7 +35,7 @@
 #include "hw/usb.h"
 #include "monitor/monitor.h"
 
-void usb_host_info(Monitor *mon)
+void usb_host_info(Monitor *mon, const QDict *qdict)
 {
     monitor_printf(mon, "USB host devices not supported\n");
 }
commit 249fe3f3e99c2a57c7f2569edb4031e63e595c9e
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Jan 18 19:30:13 2013 +0100

    cpu-defs.h: Drop qemu_work_item prototype
    
    Commit c64ca8140e9c21cd0d44c10fbe1247cb4ade8e6e (cpu: Move
    queued_work_{first,last} to CPUState) moved the qemu_work_item fields
    away. Clean up the now unused prototype.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index d0cf85a..2911b9f 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -134,8 +134,6 @@ typedef struct icount_decr_u16 {
 } icount_decr_u16;
 #endif
 
-struct qemu_work_item;
-
 typedef struct CPUBreakpoint {
     target_ulong pc;
     int flags; /* BP_* */
commit 5256a7208a7c2af19baf8f99bd4f06632f9f9ba9
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu Jan 17 20:04:16 2013 +0000

    tcg/target-arm: Add missing parens to assertions
    
    Silence a (legitimate) complaint about missing parentheses:
    
    tcg/arm/tcg-target.c: In function ‘tcg_out_qemu_ld’:
    tcg/arm/tcg-target.c:1148:5: error: suggest parentheses around
    comparison in operand of ‘&’ [-Werror=parentheses]
    tcg/arm/tcg-target.c: In function ‘tcg_out_qemu_st’:
    tcg/arm/tcg-target.c:1357:5: error: suggest parentheses around
    comparison in operand of ‘&’ [-Werror=parentheses]
    
    which meant that we would mistakenly always assert if running
    a QEMU built with debug enabled on ARM.
    
    Signed-off-by: Peter Maydell <peter.maydelL at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index c3ac85e..d9c33d8 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -1145,7 +1145,7 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
                     TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
     /* We assume that the offset is contained within 20 bits.  */
     tlb_offset = offsetof(CPUArchState, tlb_table[mem_index][0].addr_read);
-    assert(tlb_offset & ~0xfffff == 0);
+    assert((tlb_offset & ~0xfffff) == 0);
     if (tlb_offset > 0xfff) {
         tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_REG_R0,
                         0xa00 | (tlb_offset >> 12));
@@ -1354,7 +1354,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
                     TCG_AREG0, TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
     /* We assume that the offset is contained within 20 bits.  */
     tlb_offset = offsetof(CPUArchState, tlb_table[mem_index][0].addr_write);
-    assert(tlb_offset & ~0xfffff == 0);
+    assert((tlb_offset & ~0xfffff) == 0);
     if (tlb_offset > 0xfff) {
         tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_REG_R0,
                         0xa00 | (tlb_offset >> 12));
commit e4ada482420175bc17d6ccb9f2af0e769da78e01
Author: Stefan Weil <sw at weilnetz.de>
Date:   Wed Jan 16 18:37:23 2013 +0100

    Replace non-portable asprintf by g_strdup_printf
    
    g_strdup_printf already handles OOM errors, so some error handling in
    QEMU code can be removed.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/exec.c b/exec.c
index 5689613..b85508b 100644
--- a/exec.c
+++ b/exec.c
@@ -863,18 +863,16 @@ static void *file_ram_alloc(RAMBlock *block,
         return NULL;
     }
 
-    if (asprintf(&filename, "%s/qemu_back_mem.XXXXXX", path) == -1) {
-        return NULL;
-    }
+    filename = g_strdup_printf("%s/qemu_back_mem.XXXXXX", path);
 
     fd = mkstemp(filename);
     if (fd < 0) {
         perror("unable to create backing store for hugepages");
-        free(filename);
+        g_free(filename);
         return NULL;
     }
     unlink(filename);
-    free(filename);
+    g_free(filename);
 
     memory = (memory+hpagesize-1) & ~(hpagesize-1);
 
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 77f6ee7..0ad73f3 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -939,14 +939,11 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
 
             mac_addr = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
 
-            if (asprintf(&info->value->hardware_address,
-                         "%02x:%02x:%02x:%02x:%02x:%02x",
-                         (int) mac_addr[0], (int) mac_addr[1],
-                         (int) mac_addr[2], (int) mac_addr[3],
-                         (int) mac_addr[4], (int) mac_addr[5]) == -1) {
-                error_setg_errno(errp, errno, "failed to format MAC");
-                goto error;
-            }
+            info->value->hardware_address =
+                g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x",
+                                (int) mac_addr[0], (int) mac_addr[1],
+                                (int) mac_addr[2], (int) mac_addr[3],
+                                (int) mac_addr[4], (int) mac_addr[5]);
 
             info->value->has_hardware_address = true;
             close(sock);
diff --git a/util/path.c b/util/path.c
index 4c5b0f6..f0c6962 100644
--- a/util/path.c
+++ b/util/path.c
@@ -47,10 +47,7 @@ static struct pathelem *new_entry(const char *root,
 {
     struct pathelem *new = malloc(sizeof(*new));
     new->name = strdup(name);
-    if (asprintf(&new->pathname, "%s/%s", root, name) == -1) {
-        printf("Cannot allocate memory\n");
-        exit(1);
-    }
+    new->pathname = g_strdup_printf("%s/%s", root, name);
     new->num_entries = 0;
     return new;
 }
commit 0e7a75929353b04bd2fce1be8640226883b42a10
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Jan 16 14:50:29 2013 +0100

    vl: Use size_t for sizes in get_boot_devices_list()
    
    Code mixes uint32_t, int and size_t.  Very unlikely to go wrong in
    practice, but clean it up anyway.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 699383c..3b31d77 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -471,7 +471,7 @@ void fw_cfg_add_file(FWCfgState *s,  const char *filename,
 
 static void fw_cfg_machine_ready(struct Notifier *n, void *data)
 {
-    uint32_t len;
+    size_t len;
     FWCfgState *s = container_of(n, FWCfgState, machine_ready);
     char *bootindex = get_boot_devices_list(&len);
 
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index cd12f09..6599617 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -179,7 +179,7 @@ void register_devices(void);
 
 void add_boot_device_path(int32_t bootindex, DeviceState *dev,
                           const char *suffix);
-char *get_boot_devices_list(uint32_t *size);
+char *get_boot_devices_list(size_t *size);
 
 bool usb_enabled(bool default_usb);
 
diff --git a/vl.c b/vl.c
index f4cf7e8..4ee1302 100644
--- a/vl.c
+++ b/vl.c
@@ -1198,15 +1198,15 @@ void add_boot_device_path(int32_t bootindex, DeviceState *dev,
  * memory pointed by "size" is assigned total length of the array in bytes
  *
  */
-char *get_boot_devices_list(uint32_t *size)
+char *get_boot_devices_list(size_t *size)
 {
     FWBootEntry *i;
-    uint32_t total = 0;
+    size_t total = 0;
     char *list = NULL;
 
     QTAILQ_FOREACH(i, &fw_boot_order, link) {
         char *devpath = NULL, *bootpath;
-        int len;
+        size_t len;
 
         if (i->dev) {
             devpath = qdev_get_fw_dev_path(i->dev);
commit 089da572b956ef0f8f5b8d5917358e07892a77c2
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Jan 16 14:50:28 2013 +0100

    fw_cfg: Use void *, size_t instead of uint8_t *, uint32_t for blobs
    
    Many callers pass size_t, which gets silently truncated to uint32_t.
    Harmless, because all practical sizes are well below 4GiB.  Clean it
    up anyway.  Size overflow now fails assertions.
    
    Bonus: saves a whole bunch of silly casts.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 3d6dd5f..699383c 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -373,23 +373,23 @@ static const VMStateDescription vmstate_fw_cfg = {
     }
 };
 
-void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, uint8_t *data, uint32_t len)
+void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len)
 {
     int arch = !!(key & FW_CFG_ARCH_LOCAL);
 
     key &= FW_CFG_ENTRY_MASK;
 
-    assert(key < FW_CFG_MAX_ENTRY);
+    assert(key < FW_CFG_MAX_ENTRY && len < UINT32_MAX);
 
     s->entries[arch][key].data = data;
-    s->entries[arch][key].len = len;
+    s->entries[arch][key].len = (uint32_t)len;
 }
 
 void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value)
 {
     size_t sz = strlen(value) + 1;
 
-    return fw_cfg_add_bytes(s, key, (uint8_t *)g_memdup(value, sz), sz);
+    return fw_cfg_add_bytes(s, key, g_memdup(value, sz), sz);
 }
 
 void fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value)
@@ -398,7 +398,7 @@ void fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value)
 
     copy = g_malloc(sizeof(value));
     *copy = cpu_to_le16(value);
-    fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
+    fw_cfg_add_bytes(s, key, copy, sizeof(value));
 }
 
 void fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value)
@@ -407,7 +407,7 @@ void fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value)
 
     copy = g_malloc(sizeof(value));
     *copy = cpu_to_le32(value);
-    fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
+    fw_cfg_add_bytes(s, key, copy, sizeof(value));
 }
 
 void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value)
@@ -416,11 +416,11 @@ void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value)
 
     copy = g_malloc(sizeof(value));
     *copy = cpu_to_le64(value);
-    fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
+    fw_cfg_add_bytes(s, key, copy, sizeof(value));
 }
 
 void fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
-                         void *callback_opaque, uint8_t *data, size_t len)
+                         void *callback_opaque, void *data, size_t len)
 {
     int arch = !!(key & FW_CFG_ARCH_LOCAL);
 
@@ -428,23 +428,24 @@ void fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
 
     key &= FW_CFG_ENTRY_MASK;
 
-    assert(key < FW_CFG_MAX_ENTRY && len <= 65535);
+    assert(key < FW_CFG_MAX_ENTRY && len <= UINT32_MAX);
 
     s->entries[arch][key].data = data;
-    s->entries[arch][key].len = len;
+    s->entries[arch][key].len = (uint32_t)len;
     s->entries[arch][key].callback_opaque = callback_opaque;
     s->entries[arch][key].callback = callback;
 }
 
-void fw_cfg_add_file(FWCfgState *s,  const char *filename, uint8_t *data,
-                     uint32_t len)
+void fw_cfg_add_file(FWCfgState *s,  const char *filename,
+                     void *data, size_t len)
 {
     int i, index;
+    size_t dsize;
 
     if (!s->files) {
-        int dsize = sizeof(uint32_t) + sizeof(FWCfgFile) * FW_CFG_FILE_SLOTS;
+        dsize = sizeof(uint32_t) + sizeof(FWCfgFile) * FW_CFG_FILE_SLOTS;
         s->files = g_malloc0(dsize);
-        fw_cfg_add_bytes(s, FW_CFG_FILE_DIR, (uint8_t*)s->files, dsize);
+        fw_cfg_add_bytes(s, FW_CFG_FILE_DIR, s->files, dsize);
     }
 
     index = be32_to_cpu(s->files->count);
@@ -498,7 +499,7 @@ FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
     if (data_addr) {
         sysbus_mmio_map(d, 1, data_addr);
     }
-    fw_cfg_add_bytes(s, FW_CFG_SIGNATURE, (uint8_t *)"QEMU", 4);
+    fw_cfg_add_bytes(s, FW_CFG_SIGNATURE, (char *)"QEMU", 4);
     fw_cfg_add_bytes(s, FW_CFG_UUID, qemu_uuid, 16);
     fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)(display_type == DT_NOGRAPHIC));
     fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
diff --git a/hw/fw_cfg.h b/hw/fw_cfg.h
index c2c57cd..05c8df1 100644
--- a/hw/fw_cfg.h
+++ b/hw/fw_cfg.h
@@ -54,15 +54,15 @@ typedef struct FWCfgFiles {
 typedef void (*FWCfgCallback)(void *opaque, uint8_t *data);
 
 typedef struct FWCfgState FWCfgState;
-void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, uint8_t *data, uint32_t len);
+void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len);
 void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value);
 void fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value);
 void fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value);
 void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value);
 void fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
-                         void *callback_opaque, uint8_t *data, size_t len);
-void fw_cfg_add_file(FWCfgState *s, const char *filename, uint8_t *data,
-                     uint32_t len);
+                         void *callback_opaque, void *data, size_t len);
+void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data,
+                     size_t len);
 FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
                         hwaddr crl_addr, hwaddr data_addr);
 
diff --git a/hw/pc.c b/hw/pc.c
index 34cf79d..8fc69db 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -563,19 +563,18 @@ static void *bochs_bios_init(void)
 
     fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
-    fw_cfg_add_bytes(fw_cfg, FW_CFG_ACPI_TABLES, (uint8_t *)acpi_tables,
-                     acpi_tables_len);
+    fw_cfg_add_bytes(fw_cfg, FW_CFG_ACPI_TABLES,
+                     acpi_tables, acpi_tables_len);
     fw_cfg_add_i32(fw_cfg, FW_CFG_IRQ0_OVERRIDE, kvm_allows_irq0_override());
 
     smbios_table = smbios_get_table(&smbios_len);
     if (smbios_table)
         fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
                          smbios_table, smbios_len);
-    fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE, (uint8_t *)&e820_table,
-                     sizeof(e820_table));
+    fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE,
+                     &e820_table, sizeof(e820_table));
 
-    fw_cfg_add_bytes(fw_cfg, FW_CFG_HPET, (uint8_t *)&hpet_cfg,
-                     sizeof(struct hpet_fw_config));
+    fw_cfg_add_bytes(fw_cfg, FW_CFG_HPET, &hpet_cfg, sizeof(hpet_cfg));
     /* allocate memory for the NUMA channel: one (64bit) word for the number
      * of nodes, one word for each VCPU->node and one word for each node to
      * hold the amount of memory.
@@ -593,7 +592,7 @@ static void *bochs_bios_init(void)
     for (i = 0; i < nb_numa_nodes; i++) {
         numa_fw_cfg[max_cpus + 1 + i] = cpu_to_le64(node_mem[i]);
     }
-    fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, (uint8_t *)numa_fw_cfg,
+    fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg,
                      (1 + max_cpus + nb_numa_nodes) * sizeof(*numa_fw_cfg));
 
     return fw_cfg;
diff --git a/trace-events b/trace-events
index cf76a11..7de9106 100644
--- a/trace-events
+++ b/trace-events
@@ -172,7 +172,7 @@ fw_cfg_write(void *s, uint8_t value) "%p %d"
 fw_cfg_select(void *s, uint16_t key, int ret) "%p key %d = %d"
 fw_cfg_read(void *s, uint8_t ret) "%p = %d"
 fw_cfg_add_file_dupe(void *s, char *name) "%p %s"
-fw_cfg_add_file(void *s, int index, char *name, uint32_t len) "%p #%d: %s (%d bytes)"
+fw_cfg_add_file(void *s, int index, char *name, size_t len) "%p #%d: %s (%zd bytes)"
 
 # hw/hd-geometry.c
 hd_geometry_lchs_guess(void *bs, int cyls, int heads, int secs) "bs %p LCHS %d %d %d"
commit b3dd15529de22cd4bcedb6344105e87878d971b6
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Jan 16 14:50:27 2013 +0100

    pc: Clean up bochs_bios_init()'s (non-)use of sizeof
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/pc.c b/hw/pc.c
index bc5c33f..34cf79d 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -572,7 +572,7 @@ static void *bochs_bios_init(void)
         fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
                          smbios_table, smbios_len);
     fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE, (uint8_t *)&e820_table,
-                     sizeof(struct e820_table));
+                     sizeof(e820_table));
 
     fw_cfg_add_bytes(fw_cfg, FW_CFG_HPET, (uint8_t *)&hpet_cfg,
                      sizeof(struct hpet_fw_config));
@@ -580,7 +580,7 @@ static void *bochs_bios_init(void)
      * of nodes, one word for each VCPU->node and one word for each node to
      * hold the amount of memory.
      */
-    numa_fw_cfg = g_malloc0((1 + max_cpus + nb_numa_nodes) * 8);
+    numa_fw_cfg = g_new0(uint64_t, 1 + max_cpus + nb_numa_nodes);
     numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes);
     for (i = 0; i < max_cpus; i++) {
         for (j = 0; j < nb_numa_nodes; j++) {
@@ -594,7 +594,7 @@ static void *bochs_bios_init(void)
         numa_fw_cfg[max_cpus + 1 + i] = cpu_to_le64(node_mem[i]);
     }
     fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, (uint8_t *)numa_fw_cfg,
-                     (1 + max_cpus + nb_numa_nodes) * 8);
+                     (1 + max_cpus + nb_numa_nodes) * sizeof(*numa_fw_cfg));
 
     return fw_cfg;
 }
commit 0e0d2d6295076815ded8d0868b7b806380df5dda
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Jan 16 14:50:26 2013 +0100

    sun4: Fix unchecked strdup() by switching to fw_cfg_add_string()
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/sun4m.c b/hw/sun4m.c
index 95c5058..41730bc 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -1030,9 +1030,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
     if (kernel_cmdline) {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
         pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
-        fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
-                         (uint8_t*)strdup(kernel_cmdline),
-                         strlen(kernel_cmdline) + 1);
+        fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
                        strlen(kernel_cmdline) + 1);
     } else {
@@ -1676,9 +1674,7 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
     if (kernel_cmdline) {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
         pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
-        fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
-                         (uint8_t*)strdup(kernel_cmdline),
-                         strlen(kernel_cmdline) + 1);
+        fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
     }
@@ -1878,9 +1874,7 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
     if (kernel_cmdline) {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
         pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
-        fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
-                         (uint8_t*)strdup(kernel_cmdline),
-                         strlen(kernel_cmdline) + 1);
+        fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
     }
diff --git a/hw/sun4u.c b/hw/sun4u.c
index cb75d03..d36acde 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -886,9 +886,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     if (kernel_cmdline) {
         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
                        strlen(kernel_cmdline) + 1);
-        fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
-                         (uint8_t*)strdup(kernel_cmdline),
-                         strlen(kernel_cmdline) + 1);
+        fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 0);
     }
commit 96f8058629d99ab689ff233c6133d6cf7f034679
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Jan 16 14:50:25 2013 +0100

    pc: Fix unchecked strdup() by switching to fw_cfg_add_string()
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/pc.c b/hw/pc.c
index ba1f19d..bc5c33f 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -693,9 +693,7 @@ static void load_linux(void *fw_cfg,
 
     fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr);
     fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(kernel_cmdline)+1);
-    fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA,
-                     (uint8_t*)strdup(kernel_cmdline),
-                     strlen(kernel_cmdline)+1);
+    fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
 
     if (protocol >= 0x202) {
 	stl_p(header+0x228, cmdline_addr);
commit 44687f75434ea938e9d29fdc3696ff4bdc0978fa
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Jan 16 14:50:24 2013 +0100

    fw_cfg: New fw_cfg_add_string()
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 0361f68..3d6dd5f 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -385,6 +385,13 @@ void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, uint8_t *data, uint32_t len)
     s->entries[arch][key].len = len;
 }
 
+void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value)
+{
+    size_t sz = strlen(value) + 1;
+
+    return fw_cfg_add_bytes(s, key, (uint8_t *)g_memdup(value, sz), sz);
+}
+
 void fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value)
 {
     uint16_t *copy;
diff --git a/hw/fw_cfg.h b/hw/fw_cfg.h
index 7d32f28..c2c57cd 100644
--- a/hw/fw_cfg.h
+++ b/hw/fw_cfg.h
@@ -55,6 +55,7 @@ typedef void (*FWCfgCallback)(void *opaque, uint8_t *data);
 
 typedef struct FWCfgState FWCfgState;
 void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, uint8_t *data, uint32_t len);
+void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value);
 void fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value);
 void fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value);
 void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value);
commit 4cad3867b6df2c0826ae508a9fe15dd0b9d8936a
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Jan 16 14:50:23 2013 +0100

    fw_cfg: Dumb down fw_cfg_add_*() not to return success / failure
    
    No caller is checking the value, so all errors get ignored, usually
    silently.  assert() instead.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 2fadf36..0361f68 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -373,71 +373,64 @@ static const VMStateDescription vmstate_fw_cfg = {
     }
 };
 
-int fw_cfg_add_bytes(FWCfgState *s, uint16_t key, uint8_t *data, uint32_t len)
+void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, uint8_t *data, uint32_t len)
 {
     int arch = !!(key & FW_CFG_ARCH_LOCAL);
 
     key &= FW_CFG_ENTRY_MASK;
 
-    if (key >= FW_CFG_MAX_ENTRY)
-        return 0;
+    assert(key < FW_CFG_MAX_ENTRY);
 
     s->entries[arch][key].data = data;
     s->entries[arch][key].len = len;
-
-    return 1;
 }
 
-int fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value)
+void fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value)
 {
     uint16_t *copy;
 
     copy = g_malloc(sizeof(value));
     *copy = cpu_to_le16(value);
-    return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
+    fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
 }
 
-int fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value)
+void fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value)
 {
     uint32_t *copy;
 
     copy = g_malloc(sizeof(value));
     *copy = cpu_to_le32(value);
-    return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
+    fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
 }
 
-int fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value)
+void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value)
 {
     uint64_t *copy;
 
     copy = g_malloc(sizeof(value));
     *copy = cpu_to_le64(value);
-    return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
+    fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
 }
 
-int fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
-                        void *callback_opaque, uint8_t *data, size_t len)
+void fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
+                         void *callback_opaque, uint8_t *data, size_t len)
 {
     int arch = !!(key & FW_CFG_ARCH_LOCAL);
 
-    if (!(key & FW_CFG_WRITE_CHANNEL))
-        return 0;
+    assert(key & FW_CFG_WRITE_CHANNEL);
 
     key &= FW_CFG_ENTRY_MASK;
 
-    if (key >= FW_CFG_MAX_ENTRY || len > 65535)
-        return 0;
+    assert(key < FW_CFG_MAX_ENTRY && len <= 65535);
 
     s->entries[arch][key].data = data;
     s->entries[arch][key].len = len;
     s->entries[arch][key].callback_opaque = callback_opaque;
     s->entries[arch][key].callback = callback;
-
-    return 1;
 }
 
-int fw_cfg_add_file(FWCfgState *s,  const char *filename, uint8_t *data,
-                    uint32_t len)
+void fw_cfg_add_file(FWCfgState *s,  const char *filename, uint8_t *data,
+                     uint32_t len)
 {
     int i, index;
 
@@ -448,10 +441,7 @@ int fw_cfg_add_file(FWCfgState *s,  const char *filename, uint8_t *data,
     }
 
     index = be32_to_cpu(s->files->count);
-    if (index == FW_CFG_FILE_SLOTS) {
-        fprintf(stderr, "fw_cfg: out of file slots\n");
-        return 0;
-    }
+    assert(index < FW_CFG_FILE_SLOTS);
 
     fw_cfg_add_bytes(s, FW_CFG_FILE_FIRST + index, data, len);
 
@@ -460,7 +450,7 @@ int fw_cfg_add_file(FWCfgState *s,  const char *filename, uint8_t *data,
     for (i = 0; i < index; i++) {
         if (strcmp(s->files->f[index].name, s->files->f[i].name) == 0) {
             trace_fw_cfg_add_file_dupe(s, s->files->f[index].name);
-            return 1;
+            return;
         }
     }
 
@@ -469,7 +459,6 @@ int fw_cfg_add_file(FWCfgState *s,  const char *filename, uint8_t *data,
     trace_fw_cfg_add_file(s, index, s->files->f[index].name, len);
 
     s->files->count = cpu_to_be32(index+1);
-    return 1;
 }
 
 static void fw_cfg_machine_ready(struct Notifier *n, void *data)
diff --git a/hw/fw_cfg.h b/hw/fw_cfg.h
index 619a394..7d32f28 100644
--- a/hw/fw_cfg.h
+++ b/hw/fw_cfg.h
@@ -54,14 +54,14 @@ typedef struct FWCfgFiles {
 typedef void (*FWCfgCallback)(void *opaque, uint8_t *data);
 
 typedef struct FWCfgState FWCfgState;
-int fw_cfg_add_bytes(FWCfgState *s, uint16_t key, uint8_t *data, uint32_t len);
-int fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value);
-int fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value);
-int fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value);
-int fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
-                        void *callback_opaque, uint8_t *data, size_t len);
-int fw_cfg_add_file(FWCfgState *s, const char *filename, uint8_t *data,
-                    uint32_t len);
+void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, uint8_t *data, uint32_t len);
+void fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value);
+void fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value);
+void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value);
+void fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
+                         void *callback_opaque, uint8_t *data, size_t len);
+void fw_cfg_add_file(FWCfgState *s, const char *filename, uint8_t *data,
+                     uint32_t len);
 FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
                         hwaddr crl_addr, hwaddr data_addr);
 
commit f6e3534327e94c1c222cbbe8011d47b73c102686
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Jan 16 14:50:22 2013 +0100

    fw_cfg: Replace debug prints by tracepoints
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 7c9480c..2fadf36 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -26,19 +26,10 @@
 #include "isa.h"
 #include "fw_cfg.h"
 #include "sysbus.h"
+#include "trace.h"
 #include "qemu/error-report.h"
 #include "qemu/config-file.h"
 
-/* debug firmware config */
-//#define DEBUG_FW_CFG
-
-#ifdef DEBUG_FW_CFG
-#define FW_CFG_DPRINTF(fmt, ...)                        \
-    do { printf("FW_CFG: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define FW_CFG_DPRINTF(fmt, ...)
-#endif
-
 #define FW_CFG_SIZE 2
 #define FW_CFG_DATA_SIZE 1
 
@@ -213,7 +204,7 @@ static void fw_cfg_write(FWCfgState *s, uint8_t value)
     int arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL);
     FWCfgEntry *e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
 
-    FW_CFG_DPRINTF("write %d\n", value);
+    trace_fw_cfg_write(s, value);
 
     if (s->cur_entry & FW_CFG_WRITE_CHANNEL && e->callback &&
         s->cur_offset < e->len) {
@@ -238,8 +229,7 @@ static int fw_cfg_select(FWCfgState *s, uint16_t key)
         ret = 1;
     }
 
-    FW_CFG_DPRINTF("select key %d (%sfound)\n", key, ret ? "" : "not ");
-
+    trace_fw_cfg_select(s, key, ret);
     return ret;
 }
 
@@ -254,8 +244,7 @@ static uint8_t fw_cfg_read(FWCfgState *s)
     else
         ret = e->data[s->cur_offset++];
 
-    FW_CFG_DPRINTF("read %d\n", ret);
-
+    trace_fw_cfg_read(s, ret);
     return ret;
 }
 
@@ -470,16 +459,14 @@ int fw_cfg_add_file(FWCfgState *s,  const char *filename, uint8_t *data,
             filename);
     for (i = 0; i < index; i++) {
         if (strcmp(s->files->f[index].name, s->files->f[i].name) == 0) {
-            FW_CFG_DPRINTF("%s: skip duplicate: %s\n", __FUNCTION__,
-                           s->files->f[index].name);
+            trace_fw_cfg_add_file_dupe(s, s->files->f[index].name);
             return 1;
         }
     }
 
     s->files->f[index].size   = cpu_to_be32(len);
     s->files->f[index].select = cpu_to_be16(FW_CFG_FILE_FIRST + index);
-    FW_CFG_DPRINTF("%s: #%d: %s (%d bytes)\n", __FUNCTION__,
-                   index, s->files->f[index].name, len);
+    trace_fw_cfg_add_file(s, index, s->files->f[index].name, len);
 
     s->files->count = cpu_to_be32(index+1);
     return 1;
diff --git a/trace-events b/trace-events
index 6eabbac..cf76a11 100644
--- a/trace-events
+++ b/trace-events
@@ -167,6 +167,13 @@ ecc_mem_readl_ecr1(uint32_t ret) "Read event count 2 %08x"
 ecc_diag_mem_writeb(uint64_t addr, uint32_t val) "Write diagnostic %"PRId64" = %02x"
 ecc_diag_mem_readb(uint64_t addr, uint32_t ret) "Read diagnostic %"PRId64"= %02x"
 
+# hw/fw_cfg.c
+fw_cfg_write(void *s, uint8_t value) "%p %d"
+fw_cfg_select(void *s, uint16_t key, int ret) "%p key %d = %d"
+fw_cfg_read(void *s, uint8_t ret) "%p = %d"
+fw_cfg_add_file_dupe(void *s, char *name) "%p %s"
+fw_cfg_add_file(void *s, int index, char *name, uint32_t len) "%p #%d: %s (%d bytes)"
+
 # hw/hd-geometry.c
 hd_geometry_lchs_guess(void *bs, int cyls, int heads, int secs) "bs %p LCHS %d %d %d"
 hd_geometry_guess(void *bs, uint32_t cyls, uint32_t heads, uint32_t secs, int trans) "bs %p CHS %u %u %u trans %d"
commit 633f6502544e3dd6a615679ce440875be7ebbc58
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri Jan 11 15:42:53 2013 -0800

    optimize: optimize using nonzero bits
    
    This adds two optimizations using the non-zero bit mask.  In some cases
    involving shifts or ANDs the value can become zero, and can thus be
    optimized to a move of zero.  Second, useless zero-extension or an
    AND with constant can be detected that would only zero bits that are
    already zero.
    
    The main advantage of this optimization is that it turns zero-extensions
    into moves, thus enabling much better copy propagation (around 1% code
    reduction).  Here is for example a "test $0xff0000,%ecx + je" before
    optimization:
    
     mov_i64 tmp0,rcx
     movi_i64 tmp1,$0xff0000
     discard cc_src
     and_i64 cc_dst,tmp0,tmp1
     movi_i32 cc_op,$0x1c
     ext32u_i64 tmp0,cc_dst
     movi_i64 tmp12,$0x0
     brcond_i64 tmp0,tmp12,eq,$0x0
    
    and after (without patch on the left, with on the right):
    
     movi_i64 tmp1,$0xff0000                 movi_i64 tmp1,$0xff0000
     discard cc_src                          discard cc_src
     and_i64 cc_dst,rcx,tmp1                 and_i64 cc_dst,rcx,tmp1
     movi_i32 cc_op,$0x1c                    movi_i32 cc_op,$0x1c
     ext32u_i64 tmp0,cc_dst
     movi_i64 tmp12,$0x0                     movi_i64 tmp12,$0x0
     brcond_i64 tmp0,tmp12,eq,$0x0           brcond_i64 cc_dst,tmp12,eq,$0x0
    
    Other similar cases: "test %eax, %eax + jne" where eax is already 32-bit
    (after optimization, without patch on the left, with on the right):
    
     discard cc_src                          discard cc_src
     mov_i64 cc_dst,rax                      mov_i64 cc_dst,rax
     movi_i32 cc_op,$0x1c                    movi_i32 cc_op,$0x1c
     ext32u_i64 tmp0,cc_dst
     movi_i64 tmp12,$0x0                     movi_i64 tmp12,$0x0
     brcond_i64 tmp0,tmp12,ne,$0x0           brcond_i64 rax,tmp12,ne,$0x0
    
    "test $0x1, %dl + je":
    
     movi_i64 tmp1,$0x1                      movi_i64 tmp1,$0x1
     discard cc_src                          discard cc_src
     and_i64 cc_dst,rdx,tmp1                 and_i64 cc_dst,rdx,tmp1
     movi_i32 cc_op,$0x1a                    movi_i32 cc_op,$0x1a
     ext8u_i64 tmp0,cc_dst
     movi_i64 tmp12,$0x0                     movi_i64 tmp12,$0x0
     brcond_i64 tmp0,tmp12,eq,$0x0           brcond_i64 cc_dst,tmp12,eq,$0x0
    
    In some cases TCG even outsmarts GCC. :)  Here the input code has
    "and $0x2,%eax + movslq %eax,%rbx + test %rbx, %rbx" and the optimizer,
    thanks to copy propagation, does the following:
    
     movi_i64 tmp12,$0x2                     movi_i64 tmp12,$0x2
     and_i64 rax,rax,tmp12                   and_i64 rax,rax,tmp12
     mov_i64 cc_dst,rax                      mov_i64 cc_dst,rax
     ext32s_i64 tmp0,rax                  -> nop
     mov_i64 rbx,tmp0                     -> mov_i64 rbx,cc_dst
     and_i64 cc_dst,rbx,rbx               -> nop
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 090efbc..973d2d6 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -484,7 +484,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
                                     TCGArg *args, TCGOpDef *tcg_op_defs)
 {
     int i, nb_ops, op_index, nb_temps, nb_globals, nb_call_args;
-    tcg_target_ulong mask;
+    tcg_target_ulong mask, affected;
     TCGOpcode op;
     const TCGOpDef *def;
     TCGArg *gen_args;
@@ -629,6 +629,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
 
         /* Simplify using known-zero bits */
         mask = -1;
+        affected = -1;
         switch (op) {
         CASE_OP_32_64(ext8s):
             if ((temps[args[1]].mask & 0x80) != 0) {
@@ -656,7 +657,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
             mask = temps[args[2]].mask;
             if (temps[args[2]].state == TCG_TEMP_CONST) {
         and_const:
-                ;
+                affected = temps[args[1]].mask & ~mask;
             }
             mask = temps[args[1]].mask & mask;
             break;
@@ -708,6 +709,31 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
             break;
         }
 
+        if (mask == 0) {
+            assert(def->nb_oargs == 1);
+            s->gen_opc_buf[op_index] = op_to_movi(op);
+            tcg_opt_gen_movi(gen_args, args[0], 0);
+            args += def->nb_oargs + def->nb_iargs + def->nb_cargs;
+            gen_args += 2;
+            continue;
+        }
+        if (affected == 0) {
+            assert(def->nb_oargs == 1);
+            if (temps_are_copies(args[0], args[1])) {
+                s->gen_opc_buf[op_index] = INDEX_op_nop;
+            } else if (temps[args[1]].state != TCG_TEMP_CONST) {
+                s->gen_opc_buf[op_index] = op_to_mov(op);
+                tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
+                gen_args += 2;
+            } else {
+                s->gen_opc_buf[op_index] = op_to_movi(op);
+                tcg_opt_gen_movi(gen_args, args[0], temps[args[1]].val);
+                gen_args += 2;
+            }
+            args += def->nb_iargs + 1;
+            continue;
+        }
+
         /* Simplify expression for "op r, a, 0 => movi r, 0" cases */
         switch (op) {
         CASE_OP_32_64(and):
commit 3a9d8b179b1e43237365ede641d5aa6779ba91bc
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri Jan 11 15:42:52 2013 -0800

    optimize: track nonzero bits of registers
    
    Add a "mask" field to the tcg_temp_info struct.  A bit that is zero
    in "mask" will always be zero in the corresponding temporary.
    Zero bits in the mask can be produced from moves of immediates,
    zero-extensions, ANDs with constants, shifts; they can then be
    be propagated by logical operations, shifts, sign-extensions,
    negations, deposit operations, and conditional moves.  Other
    operations will just reset the mask to all-ones, i.e. unknown.
    
    [rth: s/target_ulong/tcg_target_ulong/]
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 9d05a72..090efbc 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -46,6 +46,7 @@ struct tcg_temp_info {
     uint16_t prev_copy;
     uint16_t next_copy;
     tcg_target_ulong val;
+    tcg_target_ulong mask;
 };
 
 static struct tcg_temp_info temps[TCG_MAX_TEMPS];
@@ -63,6 +64,7 @@ static void reset_temp(TCGArg temp)
         }
     }
     temps[temp].state = TCG_TEMP_UNDEF;
+    temps[temp].mask = -1;
 }
 
 /* Reset all temporaries, given that there are NB_TEMPS of them.  */
@@ -71,6 +73,7 @@ static void reset_all_temps(int nb_temps)
     int i;
     for (i = 0; i < nb_temps; i++) {
         temps[i].state = TCG_TEMP_UNDEF;
+        temps[i].mask = -1;
     }
 }
 
@@ -148,33 +151,35 @@ static bool temps_are_copies(TCGArg arg1, TCGArg arg2)
 static void tcg_opt_gen_mov(TCGContext *s, TCGArg *gen_args,
                             TCGArg dst, TCGArg src)
 {
-        reset_temp(dst);
-        assert(temps[src].state != TCG_TEMP_CONST);
-
-        if (s->temps[src].type == s->temps[dst].type) {
-            if (temps[src].state != TCG_TEMP_COPY) {
-                temps[src].state = TCG_TEMP_COPY;
-                temps[src].next_copy = src;
-                temps[src].prev_copy = src;
-            }
-            temps[dst].state = TCG_TEMP_COPY;
-            temps[dst].next_copy = temps[src].next_copy;
-            temps[dst].prev_copy = src;
-            temps[temps[dst].next_copy].prev_copy = dst;
-            temps[src].next_copy = dst;
+    reset_temp(dst);
+    temps[dst].mask = temps[src].mask;
+    assert(temps[src].state != TCG_TEMP_CONST);
+
+    if (s->temps[src].type == s->temps[dst].type) {
+        if (temps[src].state != TCG_TEMP_COPY) {
+            temps[src].state = TCG_TEMP_COPY;
+            temps[src].next_copy = src;
+            temps[src].prev_copy = src;
         }
+        temps[dst].state = TCG_TEMP_COPY;
+        temps[dst].next_copy = temps[src].next_copy;
+        temps[dst].prev_copy = src;
+        temps[temps[dst].next_copy].prev_copy = dst;
+        temps[src].next_copy = dst;
+    }
 
-        gen_args[0] = dst;
-        gen_args[1] = src;
+    gen_args[0] = dst;
+    gen_args[1] = src;
 }
 
 static void tcg_opt_gen_movi(TCGArg *gen_args, TCGArg dst, TCGArg val)
 {
-        reset_temp(dst);
-        temps[dst].state = TCG_TEMP_CONST;
-        temps[dst].val = val;
-        gen_args[0] = dst;
-        gen_args[1] = val;
+    reset_temp(dst);
+    temps[dst].state = TCG_TEMP_CONST;
+    temps[dst].val = val;
+    temps[dst].mask = val;
+    gen_args[0] = dst;
+    gen_args[1] = val;
 }
 
 static TCGOpcode op_to_mov(TCGOpcode op)
@@ -479,6 +484,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
                                     TCGArg *args, TCGOpDef *tcg_op_defs)
 {
     int i, nb_ops, op_index, nb_temps, nb_globals, nb_call_args;
+    tcg_target_ulong mask;
     TCGOpcode op;
     const TCGOpDef *def;
     TCGArg *gen_args;
@@ -621,6 +627,87 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
             break;
         }
 
+        /* Simplify using known-zero bits */
+        mask = -1;
+        switch (op) {
+        CASE_OP_32_64(ext8s):
+            if ((temps[args[1]].mask & 0x80) != 0) {
+                break;
+            }
+        CASE_OP_32_64(ext8u):
+            mask = 0xff;
+            goto and_const;
+        CASE_OP_32_64(ext16s):
+            if ((temps[args[1]].mask & 0x8000) != 0) {
+                break;
+            }
+        CASE_OP_32_64(ext16u):
+            mask = 0xffff;
+            goto and_const;
+        case INDEX_op_ext32s_i64:
+            if ((temps[args[1]].mask & 0x80000000) != 0) {
+                break;
+            }
+        case INDEX_op_ext32u_i64:
+            mask = 0xffffffffU;
+            goto and_const;
+
+        CASE_OP_32_64(and):
+            mask = temps[args[2]].mask;
+            if (temps[args[2]].state == TCG_TEMP_CONST) {
+        and_const:
+                ;
+            }
+            mask = temps[args[1]].mask & mask;
+            break;
+
+        CASE_OP_32_64(sar):
+            if (temps[args[2]].state == TCG_TEMP_CONST) {
+                mask = ((tcg_target_long)temps[args[1]].mask
+                        >> temps[args[2]].val);
+            }
+            break;
+
+        CASE_OP_32_64(shr):
+            if (temps[args[2]].state == TCG_TEMP_CONST) {
+                mask = temps[args[1]].mask >> temps[args[2]].val;
+            }
+            break;
+
+        CASE_OP_32_64(shl):
+            if (temps[args[2]].state == TCG_TEMP_CONST) {
+                mask = temps[args[1]].mask << temps[args[2]].val;
+            }
+            break;
+
+        CASE_OP_32_64(neg):
+            /* Set to 1 all bits to the left of the rightmost.  */
+            mask = -(temps[args[1]].mask & -temps[args[1]].mask);
+            break;
+
+        CASE_OP_32_64(deposit):
+            tmp = ((1ull << args[4]) - 1);
+            mask = ((temps[args[1]].mask & ~(tmp << args[3]))
+                    | ((temps[args[2]].mask & tmp) << args[3]));
+            break;
+
+        CASE_OP_32_64(or):
+        CASE_OP_32_64(xor):
+            mask = temps[args[1]].mask | temps[args[2]].mask;
+            break;
+
+        CASE_OP_32_64(setcond):
+            mask = 1;
+            break;
+
+        CASE_OP_32_64(movcond):
+            mask = temps[args[3]].mask | temps[args[4]].mask;
+            break;
+
+        default:
+            break;
+        }
+
         /* Simplify expression for "op r, a, 0 => movi r, 0" cases */
         switch (op) {
         CASE_OP_32_64(and):
@@ -947,7 +1034,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
             /* Default case: we know nothing about operation (or were unable
                to compute the operation result) so no propagation is done.
                We trash everything if the operation is the end of a basic
-               block, otherwise we only trash the output args.  */
+               block, otherwise we only trash the output args.  "mask" is
+               the non-zero bits mask for the first output arg.  */
             if (def->flags & TCG_OPF_BB_END) {
                 reset_all_temps(nb_temps);
             } else {
commit d193a14a2c94c9c4877ab100c31ec174dc78644c
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri Jan 11 15:42:51 2013 -0800

    optimize: only write to state when clearing optimizer data
    
    The next patch will add to the TCG optimizer a field that should be
    non-zero in the default case.  Thus, replace the memset of the
    temps array with a loop.  Only the state field has to be up-to-date,
    because others are not used except if the state is TCG_TEMP_COPY
    or TCG_TEMP_CONST.
    
    [rth: Extracted the loop to a function.]
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 9109b81..9d05a72 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -65,6 +65,15 @@ static void reset_temp(TCGArg temp)
     temps[temp].state = TCG_TEMP_UNDEF;
 }
 
+/* Reset all temporaries, given that there are NB_TEMPS of them.  */
+static void reset_all_temps(int nb_temps)
+{
+    int i;
+    for (i = 0; i < nb_temps; i++) {
+        temps[i].state = TCG_TEMP_UNDEF;
+    }
+}
+
 static int op_bits(TCGOpcode op)
 {
     const TCGOpDef *def = &tcg_op_defs[op];
@@ -482,7 +491,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
 
     nb_temps = s->nb_temps;
     nb_globals = s->nb_globals;
-    memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
+    reset_all_temps(nb_temps);
 
     nb_ops = tcg_opc_ptr - s->gen_opc_buf;
     gen_args = args;
@@ -768,7 +777,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
             tmp = do_constant_folding_cond(op, args[0], args[1], args[2]);
             if (tmp != 2) {
                 if (tmp) {
-                    memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
+                    reset_all_temps(nb_temps);
                     s->gen_opc_buf[op_index] = INDEX_op_br;
                     gen_args[0] = args[3];
                     gen_args += 1;
@@ -861,7 +870,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
             tmp = do_constant_folding_cond2(&args[0], &args[2], args[4]);
             if (tmp != 2) {
                 if (tmp) {
-                    memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
+                    reset_all_temps(nb_temps);
                     s->gen_opc_buf[op_index] = INDEX_op_br;
                     gen_args[0] = args[5];
                     gen_args += 1;
@@ -875,7 +884,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
                        && temps[args[3]].val == 0) {
                 /* Simplify LT/GE comparisons vs zero to a single compare
                    vs the high word of the input.  */
-                memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
+                reset_all_temps(nb_temps);
                 s->gen_opc_buf[op_index] = INDEX_op_brcond_i32;
                 gen_args[0] = args[1];
                 gen_args[1] = args[3];
@@ -940,7 +949,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
                We trash everything if the operation is the end of a basic
                block, otherwise we only trash the output args.  */
             if (def->flags & TCG_OPF_BB_END) {
-                memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
+                reset_all_temps(nb_temps);
             } else {
                 for (i = 0; i < def->nb_oargs; i++) {
                     reset_temp(args[i]);
commit 75f0585f1718c575716021d11bfeb695129f785d
Merge: 67c4f2d 5b95b8b
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Jan 19 09:56:41 2013 +0000

    Merge branch 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf
    
    * 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf:
      PPC: KVM: Add support for EPR with KVM
      openpic: export e500 epr enable into a ppc.c function
      Update Linux kernel headers
      PPC: e500: Change in-memory order of load blobs
      PPC: Provide zero SVR for -cpu e500mc and e5500
      PPC: E500: Calculate loading blob offsets properly
      openpic: set mixed mode as supported
      openpic: unify gcr mode mask updates
      openpic: move gcr write into a function

commit 67c4f2d0e11de8ee534b17edafbcbcdcca4b0e9b
Merge: 48b8599 28e942f
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Jan 19 09:55:46 2013 +0000

    Merge branch 's390-for-upstream' of git://repo.or.cz/qemu/agraf
    
    * 's390-for-upstream' of git://repo.or.cz/qemu/agraf:
      s390: Add a hypercall registration interface.
      target-s390x: Unregister reset callback on finalization
      s390x: fix indentation
      s390: Add CPU reset handler
      s390x: Remove inline function ebcdic_put and related data from cpu.h
      S390: Enable -cpu help and QMP query-cpu-definitions
      s390: Move IPL code into a separate device
      s390: new contributions GPLv2 or later

commit 48b8599c991715eeae74f0cb650fc4284cb69227
Merge: ddc01bf 9468a5d
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Jan 19 09:54:31 2013 +0000

    Merge branch 'axp-next' of git://github.com/rth7680/qemu
    
    * 'axp-next' of git://github.com/rth7680/qemu:
      alpha-linux-user: Correct select
      alpha-linux-user: Translate fcntl l_type

commit 28e942f86d46ccd46bf1f4836389abb3ff706dff
Author: Cornelia Huck <cornelia.huck at de.ibm.com>
Date:   Thu Jan 17 04:23:46 2013 +0000

    s390: Add a hypercall registration interface.
    
    Allow virtio machines to register for different diag500 function
    codes and convert s390-virtio to use it.
    
    Signed-off-by: Cornelia Huck <cornelia.huck at de.ibm.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 3cfb97e..5edaabb 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -36,6 +36,7 @@
 
 #include "hw/s390-virtio-bus.h"
 #include "hw/s390x/sclp.h"
+#include "hw/s390-virtio.h"
 
 //#define DEBUG_S390
 
@@ -47,10 +48,6 @@
     do { } while (0)
 #endif
 
-#define KVM_S390_VIRTIO_NOTIFY          0
-#define KVM_S390_VIRTIO_RESET           1
-#define KVM_S390_VIRTIO_SET_STATUS      2
-
 #define MAX_BLK_DEVS                    10
 
 static VirtIOS390Bus *s390_bus;
@@ -65,56 +62,63 @@ S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
     return ipi_states[cpu_addr];
 }
 
-int s390_virtio_hypercall(CPUS390XState *env, uint64_t mem, uint64_t hypercall)
+static int s390_virtio_hcall_notify(const uint64_t *args)
 {
+    uint64_t mem = args[0];
     int r = 0, i;
 
-    dprintf("KVM hypercall: %ld\n", hypercall);
-    switch (hypercall) {
-    case KVM_S390_VIRTIO_NOTIFY:
-        if (mem > ram_size) {
-            VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus,
-                                                               mem, &i);
-            if (dev) {
-                virtio_queue_notify(dev->vdev, i);
-            } else {
-                r = -EINVAL;
-            }
-        } else {
-            /* Early printk */
-        }
-        break;
-    case KVM_S390_VIRTIO_RESET:
-    {
-        VirtIOS390Device *dev;
-
-        dev = s390_virtio_bus_find_mem(s390_bus, mem);
-        virtio_reset(dev->vdev);
-        stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0);
-        s390_virtio_device_sync(dev);
-        s390_virtio_reset_idx(dev);
-        break;
-    }
-    case KVM_S390_VIRTIO_SET_STATUS:
-    {
-        VirtIOS390Device *dev;
-
-        dev = s390_virtio_bus_find_mem(s390_bus, mem);
+    if (mem > ram_size) {
+        VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus, mem, &i);
         if (dev) {
-            s390_virtio_device_update_status(dev);
+            virtio_queue_notify(dev->vdev, i);
         } else {
             r = -EINVAL;
         }
-        break;
+    } else {
+        /* Early printk */
     }
-    default:
+    return r;
+}
+
+static int s390_virtio_hcall_reset(const uint64_t *args)
+{
+    uint64_t mem = args[0];
+    VirtIOS390Device *dev;
+
+    dev = s390_virtio_bus_find_mem(s390_bus, mem);
+    virtio_reset(dev->vdev);
+    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0);
+    s390_virtio_device_sync(dev);
+    s390_virtio_reset_idx(dev);
+
+    return 0;
+}
+
+static int s390_virtio_hcall_set_status(const uint64_t *args)
+{
+    uint64_t mem = args[0];
+    int r = 0;
+    VirtIOS390Device *dev;
+
+    dev = s390_virtio_bus_find_mem(s390_bus, mem);
+    if (dev) {
+        s390_virtio_device_update_status(dev);
+    } else {
         r = -EINVAL;
-        break;
     }
-
     return r;
 }
 
+static void s390_virtio_register_hcalls(void)
+{
+    s390_register_virtio_hypercall(KVM_S390_VIRTIO_NOTIFY,
+                                   s390_virtio_hcall_notify);
+    s390_register_virtio_hypercall(KVM_S390_VIRTIO_RESET,
+                                   s390_virtio_hcall_reset);
+    s390_register_virtio_hypercall(KVM_S390_VIRTIO_SET_STATUS,
+                                   s390_virtio_hcall_set_status);
+}
+
 /*
  * The number of running CPUs. On s390 a shutdown is the state of all CPUs
  * being either stopped or disabled (for interrupts) waiting. We have to
@@ -182,6 +186,9 @@ static void s390_init(QEMUMachineInitArgs *args)
     qdev_prop_set_string(dev, "cmdline", args->kernel_cmdline);
     qdev_init_nofail(dev);
 
+    /* register hypercalls */
+    s390_virtio_register_hcalls();
+
     /* allocate RAM */
     memory_region_init_ram(ram, "s390.ram", my_ram_size);
     vmstate_register_ram_global(ram);
@@ -265,4 +272,3 @@ static void s390_machine_init(void)
 }
 
 machine_init(s390_machine_init);
-
diff --git a/hw/s390-virtio.h b/hw/s390-virtio.h
new file mode 100644
index 0000000..25bb610
--- /dev/null
+++ b/hw/s390-virtio.h
@@ -0,0 +1,22 @@
+/*
+ * Virtio interfaces for s390
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck <cornelia.huck at de.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#ifndef HW_S390_VIRTIO_H
+#define HW_S390_VIRTIO_H 1
+
+#define KVM_S390_VIRTIO_NOTIFY          0
+#define KVM_S390_VIRTIO_RESET           1
+#define KVM_S390_VIRTIO_SET_STATUS      2
+
+typedef int (*s390_virtio_fn)(const uint64_t *args);
+void s390_register_virtio_hypercall(uint64_t code, s390_virtio_fn fn);
+
+#endif
diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index 4a5a5d8..1b40c2e 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -1,6 +1,7 @@
 obj-y = s390-virtio-bus.o s390-virtio.o
 
 obj-y := $(addprefix ../,$(obj-y))
+obj-y += s390-virtio-hcall.o
 obj-y += sclp.o
 obj-y += event-facility.o
 obj-y += sclpquiesce.o sclpconsole.o
diff --git a/hw/s390x/s390-virtio-hcall.c b/hw/s390x/s390-virtio-hcall.c
new file mode 100644
index 0000000..d7938c0
--- /dev/null
+++ b/hw/s390x/s390-virtio-hcall.c
@@ -0,0 +1,36 @@
+/*
+ * Support for virtio hypercalls on s390
+ *
+ * Copyright 2012 IBM Corp.
+ * Author(s): Cornelia Huck <cornelia.huck at de.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include "cpu.h"
+#include "hw/s390-virtio.h"
+
+#define MAX_DIAG_SUBCODES 255
+
+static s390_virtio_fn s390_diag500_table[MAX_DIAG_SUBCODES];
+
+void s390_register_virtio_hypercall(uint64_t code, s390_virtio_fn fn)
+{
+    assert(code < MAX_DIAG_SUBCODES);
+    assert(!s390_diag500_table[code]);
+
+    s390_diag500_table[code] = fn;
+}
+
+int s390_virtio_hypercall(CPUS390XState *env)
+{
+    s390_virtio_fn fn = s390_diag500_table[env->regs[1]];
+
+    if (!fn) {
+        return -EINVAL;
+    }
+
+    return fn(&env->regs[2]);
+}
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 23d8b44..1f2d942 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -305,7 +305,7 @@ int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw
 void s390x_tod_timer(void *opaque);
 void s390x_cpu_timer(void *opaque);
 
-int s390_virtio_hypercall(CPUS390XState *env, uint64_t mem, uint64_t hypercall);
+int s390_virtio_hypercall(CPUS390XState *env);
 
 #ifdef CONFIG_KVM
 void kvm_s390_interrupt(S390CPU *cpu, int type, uint32_t code);
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index a63ee46..add6a58 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -397,7 +397,7 @@ static int handle_priv(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
 static int handle_hypercall(CPUS390XState *env, struct kvm_run *run)
 {
     cpu_synchronize_state(env);
-    env->regs[2] = s390_virtio_hypercall(env, env->regs[2], env->regs[1]);
+    env->regs[2] = s390_virtio_hypercall(env);
 
     return 0;
 }
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index 78d2c0e..09301d0 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -188,7 +188,7 @@ uint64_t HELPER(diag)(CPUS390XState *env, uint32_t num, uint64_t mem,
     switch (num) {
     case 0x500:
         /* KVM hypercall */
-        r = s390_virtio_hypercall(env, mem, code);
+        r = s390_virtio_hypercall(env);
         break;
     case 0x44:
         /* yield */
commit d5627ce8a4fd8dd6d7afd3d4d1ff7e9f1fb86d45
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jan 7 06:14:16 2013 +0000

    target-s390x: Unregister reset callback on finalization
    
    Since commit "s390: Add CPU reset handler" the CPU's instance_init
    registers a reset callback. Unregister that on instance_finalize.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 6810246..0b68db8 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -126,6 +126,15 @@ static void s390_cpu_initfn(Object *obj)
     cpu_reset(CPU(cpu));
 }
 
+static void s390_cpu_finalize(Object *obj)
+{
+#if !defined(CONFIG_USER_ONLY)
+    S390CPU *cpu = S390_CPU(obj);
+
+    qemu_unregister_reset(s390_cpu_machine_reset_cb, cpu);
+#endif
+}
+
 static void s390_cpu_class_init(ObjectClass *oc, void *data)
 {
     S390CPUClass *scc = S390_CPU_CLASS(oc);
@@ -140,6 +149,7 @@ static const TypeInfo s390_cpu_type_info = {
     .parent = TYPE_CPU,
     .instance_size = sizeof(S390CPU),
     .instance_init = s390_cpu_initfn,
+    .instance_finalize = s390_cpu_finalize,
     .abstract = false,
     .class_size = sizeof(S390CPUClass),
     .class_init = s390_cpu_class_init,
commit 419831d7104e6876f47f5eccb758855115086bbd
Author: Alexander Graf <agraf at suse.de>
Date:   Mon Jan 7 16:44:27 2013 +0100

    s390x: fix indentation
    
    In one of the last commits we accidently got 3-space indentation into
    the tree. Fix it up so it's 4 spaces wide.
    
    Reported-by: Andreas Faerber <afaerber at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 8bd3080..a63ee46 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -89,11 +89,11 @@ int kvm_arch_init_vcpu(CPUState *cpu)
 
 void kvm_arch_reset_vcpu(CPUState *cpu)
 {
-   /* The initial reset call is needed here to reset in-kernel
-    * vcpu data that we can't access directly from QEMU
-    * (i.e. with older kernels which don't support sync_regs/ONE_REG).
-    * Before this ioctl cpu_synchronize_state() is called in common kvm
-    * code (kvm-all) */
+    /* The initial reset call is needed here to reset in-kernel
+     * vcpu data that we can't access directly from QEMU
+     * (i.e. with older kernels which don't support sync_regs/ONE_REG).
+     * Before this ioctl cpu_synchronize_state() is called in common kvm
+     * code (kvm-all) */
     if (kvm_vcpu_ioctl(cpu, KVM_S390_INITIAL_RESET, NULL)) {
         perror("Can't reset vcpu\n");
     }
commit 70bada03047f723424c4d08d93719c1a83a43cd2
Author: Jens Freimann <jfrei at linux.vnet.ibm.com>
Date:   Mon Jan 7 05:27:14 2013 +0000

    s390: Add CPU reset handler
    
    Add a CPU reset handler to have all CPUs in a PoP compliant
    state.
    
    Signed-off-by: Jens Freimann <jfrei at linux.vnet.ibm.com>
    [agraf: move hw/hw.h into existing ifdef]
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 420b21b..6810246 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -4,6 +4,7 @@
  * Copyright (c) 2009 Ulrich Hecht
  * Copyright (c) 2011 Alexander Graf
  * Copyright (c) 2012 SUSE LINUX Products GmbH
+ * Copyright (c) 2012 IBM Corp.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,15 +19,21 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see
  * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ * Contributions after 2012-12-11 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
  */
 
 #include "cpu.h"
 #include "qemu-common.h"
 #include "qemu/timer.h"
 #ifndef CONFIG_USER_ONLY
+#include "hw/hw.h"
 #include "sysemu/arch_init.h"
 #endif
 
+#define CR0_RESET       0xE0UL
+#define CR14_RESET      0xC2000000UL;
+
 /* generate CPU information for cpu -? */
 void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf)
 {
@@ -63,14 +70,33 @@ static void s390_cpu_reset(CPUState *s)
         log_cpu_state(env, 0);
     }
 
+    s390_del_running_cpu(env);
+
     scc->parent_reset(s);
 
     memset(env, 0, offsetof(CPUS390XState, breakpoints));
-    /* FIXME: reset vector? */
+
+    /* architectured initial values for CR 0 and 14 */
+    env->cregs[0] = CR0_RESET;
+    env->cregs[14] = CR14_RESET;
+    /* set halted to 1 to make sure we can add the cpu in
+     * s390_ipl_cpu code, where env->halted is set back to 0
+     * after incrementing the cpu counter */
+#if !defined(CONFIG_USER_ONLY)
+    env->halted = 1;
+#endif
     tlb_flush(env, 1);
-    s390_add_running_cpu(env);
 }
 
+#if !defined(CONFIG_USER_ONLY)
+static void s390_cpu_machine_reset_cb(void *opaque)
+{
+    S390CPU *cpu = opaque;
+
+    cpu_reset(CPU(cpu));
+}
+#endif
+
 static void s390_cpu_initfn(Object *obj)
 {
     S390CPU *cpu = S390_CPU(obj);
@@ -82,12 +108,17 @@ static void s390_cpu_initfn(Object *obj)
 
     cpu_exec_init(env);
 #if !defined(CONFIG_USER_ONLY)
+    qemu_register_reset(s390_cpu_machine_reset_cb, cpu);
     qemu_get_timedate(&tm, 0);
     env->tod_offset = TOD_UNIX_EPOCH +
                       (time2tod(mktimegm(&tm)) * 1000000000ULL);
     env->tod_basetime = 0;
     env->tod_timer = qemu_new_timer_ns(vm_clock, s390x_tod_timer, cpu);
     env->cpu_timer = qemu_new_timer_ns(vm_clock, s390x_cpu_timer, cpu);
+    /* set env->halted state to 1 to avoid decrementing the running
+     * cpu counter in s390_cpu_reset to a negative number at
+     * initial ipl */
+    env->halted = 1;
 #endif
     env->cpu_num = cpu_num++;
     env->ext_index = -1;
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 5785f7d..8bd3080 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -89,7 +89,14 @@ int kvm_arch_init_vcpu(CPUState *cpu)
 
 void kvm_arch_reset_vcpu(CPUState *cpu)
 {
-    /* FIXME: add code to reset vcpu. */
+   /* The initial reset call is needed here to reset in-kernel
+    * vcpu data that we can't access directly from QEMU
+    * (i.e. with older kernels which don't support sync_regs/ONE_REG).
+    * Before this ioctl cpu_synchronize_state() is called in common kvm
+    * code (kvm-all) */
+    if (kvm_vcpu_ioctl(cpu, KVM_S390_INITIAL_RESET, NULL)) {
+        perror("Can't reset vcpu\n");
+    }
 }
 
 int kvm_arch_put_registers(CPUState *cs, int level)
commit a158986d85bf75aa078ce3fb53e60a7fa3c6c6ee
Author: Stefan Weil <sw at weilnetz.de>
Date:   Tue Jan 1 08:24:55 2013 +0000

    s390x: Remove inline function ebcdic_put and related data from cpu.h
    
    The function is only used in misc_helper.c, so move it to that file.
    
    This reduces the size of debug executables (compiled without optimization)
    because they get unused code and data for each compilation which includes
    cpu.h.
    
    Executables with optimization don't change their size.
    
    ebcdic2ascii is currently unused and could be removed (not done here).
    
    The array ascii2ebcdic must be accessed with an unsigned index, therefore
    (int)ascii[i] was replaced by (uint8_t)ascii[i]. The old code would have
    failed for a signed char less than 0. The current code only converts
    "QEMU" and spaces to EBCDIC, so there is no problem today.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index d503b9e..23d8b44 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -775,87 +775,6 @@ struct sysib_322 {
 #define SK_F                    (0x1 << 3)
 #define SK_ACC_MASK             (0xf << 4)
 
-
-/* EBCDIC handling */
-static const uint8_t ebcdic2ascii[] = {
-    0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
-    0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-    0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
-    0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-    0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
-    0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
-    0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
-    0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
-    0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
-    0x87, 0xA4, 0x5B, 0x2E, 0x3C, 0x28, 0x2B, 0x21,
-    0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
-    0x8D, 0xE1, 0x5D, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
-    0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
-    0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
-    0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-    0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
-    0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-    0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
-    0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
-    0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
-    0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-    0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
-    0x9B, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
-    0xAB, 0x07, 0xAA, 0x7C, 0x07, 0x07, 0x07, 0x07,
-    0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
-    0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
-    0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
-    0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
-    0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
-    0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
-    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-    0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07,
-};
-
-static const uint8_t ascii2ebcdic [] = {
-    0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
-    0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-    0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
-    0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F,
-    0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
-    0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
-    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
-    0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
-    0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
-    0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
-    0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
-    0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D,
-    0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
-    0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
-    0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
-    0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
-    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-    0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-    0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF
-};
-
-static inline void ebcdic_put(uint8_t *p, const char *ascii, int len)
-{
-    int i;
-
-    for (i = 0; i < len; i++) {
-        p[i] = ascii2ebcdic[(int)ascii[i]];
-    }
-}
-
 #define SIGP_SENSE             0x01
 #define SIGP_EXTERNAL_CALL     0x02
 #define SIGP_EMERGENCY         0x03
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index 3015bfe..78d2c0e 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -70,6 +70,87 @@ void HELPER(exception)(CPUS390XState *env, uint32_t excp)
 }
 
 #ifndef CONFIG_USER_ONLY
+
+/* EBCDIC handling */
+static const uint8_t ebcdic2ascii[] = {
+    0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
+    0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+    0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
+    0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+    0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
+    0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
+    0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
+    0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
+    0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
+    0x87, 0xA4, 0x5B, 0x2E, 0x3C, 0x28, 0x2B, 0x21,
+    0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
+    0x8D, 0xE1, 0x5D, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
+    0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
+    0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
+    0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+    0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
+    0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+    0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
+    0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
+    0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
+    0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+    0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
+    0x9B, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
+    0xAB, 0x07, 0xAA, 0x7C, 0x07, 0x07, 0x07, 0x07,
+    0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+    0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
+    0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
+    0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
+    0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+    0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+    0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07,
+};
+
+static const uint8_t ascii2ebcdic[] = {
+    0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
+    0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+    0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
+    0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F,
+    0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
+    0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
+    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+    0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
+    0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+    0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
+    0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
+    0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D,
+    0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+    0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+    0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
+    0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF
+};
+
+static inline void ebcdic_put(uint8_t *p, const char *ascii, int len)
+{
+    int i;
+
+    for (i = 0; i < len; i++) {
+        p[i] = ascii2ebcdic[(uint8_t)ascii[i]];
+    }
+}
+
 void program_interrupt(CPUS390XState *env, uint32_t code, int ilen)
 {
     qemu_log_mask(CPU_LOG_INT, "program interrupt at %#" PRIx64 "\n",
commit 904e5fd5c25537fdf910bfd5db832df5d9c23ad6
Author: Viktor Mihajlovski <mihajlov at linux.vnet.ibm.com>
Date:   Tue Dec 18 07:50:59 2012 +0000

    S390: Enable -cpu help and QMP query-cpu-definitions
    
    This enables qemu -cpu help to return a list of supported CPU models
    on s390 and also to query for cpu definitions in the monitor.
    Initially only cpu model = host is returned. This needs to be reworked
    into a full-fledged CPU model handling later on.
    This change is needed to allow libvirt exploiters (like OpenStack)
    to specify a CPU model.
    
    Signed-off-by: Viktor Mihajlovski <mihajlov at linux.vnet.ibm.com>
    Signed-off-by: Jens Freimann <jfrei at linux.vnet.ibm.com>
    Reviewed-by: Christian Borntraeger <borntraeger at de.ibm.com>
    [agraf: fix s390x-linux-user, adjust header locations]
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 13f93fb..3cfb97e 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -2,6 +2,7 @@
  * QEMU S390 virtio target
  *
  * Copyright (c) 2009 Alexander Graf <agraf at suse.de>
+ * Copyright IBM Corp 2012
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -13,7 +14,10 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
+ * Contributions after 2012-10-29 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ *
+ * You should have received a copy of the GNU (Lesser) General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 2ed2312..420b21b 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -23,7 +23,33 @@
 #include "cpu.h"
 #include "qemu-common.h"
 #include "qemu/timer.h"
+#ifndef CONFIG_USER_ONLY
+#include "sysemu/arch_init.h"
+#endif
+
+/* generate CPU information for cpu -? */
+void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf)
+{
+#ifdef CONFIG_KVM
+    (*cpu_fprintf)(f, "s390 %16s\n", "host");
+#endif
+}
 
+#ifndef CONFIG_USER_ONLY
+CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
+{
+    CpuDefinitionInfoList *entry;
+    CpuDefinitionInfo *info;
+
+    info = g_malloc0(sizeof(*info));
+    info->name = g_strdup("host");
+
+    entry = g_malloc0(sizeof(*entry));
+    entry->value = info;
+
+    return entry;
+}
+#endif
 
 /* CPUClass::reset() */
 static void s390_cpu_reset(CPUState *s)
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 1fa3ad3..d503b9e 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -362,6 +362,9 @@ static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls)
 #define cpu_gen_code cpu_s390x_gen_code
 #define cpu_signal_handler cpu_s390x_signal_handler
 
+void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf);
+#define cpu_list s390_cpu_list
+
 #include "exec/exec-all.h"
 
 #define EXCP_EXT 1 /* external interrupt */
commit e674a49aae8b79bc4ea07f1bcd666bbf28b12a27
Author: Christian Borntraeger <borntraeger at de.ibm.com>
Date:   Tue Dec 18 07:50:57 2012 +0000

    s390: Move IPL code into a separate device
    
    Lets move the code to setup IPL for external kernel
    or via the zipl rom into a separate file. This allows to
    
    - define a reboot handler, setting up the PSW appropriately
    - enhance the boot code to IPL disks that contain a bootmap that
      was created with zipl under LPAR or z/VM (future patch)
    - reuse that code for several machines (e.g. virtio-ccw and virtio-s390)
    - allow different machines to provide different defaults
    
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>
    Signed-off-by: Jens Freimann <jfrei at linux.vnet.ibm.com>
    [agraf: symbolify initial psw, adjust header file location, fix for QOM]
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 0e93cc3..13f93fb 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -25,7 +25,6 @@
 #include "boards.h"
 #include "monitor/monitor.h"
 #include "loader.h"
-#include "elf.h"
 #include "hw/virtio.h"
 #include "hw/sysbus.h"
 #include "sysemu/kvm.h"
@@ -48,17 +47,6 @@
 #define KVM_S390_VIRTIO_RESET           1
 #define KVM_S390_VIRTIO_SET_STATUS      2
 
-#define KERN_IMAGE_START                0x010000UL
-#define KERN_PARM_AREA                  0x010480UL
-#define INITRD_START                    0x800000UL
-#define INITRD_PARM_START               0x010408UL
-#define INITRD_PARM_SIZE                0x010410UL
-#define PARMFILE_START                  0x001000UL
-
-#define ZIPL_START			0x009000UL
-#define ZIPL_LOAD_ADDR			0x009000UL
-#define ZIPL_FILENAME			"s390-zipl.rom"
-
 #define MAX_BLK_DEVS                    10
 
 static VirtIOS390Bus *s390_bus;
@@ -156,15 +144,10 @@ static void s390_init(QEMUMachineInitArgs *args)
 {
     ram_addr_t my_ram_size = args->ram_size;
     const char *cpu_model = args->cpu_model;
-    const char *kernel_filename = args->kernel_filename;
-    const char *kernel_cmdline = args->kernel_cmdline;
-    const char *initrd_filename = args->initrd_filename;
     CPUS390XState *env = NULL;
+    DeviceState *dev;
     MemoryRegion *sysmem = get_system_memory();
     MemoryRegion *ram = g_new(MemoryRegion, 1);
-    ram_addr_t kernel_size = 0;
-    ram_addr_t initrd_offset;
-    ram_addr_t initrd_size = 0;
     int shift = 0;
     uint8_t *storage_keys;
     void *virtio_region;
@@ -185,6 +168,15 @@ static void s390_init(QEMUMachineInitArgs *args)
     /* get a BUS */
     s390_bus = s390_virtio_bus_init(&my_ram_size);
     s390_sclp_init();
+    dev  = qdev_create(NULL, "s390-ipl");
+    if (args->kernel_filename) {
+        qdev_prop_set_string(dev, "kernel", args->kernel_filename);
+    }
+    if (args->initrd_filename) {
+        qdev_prop_set_string(dev, "initrd", args->initrd_filename);
+    }
+    qdev_prop_set_string(dev, "cmdline", args->kernel_cmdline);
+    qdev_init_nofail(dev);
 
     /* allocate RAM */
     memory_region_init_ram(ram, "s390.ram", my_ram_size);
@@ -225,76 +217,6 @@ static void s390_init(QEMUMachineInitArgs *args)
         tmp_env->storage_keys = storage_keys;
     }
 
-    /* One CPU has to run */
-    s390_add_running_cpu(env);
-
-    if (kernel_filename) {
-
-        kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, NULL,
-                               NULL, 1, ELF_MACHINE, 0);
-        if (kernel_size == -1UL) {
-            kernel_size = load_image_targphys(kernel_filename, 0, ram_size);
-        }
-        if (kernel_size == -1UL) {
-            fprintf(stderr, "qemu: could not load kernel '%s'\n",
-                    kernel_filename);
-            exit(1);
-        }
-        /*
-         * we can not rely on the ELF entry point, since up to 3.2 this
-         * value was 0x800 (the SALIPL loader) and it wont work. For
-         * all (Linux) cases 0x10000 (KERN_IMAGE_START) should be fine.
-         */
-        env->psw.addr = KERN_IMAGE_START;
-        env->psw.mask = 0x0000000180000000ULL;
-    } else {
-        ram_addr_t bios_size = 0;
-        char *bios_filename;
-
-        /* Load zipl bootloader */
-        if (bios_name == NULL) {
-            bios_name = ZIPL_FILENAME;
-        }
-
-        bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-        bios_size = load_image_targphys(bios_filename, ZIPL_LOAD_ADDR, 4096);
-        g_free(bios_filename);
-
-        if ((long)bios_size < 0) {
-            hw_error("could not load bootloader '%s'\n", bios_name);
-        }
-
-        if (bios_size > 4096) {
-            hw_error("stage1 bootloader is > 4k\n");
-        }
-
-        env->psw.addr = ZIPL_START;
-        env->psw.mask = 0x0000000180000000ULL;
-    }
-
-    if (initrd_filename) {
-        initrd_offset = INITRD_START;
-        while (kernel_size + 0x100000 > initrd_offset) {
-            initrd_offset += 0x100000;
-        }
-        initrd_size = load_image_targphys(initrd_filename, initrd_offset,
-                                          ram_size - initrd_offset);
-        if (initrd_size == -1UL) {
-            fprintf(stderr, "qemu: could not load initrd '%s'\n",
-                    initrd_filename);
-            exit(1);
-        }
-
-        /* we have to overwrite values in the kernel image, which are "rom" */
-        stq_p(rom_ptr(INITRD_PARM_START), initrd_offset);
-        stq_p(rom_ptr(INITRD_PARM_SIZE), initrd_size);
-    }
-
-    if (rom_ptr(KERN_PARM_AREA)) {
-        /* we have to overwrite values in the kernel image, which are "rom" */
-        memcpy(rom_ptr(KERN_PARM_AREA), kernel_cmdline,
-               strlen(kernel_cmdline) + 1);
-    }
 
     /* Create VirtIO network adapters */
     for(i = 0; i < nb_nics; i++) {
diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index 096dfcd..4a5a5d8 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -4,3 +4,4 @@ obj-y := $(addprefix ../,$(obj-y))
 obj-y += sclp.o
 obj-y += event-facility.o
 obj-y += sclpquiesce.o sclpconsole.o
+obj-y += ipl.o
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
new file mode 100644
index 0000000..7cbbf99
--- /dev/null
+++ b/hw/s390x/ipl.c
@@ -0,0 +1,174 @@
+/*
+ * bootloader support
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Christian Borntraeger <borntraeger at de.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at your
+ * option) any later version.  See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "sysemu/sysemu.h"
+#include "cpu.h"
+#include "elf.h"
+#include "hw/loader.h"
+#include "hw/sysbus.h"
+
+#define KERN_IMAGE_START                0x010000UL
+#define KERN_PARM_AREA                  0x010480UL
+#define INITRD_START                    0x800000UL
+#define INITRD_PARM_START               0x010408UL
+#define INITRD_PARM_SIZE                0x010410UL
+#define PARMFILE_START                  0x001000UL
+#define ZIPL_FILENAME                   "s390-zipl.rom"
+#define ZIPL_IMAGE_START                0x009000UL
+#define IPL_PSW_MASK                    (PSW_MASK_32 | PSW_MASK_64)
+
+#define TYPE_S390_IPL "s390-ipl"
+#define S390_IPL(obj) \
+    OBJECT_CHECK(S390IPLState, (obj), TYPE_S390_IPL)
+#if 0
+#define S390_IPL_CLASS(klass) \
+    OBJECT_CLASS_CHECK(S390IPLState, (klass), TYPE_S390_IPL)
+#define S390_IPL_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(S390IPLState, (obj), TYPE_S390_IPL)
+#endif
+
+typedef struct S390IPLClass {
+    /*< private >*/
+    SysBusDeviceClass parent_class;
+    /*< public >*/
+
+    void (*parent_reset) (SysBusDevice *dev);
+} S390IPLClass;
+
+typedef struct S390IPLState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    char *kernel;
+    char *initrd;
+    char *cmdline;
+} S390IPLState;
+
+
+static void s390_ipl_cpu(uint64_t pswaddr)
+{
+    CPUS390XState *env = &S390_CPU(qemu_get_cpu(0))->env;
+    env->psw.addr = pswaddr;
+    env->psw.mask = IPL_PSW_MASK;
+    s390_add_running_cpu(env);
+}
+
+static int s390_ipl_init(SysBusDevice *dev)
+{
+    S390IPLState *ipl = S390_IPL(dev);
+    ram_addr_t kernel_size = 0;
+
+    if (!ipl->kernel) {
+        ram_addr_t bios_size = 0;
+        char *bios_filename;
+
+        /* Load zipl bootloader */
+        if (bios_name == NULL) {
+            bios_name = ZIPL_FILENAME;
+        }
+
+        bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+        bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START, 4096);
+        g_free(bios_filename);
+
+        if ((long)bios_size < 0) {
+            hw_error("could not load bootloader '%s'\n", bios_name);
+        }
+
+        if (bios_size > 4096) {
+            hw_error("stage1 bootloader is > 4k\n");
+        }
+        return 0;
+    } else {
+        kernel_size = load_elf(ipl->kernel, NULL, NULL, NULL, NULL,
+                               NULL, 1, ELF_MACHINE, 0);
+        if (kernel_size == -1UL) {
+            kernel_size = load_image_targphys(ipl->kernel, 0, ram_size);
+        }
+        if (kernel_size == -1UL) {
+            fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel);
+            return -1;
+        }
+        /* we have to overwrite values in the kernel image, which are "rom" */
+        strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline);
+    }
+    if (ipl->initrd) {
+        ram_addr_t initrd_offset, initrd_size;
+
+        initrd_offset = INITRD_START;
+        while (kernel_size + 0x100000 > initrd_offset) {
+            initrd_offset += 0x100000;
+        }
+        initrd_size = load_image_targphys(ipl->initrd, initrd_offset,
+                                          ram_size - initrd_offset);
+        if (initrd_size == -1UL) {
+            fprintf(stderr, "qemu: could not load initrd '%s'\n", ipl->initrd);
+            exit(1);
+        }
+
+        /* we have to overwrite values in the kernel image, which are "rom" */
+        stq_p(rom_ptr(INITRD_PARM_START), initrd_offset);
+        stq_p(rom_ptr(INITRD_PARM_SIZE), initrd_size);
+    }
+
+    return 0;
+}
+
+static Property s390_ipl_properties[] = {
+    DEFINE_PROP_STRING("kernel", S390IPLState, kernel),
+    DEFINE_PROP_STRING("initrd", S390IPLState, initrd),
+    DEFINE_PROP_STRING("cmdline", S390IPLState, cmdline),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void s390_ipl_reset(DeviceState *dev)
+{
+    S390IPLState *ipl = S390_IPL(dev);
+
+    if (ipl->kernel) {
+        /*
+         * we can not rely on the ELF entry point, since up to 3.2 this
+         * value was 0x800 (the SALIPL loader) and it wont work. For
+         * all (Linux) cases 0x10000 (KERN_IMAGE_START) should be fine.
+         */
+        return s390_ipl_cpu(KERN_IMAGE_START);
+    } else {
+        return s390_ipl_cpu(ZIPL_IMAGE_START);
+    }
+}
+
+static void s390_ipl_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = s390_ipl_init;
+    dc->props = s390_ipl_properties;
+    dc->reset = s390_ipl_reset;
+    dc->no_user = 1;
+}
+
+static TypeInfo s390_ipl_info = {
+    .class_init = s390_ipl_class_init,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .name  = "s390-ipl",
+    .instance_size  = sizeof(S390IPLState),
+};
+
+static void s390_ipl_register_types(void)
+{
+    type_register_static(&s390_ipl_info);
+}
+
+type_init(s390_ipl_register_types)
commit ccb084d3f0ec405afc6c878ace40f1ccf1e44027
Author: Christian Borntraeger <borntraeger at de.ibm.com>
Date:   Mon Nov 12 01:44:10 2012 +0000

    s390: new contributions GPLv2 or later
    
    IBMs s390 contributions were meant to to be gplv2 or later (since
    we were contributing to qemu). Several of the s390 specific files
    link to gpl code anyway, so lets clarify the licence statement for
    new contributions for those files that we have touched multiple
    times or will likely touch again.
    
    This patch does not touch files that mostly deal with tcg.
    
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index bc3fab2..1fa3ad3 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -13,7 +13,10 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
+ * Contributions after 2012-10-29 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ *
+ * You should have received a copy of the GNU (Lesser) General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 #ifndef CPU_S390X_H
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 6ec5e6d..5785f7d 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -2,6 +2,7 @@
  * QEMU S390x KVM implementation
  *
  * Copyright (c) 2009 Alexander Graf <agraf at suse.de>
+ * Copyright IBM Corp. 2012
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -13,7 +14,10 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public
+ * Contributions after 2012-10-29 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ *
+ * You should have received a copy of the GNU (Lesser) General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
commit 5b95b8b9c1b0cd30a31dbeffdaec35134248b6e9
Author: Alexander Graf <agraf at suse.de>
Date:   Thu Jan 17 11:54:38 2013 +0100

    PPC: KVM: Add support for EPR with KVM
    
    This patch links KVM EPR support to the existing TCG support we have now.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/ppc.c b/hw/ppc.c
index 1fce604..c52e22f 100644
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -435,7 +435,13 @@ void ppce500_set_mpic_proxy(bool enabled)
     CPUPPCState *env;
 
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        PowerPCCPU *cpu = ppc_env_get_cpu(env);
+        CPUState *cs = CPU(cpu);
+
         env->mpic_proxy = enabled;
+        if (kvm_enabled()) {
+            kvmppc_set_mpic_proxy(POWERPC_CPU(cs), enabled);
+        }
     }
 }
 
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 19e9f25..2f4f068 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -846,6 +846,11 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
         ret = 0;
         break;
 #endif
+    case KVM_EXIT_EPR:
+        dprintf("handle epr\n");
+        run->epr.epr = ldl_phys(env->mpic_iack);
+        ret = 0;
+        break;
     default:
         fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
         ret = -1;
@@ -1057,6 +1062,22 @@ void kvmppc_set_papr(PowerPCCPU *cpu)
     }
 }
 
+void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy)
+{
+    CPUPPCState *env = &cpu->env;
+    CPUState *cs = CPU(cpu);
+    struct kvm_enable_cap cap = {};
+    int ret;
+
+    cap.cap = KVM_CAP_PPC_EPR;
+    cap.args[0] = mpic_proxy;
+    ret = kvm_vcpu_ioctl(cs, KVM_ENABLE_CAP, &cap);
+
+    if (ret && mpic_proxy) {
+        cpu_abort(env, "This KVM version does not support EPR\n");
+    }
+}
+
 int kvmppc_smt_threads(void)
 {
     return cap_ppc_smt ? cap_ppc_smt : 1;
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 3db21fc..c30b006 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -25,6 +25,7 @@ int kvmppc_get_hasidle(CPUPPCState *env);
 int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len);
 int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level);
 void kvmppc_set_papr(PowerPCCPU *cpu);
+void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy);
 int kvmppc_smt_threads(void);
 #ifndef CONFIG_USER_ONLY
 off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem);
@@ -81,6 +82,10 @@ static inline void kvmppc_set_papr(PowerPCCPU *cpu)
 {
 }
 
+static inline void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy)
+{
+}
+
 static inline int kvmppc_smt_threads(void)
 {
     return 1;
commit e49798b1bd7657722080126bfd5e787efdb3bc23
Author: Alexander Graf <agraf at suse.de>
Date:   Thu Jan 17 11:32:21 2013 +0100

    openpic: export e500 epr enable into a ppc.c function
    
    Enabling and disabling the EPR capability (mpic_proxy) is a system
    wide operation. As such, it belongs into the ppc.c file, since that's
    where PPC specific machine wide logic happens.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/openpic.c b/hw/openpic.c
index bcafe0a..cc8ec35 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -40,6 +40,7 @@
 #include "sysbus.h"
 #include "pci/msi.h"
 #include "qemu/bitops.h"
+#include "ppc.h"
 
 //#define DEBUG_OPENPIC
 
@@ -646,8 +647,7 @@ static inline void write_IRQreg_ivpr(OpenPICState *opp, int n_IRQ, uint32_t val)
 
 static void openpic_gcr_write(OpenPICState *opp, uint64_t val)
 {
-    CPUArchState *env;
-    int mpic_proxy = 0;
+    bool mpic_proxy = false;
 
     if (val & GCR_RESET) {
         openpic_reset(&opp->busdev.qdev);
@@ -659,11 +659,10 @@ static void openpic_gcr_write(OpenPICState *opp, uint64_t val)
 
     /* Set external proxy mode */
     if ((val & opp->mpic_mode_mask) == GCR_MODE_PROXY) {
-        mpic_proxy = 1;
-    }
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        env->mpic_proxy = mpic_proxy;
+        mpic_proxy = true;
     }
+
+    ppce500_set_mpic_proxy(mpic_proxy);
 }
 
 static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,
diff --git a/hw/ppc.c b/hw/ppc.c
index e473f9e..1fce604 100644
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -428,6 +428,17 @@ void ppce500_irq_init(CPUPPCState *env)
     env->irq_inputs = (void **)qemu_allocate_irqs(&ppce500_set_irq,
                                                   cpu, PPCE500_INPUT_NB);
 }
+
+/* Enable or Disable the E500 EPR capability */
+void ppce500_set_mpic_proxy(bool enabled)
+{
+    CPUPPCState *env;
+
+    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        env->mpic_proxy = enabled;
+    }
+}
+
 /*****************************************************************************/
 /* PowerPC time base and decrementer emulation */
 
diff --git a/hw/ppc.h b/hw/ppc.h
index e73ae83..ee0cd16 100644
--- a/hw/ppc.h
+++ b/hw/ppc.h
@@ -73,6 +73,8 @@ void ppc6xx_irq_init (CPUPPCState *env);
 void ppc970_irq_init (CPUPPCState *env);
 void ppcPOWER7_irq_init (CPUPPCState *env);
 
+void ppce500_set_mpic_proxy(bool enabled);
+
 /* PPC machines for OpenBIOS */
 enum {
     ARCH_PREP = 0,
commit d3dccee187ffeacec1a38ed288c112ffa0e3b513
Author: Alexander Graf <agraf at suse.de>
Date:   Fri Jan 18 00:06:26 2013 +0100

    Update Linux kernel headers
    
    Based on kvm.git a843fac (next) plus dfdebc24 (master).
    
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
index 2fba8a6..16064d0 100644
--- a/linux-headers/asm-powerpc/kvm.h
+++ b/linux-headers/asm-powerpc/kvm.h
@@ -114,7 +114,10 @@ struct kvm_regs {
 /* Embedded Floating Point (SPE) -- IVOR32-34 if KVM_SREGS_E_IVOR */
 #define KVM_SREGS_E_SPE			(1 << 9)
 
-/* External Proxy (EXP) -- EPR */
+/*
+ * DEPRECATED! USE ONE_REG FOR THIS ONE!
+ * External Proxy (EXP) -- EPR
+ */
 #define KVM_SREGS_EXP			(1 << 10)
 
 /* External PID (E.PD) -- EPSC/EPLC */
@@ -412,5 +415,6 @@ struct kvm_get_htab_header {
 #define KVM_REG_PPC_VPA_DTL	(KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x84)
 
 #define KVM_REG_PPC_EPCR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85)
+#define KVM_REG_PPC_EPR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x86)
 
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index bfdbf4d..5af9357 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -168,6 +168,8 @@ struct kvm_pit_config {
 #define KVM_EXIT_PAPR_HCALL	  19
 #define KVM_EXIT_S390_UCONTROL	  20
 #define KVM_EXIT_WATCHDOG         21
+#define KVM_EXIT_S390_TSCH        22
+#define KVM_EXIT_EPR              23
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 /* Emulate instruction failed. */
@@ -285,6 +287,19 @@ struct kvm_run {
 			__u64 ret;
 			__u64 args[9];
 		} papr_hcall;
+		/* KVM_EXIT_S390_TSCH */
+		struct {
+			__u16 subchannel_id;
+			__u16 subchannel_nr;
+			__u32 io_int_parm;
+			__u32 io_int_word;
+			__u32 ipb;
+			__u8 dequeued;
+		} s390_tsch;
+		/* KVM_EXIT_EPR */
+		struct {
+			__u32 epr;
+		} epr;
 		/* Fix the size of the union. */
 		char padding[256];
 	};
@@ -397,10 +412,20 @@ struct kvm_s390_psw {
 #define KVM_S390_PROGRAM_INT		0xfffe0001u
 #define KVM_S390_SIGP_SET_PREFIX	0xfffe0002u
 #define KVM_S390_RESTART		0xfffe0003u
+#define KVM_S390_MCHK			0xfffe1000u
 #define KVM_S390_INT_VIRTIO		0xffff2603u
 #define KVM_S390_INT_SERVICE		0xffff2401u
 #define KVM_S390_INT_EMERGENCY		0xffff1201u
 #define KVM_S390_INT_EXTERNAL_CALL	0xffff1202u
+/* Anything below 0xfffe0000u is taken by INT_IO */
+#define KVM_S390_INT_IO(ai,cssid,ssid,schid)   \
+	(((schid)) |			       \
+	 ((ssid) << 16) |		       \
+	 ((cssid) << 18) |		       \
+	 ((ai) << 26))
+#define KVM_S390_INT_IO_MIN		0x00000000u
+#define KVM_S390_INT_IO_MAX		0xfffdffffu
+
 
 struct kvm_s390_interrupt {
 	__u32 type;
@@ -635,6 +660,8 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_IRQFD_RESAMPLE 82
 #define KVM_CAP_PPC_BOOKE_WATCHDOG 83
 #define KVM_CAP_PPC_HTAB_FD 84
+#define KVM_CAP_S390_CSS_SUPPORT 85
+#define KVM_CAP_PPC_EPR 86
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
commit b8dec1443ef6c52e72594c5a861a5d2fd7f05d80
Author: Alexander Graf <agraf at suse.de>
Date:   Thu Jan 17 11:19:28 2013 +0100

    PPC: e500: Change in-memory order of load blobs
    
    Today, we load
    
      <kernel> <initrd> <dtb>
    
    into memory in that order. However, Linux has a bug where it can only
    handle the dtb if it's within the first 64MB of where <kernel> starts.
    
    So instead, let's change the order to
    
      <kernel> <dtb> <initrd>
    
    making Linux happy.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index e5564ce..c36821a 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -41,6 +41,7 @@
 #define UIMAGE_LOAD_BASE           0
 #define DTC_LOAD_PAD               0x1800000
 #define DTC_PAD_MASK               0xFFFFF
+#define DTB_MAX_SIZE               (8 * 1024 * 1024)
 #define INITRD_LOAD_PAD            0x2000000
 #define INITRD_PAD_MASK            0xFFFFFF
 
@@ -629,6 +630,10 @@ void ppce500_init(PPCE500Params *params)
         }
 
         cur_base = loadaddr + kernel_size;
+
+        /* Reserve space for dtb */
+        dt_base = (cur_base + DTC_LOAD_PAD) & ~DTC_PAD_MASK;
+        cur_base += DTB_MAX_SIZE;
     }
 
     /* Load initrd. */
@@ -651,13 +656,13 @@ void ppce500_init(PPCE500Params *params)
         struct boot_info *boot_info;
         int dt_size;
 
-        dt_base = (cur_base + DTC_LOAD_PAD) & ~DTC_PAD_MASK;
         dt_size = ppce500_load_device_tree(env, params, dt_base, initrd_base,
                                            initrd_size);
         if (dt_size < 0) {
             fprintf(stderr, "couldn't load device tree\n");
             exit(1);
         }
+        assert(dt_size < DTB_MAX_SIZE);
 
         boot_info = env->load_info;
         boot_info->entry = entry;
commit 746a870b3c44a6c5734691fec013c78520d55f15
Author: Alexander Graf <agraf at suse.de>
Date:   Wed Jan 16 01:43:43 2013 +0100

    PPC: Provide zero SVR for -cpu e500mc and e5500
    
    Even though our -cpu types for e500mc and e5500 are no real CPUs that
    actually have version registers, a guest might still want to access
    said version register and that has to succeed for a guest to be happy.
    
    So let's expose a zero SVR value on E500_SVR SPR reads.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 3f199c4..2d78529 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8633,9 +8633,9 @@ static const ppc_def_t ppc_defs[] = {
     POWERPC_DEF("e500v2_v22",    CPU_POWERPC_e500v2_v22,             e500v2),
     /* PowerPC e500v2 v3.0 core                                              */
     POWERPC_DEF("e500v2_v30",    CPU_POWERPC_e500v2_v30,             e500v2),
-    POWERPC_DEF("e500mc",        CPU_POWERPC_e500mc,                 e500mc),
+    POWERPC_DEF_SVR("e500mc", CPU_POWERPC_e500mc, POWERPC_SVR_E500,  e500mc),
 #ifdef TARGET_PPC64
-    POWERPC_DEF("e5500",         CPU_POWERPC_e5500,                  e5500),
+    POWERPC_DEF_SVR("e5500",    CPU_POWERPC_e5500, POWERPC_SVR_E500, e5500),
 #endif
     /* PowerPC e500 microcontrollers                                         */
     /* MPC8533                                                               */
commit 528e536ea2fd3bfe8412e39a5623e80b254f3ae0
Author: Alexander Graf <agraf at suse.de>
Date:   Mon Jan 14 20:24:16 2013 +0100

    PPC: E500: Calculate loading blob offsets properly
    
    We have 3 blobs we need to load when booting the system:
    
      - kernel
      - initrd
      - dtb
    
    We place them in physical memory in that order. At least we should.
    This patch fixes the location calculation up to take any module into
    account, fixing the dtb offset along the way.
    
    Reported-by: Stuart Yoder <stuart.yoder at freescale.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 7b3e2e6..e5564ce 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -463,7 +463,8 @@ void ppce500_init(PPCE500Params *params)
     target_long kernel_size=0;
     target_ulong dt_base = 0;
     target_ulong initrd_base = 0;
-    target_long initrd_size=0;
+    target_long initrd_size = 0;
+    target_ulong cur_base = 0;
     int i = 0, j, k;
     unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
     qemu_irq **irqs, *mpic;
@@ -626,12 +627,13 @@ void ppce500_init(PPCE500Params *params)
                     params->kernel_filename);
             exit(1);
         }
+
+        cur_base = loadaddr + kernel_size;
     }
 
     /* Load initrd. */
     if (params->initrd_filename) {
-        initrd_base = (loadaddr + kernel_size + INITRD_LOAD_PAD) &
-            ~INITRD_PAD_MASK;
+        initrd_base = (cur_base + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK;
         initrd_size = load_image_targphys(params->initrd_filename, initrd_base,
                                           ram_size - initrd_base);
 
@@ -640,6 +642,8 @@ void ppce500_init(PPCE500Params *params)
                     params->initrd_filename);
             exit(1);
         }
+
+        cur_base = initrd_base + initrd_size;
     }
 
     /* If we're loading a kernel directly, we must load the device tree too. */
@@ -647,7 +651,7 @@ void ppce500_init(PPCE500Params *params)
         struct boot_info *boot_info;
         int dt_size;
 
-        dt_base = (loadaddr + kernel_size + DTC_LOAD_PAD) & ~DTC_PAD_MASK;
+        dt_base = (cur_base + DTC_LOAD_PAD) & ~DTC_PAD_MASK;
         dt_size = ppce500_load_device_tree(env, params, dt_base, initrd_base,
                                            initrd_size);
         if (dt_size < 0) {
commit 86e56a885aa5051c87906dfcd060c59f0af22309
Author: Alexander Graf <agraf at suse.de>
Date:   Mon Jan 7 20:17:24 2013 +0100

    openpic: set mixed mode as supported
    
    The Raven MPIC implementation supports the "Mixed" mode to work with
    an i8259. While we don't implement mixed mode, we should mark it as
    a supported mode in the mode bitmap.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/openpic.c b/hw/openpic.c
index c986b5d..bcafe0a 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -1470,6 +1470,7 @@ static int openpic_init(SysBusDevice *dev)
         opp->irq_ipi0 = RAVEN_IPI_IRQ;
         opp->irq_tim0 = RAVEN_TMR_IRQ;
         opp->brr1 = -1;
+        opp->mpic_mode_mask = GCR_MODE_MIXED;
         list = list_le;
         /* Don't map MSI region */
         list[2].map = false;
commit 1ac3d71302d9d49427dd068af7eccdd4de128522
Author: Alexander Graf <agraf at suse.de>
Date:   Mon Jan 7 20:15:28 2013 +0100

    openpic: unify gcr mode mask updates
    
    The mode mask already masks out bits we don't care about, so the
    actual handling code can stay intact regardless.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/openpic.c b/hw/openpic.c
index 085c954..c986b5d 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -646,22 +646,23 @@ static inline void write_IRQreg_ivpr(OpenPICState *opp, int n_IRQ, uint32_t val)
 
 static void openpic_gcr_write(OpenPICState *opp, uint64_t val)
 {
+    CPUArchState *env;
+    int mpic_proxy = 0;
+
     if (val & GCR_RESET) {
         openpic_reset(&opp->busdev.qdev);
-    } else if (opp->mpic_mode_mask) {
-        CPUArchState *env;
-        int mpic_proxy = 0;
+        return;
+    }
 
-        opp->gcr &= ~opp->mpic_mode_mask;
-        opp->gcr |= val & opp->mpic_mode_mask;
+    opp->gcr &= ~opp->mpic_mode_mask;
+    opp->gcr |= val & opp->mpic_mode_mask;
 
-        /* Set external proxy mode */
-        if ((val & opp->mpic_mode_mask) == GCR_MODE_PROXY) {
-            mpic_proxy = 1;
-        }
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
-            env->mpic_proxy = mpic_proxy;
-        }
+    /* Set external proxy mode */
+    if ((val & opp->mpic_mode_mask) == GCR_MODE_PROXY) {
+        mpic_proxy = 1;
+    }
+    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        env->mpic_proxy = mpic_proxy;
     }
 }
 
commit 7f11573b9fe6c03a9ad4cd1bbaa761e564d44fce
Author: Alexander Graf <agraf at suse.de>
Date:   Mon Jan 7 20:13:52 2013 +0100

    openpic: move gcr write into a function
    
    The GCR register contains too much functionality to be covered inside
    of the register switch statement. Move it out into a separate function.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/openpic.c b/hw/openpic.c
index f6cc07b..085c954 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -644,6 +644,27 @@ static inline void write_IRQreg_ivpr(OpenPICState *opp, int n_IRQ, uint32_t val)
             opp->src[n_IRQ].ivpr);
 }
 
+static void openpic_gcr_write(OpenPICState *opp, uint64_t val)
+{
+    if (val & GCR_RESET) {
+        openpic_reset(&opp->busdev.qdev);
+    } else if (opp->mpic_mode_mask) {
+        CPUArchState *env;
+        int mpic_proxy = 0;
+
+        opp->gcr &= ~opp->mpic_mode_mask;
+        opp->gcr |= val & opp->mpic_mode_mask;
+
+        /* Set external proxy mode */
+        if ((val & opp->mpic_mode_mask) == GCR_MODE_PROXY) {
+            mpic_proxy = 1;
+        }
+        for (env = first_cpu; env != NULL; env = env->next_cpu) {
+            env->mpic_proxy = mpic_proxy;
+        }
+    }
+}
+
 static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,
                               unsigned len)
 {
@@ -672,23 +693,7 @@ static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,
     case 0x1000: /* FRR */
         break;
     case 0x1020: /* GCR */
-        if (val & GCR_RESET) {
-            openpic_reset(&opp->busdev.qdev);
-        } else if (opp->mpic_mode_mask) {
-            CPUArchState *env;
-            int mpic_proxy = 0;
-
-            opp->gcr &= ~opp->mpic_mode_mask;
-            opp->gcr |= val & opp->mpic_mode_mask;
-
-            /* Set external proxy mode */
-            if ((val & opp->mpic_mode_mask) == GCR_MODE_PROXY) {
-                mpic_proxy = 1;
-            }
-            for (env = first_cpu; env != NULL; env = env->next_cpu) {
-                env->mpic_proxy = mpic_proxy;
-            }
-        }
+        openpic_gcr_write(opp, val);
         break;
     case 0x1080: /* VIR */
         break;
commit cf139388ad5b39228793f34eea99e0ea9a2924aa
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Jan 17 16:46:54 2013 +0100

    dataplane: support viostor virtio-pci status bit setting
    
    The viostor virtio-blk driver for Windows does not use the
    VIRTIO_CONFIG_S_DRIVER bit.  It only sets the VIRTIO_CONFIG_S_DRIVER_OK
    bit.
    
    The viostor driver refreshes the virtio-pci status byte sometimes while
    the guest is running.  We misinterpret 0x4 (VIRTIO_CONFIG_S_DRIVER_OK)
    as an indication that virtio-blk-data-plane should be stopped since 0x2
    (VIRTIO_CONFIG_S_DRIVER) is missing.  The result is that the device
    becomes unresponsive.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index df57b35..34913ee 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -571,7 +571,8 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
     uint32_t features;
 
 #ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
-    if (s->dataplane && !(status & VIRTIO_CONFIG_S_DRIVER)) {
+    if (s->dataplane && !(status & (VIRTIO_CONFIG_S_DRIVER |
+                                    VIRTIO_CONFIG_S_DRIVER_OK))) {
         virtio_blk_data_plane_stop(s->dataplane);
     }
 #endif
commit cd7fdfe59f4f965665dcd9868fe3764f5256d6aa
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Tue Jan 15 17:19:38 2013 +0100

    dataplane: avoid reentrancy during virtio_blk_data_plane_stop()
    
    When dataplane is stopping, the s->vdev->binding->set_host_notifier(...,
    false) call can invoke the virtqueue handler if an ioeventfd
    notification is pending.  This causes hw/virtio-blk.c to invoke
    virtio_blk_data_plane_start() before virtio_blk_data_plane_stop()
    returns!
    
    The result is that we try to restart dataplane while trying to stop it
    and the following assertion is raised:
    
      msix_set_mask_notifier: Assertion `!dev->msix_mask_notifier' failed.
    
    Although the code was intended to prevent this scenario, the s->started
    boolean isn't enough.  Add s->stopping so that we can postpone clearing
    s->started until we've completely stopped dataplane.
    
    This way, virtqueue handler calls during virtio_blk_data_plane_stop()
    are ignored.  When dataplane is legitimately started again later we
    already self-kick ourselves to resume processing.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/dataplane/virtio-blk.c b/hw/dataplane/virtio-blk.c
index 4b26faa..3f2da22 100644
--- a/hw/dataplane/virtio-blk.c
+++ b/hw/dataplane/virtio-blk.c
@@ -40,6 +40,7 @@ typedef struct {
 
 struct VirtIOBlockDataPlane {
     bool started;
+    bool stopping;
     QEMUBH *start_bh;
     QemuThread thread;
 
@@ -357,7 +358,7 @@ static void *data_plane_thread(void *opaque)
 
     do {
         event_poll(&s->event_poll);
-    } while (s->started || s->num_reqs > 0);
+    } while (!s->stopping || s->num_reqs > 0);
     return NULL;
 }
 
@@ -486,10 +487,10 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
 
 void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
 {
-    if (!s->started) {
+    if (!s->started || s->stopping) {
         return;
     }
-    s->started = false;
+    s->stopping = true;
     trace_virtio_blk_data_plane_stop(s);
 
     /* Stop thread or cancel pending thread creation BH */
@@ -511,4 +512,6 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
     s->vdev->binding->set_guest_notifiers(s->vdev->binding_opaque, 1, false);
 
     vring_teardown(&s->vring);
+    s->started = false;
+    s->stopping = false;
 }
commit 3249dbe661ba6ef108ecde97c54b4a4104d719c3
Author: Michael Tokarev <mjt at tls.msk.ru>
Date:   Thu Jan 17 18:47:52 2013 +0400

    win32-aio: use iov utility functions instead of open-coding them
    
    We have iov_from_buf() and iov_to_buf(), use them instead of
    open-coding these in block/win32-aio.c
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/win32-aio.c b/block/win32-aio.c
index b9236ea..5d0fbbf 100644
--- a/block/win32-aio.c
+++ b/block/win32-aio.c
@@ -29,6 +29,7 @@
 #include "block/aio.h"
 #include "raw-aio.h"
 #include "qemu/event_notifier.h"
+#include "qemu/iov.h"
 #include <windows.h>
 #include <winioctl.h>
 
@@ -80,13 +81,7 @@ static void win32_aio_process_completion(QEMUWin32AIOState *s,
     if (!waiocb->is_linear) {
         if (ret == 0 && waiocb->is_read) {
             QEMUIOVector *qiov = waiocb->qiov;
-            char *p = waiocb->buf;
-            int i;
-
-            for (i = 0; i < qiov->niov; ++i) {
-                memcpy(qiov->iov[i].iov_base, p, qiov->iov[i].iov_len);
-                p += qiov->iov[i].iov_len;
-            }
+            iov_from_buf(qiov->iov, qiov->niov, 0, waiocb->buf, qiov->size);
         }
         qemu_vfree(waiocb->buf);
     }
@@ -153,13 +148,7 @@ BlockDriverAIOCB *win32_aio_submit(BlockDriverState *bs,
     if (qiov->niov > 1) {
         waiocb->buf = qemu_blockalign(bs, qiov->size);
         if (type & QEMU_AIO_WRITE) {
-            char *p = waiocb->buf;
-            int i;
-
-            for (i = 0; i < qiov->niov; ++i) {
-                memcpy(p, qiov->iov[i].iov_base, qiov->iov[i].iov_len);
-                p += qiov->iov[i].iov_len;
-            }
+            iov_to_buf(qiov->iov, qiov->niov, 0, waiocb->buf, qiov->size);
         }
         waiocb->is_linear = false;
     } else {
commit ddc01bf16e9f04b3e72c1b946b0b8efeb7a545d2
Merge: e387f99 84c4461
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Thu Jan 17 13:09:57 2013 -0600

    Merge remote-tracking branch 'luiz/queue/qmp' into staging
    
    # By Wenchao Xia
    # Via Luiz Capitulino
    * luiz/queue/qmp:
      HMP: add sub command table to info
      HMP: move define of mon_cmds
      HMP: add infrastructure for sub command
      HMP: delete info handler
      HMP: add QDict to info callback handler

commit e387f99ebc5753ebb5b7602d86e44d064873f83c
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Tue Jan 15 19:42:38 2013 +0200

    virtio-pci: fix irqfd cleanup argument order
    
    Order of arguments of kvm_virtio_pci_irqfd_release
    got mixed up in all calls.
    As a result users see assertions during cleanup.
    
    Reported-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Tested-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Tested-by: Wanlong Gao <gaowanlong at cn.fujitsu.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 0934246..212acd8 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -576,7 +576,7 @@ undo:
             continue;
         }
         if (proxy->vdev->guest_notifier_mask) {
-            kvm_virtio_pci_irqfd_release(proxy, vector, queue_no);
+            kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
         }
         kvm_virtio_pci_vq_vector_release(proxy, vector);
     }
@@ -602,7 +602,7 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
          * Otherwise, it was cleaned when masked in the frontend.
          */
         if (proxy->vdev->guest_notifier_mask) {
-            kvm_virtio_pci_irqfd_release(proxy, vector, queue_no);
+            kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
         }
         kvm_virtio_pci_vq_vector_release(proxy, vector);
     }
@@ -651,7 +651,7 @@ static void kvm_virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
     if (proxy->vdev->guest_notifier_mask) {
         proxy->vdev->guest_notifier_mask(proxy->vdev, queue_no, true);
     } else {
-        kvm_virtio_pci_irqfd_release(proxy, vector, queue_no);
+        kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
     }
 }
 
commit 782beb5239c6306b166744e03478a75afb649811
Author: Andreas Färber <afaerber at suse.de>
Date:   Thu Jan 17 08:31:50 2013 +0100

    qom: Extend documentation on QOM method concepts
    
    Add a documentation section "Methods" and discuss among others how to
    handle overriding virtual methods.
    
    Clarify DeviceClass::realize documentation and refer to the above.
    
    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-core.h b/hw/qdev-core.h
index 3d75ae2..731aadd 100644
--- a/hw/qdev-core.h
+++ b/hw/qdev-core.h
@@ -60,14 +60,20 @@ struct VMStateDescription;
  * 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.
+ * to call the parent type's implementation if keeping their functionality
+ * is desired. Refer to QOM documentation for further discussion and examples.
+ *
+ * <note>
+ *   <para>
  * 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.
+ * For other types consult the documentation and implementation of the
+ * respective parent types.
+ *   </para>
+ * </note>
  */
 typedef struct DeviceClass {
     /*< private >*/
diff --git a/include/qom/object.h b/include/qom/object.h
index 1ef2f0e..8e16ea8 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -147,9 +147,9 @@ typedef struct InterfaceInfo InterfaceInfo;
  *   </programlisting>
  * </example>
  *
- * Introducing new virtual functions requires a class to define its own
- * struct and to add a .class_size member to the TypeInfo.  Each function
- * will also have a wrapper to call it easily:
+ * Introducing new virtual methods requires a class to define its own
+ * struct and to add a .class_size member to the #TypeInfo.  Each method
+ * will also have a wrapper function to call it easily:
  *
  * <example>
  *   <title>Defining an abstract class</title>
@@ -186,6 +186,104 @@ typedef struct InterfaceInfo InterfaceInfo;
  * similar to normal types except for the fact that are only defined by
  * their classes and never carry any state.  You can dynamically cast an object
  * to one of its #Interface types and vice versa.
+ *
+ * # Methods #
+ *
+ * A <emphasis>method</emphasis> is a function within the namespace scope of
+ * a class. It usually operates on the object instance by passing it as a
+ * strongly-typed first argument.
+ * If it does not operate on an object instance, it is dubbed
+ * <emphasis>class method</emphasis>.
+ *
+ * Methods cannot be overloaded. That is, the #ObjectClass and method name
+ * uniquely identity the function to be called; the signature does not vary
+ * except for trailing varargs.
+ *
+ * Methods are always <emphasis>virtual</emphasis>. Overriding a method in
+ * #TypeInfo.class_init of a subclass leads to any user of the class obtained
+ * via OBJECT_GET_CLASS() accessing the overridden function.
+ * The original function is not automatically invoked. It is the responsability
+ * of the overriding class to determine whether and when to invoke the method
+ * being overridden.
+ *
+ * To invoke the method being overridden, the preferred solution is to store
+ * the original value in the overriding class before overriding the method.
+ * This corresponds to |[ {super,base}.method(...) ]| in Java and C#
+ * respectively; this frees the overriding class from hardcoding its parent
+ * class, which someone might choose to change at some point.
+ *
+ * <example>
+ *   <title>Overriding a virtual method</title>
+ *   <programlisting>
+ * typedef struct MyState MyState;
+ *
+ * typedef void (*MyDoSomething)(MyState *obj);
+ *
+ * typedef struct MyClass {
+ *     ObjectClass parent_class;
+ *
+ *     MyDoSomething do_something;
+ * } MyClass;
+ *
+ * static void my_do_something(MyState *obj)
+ * {
+ *     // do something
+ * }
+ *
+ * static void my_class_init(ObjectClass *oc, void *data)
+ * {
+ *     MyClass *mc = MY_CLASS(oc);
+ *
+ *     mc->do_something = my_do_something;
+ * }
+ *
+ * static const TypeInfo my_type_info = {
+ *     .name = TYPE_MY,
+ *     .parent = TYPE_OBJECT,
+ *     .instance_size = sizeof(MyState),
+ *     .class_size = sizeof(MyClass),
+ *     .class_init = my_class_init,
+ * };
+ *
+ * typedef struct DerivedClass {
+ *     MyClass parent_class;
+ *
+ *     MyDoSomething parent_do_something;
+ * } MyClass;
+ *
+ * static void derived_do_something(MyState *obj)
+ * {
+ *     DerivedClass *dc = DERIVED_GET_CLASS(obj);
+ *
+ *     // do something here
+ *     dc->parent_do_something(obj);
+ *     // do something else here
+ * }
+ *
+ * static void derived_class_init(ObjectClass *oc, void *data)
+ * {
+ *     MyClass *mc = MY_CLASS(oc);
+ *     DerivedClass *dc = DERIVED_CLASS(oc);
+ *
+ *     dc->parent_do_something = mc->do_something;
+ *     mc->do_something = derived_do_something;
+ * }
+ *
+ * static const TypeInfo derived_type_info = {
+ *     .name = TYPE_DERIVED,
+ *     .parent = TYPE_MY,
+ *     .class_size = sizeof(DerivedClass),
+ *     .class_init = my_class_init,
+ * };
+ *   </programlisting>
+ * </example>
+ *
+ * Alternatively, object_class_by_name() can be used to obtain the class and
+ * its non-overridden methods for a specific type. This would correspond to
+ * |[ MyClass::method(...) ]| in C++.
+ *
+ * The first example of such a QOM method was #CPUClass.reset,
+ * another example is #DeviceClass.realize.
  */
 
 
commit 781c0c3321d2bda9a9d7ffe9bf51560f0987b5a0
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Tue Jan 15 08:47:26 2013 +0100

    Makefile: drop recursive libcacard clean
    
    Commit eb8eb53e5846a957cf333f2e1ec8cb6e0c04 ("libcacard: rewrite
    Makefile in non-recursive style") refactored libcacard/Makefile so it
    can be included by the top-level Makefile.
    
    The top-level clean target still loops over subdirectories, including
    libcacard/, to invoke recursive clean.  Remove libcacard from the
    recursive clean since its files are already included at the top level.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/Makefile b/Makefile
index cfa2fa6..73adf42 100644
--- a/Makefile
+++ b/Makefile
@@ -227,7 +227,7 @@ clean:
 	rm -rf qapi-generated
 	rm -rf qga/qapi-generated
 	$(MAKE) -C tests/tcg clean
-	for d in $(ALL_SUBDIRS) libcacard; do \
+	for d in $(ALL_SUBDIRS); do \
 	if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
 	rm -f $$d/qemu-options.def; \
         done
commit 84c44613f9ad8d13e0d2dbee767051527072dc12
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Mon Jan 14 14:06:29 2013 +0800

    HMP: add sub command table to info
    
      Now info command takes a table of sub info commands,
    and changed do_info() to do_info_help() to do help funtion
    only.
     Note that now "info <unknown-topic>" returns error instead
    of list of info topics.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 67569ef..0934b9b 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1521,7 +1521,8 @@ ETEXI
         .args_type  = "item:s?",
         .params     = "[subcommand]",
         .help       = "show various information about the system state",
-        .mhandler.cmd = do_info,
+        .mhandler.cmd = do_info_help,
+        .sub_table = info_cmds,
     },
 
 STEXI
diff --git a/monitor.c b/monitor.c
index ef1b7ac..20bd19b 100644
--- a/monitor.c
+++ b/monitor.c
@@ -811,28 +811,8 @@ static void user_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd,
     }
 }
 
-static void do_info(Monitor *mon, const QDict *qdict)
+static void do_info_help(Monitor *mon, const QDict *qdict)
 {
-    const mon_cmd_t *cmd;
-    const char *item = qdict_get_try_str(qdict, "item");
-
-    if (!item) {
-        goto help;
-    }
-
-    for (cmd = info_cmds; cmd->name != NULL; cmd++) {
-        if (compare_cmd(item, cmd->name))
-            break;
-    }
-
-    if (cmd->name == NULL) {
-        goto help;
-    }
-
-    cmd->mhandler.cmd(mon, NULL);
-    return;
-
-help:
     help_cmd(mon, "info");
 }
 
commit a13ced59a4f305e37bd89f27f2b18f915889cad1
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Mon Jan 14 14:06:28 2013 +0800

    HMP: move define of mon_cmds
    
      Because mon_cmds may use info_cmds, so adjust the declare sequence
    of them.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index a77dd3b..ef1b7ac 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2433,12 +2433,6 @@ int monitor_handle_fd_param(Monitor *mon, const char *fdname)
     return fd;
 }
 
-/* mon_cmds and info_cmds would be sorted at runtime */
-static mon_cmd_t mon_cmds[] = {
-#include "hmp-commands.h"
-    { NULL, NULL, },
-};
-
 /* Please update hmp-commands.hx when adding or changing commands */
 static mon_cmd_t info_cmds[] = {
     {
@@ -2752,6 +2746,12 @@ static mon_cmd_t info_cmds[] = {
     },
 };
 
+/* mon_cmds and info_cmds would be sorted at runtime */
+static mon_cmd_t mon_cmds[] = {
+#include "hmp-commands.h"
+    { NULL, NULL, },
+};
+
 static const mon_cmd_t qmp_cmds[] = {
 #include "qmp-commands-old.h"
     { /* NULL */ },
commit 5f3d335fbdaccc5044bdfe0c6aefb865e48b9100
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Mon Jan 14 14:06:27 2013 +0800

    HMP: add infrastructure for sub command
    
      This patch make parsing of hmp command aware of that it may
    have sub command. Also discard simple encapsulation function
    monitor_find_command(). For case "@command ", space after
    @command is filtered out.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index 6e87b5c..a77dd3b 100644
--- a/monitor.c
+++ b/monitor.c
@@ -129,6 +129,11 @@ typedef struct mon_cmd_t {
                           MonitorCompletion *cb, void *opaque);
     } mhandler;
     int flags;
+    /* @sub_table is a list of 2nd level of commands. If it do not exist,
+     * mhandler should be used. If it exist, sub_table[?].mhandler should be
+     * used, and mhandler of 1st level plays the role of help function.
+     */
+    struct mon_cmd_t *sub_table;
 } mon_cmd_t;
 
 /* file descriptors passed via SCM_RIGHTS */
@@ -3541,18 +3546,27 @@ static const mon_cmd_t *search_dispatch_table(const mon_cmd_t *disp_table,
     return NULL;
 }
 
-static const mon_cmd_t *monitor_find_command(const char *cmdname)
-{
-    return search_dispatch_table(mon_cmds, cmdname);
-}
-
 static const mon_cmd_t *qmp_find_cmd(const char *cmdname)
 {
     return search_dispatch_table(qmp_cmds, cmdname);
 }
 
+/*
+ * Parse @cmdline according to command table @table.
+ * If @cmdline is blank, return NULL.
+ * If it can't be parsed, report to @mon, and return NULL.
+ * Else, insert command arguments into @qdict, and return the command.
+ * If sub-command table exist, and if @cmdline contains addtional string for
+ * sub-command, this function will try search sub-command table. if no
+ * addtional string for sub-command exist, this function will return the found
+ * one in @table.
+ * Do not assume the returned command points into @table!  It doesn't
+ * when the command is a sub-command.
+ */
 static const mon_cmd_t *monitor_parse_command(Monitor *mon,
                                               const char *cmdline,
+                                              int start,
+                                              mon_cmd_t *table,
                                               QDict *qdict)
 {
     const char *p, *typestr;
@@ -3563,20 +3577,35 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
     char *key;
 
 #ifdef DEBUG
-    monitor_printf(mon, "command='%s'\n", cmdline);
+    monitor_printf(mon, "command='%s', start='%d'\n", cmdline, start);
 #endif
 
     /* extract the command name */
-    p = get_command_name(cmdline, cmdname, sizeof(cmdname));
+    p = get_command_name(cmdline + start, cmdname, sizeof(cmdname));
     if (!p)
         return NULL;
 
-    cmd = monitor_find_command(cmdname);
+    cmd = search_dispatch_table(table, cmdname);
     if (!cmd) {
-        monitor_printf(mon, "unknown command: '%s'\n", cmdname);
+        monitor_printf(mon, "unknown command: '%.*s'\n",
+                       (int)(p - cmdline), cmdline);
         return NULL;
     }
 
+    /* filter out following useless space */
+    while (qemu_isspace(*p)) {
+        p++;
+    }
+    /* search sub command */
+    if (cmd->sub_table != NULL) {
+        /* check if user set additional command */
+        if (*p == '\0') {
+            return cmd;
+        }
+        return monitor_parse_command(mon, cmdline, p - cmdline,
+                                     cmd->sub_table, qdict);
+    }
+
     /* parse the parameters */
     typestr = cmd->args_type;
     for(;;) {
@@ -3932,7 +3961,7 @@ static void handle_user_command(Monitor *mon, const char *cmdline)
 
     qdict = qdict_new();
 
-    cmd = monitor_parse_command(mon, cmdline, qdict);
+    cmd = monitor_parse_command(mon, cmdline, 0, mon_cmds, qdict);
     if (!cmd)
         goto out;
 
commit 5f11cb002a342e4fc0f87bb36fbabbc19bf04728
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Mon Jan 14 14:06:26 2013 +0800

    HMP: delete info handler
    
      Now cmd and info handler have same format, so delete info handler.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index 4468bde..6e87b5c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -123,7 +123,6 @@ typedef struct mon_cmd_t {
     const char *help;
     void (*user_print)(Monitor *mon, const QObject *data);
     union {
-        void (*info)(Monitor *mon, const QDict *qdict);
         void (*cmd)(Monitor *mon, const QDict *qdict);
         int  (*cmd_new)(Monitor *mon, const QDict *params, QObject **ret_data);
         int  (*cmd_async)(Monitor *mon, const QDict *params,
@@ -825,7 +824,7 @@ static void do_info(Monitor *mon, const QDict *qdict)
         goto help;
     }
 
-    cmd->mhandler.info(mon, NULL);
+    cmd->mhandler.cmd(mon, NULL);
     return;
 
 help:
@@ -2442,63 +2441,63 @@ static mon_cmd_t info_cmds[] = {
         .args_type  = "",
         .params     = "",
         .help       = "show the version of QEMU",
-        .mhandler.info = hmp_info_version,
+        .mhandler.cmd = hmp_info_version,
     },
     {
         .name       = "network",
         .args_type  = "",
         .params     = "",
         .help       = "show the network state",
-        .mhandler.info = do_info_network,
+        .mhandler.cmd = do_info_network,
     },
     {
         .name       = "chardev",
         .args_type  = "",
         .params     = "",
         .help       = "show the character devices",
-        .mhandler.info = hmp_info_chardev,
+        .mhandler.cmd = hmp_info_chardev,
     },
     {
         .name       = "block",
         .args_type  = "",
         .params     = "",
         .help       = "show the block devices",
-        .mhandler.info = hmp_info_block,
+        .mhandler.cmd = hmp_info_block,
     },
     {
         .name       = "blockstats",
         .args_type  = "",
         .params     = "",
         .help       = "show block device statistics",
-        .mhandler.info = hmp_info_blockstats,
+        .mhandler.cmd = hmp_info_blockstats,
     },
     {
         .name       = "block-jobs",
         .args_type  = "",
         .params     = "",
         .help       = "show progress of ongoing block device operations",
-        .mhandler.info = hmp_info_block_jobs,
+        .mhandler.cmd = hmp_info_block_jobs,
     },
     {
         .name       = "registers",
         .args_type  = "",
         .params     = "",
         .help       = "show the cpu registers",
-        .mhandler.info = do_info_registers,
+        .mhandler.cmd = do_info_registers,
     },
     {
         .name       = "cpus",
         .args_type  = "",
         .params     = "",
         .help       = "show infos for each CPU",
-        .mhandler.info = hmp_info_cpus,
+        .mhandler.cmd = hmp_info_cpus,
     },
     {
         .name       = "history",
         .args_type  = "",
         .params     = "",
         .help       = "show the command line history",
-        .mhandler.info = do_info_history,
+        .mhandler.cmd = do_info_history,
     },
 #if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_MIPS) || \
     defined(TARGET_LM32) || (defined(TARGET_SPARC) && !defined(TARGET_SPARC64))
@@ -2508,11 +2507,11 @@ static mon_cmd_t info_cmds[] = {
         .params     = "",
         .help       = "show the interrupts statistics (if available)",
 #ifdef TARGET_SPARC
-        .mhandler.info = sun4m_irq_info,
+        .mhandler.cmd = sun4m_irq_info,
 #elif defined(TARGET_LM32)
-        .mhandler.info = lm32_irq_info,
+        .mhandler.cmd = lm32_irq_info,
 #else
-        .mhandler.info = irq_info,
+        .mhandler.cmd = irq_info,
 #endif
     },
     {
@@ -2521,11 +2520,11 @@ static mon_cmd_t info_cmds[] = {
         .params     = "",
         .help       = "show i8259 (PIC) state",
 #ifdef TARGET_SPARC
-        .mhandler.info = sun4m_pic_info,
+        .mhandler.cmd = sun4m_pic_info,
 #elif defined(TARGET_LM32)
-        .mhandler.info = lm32_do_pic_info,
+        .mhandler.cmd = lm32_do_pic_info,
 #else
-        .mhandler.info = pic_info,
+        .mhandler.cmd = pic_info,
 #endif
     },
 #endif
@@ -2534,7 +2533,7 @@ static mon_cmd_t info_cmds[] = {
         .args_type  = "",
         .params     = "",
         .help       = "show PCI info",
-        .mhandler.info = hmp_info_pci,
+        .mhandler.cmd = hmp_info_pci,
     },
 #if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC) || \
     defined(TARGET_PPC) || defined(TARGET_XTENSA)
@@ -2543,7 +2542,7 @@ static mon_cmd_t info_cmds[] = {
         .args_type  = "",
         .params     = "",
         .help       = "show virtual to physical memory mappings",
-        .mhandler.info = tlb_info,
+        .mhandler.cmd = tlb_info,
     },
 #endif
 #if defined(TARGET_I386)
@@ -2552,7 +2551,7 @@ static mon_cmd_t info_cmds[] = {
         .args_type  = "",
         .params     = "",
         .help       = "show the active virtual memory mappings",
-        .mhandler.info = mem_info,
+        .mhandler.cmd = mem_info,
     },
 #endif
     {
@@ -2560,91 +2559,91 @@ static mon_cmd_t info_cmds[] = {
         .args_type  = "",
         .params     = "",
         .help       = "show memory tree",
-        .mhandler.info = do_info_mtree,
+        .mhandler.cmd = do_info_mtree,
     },
     {
         .name       = "jit",
         .args_type  = "",
         .params     = "",
         .help       = "show dynamic compiler info",
-        .mhandler.info = do_info_jit,
+        .mhandler.cmd = do_info_jit,
     },
     {
         .name       = "kvm",
         .args_type  = "",
         .params     = "",
         .help       = "show KVM information",
-        .mhandler.info = hmp_info_kvm,
+        .mhandler.cmd = hmp_info_kvm,
     },
     {
         .name       = "numa",
         .args_type  = "",
         .params     = "",
         .help       = "show NUMA information",
-        .mhandler.info = do_info_numa,
+        .mhandler.cmd = do_info_numa,
     },
     {
         .name       = "usb",
         .args_type  = "",
         .params     = "",
         .help       = "show guest USB devices",
-        .mhandler.info = usb_info,
+        .mhandler.cmd = usb_info,
     },
     {
         .name       = "usbhost",
         .args_type  = "",
         .params     = "",
         .help       = "show host USB devices",
-        .mhandler.info = usb_host_info,
+        .mhandler.cmd = usb_host_info,
     },
     {
         .name       = "profile",
         .args_type  = "",
         .params     = "",
         .help       = "show profiling information",
-        .mhandler.info = do_info_profile,
+        .mhandler.cmd = do_info_profile,
     },
     {
         .name       = "capture",
         .args_type  = "",
         .params     = "",
         .help       = "show capture information",
-        .mhandler.info = do_info_capture,
+        .mhandler.cmd = do_info_capture,
     },
     {
         .name       = "snapshots",
         .args_type  = "",
         .params     = "",
         .help       = "show the currently saved VM snapshots",
-        .mhandler.info = do_info_snapshots,
+        .mhandler.cmd = do_info_snapshots,
     },
     {
         .name       = "status",
         .args_type  = "",
         .params     = "",
         .help       = "show the current VM status (running|paused)",
-        .mhandler.info = hmp_info_status,
+        .mhandler.cmd = hmp_info_status,
     },
     {
         .name       = "pcmcia",
         .args_type  = "",
         .params     = "",
         .help       = "show guest PCMCIA status",
-        .mhandler.info = pcmcia_info,
+        .mhandler.cmd = pcmcia_info,
     },
     {
         .name       = "mice",
         .args_type  = "",
         .params     = "",
         .help       = "show which guest mouse is receiving events",
-        .mhandler.info = hmp_info_mice,
+        .mhandler.cmd = hmp_info_mice,
     },
     {
         .name       = "vnc",
         .args_type  = "",
         .params     = "",
         .help       = "show the vnc server status",
-        .mhandler.info = hmp_info_vnc,
+        .mhandler.cmd = hmp_info_vnc,
     },
 #if defined(CONFIG_SPICE)
     {
@@ -2652,7 +2651,7 @@ static mon_cmd_t info_cmds[] = {
         .args_type  = "",
         .params     = "",
         .help       = "show the spice server status",
-        .mhandler.info = hmp_info_spice,
+        .mhandler.cmd = hmp_info_spice,
     },
 #endif
     {
@@ -2660,14 +2659,14 @@ static mon_cmd_t info_cmds[] = {
         .args_type  = "",
         .params     = "",
         .help       = "show the current VM name",
-        .mhandler.info = hmp_info_name,
+        .mhandler.cmd = hmp_info_name,
     },
     {
         .name       = "uuid",
         .args_type  = "",
         .params     = "",
         .help       = "show the current VM UUID",
-        .mhandler.info = hmp_info_uuid,
+        .mhandler.cmd = hmp_info_uuid,
     },
 #if defined(TARGET_PPC)
     {
@@ -2675,7 +2674,7 @@ static mon_cmd_t info_cmds[] = {
         .args_type  = "",
         .params     = "",
         .help       = "show CPU statistics",
-        .mhandler.info = do_info_cpu_stats,
+        .mhandler.cmd = do_info_cpu_stats,
     },
 #endif
 #if defined(CONFIG_SLIRP)
@@ -2684,7 +2683,7 @@ static mon_cmd_t info_cmds[] = {
         .args_type  = "",
         .params     = "",
         .help       = "show user network stack connection states",
-        .mhandler.info = do_info_usernet,
+        .mhandler.cmd = do_info_usernet,
     },
 #endif
     {
@@ -2692,56 +2691,56 @@ static mon_cmd_t info_cmds[] = {
         .args_type  = "",
         .params     = "",
         .help       = "show migration status",
-        .mhandler.info = hmp_info_migrate,
+        .mhandler.cmd = hmp_info_migrate,
     },
     {
         .name       = "migrate_capabilities",
         .args_type  = "",
         .params     = "",
         .help       = "show current migration capabilities",
-        .mhandler.info = hmp_info_migrate_capabilities,
+        .mhandler.cmd = hmp_info_migrate_capabilities,
     },
     {
         .name       = "migrate_cache_size",
         .args_type  = "",
         .params     = "",
         .help       = "show current migration xbzrle cache size",
-        .mhandler.info = hmp_info_migrate_cache_size,
+        .mhandler.cmd = hmp_info_migrate_cache_size,
     },
     {
         .name       = "balloon",
         .args_type  = "",
         .params     = "",
         .help       = "show balloon information",
-        .mhandler.info = hmp_info_balloon,
+        .mhandler.cmd = hmp_info_balloon,
     },
     {
         .name       = "qtree",
         .args_type  = "",
         .params     = "",
         .help       = "show device tree",
-        .mhandler.info = do_info_qtree,
+        .mhandler.cmd = do_info_qtree,
     },
     {
         .name       = "qdm",
         .args_type  = "",
         .params     = "",
         .help       = "show qdev device model list",
-        .mhandler.info = do_info_qdm,
+        .mhandler.cmd = do_info_qdm,
     },
     {
         .name       = "roms",
         .args_type  = "",
         .params     = "",
         .help       = "show roms",
-        .mhandler.info = do_info_roms,
+        .mhandler.cmd = do_info_roms,
     },
     {
         .name       = "trace-events",
         .args_type  = "",
         .params     = "",
         .help       = "show available trace-events & their state",
-        .mhandler.info = do_trace_print_events,
+        .mhandler.cmd = do_trace_print_events,
     },
     {
         .name       = NULL,
commit 84f2d0ea0f39bc140a6c69ba8e3ffd6b10cae6fa
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Mon Jan 14 14:06:25 2013 +0800

    HMP: add QDict to info callback handler
    
      This patch change all info call back function to take
    additional QDict * parameter, which allow those command
    take parameter. Now it is set to NULL at default case.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/hmp.c b/hmp.c
index 68929b4..c7b6ba0 100644
--- a/hmp.c
+++ b/hmp.c
@@ -31,7 +31,7 @@ static void hmp_handle_error(Monitor *mon, Error **errp)
     }
 }
 
-void hmp_info_name(Monitor *mon)
+void hmp_info_name(Monitor *mon, const QDict *qdict)
 {
     NameInfo *info;
 
@@ -42,7 +42,7 @@ void hmp_info_name(Monitor *mon)
     qapi_free_NameInfo(info);
 }
 
-void hmp_info_version(Monitor *mon)
+void hmp_info_version(Monitor *mon, const QDict *qdict)
 {
     VersionInfo *info;
 
@@ -55,7 +55,7 @@ void hmp_info_version(Monitor *mon)
     qapi_free_VersionInfo(info);
 }
 
-void hmp_info_kvm(Monitor *mon)
+void hmp_info_kvm(Monitor *mon, const QDict *qdict)
 {
     KvmInfo *info;
 
@@ -70,7 +70,7 @@ void hmp_info_kvm(Monitor *mon)
     qapi_free_KvmInfo(info);
 }
 
-void hmp_info_status(Monitor *mon)
+void hmp_info_status(Monitor *mon, const QDict *qdict)
 {
     StatusInfo *info;
 
@@ -89,7 +89,7 @@ void hmp_info_status(Monitor *mon)
     qapi_free_StatusInfo(info);
 }
 
-void hmp_info_uuid(Monitor *mon)
+void hmp_info_uuid(Monitor *mon, const QDict *qdict)
 {
     UuidInfo *info;
 
@@ -98,7 +98,7 @@ void hmp_info_uuid(Monitor *mon)
     qapi_free_UuidInfo(info);
 }
 
-void hmp_info_chardev(Monitor *mon)
+void hmp_info_chardev(Monitor *mon, const QDict *qdict)
 {
     ChardevInfoList *char_info, *info;
 
@@ -111,7 +111,7 @@ void hmp_info_chardev(Monitor *mon)
     qapi_free_ChardevInfoList(char_info);
 }
 
-void hmp_info_mice(Monitor *mon)
+void hmp_info_mice(Monitor *mon, const QDict *qdict)
 {
     MouseInfoList *mice_list, *mouse;
 
@@ -131,7 +131,7 @@ void hmp_info_mice(Monitor *mon)
     qapi_free_MouseInfoList(mice_list);
 }
 
-void hmp_info_migrate(Monitor *mon)
+void hmp_info_migrate(Monitor *mon, const QDict *qdict)
 {
     MigrationInfo *info;
     MigrationCapabilityStatusList *caps, *cap;
@@ -209,7 +209,7 @@ void hmp_info_migrate(Monitor *mon)
     qapi_free_MigrationCapabilityStatusList(caps);
 }
 
-void hmp_info_migrate_capabilities(Monitor *mon)
+void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict)
 {
     MigrationCapabilityStatusList *caps, *cap;
 
@@ -228,13 +228,13 @@ void hmp_info_migrate_capabilities(Monitor *mon)
     qapi_free_MigrationCapabilityStatusList(caps);
 }
 
-void hmp_info_migrate_cache_size(Monitor *mon)
+void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict)
 {
     monitor_printf(mon, "xbzrel cache size: %" PRId64 " kbytes\n",
                    qmp_query_migrate_cache_size(NULL) >> 10);
 }
 
-void hmp_info_cpus(Monitor *mon)
+void hmp_info_cpus(Monitor *mon, const QDict *qdict)
 {
     CpuInfoList *cpu_list, *cpu;
 
@@ -272,7 +272,7 @@ void hmp_info_cpus(Monitor *mon)
     qapi_free_CpuInfoList(cpu_list);
 }
 
-void hmp_info_block(Monitor *mon)
+void hmp_info_block(Monitor *mon, const QDict *qdict)
 {
     BlockInfoList *block_list, *info;
 
@@ -326,7 +326,7 @@ void hmp_info_block(Monitor *mon)
     qapi_free_BlockInfoList(block_list);
 }
 
-void hmp_info_blockstats(Monitor *mon)
+void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
 {
     BlockStatsList *stats_list, *stats;
 
@@ -360,7 +360,7 @@ void hmp_info_blockstats(Monitor *mon)
     qapi_free_BlockStatsList(stats_list);
 }
 
-void hmp_info_vnc(Monitor *mon)
+void hmp_info_vnc(Monitor *mon, const QDict *qdict)
 {
     VncInfo *info;
     Error *err = NULL;
@@ -406,7 +406,7 @@ out:
     qapi_free_VncInfo(info);
 }
 
-void hmp_info_spice(Monitor *mon)
+void hmp_info_spice(Monitor *mon, const QDict *qdict)
 {
     SpiceChannelList *chan;
     SpiceInfo *info;
@@ -453,7 +453,7 @@ out:
     qapi_free_SpiceInfo(info);
 }
 
-void hmp_info_balloon(Monitor *mon)
+void hmp_info_balloon(Monitor *mon, const QDict *qdict)
 {
     BalloonInfo *info;
     Error *err = NULL;
@@ -570,7 +570,7 @@ static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev)
     }
 }
 
-void hmp_info_pci(Monitor *mon)
+void hmp_info_pci(Monitor *mon, const QDict *qdict)
 {
     PciInfoList *info_list, *info;
     Error *err = NULL;
@@ -593,7 +593,7 @@ void hmp_info_pci(Monitor *mon)
     qapi_free_PciInfoList(info_list);
 }
 
-void hmp_info_block_jobs(Monitor *mon)
+void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
 {
     BlockJobInfoList *list;
     Error *err = NULL;
diff --git a/hmp.h b/hmp.h
index 700fbdc..44be683 100644
--- a/hmp.h
+++ b/hmp.h
@@ -18,24 +18,24 @@
 #include "qapi-types.h"
 #include "qapi/qmp/qdict.h"
 
-void hmp_info_name(Monitor *mon);
-void hmp_info_version(Monitor *mon);
-void hmp_info_kvm(Monitor *mon);
-void hmp_info_status(Monitor *mon);
-void hmp_info_uuid(Monitor *mon);
-void hmp_info_chardev(Monitor *mon);
-void hmp_info_mice(Monitor *mon);
-void hmp_info_migrate(Monitor *mon);
-void hmp_info_migrate_capabilities(Monitor *mon);
-void hmp_info_migrate_cache_size(Monitor *mon);
-void hmp_info_cpus(Monitor *mon);
-void hmp_info_block(Monitor *mon);
-void hmp_info_blockstats(Monitor *mon);
-void hmp_info_vnc(Monitor *mon);
-void hmp_info_spice(Monitor *mon);
-void hmp_info_balloon(Monitor *mon);
-void hmp_info_pci(Monitor *mon);
-void hmp_info_block_jobs(Monitor *mon);
+void hmp_info_name(Monitor *mon, const QDict *qdict);
+void hmp_info_version(Monitor *mon, const QDict *qdict);
+void hmp_info_kvm(Monitor *mon, const QDict *qdict);
+void hmp_info_status(Monitor *mon, const QDict *qdict);
+void hmp_info_uuid(Monitor *mon, const QDict *qdict);
+void hmp_info_chardev(Monitor *mon, const QDict *qdict);
+void hmp_info_mice(Monitor *mon, const QDict *qdict);
+void hmp_info_migrate(Monitor *mon, const QDict *qdict);
+void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict);
+void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict);
+void hmp_info_cpus(Monitor *mon, const QDict *qdict);
+void hmp_info_block(Monitor *mon, const QDict *qdict);
+void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
+void hmp_info_vnc(Monitor *mon, const QDict *qdict);
+void hmp_info_spice(Monitor *mon, const QDict *qdict);
+void hmp_info_balloon(Monitor *mon, const QDict *qdict);
+void hmp_info_pci(Monitor *mon, const QDict *qdict);
+void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
 void hmp_quit(Monitor *mon, const QDict *qdict);
 void hmp_stop(Monitor *mon, const QDict *qdict);
 void hmp_system_reset(Monitor *mon, const QDict *qdict);
diff --git a/hw/i8259.c b/hw/i8259.c
index 264879e..54fe144 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -407,7 +407,7 @@ static void pic_init(PICCommonState *s)
     qdev_init_gpio_in(&s->dev.qdev, pic_set_irq, 8);
 }
 
-void pic_info(Monitor *mon)
+void pic_info(Monitor *mon, const QDict *qdict)
 {
     int i;
     PICCommonState *s;
@@ -425,7 +425,7 @@ void pic_info(Monitor *mon)
     }
 }
 
-void irq_info(Monitor *mon)
+void irq_info(Monitor *mon, const QDict *qdict)
 {
 #ifndef DEBUG_IRQ_COUNT
     monitor_printf(mon, "irq statistic code not compiled.\n");
diff --git a/hw/lm32_pic.c b/hw/lm32_pic.c
index 8f13355..42f298a 100644
--- a/hw/lm32_pic.c
+++ b/hw/lm32_pic.c
@@ -39,7 +39,7 @@ struct LM32PicState {
 typedef struct LM32PicState LM32PicState;
 
 static LM32PicState *pic;
-void lm32_do_pic_info(Monitor *mon)
+void lm32_do_pic_info(Monitor *mon, const QDict *qdict)
 {
     if (pic == NULL) {
         return;
@@ -49,7 +49,7 @@ void lm32_do_pic_info(Monitor *mon)
             pic->im, pic->ip, pic->irq_state);
 }
 
-void lm32_irq_info(Monitor *mon)
+void lm32_irq_info(Monitor *mon, const QDict *qdict)
 {
     int i;
     uint32_t count;
diff --git a/hw/lm32_pic.h b/hw/lm32_pic.h
index 14456f3..5556803 100644
--- a/hw/lm32_pic.h
+++ b/hw/lm32_pic.h
@@ -8,7 +8,7 @@ uint32_t lm32_pic_get_im(DeviceState *d);
 void lm32_pic_set_ip(DeviceState *d, uint32_t ip);
 void lm32_pic_set_im(DeviceState *d, uint32_t im);
 
-void lm32_do_pic_info(Monitor *mon);
-void lm32_irq_info(Monitor *mon);
+void lm32_do_pic_info(Monitor *mon, const QDict *qdict);
+void lm32_irq_info(Monitor *mon, const QDict *qdict);
 
 #endif /* QEMU_HW_LM32_PIC_H */
diff --git a/hw/loader.c b/hw/loader.c
index 3f59fcd..995edc3 100644
--- a/hw/loader.c
+++ b/hw/loader.c
@@ -778,7 +778,7 @@ void *rom_ptr(hwaddr addr)
     return rom->data + (addr - rom->addr);
 }
 
-void do_info_roms(Monitor *mon)
+void do_info_roms(Monitor *mon, const QDict *qdict)
 {
     Rom *rom;
 
diff --git a/hw/loader.h b/hw/loader.h
index 26480ad..5e61c95 100644
--- a/hw/loader.h
+++ b/hw/loader.h
@@ -1,5 +1,6 @@
 #ifndef LOADER_H
 #define LOADER_H
+#include "qapi/qmp/qdict.h"
 
 /* loader.c */
 int get_image_size(const char *filename);
@@ -30,7 +31,7 @@ int rom_load_all(void);
 void rom_set_fw(void *f);
 int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
 void *rom_ptr(hwaddr addr);
-void do_info_roms(Monitor *mon);
+void do_info_roms(Monitor *mon, const QDict *qdict);
 
 #define rom_add_file_fixed(_f, _a, _i)          \
     rom_add_file(_f, NULL, _a, _i)
diff --git a/hw/pc.h b/hw/pc.h
index 4134aa9..fbcf43d 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -40,8 +40,8 @@ qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq);
 qemu_irq *kvm_i8259_init(ISABus *bus);
 int pic_read_irq(DeviceState *d);
 int pic_get_output(DeviceState *d);
-void pic_info(Monitor *mon);
-void irq_info(Monitor *mon);
+void pic_info(Monitor *mon, const QDict *qdict);
+void irq_info(Monitor *mon, const QDict *qdict);
 
 /* Global System Interrupts */
 
diff --git a/hw/pcmcia.h b/hw/pcmcia.h
index aac1d77..f916693 100644
--- a/hw/pcmcia.h
+++ b/hw/pcmcia.h
@@ -14,7 +14,7 @@ typedef struct {
 
 void pcmcia_socket_register(PCMCIASocket *socket);
 void pcmcia_socket_unregister(PCMCIASocket *socket);
-void pcmcia_info(Monitor *mon);
+void pcmcia_info(Monitor *mon, const QDict *qdict);
 
 struct PCMCIACardState {
     void *state;
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 93283ee..1db5ee0 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -564,13 +564,13 @@ static void qbus_print(Monitor *mon, BusState *bus, int indent)
 }
 #undef qdev_printf
 
-void do_info_qtree(Monitor *mon)
+void do_info_qtree(Monitor *mon, const QDict *qdict)
 {
     if (sysbus_get_default())
         qbus_print(mon, sysbus_get_default(), 0);
 }
 
-void do_info_qdm(Monitor *mon)
+void do_info_qdm(Monitor *mon, const QDict *qdict)
 {
     object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, NULL);
 }
diff --git a/hw/qdev-monitor.h b/hw/qdev-monitor.h
index fae1b1e..9ec4850 100644
--- a/hw/qdev-monitor.h
+++ b/hw/qdev-monitor.h
@@ -6,8 +6,8 @@
 
 /*** monitor commands ***/
 
-void do_info_qtree(Monitor *mon);
-void do_info_qdm(Monitor *mon);
+void do_info_qtree(Monitor *mon, const QDict *qdict);
+void do_info_qdm(Monitor *mon, const QDict *qdict);
 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
 int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
 int qdev_device_help(QemuOpts *opts);
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 6f5de44..95c5058 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -216,13 +216,13 @@ static void nvram_init(M48t59State *nvram, uint8_t *macaddr,
 
 static DeviceState *slavio_intctl;
 
-void sun4m_pic_info(Monitor *mon)
+void sun4m_pic_info(Monitor *mon, const QDict *qdict)
 {
     if (slavio_intctl)
         slavio_pic_info(mon, slavio_intctl);
 }
 
-void sun4m_irq_info(Monitor *mon)
+void sun4m_irq_info(Monitor *mon, const QDict *qdict)
 {
     if (slavio_intctl)
         slavio_irq_info(mon, slavio_intctl);
diff --git a/hw/sun4m.h b/hw/sun4m.h
index 47eb945..0361eee 100644
--- a/hw/sun4m.h
+++ b/hw/sun4m.h
@@ -27,8 +27,8 @@ void slavio_pic_info(Monitor *mon, DeviceState *dev);
 void slavio_irq_info(Monitor *mon, DeviceState *dev);
 
 /* sun4m.c */
-void sun4m_pic_info(Monitor *mon);
-void sun4m_irq_info(Monitor *mon);
+void sun4m_pic_info(Monitor *mon, const QDict *qdict);
+void sun4m_irq_info(Monitor *mon, const QDict *qdict);
 
 /* sparc32_dma.c */
 #include "sparc32_dma.h"
diff --git a/hw/usb.h b/hw/usb.h
index 50c297f..bc42639 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -435,7 +435,7 @@ int set_usb_string(uint8_t *buf, const char *str);
 /* usb-linux.c */
 USBDevice *usb_host_device_open(USBBus *bus, const char *devname);
 int usb_host_device_close(const char *devname);
-void usb_host_info(Monitor *mon);
+void usb_host_info(Monitor *mon, const QDict *qdict);
 
 /* usb-bt.c */
 USBDevice *usb_bt_init(USBBus *bus, HCIInfo *hci);
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 2dc7675..e58cd9a 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -542,7 +542,7 @@ static char *usb_get_fw_dev_path(DeviceState *qdev)
     return fw_path;
 }
 
-void usb_info(Monitor *mon)
+void usb_info(Monitor *mon, const QDict *qdict)
 {
     USBBus *bus;
     USBDevice *dev;
diff --git a/hw/usb/host-bsd.c b/hw/usb/host-bsd.c
index 172aecb..07f0e01 100644
--- a/hw/usb/host-bsd.c
+++ b/hw/usb/host-bsd.c
@@ -633,7 +633,7 @@ static int usb_host_info_device(void *opaque,
     return 0;
 }
 
-void usb_host_info(Monitor *mon)
+void usb_host_info(Monitor *mon, const QDict *qdict)
 {
     usb_host_scan(mon, usb_host_info_device);
 }
diff --git a/hw/usb/host-linux.c b/hw/usb/host-linux.c
index ad75ce0..a2cff8a 100644
--- a/hw/usb/host-linux.c
+++ b/hw/usb/host-linux.c
@@ -1998,7 +1998,7 @@ static void hex2str(int val, char *str, size_t size)
     }
 }
 
-void usb_host_info(Monitor *mon)
+void usb_host_info(Monitor *mon, const QDict *qdict)
 {
     struct USBAutoFilter *f;
     struct USBHostDevice *s;
diff --git a/include/net/net.h b/include/net/net.h
index de42dd7..4a92b6c 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -112,7 +112,7 @@ ssize_t qemu_deliver_packet_iov(NetClientState *sender,
                             void *opaque);
 
 void print_net_client(Monitor *mon, NetClientState *nc);
-void do_info_network(Monitor *mon);
+void do_info_network(Monitor *mon, const QDict *qdict);
 
 /* NIC info */
 
diff --git a/include/net/slirp.h b/include/net/slirp.h
index 54b655c..0502389 100644
--- a/include/net/slirp.h
+++ b/include/net/slirp.h
@@ -40,7 +40,7 @@ int net_slirp_parse_legacy(QemuOptsList *opts_list, const char *optarg, int *ret
 
 int net_slirp_smb(const char *exported_dir);
 
-void do_info_usernet(Monitor *mon);
+void do_info_usernet(Monitor *mon, const QDict *qdict);
 
 #endif
 
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index c07d4ee..cd12f09 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -68,7 +68,7 @@ void qemu_add_machine_init_done_notifier(Notifier *notify);
 void do_savevm(Monitor *mon, const QDict *qdict);
 int load_vmstate(const char *name);
 void do_delvm(Monitor *mon, const QDict *qdict);
-void do_info_snapshots(Monitor *mon);
+void do_info_snapshots(Monitor *mon, const QDict *qdict);
 
 void qemu_announce_self(void);
 
@@ -171,7 +171,7 @@ extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
 
 void do_usb_add(Monitor *mon, const QDict *qdict);
 void do_usb_del(Monitor *mon, const QDict *qdict);
-void usb_info(Monitor *mon);
+void usb_info(Monitor *mon, const QDict *qdict);
 
 void rtc_change_mon_event(struct tm *tm);
 
diff --git a/monitor.c b/monitor.c
index 77ac451..4468bde 100644
--- a/monitor.c
+++ b/monitor.c
@@ -123,7 +123,7 @@ typedef struct mon_cmd_t {
     const char *help;
     void (*user_print)(Monitor *mon, const QObject *data);
     union {
-        void (*info)(Monitor *mon);
+        void (*info)(Monitor *mon, const QDict *qdict);
         void (*cmd)(Monitor *mon, const QDict *qdict);
         int  (*cmd_new)(Monitor *mon, const QDict *params, QObject **ret_data);
         int  (*cmd_async)(Monitor *mon, const QDict *params,
@@ -825,7 +825,7 @@ static void do_info(Monitor *mon, const QDict *qdict)
         goto help;
     }
 
-    cmd->mhandler.info(mon);
+    cmd->mhandler.info(mon, NULL);
     return;
 
 help:
@@ -899,19 +899,19 @@ int monitor_get_cpu_index(void)
     return cpu->cpu_index;
 }
 
-static void do_info_registers(Monitor *mon)
+static void do_info_registers(Monitor *mon, const QDict *qdict)
 {
     CPUArchState *env;
     env = mon_get_cpu();
     cpu_dump_state(env, (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU);
 }
 
-static void do_info_jit(Monitor *mon)
+static void do_info_jit(Monitor *mon, const QDict *qdict)
 {
     dump_exec_info((FILE *)mon, monitor_fprintf);
 }
 
-static void do_info_history(Monitor *mon)
+static void do_info_history(Monitor *mon, const QDict *qdict)
 {
     int i;
     const char *str;
@@ -930,7 +930,7 @@ static void do_info_history(Monitor *mon)
 
 #if defined(TARGET_PPC)
 /* XXX: not implemented in other targets */
-static void do_info_cpu_stats(Monitor *mon)
+static void do_info_cpu_stats(Monitor *mon, const QDict *qdict)
 {
     CPUArchState *env;
 
@@ -939,7 +939,7 @@ static void do_info_cpu_stats(Monitor *mon)
 }
 #endif
 
-static void do_trace_print_events(Monitor *mon)
+static void do_trace_print_events(Monitor *mon, const QDict *qdict)
 {
     trace_print_events((FILE *)mon, &monitor_fprintf);
 }
@@ -1491,7 +1491,7 @@ static void tlb_info_64(Monitor *mon, CPUArchState *env)
 }
 #endif
 
-static void tlb_info(Monitor *mon)
+static void tlb_info(Monitor *mon, const QDict *qdict)
 {
     CPUArchState *env;
 
@@ -1714,7 +1714,7 @@ static void mem_info_64(Monitor *mon, CPUArchState *env)
 }
 #endif
 
-static void mem_info(Monitor *mon)
+static void mem_info(Monitor *mon, const QDict *qdict)
 {
     CPUArchState *env;
 
@@ -1753,7 +1753,7 @@ static void print_tlb(Monitor *mon, int idx, tlb_t *tlb)
                    tlb->d, tlb->wt);
 }
 
-static void tlb_info(Monitor *mon)
+static void tlb_info(Monitor *mon, const QDict *qdict)
 {
     CPUArchState *env = mon_get_cpu();
     int i;
@@ -1769,7 +1769,7 @@ static void tlb_info(Monitor *mon)
 #endif
 
 #if defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_XTENSA)
-static void tlb_info(Monitor *mon)
+static void tlb_info(Monitor *mon, const QDict *qdict)
 {
     CPUArchState *env1 = mon_get_cpu();
 
@@ -1777,12 +1777,12 @@ static void tlb_info(Monitor *mon)
 }
 #endif
 
-static void do_info_mtree(Monitor *mon)
+static void do_info_mtree(Monitor *mon, const QDict *qdict)
 {
     mtree_info((fprintf_function)monitor_printf, mon);
 }
 
-static void do_info_numa(Monitor *mon)
+static void do_info_numa(Monitor *mon, const QDict *qdict)
 {
     int i;
     CPUArchState *env;
@@ -1808,7 +1808,7 @@ static void do_info_numa(Monitor *mon)
 int64_t qemu_time;
 int64_t dev_time;
 
-static void do_info_profile(Monitor *mon)
+static void do_info_profile(Monitor *mon, const QDict *qdict)
 {
     int64_t total;
     total = qemu_time;
@@ -1822,7 +1822,7 @@ static void do_info_profile(Monitor *mon)
     dev_time = 0;
 }
 #else
-static void do_info_profile(Monitor *mon)
+static void do_info_profile(Monitor *mon, const QDict *qdict)
 {
     monitor_printf(mon, "Internal profiler not compiled\n");
 }
@@ -1831,7 +1831,7 @@ static void do_info_profile(Monitor *mon)
 /* Capture support */
 static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
 
-static void do_info_capture(Monitor *mon)
+static void do_info_capture(Monitor *mon, const QDict *qdict)
 {
     int i;
     CaptureState *s;
diff --git a/net/net.c b/net/net.c
index 02b5458..cdd9b04 100644
--- a/net/net.c
+++ b/net/net.c
@@ -852,7 +852,7 @@ void print_net_client(Monitor *mon, NetClientState *nc)
                    NetClientOptionsKind_lookup[nc->info->type], nc->info_str);
 }
 
-void do_info_network(Monitor *mon)
+void do_info_network(Monitor *mon, const QDict *qdict)
 {
     NetClientState *nc, *peer;
     NetClientOptionsKind type;
diff --git a/net/slirp.c b/net/slirp.c
index c14259f..4df550f 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -670,7 +670,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
     return -1;
 }
 
-void do_info_usernet(Monitor *mon)
+void do_info_usernet(Monitor *mon, const QDict *qdict)
 {
     SlirpState *s;
 
diff --git a/savevm.c b/savevm.c
index 4e970ca..d9ff1d9 100644
--- a/savevm.c
+++ b/savevm.c
@@ -2307,7 +2307,7 @@ void do_delvm(Monitor *mon, const QDict *qdict)
     }
 }
 
-void do_info_snapshots(Monitor *mon)
+void do_info_snapshots(Monitor *mon, const QDict *qdict)
 {
     BlockDriverState *bs, *bs1;
     QEMUSnapshotInfo *sn_tab, *sn, s, *sn_info = &s;
diff --git a/vl.c b/vl.c
index 8ce2b10..f4cf7e8 100644
--- a/vl.c
+++ b/vl.c
@@ -1449,7 +1449,7 @@ void pcmcia_socket_unregister(PCMCIASocket *socket)
         }
 }
 
-void pcmcia_info(Monitor *mon)
+void pcmcia_info(Monitor *mon, const QDict *qdict)
 {
     struct pcmcia_socket_entry_s *iter;
 
commit e8bccad5ac6095b5af7946cd72d9aacb57f7c0a3
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jan 16 21:20:00 2013 +0100

    win32-aio: Fix memory leak
    
    The buffer is allocated for both reads and writes, and obviously it
    should be freed even if an error occurs.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-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 e4b7b75..b9236ea 100644
--- a/block/win32-aio.c
+++ b/block/win32-aio.c
@@ -87,8 +87,8 @@ static void win32_aio_process_completion(QEMUWin32AIOState *s,
                 memcpy(qiov->iov[i].iov_base, p, qiov->iov[i].iov_len);
                 p += qiov->iov[i].iov_len;
             }
-            qemu_vfree(waiocb->buf);
         }
+        qemu_vfree(waiocb->buf);
     }
 
 
commit bcbbd234d42f1111e42b91376db61922d42e7e9e
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jan 16 21:19:59 2013 +0100

    win32-aio: Fix vectored reads
    
    Copying data in the right direction really helps a lot!
    
    Cc: qemu-stable at nongnu.org
    Signed-off-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 0383370..e4b7b75 100644
--- a/block/win32-aio.c
+++ b/block/win32-aio.c
@@ -84,7 +84,7 @@ static void win32_aio_process_completion(QEMUWin32AIOState *s,
             int i;
 
             for (i = 0; i < qiov->niov; ++i) {
-                memcpy(p, qiov->iov[i].iov_base, qiov->iov[i].iov_len);
+                memcpy(qiov->iov[i].iov_base, p, qiov->iov[i].iov_len);
                 p += qiov->iov[i].iov_len;
             }
             qemu_vfree(waiocb->buf);
commit 2ea9b58f0bc62445b7ace2381b4c4db7d5597e19
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jan 16 19:25:51 2013 +0100

    aio: Fix return value of aio_poll()
    
    aio_poll() must return true if any work is still pending, even if it
    didn't make progress, so that bdrv_drain_all() doesn't stop waiting too
    early. The possibility of stopping early occasionally lead to a failed
    assertion in bdrv_drain_all(), when some in-flight request was missed
    and the function didn't really drain all requests.
    
    In order to make that change, the return value as specified in the
    function comment must change for blocking = false; fortunately, the
    return value of blocking = false callers is only used in test cases, so
    this change shouldn't cause any trouble.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/aio-posix.c b/aio-posix.c
index 88d09e1..fe4dbb4 100644
--- a/aio-posix.c
+++ b/aio-posix.c
@@ -264,5 +264,6 @@ bool aio_poll(AioContext *ctx, bool blocking)
         }
     }
 
-    return progress;
+    assert(progress || busy);
+    return true;
 }
diff --git a/aio-win32.c b/aio-win32.c
index f5ea027..38723bf 100644
--- a/aio-win32.c
+++ b/aio-win32.c
@@ -214,5 +214,6 @@ bool aio_poll(AioContext *ctx, bool blocking)
         events[ret - WAIT_OBJECT_0] = events[--count];
     }
 
-    return progress;
+    assert(progress || busy);
+    return true;
 }
diff --git a/include/block/aio.h b/include/block/aio.h
index 0933f05..8eda924 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -173,16 +173,14 @@ bool aio_pending(AioContext *ctx);
  * aio as a result of executing I/O completion or bh callbacks.
  *
  * If there is no pending AIO operation or completion (bottom half),
- * return false.  If there are pending bottom halves, return true.
+ * return false.  If there are pending AIO operations of bottom halves,
+ * return true.
  *
  * If there are no pending bottom halves, but there are pending AIO
  * operations, it may not be possible to make any progress without
  * blocking.  If @blocking is true, this function will wait until one
  * or more AIO events have completed, to ensure something has moved
  * before returning.
- *
- * If @blocking is false, this function will also return false if the
- * function cannot make any progress without blocking.
  */
 bool aio_poll(AioContext *ctx, bool blocking);
 
diff --git a/tests/test-aio.c b/tests/test-aio.c
index e4ebef7..c173870 100644
--- a/tests/test-aio.c
+++ b/tests/test-aio.c
@@ -315,13 +315,13 @@ static void test_wait_event_notifier_noflush(void)
     event_notifier_set(&data.e);
     g_assert(aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 1);
-    g_assert(!aio_poll(ctx, false));
+    g_assert(aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 1);
 
     event_notifier_set(&data.e);
     g_assert(aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 2);
-    g_assert(!aio_poll(ctx, false));
+    g_assert(aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 2);
 
     event_notifier_set(&dummy.e);
commit 6bf3ee07ff55aa795010a8e071826f38e9a26112
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jan 16 10:54:34 2013 +0100

    ide: Remove wrong assertion
    
    The Bus Master IDE Active bit (BM_STATUS_DMAING) is not only set when
    the request is still in flight, but also when it has completed and the
    size of the physical memory regions in the PRDT was larger than the
    transfer size.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index e6226e3..59fd539 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -311,7 +311,6 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
             if (bm->bus->dma->aiocb) {
                 bdrv_drain_all();
                 assert(bm->bus->dma->aiocb == NULL);
-                assert((bm->status & BM_STATUS_DMAING) == 0);
             }
         } else {
             bm->cur_addr = bm->addr;
commit 6d759117d3fd28e38c49c56c9de206cc718d32fa
Author: Jeff Cody <jcody at redhat.com>
Date:   Tue Jan 15 10:47:24 2013 -0500

    block: fix null-pointer bug on error case in block commit
    
    This is a bug that was caught by a coverity run by Markus.  In
    the error case when we errored out to exit_restore_open early in the
    function, 'overlay_bs' was still NULL at that point, although it is
    used to look up flags and perform a bdrv_reopen().
    
    Move the overlay_bs lookup to where it is needed, and check for NULL
    before restoring the flags.  Also get rid of the unneeded parameter
    initialization.
    
    Reported-By: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/commit.c b/block/commit.c
index 61ebdba..553447e 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -65,7 +65,7 @@ static void coroutine_fn commit_run(void *opaque)
     BlockDriverState *active = s->active;
     BlockDriverState *top = s->top;
     BlockDriverState *base = s->base;
-    BlockDriverState *overlay_bs = NULL;
+    BlockDriverState *overlay_bs;
     int64_t sector_num, end;
     int ret = 0;
     int n = 0;
@@ -92,8 +92,6 @@ static void coroutine_fn commit_run(void *opaque)
         }
     }
 
-    overlay_bs = bdrv_find_overlay(active, top);
-
     end = s->common.len >> BDRV_SECTOR_BITS;
     buf = qemu_blockalign(top, COMMIT_BUFFER_SIZE);
 
@@ -156,7 +154,8 @@ exit_restore_reopen:
     if (s->base_flags != bdrv_get_flags(base)) {
         bdrv_reopen(base, s->base_flags, NULL);
     }
-    if (s->orig_overlay_flags != bdrv_get_flags(overlay_bs)) {
+    overlay_bs = bdrv_find_overlay(active, top);
+    if (overlay_bs && s->orig_overlay_flags != bdrv_get_flags(overlay_bs)) {
         bdrv_reopen(overlay_bs, s->orig_overlay_flags, NULL);
     }
 
commit a4cbfe24e4d9f86622ba81b8c5b599c92c682fbc
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Jan 13 16:35:41 2013 +0000

    bswap: improve gluing
    
    OpenBSD system compiler (gcc 4.2.1) has problems with concatenation
    of macro arguments in macro functions:
      CC    aes.o
    In file included from /src/qemu/include/qemu-common.h:126,
                     from /src/qemu/aes.c:30:
    /src/qemu/include/qemu/bswap.h: In function 'leul_to_cpu':
    /src/qemu/include/qemu/bswap.h:461: warning: implicit declaration of function 'bswapHOST_LONG_BITS'
    /src/qemu/include/qemu/bswap.h:461: warning: nested extern declaration of 'bswapHOST_LONG_BITS'
    
    Function leul_to_cpu() is only used in kvm-all.c, so the warnings
    are not fatal on OpenBSD without -Werror.
    
    Fix by applying glue(). Also add do {} while(0) wrapping and fix
    semicolon use while at it.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index be9b035..e6d4798 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -72,45 +72,45 @@ static inline void bswap64s(uint64_t *s)
 
 #if defined(HOST_WORDS_BIGENDIAN)
 #define be_bswap(v, size) (v)
-#define le_bswap(v, size) bswap ## size(v)
+#define le_bswap(v, size) glue(bswap, size)(v)
 #define be_bswaps(v, size)
-#define le_bswaps(p, size) *p = bswap ## size(*p);
+#define le_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
 #else
 #define le_bswap(v, size) (v)
-#define be_bswap(v, size) bswap ## size(v)
+#define be_bswap(v, size) glue(bswap, size)(v)
 #define le_bswaps(v, size)
-#define be_bswaps(p, size) *p = bswap ## size(*p);
+#define be_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
 #endif
 
 #define CPU_CONVERT(endian, size, type)\
 static inline type endian ## size ## _to_cpu(type v)\
 {\
-    return endian ## _bswap(v, size);\
+    return glue(endian, _bswap)(v, size);\
 }\
 \
 static inline type cpu_to_ ## endian ## size(type v)\
 {\
-    return endian ## _bswap(v, size);\
+    return glue(endian, _bswap)(v, size);\
 }\
 \
 static inline void endian ## size ## _to_cpus(type *p)\
 {\
-    endian ## _bswaps(p, size)\
+    glue(endian, _bswaps)(p, size);\
 }\
 \
 static inline void cpu_to_ ## endian ## size ## s(type *p)\
 {\
-    endian ## _bswaps(p, size)\
+    glue(endian, _bswaps)(p, size);\
 }\
 \
 static inline type endian ## size ## _to_cpup(const type *p)\
 {\
-    return endian ## size ## _to_cpu(*p);\
+    return glue(glue(endian, size), _to_cpu)(*p);\
 }\
 \
 static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
 {\
-     *p = cpu_to_ ## endian ## size(v);\
+    *p = glue(glue(cpu_to_, endian), size)(v);\
 }
 
 CPU_CONVERT(be, 16, uint16_t)
commit 9468a5d4904223af2c47131f32e3a0555142e4e3
Author: Laurent Vivier <laurent at vivier.eu>
Date:   Thu Jan 10 22:30:50 2013 +0100

    alpha-linux-user: Correct select
    
    Alpha, like s390x, passes all select arguments in registers.
    
    Signed-off-by: Laurent Vivier <laurent at vivier.eu>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 94f79dd..693e66f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6227,8 +6227,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(settimeofday(&tv, NULL));
         }
         break;
-#if defined(TARGET_NR_select) && !defined(TARGET_S390X) && !defined(TARGET_S390)
+#if defined(TARGET_NR_select)
     case TARGET_NR_select:
+#if defined(TARGET_S390X) || defined(TARGET_ALPHA)
+        ret = do_select(arg1, arg2, arg3, arg4, arg5);
+#else
         {
             struct target_sel_arg_struct *sel;
             abi_ulong inp, outp, exp, tvp;
@@ -6244,6 +6247,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             unlock_user_struct(sel, arg1, 0);
             ret = do_select(nsel, inp, outp, exp, tvp);
         }
+#endif
         break;
 #endif
 #ifdef TARGET_NR_pselect6
@@ -7167,12 +7171,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         }
         break;
 #endif /* TARGET_NR_getdents64 */
-#if defined(TARGET_NR__newselect) || defined(TARGET_S390X)
-#ifdef TARGET_S390X
-    case TARGET_NR_select:
-#else
+#if defined(TARGET_NR__newselect)
     case TARGET_NR__newselect:
-#endif
         ret = do_select(arg1, arg2, arg3, arg4, arg5);
         break;
 #endif
commit 2ba7f73006371312109991869b13bf8f4b4659c4
Author: Laurent Vivier <laurent at vivier.eu>
Date:   Thu Jan 10 21:42:48 2013 +0100

    alpha-linux-user: Translate fcntl l_type
    
    The values of F_RDLCK, F_WRLCK, F_UNLCK, F_EXLCK, F_SHLCK
    differ between alpha and other linux architectures.
    
    This patch allows to run "dpkg" (database lock).
    
    Signed-off-by: Laurent Vivier <laurent at vivier.eu>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 3167a87..94f79dd 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4512,6 +4512,16 @@ static int target_to_host_fcntl_cmd(int cmd)
     return -TARGET_EINVAL;
 }
 
+#define TRANSTBL_CONVERT(a) { -1, TARGET_##a, -1, a }
+static const bitmask_transtbl flock_tbl[] = {
+    TRANSTBL_CONVERT(F_RDLCK),
+    TRANSTBL_CONVERT(F_WRLCK),
+    TRANSTBL_CONVERT(F_UNLCK),
+    TRANSTBL_CONVERT(F_EXLCK),
+    TRANSTBL_CONVERT(F_SHLCK),
+    { 0, 0, 0, 0 }
+};
+
 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
 {
     struct flock fl;
@@ -4528,7 +4538,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
     case TARGET_F_GETLK:
         if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
             return -TARGET_EFAULT;
-        fl.l_type = tswap16(target_fl->l_type);
+        fl.l_type =
+                  target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
         fl.l_whence = tswap16(target_fl->l_whence);
         fl.l_start = tswapal(target_fl->l_start);
         fl.l_len = tswapal(target_fl->l_len);
@@ -4538,7 +4549,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
         if (ret == 0) {
             if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
                 return -TARGET_EFAULT;
-            target_fl->l_type = tswap16(fl.l_type);
+            target_fl->l_type =
+                          host_to_target_bitmask(tswap16(fl.l_type), flock_tbl);
             target_fl->l_whence = tswap16(fl.l_whence);
             target_fl->l_start = tswapal(fl.l_start);
             target_fl->l_len = tswapal(fl.l_len);
@@ -4551,7 +4563,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
     case TARGET_F_SETLKW:
         if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
             return -TARGET_EFAULT;
-        fl.l_type = tswap16(target_fl->l_type);
+        fl.l_type =
+                  target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
         fl.l_whence = tswap16(target_fl->l_whence);
         fl.l_start = tswapal(target_fl->l_start);
         fl.l_len = tswapal(target_fl->l_len);
@@ -4563,7 +4576,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
     case TARGET_F_GETLK64:
         if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
             return -TARGET_EFAULT;
-        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
+        fl64.l_type =
+           target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
         fl64.l_whence = tswap16(target_fl64->l_whence);
         fl64.l_start = tswap64(target_fl64->l_start);
         fl64.l_len = tswap64(target_fl64->l_len);
@@ -4573,7 +4587,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
         if (ret == 0) {
             if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
                 return -TARGET_EFAULT;
-            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
+            target_fl64->l_type =
+                   host_to_target_bitmask(tswap16(fl64.l_type), flock_tbl) >> 1;
             target_fl64->l_whence = tswap16(fl64.l_whence);
             target_fl64->l_start = tswap64(fl64.l_start);
             target_fl64->l_len = tswap64(fl64.l_len);
@@ -4585,7 +4600,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
     case TARGET_F_SETLKW64:
         if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
             return -TARGET_EFAULT;
-        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
+        fl64.l_type =
+           target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
         fl64.l_whence = tswap16(target_fl64->l_whence);
         fl64.l_start = tswap64(target_fl64->l_start);
         fl64.l_len = tswap64(target_fl64->l_len);
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index f8f5539..92c01a9 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -2017,6 +2017,12 @@ struct target_statfs64 {
 #define TARGET_F_SETLKW        9
 #define TARGET_F_SETOWN        5       /*  for sockets. */
 #define TARGET_F_GETOWN        6       /*  for sockets. */
+
+#define TARGET_F_RDLCK         1
+#define TARGET_F_WRLCK         2
+#define TARGET_F_UNLCK         8
+#define TARGET_F_EXLCK         16
+#define TARGET_F_SHLCK         32
 #elif defined(TARGET_MIPS)
 #define TARGET_F_GETLK         14
 #define TARGET_F_SETLK         6
@@ -2031,6 +2037,18 @@ struct target_statfs64 {
 #define TARGET_F_GETOWN        9       /*  for sockets. */
 #endif
 
+#ifndef TARGET_F_RDLCK
+#define TARGET_F_RDLCK         0
+#define TARGET_F_WRLCK         1
+#define TARGET_F_UNLCK         2
+#endif
+
+#ifndef TARGET_F_EXLCK
+#define TARGET_F_EXLCK         4
+#define TARGET_F_SHLCK         8
+#endif
+
+
 #define TARGET_F_SETSIG        10      /*  for sockets. */
 #define TARGET_F_GETSIG        11      /*  for sockets. */
 


More information about the Spice-commits mailing list