[Spice-commits] 431 commits - .gitignore MAINTAINERS Makefile Makefile.objs Makefile.target QMP/qmp-events.txt QMP/qmp-shell VERSION arch_init.c audio/audio_win_int.c audio/ossaudio.c backends/baum.c backends/msmouse.c backends/rng-random.c block.c block/Makefile.objs block/blkdebug.c block/curl.c block/mirror.c block/qapi.c block/sheepdog.c block/snapshot.c block/vmdk.c block/win32-aio.c blockdev.c bsd-user/main.c cmd.c cmd.h configure cpu-exec.c cpus.c cputlb.c default-configs/pci.mak default-configs/ppc-softmmu.mak default-configs/ppc64-softmmu.mak default-configs/ppcemb-softmmu.mak device_tree.c dma-helpers.c docs/migration.txt docs/tracing.txt dump-stub.c dump.c exec.c fpu/softfloat-macros.h gdbstub.c hmp-commands.hx hmp.c hmp.h hw/9pfs hw/acpi hw/arm hw/audio hw/block hw/char hw/core hw/display hw/dma hw/i2c hw/i386 hw/ide hw/input hw/intc hw/isa hw/microblaze hw/mips hw/misc hw/net hw/nvram hw/pci hw/pci-bridge hw/pci-host hw/ppc hw/s390x hw/scsi hw/sd hw/sparc hw/sparc64 hw/ ssi hw/timer hw/usb hw/virtio hw/watchdog hw/xen include/block include/elf.h include/exec include/hw include/libfdt_env.h include/qapi include/qemu include/qemu-common.h include/qemu-io.h include/qom include/sysemu include/ui kvm-all.c kvm-stub.c libcacard/vscclient.c linux-headers/asm-arm linux-headers/asm-mips linux-headers/asm-powerpc linux-headers/asm-x86 linux-headers/linux linux-user/main.c linux-user/signal.c linux-user/syscall.c main-loop.c memory.c memory_mapping-stub.c memory_mapping.c migration.c monitor.c net/tap-bsd.c net/tap.c page_cache.c pc-bios/bios.bin pc-bios/qemu_logo_no_text.svg pc-bios/s390-ccw po/hu.po qapi-schema-test.json qapi-schema.json qemu-char.c qemu-coroutine-lock.c qemu-coroutine.c qemu-doc.texi qemu-img.c qemu-io-cmds.c qemu-io.c qemu-options.hx qemu-seccomp.c qga/commands-posix.c qga/main.c qga/service-win32.c qga/service-win32.h qmp-commands.hx qobject/json-parser.c qom/cpu.c qom/object.c roms/configure-seabios.sh roms/seabios savevm.c scri pts/create_config scripts/qapi-types.py scripts/qapi-visit.py scripts/qapi.py scripts/tracetool.py slirp/misc.c slirp/misc.h spice-qemu-char.c stubs/Makefile.objs stubs/dump.c target-arm/kvm.c target-arm/translate.c target-i386/arch_memory_mapping.c target-i386/cc_helper.c target-i386/cpu-qom.h target-i386/cpu.c target-i386/cpu.h target-i386/excp_helper.c target-i386/int_helper.c target-i386/mem_helper.c target-i386/misc_helper.c target-i386/seg_helper.c target-i386/smm_helper.c target-i386/svm_helper.c target-i386/translate.c target-mips/cpu.h target-mips/dsp_helper.c target-mips/helper.c target-moxie/helper.c target-ppc/kvm.c target-s390x/cpu.h target-s390x/kvm.c target-s390x/mem_helper.c target-sparc/cpu.c target-unicore32/translate.c tcg/aarch64 tcg/arm tcg/i386 tcg/ppc64 tcg/s390 tests/Makefile tests/ide-test.c tests/qemu-iotests tests/tcg tests/test-qmp-input-visitor.c tests/test-qmp-output-visitor.c tests/test-visitor-serialization.c trace-events translate-all.c ui/co coa.m ui/console.c ui/gtk.c ui/input.c ui/vnc.c user-exec.c util/Makefile.objs util/cutils.c util/error.c util/hexdump.c util/iov.c util/oslib-posix.c util/oslib-win32.c util/qemu-openpty.c vl.c xen-all.c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Mon Jun 17 23:19:33 PDT 2013


 .gitignore                               |    1 
 MAINTAINERS                              |   37 
 Makefile                                 |   25 
 Makefile.objs                            |    1 
 Makefile.target                          |   36 
 QMP/qmp-events.txt                       |    3 
 QMP/qmp-shell                            |    2 
 VERSION                                  |    2 
 arch_init.c                              |    9 
 audio/audio_win_int.c                    |    1 
 audio/ossaudio.c                         |    4 
 backends/baum.c                          |    2 
 backends/msmouse.c                       |    1 
 backends/rng-random.c                    |    3 
 block.c                                  |  368 -----
 block/Makefile.objs                      |    1 
 block/blkdebug.c                         |    3 
 block/curl.c                             |   12 
 block/mirror.c                           |    2 
 block/qapi.c                             |  470 ++++++
 block/sheepdog.c                         |   14 
 block/snapshot.c                         |  157 ++
 block/vmdk.c                             |   34 
 block/win32-aio.c                        |    1 
 blockdev.c                               |  297 ++--
 bsd-user/main.c                          |    6 
 cmd.c                                    |  612 --------
 cmd.h                                    |   79 -
 configure                                |  286 +---
 cpu-exec.c                               |    4 
 cpus.c                                   |    4 
 cputlb.c                                 |   35 
 default-configs/pci.mak                  |    1 
 default-configs/ppc-softmmu.mak          |    2 
 default-configs/ppc64-softmmu.mak        |    4 
 default-configs/ppcemb-softmmu.mak       |    2 
 device_tree.c                            |    2 
 dma-helpers.c                            |    5 
 docs/migration.txt                       |   17 
 docs/tracing.txt                         |    2 
 dump-stub.c                              |   36 
 dump.c                                   |   14 
 exec.c                                   |  483 +++----
 fpu/softfloat-macros.h                   |    2 
 gdbstub.c                                |    7 
 hmp-commands.hx                          |   20 
 hmp.c                                    |   39 
 hmp.h                                    |    1 
 hw/9pfs/cofile.c                         |    4 
 hw/9pfs/virtio-9p-local.c                |   50 
 hw/9pfs/virtio-9p.c                      |    2 
 hw/acpi/piix4.c                          |   14 
 hw/arm/boot.c                            |    7 
 hw/arm/exynos4210.c                      |   28 
 hw/arm/highbank.c                        |    1 
 hw/arm/xilinx_zynq.c                     |    2 
 hw/audio/adlib.c                         |   23 
 hw/audio/cs4231a.c                       |   38 
 hw/audio/gus.c                           |   27 
 hw/audio/intel-hda.c                     |   40 
 hw/audio/marvell_88w8618.c               |    1 
 hw/audio/pcspk.c                         |   19 
 hw/audio/sb16.c                          |   21 
 hw/block/Makefile.objs                   |    1 
 hw/block/fdc.c                           |   40 
 hw/block/m25p80.c                        |    1 
 hw/block/nvme.c                          |  885 ++++++++++++
 hw/block/nvme.h                          |  711 ++++++++++
 hw/block/pc_sysfw.c                      |   62 
 hw/block/pflash_cfi01.c                  |    6 
 hw/block/pflash_cfi02.c                  |    2 
 hw/block/xen_disk.c                      |    8 
 hw/char/debugcon.c                       |   27 
 hw/char/parallel.c                       |   29 
 hw/char/serial-isa.c                     |   34 
 hw/char/serial-pci.c                     |   17 
 hw/char/serial.c                         |  150 --
 hw/core/loader.c                         |    2 
 hw/core/qdev.c                           |   10 
 hw/display/cirrus_vga.c                  |   13 
 hw/display/tcx.c                         |   10 
 hw/display/vga-isa.c                     |   17 
 hw/dma/i82374.c                          |   13 
 hw/dma/pl330.c                           |    4 
 hw/dma/xilinx_axidma.c                   |    3 
 hw/i2c/core.c                            |    4 
 hw/i386/kvm/i8254.c                      |   59 
 hw/i386/kvm/i8259.c                      |   34 
 hw/i386/kvm/pci-assign.c                 |   18 
 hw/i386/multiboot.c                      |    2 
 hw/i386/multiboot.h                      |    4 
 hw/i386/pc.c                             |   57 
 hw/i386/pc_piix.c                        |   38 
 hw/i386/pc_q35.c                         |   16 
 hw/i386/smbios.c                         |   57 
 hw/i386/xen_machine_pv.c                 |   16 
 hw/ide/core.c                            |    1 
 hw/ide/isa.c                             |   16 
 hw/ide/macio.c                           |    2 
 hw/input/pckbd.c                         |   29 
 hw/input/vmmouse.c                       |    8 
 hw/intc/Makefile.objs                    |    2 
 hw/intc/apic.c                           |   42 
 hw/intc/i8259.c                          |   48 
 hw/intc/i8259_common.c                   |   34 
 hw/intc/sbi.c                            |  156 --
 hw/intc/sun4c_intctl.c                   |  208 ---
 hw/intc/xilinx_intc.c                    |    6 
 hw/isa/i82378.c                          |    4 
 hw/isa/isa-bus.c                         |   25 
 hw/isa/pc87312.c                         |   12 
 hw/isa/piix4.c                           |    2 
 hw/isa/vt82c686.c                        |    2 
 hw/microblaze/boot.c                     |   12 
 hw/mips/mips_malta.c                     |    1 
 hw/misc/applesmc.c                       |   10 
 hw/misc/debugexit.c                      |   10 
 hw/misc/ivshmem.c                        |    1 
 hw/misc/lm32_sys.c                       |    1 
 hw/misc/pc-testdev.c                     |   11 
 hw/misc/pvpanic.c                        |   23 
 hw/misc/sga.c                            |    7 
 hw/misc/vmport.c                         |   10 
 hw/net/ne2000-isa.c                      |   15 
 hw/net/rtl8139.c                         |    3 
 hw/net/virtio-net.c                      |  144 +-
 hw/net/vmxnet3.c                         |    2 
 hw/net/xilinx_axienet.c                  |    2 
 hw/nvram/fw_cfg.c                        |   22 
 hw/nvram/mac_nvram.c                     |    2 
 hw/pci-bridge/Makefile.objs              |    2 
 hw/pci-bridge/dec.c                      |  156 ++
 hw/pci-bridge/dec.h                      |   10 
 hw/pci-host/Makefile.objs                |    1 
 hw/pci-host/dec.c                        |  156 --
 hw/pci-host/dec.h                        |   10 
 hw/pci-host/q35.c                        |    1 
 hw/pci-host/versatile.c                  |   85 +
 hw/pci/msix.c                            |   33 
 hw/pci/pci.c                             |    4 
 hw/ppc/ppc440_bamboo.c                   |    2 
 hw/ppc/prep.c                            |    7 
 hw/ppc/spapr.c                           |    2 
 hw/ppc/spapr_hcall.c                     |    1 
 hw/ppc/spapr_rtas.c                      |   28 
 hw/ppc/spapr_vio.c                       |    6 
 hw/ppc/virtex_ml507.c                    |   18 
 hw/s390x/css.c                           |    2 
 hw/s390x/s390-virtio-bus.c               |    3 
 hw/s390x/virtio-ccw.c                    |   11 
 hw/scsi/megasas.c                        |    1 
 hw/scsi/vmw_pvscsi.c                     |    2 
 hw/sd/sd.c                               |   11 
 hw/sd/sdhci.c                            |   28 
 hw/sparc/sun4m.c                         |  467 ------
 hw/sparc64/sun4u.c                       |    7 
 hw/ssi/ssi.c                             |    2 
 hw/ssi/xilinx_spips.c                    |  320 +++-
 hw/timer/Makefile.objs                   |    3 
 hw/timer/exynos4210_mct.c                |    1 
 hw/timer/exynos4210_rtc.c                |    1 
 hw/timer/i8254.c                         |   28 
 hw/timer/i8254_common.c                  |   19 
 hw/timer/imx_epit.c                      |  432 ++++++
 hw/timer/imx_gpt.c                       |  465 ++++++
 hw/timer/imx_timer.c                     |  823 ------------
 hw/timer/m48t59.c                        |   22 
 hw/timer/mc146818rtc.c                   |   18 
 hw/usb/core.c                            |    2 
 hw/usb/hcd-xhci.c                        |  228 +++
 hw/usb/host-libusb.c                     |    2 
 hw/virtio/virtio-bus.c                   |   20 
 hw/virtio/virtio-pci.c                   |    9 
 hw/watchdog/wdt_ib700.c                  |    8 
 hw/xen/xen_pt_config_init.c              |    4 
 include/block/block.h                    |   34 
 include/block/block_int.h                |    1 
 include/block/coroutine_int.h            |    4 
 include/block/qapi.h                     |   47 
 include/block/snapshot.h                 |   53 
 include/elf.h                            |  129 +
 include/exec/cpu-common.h                |    6 
 include/exec/cpu-defs.h                  |    2 
 include/exec/cputlb.h                    |   12 
 include/exec/exec-all.h                  |   11 
 include/exec/memory-internal.h           |    6 
 include/exec/memory.h                    |  118 +
 include/exec/poison.h                    |    1 
 include/exec/softmmu_template.h          |   36 
 include/hw/audio/pcspk.h                 |   14 
 include/hw/char/serial.h                 |   17 
 include/hw/i386/pc.h                     |   84 -
 include/hw/i386/smbios.h                 |    2 
 include/hw/isa/i8259_internal.h          |    2 
 include/hw/isa/isa.h                     |   11 
 include/hw/loader.h                      |    3 
 include/hw/nvram/fw_cfg.h                |    4 
 include/hw/nvram/openbios_firmware_abi.h |   73 +
 include/hw/pci/msix.h                    |   11 
 include/hw/pci/pci_ids.h                 |    1 
 include/hw/qdev-core.h                   |    2 
 include/hw/sparc/firmware_abi.h          |   73 -
 include/hw/timer/i8254.h                 |   31 
 include/hw/timer/i8254_internal.h        |    1 
 include/hw/timer/mc146818rtc.h           |    1 
 include/hw/virtio/virtio-net.h           |   17 
 include/hw/xen/xen.h                     |    5 
 include/libfdt_env.h                     |   36 
 include/qapi/error.h                     |    5 
 include/qapi/qmp/qerror.h                |    3 
 include/qapi/qmp/qlist.h                 |    1 
 include/qapi/visitor.h                   |    5 
 include/qemu-common.h                    |   29 
 include/qemu-io.h                        |   46 
 include/qemu/config-file.h               |    1 
 include/qemu/error-report.h              |    1 
 include/qemu/log.h                       |    3 
 include/qemu/osdep.h                     |   11 
 include/qemu/typedefs.h                  |    3 
 include/qom/cpu.h                        |   23 
 include/sysemu/char.h                    |    2 
 include/sysemu/dma.h                     |    3 
 include/sysemu/kvm.h                     |   10 
 include/sysemu/memory_mapping.h          |   16 
 include/ui/console.h                     |    2 
 kvm-all.c                                |   44 
 kvm-stub.c                               |    1 
 libcacard/vscclient.c                    |    9 
 linux-headers/asm-arm/kvm.h              |   12 
 linux-headers/asm-mips/kvm.h             |  138 ++
 linux-headers/asm-mips/kvm_para.h        |    1 
 linux-headers/asm-powerpc/kvm.h          |   89 +
 linux-headers/asm-x86/kvm.h              |    1 
 linux-headers/linux/kvm.h                |   42 
 linux-headers/linux/vfio.h               |    1 
 linux-headers/linux/vhost.h              |   28 
 linux-user/main.c                        |    6 
 linux-user/signal.c                      |   16 
 linux-user/syscall.c                     |  285 +---
 main-loop.c                              |   43 
 memory.c                                 |  279 ++--
 memory_mapping-stub.c                    |   33 
 memory_mapping.c                         |   17 
 migration.c                              |    6 
 monitor.c                                |   32 
 net/tap-bsd.c                            |    3 
 net/tap.c                                |   18 
 page_cache.c                             |    1 
 pc-bios/bios.bin                         |binary
 pc-bios/qemu_logo_no_text.svg            |  976 ++++++++++++++
 pc-bios/s390-ccw/virtio.c                |    5 
 po/hu.po                                 |   63 
 qapi-schema-test.json                    |   15 
 qapi-schema.json                         |   63 
 qemu-char.c                              |  148 --
 qemu-coroutine-lock.c                    |   56 
 qemu-coroutine.c                         |   23 
 qemu-doc.texi                            |   10 
 qemu-img.c                               |  179 --
 qemu-io-cmds.c                           | 2118 +++++++++++++++++++++++++++++++
 qemu-io.c                                | 1954 ++--------------------------
 qemu-options.hx                          |    7 
 qemu-seccomp.c                           |    5 
 qga/commands-posix.c                     |   25 
 qga/main.c                               |   57 
 qga/service-win32.c                      |   25 
 qga/service-win32.h                      |    3 
 qmp-commands.hx                          |   69 -
 qobject/json-parser.c                    |   26 
 qom/cpu.c                                |   29 
 qom/object.c                             |    4 
 roms/configure-seabios.sh                |    2 
 roms/seabios                             |    2 
 savevm.c                                 |   50 
 scripts/create_config                    |   26 
 scripts/qapi-types.py                    |   53 
 scripts/qapi-visit.py                    |   36 
 scripts/qapi.py                          |   23 
 scripts/tracetool.py                     |   18 
 slirp/misc.c                             |    2 
 slirp/misc.h                             |   14 
 spice-qemu-char.c                        |    1 
 stubs/Makefile.objs                      |    1 
 stubs/dump.c                             |   28 
 target-arm/kvm.c                         |    4 
 target-arm/translate.c                   |  782 +++++------
 target-i386/arch_memory_mapping.c        |   28 
 target-i386/cc_helper.c                  |    2 
 target-i386/cpu-qom.h                    |    3 
 target-i386/cpu.c                        |   26 
 target-i386/cpu.h                        |   24 
 target-i386/excp_helper.c                |    2 
 target-i386/int_helper.c                 |   78 -
 target-i386/mem_helper.c                 |   18 
 target-i386/misc_helper.c                |   77 -
 target-i386/seg_helper.c                 |  180 +-
 target-i386/smm_helper.c                 |   64 
 target-i386/svm_helper.c                 |   60 
 target-i386/translate.c                  |   30 
 target-mips/cpu.h                        |    1 
 target-mips/dsp_helper.c                 |   36 
 target-mips/helper.c                     |    4 
 target-moxie/helper.c                    |    2 
 target-ppc/kvm.c                         |    6 
 target-s390x/cpu.h                       |    5 
 target-s390x/kvm.c                       |    4 
 target-s390x/mem_helper.c                |    1 
 target-sparc/cpu.c                       |  124 -
 target-unicore32/translate.c             |    1 
 tcg/aarch64/tcg-target.c                 | 1404 ++++++++++++++++++++
 tcg/aarch64/tcg-target.h                 |   99 +
 tcg/arm/tcg-target.c                     |    6 
 tcg/i386/tcg-target.c                    |    6 
 tcg/ppc64/tcg-target.c                   |   29 
 tcg/s390/tcg-target.c                    |    7 
 tests/Makefile                           |    5 
 tests/ide-test.c                         |   78 +
 tests/qemu-iotests/030                   |   99 -
 tests/qemu-iotests/041                   |  181 --
 tests/qemu-iotests/049.out               |    8 
 tests/qemu-iotests/054                   |   58 
 tests/qemu-iotests/054.out               |   10 
 tests/qemu-iotests/check                 |    3 
 tests/qemu-iotests/common.rc             |    2 
 tests/qemu-iotests/group                 |    1 
 tests/qemu-iotests/iotests.py            |   38 
 tests/qemu-iotests/qcow2.py              |   17 
 tests/tcg/linux-test.c                   |    1 
 tests/tcg/mips/mips32-dsp/extp.c         |   18 
 tests/tcg/mips/mips32-dsp/extpdp.c       |   18 
 tests/test-qmp-input-visitor.c           |  358 +++++
 tests/test-qmp-output-visitor.c          |  337 ++++
 tests/test-visitor-serialization.c       |  485 ++++++-
 trace-events                             |    7 
 translate-all.c                          |   11 
 ui/cocoa.m                               |   52 
 ui/console.c                             |    4 
 ui/gtk.c                                 |   30 
 ui/input.c                               |   13 
 ui/vnc.c                                 |    3 
 user-exec.c                              |   15 
 util/Makefile.objs                       |    2 
 util/cutils.c                            |   25 
 util/error.c                             |    5 
 util/hexdump.c                           |    2 
 util/iov.c                               |    2 
 util/oslib-posix.c                       |    9 
 util/oslib-win32.c                       |   22 
 util/qemu-openpty.c                      |  135 +
 vl.c                                     |   27 
 xen-all.c                                |   43 
 351 files changed, 15030 insertions(+), 8550 deletions(-)

New commits:
commit 21a885a7e2a0f532f7653a2607efddbd83504430
Merge: 128dc2d dbfbc63
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Jun 17 13:14:46 2013 -0500

    Merge remote-tracking branch 'luiz/queue/qmp' into staging
    
    # By Luiz Capitulino
    # Via Luiz Capitulino
    * luiz/queue/qmp:
      qerror: drop QERR_OPEN_FILE_FAILED macro
      block: bdrv_reopen_prepare(): don't use QERR_OPEN_FILE_FAILED
      savevm: qmp_xen_save_devices_state(): use error_setg_file_open()
      dump: qmp_dump_guest_memory(): use error_setg_file_open()
      cpus: use error_setg_file_open()
      blockdev: use error_setg_file_open()
      block: mirror_complete(): use error_setg_file_open()
      rng-random: use error_setg_file_open()
      error: add error_setg_file_open() helper
    
    Message-id: 1371484631-29510-1-git-send-email-lcapitulino at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 128dc2d1e4cb98ddbe9c0df2e0c914dc00925dac
Merge: 5d71bbc 0bed087
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Jun 17 13:14:13 2013 -0500

    Merge remote-tracking branch 'kwolf/for-anthony' into staging
    
    # By Liu Yuan (2) and others
    # Via Kevin Wolf
    * kwolf/for-anthony:
      vmdk: Allow reading variable size descriptor files
      NVMe: Initial commit for new storage interface
      curl: Don't set curl options on the handle just before it's going to be deleted.
      vmdk: byteswap VMDK4Header.desc_offset field
      block/curl.c: Refuse to open the handle for writes.
      sheepdog: support 'qemu-img snapshot -a'
      sheepdog: fix snapshot tag initialization
    
    Message-id: 1371486710-17793-1-git-send-email-kwolf at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 5d71bbc5fb076e6d8a37bb3e320d61432b3c2ce0
Merge: 38aea17 d1bdd3a
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Jun 17 13:14:01 2013 -0500

    Merge remote-tracking branch 'rth/fix-ppc64' into staging
    
    # By Anton Blanchard
    # Via Richard Henderson
    * rth/fix-ppc64:
      tcg-ppc64: rotr_i32 rotates wrong amount
      tcg-ppc64: Fix add2_i64
      tcg-ppc64: bswap64 rotates output 32 bits
      tcg-ppc64: Fix RLDCL opcode
    
    Message-id: 1371491129-30246-1-git-send-email-rth at twiddle.net
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit d1bdd3af49f227dd4a4b03b90cb020c55cbed440
Author: Anton Blanchard <anton at samba.org>
Date:   Sun Jun 2 22:30:18 2013 +1000

    tcg-ppc64: rotr_i32 rotates wrong amount
    
    rotr_i32 calculates the amount to left shift and puts it into a
    temporary, but then doesn't use it when doing the shift.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Anton Blanchard <anton at samba.org>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index 5cdff36..606b73d 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -1662,7 +1662,7 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args,
             tcg_out_rlw(s, RLWINM, args[0], args[1], 32 - args[2], 0, 31);
         } else {
             tcg_out32(s, SUBFIC | TAI(0, args[2], 32));
-            tcg_out32(s, RLWNM | SAB(args[1], args[0], args[2])
+            tcg_out32(s, RLWNM | SAB(args[1], args[0], 0)
                          | MB(0) | ME(31));
         }
         break;
commit 84247357104044b8c4ec4a634e84769f432cbe52
Author: Anton Blanchard <anton at samba.org>
Date:   Sun Jun 2 22:29:39 2013 +1000

    tcg-ppc64: Fix add2_i64
    
    add2_i64 was adding the lower double word to the upper double word
    of each input. Fix this so we add the lower double words, then the
    upper double words with carry propagation.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Anton Blanchard <anton at samba.org>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index 1d06530..5cdff36 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -1959,18 +1959,18 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args,
            environment.  So in 64-bit mode it's always carry-out of bit 63.
            The fallback code using deposit works just as well for 32-bit.  */
         a0 = args[0], a1 = args[1];
-        if (a0 == args[4] || (!const_args[5] && a0 == args[5])) {
+        if (a0 == args[3] || (!const_args[5] && a0 == args[5])) {
             a0 = TCG_REG_R0;
         }
-        if (const_args[3]) {
-            tcg_out32(s, ADDIC | TAI(a0, args[2], args[3]));
+        if (const_args[4]) {
+            tcg_out32(s, ADDIC | TAI(a0, args[2], args[4]));
         } else {
-            tcg_out32(s, ADDC | TAB(a0, args[2], args[3]));
+            tcg_out32(s, ADDC | TAB(a0, args[2], args[4]));
         }
         if (const_args[5]) {
-            tcg_out32(s, (args[5] ? ADDME : ADDZE) | RT(a1) | RA(args[4]));
+            tcg_out32(s, (args[5] ? ADDME : ADDZE) | RT(a1) | RA(args[3]));
         } else {
-            tcg_out32(s, ADDE | TAB(a1, args[4], args[5]));
+            tcg_out32(s, ADDE | TAB(a1, args[3], args[5]));
         }
         if (a0 != args[0]) {
             tcg_out_mov(s, TCG_TYPE_I64, args[0], a0);
@@ -2148,7 +2148,7 @@ static const TCGTargetOpDef ppc_op_defs[] = {
     { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
     { INDEX_op_deposit_i64, { "r", "0", "rZ" } },
 
-    { INDEX_op_add2_i64, { "r", "r", "r", "rI", "r", "rZM" } },
+    { INDEX_op_add2_i64, { "r", "r", "r", "r", "rI", "rZM" } },
     { INDEX_op_sub2_i64, { "r", "r", "rI", "r", "rZM", "r" } },
     { INDEX_op_muls2_i64, { "r", "r", "r", "r" } },
     { INDEX_op_mulu2_i64, { "r", "r", "r", "r" } },
commit 82e0f9170ac9307de4fc15bfb4d12d5534550322
Author: Anton Blanchard <anton at samba.org>
Date:   Sun Jun 2 22:28:27 2013 +1000

    tcg-ppc64: bswap64 rotates output 32 bits
    
    If our input and output is in the same register, bswap64 tries to
    undo a rotate of the input. This just ends up rotating the output.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Anton Blanchard <anton at samba.org>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index c7c0b8f..1d06530 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -1923,8 +1923,6 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args,
 
         if (a0 == 0) {
             tcg_out_mov(s, TCG_TYPE_I64, args[0], a0);
-            /* Revert the source rotate that we performed above.  */
-            tcg_out_rld(s, RLDICL, a1, a1, 32, 0);
         }
         break;
 
commit 8a94cfb05ea9a8991c832236b4174d354025a7b7
Author: Anton Blanchard <anton at samba.org>
Date:   Tue Jun 11 21:19:35 2013 +1000

    tcg-ppc64: Fix RLDCL opcode
    
    The rldcl instruction doesn't have an sh field, so the minor opcode
    is shifted 1 bit. We were using the XO30 macro which shifted the
    minor opcode 2 bits.
    
    Remove XO30 and add MD30 and MDS30 macros which match the
    Power ISA categories.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Anton Blanchard <anton at samba.org>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index 0fcf2b5..c7c0b8f 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -308,7 +308,8 @@ static int tcg_target_const_match (tcg_target_long val,
 
 #define OPCD(opc) ((opc)<<26)
 #define XO19(opc) (OPCD(19)|((opc)<<1))
-#define XO30(opc) (OPCD(30)|((opc)<<2))
+#define MD30(opc) (OPCD(30)|((opc)<<2))
+#define MDS30(opc) (OPCD(30)|((opc)<<1))
 #define XO31(opc) (OPCD(31)|((opc)<<1))
 #define XO58(opc) (OPCD(58)|(opc))
 #define XO62(opc) (OPCD(62)|(opc))
@@ -354,10 +355,10 @@ static int tcg_target_const_match (tcg_target_long val,
 #define RLWINM OPCD( 21)
 #define RLWNM  OPCD( 23)
 
-#define RLDICL XO30(  0)
-#define RLDICR XO30(  1)
-#define RLDIMI XO30(  3)
-#define RLDCL  XO30(  8)
+#define RLDICL MD30(  0)
+#define RLDICR MD30(  1)
+#define RLDIMI MD30(  3)
+#define RLDCL  MDS30( 8)
 
 #define BCLR   XO19( 16)
 #define BCCTR  XO19(528)
commit 0bed087df24c7b3fae366f239b9d150de3309416
Author: Evgeny Budilovsky <evgeny.budilovsky at ravellosystems.com>
Date:   Wed Jun 12 14:06:30 2013 +0300

    vmdk: Allow reading variable size descriptor files
    
    the hard-coded 2k buffer on the stack won't allow reading big descriptor
    files which can be generated when storing big images. For example 500G
    vmdk splitted to 2G chunks.
    
    Signed-off-by: Evgeny Budilovsky <evgeny.budilovsky at ravellosystems.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vmdk.c b/block/vmdk.c
index ee50a73..65ae011 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -722,27 +722,40 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
                                int64_t desc_offset)
 {
     int ret;
-    char buf[2048];
+    char *buf = NULL;
     char ct[128];
     BDRVVmdkState *s = bs->opaque;
+    int64_t size;
 
-    ret = bdrv_pread(bs->file, desc_offset, buf, sizeof(buf));
+    size = bdrv_getlength(bs->file);
+    if (size < 0) {
+        return -EINVAL;
+    }
+
+    size = MIN(size, 1 << 20);  /* avoid unbounded allocation */
+    buf = g_malloc0(size + 1);
+
+    ret = bdrv_pread(bs->file, desc_offset, buf, size);
     if (ret < 0) {
-        return ret;
+        goto exit;
     }
-    buf[2047] = '\0';
     if (vmdk_parse_description(buf, "createType", ct, sizeof(ct))) {
-        return -EMEDIUMTYPE;
+        ret = -EMEDIUMTYPE;
+        goto exit;
     }
     if (strcmp(ct, "monolithicFlat") &&
         strcmp(ct, "twoGbMaxExtentSparse") &&
         strcmp(ct, "twoGbMaxExtentFlat")) {
         fprintf(stderr,
                 "VMDK: Not supported image type \"%s\""".\n", ct);
-        return -ENOTSUP;
+        ret = -ENOTSUP;
+        goto exit;
     }
     s->desc_offset = 0;
-    return vmdk_parse_extents(buf, bs, bs->file->filename);
+    ret = vmdk_parse_extents(buf, bs, bs->file->filename);
+exit:
+    g_free(buf);
+    return ret;
 }
 
 static int vmdk_open(BlockDriverState *bs, QDict *options, int flags)
commit f3c507adcd7b00a08f2075afb6012f791ba9aec5
Author: Keith Busch <keith.busch at intel.com>
Date:   Tue Jun 4 09:17:10 2013 -0600

    NVMe: Initial commit for new storage interface
    
    Initial commit for emulated Non-Volatile-Memory Express (NVMe) pci
    storage device.
    
    NVMe is an open, industry driven storage specification defining
    an optimized register and command set designed to deliver the full
    capabilities of non-volatile memory on PCIe SSDs. Further information
    may be found on the organizations website at:
    
    http://www.nvmexpress.org/
    
    This commit implements the minimum from the specification to work with
    existing drivers.
    
    Cc: Keith Busch <keith.busch at gmail.com>
    Signed-off-by: Keith Busch <keith.busch at intel.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/MAINTAINERS b/MAINTAINERS
index 3412b07..a015f68 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -609,6 +609,11 @@ S: Supported
 F: hw/char/virtio-serial-bus.c
 F: hw/char/virtio-console.c
 
+nvme
+M: Keith Busch <keith.busch at intel.com>
+S: Supported
+F: hw/block/nvme*
+
 Xilinx EDK
 M: Peter Crosthwaite <peter.crosthwaite at petalogix.com>
 M: Edgar E. Iglesias <edgar.iglesias at gmail.com>
diff --git a/default-configs/pci.mak b/default-configs/pci.mak
index d557eab..91b1e92 100644
--- a/default-configs/pci.mak
+++ b/default-configs/pci.mak
@@ -29,3 +29,4 @@ CONFIG_SERIAL_PCI=y
 CONFIG_IPACK=y
 CONFIG_WDT_IB6300ESB=y
 CONFIG_PCI_TESTDEV=y
+CONFIG_NVME_PCI=y
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
index e4329a0..25acc67 100644
--- a/hw/block/Makefile.objs
+++ b/hw/block/Makefile.objs
@@ -8,6 +8,7 @@ common-obj-$(CONFIG_XEN_BACKEND) += xen_disk.o
 common-obj-$(CONFIG_ECC) += ecc.o
 common-obj-$(CONFIG_ONENAND) += onenand.o
 common-obj-$(CONFIG_PC_SYSFW) += pc_sysfw.o
+common-obj-$(CONFIG_NVME_PCI) += nvme.o
 
 obj-$(CONFIG_SH4) += tc58128.o
 
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
new file mode 100644
index 0000000..5db941c
--- /dev/null
+++ b/hw/block/nvme.c
@@ -0,0 +1,885 @@
+/*
+ * QEMU NVM Express Controller
+ *
+ * Copyright (c) 2012, Intel Corporation
+ *
+ * Written by Keith Busch <keith.busch at intel.com>
+ *
+ * This code is licensed under the GNU GPL v2 or later.
+ */
+
+/**
+ * Reference Specs: http://www.nvmexpress.org, 1.1, 1.0e
+ *
+ *  http://www.nvmexpress.org/resources/
+ */
+
+/**
+ * Usage: add options:
+ *      -drive file=<file>,if=none,id=<drive_id>
+ *      -device nvme,drive=<drive_id>,serial=<serial>,id=<id[optional]>
+ */
+
+#include <hw/block/block.h>
+#include <hw/hw.h>
+#include <hw/pci/msix.h>
+#include <hw/pci/pci.h>
+
+#include "nvme.h"
+
+static void nvme_process_sq(void *opaque);
+
+static int nvme_check_sqid(NvmeCtrl *n, uint16_t sqid)
+{
+    return sqid < n->num_queues && n->sq[sqid] != NULL ? 0 : -1;
+}
+
+static int nvme_check_cqid(NvmeCtrl *n, uint16_t cqid)
+{
+    return cqid < n->num_queues && n->cq[cqid] != NULL ? 0 : -1;
+}
+
+static void nvme_inc_cq_tail(NvmeCQueue *cq)
+{
+    cq->tail++;
+    if (cq->tail >= cq->size) {
+        cq->tail = 0;
+        cq->phase = !cq->phase;
+    }
+}
+
+static void nvme_inc_sq_head(NvmeSQueue *sq)
+{
+    sq->head = (sq->head + 1) % sq->size;
+}
+
+static uint8_t nvme_cq_full(NvmeCQueue *cq)
+{
+    return (cq->tail + 1) % cq->size == cq->head;
+}
+
+static uint8_t nvme_sq_empty(NvmeSQueue *sq)
+{
+    return sq->head == sq->tail;
+}
+
+static void nvme_isr_notify(NvmeCtrl *n, NvmeCQueue *cq)
+{
+    if (cq->irq_enabled) {
+        if (msix_enabled(&(n->parent_obj))) {
+            msix_notify(&(n->parent_obj), cq->vector);
+        } else {
+            qemu_irq_pulse(n->parent_obj.irq[0]);
+        }
+    }
+}
+
+static uint16_t nvme_map_prp(QEMUSGList *qsg, uint64_t prp1, uint64_t prp2,
+    uint32_t len, NvmeCtrl *n)
+{
+    hwaddr trans_len = n->page_size - (prp1 % n->page_size);
+    trans_len = MIN(len, trans_len);
+    int num_prps = (len >> n->page_bits) + 1;
+
+    if (!prp1) {
+        return NVME_INVALID_FIELD | NVME_DNR;
+    }
+
+    qemu_sglist_init(qsg, num_prps, pci_dma_context(&n->parent_obj));
+    qemu_sglist_add(qsg, prp1, trans_len);
+    len -= trans_len;
+    if (len) {
+        if (!prp2) {
+            goto unmap;
+        }
+        if (len > n->page_size) {
+            uint64_t prp_list[n->max_prp_ents];
+            uint32_t nents, prp_trans;
+            int i = 0;
+
+            nents = (len + n->page_size - 1) >> n->page_bits;
+            prp_trans = MIN(n->max_prp_ents, nents) * sizeof(uint64_t);
+            pci_dma_read(&n->parent_obj, prp2, (void *)prp_list, prp_trans);
+            while (len != 0) {
+                uint64_t prp_ent = le64_to_cpu(prp_list[i]);
+
+                if (i == n->max_prp_ents - 1 && len > n->page_size) {
+                    if (!prp_ent || prp_ent & (n->page_size - 1)) {
+                        goto unmap;
+                    }
+
+                    i = 0;
+                    nents = (len + n->page_size - 1) >> n->page_bits;
+                    prp_trans = MIN(n->max_prp_ents, nents) * sizeof(uint64_t);
+                    pci_dma_read(&n->parent_obj, prp_ent, (void *)prp_list,
+                        prp_trans);
+                    prp_ent = le64_to_cpu(prp_list[i]);
+                }
+
+                if (!prp_ent || prp_ent & (n->page_size - 1)) {
+                    goto unmap;
+                }
+
+                trans_len = MIN(len, n->page_size);
+                qemu_sglist_add(qsg, prp_ent, trans_len);
+                len -= trans_len;
+                i++;
+            }
+        } else {
+            if (prp2 & (n->page_size - 1)) {
+                goto unmap;
+            }
+            qemu_sglist_add(qsg, prp2, len);
+        }
+    }
+    return NVME_SUCCESS;
+
+ unmap:
+    qemu_sglist_destroy(qsg);
+    return NVME_INVALID_FIELD | NVME_DNR;
+}
+
+static uint16_t nvme_dma_read_prp(NvmeCtrl *n, uint8_t *ptr, uint32_t len,
+    uint64_t prp1, uint64_t prp2)
+{
+    QEMUSGList qsg;
+
+    if (nvme_map_prp(&qsg, prp1, prp2, len, n)) {
+        return NVME_INVALID_FIELD | NVME_DNR;
+    }
+    if (dma_buf_read(ptr, len, &qsg)) {
+        qemu_sglist_destroy(&qsg);
+        return NVME_INVALID_FIELD | NVME_DNR;
+    }
+    return NVME_SUCCESS;
+}
+
+static void nvme_post_cqes(void *opaque)
+{
+    NvmeCQueue *cq = opaque;
+    NvmeCtrl *n = cq->ctrl;
+    NvmeRequest *req, *next;
+
+    QTAILQ_FOREACH_SAFE(req, &cq->req_list, entry, next) {
+        NvmeSQueue *sq;
+        hwaddr addr;
+
+        if (nvme_cq_full(cq)) {
+            break;
+        }
+
+        QTAILQ_REMOVE(&cq->req_list, req, entry);
+        sq = req->sq;
+        req->cqe.status = cpu_to_le16((req->status << 1) | cq->phase);
+        req->cqe.sq_id = cpu_to_le16(sq->sqid);
+        req->cqe.sq_head = cpu_to_le16(sq->head);
+        addr = cq->dma_addr + cq->tail * n->cqe_size;
+        nvme_inc_cq_tail(cq);
+        pci_dma_write(&n->parent_obj, addr, (void *)&req->cqe,
+            sizeof(req->cqe));
+        QTAILQ_INSERT_TAIL(&sq->req_list, req, entry);
+    }
+    nvme_isr_notify(n, cq);
+}
+
+static void nvme_enqueue_req_completion(NvmeCQueue *cq, NvmeRequest *req)
+{
+    assert(cq->cqid == req->sq->cqid);
+    QTAILQ_REMOVE(&req->sq->out_req_list, req, entry);
+    QTAILQ_INSERT_TAIL(&cq->req_list, req, entry);
+    qemu_mod_timer(cq->timer, qemu_get_clock_ns(vm_clock) + 500);
+}
+
+static void nvme_rw_cb(void *opaque, int ret)
+{
+    NvmeRequest *req = opaque;
+    NvmeSQueue *sq = req->sq;
+    NvmeCtrl *n = sq->ctrl;
+    NvmeCQueue *cq = n->cq[sq->cqid];
+
+    bdrv_acct_done(n->conf.bs, &req->acct);
+    if (!ret) {
+        req->status = NVME_SUCCESS;
+    } else {
+        req->status = NVME_INTERNAL_DEV_ERROR;
+    }
+
+    qemu_sglist_destroy(&req->qsg);
+    nvme_enqueue_req_completion(cq, req);
+}
+
+static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
+    NvmeRequest *req)
+{
+    NvmeRwCmd *rw = (NvmeRwCmd *)cmd;
+    uint32_t nlb  = le32_to_cpu(rw->nlb) + 1;
+    uint64_t slba = le64_to_cpu(rw->slba);
+    uint64_t prp1 = le64_to_cpu(rw->prp1);
+    uint64_t prp2 = le64_to_cpu(rw->prp2);
+
+    uint8_t lba_index  = NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas);
+    uint8_t data_shift = ns->id_ns.lbaf[lba_index].ds;
+    uint64_t data_size = nlb << data_shift;
+    uint64_t aio_slba  = slba << (data_shift - BDRV_SECTOR_BITS);
+    int is_write = rw->opcode == NVME_CMD_WRITE ? 1 : 0;
+
+    if ((slba + nlb) > ns->id_ns.nsze) {
+        return NVME_LBA_RANGE | NVME_DNR;
+    }
+    if (nvme_map_prp(&req->qsg, prp1, prp2, data_size, n)) {
+        return NVME_INVALID_FIELD | NVME_DNR;
+    }
+    assert((nlb << data_shift) == req->qsg.size);
+
+    dma_acct_start(n->conf.bs, &req->acct, &req->qsg, is_write ?
+        BDRV_ACCT_WRITE : BDRV_ACCT_READ);
+    req->aiocb = is_write ?
+        dma_bdrv_write(n->conf.bs, &req->qsg, aio_slba, nvme_rw_cb, req) :
+        dma_bdrv_read(n->conf.bs, &req->qsg, aio_slba, nvme_rw_cb, req);
+
+    return NVME_NO_COMPLETE;
+}
+
+static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
+{
+    NvmeNamespace *ns;
+    uint32_t nsid = le32_to_cpu(cmd->nsid);
+
+    if (nsid == 0 || nsid > n->num_namespaces) {
+        return NVME_INVALID_NSID | NVME_DNR;
+    }
+
+    ns = &n->namespaces[nsid - 1];
+    switch (cmd->opcode) {
+    case NVME_CMD_FLUSH:
+        return NVME_SUCCESS;
+    case NVME_CMD_WRITE:
+    case NVME_CMD_READ:
+        return nvme_rw(n, ns, cmd, req);
+    default:
+        return NVME_INVALID_OPCODE | NVME_DNR;
+    }
+}
+
+static void nvme_free_sq(NvmeSQueue *sq, NvmeCtrl *n)
+{
+    n->sq[sq->sqid] = NULL;
+    qemu_del_timer(sq->timer);
+    qemu_free_timer(sq->timer);
+    g_free(sq->io_req);
+    if (sq->sqid) {
+        g_free(sq);
+    }
+}
+
+static uint16_t nvme_del_sq(NvmeCtrl *n, NvmeCmd *cmd)
+{
+    NvmeDeleteQ *c = (NvmeDeleteQ *)cmd;
+    NvmeRequest *req, *next;
+    NvmeSQueue *sq;
+    NvmeCQueue *cq;
+    uint16_t qid = le16_to_cpu(c->qid);
+
+    if (!qid || nvme_check_sqid(n, qid)) {
+        return NVME_INVALID_QID | NVME_DNR;
+    }
+
+    sq = n->sq[qid];
+    while (!QTAILQ_EMPTY(&sq->out_req_list)) {
+        req = QTAILQ_FIRST(&sq->out_req_list);
+        assert(req->aiocb);
+        bdrv_aio_cancel(req->aiocb);
+    }
+    if (!nvme_check_cqid(n, sq->cqid)) {
+        cq = n->cq[sq->cqid];
+        QTAILQ_REMOVE(&cq->sq_list, sq, entry);
+
+        nvme_post_cqes(cq);
+        QTAILQ_FOREACH_SAFE(req, &cq->req_list, entry, next) {
+            if (req->sq == sq) {
+                QTAILQ_REMOVE(&cq->req_list, req, entry);
+                QTAILQ_INSERT_TAIL(&sq->req_list, req, entry);
+            }
+        }
+    }
+
+    nvme_free_sq(sq, n);
+    return NVME_SUCCESS;
+}
+
+static void nvme_init_sq(NvmeSQueue *sq, NvmeCtrl *n, uint64_t dma_addr,
+    uint16_t sqid, uint16_t cqid, uint16_t size)
+{
+    int i;
+    NvmeCQueue *cq;
+
+    sq->ctrl = n;
+    sq->dma_addr = dma_addr;
+    sq->sqid = sqid;
+    sq->size = size;
+    sq->cqid = cqid;
+    sq->head = sq->tail = 0;
+    sq->io_req = g_malloc(sq->size * sizeof(*sq->io_req));
+
+    QTAILQ_INIT(&sq->req_list);
+    QTAILQ_INIT(&sq->out_req_list);
+    for (i = 0; i < sq->size; i++) {
+        sq->io_req[i].sq = sq;
+        QTAILQ_INSERT_TAIL(&(sq->req_list), &sq->io_req[i], entry);
+    }
+    sq->timer = qemu_new_timer_ns(vm_clock, nvme_process_sq, sq);
+
+    assert(n->cq[cqid]);
+    cq = n->cq[cqid];
+    QTAILQ_INSERT_TAIL(&(cq->sq_list), sq, entry);
+    n->sq[sqid] = sq;
+}
+
+static uint16_t nvme_create_sq(NvmeCtrl *n, NvmeCmd *cmd)
+{
+    NvmeSQueue *sq;
+    NvmeCreateSq *c = (NvmeCreateSq *)cmd;
+
+    uint16_t cqid = le16_to_cpu(c->cqid);
+    uint16_t sqid = le16_to_cpu(c->sqid);
+    uint16_t qsize = le16_to_cpu(c->qsize);
+    uint16_t qflags = le16_to_cpu(c->sq_flags);
+    uint64_t prp1 = le64_to_cpu(c->prp1);
+
+    if (!cqid || nvme_check_cqid(n, cqid)) {
+        return NVME_INVALID_CQID | NVME_DNR;
+    }
+    if (!sqid || (sqid && !nvme_check_sqid(n, sqid))) {
+        return NVME_INVALID_QID | NVME_DNR;
+    }
+    if (!qsize || qsize > NVME_CAP_MQES(n->bar.cap)) {
+        return NVME_MAX_QSIZE_EXCEEDED | NVME_DNR;
+    }
+    if (!prp1 || prp1 & (n->page_size - 1)) {
+        return NVME_INVALID_FIELD | NVME_DNR;
+    }
+    if (!(NVME_SQ_FLAGS_PC(qflags))) {
+        return NVME_INVALID_FIELD | NVME_DNR;
+    }
+    sq = g_malloc0(sizeof(*sq));
+    nvme_init_sq(sq, n, prp1, sqid, cqid, qsize + 1);
+    return NVME_SUCCESS;
+}
+
+static void nvme_free_cq(NvmeCQueue *cq, NvmeCtrl *n)
+{
+    n->cq[cq->cqid] = NULL;
+    qemu_del_timer(cq->timer);
+    qemu_free_timer(cq->timer);
+    msix_vector_unuse(&n->parent_obj, cq->vector);
+    if (cq->cqid) {
+        g_free(cq);
+    }
+}
+
+static uint16_t nvme_del_cq(NvmeCtrl *n, NvmeCmd *cmd)
+{
+    NvmeDeleteQ *c = (NvmeDeleteQ *)cmd;
+    NvmeCQueue *cq;
+    uint16_t qid = le16_to_cpu(c->qid);
+
+    if (!qid || nvme_check_cqid(n, qid)) {
+        return NVME_INVALID_CQID | NVME_DNR;
+    }
+
+    cq = n->cq[qid];
+    if (!QTAILQ_EMPTY(&cq->sq_list)) {
+        return NVME_INVALID_QUEUE_DEL;
+    }
+    nvme_free_cq(cq, n);
+    return NVME_SUCCESS;
+}
+
+static void nvme_init_cq(NvmeCQueue *cq, NvmeCtrl *n, uint64_t dma_addr,
+    uint16_t cqid, uint16_t vector, uint16_t size, uint16_t irq_enabled)
+{
+    cq->ctrl = n;
+    cq->cqid = cqid;
+    cq->size = size;
+    cq->dma_addr = dma_addr;
+    cq->phase = 1;
+    cq->irq_enabled = irq_enabled;
+    cq->vector = vector;
+    cq->head = cq->tail = 0;
+    QTAILQ_INIT(&cq->req_list);
+    QTAILQ_INIT(&cq->sq_list);
+    msix_vector_use(&n->parent_obj, cq->vector);
+    n->cq[cqid] = cq;
+    cq->timer = qemu_new_timer_ns(vm_clock, nvme_post_cqes, cq);
+}
+
+static uint16_t nvme_create_cq(NvmeCtrl *n, NvmeCmd *cmd)
+{
+    NvmeCQueue *cq;
+    NvmeCreateCq *c = (NvmeCreateCq *)cmd;
+    uint16_t cqid = le16_to_cpu(c->cqid);
+    uint16_t vector = le16_to_cpu(c->irq_vector);
+    uint16_t qsize = le16_to_cpu(c->qsize);
+    uint16_t qflags = le16_to_cpu(c->cq_flags);
+    uint64_t prp1 = le64_to_cpu(c->prp1);
+
+    if (!cqid || (cqid && !nvme_check_cqid(n, cqid))) {
+        return NVME_INVALID_CQID | NVME_DNR;
+    }
+    if (!qsize || qsize > NVME_CAP_MQES(n->bar.cap)) {
+        return NVME_MAX_QSIZE_EXCEEDED | NVME_DNR;
+    }
+    if (!prp1) {
+        return NVME_INVALID_FIELD | NVME_DNR;
+    }
+    if (vector > n->num_queues) {
+        return NVME_INVALID_IRQ_VECTOR | NVME_DNR;
+    }
+    if (!(NVME_CQ_FLAGS_PC(qflags))) {
+        return NVME_INVALID_FIELD | NVME_DNR;
+    }
+
+    cq = g_malloc0(sizeof(*cq));
+    nvme_init_cq(cq, n, prp1, cqid, vector, qsize + 1,
+        NVME_CQ_FLAGS_IEN(qflags));
+    return NVME_SUCCESS;
+}
+
+static uint16_t nvme_identify(NvmeCtrl *n, NvmeCmd *cmd)
+{
+    NvmeNamespace *ns;
+    NvmeIdentify *c = (NvmeIdentify *)cmd;
+    uint32_t cns  = le32_to_cpu(c->cns);
+    uint32_t nsid = le32_to_cpu(c->nsid);
+    uint64_t prp1 = le64_to_cpu(c->prp1);
+    uint64_t prp2 = le64_to_cpu(c->prp2);
+
+    if (cns) {
+        return nvme_dma_read_prp(n, (uint8_t *)&n->id_ctrl, sizeof(n->id_ctrl),
+            prp1, prp2);
+    }
+    if (nsid == 0 || nsid > n->num_namespaces) {
+        return NVME_INVALID_NSID | NVME_DNR;
+    }
+
+    ns = &n->namespaces[nsid - 1];
+    return nvme_dma_read_prp(n, (uint8_t *)&ns->id_ns, sizeof(ns->id_ns),
+        prp1, prp2);
+}
+
+static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
+{
+    uint32_t dw10 = le32_to_cpu(cmd->cdw10);
+
+    switch (dw10) {
+    case NVME_NUMBER_OF_QUEUES:
+        req->cqe.result = cpu_to_le32(n->num_queues);
+        break;
+    default:
+        return NVME_INVALID_FIELD | NVME_DNR;
+    }
+    return NVME_SUCCESS;
+}
+
+static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
+{
+    uint32_t dw10 = le32_to_cpu(cmd->cdw10);
+
+    switch (dw10) {
+    case NVME_NUMBER_OF_QUEUES:
+        req->cqe.result = cpu_to_le32(n->num_queues);
+        break;
+    default:
+        return NVME_INVALID_FIELD | NVME_DNR;
+    }
+    return NVME_SUCCESS;
+}
+
+static uint16_t nvme_admin_cmd(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
+{
+    switch (cmd->opcode) {
+    case NVME_ADM_CMD_DELETE_SQ:
+        return nvme_del_sq(n, cmd);
+    case NVME_ADM_CMD_CREATE_SQ:
+        return nvme_create_sq(n, cmd);
+    case NVME_ADM_CMD_DELETE_CQ:
+        return nvme_del_cq(n, cmd);
+    case NVME_ADM_CMD_CREATE_CQ:
+        return nvme_create_cq(n, cmd);
+    case NVME_ADM_CMD_IDENTIFY:
+        return nvme_identify(n, cmd);
+    case NVME_ADM_CMD_SET_FEATURES:
+        return nvme_set_feature(n, cmd, req);
+    case NVME_ADM_CMD_GET_FEATURES:
+        return nvme_get_feature(n, cmd, req);
+    default:
+        return NVME_INVALID_OPCODE | NVME_DNR;
+    }
+}
+
+static void nvme_process_sq(void *opaque)
+{
+    NvmeSQueue *sq = opaque;
+    NvmeCtrl *n = sq->ctrl;
+    NvmeCQueue *cq = n->cq[sq->cqid];
+
+    uint16_t status;
+    hwaddr addr;
+    NvmeCmd cmd;
+    NvmeRequest *req;
+
+    while (!(nvme_sq_empty(sq) || QTAILQ_EMPTY(&sq->req_list))) {
+        addr = sq->dma_addr + sq->head * n->sqe_size;
+        pci_dma_read(&n->parent_obj, addr, (void *)&cmd, sizeof(cmd));
+        nvme_inc_sq_head(sq);
+
+        req = QTAILQ_FIRST(&sq->req_list);
+        QTAILQ_REMOVE(&sq->req_list, req, entry);
+        QTAILQ_INSERT_TAIL(&sq->out_req_list, req, entry);
+        memset(&req->cqe, 0, sizeof(req->cqe));
+        req->cqe.cid = cmd.cid;
+
+        status = sq->sqid ? nvme_io_cmd(n, &cmd, req) :
+            nvme_admin_cmd(n, &cmd, req);
+        if (status != NVME_NO_COMPLETE) {
+            req->status = status;
+            nvme_enqueue_req_completion(cq, req);
+        }
+    }
+}
+
+static void nvme_clear_ctrl(NvmeCtrl *n)
+{
+    int i;
+
+    for (i = 0; i < n->num_queues; i++) {
+        if (n->sq[i] != NULL) {
+            nvme_free_sq(n->sq[i], n);
+        }
+    }
+    for (i = 0; i < n->num_queues; i++) {
+        if (n->cq[i] != NULL) {
+            nvme_free_cq(n->cq[i], n);
+        }
+    }
+
+    bdrv_flush(n->conf.bs);
+    n->bar.cc = 0;
+}
+
+static int nvme_start_ctrl(NvmeCtrl *n)
+{
+    uint32_t page_bits = NVME_CC_MPS(n->bar.cc) + 12;
+    uint32_t page_size = 1 << page_bits;
+
+    if (n->cq[0] || n->sq[0] || !n->bar.asq || !n->bar.acq ||
+            n->bar.asq & (page_size - 1) || n->bar.acq & (page_size - 1) ||
+            NVME_CC_MPS(n->bar.cc) < NVME_CAP_MPSMIN(n->bar.cap) ||
+            NVME_CC_MPS(n->bar.cc) > NVME_CAP_MPSMAX(n->bar.cap) ||
+            NVME_CC_IOCQES(n->bar.cc) < NVME_CTRL_CQES_MIN(n->id_ctrl.cqes) ||
+            NVME_CC_IOCQES(n->bar.cc) > NVME_CTRL_CQES_MAX(n->id_ctrl.cqes) ||
+            NVME_CC_IOSQES(n->bar.cc) < NVME_CTRL_SQES_MIN(n->id_ctrl.sqes) ||
+            NVME_CC_IOSQES(n->bar.cc) > NVME_CTRL_SQES_MAX(n->id_ctrl.sqes) ||
+            !NVME_AQA_ASQS(n->bar.aqa) || NVME_AQA_ASQS(n->bar.aqa) > 4095 ||
+            !NVME_AQA_ACQS(n->bar.aqa) || NVME_AQA_ACQS(n->bar.aqa) > 4095) {
+        return -1;
+    }
+
+    n->page_bits = page_bits;
+    n->page_size = page_size;
+    n->max_prp_ents = n->page_size / sizeof(uint64_t);
+    n->cqe_size = 1 << NVME_CC_IOCQES(n->bar.cc);
+    n->sqe_size = 1 << NVME_CC_IOSQES(n->bar.cc);
+    nvme_init_cq(&n->admin_cq, n, n->bar.acq, 0, 0,
+        NVME_AQA_ACQS(n->bar.aqa) + 1, 1);
+    nvme_init_sq(&n->admin_sq, n, n->bar.asq, 0, 0,
+        NVME_AQA_ASQS(n->bar.aqa) + 1);
+
+    return 0;
+}
+
+static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
+    unsigned size)
+{
+    switch (offset) {
+    case 0xc:
+        n->bar.intms |= data & 0xffffffff;
+        n->bar.intmc = n->bar.intms;
+        break;
+    case 0x10:
+        n->bar.intms &= ~(data & 0xffffffff);
+        n->bar.intmc = n->bar.intms;
+        break;
+    case 0x14:
+        if (NVME_CC_EN(data) && !NVME_CC_EN(n->bar.cc)) {
+            n->bar.cc = data;
+            if (nvme_start_ctrl(n)) {
+                n->bar.csts = NVME_CSTS_FAILED;
+            } else {
+                n->bar.csts = NVME_CSTS_READY;
+            }
+        } else if (!NVME_CC_EN(data) && NVME_CC_EN(n->bar.cc)) {
+            nvme_clear_ctrl(n);
+            n->bar.csts &= ~NVME_CSTS_READY;
+        }
+        if (NVME_CC_SHN(data) && !(NVME_CC_SHN(n->bar.cc))) {
+                nvme_clear_ctrl(n);
+                n->bar.cc = data;
+                n->bar.csts |= NVME_CSTS_SHST_COMPLETE;
+        } else if (!NVME_CC_SHN(data) && NVME_CC_SHN(n->bar.cc)) {
+                n->bar.csts &= ~NVME_CSTS_SHST_COMPLETE;
+                n->bar.cc = data;
+        }
+        break;
+    case 0x24:
+        n->bar.aqa = data & 0xffffffff;
+        break;
+    case 0x28:
+        n->bar.asq = data;
+        break;
+    case 0x2c:
+        n->bar.asq |= data << 32;
+        break;
+    case 0x30:
+        n->bar.acq = data;
+        break;
+    case 0x34:
+        n->bar.acq |= data << 32;
+        break;
+    default:
+        break;
+    }
+}
+
+static uint64_t nvme_mmio_read(void *opaque, hwaddr addr, unsigned size)
+{
+    NvmeCtrl *n = (NvmeCtrl *)opaque;
+    uint8_t *ptr = (uint8_t *)&n->bar;
+    uint64_t val = 0;
+
+    if (addr < sizeof(n->bar)) {
+        memcpy(&val, ptr + addr, size);
+    }
+    return val;
+}
+
+static void nvme_process_db(NvmeCtrl *n, hwaddr addr, int val)
+{
+    uint32_t qid;
+
+    if (addr & ((1 << 2) - 1)) {
+        return;
+    }
+
+    if (((addr - 0x1000) >> 2) & 1) {
+        uint16_t new_head = val & 0xffff;
+        int start_sqs;
+        NvmeCQueue *cq;
+
+        qid = (addr - (0x1000 + (1 << 2))) >> 3;
+        if (nvme_check_cqid(n, qid)) {
+            return;
+        }
+
+        cq = n->cq[qid];
+        if (new_head >= cq->size) {
+            return;
+        }
+
+        start_sqs = nvme_cq_full(cq) ? 1 : 0;
+        cq->head = new_head;
+        if (start_sqs) {
+            NvmeSQueue *sq;
+            QTAILQ_FOREACH(sq, &cq->sq_list, entry) {
+                qemu_mod_timer(sq->timer, qemu_get_clock_ns(vm_clock) + 500);
+            }
+            qemu_mod_timer(cq->timer, qemu_get_clock_ns(vm_clock) + 500);
+        }
+
+        if (cq->tail != cq->head) {
+            nvme_isr_notify(n, cq);
+        }
+    } else {
+        uint16_t new_tail = val & 0xffff;
+        NvmeSQueue *sq;
+
+        qid = (addr - 0x1000) >> 3;
+        if (nvme_check_sqid(n, qid)) {
+            return;
+        }
+
+        sq = n->sq[qid];
+        if (new_tail >= sq->size) {
+            return;
+        }
+
+        sq->tail = new_tail;
+        qemu_mod_timer(sq->timer, qemu_get_clock_ns(vm_clock) + 500);
+    }
+}
+
+static void nvme_mmio_write(void *opaque, hwaddr addr, uint64_t data,
+    unsigned size)
+{
+    NvmeCtrl *n = (NvmeCtrl *)opaque;
+    if (addr < sizeof(n->bar)) {
+        nvme_write_bar(n, addr, data, size);
+    } else if (addr >= 0x1000) {
+        nvme_process_db(n, addr, data);
+    }
+}
+
+static const MemoryRegionOps nvme_mmio_ops = {
+    .read = nvme_mmio_read,
+    .write = nvme_mmio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 2,
+        .max_access_size = 8,
+    },
+};
+
+static int nvme_init(PCIDevice *pci_dev)
+{
+    NvmeCtrl *n = NVME(pci_dev);
+    NvmeIdCtrl *id = &n->id_ctrl;
+
+    int i;
+    int64_t bs_size;
+    uint8_t *pci_conf;
+
+    if (!(n->conf.bs)) {
+        return -1;
+    }
+
+    bs_size =  bdrv_getlength(n->conf.bs);
+    if (bs_size <= 0) {
+        return -1;
+    }
+
+    blkconf_serial(&n->conf, &n->serial);
+    if (!n->serial) {
+        return -1;
+    }
+
+    pci_conf = pci_dev->config;
+    pci_conf[PCI_INTERRUPT_PIN] = 1;
+    pci_config_set_prog_interface(pci_dev->config, 0x2);
+    pci_config_set_class(pci_dev->config, PCI_CLASS_STORAGE_EXPRESS);
+    pcie_endpoint_cap_init(&n->parent_obj, 0x80);
+
+    n->num_namespaces = 1;
+    n->num_queues = 64;
+    n->reg_size = 1 << qemu_fls(0x1004 + 2 * (n->num_queues + 1) * 4);
+    n->ns_size = bs_size / (uint64_t)n->num_namespaces;
+
+    n->namespaces = g_malloc0(sizeof(*n->namespaces)*n->num_namespaces);
+    n->sq = g_malloc0(sizeof(*n->sq)*n->num_queues);
+    n->cq = g_malloc0(sizeof(*n->cq)*n->num_queues);
+
+    memory_region_init_io(&n->iomem, &nvme_mmio_ops, n, "nvme", n->reg_size);
+    pci_register_bar(&n->parent_obj, 0,
+        PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64,
+        &n->iomem);
+    msix_init_exclusive_bar(&n->parent_obj, n->num_queues, 4);
+
+    id->vid = cpu_to_le16(pci_get_word(pci_conf + PCI_VENDOR_ID));
+    id->ssvid = cpu_to_le16(pci_get_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID));
+    strpadcpy((char *)id->mn, sizeof(id->mn), "QEMU NVMe Ctrl", ' ');
+    strpadcpy((char *)id->fr, sizeof(id->fr), "1.0", ' ');
+    strpadcpy((char *)id->sn, sizeof(id->sn), n->serial, ' ');
+    id->rab = 6;
+    id->ieee[0] = 0x00;
+    id->ieee[1] = 0x02;
+    id->ieee[2] = 0xb3;
+    id->oacs = cpu_to_le16(0);
+    id->frmw = 7 << 1;
+    id->lpa = 1 << 0;
+    id->sqes = (0x6 << 4) | 0x6;
+    id->cqes = (0x4 << 4) | 0x4;
+    id->nn = cpu_to_le32(n->num_namespaces);
+    id->psd[0].mp = cpu_to_le16(0x9c4);
+    id->psd[0].enlat = cpu_to_le32(0x10);
+    id->psd[0].exlat = cpu_to_le32(0x4);
+
+    n->bar.cap = 0;
+    NVME_CAP_SET_MQES(n->bar.cap, 0x7ff);
+    NVME_CAP_SET_CQR(n->bar.cap, 1);
+    NVME_CAP_SET_AMS(n->bar.cap, 1);
+    NVME_CAP_SET_TO(n->bar.cap, 0xf);
+    NVME_CAP_SET_CSS(n->bar.cap, 1);
+
+    n->bar.vs = 0x00010001;
+    n->bar.intmc = n->bar.intms = 0;
+
+    for (i = 0; i < n->num_namespaces; i++) {
+        NvmeNamespace *ns = &n->namespaces[i];
+        NvmeIdNs *id_ns = &ns->id_ns;
+        id_ns->nsfeat = 0;
+        id_ns->nlbaf = 0;
+        id_ns->flbas = 0;
+        id_ns->mc = 0;
+        id_ns->dpc = 0;
+        id_ns->dps = 0;
+        id_ns->lbaf[0].ds = BDRV_SECTOR_BITS;
+        id_ns->ncap  = id_ns->nuse = id_ns->nsze =
+            cpu_to_le64(n->ns_size >>
+                id_ns->lbaf[NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas)].ds);
+    }
+    return 0;
+}
+
+static void nvme_exit(PCIDevice *pci_dev)
+{
+    NvmeCtrl *n = NVME(pci_dev);
+
+    nvme_clear_ctrl(n);
+    g_free(n->namespaces);
+    g_free(n->cq);
+    g_free(n->sq);
+    msix_uninit_exclusive_bar(pci_dev);
+    memory_region_destroy(&n->iomem);
+}
+
+static Property nvme_props[] = {
+    DEFINE_BLOCK_PROPERTIES(NvmeCtrl, conf),
+    DEFINE_PROP_STRING("serial", NvmeCtrl, serial),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static const VMStateDescription nvme_vmstate = {
+    .name = "nvme",
+    .unmigratable = 1,
+};
+
+static void nvme_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+    PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc);
+
+    pc->init = nvme_init;
+    pc->exit = nvme_exit;
+    pc->class_id = PCI_CLASS_STORAGE_EXPRESS;
+    pc->vendor_id = PCI_VENDOR_ID_INTEL;
+    pc->device_id = 0x5845;
+    pc->revision = 1;
+    pc->is_express = 1;
+
+    dc->desc = "Non-Volatile Memory Express";
+    dc->props = nvme_props;
+    dc->vmsd = &nvme_vmstate;
+}
+
+static const TypeInfo nvme_info = {
+    .name          = "nvme",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(NvmeCtrl),
+    .class_init    = nvme_class_init,
+};
+
+static void nvme_register_types(void)
+{
+    type_register_static(&nvme_info);
+}
+
+type_init(nvme_register_types)
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
new file mode 100644
index 0000000..bd8fc3e
--- /dev/null
+++ b/hw/block/nvme.h
@@ -0,0 +1,711 @@
+#ifndef HW_NVME_H
+#define HW_NVME_H
+
+typedef struct NvmeBar {
+    uint64_t    cap;
+    uint32_t    vs;
+    uint32_t    intms;
+    uint32_t    intmc;
+    uint32_t    cc;
+    uint32_t    rsvd1;
+    uint32_t    csts;
+    uint32_t    nssrc;
+    uint32_t    aqa;
+    uint64_t    asq;
+    uint64_t    acq;
+} NvmeBar;
+
+enum NvmeCapShift {
+    CAP_MQES_SHIFT     = 0,
+    CAP_CQR_SHIFT      = 16,
+    CAP_AMS_SHIFT      = 17,
+    CAP_TO_SHIFT       = 24,
+    CAP_DSTRD_SHIFT    = 32,
+    CAP_NSSRS_SHIFT    = 33,
+    CAP_CSS_SHIFT      = 37,
+    CAP_MPSMIN_SHIFT   = 48,
+    CAP_MPSMAX_SHIFT   = 52,
+};
+
+enum NvmeCapMask {
+    CAP_MQES_MASK      = 0xffff,
+    CAP_CQR_MASK       = 0x1,
+    CAP_AMS_MASK       = 0x3,
+    CAP_TO_MASK        = 0xff,
+    CAP_DSTRD_MASK     = 0xf,
+    CAP_NSSRS_MASK     = 0x1,
+    CAP_CSS_MASK       = 0xff,
+    CAP_MPSMIN_MASK    = 0xf,
+    CAP_MPSMAX_MASK    = 0xf,
+};
+
+#define NVME_CAP_MQES(cap)  (((cap) >> CAP_MQES_SHIFT)   & CAP_MQES_MASK)
+#define NVME_CAP_CQR(cap)   (((cap) >> CAP_CQR_SHIFT)    & CAP_CQR_MASK)
+#define NVME_CAP_AMS(cap)   (((cap) >> CAP_AMS_SHIFT)    & CAP_AMS_MASK)
+#define NVME_CAP_TO(cap)    (((cap) >> CAP_TO_SHIFT)     & CAP_TO_MASK)
+#define NVME_CAP_DSTRD(cap) (((cap) >> CAP_DSTRD_SHIFT)  & CAP_DSTRD_MASK)
+#define NVME_CAP_NSSRS(cap) (((cap) >> CAP_NSSRS_SHIFT)  & CAP_NSSRS_MASK)
+#define NVME_CAP_CSS(cap)   (((cap) >> CAP_CSS_SHIFT)    & CAP_CSS_MASK)
+#define NVME_CAP_MPSMIN(cap)(((cap) >> CAP_MPSMIN_SHIFT) & CAP_MPSMIN_MASK)
+#define NVME_CAP_MPSMAX(cap)(((cap) >> CAP_MPSMAX_SHIFT) & CAP_MPSMAX_MASK)
+
+#define NVME_CAP_SET_MQES(cap, val)   (cap |= (uint64_t)(val & CAP_MQES_MASK)  \
+                                                           << CAP_MQES_SHIFT)
+#define NVME_CAP_SET_CQR(cap, val)    (cap |= (uint64_t)(val & CAP_CQR_MASK)   \
+                                                           << CAP_CQR_SHIFT)
+#define NVME_CAP_SET_AMS(cap, val)    (cap |= (uint64_t)(val & CAP_AMS_MASK)   \
+                                                           << CAP_AMS_SHIFT)
+#define NVME_CAP_SET_TO(cap, val)     (cap |= (uint64_t)(val & CAP_TO_MASK)    \
+                                                           << CAP_TO_SHIFT)
+#define NVME_CAP_SET_DSTRD(cap, val)  (cap |= (uint64_t)(val & CAP_DSTRD_MASK) \
+                                                           << CAP_DSTRD_SHIFT)
+#define NVME_CAP_SET_NSSRS(cap, val)  (cap |= (uint64_t)(val & CAP_NSSRS_MASK) \
+                                                           << CAP_NSSRS_SHIFT)
+#define NVME_CAP_SET_CSS(cap, val)    (cap |= (uint64_t)(val & CAP_CSS_MASK)   \
+                                                           << CAP_CSS_SHIFT)
+#define NVME_CAP_SET_MPSMIN(cap, val) (cap |= (uint64_t)(val & CAP_MPSMIN_MASK)\
+                                                           << CAP_MPSMIN_SHIFT)
+#define NVME_CAP_SET_MPSMAX(cap, val) (cap |= (uint64_t)(val & CAP_MPSMAX_MASK)\
+                                                            << CAP_MPSMAX_SHIFT)
+
+enum NvmeCcShift {
+    CC_EN_SHIFT     = 0,
+    CC_CSS_SHIFT    = 4,
+    CC_MPS_SHIFT    = 7,
+    CC_AMS_SHIFT    = 11,
+    CC_SHN_SHIFT    = 14,
+    CC_IOSQES_SHIFT = 16,
+    CC_IOCQES_SHIFT = 20,
+};
+
+enum NvmeCcMask {
+    CC_EN_MASK      = 0x1,
+    CC_CSS_MASK     = 0x7,
+    CC_MPS_MASK     = 0xf,
+    CC_AMS_MASK     = 0x7,
+    CC_SHN_MASK     = 0x3,
+    CC_IOSQES_MASK  = 0xf,
+    CC_IOCQES_MASK  = 0xf,
+};
+
+#define NVME_CC_EN(cc)     ((cc >> CC_EN_SHIFT)     & CC_EN_MASK)
+#define NVME_CC_CSS(cc)    ((cc >> CC_CSS_SHIFT)    & CC_CSS_MASK)
+#define NVME_CC_MPS(cc)    ((cc >> CC_MPS_SHIFT)    & CC_MPS_MASK)
+#define NVME_CC_AMS(cc)    ((cc >> CC_AMS_SHIFT)    & CC_AMS_MASK)
+#define NVME_CC_SHN(cc)    ((cc >> CC_SHN_SHIFT)    & CC_SHN_MASK)
+#define NVME_CC_IOSQES(cc) ((cc >> CC_IOSQES_SHIFT) & CC_IOSQES_MASK)
+#define NVME_CC_IOCQES(cc) ((cc >> CC_IOCQES_SHIFT) & CC_IOCQES_MASK)
+
+enum NvmeCstsShift {
+    CSTS_RDY_SHIFT      = 0,
+    CSTS_CFS_SHIFT      = 1,
+    CSTS_SHST_SHIFT     = 2,
+    CSTS_NSSRO_SHIFT    = 4,
+};
+
+enum NvmeCstsMask {
+    CSTS_RDY_MASK   = 0x1,
+    CSTS_CFS_MASK   = 0x1,
+    CSTS_SHST_MASK  = 0x3,
+    CSTS_NSSRO_MASK = 0x1,
+};
+
+enum NvmeCsts {
+    NVME_CSTS_READY         = 1 << CSTS_RDY_SHIFT,
+    NVME_CSTS_FAILED        = 1 << CSTS_CFS_SHIFT,
+    NVME_CSTS_SHST_NORMAL   = 0 << CSTS_SHST_SHIFT,
+    NVME_CSTS_SHST_PROGRESS = 1 << CSTS_SHST_SHIFT,
+    NVME_CSTS_SHST_COMPLETE = 2 << CSTS_SHST_SHIFT,
+    NVME_CSTS_NSSRO         = 1 << CSTS_NSSRO_SHIFT,
+};
+
+#define NVME_CSTS_RDY(csts)     ((csts >> CSTS_RDY_SHIFT)   & CSTS_RDY_MASK)
+#define NVME_CSTS_CFS(csts)     ((csts >> CSTS_CFS_SHIFT)   & CSTS_CFS_MASK)
+#define NVME_CSTS_SHST(csts)    ((csts >> CSTS_SHST_SHIFT)  & CSTS_SHST_MASK)
+#define NVME_CSTS_NSSRO(csts)   ((csts >> CSTS_NSSRO_SHIFT) & CSTS_NSSRO_MASK)
+
+enum NvmeAqaShift {
+    AQA_ASQS_SHIFT  = 0,
+    AQA_ACQS_SHIFT  = 16,
+};
+
+enum NvmeAqaMask {
+    AQA_ASQS_MASK   = 0xfff,
+    AQA_ACQS_MASK   = 0xfff,
+};
+
+#define NVME_AQA_ASQS(aqa) ((aqa >> AQA_ASQS_SHIFT) & AQA_ASQS_MASK)
+#define NVME_AQA_ACQS(aqa) ((aqa >> AQA_ACQS_SHIFT) & AQA_ACQS_MASK)
+
+typedef struct NvmeCmd {
+    uint8_t     opcode;
+    uint8_t     fuse;
+    uint16_t    cid;
+    uint32_t    nsid;
+    uint64_t    res1;
+    uint64_t    mptr;
+    uint64_t    prp1;
+    uint64_t    prp2;
+    uint32_t    cdw10;
+    uint32_t    cdw11;
+    uint32_t    cdw12;
+    uint32_t    cdw13;
+    uint32_t    cdw14;
+    uint32_t    cdw15;
+} NvmeCmd;
+
+enum NvmeAdminCommands {
+    NVME_ADM_CMD_DELETE_SQ      = 0x00,
+    NVME_ADM_CMD_CREATE_SQ      = 0x01,
+    NVME_ADM_CMD_GET_LOG_PAGE   = 0x02,
+    NVME_ADM_CMD_DELETE_CQ      = 0x04,
+    NVME_ADM_CMD_CREATE_CQ      = 0x05,
+    NVME_ADM_CMD_IDENTIFY       = 0x06,
+    NVME_ADM_CMD_ABORT          = 0x08,
+    NVME_ADM_CMD_SET_FEATURES   = 0x09,
+    NVME_ADM_CMD_GET_FEATURES   = 0x0a,
+    NVME_ADM_CMD_ASYNC_EV_REQ   = 0x0c,
+    NVME_ADM_CMD_ACTIVATE_FW    = 0x10,
+    NVME_ADM_CMD_DOWNLOAD_FW    = 0x11,
+    NVME_ADM_CMD_FORMAT_NVM     = 0x80,
+    NVME_ADM_CMD_SECURITY_SEND  = 0x81,
+    NVME_ADM_CMD_SECURITY_RECV  = 0x82,
+};
+
+enum NvmeIoCommands {
+    NVME_CMD_FLUSH              = 0x00,
+    NVME_CMD_WRITE              = 0x01,
+    NVME_CMD_READ               = 0x02,
+    NVME_CMD_WRITE_UNCOR        = 0x04,
+    NVME_CMD_COMPARE            = 0x05,
+    NVME_CMD_DSM                = 0x09,
+};
+
+typedef struct NvmeDeleteQ {
+    uint8_t     opcode;
+    uint8_t     flags;
+    uint16_t    cid;
+    uint32_t    rsvd1[9];
+    uint16_t    qid;
+    uint16_t    rsvd10;
+    uint32_t    rsvd11[5];
+} NvmeDeleteQ;
+
+typedef struct NvmeCreateCq {
+    uint8_t     opcode;
+    uint8_t     flags;
+    uint16_t    cid;
+    uint32_t    rsvd1[5];
+    uint64_t    prp1;
+    uint64_t    rsvd8;
+    uint16_t    cqid;
+    uint16_t    qsize;
+    uint16_t    cq_flags;
+    uint16_t    irq_vector;
+    uint32_t    rsvd12[4];
+} NvmeCreateCq;
+
+#define NVME_CQ_FLAGS_PC(cq_flags)  (cq_flags & 0x1)
+#define NVME_CQ_FLAGS_IEN(cq_flags) ((cq_flags >> 1) & 0x1)
+
+typedef struct NvmeCreateSq {
+    uint8_t     opcode;
+    uint8_t     flags;
+    uint16_t    cid;
+    uint32_t    rsvd1[5];
+    uint64_t    prp1;
+    uint64_t    rsvd8;
+    uint16_t    sqid;
+    uint16_t    qsize;
+    uint16_t    sq_flags;
+    uint16_t    cqid;
+    uint32_t    rsvd12[4];
+} NvmeCreateSq;
+
+#define NVME_SQ_FLAGS_PC(sq_flags)      (sq_flags & 0x1)
+#define NVME_SQ_FLAGS_QPRIO(sq_flags)   ((sq_flags >> 1) & 0x3)
+
+enum NvmeQueueFlags {
+    NVME_Q_PC           = 1,
+    NVME_Q_PRIO_URGENT  = 0,
+    NVME_Q_PRIO_HIGH    = 1,
+    NVME_Q_PRIO_NORMAL  = 2,
+    NVME_Q_PRIO_LOW     = 3,
+};
+
+typedef struct NvmeIdentify {
+    uint8_t     opcode;
+    uint8_t     flags;
+    uint16_t    cid;
+    uint32_t    nsid;
+    uint64_t    rsvd2[2];
+    uint64_t    prp1;
+    uint64_t    prp2;
+    uint32_t    cns;
+    uint32_t    rsvd11[5];
+} NvmeIdentify;
+
+typedef struct NvmeRwCmd {
+    uint8_t     opcode;
+    uint8_t     flags;
+    uint16_t    cid;
+    uint32_t    nsid;
+    uint64_t    rsvd2;
+    uint64_t    mptr;
+    uint64_t    prp1;
+    uint64_t    prp2;
+    uint64_t    slba;
+    uint16_t    nlb;
+    uint16_t    control;
+    uint32_t    dsmgmt;
+    uint32_t    reftag;
+    uint16_t    apptag;
+    uint16_t    appmask;
+} NvmeRwCmd;
+
+enum {
+    NVME_RW_LR                  = 1 << 15,
+    NVME_RW_FUA                 = 1 << 14,
+    NVME_RW_DSM_FREQ_UNSPEC     = 0,
+    NVME_RW_DSM_FREQ_TYPICAL    = 1,
+    NVME_RW_DSM_FREQ_RARE       = 2,
+    NVME_RW_DSM_FREQ_READS      = 3,
+    NVME_RW_DSM_FREQ_WRITES     = 4,
+    NVME_RW_DSM_FREQ_RW         = 5,
+    NVME_RW_DSM_FREQ_ONCE       = 6,
+    NVME_RW_DSM_FREQ_PREFETCH   = 7,
+    NVME_RW_DSM_FREQ_TEMP       = 8,
+    NVME_RW_DSM_LATENCY_NONE    = 0 << 4,
+    NVME_RW_DSM_LATENCY_IDLE    = 1 << 4,
+    NVME_RW_DSM_LATENCY_NORM    = 2 << 4,
+    NVME_RW_DSM_LATENCY_LOW     = 3 << 4,
+    NVME_RW_DSM_SEQ_REQ         = 1 << 6,
+    NVME_RW_DSM_COMPRESSED      = 1 << 7,
+    NVME_RW_PRINFO_PRACT        = 1 << 13,
+    NVME_RW_PRINFO_PRCHK_GUARD  = 1 << 12,
+    NVME_RW_PRINFO_PRCHK_APP    = 1 << 11,
+    NVME_RW_PRINFO_PRCHK_REF    = 1 << 10,
+};
+
+typedef struct NvmeDsmCmd {
+    uint8_t     opcode;
+    uint8_t     flags;
+    uint16_t    cid;
+    uint32_t    nsid;
+    uint64_t    rsvd2[2];
+    uint64_t    prp1;
+    uint64_t    prp2;
+    uint32_t    nr;
+    uint32_t    attributes;
+    uint32_t    rsvd12[4];
+} NvmeDsmCmd;
+
+enum {
+    NVME_DSMGMT_IDR = 1 << 0,
+    NVME_DSMGMT_IDW = 1 << 1,
+    NVME_DSMGMT_AD  = 1 << 2,
+};
+
+typedef struct NvmeDsmRange {
+    uint32_t    cattr;
+    uint32_t    nlb;
+    uint64_t    slba;
+} NvmeDsmRange;
+
+enum NvmeAsyncEventRequest {
+    NVME_AER_TYPE_ERROR                     = 0,
+    NVME_AER_TYPE_SMART                     = 1,
+    NVME_AER_TYPE_IO_SPECIFIC               = 6,
+    NVME_AER_TYPE_VENDOR_SPECIFIC           = 7,
+    NVME_AER_INFO_ERR_INVALID_SQ            = 0,
+    NVME_AER_INFO_ERR_INVALID_DB            = 1,
+    NVME_AER_INFO_ERR_DIAG_FAIL             = 2,
+    NVME_AER_INFO_ERR_PERS_INTERNAL_ERR     = 3,
+    NVME_AER_INFO_ERR_TRANS_INTERNAL_ERR    = 4,
+    NVME_AER_INFO_ERR_FW_IMG_LOAD_ERR       = 5,
+    NVME_AER_INFO_SMART_RELIABILITY         = 0,
+    NVME_AER_INFO_SMART_TEMP_THRESH         = 1,
+    NVME_AER_INFO_SMART_SPARE_THRESH        = 2,
+};
+
+typedef struct NvmeAerResult {
+    uint8_t event_type;
+    uint8_t event_info;
+    uint8_t log_page;
+    uint8_t resv;
+} NvmeAerResult;
+
+typedef struct NvmeCqe {
+    uint32_t    result;
+    uint32_t    rsvd;
+    uint16_t    sq_head;
+    uint16_t    sq_id;
+    uint16_t    cid;
+    uint16_t    status;
+} NvmeCqe;
+
+enum NvmeStatusCodes {
+    NVME_SUCCESS                = 0x0000,
+    NVME_INVALID_OPCODE         = 0x0001,
+    NVME_INVALID_FIELD          = 0x0002,
+    NVME_CID_CONFLICT           = 0x0003,
+    NVME_DATA_TRAS_ERROR        = 0x0004,
+    NVME_POWER_LOSS_ABORT       = 0x0005,
+    NVME_INTERNAL_DEV_ERROR     = 0x0006,
+    NVME_CMD_ABORT_REQ          = 0x0007,
+    NVME_CMD_ABORT_SQ_DEL       = 0x0008,
+    NVME_CMD_ABORT_FAILED_FUSE  = 0x0009,
+    NVME_CMD_ABORT_MISSING_FUSE = 0x000a,
+    NVME_INVALID_NSID           = 0x000b,
+    NVME_CMD_SEQ_ERROR          = 0x000c,
+    NVME_LBA_RANGE              = 0x0080,
+    NVME_CAP_EXCEEDED           = 0x0081,
+    NVME_NS_NOT_READY           = 0x0082,
+    NVME_NS_RESV_CONFLICT       = 0x0083,
+    NVME_INVALID_CQID           = 0x0100,
+    NVME_INVALID_QID            = 0x0101,
+    NVME_MAX_QSIZE_EXCEEDED     = 0x0102,
+    NVME_ACL_EXCEEDED           = 0x0103,
+    NVME_RESERVED               = 0x0104,
+    NVME_AER_LIMIT_EXCEEDED     = 0x0105,
+    NVME_INVALID_FW_SLOT        = 0x0106,
+    NVME_INVALID_FW_IMAGE       = 0x0107,
+    NVME_INVALID_IRQ_VECTOR     = 0x0108,
+    NVME_INVALID_LOG_ID         = 0x0109,
+    NVME_INVALID_FORMAT         = 0x010a,
+    NVME_FW_REQ_RESET           = 0x010b,
+    NVME_INVALID_QUEUE_DEL      = 0x010c,
+    NVME_FID_NOT_SAVEABLE       = 0x010d,
+    NVME_FID_NOT_NSID_SPEC      = 0x010f,
+    NVME_FW_REQ_SUSYSTEM_RESET  = 0x0110,
+    NVME_CONFLICTING_ATTRS      = 0x0180,
+    NVME_INVALID_PROT_INFO      = 0x0181,
+    NVME_WRITE_TO_RO            = 0x0182,
+    NVME_WRITE_FAULT            = 0x0280,
+    NVME_UNRECOVERED_READ       = 0x0281,
+    NVME_E2E_GUARD_ERROR        = 0x0282,
+    NVME_E2E_APP_ERROR          = 0x0283,
+    NVME_E2E_REF_ERROR          = 0x0284,
+    NVME_CMP_FAILURE            = 0x0285,
+    NVME_ACCESS_DENIED          = 0x0286,
+    NVME_MORE                   = 0x2000,
+    NVME_DNR                    = 0x4000,
+    NVME_NO_COMPLETE            = 0xffff,
+};
+
+typedef struct NvmeFwSlotInfoLog {
+    uint8_t     afi;
+    uint8_t     reserved1[7];
+    uint8_t     frs1[8];
+    uint8_t     frs2[8];
+    uint8_t     frs3[8];
+    uint8_t     frs4[8];
+    uint8_t     frs5[8];
+    uint8_t     frs6[8];
+    uint8_t     frs7[8];
+    uint8_t     reserved2[448];
+} NvmeFwSlotInfoLog;
+
+typedef struct NvmeErrorLog {
+    uint64_t    error_count;
+    uint16_t    sqid;
+    uint16_t    cid;
+    uint16_t    status_field;
+    uint16_t    param_error_location;
+    uint64_t    lba;
+    uint32_t    nsid;
+    uint8_t     vs;
+    uint8_t     resv[35];
+} NvmeErrorLog;
+
+typedef struct NvmeSmartLog {
+    uint8_t     critical_warning;
+    uint8_t     temperature[2];
+    uint8_t     available_spare;
+    uint8_t     available_spare_threshold;
+    uint8_t     percentage_used;
+    uint8_t     reserved1[26];
+    uint64_t    data_units_read[2];
+    uint64_t    data_units_written[2];
+    uint64_t    host_read_commands[2];
+    uint64_t    host_write_commands[2];
+    uint64_t    controller_busy_time[2];
+    uint64_t    power_cycles[2];
+    uint64_t    power_on_hours[2];
+    uint64_t    unsafe_shutdowns[2];
+    uint64_t    media_errors[2];
+    uint64_t    number_of_error_log_entries[2];
+    uint8_t     reserved2[320];
+} NvmeSmartLog;
+
+enum NvmeSmartWarn {
+    NVME_SMART_SPARE                  = 1 << 0,
+    NVME_SMART_TEMPERATURE            = 1 << 1,
+    NVME_SMART_RELIABILITY            = 1 << 2,
+    NVME_SMART_MEDIA_READ_ONLY        = 1 << 3,
+    NVME_SMART_FAILED_VOLATILE_MEDIA  = 1 << 4,
+};
+
+enum LogIdentifier {
+    NVME_LOG_ERROR_INFO     = 0x01,
+    NVME_LOG_SMART_INFO     = 0x02,
+    NVME_LOG_FW_SLOT_INFO   = 0x03,
+};
+
+typedef struct NvmePSD {
+    uint16_t    mp;
+    uint16_t    reserved;
+    uint32_t    enlat;
+    uint32_t    exlat;
+    uint8_t     rrt;
+    uint8_t     rrl;
+    uint8_t     rwt;
+    uint8_t     rwl;
+    uint8_t     resv[16];
+} NvmePSD;
+
+typedef struct NvmeIdCtrl {
+    uint16_t    vid;
+    uint16_t    ssvid;
+    uint8_t     sn[20];
+    uint8_t     mn[40];
+    uint8_t     fr[8];
+    uint8_t     rab;
+    uint8_t     ieee[3];
+    uint8_t     cmic;
+    uint8_t     mdts;
+    uint8_t     rsvd255[178];
+    uint16_t    oacs;
+    uint8_t     acl;
+    uint8_t     aerl;
+    uint8_t     frmw;
+    uint8_t     lpa;
+    uint8_t     elpe;
+    uint8_t     npss;
+    uint8_t     rsvd511[248];
+    uint8_t     sqes;
+    uint8_t     cqes;
+    uint16_t    rsvd515;
+    uint32_t    nn;
+    uint16_t    oncs;
+    uint16_t    fuses;
+    uint8_t     fna;
+    uint8_t     vwc;
+    uint16_t    awun;
+    uint16_t    awupf;
+    uint8_t     rsvd703[174];
+    uint8_t     rsvd2047[1344];
+    NvmePSD     psd[32];
+    uint8_t     vs[1024];
+} NvmeIdCtrl;
+
+enum NvmeIdCtrlOacs {
+    NVME_OACS_SECURITY  = 1 << 0,
+    NVME_OACS_FORMAT    = 1 << 1,
+    NVME_OACS_FW        = 1 << 2,
+};
+
+enum NvmeIdCtrlOncs {
+    NVME_ONCS_COMPARE       = 1 << 0,
+    NVME_ONCS_WRITE_UNCORR  = 1 << 1,
+    NVME_ONCS_DSM           = 1 << 2,
+    NVME_ONCS_WRITE_ZEROS   = 1 << 3,
+    NVME_ONCS_FEATURES      = 1 << 4,
+    NVME_ONCS_RESRVATIONS   = 1 << 5,
+};
+
+#define NVME_CTRL_SQES_MIN(sqes) ((sqes) & 0xf)
+#define NVME_CTRL_SQES_MAX(sqes) (((sqes) >> 4) & 0xf)
+#define NVME_CTRL_CQES_MIN(cqes) ((cqes) & 0xf)
+#define NVME_CTRL_CQES_MAX(cqes) (((cqes) >> 4) & 0xf)
+
+typedef struct NvmeFeatureVal {
+    uint32_t    arbitration;
+    uint32_t    power_mgmt;
+    uint32_t    temp_thresh;
+    uint32_t    err_rec;
+    uint32_t    volatile_wc;
+    uint32_t    num_queues;
+    uint32_t    int_coalescing;
+    uint32_t    *int_vector_config;
+    uint32_t    write_atomicity;
+    uint32_t    async_config;
+    uint32_t    sw_prog_marker;
+} NvmeFeatureVal;
+
+#define NVME_ARB_AB(arb)    (arb & 0x7)
+#define NVME_ARB_LPW(arb)   ((arb >> 8) & 0xff)
+#define NVME_ARB_MPW(arb)   ((arb >> 16) & 0xff)
+#define NVME_ARB_HPW(arb)   ((arb >> 24) & 0xff)
+
+#define NVME_INTC_THR(intc)     (intc & 0xff)
+#define NVME_INTC_TIME(intc)    ((intc >> 8) & 0xff)
+
+enum NvmeFeatureIds {
+    NVME_ARBITRATION                = 0x1,
+    NVME_POWER_MANAGEMENT           = 0x2,
+    NVME_LBA_RANGE_TYPE             = 0x3,
+    NVME_TEMPERATURE_THRESHOLD      = 0x4,
+    NVME_ERROR_RECOVERY             = 0x5,
+    NVME_VOLATILE_WRITE_CACHE       = 0x6,
+    NVME_NUMBER_OF_QUEUES           = 0x7,
+    NVME_INTERRUPT_COALESCING       = 0x8,
+    NVME_INTERRUPT_VECTOR_CONF      = 0x9,
+    NVME_WRITE_ATOMICITY            = 0xa,
+    NVME_ASYNCHRONOUS_EVENT_CONF    = 0xb,
+    NVME_SOFTWARE_PROGRESS_MARKER   = 0x80
+};
+
+typedef struct NvmeRangeType {
+    uint8_t     type;
+    uint8_t     attributes;
+    uint8_t     rsvd2[14];
+    uint64_t    slba;
+    uint64_t    nlb;
+    uint8_t     guid[16];
+    uint8_t     rsvd48[16];
+} NvmeRangeType;
+
+typedef struct NvmeLBAF {
+    uint16_t    ms;
+    uint8_t     ds;
+    uint8_t     rp;
+} NvmeLBAF;
+
+typedef struct NvmeIdNs {
+    uint64_t    nsze;
+    uint64_t    ncap;
+    uint64_t    nuse;
+    uint8_t     nsfeat;
+    uint8_t     nlbaf;
+    uint8_t     flbas;
+    uint8_t     mc;
+    uint8_t     dpc;
+    uint8_t     dps;
+    uint8_t     res30[98];
+    NvmeLBAF    lbaf[16];
+    uint8_t     res192[192];
+    uint8_t     vs[3712];
+} NvmeIdNs;
+
+#define NVME_ID_NS_NSFEAT_THIN(nsfeat)      ((nsfeat & 0x1))
+#define NVME_ID_NS_FLBAS_EXTENDED(flbas)    ((flbas >> 4) & 0x1)
+#define NVME_ID_NS_FLBAS_INDEX(flbas)       ((flbas & 0xf))
+#define NVME_ID_NS_MC_SEPARATE(mc)          ((mc >> 1) & 0x1)
+#define NVME_ID_NS_MC_EXTENDED(mc)          ((mc & 0x1))
+#define NVME_ID_NS_DPC_LAST_EIGHT(dpc)      ((dpc >> 4) & 0x1)
+#define NVME_ID_NS_DPC_FIRST_EIGHT(dpc)     ((dpc >> 3) & 0x1)
+#define NVME_ID_NS_DPC_TYPE_3(dpc)          ((dpc >> 2) & 0x1)
+#define NVME_ID_NS_DPC_TYPE_2(dpc)          ((dpc >> 1) & 0x1)
+#define NVME_ID_NS_DPC_TYPE_1(dpc)          ((dpc & 0x1))
+#define NVME_ID_NS_DPC_TYPE_MASK            0x7
+
+enum NvmeIdNsDps {
+    DPS_TYPE_NONE   = 0,
+    DPS_TYPE_1      = 1,
+    DPS_TYPE_2      = 2,
+    DPS_TYPE_3      = 3,
+    DPS_TYPE_MASK   = 0x7,
+    DPS_FIRST_EIGHT = 8,
+};
+
+static inline void _nvme_check_size(void)
+{
+    QEMU_BUILD_BUG_ON(sizeof(NvmeAerResult) != 4);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeCqe) != 16);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeDsmRange) != 16);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeCmd) != 64);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeDeleteQ) != 64);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeCreateCq) != 64);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeCreateSq) != 64);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeIdentify) != 64);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeRwCmd) != 64);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeDsmCmd) != 64);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeRangeType) != 64);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeErrorLog) != 64);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeFwSlotInfoLog) != 512);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeSmartLog) != 512);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeIdCtrl) != 4096);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeIdNs) != 4096);
+}
+
+typedef struct NvmeAsyncEvent {
+    QSIMPLEQ_ENTRY(NvmeAsyncEvent) entry;
+    NvmeAerResult result;
+} NvmeAsyncEvent;
+
+typedef struct NvmeRequest {
+    struct NvmeSQueue       *sq;
+    BlockDriverAIOCB        *aiocb;
+    uint16_t                status;
+    NvmeCqe                 cqe;
+    BlockAcctCookie         acct;
+    QEMUSGList              qsg;
+    QTAILQ_ENTRY(NvmeRequest)entry;
+} NvmeRequest;
+
+typedef struct NvmeSQueue {
+    struct NvmeCtrl *ctrl;
+    uint16_t    sqid;
+    uint16_t    cqid;
+    uint32_t    head;
+    uint32_t    tail;
+    uint32_t    size;
+    uint64_t    dma_addr;
+    QEMUTimer   *timer;
+    NvmeRequest *io_req;
+    QTAILQ_HEAD(sq_req_list, NvmeRequest) req_list;
+    QTAILQ_HEAD(out_req_list, NvmeRequest) out_req_list;
+    QTAILQ_ENTRY(NvmeSQueue) entry;
+} NvmeSQueue;
+
+typedef struct NvmeCQueue {
+    struct NvmeCtrl *ctrl;
+    uint8_t     phase;
+    uint16_t    cqid;
+    uint16_t    irq_enabled;
+    uint32_t    head;
+    uint32_t    tail;
+    uint32_t    vector;
+    uint32_t    size;
+    uint64_t    dma_addr;
+    QEMUTimer   *timer;
+    QTAILQ_HEAD(sq_list, NvmeSQueue) sq_list;
+    QTAILQ_HEAD(cq_req_list, NvmeRequest) req_list;
+} NvmeCQueue;
+
+typedef struct NvmeNamespace {
+    NvmeIdNs        id_ns;
+} NvmeNamespace;
+
+#define TYPE_NVME "nvme"
+#define NVME(obj) \
+        OBJECT_CHECK(NvmeCtrl, (obj), TYPE_NVME)
+
+typedef struct NvmeCtrl {
+    PCIDevice    parent_obj;
+    MemoryRegion iomem;
+    NvmeBar      bar;
+    BlockConf    conf;
+
+    uint16_t    page_size;
+    uint16_t    page_bits;
+    uint16_t    max_prp_ents;
+    uint16_t    cqe_size;
+    uint16_t    sqe_size;
+    uint32_t    reg_size;
+    uint32_t    num_namespaces;
+    uint32_t    num_queues;
+    uint32_t    max_q_ents;
+    uint64_t    ns_size;
+
+    char            *serial;
+    NvmeNamespace   *namespaces;
+    NvmeSQueue      **sq;
+    NvmeCQueue      **cq;
+    NvmeSQueue      admin_sq;
+    NvmeCQueue      admin_cq;
+    NvmeIdCtrl      id_ctrl;
+} NvmeCtrl;
+
+#endif /* HW_NVME_H */
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index d8dc2f1..08f8161 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -19,6 +19,7 @@
 #define PCI_CLASS_STORAGE_IDE            0x0101
 #define PCI_CLASS_STORAGE_RAID           0x0104
 #define PCI_CLASS_STORAGE_SATA           0x0106
+#define PCI_CLASS_STORAGE_EXPRESS        0x0108
 #define PCI_CLASS_STORAGE_OTHER          0x0180
 
 #define PCI_CLASS_NETWORK_ETHERNET       0x0200
commit 8da1aa15db2f55c42bdcea95e27b1a190d2be754
Author: Richard W.M. Jones <rjones at redhat.com>
Date:   Mon Jun 10 17:40:15 2013 +0100

    curl: Don't set curl options on the handle just before it's going to be deleted.
    
    (Found by Kamil Dudka)
    
    Signed-off-by: Richard W.M. Jones <rjones at redhat.com>
    Cc: Michael Tokarev <mjt at tls.msk.ru>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/curl.c b/block/curl.c
index 0fba451..6af8cb7 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -452,8 +452,6 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags)
     if (curl_easy_perform(state->curl))
         goto out;
     curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d);
-    curl_easy_setopt(state->curl, CURLOPT_WRITEFUNCTION, (void *)curl_read_cb);
-    curl_easy_setopt(state->curl, CURLOPT_NOBODY, 0);
     if (d)
         s->len = (size_t)d;
     else if(!s->len)
commit 5a394b9e96eb3c39676353bdf8a230180ae8d6f4
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Mon Jun 10 11:07:33 2013 +0200

    vmdk: byteswap VMDK4Header.desc_offset field
    
    Remember to byteswap VMDK4Header.desc_offset on big-endian machines.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vmdk.c b/block/vmdk.c
index 608daaf..ee50a73 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -507,8 +507,11 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
     if (ret < 0) {
         return ret;
     }
-    if (header.capacity == 0 && header.desc_offset) {
-        return vmdk_open_desc_file(bs, flags, header.desc_offset << 9);
+    if (header.capacity == 0) {
+        int64_t desc_offset = le64_to_cpu(header.desc_offset);
+        if (desc_offset) {
+            return vmdk_open_desc_file(bs, flags, desc_offset << 9);
+        }
     }
 
     if (le64_to_cpu(header.gd_offset) == VMDK4_GD_AT_END) {
commit a7cea2ba47ea6d361584072f96d7858f5cc99009
Author: Richard W.M. Jones <rjones at redhat.com>
Date:   Mon Jun 10 12:38:43 2013 +0100

    block/curl.c: Refuse to open the handle for writes.
    
    Signed-off-by: Richard W.M. Jones <rjones at redhat.com>
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/curl.c b/block/curl.c
index 4dc3b4b..0fba451 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -406,6 +406,12 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags)
 
     static int inited = 0;
 
+    if (flags & BDRV_O_RDWR) {
+        qerror_report(ERROR_CLASS_GENERIC_ERROR,
+                      "curl block device does not support writes");
+        return -EROFS;
+    }
+
     opts = qemu_opts_create_nofail(&runtime_opts);
     qemu_opts_absorb_qdict(opts, options, &local_err);
     if (error_is_set(&local_err)) {
commit cede621ffc13ba1e209d9a21e85b21e150b74045
Author: Liu Yuan <namei.unix at gmail.com>
Date:   Sat Jun 8 01:54:26 2013 +0800

    sheepdog: support 'qemu-img snapshot -a'
    
    Just call sd_create_branch() in the snapshot_goto to rollback the image is good
    enough. With this patch, 'loadvm' process for sheepdog is modified:
    
    Suppose we have a snapshot chain A --> B --> C, we do 'loadvm A' so as to get
    a new chain,
    
    A --> B
    |
    V
    C1
    
    in the old code:
    
    1 reload inode of A (in snapshot_goto)
    2 read vmstate via A's vdi_id (loadvm_state)
    3 delete C and create C1, reload inode of C1 (sd_create_branch on write)
    
    with this patch applied:
    
    1 reload inode of A, delete C and create C1  (in snapshot_goto)
    2 read vmstate via C1's parent, that is A's vdi_id (loadvm_state)
    
    This will fix the possible bug that QEMU exit between 2 and 3 in the old code
    
    Cc: qemu-devel at nongnu.org
    Cc: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
    Cc: Kevin Wolf <kwolf at redhat.com>
    Cc: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Liu Yuan <namei.unix at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/sheepdog.c b/block/sheepdog.c
index 94218ac..1b7c3f1 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -2071,14 +2071,11 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
         goto out;
     }
 
-    if (!s->inode.vm_state_size) {
-        error_report("Invalid snapshot");
-        ret = -ENOENT;
+    ret = sd_create_branch(s);
+    if (ret) {
         goto out;
     }
 
-    s->is_snapshot = true;
-
     g_free(old_s);
 
     return 0;
@@ -2196,8 +2193,9 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
     int fd, ret = 0, remaining = size;
     unsigned int data_len;
     uint64_t vmstate_oid;
-    uint32_t vdi_index;
     uint64_t offset;
+    uint32_t vdi_index;
+    uint32_t vdi_id = load ? s->inode.parent_vdi_id : s->inode.vdi_id;
 
     fd = connect_to_sdog(s);
     if (fd < 0) {
@@ -2210,7 +2208,7 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
 
         data_len = MIN(remaining, SD_DATA_OBJ_SIZE - offset);
 
-        vmstate_oid = vid_to_vmstate_oid(s->inode.vdi_id, vdi_index);
+        vmstate_oid = vid_to_vmstate_oid(vdi_id, vdi_index);
 
         create = (offset == 0);
         if (load) {
commit b579ffb3fd64243b64ac5aaf659ac88518f17835
Author: Liu Yuan <namei.unix at gmail.com>
Date:   Sat Jun 8 01:54:25 2013 +0800

    sheepdog: fix snapshot tag initialization
    
    This is an old and obvious bug. We should pass snapshot_id to the
    tag. Or simple command like 'qemu-img snapshot -a tag sheepdog:image' will fail
    
    Cc: qemu-devel at nongnu.org
    Cc: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
    Cc: Kevin Wolf <kwolf at redhat.com>
    Cc: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Liu Yuan <namei.unix at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/sheepdog.c b/block/sheepdog.c
index 21a4edf..94218ac 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -2063,7 +2063,7 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
     if (snapid) {
         tag[0] = 0;
     } else {
-        pstrcpy(tag, sizeof(tag), s->name);
+        pstrcpy(tag, sizeof(tag), snapshot_id);
     }
 
     ret = reload_inode(s, snapid, tag);
commit dbfbc6373441e436ac6e2bcf7a8acb284225aa21
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Fri Jun 7 14:37:54 2013 -0400

    qerror: drop QERR_OPEN_FILE_FAILED macro
    
    Not used since the last commit.
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Acked-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index 6c0a18d..c30c2f6 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -177,9 +177,6 @@ void assert_no_error(Error *err);
 #define QERR_NOT_SUPPORTED \
     ERROR_CLASS_GENERIC_ERROR, "Not supported"
 
-#define QERR_OPEN_FILE_FAILED \
-    ERROR_CLASS_GENERIC_ERROR, "Could not open '%s'"
-
 #define QERR_PERMISSION_DENIED \
     ERROR_CLASS_GENERIC_ERROR, "Insufficient permission to perform this operation"
 
commit d8b6895f7a8e5bcc5be1557e8048db43882f3b33
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Mon Jun 10 11:29:27 2013 -0400

    block: bdrv_reopen_prepare(): don't use QERR_OPEN_FILE_FAILED
    
    The call to drv->bdrv_reopen_prepare() can fail due to reasons
    other than an open failure. Unfortunately, we can't use errno
    nor -ret, cause they are not always set.
    
    Stick to a generic error message then.
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Acked-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index 79ad33d..b88ad2f 100644
--- a/block.c
+++ b/block.c
@@ -1291,8 +1291,8 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
             if (local_err != NULL) {
                 error_propagate(errp, local_err);
             } else {
-                error_set(errp, QERR_OPEN_FILE_FAILED,
-                          reopen_state->bs->filename);
+                error_setg(errp, "failed while preparing to reopen image '%s'",
+                           reopen_state->bs->filename);
             }
             goto error;
         }
commit 1befce9652a1b7cfca0191b3031fae3cbce26ef0
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Fri Jun 7 14:36:58 2013 -0400

    savevm: qmp_xen_save_devices_state(): use error_setg_file_open()
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Acked-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/savevm.c b/savevm.c
index 2ce439f..ff5ece6 100644
--- a/savevm.c
+++ b/savevm.c
@@ -2410,7 +2410,7 @@ void qmp_xen_save_devices_state(const char *filename, Error **errp)
 
     f = qemu_fopen(filename, "wb");
     if (!f) {
-        error_set(errp, QERR_OPEN_FILE_FAILED, filename);
+        error_setg_file_open(errp, errno, filename);
         goto the_end;
     }
     ret = qemu_save_device_state(f);
commit 7581766b719afd63dcf922ddbf982291f596ed12
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Fri Jun 7 14:36:01 2013 -0400

    dump: qmp_dump_guest_memory(): use error_setg_file_open()
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Acked-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/dump.c b/dump.c
index 44a1339..c812cfa 100644
--- a/dump.c
+++ b/dump.c
@@ -853,7 +853,7 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
     if  (strstart(file, "file:", &p)) {
         fd = qemu_open(p, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR);
         if (fd < 0) {
-            error_set(errp, QERR_OPEN_FILE_FAILED, p);
+            error_setg_file_open(errp, errno, p);
             return;
         }
     }
commit 618da851ec8059460be8e0670bc835d3c2003708
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Fri Jun 7 14:35:06 2013 -0400

    cpus: use error_setg_file_open()
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Acked-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/cpus.c b/cpus.c
index c232265..c8bc8ad 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1278,7 +1278,7 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
 
     f = fopen(filename, "wb");
     if (!f) {
-        error_set(errp, QERR_OPEN_FILE_FAILED, filename);
+        error_setg_file_open(errp, errno, filename);
         return;
     }
 
@@ -1308,7 +1308,7 @@ void qmp_pmemsave(int64_t addr, int64_t size, const char *filename,
 
     f = fopen(filename, "wb");
     if (!f) {
-        error_set(errp, QERR_OPEN_FILE_FAILED, filename);
+        error_setg_file_open(errp, errno, filename);
         return;
     }
 
commit 0eef407c7b4130d13138c1f75d9975165433f654
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Fri Jun 7 14:33:48 2013 -0400

    blockdev: use error_setg_file_open()
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Acked-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/blockdev.c b/blockdev.c
index 9937311..5975dde 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -899,7 +899,7 @@ static void external_snapshot_prepare(BlkTransactionStates *common,
     ret = bdrv_open(states->new_bs, new_image_file, NULL,
                     flags | BDRV_O_NO_BACKING, drv);
     if (ret != 0) {
-        error_set(errp, QERR_OPEN_FILE_FAILED, new_image_file);
+        error_setg_file_open(errp, -ret, new_image_file);
     }
 }
 
@@ -1062,8 +1062,11 @@ static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename,
                                     int bdrv_flags, BlockDriver *drv,
                                     const char *password, Error **errp)
 {
-    if (bdrv_open(bs, filename, NULL, bdrv_flags, drv) < 0) {
-        error_set(errp, QERR_OPEN_FILE_FAILED, filename);
+    int ret;
+
+    ret = bdrv_open(bs, filename, NULL, bdrv_flags, drv);
+    if (ret < 0) {
+        error_setg_file_open(errp, -ret, filename);
         return;
     }
 
@@ -1483,7 +1486,7 @@ void qmp_drive_mirror(const char *device, const char *target,
 
     if (ret < 0) {
         bdrv_delete(target_bs);
-        error_set(errp, QERR_OPEN_FILE_FAILED, target);
+        error_setg_file_open(errp, -ret, target);
         return;
     }
 
commit dacc26aae5d291317a3277970a4f39a562939a78
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Fri Jun 7 14:31:46 2013 -0400

    block: mirror_complete(): use error_setg_file_open()
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Acked-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/mirror.c b/block/mirror.c
index 8b07dec..1ae724f 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -512,7 +512,7 @@ static void mirror_complete(BlockJob *job, Error **errp)
         char backing_filename[PATH_MAX];
         bdrv_get_full_backing_filename(s->target, backing_filename,
                                        sizeof(backing_filename));
-        error_set(errp, QERR_OPEN_FILE_FAILED, backing_filename);
+        error_setg_file_open(errp, -ret, backing_filename);
         return;
     }
     if (!s->synced) {
commit bc5741add11113ee8febdcf33931ec3afe10c729
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Fri Jun 7 14:28:02 2013 -0400

    rng-random: use error_setg_file_open()
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Acked-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/backends/rng-random.c b/backends/rng-random.c
index 830360c..68dfc8a 100644
--- a/backends/rng-random.c
+++ b/backends/rng-random.c
@@ -78,9 +78,8 @@ static void rng_random_opened(RngBackend *b, Error **errp)
                   "filename", "a valid filename");
     } else {
         s->fd = qemu_open(s->filename, O_RDONLY | O_NONBLOCK);
-
         if (s->fd == -1) {
-            error_set(errp, QERR_OPEN_FILE_FAILED, s->filename);
+            error_setg_file_open(errp, errno, s->filename);
         }
     }
 }
commit 54028d7542cffe97c4685994baac66988c4b7db9
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Fri Jun 7 14:24:49 2013 -0400

    error: add error_setg_file_open() helper
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Acked-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/include/qapi/error.h b/include/qapi/error.h
index 5cd2f0c..ffd1cea 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -45,6 +45,11 @@ void error_set_errno(Error **err, int os_error, ErrorClass err_class, const char
     error_set_errno(err, os_error, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
 
 /**
+ * Helper for open() errors
+ */
+void error_setg_file_open(Error **errp, int os_errno, const char *filename);
+
+/**
  * Returns true if an indirect pointer to an error is pointing to a valid
  * error object.
  */
diff --git a/util/error.c b/util/error.c
index 519f6b6..53b0435 100644
--- a/util/error.c
+++ b/util/error.c
@@ -71,6 +71,11 @@ void error_set_errno(Error **errp, int os_errno, ErrorClass err_class,
     *errp = err;
 }
 
+void error_setg_file_open(Error **errp, int os_errno, const char *filename)
+{
+    error_setg_errno(errp, os_errno, "Could not open '%s'", filename);
+}
+
 Error *error_copy(const Error *err)
 {
     Error *err_new;
commit 38aea177d93556aada7c4c7aa530f0050715e293
Merge: b7a3b1c 187f1bc
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Jun 17 08:57:56 2013 -0500

    Merge remote-tracking branch 'pmaydell/configury.next' into staging
    
    # By Paolo Bonzini (4) and others
    # Via Peter Maydell
    * pmaydell/configury.next:
      ppc: Remove CONFIG_FDT conditionals
      microblaze: Remove CONFIG_FDT conditionals
      arm: Remove CONFIG_FDT conditionals
      configure: Require libfdt for arm, ppc, microblaze softmmu targets
      configure: dtc: Probe for libfdt_env.h
      build: drop TARGET_TYPE
      main: use TARGET_ARCH only for the target-specific #define
      build: do not use TARGET_ARCH
      build: rename TARGET_ARCH2 to TARGET_NAME
      Add a stp file for usage from build directory
    
    Message-id: 1371221594-11556-1-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit b7a3b1cde2127f70d9fc24b7c99fbbc3899afab5
Merge: 030b4b7 b165b0d
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Jun 17 08:57:07 2013 -0500

    Merge remote-tracking branch 'mjt/trivial-patches' into staging
    
    # By Michael Tokarev (1) and Vladimir Senkov (1)
    # Via Michael Tokarev
    * mjt/trivial-patches:
      char/serial: fix copy&paste error (fifo8_is_full vs empty)
      vl: always define no_frame
    
    Message-id: 1371455050-9523-1-git-send-email-mjt at msgid.tls.msk.ru
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit b165b0d8e62bb65a02d7670d75ebb77a9280bde1
Author: Vladimir Senkov <hangup at gmail.com>
Date:   Sun Jun 16 20:30:52 2013 -0400

    char/serial: fix copy&paste error (fifo8_is_full vs empty)
    
    Copy&paste error in serial.c causes a crash when attempting
    to read from UART (if there is no data to be read)
    
    Signed-off-by: Vladimir Senkov <hangup at gmail.com>
    Reviewed-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/char/serial.c b/hw/char/serial.c
index b537e42..6382f98 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -424,7 +424,7 @@ static uint64_t serial_ioport_read(void *opaque, hwaddr addr, unsigned size)
             ret = s->divider & 0xff;
         } else {
             if(s->fcr & UART_FCR_FE) {
-                ret = fifo8_is_full(&s->recv_fifo) ?
+                ret = fifo8_is_empty(&s->recv_fifo) ?
                             0 : fifo8_pop(&s->recv_fifo);
                 if (s->recv_fifo.num == 0) {
                     s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
commit 616404cd42db5f683d49772dcc2c53c8f6466024
Author: Michael Tokarev <mjt at tls.msk.ru>
Date:   Sat Jun 15 14:36:22 2013 +0400

    vl: always define no_frame
    
    Commit 047d4e151dd46 "Unbreak -no-quit for GTK, validate SDL options" broke
    build of qemu without sdl, by referencing `no_frame' variable which is defined
    inside #if SDL block.  Fix that by defining that variable unconditionally.
    
    This is a better fix for the build issue introduced by that patch than
    a revert.  This change keeps the new functinality introduced by that patch
    and just fixes the compilation.  It still is not a complete fix around the
    original issue (not working -no-frame et al with -display gtk), because it
    makes only the legacy interface working, not the new suboption interface,
    so a few more changes are needed.
    
    Cc: Peter Wu <lekensteyn at gmail.com>
    Cc: qemu-trivial at nongnu.org
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>
    Reviewed-by: Peter Wu <lekensteyn at gmail.com>

diff --git a/vl.c b/vl.c
index 9f8fd6e..f94ec9c 100644
--- a/vl.c
+++ b/vl.c
@@ -199,9 +199,7 @@ static int rtc_date_offset = -1; /* -1 means no change */
 QEMUClock *rtc_clock;
 int vga_interface_type = VGA_NONE;
 static int full_screen = 0;
-#ifdef CONFIG_SDL
 static int no_frame = 0;
-#endif
 int no_quit = 0;
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
commit 030b4b7debf659dcd6fc66826564285fdce5057d
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sun Jun 16 16:13:07 2013 +0200

    gtk: Fix compiler warning (GTK 3 deprecated function)
    
    With GTK 3, the function gdk_cursor_unref is deprecated:
    
    qemu/ui/gtk.c: In function ‘gd_cursor_define’:
    qemu/ui/gtk.c:380:5: error:
     ‘gdk_cursor_unref’ is deprecated (declared at /usr/include/gtk-3.0/gdk/gdkcursor.h:233): Use 'g_object_unref' instead [-Werror=deprecated-declarations]
    
    Fix the gcc compiler warning by using conditional compilation.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Message-id: 1371391987-10795-1-git-send-email-sw at weilnetz.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/ui/gtk.c b/ui/gtk.c
index 50a6993..7310e20 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -377,7 +377,11 @@ static void gd_cursor_define(DisplayChangeListener *dcl,
                                         pixbuf, c->hot_x, c->hot_y);
     gdk_window_set_cursor(gtk_widget_get_window(s->drawing_area), cursor);
     g_object_unref(pixbuf);
+#if !GTK_CHECK_VERSION(3, 0, 0)
     gdk_cursor_unref(cursor);
+#else
+    g_object_unref(cursor);
+#endif
 }
 
 static void gd_switch(DisplayChangeListener *dcl,
commit a1077090cea97df26a754d16d7c9e1d410d81eaa
Author: Michael Tokarev <mjt at tls.msk.ru>
Date:   Sat Jun 15 14:42:03 2013 +0400

    vl: always define no_frame
    
    Commit 047d4e151dd46 "Unbreak -no-quit for GTK, validate SDL options" broke
    build of qemu without sdl, by referencing `no_frame' variable which is defined
    inside #if SDL block.  Fix that by defining that variable unconditionally.
    
    This is a better fix for the build issue introduced by that patch than
    a revert.  This change keeps the new functinality introduced by that patch
    and just fixes the compilation.  It still is not a complete fix around the
    original issue (not working -no-frame et al with -display gtk), because it
    makes only the legacy interface working, not the new suboption interface,
    so a few more changes are needed.
    
    Cc: Peter Wu <lekensteyn at gmail.com>
    Cc: qemu-trivial at nongnu.org
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>
    Reviewed-by: Peter Wu <lekensteyn at gmail.com>
    Tested-by: Andreas Färber <afaerber at suse.de>
    Message-id: 1371292923-28105-1-git-send-email-mjt at msgid.tls.msk.ru
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/vl.c b/vl.c
index 9f8fd6e..f94ec9c 100644
--- a/vl.c
+++ b/vl.c
@@ -199,9 +199,7 @@ static int rtc_date_offset = -1; /* -1 means no change */
 QEMUClock *rtc_clock;
 int vga_interface_type = VGA_NONE;
 static int full_screen = 0;
-#ifdef CONFIG_SDL
 static int no_frame = 0;
-#endif
 int no_quit = 0;
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
commit 90a2541b763b31d2b551b07e24aae3de5266d31b
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Tue May 28 16:21:10 2013 +0800

    target-i386: fix over 80 chars warnings
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index 4ee618d..e345f9a 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -122,7 +122,8 @@ void helper_cpuid(CPUX86State *env)
 
     cpu_svm_check_intercept_param(env, SVM_EXIT_CPUID, 0);
 
-    cpu_x86_cpuid(env, (uint32_t)env->regs[R_EAX], (uint32_t)env->regs[R_ECX], &eax, &ebx, &ecx, &edx);
+    cpu_x86_cpuid(env, (uint32_t)env->regs[R_EAX], (uint32_t)env->regs[R_ECX],
+                  &eax, &ebx, &ecx, &edx);
     env->regs[R_EAX] = eax;
     env->regs[R_EBX] = ebx;
     env->regs[R_ECX] = ecx;
@@ -271,7 +272,8 @@ void helper_wrmsr(CPUX86State *env)
 
     cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1);
 
-    val = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
+    val = ((uint32_t)env->regs[R_EAX]) |
+        ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
 
     switch ((uint32_t)env->regs[R_ECX]) {
     case MSR_IA32_SYSENTER_CS:
@@ -350,7 +352,8 @@ void helper_wrmsr(CPUX86State *env)
     case MSR_MTRRphysBase(5):
     case MSR_MTRRphysBase(6):
     case MSR_MTRRphysBase(7):
-        env->mtrr_var[((uint32_t)env->regs[R_ECX] - MSR_MTRRphysBase(0)) / 2].base = val;
+        env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+                       MSR_MTRRphysBase(0)) / 2].base = val;
         break;
     case MSR_MTRRphysMask(0):
     case MSR_MTRRphysMask(1):
@@ -360,14 +363,17 @@ void helper_wrmsr(CPUX86State *env)
     case MSR_MTRRphysMask(5):
     case MSR_MTRRphysMask(6):
     case MSR_MTRRphysMask(7):
-        env->mtrr_var[((uint32_t)env->regs[R_ECX] - MSR_MTRRphysMask(0)) / 2].mask = val;
+        env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+                       MSR_MTRRphysMask(0)) / 2].mask = val;
         break;
     case MSR_MTRRfix64K_00000:
-        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - MSR_MTRRfix64K_00000] = val;
+        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+                        MSR_MTRRfix64K_00000] = val;
         break;
     case MSR_MTRRfix16K_80000:
     case MSR_MTRRfix16K_A0000:
-        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - MSR_MTRRfix16K_80000 + 1] = val;
+        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+                        MSR_MTRRfix16K_80000 + 1] = val;
         break;
     case MSR_MTRRfix4K_C0000:
     case MSR_MTRRfix4K_C8000:
@@ -377,7 +383,8 @@ void helper_wrmsr(CPUX86State *env)
     case MSR_MTRRfix4K_E8000:
     case MSR_MTRRfix4K_F0000:
     case MSR_MTRRfix4K_F8000:
-        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - MSR_MTRRfix4K_C0000 + 3] = val;
+        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+                        MSR_MTRRfix4K_C0000 + 3] = val;
         break;
     case MSR_MTRRdefType:
         env->mtrr_deftype = val;
@@ -399,7 +406,8 @@ void helper_wrmsr(CPUX86State *env)
         break;
     default:
         if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL
-            && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
+            && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL +
+            (4 * env->mcg_cap & 0xff)) {
             uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL;
             if ((offset & 0x3) != 0
                 || (val == 0 || val == ~(uint64_t)0)) {
@@ -480,7 +488,8 @@ void helper_rdmsr(CPUX86State *env)
     case MSR_MTRRphysBase(5):
     case MSR_MTRRphysBase(6):
     case MSR_MTRRphysBase(7):
-        val = env->mtrr_var[((uint32_t)env->regs[R_ECX] - MSR_MTRRphysBase(0)) / 2].base;
+        val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+                             MSR_MTRRphysBase(0)) / 2].base;
         break;
     case MSR_MTRRphysMask(0):
     case MSR_MTRRphysMask(1):
@@ -490,14 +499,16 @@ void helper_rdmsr(CPUX86State *env)
     case MSR_MTRRphysMask(5):
     case MSR_MTRRphysMask(6):
     case MSR_MTRRphysMask(7):
-        val = env->mtrr_var[((uint32_t)env->regs[R_ECX] - MSR_MTRRphysMask(0)) / 2].mask;
+        val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+                             MSR_MTRRphysMask(0)) / 2].mask;
         break;
     case MSR_MTRRfix64K_00000:
         val = env->mtrr_fixed[0];
         break;
     case MSR_MTRRfix16K_80000:
     case MSR_MTRRfix16K_A0000:
-        val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - MSR_MTRRfix16K_80000 + 1];
+        val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+                              MSR_MTRRfix16K_80000 + 1];
         break;
     case MSR_MTRRfix4K_C0000:
     case MSR_MTRRfix4K_C8000:
@@ -507,7 +518,8 @@ void helper_rdmsr(CPUX86State *env)
     case MSR_MTRRfix4K_E8000:
     case MSR_MTRRfix4K_F0000:
     case MSR_MTRRfix4K_F8000:
-        val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - MSR_MTRRfix4K_C0000 + 3];
+        val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+                              MSR_MTRRfix4K_C0000 + 3];
         break;
     case MSR_MTRRdefType:
         val = env->mtrr_deftype;
@@ -539,7 +551,8 @@ void helper_rdmsr(CPUX86State *env)
         break;
     default:
         if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL
-            && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
+            && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL +
+            (4 * env->mcg_cap & 0xff)) {
             uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL;
             val = env->mce_banks[offset];
             break;
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 939d7dc..9c799e1 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -1811,9 +1811,9 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
         if (!(e2 & DESC_C_MASK) && dpl < cpl) {
             /* to inner privilege */
             get_ss_esp_from_tss(env, &ss, &sp, dpl);
-            LOG_PCALL("new ss:esp=%04x:%08x param_count=%d env->regs[R_ESP]=" TARGET_FMT_lx
-                      "\n",
-                      ss, sp, param_count, env->regs[R_ESP]);
+            LOG_PCALL("new ss:esp=%04x:%08x param_count=%d env->regs[R_ESP]="
+                      TARGET_FMT_lx "\n", ss, sp, param_count,
+                      env->regs[R_ESP]);
             if ((ss & 0xfffc) == 0) {
                 raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
             }
@@ -1847,16 +1847,18 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
                 PUSHL(ssp, sp, sp_mask, env->segs[R_SS].selector);
                 PUSHL(ssp, sp, sp_mask, env->regs[R_ESP]);
                 for (i = param_count - 1; i >= 0; i--) {
-                    val = cpu_ldl_kernel(env, old_ssp + ((env->regs[R_ESP] + i * 4) &
-                                                         old_sp_mask));
+                    val = cpu_ldl_kernel(env, old_ssp +
+                                         ((env->regs[R_ESP] + i * 4) &
+                                          old_sp_mask));
                     PUSHL(ssp, sp, sp_mask, val);
                 }
             } else {
                 PUSHW(ssp, sp, sp_mask, env->segs[R_SS].selector);
                 PUSHW(ssp, sp, sp_mask, env->regs[R_ESP]);
                 for (i = param_count - 1; i >= 0; i--) {
-                    val = cpu_lduw_kernel(env, old_ssp + ((env->regs[R_ESP] + i * 2) &
-                                                          old_sp_mask));
+                    val = cpu_lduw_kernel(env, old_ssp +
+                                          ((env->regs[R_ESP] + i * 2) &
+                                           old_sp_mask));
                     PUSHW(ssp, sp, sp_mask, val);
                 }
             }
diff --git a/target-i386/svm_helper.c b/target-i386/svm_helper.c
index e18fa35..4a7de42 100644
--- a/target-i386/svm_helper.c
+++ b/target-i386/svm_helper.c
@@ -658,8 +658,10 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
                        R_DS);
 
     env->eip = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip));
-    env->regs[R_ESP] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp));
-    env->regs[R_EAX] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax));
+    env->regs[R_ESP] = ldq_phys(env->vm_hsave +
+                                offsetof(struct vmcb, save.rsp));
+    env->regs[R_EAX] = ldq_phys(env->vm_hsave +
+                                offsetof(struct vmcb, save.rax));
 
     env->dr[6] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr6));
     env->dr[7] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr7));
commit 0bc60a8ae076402fbdbd2d6334bbe6ea88b428ff
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Tue May 28 16:21:09 2013 +0800

    target-i386/helper: remove redundant env->eip assignment
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-i386/svm_helper.c b/target-i386/svm_helper.c
index 649be02..e18fa35 100644
--- a/target-i386/svm_helper.c
+++ b/target-i386/svm_helper.c
@@ -249,7 +249,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
                        R_DS);
 
     env->eip = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip));
-    env->eip = env->eip;
+
     env->regs[R_ESP] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp));
     env->regs[R_EAX] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax));
     env->dr[7] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr7));
commit 80cf2c81a1be732cf1ce4a810ddc7721714d684e
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Tue May 28 16:21:08 2013 +0800

    target-i386/helper: remove DF macro
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/cpu-exec.c b/cpu-exec.c
index 31c089d..ec46380 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -230,7 +230,7 @@ int cpu_exec(CPUArchState *env)
 #if defined(TARGET_I386)
     /* put eflags in CPU temporary format */
     CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-    DF = 1 - (2 * ((env->eflags >> 10) & 1));
+    env->df = 1 - (2 * ((env->eflags >> 10) & 1));
     CC_OP = CC_OP_EFLAGS;
     env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
 #elif defined(TARGET_SPARC)
@@ -681,7 +681,7 @@ int cpu_exec(CPUArchState *env)
 #if defined(TARGET_I386)
     /* restore flags in standard format */
     env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP)
-        | (DF & DF_MASK);
+        | (env->df & DF_MASK);
 #elif defined(TARGET_ARM)
     /* XXX: Save/restore host fpu exception state?.  */
 #elif defined(TARGET_UNICORE32)
diff --git a/target-i386/cc_helper.c b/target-i386/cc_helper.c
index 9daa1a0..ee04092 100644
--- a/target-i386/cc_helper.c
+++ b/target-i386/cc_helper.c
@@ -331,7 +331,7 @@ target_ulong helper_read_eflags(CPUX86State *env)
     uint32_t eflags;
 
     eflags = cpu_cc_compute_all(env, CC_OP);
-    eflags |= (DF & DF_MASK);
+    eflags |= (env->df & DF_MASK);
     eflags |= env->eflags & ~(VM_MASK | RF_MASK);
     return eflags;
 }
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index b909f73..62e3547 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1101,8 +1101,6 @@ static inline int cpu_mmu_index (CPUX86State *env)
         ? MMU_KSMAP_IDX : MMU_KERNEL_IDX;
 }
 
-#define DF  (env->df)
-
 #define CC_DST  (env->cc_dst)
 #define CC_SRC  (env->cc_src)
 #define CC_SRC2 (env->cc_src2)
@@ -1196,7 +1194,7 @@ uint32_t cpu_cc_compute_all(CPUX86State *env1, int op);
 
 static inline uint32_t cpu_compute_eflags(CPUX86State *env)
 {
-    return env->eflags | cpu_cc_compute_all(env, CC_OP) | (DF & DF_MASK);
+    return env->eflags | cpu_cc_compute_all(env, CC_OP) | (env->df & DF_MASK);
 }
 
 /* NOTE: CC_OP must be modified manually to CC_OP_EFLAGS */
@@ -1204,7 +1202,7 @@ static inline void cpu_load_eflags(CPUX86State *env, int eflags,
                                    int update_mask)
 {
     CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-    DF = 1 - (2 * ((eflags >> 10) & 1));
+    env->df = 1 - (2 * ((eflags >> 10) & 1));
     env->eflags = (env->eflags & ~update_mask) |
         (eflags & update_mask) | 0x2;
 }
commit a78d0eabd4ca05789a9604fe632b9399bf378fee
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Tue May 28 16:21:07 2013 +0800

    target-i386/helper: remove EIP macro
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 585776a..b909f73 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1101,8 +1101,6 @@ static inline int cpu_mmu_index (CPUX86State *env)
         ? MMU_KSMAP_IDX : MMU_KERNEL_IDX;
 }
 
-#undef EIP
-#define EIP (env->eip)
 #define DF  (env->df)
 
 #define CC_DST  (env->cc_dst)
diff --git a/target-i386/excp_helper.c b/target-i386/excp_helper.c
index 179ea82..5319aef 100644
--- a/target-i386/excp_helper.c
+++ b/target-i386/excp_helper.c
@@ -87,7 +87,7 @@ static int check_exception(CPUX86State *env, int intno, int *error_code)
 /*
  * Signal an interruption. It is executed in the main CPU loop.
  * is_int is TRUE if coming from the int instruction. next_eip is the
- * EIP value AFTER the interrupt instruction. It is only relevant if
+ * env->eip value AFTER the interrupt instruction. It is only relevant if
  * is_int is TRUE.
  */
 static void QEMU_NORETURN raise_interrupt2(CPUX86State *env, int intno,
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index 380e54e..4ee618d 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -569,7 +569,7 @@ void helper_hlt(CPUX86State *env, int next_eip_addend)
     X86CPU *cpu = x86_env_get_cpu(env);
 
     cpu_svm_check_intercept_param(env, SVM_EXIT_HLT, 0);
-    EIP += next_eip_addend;
+    env->eip += next_eip_addend;
 
     do_hlt(cpu);
 }
@@ -592,7 +592,7 @@ void helper_mwait(CPUX86State *env, int next_eip_addend)
         raise_exception(env, EXCP0D_GPF);
     }
     cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0);
-    EIP += next_eip_addend;
+    env->eip += next_eip_addend;
 
     cpu = x86_env_get_cpu(env);
     cs = CPU(cpu);
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 8b2766d..939d7dc 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -457,7 +457,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
         tss_load_seg(env, R_GS, new_segs[R_GS]);
     }
 
-    /* check that EIP is in the CS segment limits */
+    /* check that env->eip is in the CS segment limits */
     if (new_eip > env->segs[R_CS].limit) {
         /* XXX: different exception if CALL? */
         raise_exception_err(env, EXCP0D_GPF, 0);
@@ -1122,7 +1122,7 @@ static void do_interrupt_user(CPUX86State *env, int intno, int is_int,
        exiting the emulation with the suitable exception and error
        code */
     if (is_int) {
-        EIP = next_eip;
+        env->eip = next_eip;
     }
 }
 
@@ -1157,7 +1157,7 @@ static void handle_even_inj(CPUX86State *env, int intno, int is_int,
 
 /*
  * Begin execution of an interruption. is_int is TRUE if coming from
- * the int instruction. next_eip is the EIP value AFTER the interrupt
+ * the int instruction. next_eip is the env->eip value AFTER the interrupt
  * instruction. It is only relevant if is_int is TRUE.
  */
 static void do_interrupt_all(CPUX86State *env, int intno, int is_int,
@@ -1171,8 +1171,8 @@ static void do_interrupt_all(CPUX86State *env, int intno, int is_int,
                      " pc=" TARGET_FMT_lx " SP=%04x:" TARGET_FMT_lx,
                      count, intno, error_code, is_int,
                      env->hflags & HF_CPL_MASK,
-                     env->segs[R_CS].selector, EIP,
-                     (int)env->segs[R_CS].base + EIP,
+                     env->segs[R_CS].selector, env->eip,
+                     (int)env->segs[R_CS].base + env->eip,
                      env->segs[R_SS].selector, env->regs[R_ESP]);
             if (intno == 0x0e) {
                 qemu_log(" CR2=" TARGET_FMT_lx, env->cr[2]);
@@ -1584,7 +1584,7 @@ void helper_ljmp_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
         }
         cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
                        get_seg_base(e1, e2), limit, e2);
-        EIP = new_eip;
+        env->eip = new_eip;
     } else {
         /* jump to call or task gate */
         dpl = (e2 >> DESC_DPL_SHIFT) & 3;
@@ -1637,7 +1637,7 @@ void helper_ljmp_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
             }
             cpu_x86_load_seg_cache(env, R_CS, (gate_cs & 0xfffc) | cpl,
                                    get_seg_base(e1, e2), limit, e2);
-            EIP = new_eip;
+            env->eip = new_eip;
             break;
         default:
             raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
@@ -1731,7 +1731,7 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
             cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
                                    get_seg_base(e1, e2),
                                    get_seg_limit(e1, e2), e2);
-            EIP = new_eip;
+            env->eip = new_eip;
         } else
 #endif
         {
@@ -1754,7 +1754,7 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
             SET_ESP(sp, sp_mask);
             cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
                                    get_seg_base(e1, e2), limit, e2);
-            EIP = new_eip;
+            env->eip = new_eip;
         }
     } else {
         /* check gate type */
@@ -1895,7 +1895,7 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
                        e2);
         cpu_x86_set_cpl(env, dpl);
         SET_ESP(sp, sp_mask);
-        EIP = offset;
+        env->eip = offset;
     }
 }
 
@@ -2251,7 +2251,7 @@ void helper_sysenter(CPUX86State *env)
                            DESC_S_MASK |
                            DESC_W_MASK | DESC_A_MASK);
     env->regs[R_ESP] = env->sysenter_esp;
-    EIP = env->sysenter_eip;
+    env->eip = env->sysenter_eip;
 }
 
 void helper_sysexit(CPUX86State *env, int dflag)
@@ -2291,7 +2291,7 @@ void helper_sysexit(CPUX86State *env, int dflag)
                                DESC_W_MASK | DESC_A_MASK);
     }
     env->regs[R_ESP] = env->regs[R_ECX];
-    EIP = env->regs[R_EDX];
+    env->eip = env->regs[R_EDX];
 }
 
 target_ulong helper_lsl(CPUX86State *env, target_ulong selector1)
diff --git a/target-i386/svm_helper.c b/target-i386/svm_helper.c
index 5706026..649be02 100644
--- a/target-i386/svm_helper.c
+++ b/target-i386/svm_helper.c
@@ -170,7 +170,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
                  &env->segs[R_DS]);
 
     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip),
-             EIP + next_eip_addend);
+             env->eip + next_eip_addend);
     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp), env->regs[R_ESP]);
     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax), env->regs[R_EAX]);
 
@@ -248,8 +248,8 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
     svm_load_seg_cache(env, env->vm_vmcb + offsetof(struct vmcb, save.ds),
                        R_DS);
 
-    EIP = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip));
-    env->eip = EIP;
+    env->eip = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip));
+    env->eip = env->eip;
     env->regs[R_ESP] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp));
     env->regs[R_EAX] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax));
     env->dr[7] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr7));
@@ -302,7 +302,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
             env->exception_index = EXCP02_NMI;
             env->error_code = event_inj_err;
             env->exception_is_int = 0;
-            env->exception_next_eip = EIP;
+            env->exception_next_eip = env->eip;
             qemu_log_mask(CPU_LOG_TB_IN_ASM, "NMI");
             cpu_loop_exit(env);
             break;
@@ -318,7 +318,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
             env->exception_index = vector;
             env->error_code = event_inj_err;
             env->exception_is_int = 1;
-            env->exception_next_eip = EIP;
+            env->exception_next_eip = env->eip;
             qemu_log_mask(CPU_LOG_TB_IN_ASM, "SOFT");
             cpu_loop_exit(env);
             break;
@@ -539,7 +539,7 @@ void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param,
         uint16_t mask = (1 << ((param >> 4) & 7)) - 1;
 
         if (lduw_phys(addr + port / 8) & (mask << (port & 7))) {
-            /* next EIP */
+            /* next env->eip */
             stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
                      env->eip + next_eip_addend);
             helper_vmexit(env, SVM_EXIT_IOIO, param | (port << 16));
@@ -558,7 +558,7 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
                   exit_code, exit_info_1,
                   ldq_phys(env->vm_vmcb + offsetof(struct vmcb,
                                                    control.exit_info_2)),
-                  EIP);
+                  env->eip);
 
     if (env->hflags & HF_INHIBIT_IRQ_MASK) {
         stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_state),
@@ -657,7 +657,7 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
     svm_load_seg_cache(env, env->vm_hsave + offsetof(struct vmcb, save.ds),
                        R_DS);
 
-    EIP = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip));
+    env->eip = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip));
     env->regs[R_ESP] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp));
     env->regs[R_EAX] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax));
 
commit cf75c5977c01060d344eb804abf81e938d33105b
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Tue May 28 16:21:06 2013 +0800

    target-i386/helper: remove EDI macro
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index e287290..585776a 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1101,8 +1101,6 @@ static inline int cpu_mmu_index (CPUX86State *env)
         ? MMU_KSMAP_IDX : MMU_KERNEL_IDX;
 }
 
-#undef EDI
-#define EDI (env->regs[R_EDI])
 #undef EIP
 #define EIP (env->eip)
 #define DF  (env->df)
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 0e02eda..8b2766d 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -331,7 +331,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
         cpu_stl_kernel(env, env->tr.base + (0x28 + 4 * 4), env->regs[R_ESP]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 5 * 4), env->regs[R_EBP]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 6 * 4), env->regs[R_ESI]);
-        cpu_stl_kernel(env, env->tr.base + (0x28 + 7 * 4), EDI);
+        cpu_stl_kernel(env, env->tr.base + (0x28 + 7 * 4), env->regs[R_EDI]);
         for (i = 0; i < 6; i++) {
             cpu_stw_kernel(env, env->tr.base + (0x48 + i * 4),
                            env->segs[i].selector);
@@ -347,7 +347,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
         cpu_stw_kernel(env, env->tr.base + (0x12 + 4 * 2), env->regs[R_ESP]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 5 * 2), env->regs[R_EBP]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 6 * 2), env->regs[R_ESI]);
-        cpu_stw_kernel(env, env->tr.base + (0x12 + 7 * 2), EDI);
+        cpu_stw_kernel(env, env->tr.base + (0x12 + 7 * 2), env->regs[R_EDI]);
         for (i = 0; i < 4; i++) {
             cpu_stw_kernel(env, env->tr.base + (0x22 + i * 4),
                            env->segs[i].selector);
@@ -403,7 +403,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
     env->regs[R_ESP] = new_regs[4];
     env->regs[R_EBP] = new_regs[5];
     env->regs[R_ESI] = new_regs[6];
-    EDI = new_regs[7];
+    env->regs[R_EDI] = new_regs[7];
     if (new_eflags & VM_MASK) {
         for (i = 0; i < 6; i++) {
             load_seg_vm(env, i, new_segs[i]);
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index d051f03..2489573 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -89,7 +89,7 @@ void do_smm_enter(CPUX86State *env)
     stq_phys(sm_state + 0x7fd8, env->regs[R_ESP]);
     stq_phys(sm_state + 0x7fd0, env->regs[R_EBP]);
     stq_phys(sm_state + 0x7fc8, env->regs[R_ESI]);
-    stq_phys(sm_state + 0x7fc0, EDI);
+    stq_phys(sm_state + 0x7fc0, env->regs[R_EDI]);
     for (i = 8; i < 16; i++) {
         stq_phys(sm_state + 0x7ff8 - i * 8, env->regs[i]);
     }
@@ -109,7 +109,7 @@ void do_smm_enter(CPUX86State *env)
     stl_phys(sm_state + 0x7ff8, env->cr[3]);
     stl_phys(sm_state + 0x7ff4, cpu_compute_eflags(env));
     stl_phys(sm_state + 0x7ff0, env->eip);
-    stl_phys(sm_state + 0x7fec, EDI);
+    stl_phys(sm_state + 0x7fec, env->regs[R_EDI]);
     stl_phys(sm_state + 0x7fe8, env->regs[R_ESI]);
     stl_phys(sm_state + 0x7fe4, env->regs[R_EBP]);
     stl_phys(sm_state + 0x7fe0, env->regs[R_ESP]);
@@ -220,7 +220,7 @@ void helper_rsm(CPUX86State *env)
     env->regs[R_ESP] = ldq_phys(sm_state + 0x7fd8);
     env->regs[R_EBP] = ldq_phys(sm_state + 0x7fd0);
     env->regs[R_ESI] = ldq_phys(sm_state + 0x7fc8);
-    EDI = ldq_phys(sm_state + 0x7fc0);
+    env->regs[R_EDI] = ldq_phys(sm_state + 0x7fc0);
     for (i = 8; i < 16; i++) {
         env->regs[i] = ldq_phys(sm_state + 0x7ff8 - i * 8);
     }
@@ -244,7 +244,7 @@ void helper_rsm(CPUX86State *env)
     cpu_load_eflags(env, ldl_phys(sm_state + 0x7ff4),
                     ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
     env->eip = ldl_phys(sm_state + 0x7ff0);
-    EDI = ldl_phys(sm_state + 0x7fec);
+    env->regs[R_EDI] = ldl_phys(sm_state + 0x7fec);
     env->regs[R_ESI] = ldl_phys(sm_state + 0x7fe8);
     env->regs[R_EBP] = ldl_phys(sm_state + 0x7fe4);
     env->regs[R_ESP] = ldl_phys(sm_state + 0x7fe0);
commit 78c3c6d34a94885c8d7e83ab282062ab642af75b
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Tue May 28 16:21:05 2013 +0800

    target-i386/helper: remove ESI macro
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 6b058bb..e287290 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1101,8 +1101,6 @@ static inline int cpu_mmu_index (CPUX86State *env)
         ? MMU_KSMAP_IDX : MMU_KERNEL_IDX;
 }
 
-#undef ESI
-#define ESI (env->regs[R_ESI])
 #undef EDI
 #define EDI (env->regs[R_EDI])
 #undef EIP
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 0c4b3d8..0e02eda 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -330,7 +330,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
         cpu_stl_kernel(env, env->tr.base + (0x28 + 3 * 4), env->regs[R_EBX]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 4 * 4), env->regs[R_ESP]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 5 * 4), env->regs[R_EBP]);
-        cpu_stl_kernel(env, env->tr.base + (0x28 + 6 * 4), ESI);
+        cpu_stl_kernel(env, env->tr.base + (0x28 + 6 * 4), env->regs[R_ESI]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 7 * 4), EDI);
         for (i = 0; i < 6; i++) {
             cpu_stw_kernel(env, env->tr.base + (0x48 + i * 4),
@@ -346,7 +346,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
         cpu_stw_kernel(env, env->tr.base + (0x12 + 3 * 2), env->regs[R_EBX]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 4 * 2), env->regs[R_ESP]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 5 * 2), env->regs[R_EBP]);
-        cpu_stw_kernel(env, env->tr.base + (0x12 + 6 * 2), ESI);
+        cpu_stw_kernel(env, env->tr.base + (0x12 + 6 * 2), env->regs[R_ESI]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 7 * 2), EDI);
         for (i = 0; i < 4; i++) {
             cpu_stw_kernel(env, env->tr.base + (0x22 + i * 4),
@@ -402,7 +402,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
     env->regs[R_EBX] = new_regs[3];
     env->regs[R_ESP] = new_regs[4];
     env->regs[R_EBP] = new_regs[5];
-    ESI = new_regs[6];
+    env->regs[R_ESI] = new_regs[6];
     EDI = new_regs[7];
     if (new_eflags & VM_MASK) {
         for (i = 0; i < 6; i++) {
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index 50c5d99..d051f03 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -88,7 +88,7 @@ void do_smm_enter(CPUX86State *env)
     stq_phys(sm_state + 0x7fe0, env->regs[R_EBX]);
     stq_phys(sm_state + 0x7fd8, env->regs[R_ESP]);
     stq_phys(sm_state + 0x7fd0, env->regs[R_EBP]);
-    stq_phys(sm_state + 0x7fc8, ESI);
+    stq_phys(sm_state + 0x7fc8, env->regs[R_ESI]);
     stq_phys(sm_state + 0x7fc0, EDI);
     for (i = 8; i < 16; i++) {
         stq_phys(sm_state + 0x7ff8 - i * 8, env->regs[i]);
@@ -110,7 +110,7 @@ void do_smm_enter(CPUX86State *env)
     stl_phys(sm_state + 0x7ff4, cpu_compute_eflags(env));
     stl_phys(sm_state + 0x7ff0, env->eip);
     stl_phys(sm_state + 0x7fec, EDI);
-    stl_phys(sm_state + 0x7fe8, ESI);
+    stl_phys(sm_state + 0x7fe8, env->regs[R_ESI]);
     stl_phys(sm_state + 0x7fe4, env->regs[R_EBP]);
     stl_phys(sm_state + 0x7fe0, env->regs[R_ESP]);
     stl_phys(sm_state + 0x7fdc, env->regs[R_EBX]);
@@ -219,7 +219,7 @@ void helper_rsm(CPUX86State *env)
     env->regs[R_EBX] = ldq_phys(sm_state + 0x7fe0);
     env->regs[R_ESP] = ldq_phys(sm_state + 0x7fd8);
     env->regs[R_EBP] = ldq_phys(sm_state + 0x7fd0);
-    ESI = ldq_phys(sm_state + 0x7fc8);
+    env->regs[R_ESI] = ldq_phys(sm_state + 0x7fc8);
     EDI = ldq_phys(sm_state + 0x7fc0);
     for (i = 8; i < 16; i++) {
         env->regs[i] = ldq_phys(sm_state + 0x7ff8 - i * 8);
@@ -245,7 +245,7 @@ void helper_rsm(CPUX86State *env)
                     ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
     env->eip = ldl_phys(sm_state + 0x7ff0);
     EDI = ldl_phys(sm_state + 0x7fec);
-    ESI = ldl_phys(sm_state + 0x7fe8);
+    env->regs[R_ESI] = ldl_phys(sm_state + 0x7fe8);
     env->regs[R_EBP] = ldl_phys(sm_state + 0x7fe4);
     env->regs[R_ESP] = ldl_phys(sm_state + 0x7fe0);
     env->regs[R_EBX] = ldl_phys(sm_state + 0x7fdc);
commit 08b3ded6bdc06ac6b9d1f700a1ee108f4ba4030f
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Tue May 28 16:21:04 2013 +0800

    target-i386/helper: remove ESP macro
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index fc0cf65..6b058bb 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1101,8 +1101,6 @@ static inline int cpu_mmu_index (CPUX86State *env)
         ? MMU_KSMAP_IDX : MMU_KERNEL_IDX;
 }
 
-#undef ESP
-#define ESP (env->regs[R_ESP])
 #undef ESI
 #define ESI (env->regs[R_ESI])
 #undef EDI
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 56db00f..0c4b3d8 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -328,7 +328,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
         cpu_stl_kernel(env, env->tr.base + (0x28 + 1 * 4), env->regs[R_ECX]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 2 * 4), env->regs[R_EDX]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 3 * 4), env->regs[R_EBX]);
-        cpu_stl_kernel(env, env->tr.base + (0x28 + 4 * 4), ESP);
+        cpu_stl_kernel(env, env->tr.base + (0x28 + 4 * 4), env->regs[R_ESP]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 5 * 4), env->regs[R_EBP]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 6 * 4), ESI);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 7 * 4), EDI);
@@ -344,7 +344,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
         cpu_stw_kernel(env, env->tr.base + (0x12 + 1 * 2), env->regs[R_ECX]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 2 * 2), env->regs[R_EDX]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 3 * 2), env->regs[R_EBX]);
-        cpu_stw_kernel(env, env->tr.base + (0x12 + 4 * 2), ESP);
+        cpu_stw_kernel(env, env->tr.base + (0x12 + 4 * 2), env->regs[R_ESP]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 5 * 2), env->regs[R_EBP]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 6 * 2), ESI);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 7 * 2), EDI);
@@ -400,7 +400,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
     env->regs[R_ECX] = new_regs[1];
     env->regs[R_EDX] = new_regs[2];
     env->regs[R_EBX] = new_regs[3];
-    ESP = new_regs[4];
+    env->regs[R_ESP] = new_regs[4];
     env->regs[R_EBP] = new_regs[5];
     ESI = new_regs[6];
     EDI = new_regs[7];
@@ -502,20 +502,22 @@ static int exception_has_error_code(int intno)
 }
 
 #ifdef TARGET_X86_64
-#define SET_ESP(val, sp_mask)                           \
-    do {                                                \
-        if ((sp_mask) == 0xffff) {                      \
-            ESP = (ESP & ~0xffff) | ((val) & 0xffff);   \
-        } else if ((sp_mask) == 0xffffffffLL) {         \
-            ESP = (uint32_t)(val);                      \
-        } else {                                        \
-            ESP = (val);                                \
-        }                                               \
+#define SET_ESP(val, sp_mask)                                   \
+    do {                                                        \
+        if ((sp_mask) == 0xffff) {                              \
+            env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) |   \
+                ((val) & 0xffff);                               \
+        } else if ((sp_mask) == 0xffffffffLL) {                 \
+            env->regs[R_ESP] = (uint32_t)(val);                 \
+        } else {                                                \
+            env->regs[R_ESP] = (val);                           \
+        }                                                       \
     } while (0)
 #else
-#define SET_ESP(val, sp_mask)                           \
-    do {                                                \
-        ESP = (ESP & ~(sp_mask)) | ((val) & (sp_mask)); \
+#define SET_ESP(val, sp_mask)                                   \
+    do {                                                        \
+        env->regs[R_ESP] = (env->regs[R_ESP] & ~(sp_mask)) |    \
+            ((val) & (sp_mask));                                \
     } while (0)
 #endif
 
@@ -598,7 +600,7 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int,
             } else {
                 mask = 0xffff;
             }
-            esp = (ESP - (2 << shift)) & mask;
+            esp = (env->regs[R_ESP] - (2 << shift)) & mask;
             ssp = env->segs[R_SS].base + esp;
             if (shift) {
                 cpu_stl_kernel(env, ssp, error_code);
@@ -680,7 +682,7 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int,
         new_stack = 0;
         sp_mask = get_sp_mask(env->segs[R_SS].flags);
         ssp = env->segs[R_SS].base;
-        esp = ESP;
+        esp = env->regs[R_ESP];
         dpl = cpl;
     } else {
         raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
@@ -709,7 +711,7 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int,
                 PUSHL(ssp, esp, sp_mask, env->segs[R_ES].selector);
             }
             PUSHL(ssp, esp, sp_mask, env->segs[R_SS].selector);
-            PUSHL(ssp, esp, sp_mask, ESP);
+            PUSHL(ssp, esp, sp_mask, env->regs[R_ESP]);
         }
         PUSHL(ssp, esp, sp_mask, cpu_compute_eflags(env));
         PUSHL(ssp, esp, sp_mask, env->segs[R_CS].selector);
@@ -726,7 +728,7 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int,
                 PUSHW(ssp, esp, sp_mask, env->segs[R_ES].selector);
             }
             PUSHW(ssp, esp, sp_mask, env->segs[R_SS].selector);
-            PUSHW(ssp, esp, sp_mask, ESP);
+            PUSHW(ssp, esp, sp_mask, env->regs[R_ESP]);
         }
         PUSHW(ssp, esp, sp_mask, cpu_compute_eflags(env));
         PUSHW(ssp, esp, sp_mask, env->segs[R_CS].selector);
@@ -888,7 +890,7 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
         if (ist != 0) {
             esp = get_rsp_from_tss(env, ist + 3);
         } else {
-            esp = ESP;
+            esp = env->regs[R_ESP];
         }
         esp &= ~0xfLL; /* align stack */
         dpl = cpl;
@@ -899,7 +901,7 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
     }
 
     PUSHQ(esp, env->segs[R_SS].selector);
-    PUSHQ(esp, ESP);
+    PUSHQ(esp, env->regs[R_ESP]);
     PUSHQ(esp, cpu_compute_eflags(env));
     PUSHQ(esp, env->segs[R_CS].selector);
     PUSHQ(esp, old_eip);
@@ -911,7 +913,7 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
         ss = 0 | dpl;
         cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0);
     }
-    ESP = esp;
+    env->regs[R_ESP] = esp;
 
     selector = (selector & ~3) | dpl;
     cpu_x86_load_seg_cache(env, R_CS, selector,
@@ -1069,7 +1071,7 @@ static void do_interrupt_real(CPUX86State *env, int intno, int is_int,
     ptr = dt->base + intno * 4;
     offset = cpu_lduw_kernel(env, ptr);
     selector = cpu_lduw_kernel(env, ptr + 2);
-    esp = ESP;
+    esp = env->regs[R_ESP];
     ssp = env->segs[R_SS].base;
     if (is_int) {
         old_eip = next_eip;
@@ -1083,7 +1085,7 @@ static void do_interrupt_real(CPUX86State *env, int intno, int is_int,
     PUSHW(ssp, esp, 0xffff, old_eip);
 
     /* update processor state */
-    ESP = (ESP & ~0xffff) | (esp & 0xffff);
+    env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) | (esp & 0xffff);
     env->eip = offset;
     env->segs[R_CS].selector = selector;
     env->segs[R_CS].base = (selector << 4);
@@ -1171,7 +1173,7 @@ static void do_interrupt_all(CPUX86State *env, int intno, int is_int,
                      env->hflags & HF_CPL_MASK,
                      env->segs[R_CS].selector, EIP,
                      (int)env->segs[R_CS].base + EIP,
-                     env->segs[R_SS].selector, ESP);
+                     env->segs[R_SS].selector, env->regs[R_ESP]);
             if (intno == 0x0e) {
                 qemu_log(" CR2=" TARGET_FMT_lx, env->cr[2]);
             } else {
@@ -1273,7 +1275,7 @@ void helper_enter_level(CPUX86State *env, int level, int data32,
     esp_mask = get_sp_mask(env->segs[R_SS].flags);
     ssp = env->segs[R_SS].base;
     ebp = env->regs[R_EBP];
-    esp = ESP;
+    esp = env->regs[R_ESP];
     if (data32) {
         /* 32 bit */
         esp -= 4;
@@ -1306,7 +1308,7 @@ void helper_enter64_level(CPUX86State *env, int level, int data64,
     target_ulong esp, ebp;
 
     ebp = env->regs[R_EBP];
-    esp = ESP;
+    esp = env->regs[R_ESP];
 
     if (data64) {
         /* 64 bit */
@@ -1653,7 +1655,7 @@ void helper_lcall_real(CPUX86State *env, int new_cs, target_ulong new_eip1,
     target_ulong ssp;
 
     new_eip = new_eip1;
-    esp = ESP;
+    esp = env->regs[R_ESP];
     esp_mask = get_sp_mask(env->segs[R_SS].flags);
     ssp = env->segs[R_SS].base;
     if (shift) {
@@ -1721,11 +1723,11 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
             target_ulong rsp;
 
             /* 64 bit case */
-            rsp = ESP;
+            rsp = env->regs[R_ESP];
             PUSHQ(rsp, env->segs[R_CS].selector);
             PUSHQ(rsp, next_eip);
             /* from this point, not restartable */
-            ESP = rsp;
+            env->regs[R_ESP] = rsp;
             cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
                                    get_seg_base(e1, e2),
                                    get_seg_limit(e1, e2), e2);
@@ -1733,7 +1735,7 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
         } else
 #endif
         {
-            sp = ESP;
+            sp = env->regs[R_ESP];
             sp_mask = get_sp_mask(env->segs[R_SS].flags);
             ssp = env->segs[R_SS].base;
             if (shift) {
@@ -1809,9 +1811,9 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
         if (!(e2 & DESC_C_MASK) && dpl < cpl) {
             /* to inner privilege */
             get_ss_esp_from_tss(env, &ss, &sp, dpl);
-            LOG_PCALL("new ss:esp=%04x:%08x param_count=%d ESP=" TARGET_FMT_lx
+            LOG_PCALL("new ss:esp=%04x:%08x param_count=%d env->regs[R_ESP]=" TARGET_FMT_lx
                       "\n",
-                      ss, sp, param_count, ESP);
+                      ss, sp, param_count, env->regs[R_ESP]);
             if ((ss & 0xfffc) == 0) {
                 raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
             }
@@ -1843,17 +1845,17 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
             ssp = get_seg_base(ss_e1, ss_e2);
             if (shift) {
                 PUSHL(ssp, sp, sp_mask, env->segs[R_SS].selector);
-                PUSHL(ssp, sp, sp_mask, ESP);
+                PUSHL(ssp, sp, sp_mask, env->regs[R_ESP]);
                 for (i = param_count - 1; i >= 0; i--) {
-                    val = cpu_ldl_kernel(env, old_ssp + ((ESP + i * 4) &
+                    val = cpu_ldl_kernel(env, old_ssp + ((env->regs[R_ESP] + i * 4) &
                                                          old_sp_mask));
                     PUSHL(ssp, sp, sp_mask, val);
                 }
             } else {
                 PUSHW(ssp, sp, sp_mask, env->segs[R_SS].selector);
-                PUSHW(ssp, sp, sp_mask, ESP);
+                PUSHW(ssp, sp, sp_mask, env->regs[R_ESP]);
                 for (i = param_count - 1; i >= 0; i--) {
-                    val = cpu_lduw_kernel(env, old_ssp + ((ESP + i * 2) &
+                    val = cpu_lduw_kernel(env, old_ssp + ((env->regs[R_ESP] + i * 2) &
                                                           old_sp_mask));
                     PUSHW(ssp, sp, sp_mask, val);
                 }
@@ -1861,7 +1863,7 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
             new_stack = 1;
         } else {
             /* to same privilege */
-            sp = ESP;
+            sp = env->regs[R_ESP];
             sp_mask = get_sp_mask(env->segs[R_SS].flags);
             ssp = env->segs[R_SS].base;
             /* push_size = (4 << shift); */
@@ -1905,7 +1907,7 @@ void helper_iret_real(CPUX86State *env, int shift)
     int eflags_mask;
 
     sp_mask = 0xffff; /* XXXX: use SS segment size? */
-    sp = ESP;
+    sp = env->regs[R_ESP];
     ssp = env->segs[R_SS].base;
     if (shift == 1) {
         /* 32 bits */
@@ -1919,7 +1921,7 @@ void helper_iret_real(CPUX86State *env, int shift)
         POPW(ssp, sp, sp_mask, new_cs);
         POPW(ssp, sp, sp_mask, new_eflags);
     }
-    ESP = (ESP & ~sp_mask) | (sp & sp_mask);
+    env->regs[R_ESP] = (env->regs[R_ESP] & ~sp_mask) | (sp & sp_mask);
     env->segs[R_CS].selector = new_cs;
     env->segs[R_CS].base = (new_cs << 4);
     env->eip = new_eip;
@@ -1978,7 +1980,7 @@ static inline void helper_ret_protected(CPUX86State *env, int shift,
     {
         sp_mask = get_sp_mask(env->segs[R_SS].flags);
     }
-    sp = ESP;
+    sp = env->regs[R_ESP];
     ssp = env->segs[R_SS].base;
     new_eflags = 0; /* avoid warning */
 #ifdef TARGET_X86_64
@@ -2179,7 +2181,7 @@ static inline void helper_ret_protected(CPUX86State *env, int shift,
     load_seg_vm(env, R_GS, new_gs & 0xffff);
 
     env->eip = new_eip & 0xffff;
-    ESP = new_esp;
+    env->regs[R_ESP] = new_esp;
 }
 
 void helper_iret_protected(CPUX86State *env, int shift, int next_eip)
@@ -2248,7 +2250,7 @@ void helper_sysenter(CPUX86State *env)
                            DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
                            DESC_S_MASK |
                            DESC_W_MASK | DESC_A_MASK);
-    ESP = env->sysenter_esp;
+    env->regs[R_ESP] = env->sysenter_esp;
     EIP = env->sysenter_eip;
 }
 
@@ -2288,7 +2290,7 @@ void helper_sysexit(CPUX86State *env, int dflag)
                                DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
                                DESC_W_MASK | DESC_A_MASK);
     }
-    ESP = env->regs[R_ECX];
+    env->regs[R_ESP] = env->regs[R_ECX];
     EIP = env->regs[R_EDX];
 }
 
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index 4bd73eb..50c5d99 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -86,7 +86,7 @@ void do_smm_enter(CPUX86State *env)
     stq_phys(sm_state + 0x7ff0, env->regs[R_ECX]);
     stq_phys(sm_state + 0x7fe8, env->regs[R_EDX]);
     stq_phys(sm_state + 0x7fe0, env->regs[R_EBX]);
-    stq_phys(sm_state + 0x7fd8, ESP);
+    stq_phys(sm_state + 0x7fd8, env->regs[R_ESP]);
     stq_phys(sm_state + 0x7fd0, env->regs[R_EBP]);
     stq_phys(sm_state + 0x7fc8, ESI);
     stq_phys(sm_state + 0x7fc0, EDI);
@@ -112,7 +112,7 @@ void do_smm_enter(CPUX86State *env)
     stl_phys(sm_state + 0x7fec, EDI);
     stl_phys(sm_state + 0x7fe8, ESI);
     stl_phys(sm_state + 0x7fe4, env->regs[R_EBP]);
-    stl_phys(sm_state + 0x7fe0, ESP);
+    stl_phys(sm_state + 0x7fe0, env->regs[R_ESP]);
     stl_phys(sm_state + 0x7fdc, env->regs[R_EBX]);
     stl_phys(sm_state + 0x7fd8, env->regs[R_EDX]);
     stl_phys(sm_state + 0x7fd4, env->regs[R_ECX]);
@@ -217,7 +217,7 @@ void helper_rsm(CPUX86State *env)
     env->regs[R_ECX] = ldq_phys(sm_state + 0x7ff0);
     env->regs[R_EDX] = ldq_phys(sm_state + 0x7fe8);
     env->regs[R_EBX] = ldq_phys(sm_state + 0x7fe0);
-    ESP = ldq_phys(sm_state + 0x7fd8);
+    env->regs[R_ESP] = ldq_phys(sm_state + 0x7fd8);
     env->regs[R_EBP] = ldq_phys(sm_state + 0x7fd0);
     ESI = ldq_phys(sm_state + 0x7fc8);
     EDI = ldq_phys(sm_state + 0x7fc0);
@@ -247,7 +247,7 @@ void helper_rsm(CPUX86State *env)
     EDI = ldl_phys(sm_state + 0x7fec);
     ESI = ldl_phys(sm_state + 0x7fe8);
     env->regs[R_EBP] = ldl_phys(sm_state + 0x7fe4);
-    ESP = ldl_phys(sm_state + 0x7fe0);
+    env->regs[R_ESP] = ldl_phys(sm_state + 0x7fe0);
     env->regs[R_EBX] = ldl_phys(sm_state + 0x7fdc);
     env->regs[R_EDX] = ldl_phys(sm_state + 0x7fd8);
     env->regs[R_ECX] = ldl_phys(sm_state + 0x7fd4);
diff --git a/target-i386/svm_helper.c b/target-i386/svm_helper.c
index b59a2ca..5706026 100644
--- a/target-i386/svm_helper.c
+++ b/target-i386/svm_helper.c
@@ -171,7 +171,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
 
     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip),
              EIP + next_eip_addend);
-    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp), ESP);
+    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp), env->regs[R_ESP]);
     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax), env->regs[R_EAX]);
 
     /* load the interception bitmaps so we do not need to access the
@@ -250,7 +250,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
 
     EIP = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip));
     env->eip = EIP;
-    ESP = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp));
+    env->regs[R_ESP] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp));
     env->regs[R_EAX] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax));
     env->dr[7] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr7));
     env->dr[6] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr6));
@@ -606,7 +606,7 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
              cpu_compute_eflags(env));
     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip),
              env->eip);
-    stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp), ESP);
+    stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp), env->regs[R_ESP]);
     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax), env->regs[R_EAX]);
     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr7), env->dr[7]);
     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr6), env->dr[6]);
@@ -658,7 +658,7 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
                        R_DS);
 
     EIP = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip));
-    ESP = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp));
+    env->regs[R_ESP] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp));
     env->regs[R_EAX] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax));
 
     env->dr[6] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr6));
commit c12dddd7918e3479d0b5b0a1b25588d557347171
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Tue May 28 16:21:03 2013 +0800

    target-i386/helper: remove EBP macro
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index ebc5abd..fc0cf65 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1103,8 +1103,6 @@ static inline int cpu_mmu_index (CPUX86State *env)
 
 #undef ESP
 #define ESP (env->regs[R_ESP])
-#undef EBP
-#define EBP (env->regs[R_EBP])
 #undef ESI
 #define ESI (env->regs[R_ESI])
 #undef EDI
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index fc67f52..56db00f 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -329,7 +329,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
         cpu_stl_kernel(env, env->tr.base + (0x28 + 2 * 4), env->regs[R_EDX]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 3 * 4), env->regs[R_EBX]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 4 * 4), ESP);
-        cpu_stl_kernel(env, env->tr.base + (0x28 + 5 * 4), EBP);
+        cpu_stl_kernel(env, env->tr.base + (0x28 + 5 * 4), env->regs[R_EBP]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 6 * 4), ESI);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 7 * 4), EDI);
         for (i = 0; i < 6; i++) {
@@ -345,7 +345,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
         cpu_stw_kernel(env, env->tr.base + (0x12 + 2 * 2), env->regs[R_EDX]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 3 * 2), env->regs[R_EBX]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 4 * 2), ESP);
-        cpu_stw_kernel(env, env->tr.base + (0x12 + 5 * 2), EBP);
+        cpu_stw_kernel(env, env->tr.base + (0x12 + 5 * 2), env->regs[R_EBP]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 6 * 2), ESI);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 7 * 2), EDI);
         for (i = 0; i < 4; i++) {
@@ -401,7 +401,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
     env->regs[R_EDX] = new_regs[2];
     env->regs[R_EBX] = new_regs[3];
     ESP = new_regs[4];
-    EBP = new_regs[5];
+    env->regs[R_EBP] = new_regs[5];
     ESI = new_regs[6];
     EDI = new_regs[7];
     if (new_eflags & VM_MASK) {
@@ -1272,7 +1272,7 @@ void helper_enter_level(CPUX86State *env, int level, int data32,
 
     esp_mask = get_sp_mask(env->segs[R_SS].flags);
     ssp = env->segs[R_SS].base;
-    ebp = EBP;
+    ebp = env->regs[R_EBP];
     esp = ESP;
     if (data32) {
         /* 32 bit */
@@ -1305,7 +1305,7 @@ void helper_enter64_level(CPUX86State *env, int level, int data64,
 {
     target_ulong esp, ebp;
 
-    ebp = EBP;
+    ebp = env->regs[R_EBP];
     esp = ESP;
 
     if (data64) {
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index 5bc6802..4bd73eb 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -87,7 +87,7 @@ void do_smm_enter(CPUX86State *env)
     stq_phys(sm_state + 0x7fe8, env->regs[R_EDX]);
     stq_phys(sm_state + 0x7fe0, env->regs[R_EBX]);
     stq_phys(sm_state + 0x7fd8, ESP);
-    stq_phys(sm_state + 0x7fd0, EBP);
+    stq_phys(sm_state + 0x7fd0, env->regs[R_EBP]);
     stq_phys(sm_state + 0x7fc8, ESI);
     stq_phys(sm_state + 0x7fc0, EDI);
     for (i = 8; i < 16; i++) {
@@ -111,7 +111,7 @@ void do_smm_enter(CPUX86State *env)
     stl_phys(sm_state + 0x7ff0, env->eip);
     stl_phys(sm_state + 0x7fec, EDI);
     stl_phys(sm_state + 0x7fe8, ESI);
-    stl_phys(sm_state + 0x7fe4, EBP);
+    stl_phys(sm_state + 0x7fe4, env->regs[R_EBP]);
     stl_phys(sm_state + 0x7fe0, ESP);
     stl_phys(sm_state + 0x7fdc, env->regs[R_EBX]);
     stl_phys(sm_state + 0x7fd8, env->regs[R_EDX]);
@@ -218,7 +218,7 @@ void helper_rsm(CPUX86State *env)
     env->regs[R_EDX] = ldq_phys(sm_state + 0x7fe8);
     env->regs[R_EBX] = ldq_phys(sm_state + 0x7fe0);
     ESP = ldq_phys(sm_state + 0x7fd8);
-    EBP = ldq_phys(sm_state + 0x7fd0);
+    env->regs[R_EBP] = ldq_phys(sm_state + 0x7fd0);
     ESI = ldq_phys(sm_state + 0x7fc8);
     EDI = ldq_phys(sm_state + 0x7fc0);
     for (i = 8; i < 16; i++) {
@@ -246,7 +246,7 @@ void helper_rsm(CPUX86State *env)
     env->eip = ldl_phys(sm_state + 0x7ff0);
     EDI = ldl_phys(sm_state + 0x7fec);
     ESI = ldl_phys(sm_state + 0x7fe8);
-    EBP = ldl_phys(sm_state + 0x7fe4);
+    env->regs[R_EBP] = ldl_phys(sm_state + 0x7fe4);
     ESP = ldl_phys(sm_state + 0x7fe0);
     env->regs[R_EBX] = ldl_phys(sm_state + 0x7fdc);
     env->regs[R_EDX] = ldl_phys(sm_state + 0x7fd8);
commit 00f5e6f21ea55046173a8a106b7654036888e9b3
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Tue May 28 16:21:02 2013 +0800

    target-i386/helper: remove EDX macro
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index b3c6fcb..ebc5abd 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1101,8 +1101,6 @@ static inline int cpu_mmu_index (CPUX86State *env)
         ? MMU_KSMAP_IDX : MMU_KERNEL_IDX;
 }
 
-#undef EDX
-#define EDX (env->regs[R_EDX])
 #undef ESP
 #define ESP (env->regs[R_ESP])
 #undef EBP
diff --git a/target-i386/int_helper.c b/target-i386/int_helper.c
index 16d1ed5..0555318 100644
--- a/target-i386/int_helper.c
+++ b/target-i386/int_helper.c
@@ -81,7 +81,7 @@ void helper_divw_AX(CPUX86State *env, target_ulong t0)
 {
     unsigned int num, den, q, r;
 
-    num = (env->regs[R_EAX] & 0xffff) | ((EDX & 0xffff) << 16);
+    num = (env->regs[R_EAX] & 0xffff) | ((env->regs[R_EDX] & 0xffff) << 16);
     den = (t0 & 0xffff);
     if (den == 0) {
         raise_exception(env, EXCP00_DIVZ);
@@ -93,14 +93,14 @@ void helper_divw_AX(CPUX86State *env, target_ulong t0)
     q &= 0xffff;
     r = (num % den) & 0xffff;
     env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | q;
-    EDX = (EDX & ~0xffff) | r;
+    env->regs[R_EDX] = (env->regs[R_EDX] & ~0xffff) | r;
 }
 
 void helper_idivw_AX(CPUX86State *env, target_ulong t0)
 {
     int num, den, q, r;
 
-    num = (env->regs[R_EAX] & 0xffff) | ((EDX & 0xffff) << 16);
+    num = (env->regs[R_EAX] & 0xffff) | ((env->regs[R_EDX] & 0xffff) << 16);
     den = (int16_t)t0;
     if (den == 0) {
         raise_exception(env, EXCP00_DIVZ);
@@ -112,7 +112,7 @@ void helper_idivw_AX(CPUX86State *env, target_ulong t0)
     q &= 0xffff;
     r = (num % den) & 0xffff;
     env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | q;
-    EDX = (EDX & ~0xffff) | r;
+    env->regs[R_EDX] = (env->regs[R_EDX] & ~0xffff) | r;
 }
 
 void helper_divl_EAX(CPUX86State *env, target_ulong t0)
@@ -120,7 +120,7 @@ void helper_divl_EAX(CPUX86State *env, target_ulong t0)
     unsigned int den, r;
     uint64_t num, q;
 
-    num = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)EDX) << 32);
+    num = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
     den = t0;
     if (den == 0) {
         raise_exception(env, EXCP00_DIVZ);
@@ -131,7 +131,7 @@ void helper_divl_EAX(CPUX86State *env, target_ulong t0)
         raise_exception(env, EXCP00_DIVZ);
     }
     env->regs[R_EAX] = (uint32_t)q;
-    EDX = (uint32_t)r;
+    env->regs[R_EDX] = (uint32_t)r;
 }
 
 void helper_idivl_EAX(CPUX86State *env, target_ulong t0)
@@ -139,7 +139,7 @@ void helper_idivl_EAX(CPUX86State *env, target_ulong t0)
     int den, r;
     int64_t num, q;
 
-    num = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)EDX) << 32);
+    num = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
     den = t0;
     if (den == 0) {
         raise_exception(env, EXCP00_DIVZ);
@@ -150,7 +150,7 @@ void helper_idivl_EAX(CPUX86State *env, target_ulong t0)
         raise_exception(env, EXCP00_DIVZ);
     }
     env->regs[R_EAX] = (uint32_t)q;
-    EDX = (uint32_t)r;
+    env->regs[R_EDX] = (uint32_t)r;
 }
 
 /* bcd */
@@ -382,12 +382,12 @@ void helper_divq_EAX(CPUX86State *env, target_ulong t0)
         raise_exception(env, EXCP00_DIVZ);
     }
     r0 = env->regs[R_EAX];
-    r1 = EDX;
+    r1 = env->regs[R_EDX];
     if (div64(&r0, &r1, t0)) {
         raise_exception(env, EXCP00_DIVZ);
     }
     env->regs[R_EAX] = r0;
-    EDX = r1;
+    env->regs[R_EDX] = r1;
 }
 
 void helper_idivq_EAX(CPUX86State *env, target_ulong t0)
@@ -398,12 +398,12 @@ void helper_idivq_EAX(CPUX86State *env, target_ulong t0)
         raise_exception(env, EXCP00_DIVZ);
     }
     r0 = env->regs[R_EAX];
-    r1 = EDX;
+    r1 = env->regs[R_EDX];
     if (idiv64(&r0, &r1, t0)) {
         raise_exception(env, EXCP00_DIVZ);
     }
     env->regs[R_EAX] = r0;
-    EDX = r1;
+    env->regs[R_EDX] = r1;
 }
 #endif
 
diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c
index 41ac847..319a219 100644
--- a/target-i386/mem_helper.c
+++ b/target-i386/mem_helper.c
@@ -45,13 +45,13 @@ void helper_cmpxchg8b(CPUX86State *env, target_ulong a0)
 
     eflags = cpu_cc_compute_all(env, CC_OP);
     d = cpu_ldq_data(env, a0);
-    if (d == (((uint64_t)EDX << 32) | (uint32_t)env->regs[R_EAX])) {
+    if (d == (((uint64_t)env->regs[R_EDX] << 32) | (uint32_t)env->regs[R_EAX])) {
         cpu_stq_data(env, a0, ((uint64_t)env->regs[R_ECX] << 32) | (uint32_t)env->regs[R_EBX]);
         eflags |= CC_Z;
     } else {
         /* always do the store */
         cpu_stq_data(env, a0, d);
-        EDX = (uint32_t)(d >> 32);
+        env->regs[R_EDX] = (uint32_t)(d >> 32);
         env->regs[R_EAX] = (uint32_t)d;
         eflags &= ~CC_Z;
     }
@@ -70,7 +70,7 @@ void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
     eflags = cpu_cc_compute_all(env, CC_OP);
     d0 = cpu_ldq_data(env, a0);
     d1 = cpu_ldq_data(env, a0 + 8);
-    if (d0 == env->regs[R_EAX] && d1 == EDX) {
+    if (d0 == env->regs[R_EAX] && d1 == env->regs[R_EDX]) {
         cpu_stq_data(env, a0, env->regs[R_EBX]);
         cpu_stq_data(env, a0 + 8, env->regs[R_ECX]);
         eflags |= CC_Z;
@@ -78,7 +78,7 @@ void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
         /* always do the store */
         cpu_stq_data(env, a0, d0);
         cpu_stq_data(env, a0 + 8, d1);
-        EDX = d1;
+        env->regs[R_EDX] = d1;
         env->regs[R_EAX] = d0;
         eflags &= ~CC_Z;
     }
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index b0afffe..380e54e 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -126,7 +126,7 @@ void helper_cpuid(CPUX86State *env)
     env->regs[R_EAX] = eax;
     env->regs[R_EBX] = ebx;
     env->regs[R_ECX] = ecx;
-    EDX = edx;
+    env->regs[R_EDX] = edx;
 }
 
 #if defined(CONFIG_USER_ONLY)
@@ -235,7 +235,7 @@ void helper_rdtsc(CPUX86State *env)
 
     val = cpu_get_tsc(env) + env->tsc_offset;
     env->regs[R_EAX] = (uint32_t)(val);
-    EDX = (uint32_t)(val >> 32);
+    env->regs[R_EDX] = (uint32_t)(val >> 32);
 }
 
 void helper_rdtscp(CPUX86State *env)
@@ -271,7 +271,7 @@ void helper_wrmsr(CPUX86State *env)
 
     cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1);
 
-    val = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)EDX) << 32);
+    val = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
 
     switch ((uint32_t)env->regs[R_ECX]) {
     case MSR_IA32_SYSENTER_CS:
@@ -549,7 +549,7 @@ void helper_rdmsr(CPUX86State *env)
         break;
     }
     env->regs[R_EAX] = (uint32_t)(val);
-    EDX = (uint32_t)(val >> 32);
+    env->regs[R_EDX] = (uint32_t)(val >> 32);
 }
 #endif
 
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 60d723a..fc67f52 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -326,7 +326,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
         cpu_stl_kernel(env, env->tr.base + 0x24, old_eflags);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 0 * 4), env->regs[R_EAX]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 1 * 4), env->regs[R_ECX]);
-        cpu_stl_kernel(env, env->tr.base + (0x28 + 2 * 4), EDX);
+        cpu_stl_kernel(env, env->tr.base + (0x28 + 2 * 4), env->regs[R_EDX]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 3 * 4), env->regs[R_EBX]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 4 * 4), ESP);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 5 * 4), EBP);
@@ -342,7 +342,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
         cpu_stw_kernel(env, env->tr.base + 0x10, old_eflags);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 0 * 2), env->regs[R_EAX]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 1 * 2), env->regs[R_ECX]);
-        cpu_stw_kernel(env, env->tr.base + (0x12 + 2 * 2), EDX);
+        cpu_stw_kernel(env, env->tr.base + (0x12 + 2 * 2), env->regs[R_EDX]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 3 * 2), env->regs[R_EBX]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 4 * 2), ESP);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 5 * 2), EBP);
@@ -398,7 +398,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
     /* XXX: what to do in 16 bit case? */
     env->regs[R_EAX] = new_regs[0];
     env->regs[R_ECX] = new_regs[1];
-    EDX = new_regs[2];
+    env->regs[R_EDX] = new_regs[2];
     env->regs[R_EBX] = new_regs[3];
     ESP = new_regs[4];
     EBP = new_regs[5];
@@ -2289,7 +2289,7 @@ void helper_sysexit(CPUX86State *env, int dflag)
                                DESC_W_MASK | DESC_A_MASK);
     }
     ESP = env->regs[R_ECX];
-    EIP = EDX;
+    EIP = env->regs[R_EDX];
 }
 
 target_ulong helper_lsl(CPUX86State *env, target_ulong selector1)
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index 952c728..5bc6802 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -84,7 +84,7 @@ void do_smm_enter(CPUX86State *env)
 
     stq_phys(sm_state + 0x7ff8, env->regs[R_EAX]);
     stq_phys(sm_state + 0x7ff0, env->regs[R_ECX]);
-    stq_phys(sm_state + 0x7fe8, EDX);
+    stq_phys(sm_state + 0x7fe8, env->regs[R_EDX]);
     stq_phys(sm_state + 0x7fe0, env->regs[R_EBX]);
     stq_phys(sm_state + 0x7fd8, ESP);
     stq_phys(sm_state + 0x7fd0, EBP);
@@ -114,7 +114,7 @@ void do_smm_enter(CPUX86State *env)
     stl_phys(sm_state + 0x7fe4, EBP);
     stl_phys(sm_state + 0x7fe0, ESP);
     stl_phys(sm_state + 0x7fdc, env->regs[R_EBX]);
-    stl_phys(sm_state + 0x7fd8, EDX);
+    stl_phys(sm_state + 0x7fd8, env->regs[R_EDX]);
     stl_phys(sm_state + 0x7fd4, env->regs[R_ECX]);
     stl_phys(sm_state + 0x7fd0, env->regs[R_EAX]);
     stl_phys(sm_state + 0x7fcc, env->dr[6]);
@@ -215,7 +215,7 @@ void helper_rsm(CPUX86State *env)
 
     env->regs[R_EAX] = ldq_phys(sm_state + 0x7ff8);
     env->regs[R_ECX] = ldq_phys(sm_state + 0x7ff0);
-    EDX = ldq_phys(sm_state + 0x7fe8);
+    env->regs[R_EDX] = ldq_phys(sm_state + 0x7fe8);
     env->regs[R_EBX] = ldq_phys(sm_state + 0x7fe0);
     ESP = ldq_phys(sm_state + 0x7fd8);
     EBP = ldq_phys(sm_state + 0x7fd0);
@@ -249,7 +249,7 @@ void helper_rsm(CPUX86State *env)
     EBP = ldl_phys(sm_state + 0x7fe4);
     ESP = ldl_phys(sm_state + 0x7fe0);
     env->regs[R_EBX] = ldl_phys(sm_state + 0x7fdc);
-    EDX = ldl_phys(sm_state + 0x7fd8);
+    env->regs[R_EDX] = ldl_phys(sm_state + 0x7fd8);
     env->regs[R_ECX] = ldl_phys(sm_state + 0x7fd4);
     env->regs[R_EAX] = ldl_phys(sm_state + 0x7fd0);
     env->dr[6] = ldl_phys(sm_state + 0x7fcc);
commit a416561005da6e4f9903541486f53c2cbc3a428d
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Tue May 28 16:21:01 2013 +0800

    target-i386/helper: remove ECX macro
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 28ff02d..b3c6fcb 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1101,8 +1101,6 @@ static inline int cpu_mmu_index (CPUX86State *env)
         ? MMU_KSMAP_IDX : MMU_KERNEL_IDX;
 }
 
-#undef ECX
-#define ECX (env->regs[R_ECX])
 #undef EDX
 #define EDX (env->regs[R_EDX])
 #undef ESP
diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c
index 6370fb5..41ac847 100644
--- a/target-i386/mem_helper.c
+++ b/target-i386/mem_helper.c
@@ -46,7 +46,7 @@ void helper_cmpxchg8b(CPUX86State *env, target_ulong a0)
     eflags = cpu_cc_compute_all(env, CC_OP);
     d = cpu_ldq_data(env, a0);
     if (d == (((uint64_t)EDX << 32) | (uint32_t)env->regs[R_EAX])) {
-        cpu_stq_data(env, a0, ((uint64_t)ECX << 32) | (uint32_t)env->regs[R_EBX]);
+        cpu_stq_data(env, a0, ((uint64_t)env->regs[R_ECX] << 32) | (uint32_t)env->regs[R_EBX]);
         eflags |= CC_Z;
     } else {
         /* always do the store */
@@ -72,7 +72,7 @@ void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
     d1 = cpu_ldq_data(env, a0 + 8);
     if (d0 == env->regs[R_EAX] && d1 == EDX) {
         cpu_stq_data(env, a0, env->regs[R_EBX]);
-        cpu_stq_data(env, a0 + 8, ECX);
+        cpu_stq_data(env, a0 + 8, env->regs[R_ECX]);
         eflags |= CC_Z;
     } else {
         /* always do the store */
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index d7be4f4..b0afffe 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -122,10 +122,10 @@ void helper_cpuid(CPUX86State *env)
 
     cpu_svm_check_intercept_param(env, SVM_EXIT_CPUID, 0);
 
-    cpu_x86_cpuid(env, (uint32_t)env->regs[R_EAX], (uint32_t)ECX, &eax, &ebx, &ecx, &edx);
+    cpu_x86_cpuid(env, (uint32_t)env->regs[R_EAX], (uint32_t)env->regs[R_ECX], &eax, &ebx, &ecx, &edx);
     env->regs[R_EAX] = eax;
     env->regs[R_EBX] = ebx;
-    ECX = ecx;
+    env->regs[R_ECX] = ecx;
     EDX = edx;
 }
 
@@ -241,7 +241,7 @@ void helper_rdtsc(CPUX86State *env)
 void helper_rdtscp(CPUX86State *env)
 {
     helper_rdtsc(env);
-    ECX = (uint32_t)(env->tsc_aux);
+    env->regs[R_ECX] = (uint32_t)(env->tsc_aux);
 }
 
 void helper_rdpmc(CPUX86State *env)
@@ -273,7 +273,7 @@ void helper_wrmsr(CPUX86State *env)
 
     val = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)EDX) << 32);
 
-    switch ((uint32_t)ECX) {
+    switch ((uint32_t)env->regs[R_ECX]) {
     case MSR_IA32_SYSENTER_CS:
         env->sysenter_cs = val & 0xffff;
         break;
@@ -350,7 +350,7 @@ void helper_wrmsr(CPUX86State *env)
     case MSR_MTRRphysBase(5):
     case MSR_MTRRphysBase(6):
     case MSR_MTRRphysBase(7):
-        env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysBase(0)) / 2].base = val;
+        env->mtrr_var[((uint32_t)env->regs[R_ECX] - MSR_MTRRphysBase(0)) / 2].base = val;
         break;
     case MSR_MTRRphysMask(0):
     case MSR_MTRRphysMask(1):
@@ -360,14 +360,14 @@ void helper_wrmsr(CPUX86State *env)
     case MSR_MTRRphysMask(5):
     case MSR_MTRRphysMask(6):
     case MSR_MTRRphysMask(7):
-        env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysMask(0)) / 2].mask = val;
+        env->mtrr_var[((uint32_t)env->regs[R_ECX] - MSR_MTRRphysMask(0)) / 2].mask = val;
         break;
     case MSR_MTRRfix64K_00000:
-        env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix64K_00000] = val;
+        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - MSR_MTRRfix64K_00000] = val;
         break;
     case MSR_MTRRfix16K_80000:
     case MSR_MTRRfix16K_A0000:
-        env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix16K_80000 + 1] = val;
+        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - MSR_MTRRfix16K_80000 + 1] = val;
         break;
     case MSR_MTRRfix4K_C0000:
     case MSR_MTRRfix4K_C8000:
@@ -377,7 +377,7 @@ void helper_wrmsr(CPUX86State *env)
     case MSR_MTRRfix4K_E8000:
     case MSR_MTRRfix4K_F0000:
     case MSR_MTRRfix4K_F8000:
-        env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix4K_C0000 + 3] = val;
+        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - MSR_MTRRfix4K_C0000 + 3] = val;
         break;
     case MSR_MTRRdefType:
         env->mtrr_deftype = val;
@@ -398,9 +398,9 @@ void helper_wrmsr(CPUX86State *env)
         env->msr_ia32_misc_enable = val;
         break;
     default:
-        if ((uint32_t)ECX >= MSR_MC0_CTL
-            && (uint32_t)ECX < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
-            uint32_t offset = (uint32_t)ECX - MSR_MC0_CTL;
+        if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL
+            && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
+            uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL;
             if ((offset & 0x3) != 0
                 || (val == 0 || val == ~(uint64_t)0)) {
                 env->mce_banks[offset] = val;
@@ -418,7 +418,7 @@ void helper_rdmsr(CPUX86State *env)
 
     cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0);
 
-    switch ((uint32_t)ECX) {
+    switch ((uint32_t)env->regs[R_ECX]) {
     case MSR_IA32_SYSENTER_CS:
         val = env->sysenter_cs;
         break;
@@ -480,7 +480,7 @@ void helper_rdmsr(CPUX86State *env)
     case MSR_MTRRphysBase(5):
     case MSR_MTRRphysBase(6):
     case MSR_MTRRphysBase(7):
-        val = env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysBase(0)) / 2].base;
+        val = env->mtrr_var[((uint32_t)env->regs[R_ECX] - MSR_MTRRphysBase(0)) / 2].base;
         break;
     case MSR_MTRRphysMask(0):
     case MSR_MTRRphysMask(1):
@@ -490,14 +490,14 @@ void helper_rdmsr(CPUX86State *env)
     case MSR_MTRRphysMask(5):
     case MSR_MTRRphysMask(6):
     case MSR_MTRRphysMask(7):
-        val = env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysMask(0)) / 2].mask;
+        val = env->mtrr_var[((uint32_t)env->regs[R_ECX] - MSR_MTRRphysMask(0)) / 2].mask;
         break;
     case MSR_MTRRfix64K_00000:
         val = env->mtrr_fixed[0];
         break;
     case MSR_MTRRfix16K_80000:
     case MSR_MTRRfix16K_A0000:
-        val = env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix16K_80000 + 1];
+        val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - MSR_MTRRfix16K_80000 + 1];
         break;
     case MSR_MTRRfix4K_C0000:
     case MSR_MTRRfix4K_C8000:
@@ -507,7 +507,7 @@ void helper_rdmsr(CPUX86State *env)
     case MSR_MTRRfix4K_E8000:
     case MSR_MTRRfix4K_F0000:
     case MSR_MTRRfix4K_F8000:
-        val = env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix4K_C0000 + 3];
+        val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - MSR_MTRRfix4K_C0000 + 3];
         break;
     case MSR_MTRRdefType:
         val = env->mtrr_deftype;
@@ -538,9 +538,9 @@ void helper_rdmsr(CPUX86State *env)
         val = env->msr_ia32_misc_enable;
         break;
     default:
-        if ((uint32_t)ECX >= MSR_MC0_CTL
-            && (uint32_t)ECX < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
-            uint32_t offset = (uint32_t)ECX - MSR_MC0_CTL;
+        if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL
+            && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
+            uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL;
             val = env->mce_banks[offset];
             break;
         }
@@ -576,7 +576,7 @@ void helper_hlt(CPUX86State *env, int next_eip_addend)
 
 void helper_monitor(CPUX86State *env, target_ulong ptr)
 {
-    if ((uint32_t)ECX != 0) {
+    if ((uint32_t)env->regs[R_ECX] != 0) {
         raise_exception(env, EXCP0D_GPF);
     }
     /* XXX: store address? */
@@ -588,7 +588,7 @@ void helper_mwait(CPUX86State *env, int next_eip_addend)
     CPUState *cs;
     X86CPU *cpu;
 
-    if ((uint32_t)ECX != 0) {
+    if ((uint32_t)env->regs[R_ECX] != 0) {
         raise_exception(env, EXCP0D_GPF);
     }
     cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0);
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index b3c087f..60d723a 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -325,7 +325,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
         cpu_stl_kernel(env, env->tr.base + 0x20, next_eip);
         cpu_stl_kernel(env, env->tr.base + 0x24, old_eflags);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 0 * 4), env->regs[R_EAX]);
-        cpu_stl_kernel(env, env->tr.base + (0x28 + 1 * 4), ECX);
+        cpu_stl_kernel(env, env->tr.base + (0x28 + 1 * 4), env->regs[R_ECX]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 2 * 4), EDX);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 3 * 4), env->regs[R_EBX]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 4 * 4), ESP);
@@ -341,7 +341,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
         cpu_stw_kernel(env, env->tr.base + 0x0e, next_eip);
         cpu_stw_kernel(env, env->tr.base + 0x10, old_eflags);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 0 * 2), env->regs[R_EAX]);
-        cpu_stw_kernel(env, env->tr.base + (0x12 + 1 * 2), ECX);
+        cpu_stw_kernel(env, env->tr.base + (0x12 + 1 * 2), env->regs[R_ECX]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 2 * 2), EDX);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 3 * 2), env->regs[R_EBX]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 4 * 2), ESP);
@@ -397,7 +397,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
     cpu_load_eflags(env, new_eflags, eflags_mask);
     /* XXX: what to do in 16 bit case? */
     env->regs[R_EAX] = new_regs[0];
-    ECX = new_regs[1];
+    env->regs[R_ECX] = new_regs[1];
     EDX = new_regs[2];
     env->regs[R_EBX] = new_regs[3];
     ESP = new_regs[4];
@@ -949,7 +949,7 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
     if (env->hflags & HF_LMA_MASK) {
         int code64;
 
-        ECX = env->eip + next_eip_addend;
+        env->regs[R_ECX] = env->eip + next_eip_addend;
         env->regs[11] = cpu_compute_eflags(env);
 
         code64 = env->hflags & HF_CS64_MASK;
@@ -974,7 +974,7 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
             env->eip = env->cstar;
         }
     } else {
-        ECX = (uint32_t)(env->eip + next_eip_addend);
+        env->regs[R_ECX] = (uint32_t)(env->eip + next_eip_addend);
 
         cpu_x86_set_cpl(env, 0);
         cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
@@ -1015,14 +1015,14 @@ void helper_sysret(CPUX86State *env, int dflag)
                                    DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
                                    DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK |
                                    DESC_L_MASK);
-            env->eip = ECX;
+            env->eip = env->regs[R_ECX];
         } else {
             cpu_x86_load_seg_cache(env, R_CS, selector | 3,
                                    0, 0xffffffff,
                                    DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
                                    DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
                                    DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
-            env->eip = (uint32_t)ECX;
+            env->eip = (uint32_t)env->regs[R_ECX];
         }
         cpu_x86_load_seg_cache(env, R_SS, selector + 8,
                                0, 0xffffffff,
@@ -1039,7 +1039,7 @@ void helper_sysret(CPUX86State *env, int dflag)
                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
                                DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
                                DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
-        env->eip = (uint32_t)ECX;
+        env->eip = (uint32_t)env->regs[R_ECX];
         cpu_x86_load_seg_cache(env, R_SS, selector + 8,
                                0, 0xffffffff,
                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
@@ -2288,7 +2288,7 @@ void helper_sysexit(CPUX86State *env, int dflag)
                                DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
                                DESC_W_MASK | DESC_A_MASK);
     }
-    ESP = ECX;
+    ESP = env->regs[R_ECX];
     EIP = EDX;
 }
 
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index 28c78a5..952c728 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -83,7 +83,7 @@ void do_smm_enter(CPUX86State *env)
     stq_phys(sm_state + 0x7ed0, env->efer);
 
     stq_phys(sm_state + 0x7ff8, env->regs[R_EAX]);
-    stq_phys(sm_state + 0x7ff0, ECX);
+    stq_phys(sm_state + 0x7ff0, env->regs[R_ECX]);
     stq_phys(sm_state + 0x7fe8, EDX);
     stq_phys(sm_state + 0x7fe0, env->regs[R_EBX]);
     stq_phys(sm_state + 0x7fd8, ESP);
@@ -115,7 +115,7 @@ void do_smm_enter(CPUX86State *env)
     stl_phys(sm_state + 0x7fe0, ESP);
     stl_phys(sm_state + 0x7fdc, env->regs[R_EBX]);
     stl_phys(sm_state + 0x7fd8, EDX);
-    stl_phys(sm_state + 0x7fd4, ECX);
+    stl_phys(sm_state + 0x7fd4, env->regs[R_ECX]);
     stl_phys(sm_state + 0x7fd0, env->regs[R_EAX]);
     stl_phys(sm_state + 0x7fcc, env->dr[6]);
     stl_phys(sm_state + 0x7fc8, env->dr[7]);
@@ -214,7 +214,7 @@ void helper_rsm(CPUX86State *env)
     env->tr.flags = (lduw_phys(sm_state + 0x7e92) & 0xf0ff) << 8;
 
     env->regs[R_EAX] = ldq_phys(sm_state + 0x7ff8);
-    ECX = ldq_phys(sm_state + 0x7ff0);
+    env->regs[R_ECX] = ldq_phys(sm_state + 0x7ff0);
     EDX = ldq_phys(sm_state + 0x7fe8);
     env->regs[R_EBX] = ldq_phys(sm_state + 0x7fe0);
     ESP = ldq_phys(sm_state + 0x7fd8);
@@ -250,7 +250,7 @@ void helper_rsm(CPUX86State *env)
     ESP = ldl_phys(sm_state + 0x7fe0);
     env->regs[R_EBX] = ldl_phys(sm_state + 0x7fdc);
     EDX = ldl_phys(sm_state + 0x7fd8);
-    ECX = ldl_phys(sm_state + 0x7fd4);
+    env->regs[R_ECX] = ldl_phys(sm_state + 0x7fd4);
     env->regs[R_EAX] = ldl_phys(sm_state + 0x7fd0);
     env->dr[6] = ldl_phys(sm_state + 0x7fcc);
     env->dr[7] = ldl_phys(sm_state + 0x7fc8);
diff --git a/target-i386/svm_helper.c b/target-i386/svm_helper.c
index 1243207..b59a2ca 100644
--- a/target-i386/svm_helper.c
+++ b/target-i386/svm_helper.c
@@ -489,18 +489,18 @@ void helper_svm_check_intercept_param(CPUX86State *env, uint32_t type,
                                               control.msrpm_base_pa));
             uint32_t t0, t1;
 
-            switch ((uint32_t)ECX) {
+            switch ((uint32_t)env->regs[R_ECX]) {
             case 0 ... 0x1fff:
-                t0 = (ECX * 2) % 8;
-                t1 = (ECX * 2) / 8;
+                t0 = (env->regs[R_ECX] * 2) % 8;
+                t1 = (env->regs[R_ECX] * 2) / 8;
                 break;
             case 0xc0000000 ... 0xc0001fff:
-                t0 = (8192 + ECX - 0xc0000000) * 2;
+                t0 = (8192 + env->regs[R_ECX] - 0xc0000000) * 2;
                 t1 = (t0 / 8);
                 t0 %= 8;
                 break;
             case 0xc0010000 ... 0xc0011fff:
-                t0 = (16384 + ECX - 0xc0010000) * 2;
+                t0 = (16384 + env->regs[R_ECX] - 0xc0010000) * 2;
                 t1 = (t0 / 8);
                 t0 %= 8;
                 break;
commit 70b513654c5a4722e727d69ec6999e6e7818670f
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Tue May 28 16:21:00 2013 +0800

    target-i386/helper: remove EBX macro
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 4585c0a..28ff02d 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1105,8 +1105,6 @@ static inline int cpu_mmu_index (CPUX86State *env)
 #define ECX (env->regs[R_ECX])
 #undef EDX
 #define EDX (env->regs[R_EDX])
-#undef EBX
-#define EBX (env->regs[R_EBX])
 #undef ESP
 #define ESP (env->regs[R_ESP])
 #undef EBP
diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c
index f0f5aec..6370fb5 100644
--- a/target-i386/mem_helper.c
+++ b/target-i386/mem_helper.c
@@ -46,7 +46,7 @@ void helper_cmpxchg8b(CPUX86State *env, target_ulong a0)
     eflags = cpu_cc_compute_all(env, CC_OP);
     d = cpu_ldq_data(env, a0);
     if (d == (((uint64_t)EDX << 32) | (uint32_t)env->regs[R_EAX])) {
-        cpu_stq_data(env, a0, ((uint64_t)ECX << 32) | (uint32_t)EBX);
+        cpu_stq_data(env, a0, ((uint64_t)ECX << 32) | (uint32_t)env->regs[R_EBX]);
         eflags |= CC_Z;
     } else {
         /* always do the store */
@@ -71,7 +71,7 @@ void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
     d0 = cpu_ldq_data(env, a0);
     d1 = cpu_ldq_data(env, a0 + 8);
     if (d0 == env->regs[R_EAX] && d1 == EDX) {
-        cpu_stq_data(env, a0, EBX);
+        cpu_stq_data(env, a0, env->regs[R_EBX]);
         cpu_stq_data(env, a0 + 8, ECX);
         eflags |= CC_Z;
     } else {
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index a6a787f..d7be4f4 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -124,7 +124,7 @@ void helper_cpuid(CPUX86State *env)
 
     cpu_x86_cpuid(env, (uint32_t)env->regs[R_EAX], (uint32_t)ECX, &eax, &ebx, &ecx, &edx);
     env->regs[R_EAX] = eax;
-    EBX = ebx;
+    env->regs[R_EBX] = ebx;
     ECX = ecx;
     EDX = edx;
 }
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 719b7bb..b3c087f 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -327,7 +327,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
         cpu_stl_kernel(env, env->tr.base + (0x28 + 0 * 4), env->regs[R_EAX]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 1 * 4), ECX);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 2 * 4), EDX);
-        cpu_stl_kernel(env, env->tr.base + (0x28 + 3 * 4), EBX);
+        cpu_stl_kernel(env, env->tr.base + (0x28 + 3 * 4), env->regs[R_EBX]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 4 * 4), ESP);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 5 * 4), EBP);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 6 * 4), ESI);
@@ -343,7 +343,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
         cpu_stw_kernel(env, env->tr.base + (0x12 + 0 * 2), env->regs[R_EAX]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 1 * 2), ECX);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 2 * 2), EDX);
-        cpu_stw_kernel(env, env->tr.base + (0x12 + 3 * 2), EBX);
+        cpu_stw_kernel(env, env->tr.base + (0x12 + 3 * 2), env->regs[R_EBX]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 4 * 2), ESP);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 5 * 2), EBP);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 6 * 2), ESI);
@@ -399,7 +399,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
     env->regs[R_EAX] = new_regs[0];
     ECX = new_regs[1];
     EDX = new_regs[2];
-    EBX = new_regs[3];
+    env->regs[R_EBX] = new_regs[3];
     ESP = new_regs[4];
     EBP = new_regs[5];
     ESI = new_regs[6];
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index 1ea6107..28c78a5 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -85,7 +85,7 @@ void do_smm_enter(CPUX86State *env)
     stq_phys(sm_state + 0x7ff8, env->regs[R_EAX]);
     stq_phys(sm_state + 0x7ff0, ECX);
     stq_phys(sm_state + 0x7fe8, EDX);
-    stq_phys(sm_state + 0x7fe0, EBX);
+    stq_phys(sm_state + 0x7fe0, env->regs[R_EBX]);
     stq_phys(sm_state + 0x7fd8, ESP);
     stq_phys(sm_state + 0x7fd0, EBP);
     stq_phys(sm_state + 0x7fc8, ESI);
@@ -113,7 +113,7 @@ void do_smm_enter(CPUX86State *env)
     stl_phys(sm_state + 0x7fe8, ESI);
     stl_phys(sm_state + 0x7fe4, EBP);
     stl_phys(sm_state + 0x7fe0, ESP);
-    stl_phys(sm_state + 0x7fdc, EBX);
+    stl_phys(sm_state + 0x7fdc, env->regs[R_EBX]);
     stl_phys(sm_state + 0x7fd8, EDX);
     stl_phys(sm_state + 0x7fd4, ECX);
     stl_phys(sm_state + 0x7fd0, env->regs[R_EAX]);
@@ -216,7 +216,7 @@ void helper_rsm(CPUX86State *env)
     env->regs[R_EAX] = ldq_phys(sm_state + 0x7ff8);
     ECX = ldq_phys(sm_state + 0x7ff0);
     EDX = ldq_phys(sm_state + 0x7fe8);
-    EBX = ldq_phys(sm_state + 0x7fe0);
+    env->regs[R_EBX] = ldq_phys(sm_state + 0x7fe0);
     ESP = ldq_phys(sm_state + 0x7fd8);
     EBP = ldq_phys(sm_state + 0x7fd0);
     ESI = ldq_phys(sm_state + 0x7fc8);
@@ -248,7 +248,7 @@ void helper_rsm(CPUX86State *env)
     ESI = ldl_phys(sm_state + 0x7fe8);
     EBP = ldl_phys(sm_state + 0x7fe4);
     ESP = ldl_phys(sm_state + 0x7fe0);
-    EBX = ldl_phys(sm_state + 0x7fdc);
+    env->regs[R_EBX] = ldl_phys(sm_state + 0x7fdc);
     EDX = ldl_phys(sm_state + 0x7fd8);
     ECX = ldl_phys(sm_state + 0x7fd4);
     env->regs[R_EAX] = ldl_phys(sm_state + 0x7fd0);
commit 4b34e3ad83588602834c05c0d59a0d2973e9f48c
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Tue May 28 16:20:59 2013 +0800

    target-i386/helper: remove EAX macro
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 058c57f..4585c0a 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1101,8 +1101,6 @@ static inline int cpu_mmu_index (CPUX86State *env)
         ? MMU_KSMAP_IDX : MMU_KERNEL_IDX;
 }
 
-#undef EAX
-#define EAX (env->regs[R_EAX])
 #undef ECX
 #define ECX (env->regs[R_ECX])
 #undef EDX
diff --git a/target-i386/int_helper.c b/target-i386/int_helper.c
index 74c7c36..16d1ed5 100644
--- a/target-i386/int_helper.c
+++ b/target-i386/int_helper.c
@@ -45,7 +45,7 @@ void helper_divb_AL(CPUX86State *env, target_ulong t0)
 {
     unsigned int num, den, q, r;
 
-    num = (EAX & 0xffff);
+    num = (env->regs[R_EAX] & 0xffff);
     den = (t0 & 0xff);
     if (den == 0) {
         raise_exception(env, EXCP00_DIVZ);
@@ -56,14 +56,14 @@ void helper_divb_AL(CPUX86State *env, target_ulong t0)
     }
     q &= 0xff;
     r = (num % den) & 0xff;
-    EAX = (EAX & ~0xffff) | (r << 8) | q;
+    env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | (r << 8) | q;
 }
 
 void helper_idivb_AL(CPUX86State *env, target_ulong t0)
 {
     int num, den, q, r;
 
-    num = (int16_t)EAX;
+    num = (int16_t)env->regs[R_EAX];
     den = (int8_t)t0;
     if (den == 0) {
         raise_exception(env, EXCP00_DIVZ);
@@ -74,14 +74,14 @@ void helper_idivb_AL(CPUX86State *env, target_ulong t0)
     }
     q &= 0xff;
     r = (num % den) & 0xff;
-    EAX = (EAX & ~0xffff) | (r << 8) | q;
+    env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | (r << 8) | q;
 }
 
 void helper_divw_AX(CPUX86State *env, target_ulong t0)
 {
     unsigned int num, den, q, r;
 
-    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
+    num = (env->regs[R_EAX] & 0xffff) | ((EDX & 0xffff) << 16);
     den = (t0 & 0xffff);
     if (den == 0) {
         raise_exception(env, EXCP00_DIVZ);
@@ -92,7 +92,7 @@ void helper_divw_AX(CPUX86State *env, target_ulong t0)
     }
     q &= 0xffff;
     r = (num % den) & 0xffff;
-    EAX = (EAX & ~0xffff) | q;
+    env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | q;
     EDX = (EDX & ~0xffff) | r;
 }
 
@@ -100,7 +100,7 @@ void helper_idivw_AX(CPUX86State *env, target_ulong t0)
 {
     int num, den, q, r;
 
-    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
+    num = (env->regs[R_EAX] & 0xffff) | ((EDX & 0xffff) << 16);
     den = (int16_t)t0;
     if (den == 0) {
         raise_exception(env, EXCP00_DIVZ);
@@ -111,7 +111,7 @@ void helper_idivw_AX(CPUX86State *env, target_ulong t0)
     }
     q &= 0xffff;
     r = (num % den) & 0xffff;
-    EAX = (EAX & ~0xffff) | q;
+    env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | q;
     EDX = (EDX & ~0xffff) | r;
 }
 
@@ -120,7 +120,7 @@ void helper_divl_EAX(CPUX86State *env, target_ulong t0)
     unsigned int den, r;
     uint64_t num, q;
 
-    num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
+    num = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)EDX) << 32);
     den = t0;
     if (den == 0) {
         raise_exception(env, EXCP00_DIVZ);
@@ -130,7 +130,7 @@ void helper_divl_EAX(CPUX86State *env, target_ulong t0)
     if (q > 0xffffffff) {
         raise_exception(env, EXCP00_DIVZ);
     }
-    EAX = (uint32_t)q;
+    env->regs[R_EAX] = (uint32_t)q;
     EDX = (uint32_t)r;
 }
 
@@ -139,7 +139,7 @@ void helper_idivl_EAX(CPUX86State *env, target_ulong t0)
     int den, r;
     int64_t num, q;
 
-    num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
+    num = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)EDX) << 32);
     den = t0;
     if (den == 0) {
         raise_exception(env, EXCP00_DIVZ);
@@ -149,7 +149,7 @@ void helper_idivl_EAX(CPUX86State *env, target_ulong t0)
     if (q != (int32_t)q) {
         raise_exception(env, EXCP00_DIVZ);
     }
-    EAX = (uint32_t)q;
+    env->regs[R_EAX] = (uint32_t)q;
     EDX = (uint32_t)r;
 }
 
@@ -160,10 +160,10 @@ void helper_aam(CPUX86State *env, int base)
 {
     int al, ah;
 
-    al = EAX & 0xff;
+    al = env->regs[R_EAX] & 0xff;
     ah = al / base;
     al = al % base;
-    EAX = (EAX & ~0xffff) | al | (ah << 8);
+    env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | al | (ah << 8);
     CC_DST = al;
 }
 
@@ -171,10 +171,10 @@ void helper_aad(CPUX86State *env, int base)
 {
     int al, ah;
 
-    al = EAX & 0xff;
-    ah = (EAX >> 8) & 0xff;
+    al = env->regs[R_EAX] & 0xff;
+    ah = (env->regs[R_EAX] >> 8) & 0xff;
     al = ((ah * base) + al) & 0xff;
-    EAX = (EAX & ~0xffff) | al;
+    env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | al;
     CC_DST = al;
 }
 
@@ -186,8 +186,8 @@ void helper_aaa(CPUX86State *env)
 
     eflags = cpu_cc_compute_all(env, CC_OP);
     af = eflags & CC_A;
-    al = EAX & 0xff;
-    ah = (EAX >> 8) & 0xff;
+    al = env->regs[R_EAX] & 0xff;
+    ah = (env->regs[R_EAX] >> 8) & 0xff;
 
     icarry = (al > 0xf9);
     if (((al & 0x0f) > 9) || af) {
@@ -198,7 +198,7 @@ void helper_aaa(CPUX86State *env)
         eflags &= ~(CC_C | CC_A);
         al &= 0x0f;
     }
-    EAX = (EAX & ~0xffff) | al | (ah << 8);
+    env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | al | (ah << 8);
     CC_SRC = eflags;
 }
 
@@ -210,8 +210,8 @@ void helper_aas(CPUX86State *env)
 
     eflags = cpu_cc_compute_all(env, CC_OP);
     af = eflags & CC_A;
-    al = EAX & 0xff;
-    ah = (EAX >> 8) & 0xff;
+    al = env->regs[R_EAX] & 0xff;
+    ah = (env->regs[R_EAX] >> 8) & 0xff;
 
     icarry = (al < 6);
     if (((al & 0x0f) > 9) || af) {
@@ -222,7 +222,7 @@ void helper_aas(CPUX86State *env)
         eflags &= ~(CC_C | CC_A);
         al &= 0x0f;
     }
-    EAX = (EAX & ~0xffff) | al | (ah << 8);
+    env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | al | (ah << 8);
     CC_SRC = eflags;
 }
 
@@ -234,7 +234,7 @@ void helper_daa(CPUX86State *env)
     eflags = cpu_cc_compute_all(env, CC_OP);
     cf = eflags & CC_C;
     af = eflags & CC_A;
-    old_al = al = EAX & 0xff;
+    old_al = al = env->regs[R_EAX] & 0xff;
 
     eflags = 0;
     if (((al & 0x0f) > 9) || af) {
@@ -245,7 +245,7 @@ void helper_daa(CPUX86State *env)
         al = (al + 0x60) & 0xff;
         eflags |= CC_C;
     }
-    EAX = (EAX & ~0xff) | al;
+    env->regs[R_EAX] = (env->regs[R_EAX] & ~0xff) | al;
     /* well, speed is not an issue here, so we compute the flags by hand */
     eflags |= (al == 0) << 6; /* zf */
     eflags |= parity_table[al]; /* pf */
@@ -261,7 +261,7 @@ void helper_das(CPUX86State *env)
     eflags = cpu_cc_compute_all(env, CC_OP);
     cf = eflags & CC_C;
     af = eflags & CC_A;
-    al = EAX & 0xff;
+    al = env->regs[R_EAX] & 0xff;
 
     eflags = 0;
     al1 = al;
@@ -276,7 +276,7 @@ void helper_das(CPUX86State *env)
         al = (al - 0x60) & 0xff;
         eflags |= CC_C;
     }
-    EAX = (EAX & ~0xff) | al;
+    env->regs[R_EAX] = (env->regs[R_EAX] & ~0xff) | al;
     /* well, speed is not an issue here, so we compute the flags by hand */
     eflags |= (al == 0) << 6; /* zf */
     eflags |= parity_table[al]; /* pf */
@@ -381,12 +381,12 @@ void helper_divq_EAX(CPUX86State *env, target_ulong t0)
     if (t0 == 0) {
         raise_exception(env, EXCP00_DIVZ);
     }
-    r0 = EAX;
+    r0 = env->regs[R_EAX];
     r1 = EDX;
     if (div64(&r0, &r1, t0)) {
         raise_exception(env, EXCP00_DIVZ);
     }
-    EAX = r0;
+    env->regs[R_EAX] = r0;
     EDX = r1;
 }
 
@@ -397,12 +397,12 @@ void helper_idivq_EAX(CPUX86State *env, target_ulong t0)
     if (t0 == 0) {
         raise_exception(env, EXCP00_DIVZ);
     }
-    r0 = EAX;
+    r0 = env->regs[R_EAX];
     r1 = EDX;
     if (idiv64(&r0, &r1, t0)) {
         raise_exception(env, EXCP00_DIVZ);
     }
-    EAX = r0;
+    env->regs[R_EAX] = r0;
     EDX = r1;
 }
 #endif
diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c
index 6cf9ba0..f0f5aec 100644
--- a/target-i386/mem_helper.c
+++ b/target-i386/mem_helper.c
@@ -45,14 +45,14 @@ void helper_cmpxchg8b(CPUX86State *env, target_ulong a0)
 
     eflags = cpu_cc_compute_all(env, CC_OP);
     d = cpu_ldq_data(env, a0);
-    if (d == (((uint64_t)EDX << 32) | (uint32_t)EAX)) {
+    if (d == (((uint64_t)EDX << 32) | (uint32_t)env->regs[R_EAX])) {
         cpu_stq_data(env, a0, ((uint64_t)ECX << 32) | (uint32_t)EBX);
         eflags |= CC_Z;
     } else {
         /* always do the store */
         cpu_stq_data(env, a0, d);
         EDX = (uint32_t)(d >> 32);
-        EAX = (uint32_t)d;
+        env->regs[R_EAX] = (uint32_t)d;
         eflags &= ~CC_Z;
     }
     CC_SRC = eflags;
@@ -70,7 +70,7 @@ void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
     eflags = cpu_cc_compute_all(env, CC_OP);
     d0 = cpu_ldq_data(env, a0);
     d1 = cpu_ldq_data(env, a0 + 8);
-    if (d0 == EAX && d1 == EDX) {
+    if (d0 == env->regs[R_EAX] && d1 == EDX) {
         cpu_stq_data(env, a0, EBX);
         cpu_stq_data(env, a0 + 8, ECX);
         eflags |= CC_Z;
@@ -79,7 +79,7 @@ void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
         cpu_stq_data(env, a0, d0);
         cpu_stq_data(env, a0 + 8, d1);
         EDX = d1;
-        EAX = d0;
+        env->regs[R_EAX] = d0;
         eflags &= ~CC_Z;
     }
     CC_SRC = eflags;
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index ec834fc..a6a787f 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -122,8 +122,8 @@ void helper_cpuid(CPUX86State *env)
 
     cpu_svm_check_intercept_param(env, SVM_EXIT_CPUID, 0);
 
-    cpu_x86_cpuid(env, (uint32_t)EAX, (uint32_t)ECX, &eax, &ebx, &ecx, &edx);
-    EAX = eax;
+    cpu_x86_cpuid(env, (uint32_t)env->regs[R_EAX], (uint32_t)ECX, &eax, &ebx, &ecx, &edx);
+    env->regs[R_EAX] = eax;
     EBX = ebx;
     ECX = ecx;
     EDX = edx;
@@ -234,7 +234,7 @@ void helper_rdtsc(CPUX86State *env)
     cpu_svm_check_intercept_param(env, SVM_EXIT_RDTSC, 0);
 
     val = cpu_get_tsc(env) + env->tsc_offset;
-    EAX = (uint32_t)(val);
+    env->regs[R_EAX] = (uint32_t)(val);
     EDX = (uint32_t)(val >> 32);
 }
 
@@ -271,7 +271,7 @@ void helper_wrmsr(CPUX86State *env)
 
     cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1);
 
-    val = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
+    val = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)EDX) << 32);
 
     switch ((uint32_t)ECX) {
     case MSR_IA32_SYSENTER_CS:
@@ -548,7 +548,7 @@ void helper_rdmsr(CPUX86State *env)
         val = 0;
         break;
     }
-    EAX = (uint32_t)(val);
+    env->regs[R_EAX] = (uint32_t)(val);
     EDX = (uint32_t)(val >> 32);
 }
 #endif
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 906e4f3..719b7bb 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -324,7 +324,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
         /* 32 bit */
         cpu_stl_kernel(env, env->tr.base + 0x20, next_eip);
         cpu_stl_kernel(env, env->tr.base + 0x24, old_eflags);
-        cpu_stl_kernel(env, env->tr.base + (0x28 + 0 * 4), EAX);
+        cpu_stl_kernel(env, env->tr.base + (0x28 + 0 * 4), env->regs[R_EAX]);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 1 * 4), ECX);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 2 * 4), EDX);
         cpu_stl_kernel(env, env->tr.base + (0x28 + 3 * 4), EBX);
@@ -340,7 +340,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
         /* 16 bit */
         cpu_stw_kernel(env, env->tr.base + 0x0e, next_eip);
         cpu_stw_kernel(env, env->tr.base + 0x10, old_eflags);
-        cpu_stw_kernel(env, env->tr.base + (0x12 + 0 * 2), EAX);
+        cpu_stw_kernel(env, env->tr.base + (0x12 + 0 * 2), env->regs[R_EAX]);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 1 * 2), ECX);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 2 * 2), EDX);
         cpu_stw_kernel(env, env->tr.base + (0x12 + 3 * 2), EBX);
@@ -396,7 +396,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
     }
     cpu_load_eflags(env, new_eflags, eflags_mask);
     /* XXX: what to do in 16 bit case? */
-    EAX = new_regs[0];
+    env->regs[R_EAX] = new_regs[0];
     ECX = new_regs[1];
     EDX = new_regs[2];
     EBX = new_regs[3];
@@ -1175,7 +1175,7 @@ static void do_interrupt_all(CPUX86State *env, int intno, int is_int,
             if (intno == 0x0e) {
                 qemu_log(" CR2=" TARGET_FMT_lx, env->cr[2]);
             } else {
-                qemu_log(" EAX=" TARGET_FMT_lx, EAX);
+                qemu_log(" env->regs[R_EAX]=" TARGET_FMT_lx, env->regs[R_EAX]);
             }
             qemu_log("\n");
             log_cpu_state(env, CPU_DUMP_CCOP);
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index eea2fe9..1ea6107 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -82,7 +82,7 @@ void do_smm_enter(CPUX86State *env)
 
     stq_phys(sm_state + 0x7ed0, env->efer);
 
-    stq_phys(sm_state + 0x7ff8, EAX);
+    stq_phys(sm_state + 0x7ff8, env->regs[R_EAX]);
     stq_phys(sm_state + 0x7ff0, ECX);
     stq_phys(sm_state + 0x7fe8, EDX);
     stq_phys(sm_state + 0x7fe0, EBX);
@@ -116,7 +116,7 @@ void do_smm_enter(CPUX86State *env)
     stl_phys(sm_state + 0x7fdc, EBX);
     stl_phys(sm_state + 0x7fd8, EDX);
     stl_phys(sm_state + 0x7fd4, ECX);
-    stl_phys(sm_state + 0x7fd0, EAX);
+    stl_phys(sm_state + 0x7fd0, env->regs[R_EAX]);
     stl_phys(sm_state + 0x7fcc, env->dr[6]);
     stl_phys(sm_state + 0x7fc8, env->dr[7]);
 
@@ -213,7 +213,7 @@ void helper_rsm(CPUX86State *env)
     env->tr.limit = ldl_phys(sm_state + 0x7e94);
     env->tr.flags = (lduw_phys(sm_state + 0x7e92) & 0xf0ff) << 8;
 
-    EAX = ldq_phys(sm_state + 0x7ff8);
+    env->regs[R_EAX] = ldq_phys(sm_state + 0x7ff8);
     ECX = ldq_phys(sm_state + 0x7ff0);
     EDX = ldq_phys(sm_state + 0x7fe8);
     EBX = ldq_phys(sm_state + 0x7fe0);
@@ -251,7 +251,7 @@ void helper_rsm(CPUX86State *env)
     EBX = ldl_phys(sm_state + 0x7fdc);
     EDX = ldl_phys(sm_state + 0x7fd8);
     ECX = ldl_phys(sm_state + 0x7fd4);
-    EAX = ldl_phys(sm_state + 0x7fd0);
+    env->regs[R_EAX] = ldl_phys(sm_state + 0x7fd0);
     env->dr[6] = ldl_phys(sm_state + 0x7fcc);
     env->dr[7] = ldl_phys(sm_state + 0x7fc8);
 
diff --git a/target-i386/svm_helper.c b/target-i386/svm_helper.c
index c46a213..1243207 100644
--- a/target-i386/svm_helper.c
+++ b/target-i386/svm_helper.c
@@ -129,9 +129,9 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
     cpu_svm_check_intercept_param(env, SVM_EXIT_VMRUN, 0);
 
     if (aflag == 2) {
-        addr = EAX;
+        addr = env->regs[R_EAX];
     } else {
-        addr = (uint32_t)EAX;
+        addr = (uint32_t)env->regs[R_EAX];
     }
 
     qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmrun! " TARGET_FMT_lx "\n", addr);
@@ -172,7 +172,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip),
              EIP + next_eip_addend);
     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp), ESP);
-    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax), EAX);
+    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax), env->regs[R_EAX]);
 
     /* load the interception bitmaps so we do not need to access the
        vmcb in svm mode */
@@ -251,7 +251,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
     EIP = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip));
     env->eip = EIP;
     ESP = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp));
-    EAX = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax));
+    env->regs[R_EAX] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax));
     env->dr[7] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr7));
     env->dr[6] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr6));
     cpu_x86_set_cpl(env, ldub_phys(env->vm_vmcb + offsetof(struct vmcb,
@@ -341,9 +341,9 @@ void helper_vmload(CPUX86State *env, int aflag)
     cpu_svm_check_intercept_param(env, SVM_EXIT_VMLOAD, 0);
 
     if (aflag == 2) {
-        addr = EAX;
+        addr = env->regs[R_EAX];
     } else {
-        addr = (uint32_t)EAX;
+        addr = (uint32_t)env->regs[R_EAX];
     }
 
     qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmload! " TARGET_FMT_lx
@@ -379,9 +379,9 @@ void helper_vmsave(CPUX86State *env, int aflag)
     cpu_svm_check_intercept_param(env, SVM_EXIT_VMSAVE, 0);
 
     if (aflag == 2) {
-        addr = EAX;
+        addr = env->regs[R_EAX];
     } else {
-        addr = (uint32_t)EAX;
+        addr = (uint32_t)env->regs[R_EAX];
     }
 
     qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmsave! " TARGET_FMT_lx
@@ -439,9 +439,9 @@ void helper_invlpga(CPUX86State *env, int aflag)
     cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPGA, 0);
 
     if (aflag == 2) {
-        addr = EAX;
+        addr = env->regs[R_EAX];
     } else {
-        addr = (uint32_t)EAX;
+        addr = (uint32_t)env->regs[R_EAX];
     }
 
     /* XXX: could use the ASID to see if it is needed to do the
@@ -607,7 +607,7 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip),
              env->eip);
     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp), ESP);
-    stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax), EAX);
+    stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax), env->regs[R_EAX]);
     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr7), env->dr[7]);
     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr6), env->dr[6]);
     stb_phys(env->vm_vmcb + offsetof(struct vmcb, save.cpl),
@@ -659,7 +659,7 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
 
     EIP = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip));
     ESP = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp));
-    EAX = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax));
+    env->regs[R_EAX] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax));
 
     env->dr[6] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr6));
     env->dr[7] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr7));
commit 371a775dc18ece3ff7d77328d1ee28cb2d473706
Merge: 22bfa16 fef7fbc
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Jun 15 10:53:44 2013 +0000

    Merge branch 'realize-isa.v2' of git://github.com/afaerber/qemu-cpu
    
    * 'realize-isa.v2' of git://github.com/afaerber/qemu-cpu:
      qdev: Drop FROM_QBUS() macro
      isa: QOM'ify ISADevice
      isa: QOM'ify ISABus
      i8259: Convert PICCommonState to use QOM realizefn
      kvm/i8259: QOM'ify some more
      i8259: QOM'ify some more
      i8254: Convert PITCommonState to QOM realizefn
      kvm/i8254: QOM'ify some more
      i8254: QOM'ify some more
      isa: Use realizefn for ISADevice
      cs4231a: QOM'ify some more
      gus: QOM'ify some more

commit 22bfa16ed3d4c9d534dcfe6f2381a654f32296b9
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Mon Jun 10 13:23:20 2013 -0500

    ide-test: fix failure for test_flush
    
    bd07684aacfb61668ae2c25b7dd00b64f3d7c7f3 added a test to ensure BSY
    flag is set when a flush request is in flight. It does this by setting
    a blkdebug breakpoint on flush_to_os before issuing a CMD_FLUSH_CACHE.
    It then resumes CMD_FLUSH_CACHE operation and checks that BSY is unset.
    
    The actual unsetting of BSY does not occur until ide_flush_cb gets
    called in a bh, however, so in some cases this check will race with
    the actual completion.
    
    Fix this by polling the ide status register until BSY flag gets unset
    before we do our final sanity checks. According to
    f68ec8379e88502b4841a110c070e9b118d3151c this is in line with how a guest
    would determine whether or not the device is still busy.
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/tests/ide-test.c b/tests/ide-test.c
index 828e71a..7e2eb94 100644
--- a/tests/ide-test.c
+++ b/tests/ide-test.c
@@ -455,7 +455,10 @@ static void test_flush(void)
     data = inb(IDE_BASE + reg_device);
     g_assert_cmpint(data & DEV, ==, 0);
 
-    data = inb(IDE_BASE + reg_status);
+    do {
+        data = inb(IDE_BASE + reg_status);
+    } while (data & BSY);
+
     assert_bit_set(data, DRDY);
     assert_bit_clear(data, BSY | DF | ERR | DRQ);
 
commit 187f1bcb9ce8e3cd3f634dd5405f9e5ed02b38ce
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri May 24 16:26:57 2013 +0100

    ppc: Remove CONFIG_FDT conditionals
    
    Now that we know we're compiling with libfdt we can remove the
    CONFIG_FDT conditionals.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Reviewed-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Tested-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: 1369409217-7553-5-git-send-email-peter.maydell at linaro.org

diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index cc3587f..bcaa52f 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -42,6 +42,6 @@ CONFIG_I8259=y
 CONFIG_XILINX=y
 CONFIG_XILINX_ETHLITE=y
 CONFIG_OPENPIC=y
-CONFIG_E500=$(CONFIG_FDT)
+CONFIG_E500=y
 # For PReP
 CONFIG_MC146818RTC=y
diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
index 884ea8a..8b7874e 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -42,8 +42,8 @@ CONFIG_I8259=y
 CONFIG_XILINX=y
 CONFIG_XILINX_ETHLITE=y
 CONFIG_OPENPIC=y
-CONFIG_PSERIES=$(CONFIG_FDT)
-CONFIG_E500=$(CONFIG_FDT)
+CONFIG_PSERIES=y
+CONFIG_E500=y
 # For pSeries
 CONFIG_PCI_HOTPLUG=y
 # For PReP
diff --git a/default-configs/ppcemb-softmmu.mak b/default-configs/ppcemb-softmmu.mak
index be93e03..61920ff 100644
--- a/default-configs/ppcemb-softmmu.mak
+++ b/default-configs/ppcemb-softmmu.mak
@@ -37,6 +37,6 @@ CONFIG_I8259=y
 CONFIG_XILINX=y
 CONFIG_XILINX_ETHLITE=y
 CONFIG_OPENPIC=y
-CONFIG_E500=$(CONFIG_FDT)
+CONFIG_E500=y
 # For PReP
 CONFIG_MC146818RTC=y
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index a55e717..b0c1c02 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -58,7 +58,6 @@ static int bamboo_load_device_tree(hwaddr addr,
                                      const char *kernel_cmdline)
 {
     int ret = -1;
-#ifdef CONFIG_FDT
     uint32_t mem_reg_property[] = { 0, 0, cpu_to_be32(ramsize) };
     char *filename;
     int fdt_size;
@@ -115,7 +114,6 @@ static int bamboo_load_device_tree(hwaddr addr,
     g_free(fdt);
 
 out:
-#endif
 
     return ret;
 }
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index 1405c32..304f316 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -34,9 +34,7 @@
 #include "hw/ppc/spapr_vio.h"
 #include "hw/ppc/xics.h"
 
-#ifdef CONFIG_FDT
 #include <libfdt.h>
-#endif /* CONFIG_FDT */
 
 /* #define DEBUG_SPAPR */
 
@@ -94,7 +92,6 @@ VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
     return NULL;
 }
 
-#ifdef CONFIG_FDT
 static int vio_make_devnode(VIOsPAPRDevice *dev,
                             void *fdt)
 {
@@ -159,7 +156,6 @@ static int vio_make_devnode(VIOsPAPRDevice *dev,
 
     return node_off;
 }
-#endif /* CONFIG_FDT */
 
 /*
  * CRQ handling
@@ -570,7 +566,6 @@ static void spapr_vio_register_types(void)
 
 type_init(spapr_vio_register_types)
 
-#ifdef CONFIG_FDT
 static int compare_reg(const void *p1, const void *p2)
 {
     VIOsPAPRDevice const *dev1, *dev2;
@@ -655,4 +650,3 @@ int spapr_populate_chosen_stdout(void *fdt, VIOsPAPRBus *bus)
 
     return ret;
 }
-#endif /* CONFIG_FDT */
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index 1b4ce76..709a707 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -141,7 +141,6 @@ static int xilinx_load_device_tree(hwaddr addr,
 {
     char *path;
     int fdt_size;
-#ifdef CONFIG_FDT
     void *fdt;
     int r;
 
@@ -162,23 +161,6 @@ static int xilinx_load_device_tree(hwaddr addr,
     if (r < 0)
         fprintf(stderr, "couldn't set /chosen/bootargs\n");
     cpu_physical_memory_write(addr, fdt, fdt_size);
-#else
-    /* We lack libfdt so we cannot manipulate the fdt. Just pass on the blob
-       to the kernel.  */
-    fdt_size = load_image_targphys("ppc.dtb", addr, 0x10000);
-    if (fdt_size < 0) {
-        path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
-        if (path) {
-            fdt_size = load_image_targphys(path, addr, 0x10000);
-            g_free(path);
-        }
-    }
-
-    if (kernel_cmdline) {
-        fprintf(stderr,
-                "Warning: missing libfdt, cannot pass cmdline to kernel!\n");
-    }
-#endif
     return fdt_size;
 }
 
commit 564720219a0863625e9989fd258ccc57a616550f
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri May 24 16:26:56 2013 +0100

    microblaze: Remove CONFIG_FDT conditionals
    
    Now that we know we're compiling with libfdt we can remove the
    CONFIG_FDT conditionals.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Reviewed-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Tested-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: 1369409217-7553-4-git-send-email-peter.maydell at linaro.org

diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index e543d88..3f1d70e 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -61,7 +61,6 @@ static int microblaze_load_dtb(hwaddr addr,
                                       const char *dtb_filename)
 {
     int fdt_size;
-#ifdef CONFIG_FDT
     void *fdt = NULL;
     int r;
 
@@ -81,17 +80,6 @@ static int microblaze_load_dtb(hwaddr addr,
     }
 
     cpu_physical_memory_write(addr, fdt, fdt_size);
-#else
-    /* We lack libfdt so we cannot manipulate the fdt. Just pass on the blob
-       to the kernel.  */
-    if (dtb_filename) {
-        fdt_size = load_image_targphys(dtb_filename, addr, 0x10000);
-    }
-    if (kernel_cmdline) {
-        fprintf(stderr,
-                "Warning: missing libfdt, cannot pass cmdline to kernel!\n");
-    }
-#endif
     return fdt_size;
 }
 
commit 298c3833dba62512659ab550c3daa1e6d8faec94
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri May 24 16:26:55 2013 +0100

    arm: Remove CONFIG_FDT conditionals
    
    Now that we know we're compiling with libfdt, we can remove the
    CONFIG_FDT conditionals.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Reviewed-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Tested-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: 1369409217-7553-3-git-send-email-peter.maydell at linaro.org

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index f451529..defcf15 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -227,7 +227,6 @@ static void set_kernel_args_old(const struct arm_boot_info *info)
 
 static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
 {
-#ifdef CONFIG_FDT
     uint32_t *mem_reg_property;
     uint32_t mem_reg_propsize;
     void *fdt = NULL;
@@ -308,12 +307,6 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
     cpu_physical_memory_write(addr, fdt, size);
 
     return 0;
-
-#else
-    fprintf(stderr, "Device tree requested, "
-                "but qemu was compiled without fdt support\n");
-    return -1;
-#endif
 }
 
 static void do_cpu_reset(void *opaque)
commit e169e1e1ae1e75c522f932554890fb0f2f3e9999
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri May 24 16:26:54 2013 +0100

    configure: Require libfdt for arm, ppc, microblaze softmmu targets
    
    A number of our softmmu targets (PPC, ARM, Microblaze) now more or
    less require flattened device tree support for various board models
    to work correctly.  Make libfdt mandatory if the target list includes
    these, rather than building unhelpful half-functional binaries.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Reviewed-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Tested-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: 1369409217-7553-2-git-send-email-peter.maydell at linaro.org

diff --git a/configure b/configure
index 31b7783..ad32f87 100755
--- a/configure
+++ b/configure
@@ -2486,6 +2486,26 @@ fi
 
 ##########################################
 # fdt probe
+# fdt support is mandatory for at least some target architectures,
+# so insist on it if we're building those system emulators.
+fdt_required=no
+for target in $target_list; do
+  case $target in
+    arm*-softmmu|ppc*-softmmu|microblaze*-softmmu)
+      fdt_required=yes
+    ;;
+  esac
+done
+
+if test "$fdt_required" = "yes"; then
+  if test "$fdt" = "no"; then
+    error_exit "fdt disabled but some requested targets require it." \
+      "You can turn off fdt only if you also disable all the system emulation" \
+      "targets which need it (by specifying a cut down --target-list)."
+  fi
+  fdt=yes
+fi
+
 if test "$fdt" != "no" ; then
   fdt_libs="-lfdt"
   # explicitly check for libfdt_env.h as it is missing in some stable installs
commit 96ce65457690561417ae8e6f0e85f3c6f135018b
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon May 27 14:20:57 2013 +1000

    configure: dtc: Probe for libfdt_env.h
    
    Currently QEMU provides a local clone of the file libfdt_env.h in
    /include. This file is supposed to come with the libfdt package and is
    only needed for broken installs of libfdt. Now that we have submodule
    dtc, just ignore these broken installs and prompt for the dtc submodule
    install instead. QEMU's local libfdt_env.h is removed accordingly.
    
    Manifests as a bug when building QEMU with modern libfdt. The new
    version of libfdt does not compile when QEMUs libfdt_env.h takes
    precedence over the hosts.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Acked-by: David Gibson <david at gibson.dropbear.id.au>
    Signed-off-by: Kim Phillips <kim.phillips at freescale.com>
    Acked-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 9b6a3a52e3f46cfbc1ded9ab56385ec045e46705.1369628289.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/configure b/configure
index 8732185..31b7783 100755
--- a/configure
+++ b/configure
@@ -2488,7 +2488,9 @@ fi
 # fdt probe
 if test "$fdt" != "no" ; then
   fdt_libs="-lfdt"
+  # explicitly check for libfdt_env.h as it is missing in some stable installs
   cat > $TMPC << EOF
+#include <libfdt_env.h>
 int main(void) { return 0; }
 EOF
   if compile_prog "" "$fdt_libs" ; then
diff --git a/include/libfdt_env.h b/include/libfdt_env.h
deleted file mode 100644
index 3667d4c..0000000
--- a/include/libfdt_env.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Copyright IBM Corp. 2008
- * Authors: Hollis Blanchard <hollisb at us.ibm.com>
- *
- */
-
-#ifndef _LIBFDT_ENV_H
-#define _LIBFDT_ENV_H
-
-#include "qemu/bswap.h"
-
-#ifdef HOST_WORDS_BIGENDIAN
-#define fdt32_to_cpu(x)  (x)
-#define cpu_to_fdt32(x)  (x)
-#define fdt64_to_cpu(x)  (x)
-#define cpu_to_fdt64(x)  (x)
-#else
-#define fdt32_to_cpu(x)  bswap32(x)
-#define cpu_to_fdt32(x)  bswap32(x)
-#define fdt64_to_cpu(x)  bswap64(x)
-#define cpu_to_fdt64(x)  bswap64(x)
-#endif
-
-#endif /* _LIBFDT_ENV_H */
commit c02a9552a4c89f2fdf23defe1d2c13b834ae3a4a
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Jun 4 14:45:28 2013 +0200

    build: drop TARGET_TYPE
    
    Just use the TARGET_NAME free string.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Message-id: 1370349928-20419-6-git-send-email-pbonzini at redhat.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/arch_init.c b/arch_init.c
index 23ca953..699c927 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -1094,7 +1094,7 @@ TargetInfo *qmp_query_target(Error **errp)
 {
     TargetInfo *info = g_malloc0(sizeof(*info));
 
-    info->arch = TARGET_TYPE;
+    info->arch = g_strdup(TARGET_NAME);
 
     return info;
 }
diff --git a/configure b/configure
index 46a2173..8732185 100755
--- a/configure
+++ b/configure
@@ -4246,7 +4246,6 @@ upper() {
 target_arch_name="`upper $TARGET_ARCH`"
 echo "TARGET_$target_arch_name=y" >> $config_target_mak
 echo "TARGET_NAME=$target_name" >> $config_target_mak
-echo "TARGET_TYPE=TARGET_TYPE_`upper $target_name`" >> $config_target_mak
 echo "TARGET_BASE_ARCH=$TARGET_BASE_ARCH" >> $config_target_mak
 if [ "$TARGET_ABI_DIR" = "" ]; then
   TARGET_ABI_DIR=$TARGET_ARCH
diff --git a/qapi-schema.json b/qapi-schema.json
index 5ad6894..a80ee40 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3013,22 +3013,6 @@
 { 'command': 'query-fdsets', 'returns': ['FdsetInfo'] }
 
 ##
-# @TargetType
-#
-# Target CPU emulation type
-#
-# These parameters correspond to the softmmu binary CPU name that is currently
-# running.
-#
-# Since: 1.2.0
-##
-{ 'enum': 'TargetType',
-  'data': [ 'alpha', 'arm', 'cris', 'i386', 'lm32', 'm68k', 'microblazeel',
-            'microblaze', 'mips64el', 'mips64', 'mipsel', 'mips', 'moxie',
-            'or32', 'ppc64', 'ppcemb', 'ppc', 's390x', 'sh4eb', 'sh4',
-            'sparc64', 'sparc', 'unicore32', 'x86_64', 'xtensaeb', 'xtensa' ] }
-
-##
 # @TargetInfo:
 #
 # Information describing the QEMU target.
@@ -3038,7 +3022,7 @@
 # Since: 1.2.0
 ##
 { 'type': 'TargetInfo',
-  'data': { 'arch': 'TargetType' } }
+  'data': { 'arch': 'str' } }
 
 ##
 # @query-target:
commit 2e59915d4375b632964c0594799fd5876958eda6
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Jun 4 14:45:27 2013 +0200

    main: use TARGET_ARCH only for the target-specific #define
    
    Everything else needs to match the executable name, which is
    TARGET_NAME.
    
    Before:
        $ sh4eb-linux-user/qemu-sh4eb --help
        usage: qemu-sh4 [options] program [arguments...]
        Linux CPU emulator (compiled for sh4 emulation)
    
    After:
        $ sh4eb-linux-user/qemu-sh4eb --help
        usage: qemu-sh4eb [options] program [arguments...]
        Linux CPU emulator (compiled for sh4eb emulation)
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 1370349928-20419-5-git-send-email-pbonzini at redhat.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/arch_init.c b/arch_init.c
index 5d32ecf..23ca953 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -123,7 +123,7 @@ static struct defconfig_file {
     bool userconfig;
 } default_config_files[] = {
     { CONFIG_QEMU_CONFDIR "/qemu.conf",                   true },
-    { CONFIG_QEMU_CONFDIR "/target-" TARGET_ARCH ".conf", true },
+    { CONFIG_QEMU_CONFDIR "/target-" TARGET_NAME ".conf", true },
     { NULL }, /* end of list */
 };
 
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 0da3ab9..572f13a 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -670,8 +670,8 @@ void cpu_loop(CPUSPARCState *env)
 
 static void usage(void)
 {
-    printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
-           "usage: qemu-" TARGET_ARCH " [options] program [arguments...]\n"
+    printf("qemu-" TARGET_NAME " version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
+           "usage: qemu-" TARGET_NAME " [options] program [arguments...]\n"
            "BSD CPU emulator (compiled for %s emulation)\n"
            "\n"
            "Standard options:\n"
@@ -706,7 +706,7 @@ static void usage(void)
            "Note that if you provide several changes to single variable\n"
            "last change will stay in effect.\n"
            ,
-           TARGET_ARCH,
+           TARGET_NAME,
            interp_prefix,
            x86_stack_size);
     exit(1);
diff --git a/configure b/configure
index 1dfa712..46a2173 100755
--- a/configure
+++ b/configure
@@ -4243,7 +4243,6 @@ upper() {
     echo "$@"| LC_ALL=C tr '[a-z]' '[A-Z]'
 }
 
-echo "TARGET_ARCH=$TARGET_ARCH" >> $config_target_mak
 target_arch_name="`upper $TARGET_ARCH`"
 echo "TARGET_$target_arch_name=y" >> $config_target_mak
 echo "TARGET_NAME=$target_name" >> $config_target_mak
diff --git a/linux-user/main.c b/linux-user/main.c
index b97b8cf..21725a4 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3339,7 +3339,7 @@ static void handle_arg_strace(const char *arg)
 
 static void handle_arg_version(const char *arg)
 {
-    printf("qemu-" TARGET_ARCH " version " QEMU_VERSION QEMU_PKGVERSION
+    printf("qemu-" TARGET_NAME " version " QEMU_VERSION QEMU_PKGVERSION
            ", Copyright (c) 2003-2008 Fabrice Bellard\n");
     exit(0);
 }
@@ -3400,8 +3400,8 @@ static void usage(void)
     int maxarglen;
     int maxenvlen;
 
-    printf("usage: qemu-" TARGET_ARCH " [options] program [arguments...]\n"
-           "Linux CPU emulator (compiled for " TARGET_ARCH " emulation)\n"
+    printf("usage: qemu-" TARGET_NAME " [options] program [arguments...]\n"
+           "Linux CPU emulator (compiled for " TARGET_NAME " emulation)\n"
            "\n"
            "Options and associated environment variables:\n"
            "\n");
diff --git a/scripts/create_config b/scripts/create_config
index 6461ef6..b1adbf5 100755
--- a/scripts/create_config
+++ b/scripts/create_config
@@ -77,16 +77,10 @@ case $line in
     value=${line#*=}
     echo "#define $name $value"
     ;;
- TARGET_ARCH=*) # configuration
-    target_arch=${line#*=}
-    echo "#define TARGET_ARCH \"$target_arch\""
-    ;;
  TARGET_BASE_ARCH=*) # configuration
     target_base_arch=${line#*=}
-    if [ "$target_base_arch" != "$target_arch" ]; then
-      base_arch_name=`echo $target_base_arch | LC_ALL=C tr '[a-z]' '[A-Z]'`
-      echo "#define TARGET_$base_arch_name 1"
-    fi
+    base_arch_name=`echo $target_base_arch | LC_ALL=C tr '[a-z]' '[A-Z]'`
+    echo "#define TARGET_$base_arch_name 1"
     ;;
  TARGET_XML_FILES=*)
     # do nothing
@@ -95,7 +89,8 @@ case $line in
     # do nothing
     ;;
  TARGET_NAME=*)
-    # do nothing
+    target_name=${line#*=}
+    echo "#define TARGET_NAME \"$target_name\""
     ;;
  TARGET_DIRS=*)
     # do nothing
commit b9a7b74f77619d3e7fb3834fbdcd3bde036ac399
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Jun 4 14:45:26 2013 +0200

    build: do not use TARGET_ARCH
    
    TARGET_ARCH is generally wrong to use, there are better variables
    provided in config-target.mak.  The right one is usually TARGET_NAME
    (previously TARGET_ARCH2), but for bsd-user we can also use TARGET_ABI_DIR
    for consistency with linux-user.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 1370349928-20419-4-git-send-email-pbonzini at redhat.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/Makefile.target b/Makefile.target
index fcc880b..9a49852 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -48,7 +48,7 @@ $(QEMU_PROG).stp-installed: $(SRC_PATH)/trace-events
 		--format=stap \
 		--backend=$(TRACE_BACKEND) \
 		--binary=$(bindir)/$(QEMU_PROG) \
-		--target-arch=$(TARGET_ARCH) \
+		--target-name=$(TARGET_NAME) \
 		--target-type=$(TARGET_TYPE) \
 		< $< > $@,"  GEN   $(TARGET_DIR)$(QEMU_PROG).stp-installed")
 
@@ -57,7 +57,7 @@ $(QEMU_PROG).stp: $(SRC_PATH)/trace-events
 		--format=stap \
 		--backend=$(TRACE_BACKEND) \
 		--binary=$(realpath .)/$(QEMU_PROG) \
-		--target-arch=$(TARGET_ARCH) \
+		--target-name=$(TARGET_NAME) \
 		--target-type=$(TARGET_TYPE) \
 		< $< > $@,"  GEN   $(TARGET_DIR)$(QEMU_PROG).stp")
 
@@ -103,7 +103,7 @@ endif #CONFIG_LINUX_USER
 
 ifdef CONFIG_BSD_USER
 
-QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ARCH)
+QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ABI_DIR)
 
 obj-y += bsd-user/
 obj-y += gdbstub.o user-exec.o
@@ -128,7 +128,7 @@ obj-$(CONFIG_XEN) += xen-all.o xen-mapcache.o
 obj-$(CONFIG_NO_XEN) += xen-stub.o
 
 # Hardware support
-ifeq ($(TARGET_ARCH), sparc64)
+ifeq ($(TARGET_NAME), sparc64)
 obj-y += hw/sparc64/
 else
 obj-y += hw/$(TARGET_BASE_ARCH)/
diff --git a/docs/tracing.txt b/docs/tracing.txt
index 60ff9c5..bfc261b 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -225,7 +225,7 @@ probes:
     scripts/tracetool --dtrace --stap \
                       --binary path/to/qemu-binary \
                       --target-type system \
-                      --target-arch x86_64 \
+                      --target-name x86_64 \
                       <trace-events >qemu.stp
 
 == Trace event properties ==
diff --git a/scripts/tracetool.py b/scripts/tracetool.py
index a79ec0f..5f4890f 100755
--- a/scripts/tracetool.py
+++ b/scripts/tracetool.py
@@ -46,9 +46,9 @@ Options:
     --check-backend          Check if the given backend is valid.
     --binary <path>          Full path to QEMU binary.
     --target-type <type>     QEMU emulator target type ('system' or 'user').
-    --target-arch <arch>     QEMU emulator target arch.
+    --target-name <name>     QEMU emulator target name.
     --probe-prefix <prefix>  Prefix for dtrace probe names
-                             (default: qemu-<target-type>-<target-arch>).\
+                             (default: qemu-<target-type>-<target-name>).\
 """ % {
             "script" : _SCRIPT,
             "backends" : backend_descr,
@@ -66,7 +66,7 @@ def main(args):
     _SCRIPT = args[0]
 
     long_opts  = [ "backend=", "format=", "help", "list-backends", "check-backend" ]
-    long_opts += [ "binary=", "target-type=", "target-arch=", "probe-prefix=" ]
+    long_opts += [ "binary=", "target-type=", "target-name=", "probe-prefix=" ]
 
     try:
         opts, args = getopt.getopt(args[1:], "", long_opts)
@@ -78,7 +78,7 @@ def main(args):
     arg_format = ""
     binary = None
     target_type = None
-    target_arch = None
+    target_name = None
     probe_prefix = None
     for opt, arg in opts:
         if opt == "--help":
@@ -100,8 +100,8 @@ def main(args):
             binary = arg
         elif opt == '--target-type':
             target_type = arg
-        elif opt == '--target-arch':
-            target_arch = arg
+        elif opt == '--target-name':
+            target_name = arg
         elif opt == '--probe-prefix':
             probe_prefix = arg
 
@@ -122,11 +122,11 @@ def main(args):
             error_opt("--binary is required for SystemTAP tapset generator")
         if probe_prefix is None and target_type is None:
             error_opt("--target-type is required for SystemTAP tapset generator")
-        if probe_prefix is None and target_arch is None:
-            error_opt("--target-arch is required for SystemTAP tapset generator")
+        if probe_prefix is None and target_name is None:
+            error_opt("--target-name is required for SystemTAP tapset generator")
 
         if probe_prefix is None:
-            probe_prefix = ".".join([ "qemu", target_type, target_arch ])
+            probe_prefix = ".".join([ "qemu", target_type, target_name ])
 
     try:
         tracetool.generate(sys.stdin, arg_format, arg_backend,
commit c1799a846285764de588533e21e61167a33f5a8f
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri Jun 14 15:19:07 2013 +0100

    build: rename TARGET_ARCH2 to TARGET_NAME
    
    Do not introduce any new use yet.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 1370349928-20419-3-git-send-email-pbonzini at redhat.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/Makefile.target b/Makefile.target
index 2903897..fcc880b 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -15,14 +15,14 @@ QEMU_CFLAGS+=-I$(SRC_PATH)/include
 
 ifdef CONFIG_USER_ONLY
 # user emulator name
-QEMU_PROG=qemu-$(TARGET_ARCH2)
+QEMU_PROG=qemu-$(TARGET_NAME)
 else
 # system emulator name
 ifneq (,$(findstring -mwindows,$(libs_softmmu)))
 # Terminate program name with a 'w' because the linker builds a windows executable.
-QEMU_PROGW=qemu-system-$(TARGET_ARCH2)w$(EXESUF)
+QEMU_PROGW=qemu-system-$(TARGET_NAME)w$(EXESUF)
 endif # windows executable
-QEMU_PROG=qemu-system-$(TARGET_ARCH2)$(EXESUF)
+QEMU_PROG=qemu-system-$(TARGET_NAME)$(EXESUF)
 endif
 
 PROGS=$(QEMU_PROG)
diff --git a/configure b/configure
index 60b0811..1dfa712 100755
--- a/configure
+++ b/configure
@@ -4083,10 +4083,10 @@ fi
 for target in $target_list; do
 target_dir="$target"
 config_target_mak=$target_dir/config-target.mak
-target_arch2=`echo $target | cut -d '-' -f 1`
+target_name=`echo $target | cut -d '-' -f 1`
 target_bigendian="no"
 
-case "$target_arch2" in
+case "$target_name" in
   armeb|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or32|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
   target_bigendian=yes
   ;;
@@ -4096,17 +4096,17 @@ target_user_only="no"
 target_linux_user="no"
 target_bsd_user="no"
 case "$target" in
-  ${target_arch2}-softmmu)
+  ${target_name}-softmmu)
     target_softmmu="yes"
     ;;
-  ${target_arch2}-linux-user)
+  ${target_name}-linux-user)
     if test "$linux" != "yes" ; then
       error_exit "Target '$target' is only available on a Linux host"
     fi
     target_user_only="yes"
     target_linux_user="yes"
     ;;
-  ${target_arch2}-bsd-user)
+  ${target_name}-bsd-user)
     if test "$bsd" != "yes" ; then
       error_exit "Target '$target' is only available on a BSD host"
     fi
@@ -4124,14 +4124,14 @@ echo "# Automatically generated by configure - do not modify" > $config_target_m
 
 bflt="no"
 target_nptl="no"
-interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_arch2/g"`
+interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_name/g"`
 gdb_xml_files=""
 
-TARGET_ARCH="$target_arch2"
+TARGET_ARCH="$target_name"
 TARGET_BASE_ARCH=""
 TARGET_ABI_DIR=""
 
-case "$target_arch2" in
+case "$target_name" in
   i386)
   ;;
   x86_64)
@@ -4246,14 +4246,14 @@ upper() {
 echo "TARGET_ARCH=$TARGET_ARCH" >> $config_target_mak
 target_arch_name="`upper $TARGET_ARCH`"
 echo "TARGET_$target_arch_name=y" >> $config_target_mak
-echo "TARGET_ARCH2=$target_arch2" >> $config_target_mak
-echo "TARGET_TYPE=TARGET_TYPE_`upper $target_arch2`" >> $config_target_mak
+echo "TARGET_NAME=$target_name" >> $config_target_mak
+echo "TARGET_TYPE=TARGET_TYPE_`upper $target_name`" >> $config_target_mak
 echo "TARGET_BASE_ARCH=$TARGET_BASE_ARCH" >> $config_target_mak
 if [ "$TARGET_ABI_DIR" = "" ]; then
   TARGET_ABI_DIR=$TARGET_ARCH
 fi
 echo "TARGET_ABI_DIR=$TARGET_ABI_DIR" >> $config_target_mak
-case "$target_arch2" in
+case "$target_name" in
   i386|x86_64)
     if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then
       echo "CONFIG_XEN=y" >> $config_target_mak
@@ -4264,17 +4264,17 @@ case "$target_arch2" in
     ;;
   *)
 esac
-case "$target_arch2" in
+case "$target_name" in
   arm|i386|x86_64|ppcemb|ppc|ppc64|s390x)
     # Make sure the target and host cpus are compatible
     if test "$kvm" = "yes" -a "$target_softmmu" = "yes" -a \
-      \( "$target_arch2" = "$cpu" -o \
-      \( "$target_arch2" = "ppcemb" -a "$cpu" = "ppc" \) -o \
-      \( "$target_arch2" = "ppc64"  -a "$cpu" = "ppc" \) -o \
-      \( "$target_arch2" = "ppc"    -a "$cpu" = "ppc64" \) -o \
-      \( "$target_arch2" = "ppcemb" -a "$cpu" = "ppc64" \) -o \
-      \( "$target_arch2" = "x86_64" -a "$cpu" = "i386"   \) -o \
-      \( "$target_arch2" = "i386"   -a "$cpu" = "x86_64" \) \) ; then
+      \( "$target_name" = "$cpu" -o \
+      \( "$target_name" = "ppcemb" -a "$cpu" = "ppc" \) -o \
+      \( "$target_name" = "ppc64"  -a "$cpu" = "ppc" \) -o \
+      \( "$target_name" = "ppc"    -a "$cpu" = "ppc64" \) -o \
+      \( "$target_name" = "ppcemb" -a "$cpu" = "ppc64" \) -o \
+      \( "$target_name" = "x86_64" -a "$cpu" = "i386"   \) -o \
+      \( "$target_name" = "i386"   -a "$cpu" = "x86_64" \) \) ; then
       echo "CONFIG_KVM=y" >> $config_target_mak
       if test "$vhost_net" = "yes" ; then
         echo "CONFIG_VHOST_NET=y" >> $config_target_mak
diff --git a/scripts/create_config b/scripts/create_config
index 258513a..6461ef6 100755
--- a/scripts/create_config
+++ b/scripts/create_config
@@ -94,7 +94,7 @@ case $line in
  TARGET_ABI_DIR=*)
     # do nothing
     ;;
- TARGET_ARCH2=*)
+ TARGET_NAME=*)
     # do nothing
     ;;
  TARGET_DIRS=*)
commit c14518e94251c5c0857915a5cef102f23abf1e8b
Author: Alon Levy <alevy at redhat.com>
Date:   Fri Jun 14 15:19:07 2013 +0100

    Add a stp file for usage from build directory
    
    For systemtap the location of the process being tapped is crucial, as a
    result the existing stp file requires installation for use.
    
    There are now two files:
    $(TARGET_DIR)/$(QEMU_PROG).stp-installed: copied to $(tapdir)/$(QEMU_PROG).stp
    $(TARGET_DIR)/$(QEMU_PROG).stp: pointing to the built binary, usable
                                    without installation
    
    To use:
    stap -I $(TARGET_DIR) ...
    
    Signed-off-by: Alon Levy <alevy at redhat.com>
    Acked-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 1370349928-20419-2-git-send-email-pbonzini at redhat.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/Makefile.target b/Makefile.target
index b0be124..2903897 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -35,7 +35,7 @@ config-target.h: config-target.h-timestamp
 config-target.h-timestamp: config-target.mak
 
 ifdef CONFIG_TRACE_SYSTEMTAP
-stap: $(QEMU_PROG).stp
+stap: $(QEMU_PROG).stp-installed $(QEMU_PROG).stp
 
 ifdef CONFIG_USER_ONLY
 TARGET_TYPE=user
@@ -43,14 +43,24 @@ else
 TARGET_TYPE=system
 endif
 
-$(QEMU_PROG).stp: $(SRC_PATH)/trace-events
+$(QEMU_PROG).stp-installed: $(SRC_PATH)/trace-events
 	$(call quiet-command,$(TRACETOOL) \
 		--format=stap \
 		--backend=$(TRACE_BACKEND) \
 		--binary=$(bindir)/$(QEMU_PROG) \
 		--target-arch=$(TARGET_ARCH) \
 		--target-type=$(TARGET_TYPE) \
+		< $< > $@,"  GEN   $(TARGET_DIR)$(QEMU_PROG).stp-installed")
+
+$(QEMU_PROG).stp: $(SRC_PATH)/trace-events
+	$(call quiet-command,$(TRACETOOL) \
+		--format=stap \
+		--backend=$(TRACE_BACKEND) \
+		--binary=$(realpath .)/$(QEMU_PROG) \
+		--target-arch=$(TARGET_ARCH) \
+		--target-type=$(TARGET_TYPE) \
 		< $< > $@,"  GEN   $(TARGET_DIR)$(QEMU_PROG).stp")
+
 else
 stap:
 endif
@@ -182,7 +192,7 @@ endif
 endif
 ifdef CONFIG_TRACE_SYSTEMTAP
 	$(INSTALL_DIR) "$(DESTDIR)$(qemu_datadir)/../systemtap/tapset"
-	$(INSTALL_DATA) $(QEMU_PROG).stp "$(DESTDIR)$(qemu_datadir)/../systemtap/tapset"
+	$(INSTALL_DATA) $(QEMU_PROG).stp-installed "$(DESTDIR)$(qemu_datadir)/../systemtap/tapset/$(QEMU_PROG).stp"
 endif
 
 GENERATED_HEADERS += config-target.h
commit 52bb7c6a0663b9a0ac1727f7b55811d69aaf3789
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Thu Jun 6 15:34:52 2013 +1000

    audio/intel-hda: QOM casting sweep
    
    Define and use standard QOM cast macro. Remove usages of DO_UPCAST and
    direct -> style casting.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Gerd Hoffmann <kraxel at redhat.com>
    Message-id: 96f00396338321f5a76c9b86c629b69895e4d2d0.1370496582.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index eac0cf3..3ac90d5 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -191,6 +191,9 @@ struct IntelHDAState {
 
 #define TYPE_INTEL_HDA_GENERIC "intel-hda-generic"
 
+#define INTEL_HDA(obj) \
+    OBJECT_CHECK(IntelHDAState, (obj), TYPE_INTEL_HDA_GENERIC)
+
 struct IntelHDAReg {
     const char *name;      /* register name */
     uint32_t   size;       /* size in bytes */
@@ -500,7 +503,7 @@ static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool runn
 static void intel_hda_set_g_ctl(IntelHDAState *d, const IntelHDAReg *reg, uint32_t old)
 {
     if ((d->g_ctl & ICH6_GCTL_RESET) == 0) {
-        intel_hda_reset(&d->pci.qdev);
+        intel_hda_reset(DEVICE(d));
     }
 }
 
@@ -1104,7 +1107,7 @@ static const MemoryRegionOps intel_hda_mmio_ops = {
 static void intel_hda_reset(DeviceState *dev)
 {
     BusChild *kid;
-    IntelHDAState *d = DO_UPCAST(IntelHDAState, pci.qdev, dev);
+    IntelHDAState *d = INTEL_HDA(dev);
     HDACodecDevice *cdev;
 
     intel_hda_regs_reset(d);
@@ -1122,7 +1125,7 @@ static void intel_hda_reset(DeviceState *dev)
 
 static int intel_hda_init(PCIDevice *pci)
 {
-    IntelHDAState *d = DO_UPCAST(IntelHDAState, pci, pci);
+    IntelHDAState *d = INTEL_HDA(pci);
     uint8_t *conf = d->pci.config;
 
     d->name = object_get_typename(OBJECT(d));
@@ -1139,7 +1142,7 @@ static int intel_hda_init(PCIDevice *pci)
         msi_init(&d->pci, 0x50, 1, true, false);
     }
 
-    hda_codec_bus_init(&d->pci.qdev, &d->codecs,
+    hda_codec_bus_init(DEVICE(pci), &d->codecs,
                        intel_hda_response, intel_hda_xfer);
 
     return 0;
@@ -1147,7 +1150,7 @@ static int intel_hda_init(PCIDevice *pci)
 
 static void intel_hda_exit(PCIDevice *pci)
 {
-    IntelHDAState *d = DO_UPCAST(IntelHDAState, pci, pci);
+    IntelHDAState *d = INTEL_HDA(pci);
 
     msi_uninit(&d->pci);
     memory_region_destroy(&d->mmio);
@@ -1312,12 +1315,12 @@ static const TypeInfo hda_codec_device_type_info = {
  */
 static int intel_hda_and_codec_init(PCIBus *bus)
 {
-    PCIDevice *controller;
+    DeviceState *controller;
     BusState *hdabus;
     DeviceState *codec;
 
-    controller = pci_create_simple(bus, -1, "intel-hda");
-    hdabus = QLIST_FIRST(&controller->qdev.child_bus);
+    controller = DEVICE(pci_create_simple(bus, -1, "intel-hda"));
+    hdabus = QLIST_FIRST(&controller->child_bus);
     codec = qdev_create(hdabus, "hda-duplex");
     qdev_init_nofail(codec);
     return 0;
commit 062db74023043c8fe50869f19c3b9c6bb3e4699c
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Thu Jun 6 15:34:08 2013 +1000

    audio/intel-hda: Fix Inheritance hierachy
    
    The ich6 and ich9 variants either need to inherit one from the other,
    or both from a common base class, otherwise its not possible to create
    a QOM cast macro for use by the shared implementation functions.
    Went for option B, with a common base class.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Gerd Hoffmann <kraxel at redhat.com>
    Message-id: 54453b6aa8afa1a76b2ec1932f1d7fd25205d0bc.1370496582.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index 1016af0..eac0cf3 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -189,6 +189,8 @@ struct IntelHDAState {
     uint32_t msi;
 };
 
+#define TYPE_INTEL_HDA_GENERIC "intel-hda-generic"
+
 struct IntelHDAReg {
     const char *name;      /* register name */
     uint32_t   size;       /* size in bytes */
@@ -1232,7 +1234,7 @@ static Property intel_hda_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static void intel_hda_class_init_common(ObjectClass *klass)
+static void intel_hda_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
@@ -1251,7 +1253,6 @@ static void intel_hda_class_init_ich6(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
-    intel_hda_class_init_common(klass);
     k->device_id = 0x2668;
     k->revision = 1;
     dc->desc = "Intel HD Audio Controller (ich6)";
@@ -1262,23 +1263,28 @@ static void intel_hda_class_init_ich9(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
-    intel_hda_class_init_common(klass);
     k->device_id = 0x293e;
     k->revision = 3;
     dc->desc = "Intel HD Audio Controller (ich9)";
 }
 
-static const TypeInfo intel_hda_info_ich6 = {
-    .name          = "intel-hda",
+static const TypeInfo intel_hda_info = {
+    .name          = TYPE_INTEL_HDA_GENERIC,
     .parent        = TYPE_PCI_DEVICE,
     .instance_size = sizeof(IntelHDAState),
+    .class_init    = intel_hda_class_init,
+    .abstract      = true,
+};
+
+static const TypeInfo intel_hda_info_ich6 = {
+    .name          = "intel-hda",
+    .parent        = TYPE_INTEL_HDA_GENERIC,
     .class_init    = intel_hda_class_init_ich6,
 };
 
 static const TypeInfo intel_hda_info_ich9 = {
     .name          = "ich9-intel-hda",
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(IntelHDAState),
+    .parent        = TYPE_INTEL_HDA_GENERIC,
     .class_init    = intel_hda_class_init_ich9,
 };
 
@@ -1320,6 +1326,7 @@ static int intel_hda_and_codec_init(PCIBus *bus)
 static void intel_hda_register_types(void)
 {
     type_register_static(&hda_codec_bus_info);
+    type_register_static(&intel_hda_info);
     type_register_static(&intel_hda_info_ich6);
     type_register_static(&intel_hda_info_ich9);
     type_register_static(&hda_codec_device_type_info);
commit 6e5c4540d18d1e9a5253104df161a7e0d408ca95
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Jun 7 15:00:36 2013 +0200

    smbios: Check R in -smbios type=0, release=R parses okay
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Laszlo "ever the optimist" Ersek <lersek at redhat.com>
    Message-id: 1370610036-10577-7-git-send-email-armbru at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/i386/smbios.c b/hw/i386/smbios.c
index 6431dd4..e708cb8 100644
--- a/hw/i386/smbios.c
+++ b/hw/i386/smbios.c
@@ -140,7 +140,10 @@ static void smbios_build_type_0_fields(const char *t)
                                      bios_release_date_str),
                          buf, strlen(buf) + 1);
     if (get_param_value(buf, sizeof(buf), "release", t)) {
-        sscanf(buf, "%hhu.%hhu", &major, &minor);
+        if (sscanf(buf, "%hhu.%hhu", &major, &minor) != 2) {
+            error_report("Invalid release");
+            exit(1);
+        }
         smbios_add_field(0, offsetof(struct smbios_type_0,
                                      system_bios_major_release),
                          &major, 1);
commit 527cd96f15348f4454d5bb71f69aaeb95461c90e
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Jun 7 15:00:35 2013 +0200

    smbios: Fix -smbios type=0, release=... for big endian hosts
    
    Classic endianness bug due to careless dirty coding: assuming reading
    a byte from an int variable gets the least significant byte.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Laszlo "ever the optimist" Ersek <lersek at redhat.com>
    Message-id: 1370610036-10577-6-git-send-email-armbru at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/i386/smbios.c b/hw/i386/smbios.c
index 322f0a0..6431dd4 100644
--- a/hw/i386/smbios.c
+++ b/hw/i386/smbios.c
@@ -127,6 +127,7 @@ void smbios_add_field(int type, int offset, const void *data, size_t len)
 static void smbios_build_type_0_fields(const char *t)
 {
     char buf[1024];
+    unsigned char major, minor;
 
     if (get_param_value(buf, sizeof(buf), "vendor", t))
         smbios_add_field(0, offsetof(struct smbios_type_0, vendor_str),
@@ -139,8 +140,7 @@ static void smbios_build_type_0_fields(const char *t)
                                      bios_release_date_str),
                          buf, strlen(buf) + 1);
     if (get_param_value(buf, sizeof(buf), "release", t)) {
-        int major, minor;
-        sscanf(buf, "%d.%d", &major, &minor);
+        sscanf(buf, "%hhu.%hhu", &major, &minor);
         smbios_add_field(0, offsetof(struct smbios_type_0,
                                      system_bios_major_release),
                          &major, 1);
commit ebc85e3f724d17530e74df665d1a30fb9b0041b5
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Jun 7 15:00:34 2013 +0200

    smbios: Clean up smbios_add_field() parameters
    
    Having size precede the associated pointer is odd.  Swap them, and fix
    up the types.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Laszlo "ever the optimist" Ersek <lersek at redhat.com>
    Message-id: 1370610036-10577-5-git-send-email-armbru at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/arch_init.c b/arch_init.c
index 5d71870..872020e 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -1029,7 +1029,7 @@ int qemu_uuid_parse(const char *str, uint8_t *uuid)
         return -1;
     }
 #ifdef TARGET_I386
-    smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
+    smbios_add_field(1, offsetof(struct smbios_type_1, uuid), uuid, 16);
 #endif
     return 0;
 }
diff --git a/hw/i386/smbios.c b/hw/i386/smbios.c
index a67a328..322f0a0 100644
--- a/hw/i386/smbios.c
+++ b/hw/i386/smbios.c
@@ -99,7 +99,7 @@ static void smbios_check_collision(int type, int entry)
     }
 }
 
-void smbios_add_field(int type, int offset, int len, void *data)
+void smbios_add_field(int type, int offset, const void *data, size_t len)
 {
     struct smbios_field *field;
 
@@ -130,21 +130,23 @@ static void smbios_build_type_0_fields(const char *t)
 
     if (get_param_value(buf, sizeof(buf), "vendor", t))
         smbios_add_field(0, offsetof(struct smbios_type_0, vendor_str),
-                         strlen(buf) + 1, buf);
+                         buf, strlen(buf) + 1);
     if (get_param_value(buf, sizeof(buf), "version", t))
         smbios_add_field(0, offsetof(struct smbios_type_0, bios_version_str),
-                         strlen(buf) + 1, buf);
+                         buf, strlen(buf) + 1);
     if (get_param_value(buf, sizeof(buf), "date", t))
         smbios_add_field(0, offsetof(struct smbios_type_0,
                                      bios_release_date_str),
-                                     strlen(buf) + 1, buf);
+                         buf, strlen(buf) + 1);
     if (get_param_value(buf, sizeof(buf), "release", t)) {
         int major, minor;
         sscanf(buf, "%d.%d", &major, &minor);
         smbios_add_field(0, offsetof(struct smbios_type_0,
-                                     system_bios_major_release), 1, &major);
+                                     system_bios_major_release),
+                         &major, 1);
         smbios_add_field(0, offsetof(struct smbios_type_0,
-                                     system_bios_minor_release), 1, &minor);
+                                     system_bios_minor_release),
+                         &minor, 1);
     }
 }
 
@@ -154,16 +156,16 @@ static void smbios_build_type_1_fields(const char *t)
 
     if (get_param_value(buf, sizeof(buf), "manufacturer", t))
         smbios_add_field(1, offsetof(struct smbios_type_1, manufacturer_str),
-                         strlen(buf) + 1, buf);
+                         buf, strlen(buf) + 1);
     if (get_param_value(buf, sizeof(buf), "product", t))
         smbios_add_field(1, offsetof(struct smbios_type_1, product_name_str),
-                         strlen(buf) + 1, buf);
+                         buf, strlen(buf) + 1);
     if (get_param_value(buf, sizeof(buf), "version", t))
         smbios_add_field(1, offsetof(struct smbios_type_1, version_str),
-                         strlen(buf) + 1, buf);
+                         buf, strlen(buf) + 1);
     if (get_param_value(buf, sizeof(buf), "serial", t))
         smbios_add_field(1, offsetof(struct smbios_type_1, serial_number_str),
-                         strlen(buf) + 1, buf);
+                         buf, strlen(buf) + 1);
     if (get_param_value(buf, sizeof(buf), "uuid", t)) {
         if (qemu_uuid_parse(buf, qemu_uuid) != 0) {
             error_report("Invalid UUID");
@@ -172,10 +174,10 @@ static void smbios_build_type_1_fields(const char *t)
     }
     if (get_param_value(buf, sizeof(buf), "sku", t))
         smbios_add_field(1, offsetof(struct smbios_type_1, sku_number_str),
-                         strlen(buf) + 1, buf);
+                         buf, strlen(buf) + 1);
     if (get_param_value(buf, sizeof(buf), "family", t))
         smbios_add_field(1, offsetof(struct smbios_type_1, family_str),
-                         strlen(buf) + 1, buf);
+                         buf, strlen(buf) + 1);
 }
 
 int smbios_entry_add(const char *t)
diff --git a/include/hw/i386/smbios.h b/include/hw/i386/smbios.h
index 94e3641..9babeaf 100644
--- a/include/hw/i386/smbios.h
+++ b/include/hw/i386/smbios.h
@@ -14,7 +14,7 @@
  */
 
 int smbios_entry_add(const char *t);
-void smbios_add_field(int type, int offset, int len, void *data);
+void smbios_add_field(int type, int offset, const void *data, size_t len);
 uint8_t *smbios_get_table(size_t *length);
 
 /*
commit 5bb95e41868b461f37159efb48908828ebd7ab36
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Jun 7 15:00:33 2013 +0200

    smbios: Convert to error_report()
    
    Improves diagnistics from ad hoc messages like
    
        Invalid SMBIOS UUID string
    
    to
    
        qemu-system-x86_64: -smbios type=1,uuid=gaga: Invalid UUID
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Laszlo "ever the optimist" Ersek <lersek at redhat.com>
    Message-id: 1370610036-10577-4-git-send-email-armbru at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/arch_init.c b/arch_init.c
index 5d32ecf..5d71870 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -1053,7 +1053,6 @@ void do_smbios_option(const char *optarg)
 {
 #ifdef TARGET_I386
     if (smbios_entry_add(optarg) < 0) {
-        fprintf(stderr, "Wrong smbios provided\n");
         exit(1);
     }
 #endif
diff --git a/hw/i386/smbios.c b/hw/i386/smbios.c
index c00bb2f..a67a328 100644
--- a/hw/i386/smbios.c
+++ b/hw/i386/smbios.c
@@ -13,6 +13,7 @@
  * GNU GPL, version 2 or (at your option) any later version.
  */
 
+#include "qemu/error-report.h"
 #include "sysemu/sysemu.h"
 #include "hw/i386/smbios.h"
 #include "hw/loader.h"
@@ -48,8 +49,7 @@ static int smbios_type4_count = 0;
 static void smbios_validate_table(void)
 {
     if (smbios_type4_count && smbios_type4_count != smp_cpus) {
-         fprintf(stderr,
-                 "Number of SMBIOS Type 4 tables must match cpu count.\n");
+        error_report("Number of SMBIOS Type 4 tables must match cpu count");
         exit(1);
     }
 }
@@ -82,16 +82,16 @@ static void smbios_check_collision(int type, int entry)
         if (entry == SMBIOS_TABLE_ENTRY && header->type == SMBIOS_FIELD_ENTRY) {
             struct smbios_field *field = (void *)header;
             if (type == field->type) {
-                fprintf(stderr, "SMBIOS type %d field already defined, "
-                                "cannot add table\n", type);
+                error_report("SMBIOS type %d field already defined, "
+                             "cannot add table", type);
                 exit(1);
             }
         } else if (entry == SMBIOS_FIELD_ENTRY &&
                    header->type == SMBIOS_TABLE_ENTRY) {
             struct smbios_structure_header *table = (void *)(header + 1);
             if (type == table->type) {
-                fprintf(stderr, "SMBIOS type %d table already defined, "
-                                "cannot add field\n", type);
+                error_report("SMBIOS type %d table already defined, "
+                             "cannot add field", type);
                 exit(1);
             }
         }
@@ -166,7 +166,7 @@ static void smbios_build_type_1_fields(const char *t)
                          strlen(buf) + 1, buf);
     if (get_param_value(buf, sizeof(buf), "uuid", t)) {
         if (qemu_uuid_parse(buf, qemu_uuid) != 0) {
-            fprintf(stderr, "Invalid SMBIOS UUID string\n");
+            error_report("Invalid UUID");
             exit(1);
         }
     }
@@ -188,7 +188,7 @@ int smbios_entry_add(const char *t)
         int size = get_image_size(buf);
 
         if (size == -1 || size < sizeof(struct smbios_structure_header)) {
-            fprintf(stderr, "Cannot read smbios file %s\n", buf);
+            error_report("Cannot read SMBIOS file %s", buf);
             exit(1);
         }
 
@@ -204,7 +204,7 @@ int smbios_entry_add(const char *t)
         table->header.length = cpu_to_le16(sizeof(*table) + size);
 
         if (load_image(buf, table->data) != size) {
-            fprintf(stderr, "Failed to load smbios file %s", buf);
+            error_report("Failed to load SMBIOS file %s", buf);
             exit(1);
         }
 
@@ -230,12 +230,12 @@ int smbios_entry_add(const char *t)
             smbios_build_type_1_fields(t);
             return 0;
         default:
-            fprintf(stderr, "Don't know how to build fields for SMBIOS type "
-                    "%ld\n", type);
+            error_report("Don't know how to build fields for SMBIOS type %ld",
+                         type);
             exit(1);
         }
     }
 
-    fprintf(stderr, "smbios: must specify type= or file=\n");
+    error_report("Must specify type= or file=");
     return -1;
 }
commit f3eededb2fbc73c73daf08f791f0407b8541f4f4
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Jun 7 15:00:32 2013 +0200

    log.h: Supply missing includes
    
    <stdio.h> has always been missing.  Rest missed in commit eeacee4.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Laszlo "ever the optimist" Ersek <lersek at redhat.com>
    Message-id: 1370610036-10577-3-git-send-email-armbru at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/include/qemu/log.h b/include/qemu/log.h
index 6b0db02..fd76f91 100644
--- a/include/qemu/log.h
+++ b/include/qemu/log.h
@@ -2,6 +2,9 @@
 #define QEMU_LOG_H
 
 #include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include "qemu/compiler.h"
 #ifdef NEED_CPU_H
 #include "disas/disas.h"
 #endif
commit b293796fd71009ecffe4343713a4e4e568c33fb0
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Jun 7 15:00:31 2013 +0200

    error-report.h: Supply missing include
    
    Missed in commit e5924d8.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Laszlo "ever the optimist" Ersek <lersek at redhat.com>
    Message-id: 1370610036-10577-2-git-send-email-armbru at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/include/qemu/error-report.h b/include/qemu/error-report.h
index c902cc1..14c1719 100644
--- a/include/qemu/error-report.h
+++ b/include/qemu/error-report.h
@@ -14,6 +14,7 @@
 #define QEMU_ERROR_H
 
 #include <stdarg.h>
+#include "qemu/compiler.h"
 
 typedef struct Location {
     /* all members are private to qemu-error.c */
commit 301255e6303457e10b9a42dc208f80c058004c1c
Merge: 5f13731 ba275ad
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Jun 14 07:51:45 2013 -0500

    Merge remote-tracking branch 'mjt/trivial-patches-next' into staging
    
    # By Michael Tokarev (4) and others
    # Via Michael Tokarev
    * mjt/trivial-patches-next: (26 commits)
      piix: fix some printf errors when debug is enabled
      cputlb: fix debug logs
      create qemu_openpty_raw() helper function and move it to a separate file
      main-loop: do not include slirp/slirp.h, use libslirp.h instead
      libcacard/vscclient: fix leakage of socket on error paths
      linux-headers: Update to v3.10-rc5
      KVM: PPC: Add dummy kvm_arch_init_irq_routing()
      KVM: S390: Add dummy kvm_arch_init_irq_routing()
      KVM: ARM: Add dummy kvm_arch_init_irq_routing()
      ivshmem: add missing error exit(2)
      hw/xen: Use g_free instead of free and fix potential memory leaks
      target-sparc: Replace free by g_free
      hw/scsi: Don't increment a boolean value
      device tree: Fix cppcheck warning
      Makefile: Install qemu-img and qemu-nbd man pages only if built
      Unbreak -no-quit for GTK, validate SDL options
      gtk: implement -full-screen
      char/serial: serial_ioport_write: Factor out common code
      char/serial: Use generic Fifo8
      char/serial: cosmetic fixes.
      ...
    
    Message-id: 1371207042-17980-1-git-send-email-mjt at msgid.tls.msk.ru
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 5f13731f8cb6aadecf214513ec810d61dc1f71dc
Merge: 86a6a07 c67e216
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Jun 14 07:51:30 2013 -0500

    Merge remote-tracking branch 'afaerber/qom-cpu' into staging
    
    # By Andreas Färber (12) and others
    # Via Andreas Färber
    * afaerber/qom-cpu:
      spapr_rtas: Abstract rtas_start_cpu() with qemu_get_cpu()
      spapr_rtas: Abstract rtas_query_cpu_stopped_state() with qemu_get_cpu()
      memory_mapping: Improve qemu_get_guest_memory_mapping() error reporting
      dump: Abstract dump_init() with cpu_synchronize_all_states()
      cpu: Change default for CPUClass::get_paging_enabled()
      dump: Drop qmp_dump_guest_memory() stub and build for all targets
      memory_mapping: Drop qemu_get_memory_mapping() stub
      cpu: Turn cpu_get_memory_mapping() into a CPUState hook
      memory_mapping: Move MemoryMappingList typedef to qemu/typedefs.h
      cpu: Turn cpu_paging_enabled() into a CPUState hook
      monitor: Simplify do_inject_mce() with qemu_get_cpu()
      target-i386: cpu: Fix potential buffer overrun in get_register_name_32()
      target-i386: Set level=4 on Conroe/Penryn/Nehalem
      target-i386: Update model values on Conroe/Penryn/Nehalem CPU models
      pc: Create pc-*-1.6 machine-types
      pc: Fix crash when attempting to hotplug CPU with negative ID
      dump: Move stubs into libqemustub.a

commit 86a6a0774509c59f1570f763a0fad57e26762d9c
Merge: db9707f b25a464
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Jun 14 07:51:05 2013 -0500

    Merge remote-tracking branch 'pmaydell/tcg-aarch64.next' into staging
    
    # By Claudio Fontana (9) and others
    # Via Peter Maydell
    * pmaydell/tcg-aarch64.next:
      MAINTAINERS: add tcg/aarch64 maintainer
      configure: permit compilation on arm aarch64
      tcg/aarch64: implement user mode qemu ld/st
      user-exec.c: aarch64 initial implementation of cpu_signal_handler
      tcg/aarch64: implement sign/zero extend operations
      tcg/aarch64: implement byte swap operations
      tcg/aarch64: implement AND/TEST immediate pattern
      tcg/aarch64: improve arith shifted regs operations
      tcg/aarch64: implement new TCG target for aarch64
      include/elf.h: add aarch64 ELF machine and relocs
      configure: Drop CONFIG_ATFILE test
      linux-user: Drop direct use of openat etc syscalls
      linux-user: Allow getdents to be provided by getdents64
    
    Message-id: 1371052645-9006-1-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit db9707f7a17d00781a8fb13354a359bd05a46646
Merge: 6e8d2b6 5866e07
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Jun 14 07:50:58 2013 -0500

    Merge remote-tracking branch 'pmaydell/target-arm.next' into staging
    
    # By Peter Chubb
    # Via Peter Maydell
    * pmaydell/target-arm.next:
      Fix rfe instruction
    
    Message-id: 1370268884-25945-1-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 6e8d2b654656830877937ba02bb8ea1c4945a1fc
Merge: bd5c51e 56bbc2f
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Jun 14 07:50:36 2013 -0500

    Merge remote-tracking branch 'rth/tcg-for-anthony' into staging
    
    # By Richard Henderson
    # Via Richard Henderson
    * rth/tcg-for-anthony:
      tcg: Remove redundant tcg_target_init checks
      tcg: Use QEMU_BUILD_BUG_ON for CPU_TLB_ENTRY_BITS
    
    Message-id: 1370437167-11278-1-git-send-email-rth at twiddle.net
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit ba275adba09adfc0f7ec533f1fddba678d9ba826
Author: Hu Tao <hutao at cn.fujitsu.com>
Date:   Fri Jun 14 15:11:30 2013 +0800

    piix: fix some printf errors when debug is enabled
    
    And use PRIxxx macros if possible.
    
    Signed-off-by: Hu Tao <hutao at cn.fujitsu.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index e6525ac..756df3b 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -518,7 +518,7 @@ static uint64_t gpe_readb(void *opaque, hwaddr addr, unsigned width)
     PIIX4PMState *s = opaque;
     uint32_t val = acpi_gpe_ioport_readb(&s->ar, addr);
 
-    PIIX4_DPRINTF("gpe read %x == %x\n", addr, val);
+    PIIX4_DPRINTF("gpe read %" HWADDR_PRIx " == %" PRIu32 "\n", addr, val);
     return val;
 }
 
@@ -530,7 +530,7 @@ static void gpe_writeb(void *opaque, hwaddr addr, uint64_t val,
     acpi_gpe_ioport_writeb(&s->ar, addr, val);
     pm_update_sci(s);
 
-    PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val);
+    PIIX4_DPRINTF("gpe write %" HWADDR_PRIx " <== %" PRIu64 "\n", addr, val);
 }
 
 static const MemoryRegionOps piix4_gpe_ops = {
@@ -553,15 +553,15 @@ static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
         /* Manufacture an "up" value to cause a device check on any hotplug
          * slot with a device.  Extra device checks are harmless. */
         val = s->pci0_slot_device_present & s->pci0_hotplug_enable;
-        PIIX4_DPRINTF("pci_up_read %x\n", val);
+        PIIX4_DPRINTF("pci_up_read %" PRIu32 "\n", val);
         break;
     case PCI_DOWN_BASE - PCI_HOTPLUG_ADDR:
         val = s->pci0_status.down;
-        PIIX4_DPRINTF("pci_down_read %x\n", val);
+        PIIX4_DPRINTF("pci_down_read %" PRIu32 "\n", val);
         break;
     case PCI_EJ_BASE - PCI_HOTPLUG_ADDR:
         /* No feature defined yet */
-        PIIX4_DPRINTF("pci_features_read %x\n", val);
+        PIIX4_DPRINTF("pci_features_read %" PRIu32 "\n", val);
         break;
     case PCI_RMV_BASE - PCI_HOTPLUG_ADDR:
         val = s->pci0_hotplug_enable;
@@ -579,7 +579,7 @@ static void pci_write(void *opaque, hwaddr addr, uint64_t data,
     switch (addr) {
     case PCI_EJ_BASE - PCI_HOTPLUG_ADDR:
         acpi_piix_eject_slot(opaque, (uint32_t)data);
-        PIIX4_DPRINTF("pciej write %" HWADDR_PRIx " <== % " PRIu64 "\n",
+        PIIX4_DPRINTF("pciej write %" HWADDR_PRIx " <== %" PRIu64 "\n",
                       addr, data);
         break;
     default:
commit 54b949d27064a294304775e427f49d3706ed4a95
Author: Hervé Poussineau <hpoussin at reactos.org>
Date:   Wed Jun 5 20:16:42 2013 +0800

    cputlb: fix debug logs
    
    'pd' variable has been removed in 06ef3525e1f271b6a842781a05eace5cf63b95c2.
    
    Signed-off-by: Hervé Poussineau <hpoussin at reactos.org>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/cputlb.c b/cputlb.c
index 86666c8..1230e9e 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -262,8 +262,8 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
 
 #if defined(DEBUG_TLB)
     printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx
-           " prot=%x idx=%d pd=0x%08lx\n",
-           vaddr, paddr, prot, mmu_idx, pd);
+           " prot=%x idx=%d\n",
+           vaddr, paddr, prot, mmu_idx);
 #endif
 
     address = vaddr;
commit 4efeabbbe8441cc327052304976c7b9b86309d72
Author: Michael Tokarev <mjt at tls.msk.ru>
Date:   Wed Jun 5 18:44:54 2013 +0400

    create qemu_openpty_raw() helper function and move it to a separate file
    
    In two places qemu uses openpty() which is very system-dependent,
    and in both places the pty is switched to raw mode as well.
    Make a wrapper function which does both steps, and move all the
    system-dependent complexity into a separate file, together
    with static/local implementations of openpty() and cfmakeraw()
    from qemu-char.c.
    
    It is in a separate file, not part of oslib-posix.c, because
    openpty() often resides in -lutil which is not linked to
    every program qemu builds.
    
    This change removes #including of <pty.h>, <termios.h>
    and other rather specific system headers out of qemu-common.h,
    which isn't a place for such specific headers really.
    
    This version has been verified to build correctly on Linux,
    OpenBSD, FreeBSD and OpenIndiana.  On the latter it lets qemu
    to be built with gtk gui which were not possible there due to
    missing openpty() and cfmakeraw().
    
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>
    Tested-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/include/qemu-common.h b/include/qemu-common.h
index ed8b6e2..3c91375 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -42,19 +42,6 @@
 #include <signal.h>
 #include "glib-compat.h"
 
-#if defined(__GLIBC__)
-# include <pty.h>
-#elif defined CONFIG_BSD
-# include <termios.h>
-# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
-#  include <libutil.h>
-# else
-#  include <util.h>
-# endif
-#elif defined CONFIG_SOLARIS
-# include <stropts.h>
-#endif
-
 #ifdef _WIN32
 #include "sysemu/os-win32.h"
 #endif
@@ -235,6 +222,8 @@ ssize_t qemu_recv_full(int fd, void *buf, size_t count, int flags)
 
 #ifndef _WIN32
 int qemu_pipe(int pipefd[2]);
+/* like openpty() but also makes it raw; return master fd */
+int qemu_openpty_raw(int *aslave, char *pty_name);
 #endif
 
 #ifdef _WIN32
diff --git a/qemu-char.c b/qemu-char.c
index 596bf9e..2c3cfe6 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -964,63 +964,6 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts)
     return chr;
 }
 
-#ifdef __sun__
-/* Once Solaris has openpty(), this is going to be removed. */
-static int openpty(int *amaster, int *aslave, char *name,
-                   struct termios *termp, struct winsize *winp)
-{
-        const char *slave;
-        int mfd = -1, sfd = -1;
-
-        *amaster = *aslave = -1;
-
-        mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
-        if (mfd < 0)
-                goto err;
-
-        if (grantpt(mfd) == -1 || unlockpt(mfd) == -1)
-                goto err;
-
-        if ((slave = ptsname(mfd)) == NULL)
-                goto err;
-
-        if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1)
-                goto err;
-
-        if (ioctl(sfd, I_PUSH, "ptem") == -1 ||
-            (termp != NULL && tcgetattr(sfd, termp) < 0))
-                goto err;
-
-        if (amaster)
-                *amaster = mfd;
-        if (aslave)
-                *aslave = sfd;
-        if (winp)
-                ioctl(sfd, TIOCSWINSZ, winp);
-
-        return 0;
-
-err:
-        if (sfd != -1)
-                close(sfd);
-        close(mfd);
-        return -1;
-}
-
-static void cfmakeraw (struct termios *termios_p)
-{
-        termios_p->c_iflag &=
-                ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
-        termios_p->c_oflag &= ~OPOST;
-        termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
-        termios_p->c_cflag &= ~(CSIZE|PARENB);
-        termios_p->c_cflag |= CS8;
-
-        termios_p->c_cc[VMIN] = 0;
-        termios_p->c_cc[VTIME] = 0;
-}
-#endif
-
 #if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
     || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \
     || defined(__GLIBC__)
@@ -1192,34 +1135,24 @@ static CharDriverState *qemu_chr_open_pty(const char *id,
 {
     CharDriverState *chr;
     PtyCharDriver *s;
-    struct termios tty;
     int master_fd, slave_fd;
-#if defined(__OpenBSD__) || defined(__DragonFly__)
     char pty_name[PATH_MAX];
-#define q_ptsname(x) pty_name
-#else
-    char *pty_name = NULL;
-#define q_ptsname(x) ptsname(x)
-#endif
 
-    if (openpty(&master_fd, &slave_fd, pty_name, NULL, NULL) < 0) {
+    master_fd = qemu_openpty_raw(&slave_fd, pty_name);
+    if (master_fd < 0) {
         return NULL;
     }
 
-    /* Set raw attributes on the pty. */
-    tcgetattr(slave_fd, &tty);
-    cfmakeraw(&tty);
-    tcsetattr(slave_fd, TCSAFLUSH, &tty);
     close(slave_fd);
 
     chr = g_malloc0(sizeof(CharDriverState));
 
-    chr->filename = g_strdup_printf("pty:%s", q_ptsname(master_fd));
-    ret->pty = g_strdup(q_ptsname(master_fd));
+    chr->filename = g_strdup_printf("pty:%s", pty_name);
+    ret->pty = g_strdup(pty_name);
     ret->has_pty = true;
 
     fprintf(stderr, "char device redirected to %s (label %s)\n",
-            q_ptsname(master_fd), id);
+            pty_name, id);
 
     s = g_malloc0(sizeof(PtyCharDriver));
     chr->opaque = s;
diff --git a/ui/gtk.c b/ui/gtk.c
index e314dba..50a6993 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1160,8 +1160,7 @@ static GSList *gd_vc_init(GtkDisplayState *s, VirtualConsole *vc, int index, GSL
     GIOChannel *chan;
     GtkWidget *scrolled_window;
     GtkAdjustment *vadjustment;
-    int master_fd, slave_fd, ret;
-    struct termios tty;
+    int master_fd, slave_fd;
 
     snprintf(buffer, sizeof(buffer), "vc%d", index);
     snprintf(path, sizeof(path), "<QEMU>/View/VC%d", index);
@@ -1181,13 +1180,8 @@ static GSList *gd_vc_init(GtkDisplayState *s, VirtualConsole *vc, int index, GSL
 
     vc->terminal = vte_terminal_new();
 
-    ret = openpty(&master_fd, &slave_fd, NULL, NULL, NULL);
-    g_assert(ret != -1);
-
-    /* Set raw attributes on the pty. */
-    tcgetattr(slave_fd, &tty);
-    cfmakeraw(&tty);
-    tcsetattr(slave_fd, TCSAFLUSH, &tty);
+    master_fd = qemu_openpty_raw(&slave_fd, NULL);
+    g_assert(master_fd != -1);
 
 #if VTE_CHECK_VERSION(0, 26, 0)
     pty = vte_pty_new_foreign(master_fd, NULL);
diff --git a/util/Makefile.objs b/util/Makefile.objs
index 4a1bd4e..dc72ab0 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -1,6 +1,6 @@
 util-obj-y = osdep.o cutils.o unicode.o qemu-timer-common.o
 util-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o event_notifier-win32.o
-util-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o event_notifier-posix.o
+util-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o event_notifier-posix.o qemu-openpty.o
 util-obj-y += envlist.o path.o host-utils.o cache-utils.o module.o
 util-obj-y += bitmap.o bitops.o hbitmap.o
 util-obj-y += fifo8.o
diff --git a/util/qemu-openpty.c b/util/qemu-openpty.c
new file mode 100644
index 0000000..4febfe9
--- /dev/null
+++ b/util/qemu-openpty.c
@@ -0,0 +1,135 @@
+/*
+ * qemu-openpty.c
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2010 Red Hat, Inc.
+ *
+ * Wrapper function qemu_openpty() implementation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/*
+ * This is not part of oslib-posix.c because this function
+ * uses openpty() which often in -lutil, and if we add this
+ * dependency to oslib-posix.o, every app will have to be
+ * linked with -lutil.
+ */
+
+#include "config-host.h"
+#include "qemu-common.h"
+
+#if defined(__GLIBC__)
+# include <pty.h>
+#elif defined CONFIG_BSD
+# include <termios.h>
+# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+#  include <libutil.h>
+# else
+#  include <util.h>
+# endif
+#elif defined CONFIG_SOLARIS
+# include <termios.h>
+# include <stropts.h>
+#endif
+
+#ifdef __sun__
+/* Once Solaris has openpty(), this is going to be removed. */
+static int openpty(int *amaster, int *aslave, char *name,
+                   struct termios *termp, struct winsize *winp)
+{
+        const char *slave;
+        int mfd = -1, sfd = -1;
+
+        *amaster = *aslave = -1;
+
+        mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
+        if (mfd < 0)
+                goto err;
+
+        if (grantpt(mfd) == -1 || unlockpt(mfd) == -1)
+                goto err;
+
+        if ((slave = ptsname(mfd)) == NULL)
+                goto err;
+
+        if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1)
+                goto err;
+
+        if (ioctl(sfd, I_PUSH, "ptem") == -1 ||
+            (termp != NULL && tcgetattr(sfd, termp) < 0))
+                goto err;
+
+        if (amaster)
+                *amaster = mfd;
+        if (aslave)
+                *aslave = sfd;
+        if (winp)
+                ioctl(sfd, TIOCSWINSZ, winp);
+
+        return 0;
+
+err:
+        if (sfd != -1)
+                close(sfd);
+        close(mfd);
+        return -1;
+}
+
+static void cfmakeraw (struct termios *termios_p)
+{
+        termios_p->c_iflag &=
+                ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
+        termios_p->c_oflag &= ~OPOST;
+        termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+        termios_p->c_cflag &= ~(CSIZE|PARENB);
+        termios_p->c_cflag |= CS8;
+
+        termios_p->c_cc[VMIN] = 0;
+        termios_p->c_cc[VTIME] = 0;
+}
+#endif
+
+int qemu_openpty_raw(int *aslave, char *pty_name)
+{
+    int amaster;
+    struct termios tty;
+#if defined(__OpenBSD__) || defined(__DragonFly__)
+    char pty_buf[PATH_MAX];
+#define q_ptsname(x) pty_buf
+#else
+    char *pty_buf = NULL;
+#define q_ptsname(x) ptsname(x)
+#endif
+
+    if (openpty(&amaster, aslave, pty_buf, NULL, NULL) < 0) {
+        return -1;
+    }
+
+    /* Set raw attributes on the pty. */
+    tcgetattr(*aslave, &tty);
+    cfmakeraw(&tty);
+    tcsetattr(*aslave, TCSAFLUSH, &tty);
+
+    if (pty_name) {
+        strcpy(pty_name, q_ptsname(amaster));
+    }
+
+    return amaster;
+}
commit c67e216bdf42abfb8505790b2da9562356103976
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed May 29 21:06:39 2013 +0200

    spapr_rtas: Abstract rtas_start_cpu() with qemu_get_cpu()
    
    Instead of looping over all CPUArchState, use a helper to obtain the
    desired CPUState.
    Free the "cpu" variable for PowerPCCPU, to access its CPUPPCState.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index a1c3d20..f4bd3c9 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -160,8 +160,7 @@ static void rtas_start_cpu(sPAPREnvironment *spapr,
                            uint32_t nret, target_ulong rets)
 {
     target_ulong id, start, r3;
-    CPUState *cpu;
-    CPUPPCState *env;
+    CPUState *cs;
 
     if (nargs != 3 || nret != 1) {
         rtas_st(rets, 0, -3);
@@ -172,14 +171,12 @@ static void rtas_start_cpu(sPAPREnvironment *spapr,
     start = rtas_ld(args, 1);
     r3 = rtas_ld(args, 2);
 
-    for (env = first_cpu; env; env = env->next_cpu) {
-        cpu = CPU(ppc_env_get_cpu(env));
-
-        if (cpu->cpu_index != id) {
-            continue;
-        }
+    cs = qemu_get_cpu(id);
+    if (cs != NULL) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
+        CPUPPCState *env = &cpu->env;
 
-        if (!cpu->halted) {
+        if (!cs->halted) {
             rtas_st(rets, 0, -1);
             return;
         }
@@ -192,9 +189,9 @@ static void rtas_start_cpu(sPAPREnvironment *spapr,
         env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
         env->nip = start;
         env->gpr[3] = r3;
-        cpu->halted = 0;
+        cs->halted = 0;
 
-        qemu_cpu_kick(cpu);
+        qemu_cpu_kick(cs);
 
         rtas_st(rets, 0, 0);
         return;
commit 05318a858c1212d845d03f924e6ab5f22ab51ab6
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed May 29 21:03:31 2013 +0200

    spapr_rtas: Abstract rtas_query_cpu_stopped_state() with qemu_get_cpu()
    
    Instead of looping over all CPUArchState, use a helper to obtain the
    desired CPUState directly. Saves a CPUPPCState variable and QOM cast.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 8ecaa5f..a1c3d20 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -130,7 +130,6 @@ static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr,
                                          uint32_t nret, target_ulong rets)
 {
     target_ulong id;
-    CPUPPCState *env;
     CPUState *cpu;
 
     if (nargs != 1 || nret != 2) {
@@ -139,12 +138,8 @@ static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr,
     }
 
     id = rtas_ld(args, 0);
-    for (env = first_cpu; env; env = env->next_cpu) {
-        cpu = CPU(ppc_env_get_cpu(env));
-        if (cpu->cpu_index != id) {
-            continue;
-        }
-
+    cpu = qemu_get_cpu(id);
+    if (cpu != NULL) {
         if (cpu->halted) {
             rtas_st(rets, 1, 0);
         } else {
commit b25a464c6bddbe5d25b7552ba1fec1835269ac84
Author: Claudio Fontana <claudio.fontana at huawei.com>
Date:   Wed Jun 12 16:20:24 2013 +0100

    MAINTAINERS: add tcg/aarch64 maintainer
    
    Signed-off-by: Claudio Fontana <claudio.fontana at huawei.com>
    Message-id: 51ACA0B2.80800 at huawei.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/MAINTAINERS b/MAINTAINERS
index 13c0cc5..3412b07 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -767,6 +767,12 @@ M: qemu-devel at nongnu.org
 S: Maintained
 F: tcg/
 
+AArch64 target
+M: Claudio Fontana <claudio.fontana at huawei.com>
+M: Claudio Fontana <claudio.fontana at gmail.com>
+S: Maintained
+F: tcg/aarch64/
+
 ARM target
 M: Andrzej Zaborowski <balrogg at gmail.com>
 S: Maintained
commit 1f0803137df68c1fc02ebd0c5ec2e7aad54bbf3b
Author: Claudio Fontana <claudio.fontana at huawei.com>
Date:   Wed Jun 12 16:20:23 2013 +0100

    configure: permit compilation on arm aarch64
    
    support compiling on aarch64.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Claudio Fontana <claudio.fontana at huawei.com>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Message-id: 51A5C5ED.90103 at huawei.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/configure b/configure
index cb42269..1bab634 100755
--- a/configure
+++ b/configure
@@ -386,6 +386,8 @@ elif check_define __s390__ ; then
   fi
 elif check_define __arm__ ; then
   cpu="arm"
+elif check_define __aarch64__ ; then
+  cpu="aarch64"
 elif check_define __hppa__ ; then
   cpu="hppa"
 else
@@ -408,6 +410,9 @@ case "$cpu" in
   armv*b|armv*l|arm)
     cpu="arm"
   ;;
+  aarch64)
+    cpu="aarch64"
+  ;;
   hppa|parisc|parisc64)
     cpu="hppa"
   ;;
@@ -4060,6 +4065,9 @@ if test "$linux" = "yes" ; then
   s390x)
     linux_arch=s390
     ;;
+  aarch64)
+    linux_arch=arm64
+    ;;
   *)
     # For most CPUs the kernel architecture name and QEMU CPU name match.
     linux_arch="$cpu"
commit 6a91c7c978d77461cc2ed056a2869b90bebded3e
Author: Jani Kokkonen <jani.kokkonen at huawei.com>
Date:   Wed Jun 12 16:20:23 2013 +0100

    tcg/aarch64: implement user mode qemu ld/st
    
    also put aarch64 in the list of archs that do not need an ldscript.
    
    Signed-off-by: Jani Kokkoken <jani.kokkonen at huawei.com>
    Signed-off-by: Claudio Fontana <claudio.fontana at huawei.com>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 51AF40EE.1000104 at huawei.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/configure b/configure
index bb413be..cb42269 100755
--- a/configure
+++ b/configure
@@ -4424,7 +4424,7 @@ fi
 
 if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then
   case "$ARCH" in
-  alpha | s390x)
+  alpha | s390x | aarch64)
     # The default placement of the application is fine.
     ;;
   *)
diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index 934109e..562a549 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -24,10 +24,16 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
 };
 #endif /* NDEBUG */
 
+#ifdef TARGET_WORDS_BIGENDIAN
+ #define TCG_LDST_BSWAP 1
+#else
+ #define TCG_LDST_BSWAP 0
+#endif
+
 static const int tcg_target_reg_alloc_order[] = {
     TCG_REG_X20, TCG_REG_X21, TCG_REG_X22, TCG_REG_X23,
     TCG_REG_X24, TCG_REG_X25, TCG_REG_X26, TCG_REG_X27,
-    TCG_REG_X28,
+    TCG_REG_X28, /* we will reserve this for GUEST_BASE if configured */
 
     TCG_REG_X9, TCG_REG_X10, TCG_REG_X11, TCG_REG_X12,
     TCG_REG_X13, TCG_REG_X14, TCG_REG_X15,
@@ -51,6 +57,14 @@ static const int tcg_target_call_oarg_regs[1] = {
 
 #define TCG_REG_TMP TCG_REG_X8
 
+#ifndef CONFIG_SOFTMMU
+# if defined(CONFIG_USE_GUEST_BASE)
+# define TCG_REG_GUEST_BASE TCG_REG_X28
+# else
+# define TCG_REG_GUEST_BASE TCG_REG_XZR
+# endif
+#endif
+
 static inline void reloc_pc26(void *code_ptr, tcg_target_long target)
 {
     tcg_target_long offset; uint32_t insn;
@@ -713,6 +727,94 @@ static const void * const qemu_st_helpers[4] = {
     helper_stq_mmu,
 };
 
+#else /* !CONFIG_SOFTMMU */
+
+static void tcg_out_qemu_ld_direct(TCGContext *s, int opc, TCGReg data_r,
+                                   TCGReg addr_r, TCGReg off_r)
+{
+    switch (opc) {
+    case 0:
+        tcg_out_ldst_r(s, LDST_8, LDST_LD, data_r, addr_r, off_r);
+        break;
+    case 0 | 4:
+        tcg_out_ldst_r(s, LDST_8, LDST_LD_S_X, data_r, addr_r, off_r);
+        break;
+    case 1:
+        tcg_out_ldst_r(s, LDST_16, LDST_LD, data_r, addr_r, off_r);
+        if (TCG_LDST_BSWAP) {
+            tcg_out_rev16(s, 0, data_r, data_r);
+        }
+        break;
+    case 1 | 4:
+        if (TCG_LDST_BSWAP) {
+            tcg_out_ldst_r(s, LDST_16, LDST_LD, data_r, addr_r, off_r);
+            tcg_out_rev16(s, 0, data_r, data_r);
+            tcg_out_sxt(s, 1, 1, data_r, data_r);
+        } else {
+            tcg_out_ldst_r(s, LDST_16, LDST_LD_S_X, data_r, addr_r, off_r);
+        }
+        break;
+    case 2:
+        tcg_out_ldst_r(s, LDST_32, LDST_LD, data_r, addr_r, off_r);
+        if (TCG_LDST_BSWAP) {
+            tcg_out_rev(s, 0, data_r, data_r);
+        }
+        break;
+    case 2 | 4:
+        if (TCG_LDST_BSWAP) {
+            tcg_out_ldst_r(s, LDST_32, LDST_LD, data_r, addr_r, off_r);
+            tcg_out_rev(s, 0, data_r, data_r);
+            tcg_out_sxt(s, 1, 2, data_r, data_r);
+        } else {
+            tcg_out_ldst_r(s, LDST_32, LDST_LD_S_X, data_r, addr_r, off_r);
+        }
+        break;
+    case 3:
+        tcg_out_ldst_r(s, LDST_64, LDST_LD, data_r, addr_r, off_r);
+        if (TCG_LDST_BSWAP) {
+            tcg_out_rev(s, 1, data_r, data_r);
+        }
+        break;
+    default:
+        tcg_abort();
+    }
+}
+
+static void tcg_out_qemu_st_direct(TCGContext *s, int opc, TCGReg data_r,
+                                   TCGReg addr_r, TCGReg off_r)
+{
+    switch (opc) {
+    case 0:
+        tcg_out_ldst_r(s, LDST_8, LDST_ST, data_r, addr_r, off_r);
+        break;
+    case 1:
+        if (TCG_LDST_BSWAP) {
+            tcg_out_rev16(s, 0, TCG_REG_TMP, data_r);
+            tcg_out_ldst_r(s, LDST_16, LDST_ST, TCG_REG_TMP, addr_r, off_r);
+        } else {
+            tcg_out_ldst_r(s, LDST_16, LDST_ST, data_r, addr_r, off_r);
+        }
+        break;
+    case 2:
+        if (TCG_LDST_BSWAP) {
+            tcg_out_rev(s, 0, TCG_REG_TMP, data_r);
+            tcg_out_ldst_r(s, LDST_32, LDST_ST, TCG_REG_TMP, addr_r, off_r);
+        } else {
+            tcg_out_ldst_r(s, LDST_32, LDST_ST, data_r, addr_r, off_r);
+        }
+        break;
+    case 3:
+        if (TCG_LDST_BSWAP) {
+            tcg_out_rev(s, 1, TCG_REG_TMP, data_r);
+            tcg_out_ldst_r(s, LDST_64, LDST_ST, TCG_REG_TMP, addr_r, off_r);
+        } else {
+            tcg_out_ldst_r(s, LDST_64, LDST_ST, data_r, addr_r, off_r);
+        }
+        break;
+    default:
+        tcg_abort();
+    }
+}
 #endif /* CONFIG_SOFTMMU */
 
 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
@@ -745,8 +847,9 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
     }
 
 #else /* !CONFIG_SOFTMMU */
-    tcg_abort(); /* TODO */
-#endif
+    tcg_out_qemu_ld_direct(s, opc, data_reg, addr_reg,
+                           GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR);
+#endif /* CONFIG_SOFTMMU */
 }
 
 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
@@ -774,8 +877,9 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
     tcg_out_callr(s, TCG_REG_TMP);
 
 #else /* !CONFIG_SOFTMMU */
-    tcg_abort(); /* TODO */
-#endif
+    tcg_out_qemu_st_direct(s, opc, data_reg, addr_reg,
+                           GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR);
+#endif /* CONFIG_SOFTMMU */
 }
 
 static uint8_t *tb_ret_addr;
@@ -1270,6 +1374,13 @@ static void tcg_target_qemu_prologue(TCGContext *s)
     tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE,
                   CPU_TEMP_BUF_NLONGS * sizeof(long));
 
+#if defined(CONFIG_USE_GUEST_BASE)
+    if (GUEST_BASE) {
+        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_GUEST_BASE, GUEST_BASE);
+        tcg_regset_set_reg(s->reserved_regs, TCG_REG_GUEST_BASE);
+    }
+#endif
+
     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
     tcg_out_gotor(s, tcg_target_call_iarg_regs[1]);
 
commit f129061c6abfaee2133fcb55c384ec5f99028f62
Author: Claudio Fontana <claudio.fontana at huawei.com>
Date:   Wed Jun 12 16:20:23 2013 +0100

    user-exec.c: aarch64 initial implementation of cpu_signal_handler
    
    Signed-off-by: Claudio Fontana <claudio.fontana at huawei.com>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 51AF4028.5030504 at huawei.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/user-exec.c b/user-exec.c
index 71bd6c5..fa7f1f1 100644
--- a/user-exec.c
+++ b/user-exec.c
@@ -448,6 +448,21 @@ int cpu_signal_handler(int host_signum, void *pinfo,
                              &uc->uc_sigmask, puc);
 }
 
+#elif defined(__aarch64__)
+
+int cpu_signal_handler(int host_signum, void *pinfo,
+                       void *puc)
+{
+    siginfo_t *info = pinfo;
+    struct ucontext *uc = puc;
+    uint64_t pc;
+    int is_write = 0; /* XXX how to determine? */
+
+    pc = uc->uc_mcontext.pc;
+    return handle_cpu_signal(pc, (uint64_t)info->si_addr,
+                             is_write, &uc->uc_sigmask, puc);
+}
+
 #elif defined(__mc68000)
 
 int cpu_signal_handler(int host_signum, void *pinfo,
commit 31f1275b90f4803ee5a2900020f21d3320ce62b7
Author: Claudio Fontana <claudio.fontana at huawei.com>
Date:   Wed Jun 12 16:20:23 2013 +0100

    tcg/aarch64: implement sign/zero extend operations
    
    implement the optional sign/zero extend operations with the dedicated
    aarch64 instructions.
    
    Signed-off-by: Claudio Fontana <claudio.fontana at huawei.com>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Message-id: 51AC9A58.40502 at huawei.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index ba65a62..934109e 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -674,6 +674,24 @@ static inline void tcg_out_rev16(TCGContext *s, int ext, TCGReg rd, TCGReg rm)
     tcg_out32(s, base | rm << 5 | rd);
 }
 
+static inline void tcg_out_sxt(TCGContext *s, int ext, int s_bits,
+                               TCGReg rd, TCGReg rn)
+{
+    /* using ALIASes SXTB 0x13001c00, SXTH 0x13003c00, SXTW 0x93407c00
+       of SBFM Xd, Xn, #0, #7|15|31 */
+    int bits = 8 * (1 << s_bits) - 1;
+    tcg_out_sbfm(s, ext, rd, rn, 0, bits);
+}
+
+static inline void tcg_out_uxt(TCGContext *s, int s_bits,
+                               TCGReg rd, TCGReg rn)
+{
+    /* using ALIASes UXTB 0x53001c00, UXTH 0x53003c00
+       of UBFM Wd, Wn, #0, #7|15 */
+    int bits = 8 * (1 << s_bits) - 1;
+    tcg_out_ubfm(s, 0, rd, rn, 0, bits);
+}
+
 #ifdef CONFIG_SOFTMMU
 #include "exec/softmmu_defs.h"
 
@@ -721,8 +739,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
     tcg_out_callr(s, TCG_REG_TMP);
 
     if (opc & 0x04) { /* sign extend */
-        unsigned int bits = 8 * (1 << s_bits) - 1;
-        tcg_out_sbfm(s, 1, data_reg, TCG_REG_X0, 0, bits); /* 7|15|31 */
+        tcg_out_sxt(s, 1, s_bits, data_reg, TCG_REG_X0);
     } else {
         tcg_out_movr(s, 1, data_reg, TCG_REG_X0);
     }
@@ -1037,6 +1054,31 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         tcg_out_rev16(s, 0, args[0], args[1]);
         break;
 
+    case INDEX_op_ext8s_i64:
+        ext = 1; /* fall through */
+    case INDEX_op_ext8s_i32:
+        tcg_out_sxt(s, ext, 0, args[0], args[1]);
+        break;
+    case INDEX_op_ext16s_i64:
+        ext = 1; /* fall through */
+    case INDEX_op_ext16s_i32:
+        tcg_out_sxt(s, ext, 1, args[0], args[1]);
+        break;
+    case INDEX_op_ext32s_i64:
+        tcg_out_sxt(s, 1, 2, args[0], args[1]);
+        break;
+    case INDEX_op_ext8u_i64:
+    case INDEX_op_ext8u_i32:
+        tcg_out_uxt(s, 0, args[0], args[1]);
+        break;
+    case INDEX_op_ext16u_i64:
+    case INDEX_op_ext16u_i32:
+        tcg_out_uxt(s, 1, args[0], args[1]);
+        break;
+    case INDEX_op_ext32u_i64:
+        tcg_out_movr(s, 0, args[0], args[1]);
+        break;
+
     default:
         tcg_abort(); /* opcode not implemented */
     }
@@ -1125,6 +1167,18 @@ static const TCGTargetOpDef aarch64_op_defs[] = {
     { INDEX_op_bswap32_i64, { "r", "r" } },
     { INDEX_op_bswap64_i64, { "r", "r" } },
 
+    { INDEX_op_ext8s_i32, { "r", "r" } },
+    { INDEX_op_ext16s_i32, { "r", "r" } },
+    { INDEX_op_ext8u_i32, { "r", "r" } },
+    { INDEX_op_ext16u_i32, { "r", "r" } },
+
+    { INDEX_op_ext8s_i64, { "r", "r" } },
+    { INDEX_op_ext16s_i64, { "r", "r" } },
+    { INDEX_op_ext32s_i64, { "r", "r" } },
+    { INDEX_op_ext8u_i64, { "r", "r" } },
+    { INDEX_op_ext16u_i64, { "r", "r" } },
+    { INDEX_op_ext32u_i64, { "r", "r" } },
+
     { -1 },
 };
 
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 247ef43..97e4a5b 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -40,10 +40,10 @@ typedef enum {
 
 /* optional instructions */
 #define TCG_TARGET_HAS_div_i32          0
-#define TCG_TARGET_HAS_ext8s_i32        0
-#define TCG_TARGET_HAS_ext16s_i32       0
-#define TCG_TARGET_HAS_ext8u_i32        0
-#define TCG_TARGET_HAS_ext16u_i32       0
+#define TCG_TARGET_HAS_ext8s_i32        1
+#define TCG_TARGET_HAS_ext16s_i32       1
+#define TCG_TARGET_HAS_ext8u_i32        1
+#define TCG_TARGET_HAS_ext16u_i32       1
 #define TCG_TARGET_HAS_bswap16_i32      1
 #define TCG_TARGET_HAS_bswap32_i32      1
 #define TCG_TARGET_HAS_not_i32          0
@@ -62,12 +62,12 @@ typedef enum {
 #define TCG_TARGET_HAS_muls2_i32        0
 
 #define TCG_TARGET_HAS_div_i64          0
-#define TCG_TARGET_HAS_ext8s_i64        0
-#define TCG_TARGET_HAS_ext16s_i64       0
-#define TCG_TARGET_HAS_ext32s_i64       0
-#define TCG_TARGET_HAS_ext8u_i64        0
-#define TCG_TARGET_HAS_ext16u_i64       0
-#define TCG_TARGET_HAS_ext32u_i64       0
+#define TCG_TARGET_HAS_ext8s_i64        1
+#define TCG_TARGET_HAS_ext16s_i64       1
+#define TCG_TARGET_HAS_ext32s_i64       1
+#define TCG_TARGET_HAS_ext8u_i64        1
+#define TCG_TARGET_HAS_ext16u_i64       1
+#define TCG_TARGET_HAS_ext32u_i64       1
 #define TCG_TARGET_HAS_bswap16_i64      1
 #define TCG_TARGET_HAS_bswap32_i64      1
 #define TCG_TARGET_HAS_bswap64_i64      1
commit 9c4a059df3501ba53c00724287ef50bba80b5f80
Author: Claudio Fontana <claudio.fontana at huawei.com>
Date:   Wed Jun 12 16:20:23 2013 +0100

    tcg/aarch64: implement byte swap operations
    
    implement the optional byte swap operations with the dedicated
    aarch64 instructions.
    
    Signed-off-by: Claudio Fontana <claudio.fontana at huawei.com>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Message-id: 51AC9A33.9050003 at huawei.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index bb59794..ba65a62 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -660,6 +660,20 @@ static inline void tcg_out_goto_label_cond(TCGContext *s,
     }
 }
 
+static inline void tcg_out_rev(TCGContext *s, int ext, TCGReg rd, TCGReg rm)
+{
+    /* using REV 0x5ac00800 */
+    unsigned int base = ext ? 0xdac00c00 : 0x5ac00800;
+    tcg_out32(s, base | rm << 5 | rd);
+}
+
+static inline void tcg_out_rev16(TCGContext *s, int ext, TCGReg rd, TCGReg rm)
+{
+    /* using REV16 0x5ac00400 */
+    unsigned int base = ext ? 0xdac00400 : 0x5ac00400;
+    tcg_out32(s, base | rm << 5 | rd);
+}
+
 #ifdef CONFIG_SOFTMMU
 #include "exec/softmmu_defs.h"
 
@@ -1012,6 +1026,17 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         tcg_out_qemu_st(s, args, 3);
         break;
 
+    case INDEX_op_bswap64_i64:
+        ext = 1; /* fall through */
+    case INDEX_op_bswap32_i64:
+    case INDEX_op_bswap32_i32:
+        tcg_out_rev(s, ext, args[0], args[1]);
+        break;
+    case INDEX_op_bswap16_i64:
+    case INDEX_op_bswap16_i32:
+        tcg_out_rev16(s, 0, args[0], args[1]);
+        break;
+
     default:
         tcg_abort(); /* opcode not implemented */
     }
@@ -1093,6 +1118,13 @@ static const TCGTargetOpDef aarch64_op_defs[] = {
     { INDEX_op_qemu_st16, { "l", "l" } },
     { INDEX_op_qemu_st32, { "l", "l" } },
     { INDEX_op_qemu_st64, { "l", "l" } },
+
+    { INDEX_op_bswap16_i32, { "r", "r" } },
+    { INDEX_op_bswap32_i32, { "r", "r" } },
+    { INDEX_op_bswap16_i64, { "r", "r" } },
+    { INDEX_op_bswap32_i64, { "r", "r" } },
+    { INDEX_op_bswap64_i64, { "r", "r" } },
+
     { -1 },
 };
 
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 075ab2a..247ef43 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -44,8 +44,8 @@ typedef enum {
 #define TCG_TARGET_HAS_ext16s_i32       0
 #define TCG_TARGET_HAS_ext8u_i32        0
 #define TCG_TARGET_HAS_ext16u_i32       0
-#define TCG_TARGET_HAS_bswap16_i32      0
-#define TCG_TARGET_HAS_bswap32_i32      0
+#define TCG_TARGET_HAS_bswap16_i32      1
+#define TCG_TARGET_HAS_bswap32_i32      1
 #define TCG_TARGET_HAS_not_i32          0
 #define TCG_TARGET_HAS_neg_i32          0
 #define TCG_TARGET_HAS_rot_i32          1
@@ -68,9 +68,9 @@ typedef enum {
 #define TCG_TARGET_HAS_ext8u_i64        0
 #define TCG_TARGET_HAS_ext16u_i64       0
 #define TCG_TARGET_HAS_ext32u_i64       0
-#define TCG_TARGET_HAS_bswap16_i64      0
-#define TCG_TARGET_HAS_bswap32_i64      0
-#define TCG_TARGET_HAS_bswap64_i64      0
+#define TCG_TARGET_HAS_bswap16_i64      1
+#define TCG_TARGET_HAS_bswap32_i64      1
+#define TCG_TARGET_HAS_bswap64_i64      1
 #define TCG_TARGET_HAS_not_i64          0
 #define TCG_TARGET_HAS_neg_i64          0
 #define TCG_TARGET_HAS_rot_i64          1
commit 7deea126b24508e8ffa7aa4aecfa6fa97eddc384
Author: Claudio Fontana <claudio.fontana at huawei.com>
Date:   Wed Jun 12 16:20:22 2013 +0100

    tcg/aarch64: implement AND/TEST immediate pattern
    
    add functions to AND/TEST registers with immediate patterns.
    
    Signed-off-by: Claudio Fontana <claudio.fontana at huawei.com>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Message-id: 51AC9A0C.3090303 at huawei.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index 2aa9f75..bb59794 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -580,6 +580,40 @@ static inline void tcg_out_call(TCGContext *s, tcg_target_long target)
     }
 }
 
+/* encode a logical immediate, mapping user parameter
+   M=set bits pattern length to S=M-1 */
+static inline unsigned int
+aarch64_limm(unsigned int m, unsigned int r)
+{
+    assert(m > 0);
+    return r << 16 | (m - 1) << 10;
+}
+
+/* test a register against an immediate bit pattern made of
+   M set bits rotated right by R.
+   Examples:
+   to test a 32/64 reg against 0x00000007, pass M = 3,  R = 0.
+   to test a 32/64 reg against 0x000000ff, pass M = 8,  R = 0.
+   to test a 32bit reg against 0xff000000, pass M = 8,  R = 8.
+   to test a 32bit reg against 0xff0000ff, pass M = 16, R = 8.
+ */
+static inline void tcg_out_tst(TCGContext *s, int ext, TCGReg rn,
+                               unsigned int m, unsigned int r)
+{
+    /* using TST alias of ANDS XZR, Xn,#bimm64 0x7200001f */
+    unsigned int base = ext ? 0xf240001f : 0x7200001f;
+    tcg_out32(s, base | aarch64_limm(m, r) | rn << 5);
+}
+
+/* and a register with a bit pattern, similarly to TST, no flags change */
+static inline void tcg_out_andi(TCGContext *s, int ext, TCGReg rd, TCGReg rn,
+                                unsigned int m, unsigned int r)
+{
+    /* using AND 0x12000000 */
+    unsigned int base = ext ? 0x92400000 : 0x12000000;
+    tcg_out32(s, base | aarch64_limm(m, r) | rn << 5 | rd);
+}
+
 static inline void tcg_out_ret(TCGContext *s)
 {
     /* emit RET { LR } */
commit 36fac14a6416fe1f8f6f23bfac5f9e662be78d2b
Author: Claudio Fontana <claudio.fontana at huawei.com>
Date:   Wed Jun 12 16:20:22 2013 +0100

    tcg/aarch64: improve arith shifted regs operations
    
    for arith operations, add SUBS, ANDS, ADDS and add a shift parameter
    so that all arith instructions can make use of shifted registers.
    
    Signed-off-by: Claudio Fontana <claudio.fontana at huawei.com>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Message-id: 51AC998B.7070506 at huawei.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index ff626eb..2aa9f75 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -186,11 +186,14 @@ enum aarch64_ldst_op_type { /* type of operation */
 };
 
 enum aarch64_arith_opc {
-    ARITH_ADD = 0x0b,
-    ARITH_SUB = 0x4b,
     ARITH_AND = 0x0a,
+    ARITH_ADD = 0x0b,
     ARITH_OR = 0x2a,
-    ARITH_XOR = 0x4a
+    ARITH_ADDS = 0x2b,
+    ARITH_XOR = 0x4a,
+    ARITH_SUB = 0x4b,
+    ARITH_ANDS = 0x6a,
+    ARITH_SUBS = 0x6b,
 };
 
 enum aarch64_srr_opc {
@@ -394,12 +397,20 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
 }
 
 static inline void tcg_out_arith(TCGContext *s, enum aarch64_arith_opc opc,
-                                 int ext, TCGReg rd, TCGReg rn, TCGReg rm)
+                                 int ext, TCGReg rd, TCGReg rn, TCGReg rm,
+                                 int shift_imm)
 {
     /* Using shifted register arithmetic operations */
-    /* if extended registry operation (64bit) just OR with 0x80 << 24 */
-    unsigned int base = ext ? (0x80 | opc) << 24 : opc << 24;
-    tcg_out32(s, base | rm << 16 | rn << 5 | rd);
+    /* if extended register operation (64bit) just OR with 0x80 << 24 */
+    unsigned int shift, base = ext ? (0x80 | opc) << 24 : opc << 24;
+    if (shift_imm == 0) {
+        shift = 0;
+    } else if (shift_imm > 0) {
+        shift = shift_imm << 10 | 1 << 22;
+    } else /* (shift_imm < 0) */ {
+        shift = (-shift_imm) << 10;
+    }
+    tcg_out32(s, base | rm << 16 | shift | rn << 5 | rd);
 }
 
 static inline void tcg_out_mul(TCGContext *s, int ext,
@@ -482,11 +493,11 @@ static inline void tcg_out_rotl(TCGContext *s, int ext,
     tcg_out_extr(s, ext, rd, rn, rn, bits - (m & max));
 }
 
-static inline void tcg_out_cmp(TCGContext *s, int ext, TCGReg rn, TCGReg rm)
+static inline void tcg_out_cmp(TCGContext *s, int ext, TCGReg rn, TCGReg rm,
+                               int shift_imm)
 {
     /* Using CMP alias SUBS wzr, Wn, Wm */
-    unsigned int base = ext ? 0xeb00001f : 0x6b00001f;
-    tcg_out32(s, base | rm << 16 | rn << 5);
+    tcg_out_arith(s, ARITH_SUBS, ext, TCG_REG_XZR, rn, rm, shift_imm);
 }
 
 static inline void tcg_out_cset(TCGContext *s, int ext, TCGReg rd, TCGCond c)
@@ -830,31 +841,31 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
     case INDEX_op_add_i64:
         ext = 1; /* fall through */
     case INDEX_op_add_i32:
-        tcg_out_arith(s, ARITH_ADD, ext, args[0], args[1], args[2]);
+        tcg_out_arith(s, ARITH_ADD, ext, args[0], args[1], args[2], 0);
         break;
 
     case INDEX_op_sub_i64:
         ext = 1; /* fall through */
     case INDEX_op_sub_i32:
-        tcg_out_arith(s, ARITH_SUB, ext, args[0], args[1], args[2]);
+        tcg_out_arith(s, ARITH_SUB, ext, args[0], args[1], args[2], 0);
         break;
 
     case INDEX_op_and_i64:
         ext = 1; /* fall through */
     case INDEX_op_and_i32:
-        tcg_out_arith(s, ARITH_AND, ext, args[0], args[1], args[2]);
+        tcg_out_arith(s, ARITH_AND, ext, args[0], args[1], args[2], 0);
         break;
 
     case INDEX_op_or_i64:
         ext = 1; /* fall through */
     case INDEX_op_or_i32:
-        tcg_out_arith(s, ARITH_OR, ext, args[0], args[1], args[2]);
+        tcg_out_arith(s, ARITH_OR, ext, args[0], args[1], args[2], 0);
         break;
 
     case INDEX_op_xor_i64:
         ext = 1; /* fall through */
     case INDEX_op_xor_i32:
-        tcg_out_arith(s, ARITH_XOR, ext, args[0], args[1], args[2]);
+        tcg_out_arith(s, ARITH_XOR, ext, args[0], args[1], args[2], 0);
         break;
 
     case INDEX_op_mul_i64:
@@ -909,7 +920,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         if (const_args[2]) {    /* ROR / EXTR Wd, Wm, Wm, 32 - m */
             tcg_out_rotl(s, ext, args[0], args[1], args[2]);
         } else {
-            tcg_out_arith(s, ARITH_SUB, 0, TCG_REG_TMP, TCG_REG_XZR, args[2]);
+            tcg_out_arith(s, ARITH_SUB, 0,
+                          TCG_REG_TMP, TCG_REG_XZR, args[2], 0);
             tcg_out_shiftrot_reg(s, SRR_ROR, ext,
                                  args[0], args[1], TCG_REG_TMP);
         }
@@ -918,14 +930,14 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
     case INDEX_op_brcond_i64:
         ext = 1; /* fall through */
     case INDEX_op_brcond_i32: /* CMP 0, 1, cond(2), label 3 */
-        tcg_out_cmp(s, ext, args[0], args[1]);
+        tcg_out_cmp(s, ext, args[0], args[1], 0);
         tcg_out_goto_label_cond(s, args[2], args[3]);
         break;
 
     case INDEX_op_setcond_i64:
         ext = 1; /* fall through */
     case INDEX_op_setcond_i32:
-        tcg_out_cmp(s, ext, args[1], args[2]);
+        tcg_out_cmp(s, ext, args[1], args[2], 0);
         tcg_out_cset(s, 0, args[0], args[3]);
         break;
 
commit 4a136e0a6b4ceac177bc2ab29502161553e25ae2
Author: Claudio Fontana <claudio.fontana at huawei.com>
Date:   Wed Jun 12 16:20:22 2013 +0100

    tcg/aarch64: implement new TCG target for aarch64
    
    add preliminary support for TCG target aarch64.
    
    Signed-off-by: Claudio Fontana <claudio.fontana at huawei.com>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 51A5C596.3090108 at huawei.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 17fde25..b2162a4 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -128,7 +128,7 @@ static inline void tlb_flush(CPUArchState *env, int flush_global)
 
 #if defined(__arm__) || defined(_ARCH_PPC) \
     || defined(__x86_64__) || defined(__i386__) \
-    || defined(__sparc__) \
+    || defined(__sparc__) || defined(__aarch64__) \
     || defined(CONFIG_TCG_INTERPRETER)
 #define USE_DIRECT_JUMP
 #endif
@@ -230,6 +230,9 @@ static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
     *(uint32_t *)jmp_addr = addr - (jmp_addr + 4);
     /* no need to flush icache explicitly */
 }
+#elif defined(__aarch64__)
+void aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr);
+#define tb_set_jmp_target1 aarch64_tb_set_jmp_target
 #elif defined(__arm__)
 static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
 {
diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
new file mode 100644
index 0000000..ff626eb
--- /dev/null
+++ b/tcg/aarch64/tcg-target.c
@@ -0,0 +1,1161 @@
+/*
+ * Initial TCG Implementation for aarch64
+ *
+ * Copyright (c) 2013 Huawei Technologies Duesseldorf GmbH
+ * Written by Claudio Fontana
+ *
+ * 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 for details.
+ */
+
+#include "qemu/bitops.h"
+
+#ifndef NDEBUG
+static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
+    "%x0", "%x1", "%x2", "%x3", "%x4", "%x5", "%x6", "%x7",
+    "%x8", "%x9", "%x10", "%x11", "%x12", "%x13", "%x14", "%x15",
+    "%x16", "%x17", "%x18", "%x19", "%x20", "%x21", "%x22", "%x23",
+    "%x24", "%x25", "%x26", "%x27", "%x28",
+    "%fp", /* frame pointer */
+    "%lr", /* link register */
+    "%sp",  /* stack pointer */
+};
+#endif /* NDEBUG */
+
+static const int tcg_target_reg_alloc_order[] = {
+    TCG_REG_X20, TCG_REG_X21, TCG_REG_X22, TCG_REG_X23,
+    TCG_REG_X24, TCG_REG_X25, TCG_REG_X26, TCG_REG_X27,
+    TCG_REG_X28,
+
+    TCG_REG_X9, TCG_REG_X10, TCG_REG_X11, TCG_REG_X12,
+    TCG_REG_X13, TCG_REG_X14, TCG_REG_X15,
+    TCG_REG_X16, TCG_REG_X17,
+
+    TCG_REG_X18, TCG_REG_X19, /* will not use these, see tcg_target_init */
+
+    TCG_REG_X0, TCG_REG_X1, TCG_REG_X2, TCG_REG_X3,
+    TCG_REG_X4, TCG_REG_X5, TCG_REG_X6, TCG_REG_X7,
+
+    TCG_REG_X8, /* will not use, see tcg_target_init */
+};
+
+static const int tcg_target_call_iarg_regs[8] = {
+    TCG_REG_X0, TCG_REG_X1, TCG_REG_X2, TCG_REG_X3,
+    TCG_REG_X4, TCG_REG_X5, TCG_REG_X6, TCG_REG_X7
+};
+static const int tcg_target_call_oarg_regs[1] = {
+    TCG_REG_X0
+};
+
+#define TCG_REG_TMP TCG_REG_X8
+
+static inline void reloc_pc26(void *code_ptr, tcg_target_long target)
+{
+    tcg_target_long offset; uint32_t insn;
+    offset = (target - (tcg_target_long)code_ptr) / 4;
+    /* read instruction, mask away previous PC_REL26 parameter contents,
+       set the proper offset, then write back the instruction. */
+    insn = *(uint32_t *)code_ptr;
+    insn = deposit32(insn, 0, 26, offset);
+    *(uint32_t *)code_ptr = insn;
+}
+
+static inline void reloc_pc19(void *code_ptr, tcg_target_long target)
+{
+    tcg_target_long offset; uint32_t insn;
+    offset = (target - (tcg_target_long)code_ptr) / 4;
+    /* read instruction, mask away previous PC_REL19 parameter contents,
+       set the proper offset, then write back the instruction. */
+    insn = *(uint32_t *)code_ptr;
+    insn = deposit32(insn, 5, 19, offset);
+    *(uint32_t *)code_ptr = insn;
+}
+
+static inline void patch_reloc(uint8_t *code_ptr, int type,
+                               tcg_target_long value, tcg_target_long addend)
+{
+    value += addend;
+
+    switch (type) {
+    case R_AARCH64_JUMP26:
+    case R_AARCH64_CALL26:
+        reloc_pc26(code_ptr, value);
+        break;
+    case R_AARCH64_CONDBR19:
+        reloc_pc19(code_ptr, value);
+        break;
+
+    default:
+        tcg_abort();
+    }
+}
+
+/* parse target specific constraints */
+static int target_parse_constraint(TCGArgConstraint *ct,
+                                   const char **pct_str)
+{
+    const char *ct_str = *pct_str;
+
+    switch (ct_str[0]) {
+    case 'r':
+        ct->ct |= TCG_CT_REG;
+        tcg_regset_set32(ct->u.regs, 0, (1ULL << TCG_TARGET_NB_REGS) - 1);
+        break;
+    case 'l': /* qemu_ld / qemu_st address, data_reg */
+        ct->ct |= TCG_CT_REG;
+        tcg_regset_set32(ct->u.regs, 0, (1ULL << TCG_TARGET_NB_REGS) - 1);
+#ifdef CONFIG_SOFTMMU
+        /* x0 and x1 will be overwritten when reading the tlb entry,
+           and x2, and x3 for helper args, better to avoid using them. */
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_X0);
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_X1);
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_X2);
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_X3);
+#endif
+        break;
+    default:
+        return -1;
+    }
+
+    ct_str++;
+    *pct_str = ct_str;
+    return 0;
+}
+
+static inline int tcg_target_const_match(tcg_target_long val,
+                                         const TCGArgConstraint *arg_ct)
+{
+    int ct = arg_ct->ct;
+
+    if (ct & TCG_CT_CONST) {
+        return 1;
+    }
+
+    return 0;
+}
+
+enum aarch64_cond_code {
+    COND_EQ = 0x0,
+    COND_NE = 0x1,
+    COND_CS = 0x2,     /* Unsigned greater or equal */
+    COND_HS = COND_CS, /* ALIAS greater or equal */
+    COND_CC = 0x3,     /* Unsigned less than */
+    COND_LO = COND_CC, /* ALIAS Lower */
+    COND_MI = 0x4,     /* Negative */
+    COND_PL = 0x5,     /* Zero or greater */
+    COND_VS = 0x6,     /* Overflow */
+    COND_VC = 0x7,     /* No overflow */
+    COND_HI = 0x8,     /* Unsigned greater than */
+    COND_LS = 0x9,     /* Unsigned less or equal */
+    COND_GE = 0xa,
+    COND_LT = 0xb,
+    COND_GT = 0xc,
+    COND_LE = 0xd,
+    COND_AL = 0xe,
+    COND_NV = 0xf, /* behaves like COND_AL here */
+};
+
+static const enum aarch64_cond_code tcg_cond_to_aarch64[] = {
+    [TCG_COND_EQ] = COND_EQ,
+    [TCG_COND_NE] = COND_NE,
+    [TCG_COND_LT] = COND_LT,
+    [TCG_COND_GE] = COND_GE,
+    [TCG_COND_LE] = COND_LE,
+    [TCG_COND_GT] = COND_GT,
+    /* unsigned */
+    [TCG_COND_LTU] = COND_LO,
+    [TCG_COND_GTU] = COND_HI,
+    [TCG_COND_GEU] = COND_HS,
+    [TCG_COND_LEU] = COND_LS,
+};
+
+/* opcodes for LDR / STR instructions with base + simm9 addressing */
+enum aarch64_ldst_op_data { /* size of the data moved */
+    LDST_8 = 0x38,
+    LDST_16 = 0x78,
+    LDST_32 = 0xb8,
+    LDST_64 = 0xf8,
+};
+enum aarch64_ldst_op_type { /* type of operation */
+    LDST_ST = 0x0,    /* store */
+    LDST_LD = 0x4,    /* load */
+    LDST_LD_S_X = 0x8,  /* load and sign-extend into Xt */
+    LDST_LD_S_W = 0xc,  /* load and sign-extend into Wt */
+};
+
+enum aarch64_arith_opc {
+    ARITH_ADD = 0x0b,
+    ARITH_SUB = 0x4b,
+    ARITH_AND = 0x0a,
+    ARITH_OR = 0x2a,
+    ARITH_XOR = 0x4a
+};
+
+enum aarch64_srr_opc {
+    SRR_SHL = 0x0,
+    SRR_SHR = 0x4,
+    SRR_SAR = 0x8,
+    SRR_ROR = 0xc
+};
+
+static inline enum aarch64_ldst_op_data
+aarch64_ldst_get_data(TCGOpcode tcg_op)
+{
+    switch (tcg_op) {
+    case INDEX_op_ld8u_i32:
+    case INDEX_op_ld8s_i32:
+    case INDEX_op_ld8u_i64:
+    case INDEX_op_ld8s_i64:
+    case INDEX_op_st8_i32:
+    case INDEX_op_st8_i64:
+        return LDST_8;
+
+    case INDEX_op_ld16u_i32:
+    case INDEX_op_ld16s_i32:
+    case INDEX_op_ld16u_i64:
+    case INDEX_op_ld16s_i64:
+    case INDEX_op_st16_i32:
+    case INDEX_op_st16_i64:
+        return LDST_16;
+
+    case INDEX_op_ld_i32:
+    case INDEX_op_st_i32:
+    case INDEX_op_ld32u_i64:
+    case INDEX_op_ld32s_i64:
+    case INDEX_op_st32_i64:
+        return LDST_32;
+
+    case INDEX_op_ld_i64:
+    case INDEX_op_st_i64:
+        return LDST_64;
+
+    default:
+        tcg_abort();
+    }
+}
+
+static inline enum aarch64_ldst_op_type
+aarch64_ldst_get_type(TCGOpcode tcg_op)
+{
+    switch (tcg_op) {
+    case INDEX_op_st8_i32:
+    case INDEX_op_st16_i32:
+    case INDEX_op_st8_i64:
+    case INDEX_op_st16_i64:
+    case INDEX_op_st_i32:
+    case INDEX_op_st32_i64:
+    case INDEX_op_st_i64:
+        return LDST_ST;
+
+    case INDEX_op_ld8u_i32:
+    case INDEX_op_ld16u_i32:
+    case INDEX_op_ld8u_i64:
+    case INDEX_op_ld16u_i64:
+    case INDEX_op_ld_i32:
+    case INDEX_op_ld32u_i64:
+    case INDEX_op_ld_i64:
+        return LDST_LD;
+
+    case INDEX_op_ld8s_i32:
+    case INDEX_op_ld16s_i32:
+        return LDST_LD_S_W;
+
+    case INDEX_op_ld8s_i64:
+    case INDEX_op_ld16s_i64:
+    case INDEX_op_ld32s_i64:
+        return LDST_LD_S_X;
+
+    default:
+        tcg_abort();
+    }
+}
+
+static inline uint32_t tcg_in32(TCGContext *s)
+{
+    uint32_t v = *(uint32_t *)s->code_ptr;
+    return v;
+}
+
+static inline void tcg_out_ldst_9(TCGContext *s,
+                                  enum aarch64_ldst_op_data op_data,
+                                  enum aarch64_ldst_op_type op_type,
+                                  TCGReg rd, TCGReg rn, tcg_target_long offset)
+{
+    /* use LDUR with BASE register with 9bit signed unscaled offset */
+    unsigned int mod, off;
+
+    if (offset < 0) {
+        off = (256 + offset);
+        mod = 0x1;
+    } else {
+        off = offset;
+        mod = 0x0;
+    }
+
+    mod |= op_type;
+    tcg_out32(s, op_data << 24 | mod << 20 | off << 12 | rn << 5 | rd);
+}
+
+static inline void tcg_out_movr(TCGContext *s, int ext, TCGReg rd, TCGReg src)
+{
+    /* register to register move using MOV (shifted register with no shift) */
+    /* using MOV 0x2a0003e0 | (shift).. */
+    unsigned int base = ext ? 0xaa0003e0 : 0x2a0003e0;
+    tcg_out32(s, base | src << 16 | rd);
+}
+
+static inline void tcg_out_movi_aux(TCGContext *s,
+                                    TCGReg rd, uint64_t value)
+{
+    uint32_t half, base, shift, movk = 0;
+    /* construct halfwords of the immediate with MOVZ/MOVK with LSL */
+    /* using MOVZ 0x52800000 | extended reg.. */
+    base = (value > 0xffffffff) ? 0xd2800000 : 0x52800000;
+    /* count trailing zeros in 16 bit steps, mapping 64 to 0. Emit the
+       first MOVZ with the half-word immediate skipping the zeros, with a shift
+       (LSL) equal to this number. Then morph all next instructions into MOVKs.
+       Zero the processed half-word in the value, continue until empty.
+       We build the final result 16bits at a time with up to 4 instructions,
+       but do not emit instructions for 16bit zero holes. */
+    do {
+        shift = ctz64(value) & (63 & -16);
+        half = (value >> shift) & 0xffff;
+        tcg_out32(s, base | movk | shift << 17 | half << 5 | rd);
+        movk = 0x20000000; /* morph next MOVZs into MOVKs */
+        value &= ~(0xffffUL << shift);
+    } while (value);
+}
+
+static inline void tcg_out_movi(TCGContext *s, TCGType type,
+                                TCGReg rd, tcg_target_long value)
+{
+    if (type == TCG_TYPE_I64) {
+        tcg_out_movi_aux(s, rd, value);
+    } else {
+        tcg_out_movi_aux(s, rd, value & 0xffffffff);
+    }
+}
+
+static inline void tcg_out_ldst_r(TCGContext *s,
+                                  enum aarch64_ldst_op_data op_data,
+                                  enum aarch64_ldst_op_type op_type,
+                                  TCGReg rd, TCGReg base, TCGReg regoff)
+{
+    /* load from memory to register using base + 64bit register offset */
+    /* using f.e. STR Wt, [Xn, Xm] 0xb8600800|(regoff << 16)|(base << 5)|rd */
+    /* the 0x6000 is for the "no extend field" */
+    tcg_out32(s, 0x00206800
+              | op_data << 24 | op_type << 20 | regoff << 16 | base << 5 | rd);
+}
+
+/* solve the whole ldst problem */
+static inline void tcg_out_ldst(TCGContext *s, enum aarch64_ldst_op_data data,
+                                enum aarch64_ldst_op_type type,
+                                TCGReg rd, TCGReg rn, tcg_target_long offset)
+{
+    if (offset >= -256 && offset < 256) {
+        tcg_out_ldst_9(s, data, type, rd, rn, offset);
+    } else {
+        tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, offset);
+        tcg_out_ldst_r(s, data, type, rd, rn, TCG_REG_TMP);
+    }
+}
+
+/* mov alias implemented with add immediate, useful to move to/from SP */
+static inline void tcg_out_movr_sp(TCGContext *s, int ext, TCGReg rd, TCGReg rn)
+{
+    /* using ADD 0x11000000 | (ext) | rn << 5 | rd */
+    unsigned int base = ext ? 0x91000000 : 0x11000000;
+    tcg_out32(s, base | rn << 5 | rd);
+}
+
+static inline void tcg_out_mov(TCGContext *s,
+                               TCGType type, TCGReg ret, TCGReg arg)
+{
+    if (ret != arg) {
+        tcg_out_movr(s, type == TCG_TYPE_I64, ret, arg);
+    }
+}
+
+static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
+                              TCGReg arg1, tcg_target_long arg2)
+{
+    tcg_out_ldst(s, (type == TCG_TYPE_I64) ? LDST_64 : LDST_32, LDST_LD,
+                 arg, arg1, arg2);
+}
+
+static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
+                              TCGReg arg1, tcg_target_long arg2)
+{
+    tcg_out_ldst(s, (type == TCG_TYPE_I64) ? LDST_64 : LDST_32, LDST_ST,
+                 arg, arg1, arg2);
+}
+
+static inline void tcg_out_arith(TCGContext *s, enum aarch64_arith_opc opc,
+                                 int ext, TCGReg rd, TCGReg rn, TCGReg rm)
+{
+    /* Using shifted register arithmetic operations */
+    /* if extended registry operation (64bit) just OR with 0x80 << 24 */
+    unsigned int base = ext ? (0x80 | opc) << 24 : opc << 24;
+    tcg_out32(s, base | rm << 16 | rn << 5 | rd);
+}
+
+static inline void tcg_out_mul(TCGContext *s, int ext,
+                               TCGReg rd, TCGReg rn, TCGReg rm)
+{
+    /* Using MADD 0x1b000000 with Ra = wzr alias MUL 0x1b007c00 */
+    unsigned int base = ext ? 0x9b007c00 : 0x1b007c00;
+    tcg_out32(s, base | rm << 16 | rn << 5 | rd);
+}
+
+static inline void tcg_out_shiftrot_reg(TCGContext *s,
+                                        enum aarch64_srr_opc opc, int ext,
+                                        TCGReg rd, TCGReg rn, TCGReg rm)
+{
+    /* using 2-source data processing instructions 0x1ac02000 */
+    unsigned int base = ext ? 0x9ac02000 : 0x1ac02000;
+    tcg_out32(s, base | rm << 16 | opc << 8 | rn << 5 | rd);
+}
+
+static inline void tcg_out_ubfm(TCGContext *s, int ext, TCGReg rd, TCGReg rn,
+                                unsigned int a, unsigned int b)
+{
+    /* Using UBFM 0x53000000 Wd, Wn, a, b */
+    unsigned int base = ext ? 0xd3400000 : 0x53000000;
+    tcg_out32(s, base | a << 16 | b << 10 | rn << 5 | rd);
+}
+
+static inline void tcg_out_sbfm(TCGContext *s, int ext, TCGReg rd, TCGReg rn,
+                                unsigned int a, unsigned int b)
+{
+    /* Using SBFM 0x13000000 Wd, Wn, a, b */
+    unsigned int base = ext ? 0x93400000 : 0x13000000;
+    tcg_out32(s, base | a << 16 | b << 10 | rn << 5 | rd);
+}
+
+static inline void tcg_out_extr(TCGContext *s, int ext, TCGReg rd,
+                                TCGReg rn, TCGReg rm, unsigned int a)
+{
+    /* Using EXTR 0x13800000 Wd, Wn, Wm, a */
+    unsigned int base = ext ? 0x93c00000 : 0x13800000;
+    tcg_out32(s, base | rm << 16 | a << 10 | rn << 5 | rd);
+}
+
+static inline void tcg_out_shl(TCGContext *s, int ext,
+                               TCGReg rd, TCGReg rn, unsigned int m)
+{
+    int bits, max;
+    bits = ext ? 64 : 32;
+    max = bits - 1;
+    tcg_out_ubfm(s, ext, rd, rn, bits - (m & max), max - (m & max));
+}
+
+static inline void tcg_out_shr(TCGContext *s, int ext,
+                               TCGReg rd, TCGReg rn, unsigned int m)
+{
+    int max = ext ? 63 : 31;
+    tcg_out_ubfm(s, ext, rd, rn, m & max, max);
+}
+
+static inline void tcg_out_sar(TCGContext *s, int ext,
+                               TCGReg rd, TCGReg rn, unsigned int m)
+{
+    int max = ext ? 63 : 31;
+    tcg_out_sbfm(s, ext, rd, rn, m & max, max);
+}
+
+static inline void tcg_out_rotr(TCGContext *s, int ext,
+                                TCGReg rd, TCGReg rn, unsigned int m)
+{
+    int max = ext ? 63 : 31;
+    tcg_out_extr(s, ext, rd, rn, rn, m & max);
+}
+
+static inline void tcg_out_rotl(TCGContext *s, int ext,
+                                TCGReg rd, TCGReg rn, unsigned int m)
+{
+    int bits, max;
+    bits = ext ? 64 : 32;
+    max = bits - 1;
+    tcg_out_extr(s, ext, rd, rn, rn, bits - (m & max));
+}
+
+static inline void tcg_out_cmp(TCGContext *s, int ext, TCGReg rn, TCGReg rm)
+{
+    /* Using CMP alias SUBS wzr, Wn, Wm */
+    unsigned int base = ext ? 0xeb00001f : 0x6b00001f;
+    tcg_out32(s, base | rm << 16 | rn << 5);
+}
+
+static inline void tcg_out_cset(TCGContext *s, int ext, TCGReg rd, TCGCond c)
+{
+    /* Using CSET alias of CSINC 0x1a800400 Xd, XZR, XZR, invert(cond) */
+    unsigned int base = ext ? 0x9a9f07e0 : 0x1a9f07e0;
+    tcg_out32(s, base | tcg_cond_to_aarch64[tcg_invert_cond(c)] << 12 | rd);
+}
+
+static inline void tcg_out_goto(TCGContext *s, tcg_target_long target)
+{
+    tcg_target_long offset;
+    offset = (target - (tcg_target_long)s->code_ptr) / 4;
+
+    if (offset < -0x02000000 || offset >= 0x02000000) {
+        /* out of 26bit range */
+        tcg_abort();
+    }
+
+    tcg_out32(s, 0x14000000 | (offset & 0x03ffffff));
+}
+
+static inline void tcg_out_goto_noaddr(TCGContext *s)
+{
+    /* We pay attention here to not modify the branch target by
+       reading from the buffer. This ensure that caches and memory are
+       kept coherent during retranslation.
+       Mask away possible garbage in the high bits for the first translation,
+       while keeping the offset bits for retranslation. */
+    uint32_t insn;
+    insn = (tcg_in32(s) & 0x03ffffff) | 0x14000000;
+    tcg_out32(s, insn);
+}
+
+static inline void tcg_out_goto_cond_noaddr(TCGContext *s, TCGCond c)
+{
+    /* see comments in tcg_out_goto_noaddr */
+    uint32_t insn;
+    insn = tcg_in32(s) & (0x07ffff << 5);
+    insn |= 0x54000000 | tcg_cond_to_aarch64[c];
+    tcg_out32(s, insn);
+}
+
+static inline void tcg_out_goto_cond(TCGContext *s, TCGCond c,
+                                     tcg_target_long target)
+{
+    tcg_target_long offset;
+    offset = (target - (tcg_target_long)s->code_ptr) / 4;
+
+    if (offset < -0x40000 || offset >= 0x40000) {
+        /* out of 19bit range */
+        tcg_abort();
+    }
+
+    offset &= 0x7ffff;
+    tcg_out32(s, 0x54000000 | tcg_cond_to_aarch64[c] | offset << 5);
+}
+
+static inline void tcg_out_callr(TCGContext *s, TCGReg reg)
+{
+    tcg_out32(s, 0xd63f0000 | reg << 5);
+}
+
+static inline void tcg_out_gotor(TCGContext *s, TCGReg reg)
+{
+    tcg_out32(s, 0xd61f0000 | reg << 5);
+}
+
+static inline void tcg_out_call(TCGContext *s, tcg_target_long target)
+{
+    tcg_target_long offset;
+
+    offset = (target - (tcg_target_long)s->code_ptr) / 4;
+
+    if (offset < -0x02000000 || offset >= 0x02000000) { /* out of 26bit rng */
+        tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, target);
+        tcg_out_callr(s, TCG_REG_TMP);
+    } else {
+        tcg_out32(s, 0x94000000 | (offset & 0x03ffffff));
+    }
+}
+
+static inline void tcg_out_ret(TCGContext *s)
+{
+    /* emit RET { LR } */
+    tcg_out32(s, 0xd65f03c0);
+}
+
+void aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
+{
+    tcg_target_long target, offset;
+    target = (tcg_target_long)addr;
+    offset = (target - (tcg_target_long)jmp_addr) / 4;
+
+    if (offset < -0x02000000 || offset >= 0x02000000) {
+        /* out of 26bit range */
+        tcg_abort();
+    }
+
+    patch_reloc((uint8_t *)jmp_addr, R_AARCH64_JUMP26, target, 0);
+    flush_icache_range(jmp_addr, jmp_addr + 4);
+}
+
+static inline void tcg_out_goto_label(TCGContext *s, int label_index)
+{
+    TCGLabel *l = &s->labels[label_index];
+
+    if (!l->has_value) {
+        tcg_out_reloc(s, s->code_ptr, R_AARCH64_JUMP26, label_index, 0);
+        tcg_out_goto_noaddr(s);
+    } else {
+        tcg_out_goto(s, l->u.value);
+    }
+}
+
+static inline void tcg_out_goto_label_cond(TCGContext *s,
+                                           TCGCond c, int label_index)
+{
+    TCGLabel *l = &s->labels[label_index];
+
+    if (!l->has_value) {
+        tcg_out_reloc(s, s->code_ptr, R_AARCH64_CONDBR19, label_index, 0);
+        tcg_out_goto_cond_noaddr(s, c);
+    } else {
+        tcg_out_goto_cond(s, c, l->u.value);
+    }
+}
+
+#ifdef CONFIG_SOFTMMU
+#include "exec/softmmu_defs.h"
+
+/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
+   int mmu_idx) */
+static const void * const qemu_ld_helpers[4] = {
+    helper_ldb_mmu,
+    helper_ldw_mmu,
+    helper_ldl_mmu,
+    helper_ldq_mmu,
+};
+
+/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
+   uintxx_t val, int mmu_idx) */
+static const void * const qemu_st_helpers[4] = {
+    helper_stb_mmu,
+    helper_stw_mmu,
+    helper_stl_mmu,
+    helper_stq_mmu,
+};
+
+#endif /* CONFIG_SOFTMMU */
+
+static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
+{
+    TCGReg addr_reg, data_reg;
+#ifdef CONFIG_SOFTMMU
+    int mem_index, s_bits;
+#endif
+    data_reg = args[0];
+    addr_reg = args[1];
+
+#ifdef CONFIG_SOFTMMU
+    mem_index = args[2];
+    s_bits = opc & 3;
+
+    /* TODO: insert TLB lookup here */
+
+    /* all arguments passed via registers */
+    tcg_out_movr(s, 1, TCG_REG_X0, TCG_AREG0);
+    tcg_out_movr(s, (TARGET_LONG_BITS == 64), TCG_REG_X1, addr_reg);
+    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X2, mem_index);
+    tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP,
+                 (tcg_target_long)qemu_ld_helpers[s_bits]);
+    tcg_out_callr(s, TCG_REG_TMP);
+
+    if (opc & 0x04) { /* sign extend */
+        unsigned int bits = 8 * (1 << s_bits) - 1;
+        tcg_out_sbfm(s, 1, data_reg, TCG_REG_X0, 0, bits); /* 7|15|31 */
+    } else {
+        tcg_out_movr(s, 1, data_reg, TCG_REG_X0);
+    }
+
+#else /* !CONFIG_SOFTMMU */
+    tcg_abort(); /* TODO */
+#endif
+}
+
+static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
+{
+    TCGReg addr_reg, data_reg;
+#ifdef CONFIG_SOFTMMU
+    int mem_index, s_bits;
+#endif
+    data_reg = args[0];
+    addr_reg = args[1];
+
+#ifdef CONFIG_SOFTMMU
+    mem_index = args[2];
+    s_bits = opc & 3;
+
+    /* TODO: insert TLB lookup here */
+
+    /* all arguments passed via registers */
+    tcg_out_movr(s, 1, TCG_REG_X0, TCG_AREG0);
+    tcg_out_movr(s, (TARGET_LONG_BITS == 64), TCG_REG_X1, addr_reg);
+    tcg_out_movr(s, 1, TCG_REG_X2, data_reg);
+    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X3, mem_index);
+    tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP,
+                 (tcg_target_long)qemu_st_helpers[s_bits]);
+    tcg_out_callr(s, TCG_REG_TMP);
+
+#else /* !CONFIG_SOFTMMU */
+    tcg_abort(); /* TODO */
+#endif
+}
+
+static uint8_t *tb_ret_addr;
+
+/* callee stack use example:
+   stp     x29, x30, [sp,#-32]!
+   mov     x29, sp
+   stp     x1, x2, [sp,#16]
+   ...
+   ldp     x1, x2, [sp,#16]
+   ldp     x29, x30, [sp],#32
+   ret
+*/
+
+/* push r1 and r2, and alloc stack space for a total of
+   alloc_n elements (1 element=16 bytes, must be between 1 and 31. */
+static inline void tcg_out_push_pair(TCGContext *s, TCGReg addr,
+                                     TCGReg r1, TCGReg r2, int alloc_n)
+{
+    /* using indexed scaled simm7 STP 0x28800000 | (ext) | 0x01000000 (pre-idx)
+       | alloc_n * (-1) << 16 | r2 << 10 | addr << 5 | r1 */
+    assert(alloc_n > 0 && alloc_n < 0x20);
+    alloc_n = (-alloc_n) & 0x3f;
+    tcg_out32(s, 0xa9800000 | alloc_n << 16 | r2 << 10 | addr << 5 | r1);
+}
+
+/* dealloc stack space for a total of alloc_n elements and pop r1, r2.  */
+static inline void tcg_out_pop_pair(TCGContext *s, TCGReg addr,
+                                    TCGReg r1, TCGReg r2, int alloc_n)
+{
+    /* using indexed scaled simm7 LDP 0x28c00000 | (ext) | nothing (post-idx)
+       | alloc_n << 16 | r2 << 10 | addr << 5 | r1 */
+    assert(alloc_n > 0 && alloc_n < 0x20);
+    tcg_out32(s, 0xa8c00000 | alloc_n << 16 | r2 << 10 | addr << 5 | r1);
+}
+
+static inline void tcg_out_store_pair(TCGContext *s, TCGReg addr,
+                                      TCGReg r1, TCGReg r2, int idx)
+{
+    /* using register pair offset simm7 STP 0x29000000 | (ext)
+       | idx << 16 | r2 << 10 | addr << 5 | r1 */
+    assert(idx > 0 && idx < 0x20);
+    tcg_out32(s, 0xa9000000 | idx << 16 | r2 << 10 | addr << 5 | r1);
+}
+
+static inline void tcg_out_load_pair(TCGContext *s, TCGReg addr,
+                                     TCGReg r1, TCGReg r2, int idx)
+{
+    /* using register pair offset simm7 LDP 0x29400000 | (ext)
+       | idx << 16 | r2 << 10 | addr << 5 | r1 */
+    assert(idx > 0 && idx < 0x20);
+    tcg_out32(s, 0xa9400000 | idx << 16 | r2 << 10 | addr << 5 | r1);
+}
+
+static void tcg_out_op(TCGContext *s, TCGOpcode opc,
+                       const TCGArg *args, const int *const_args)
+{
+    /* ext will be set in the switch below, which will fall through to the
+       common code. It triggers the use of extended regs where appropriate. */
+    int ext = 0;
+
+    switch (opc) {
+    case INDEX_op_exit_tb:
+        tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X0, args[0]);
+        tcg_out_goto(s, (tcg_target_long)tb_ret_addr);
+        break;
+
+    case INDEX_op_goto_tb:
+#ifndef USE_DIRECT_JUMP
+#error "USE_DIRECT_JUMP required for aarch64"
+#endif
+        assert(s->tb_jmp_offset != NULL); /* consistency for USE_DIRECT_JUMP */
+        s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
+        /* actual branch destination will be patched by
+           aarch64_tb_set_jmp_target later, beware retranslation. */
+        tcg_out_goto_noaddr(s);
+        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
+        break;
+
+    case INDEX_op_call:
+        if (const_args[0]) {
+            tcg_out_call(s, args[0]);
+        } else {
+            tcg_out_callr(s, args[0]);
+        }
+        break;
+
+    case INDEX_op_br:
+        tcg_out_goto_label(s, args[0]);
+        break;
+
+    case INDEX_op_ld_i32:
+    case INDEX_op_ld_i64:
+    case INDEX_op_st_i32:
+    case INDEX_op_st_i64:
+    case INDEX_op_ld8u_i32:
+    case INDEX_op_ld8s_i32:
+    case INDEX_op_ld16u_i32:
+    case INDEX_op_ld16s_i32:
+    case INDEX_op_ld8u_i64:
+    case INDEX_op_ld8s_i64:
+    case INDEX_op_ld16u_i64:
+    case INDEX_op_ld16s_i64:
+    case INDEX_op_ld32u_i64:
+    case INDEX_op_ld32s_i64:
+    case INDEX_op_st8_i32:
+    case INDEX_op_st8_i64:
+    case INDEX_op_st16_i32:
+    case INDEX_op_st16_i64:
+    case INDEX_op_st32_i64:
+        tcg_out_ldst(s, aarch64_ldst_get_data(opc), aarch64_ldst_get_type(opc),
+                     args[0], args[1], args[2]);
+        break;
+
+    case INDEX_op_mov_i64:
+        ext = 1; /* fall through */
+    case INDEX_op_mov_i32:
+        tcg_out_movr(s, ext, args[0], args[1]);
+        break;
+
+    case INDEX_op_movi_i64:
+        tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
+        break;
+    case INDEX_op_movi_i32:
+        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
+        break;
+
+    case INDEX_op_add_i64:
+        ext = 1; /* fall through */
+    case INDEX_op_add_i32:
+        tcg_out_arith(s, ARITH_ADD, ext, args[0], args[1], args[2]);
+        break;
+
+    case INDEX_op_sub_i64:
+        ext = 1; /* fall through */
+    case INDEX_op_sub_i32:
+        tcg_out_arith(s, ARITH_SUB, ext, args[0], args[1], args[2]);
+        break;
+
+    case INDEX_op_and_i64:
+        ext = 1; /* fall through */
+    case INDEX_op_and_i32:
+        tcg_out_arith(s, ARITH_AND, ext, args[0], args[1], args[2]);
+        break;
+
+    case INDEX_op_or_i64:
+        ext = 1; /* fall through */
+    case INDEX_op_or_i32:
+        tcg_out_arith(s, ARITH_OR, ext, args[0], args[1], args[2]);
+        break;
+
+    case INDEX_op_xor_i64:
+        ext = 1; /* fall through */
+    case INDEX_op_xor_i32:
+        tcg_out_arith(s, ARITH_XOR, ext, args[0], args[1], args[2]);
+        break;
+
+    case INDEX_op_mul_i64:
+        ext = 1; /* fall through */
+    case INDEX_op_mul_i32:
+        tcg_out_mul(s, ext, args[0], args[1], args[2]);
+        break;
+
+    case INDEX_op_shl_i64:
+        ext = 1; /* fall through */
+    case INDEX_op_shl_i32:
+        if (const_args[2]) {    /* LSL / UBFM Wd, Wn, (32 - m) */
+            tcg_out_shl(s, ext, args[0], args[1], args[2]);
+        } else {                /* LSL / LSLV */
+            tcg_out_shiftrot_reg(s, SRR_SHL, ext, args[0], args[1], args[2]);
+        }
+        break;
+
+    case INDEX_op_shr_i64:
+        ext = 1; /* fall through */
+    case INDEX_op_shr_i32:
+        if (const_args[2]) {    /* LSR / UBFM Wd, Wn, m, 31 */
+            tcg_out_shr(s, ext, args[0], args[1], args[2]);
+        } else {                /* LSR / LSRV */
+            tcg_out_shiftrot_reg(s, SRR_SHR, ext, args[0], args[1], args[2]);
+        }
+        break;
+
+    case INDEX_op_sar_i64:
+        ext = 1; /* fall through */
+    case INDEX_op_sar_i32:
+        if (const_args[2]) {    /* ASR / SBFM Wd, Wn, m, 31 */
+            tcg_out_sar(s, ext, args[0], args[1], args[2]);
+        } else {                /* ASR / ASRV */
+            tcg_out_shiftrot_reg(s, SRR_SAR, ext, args[0], args[1], args[2]);
+        }
+        break;
+
+    case INDEX_op_rotr_i64:
+        ext = 1; /* fall through */
+    case INDEX_op_rotr_i32:
+        if (const_args[2]) {    /* ROR / EXTR Wd, Wm, Wm, m */
+            tcg_out_rotr(s, ext, args[0], args[1], args[2]);
+        } else {                /* ROR / RORV */
+            tcg_out_shiftrot_reg(s, SRR_ROR, ext, args[0], args[1], args[2]);
+        }
+        break;
+
+    case INDEX_op_rotl_i64:
+        ext = 1; /* fall through */
+    case INDEX_op_rotl_i32:     /* same as rotate right by (32 - m) */
+        if (const_args[2]) {    /* ROR / EXTR Wd, Wm, Wm, 32 - m */
+            tcg_out_rotl(s, ext, args[0], args[1], args[2]);
+        } else {
+            tcg_out_arith(s, ARITH_SUB, 0, TCG_REG_TMP, TCG_REG_XZR, args[2]);
+            tcg_out_shiftrot_reg(s, SRR_ROR, ext,
+                                 args[0], args[1], TCG_REG_TMP);
+        }
+        break;
+
+    case INDEX_op_brcond_i64:
+        ext = 1; /* fall through */
+    case INDEX_op_brcond_i32: /* CMP 0, 1, cond(2), label 3 */
+        tcg_out_cmp(s, ext, args[0], args[1]);
+        tcg_out_goto_label_cond(s, args[2], args[3]);
+        break;
+
+    case INDEX_op_setcond_i64:
+        ext = 1; /* fall through */
+    case INDEX_op_setcond_i32:
+        tcg_out_cmp(s, ext, args[1], args[2]);
+        tcg_out_cset(s, 0, args[0], args[3]);
+        break;
+
+    case INDEX_op_qemu_ld8u:
+        tcg_out_qemu_ld(s, args, 0 | 0);
+        break;
+    case INDEX_op_qemu_ld8s:
+        tcg_out_qemu_ld(s, args, 4 | 0);
+        break;
+    case INDEX_op_qemu_ld16u:
+        tcg_out_qemu_ld(s, args, 0 | 1);
+        break;
+    case INDEX_op_qemu_ld16s:
+        tcg_out_qemu_ld(s, args, 4 | 1);
+        break;
+    case INDEX_op_qemu_ld32u:
+        tcg_out_qemu_ld(s, args, 0 | 2);
+        break;
+    case INDEX_op_qemu_ld32s:
+        tcg_out_qemu_ld(s, args, 4 | 2);
+        break;
+    case INDEX_op_qemu_ld32:
+        tcg_out_qemu_ld(s, args, 0 | 2);
+        break;
+    case INDEX_op_qemu_ld64:
+        tcg_out_qemu_ld(s, args, 0 | 3);
+        break;
+    case INDEX_op_qemu_st8:
+        tcg_out_qemu_st(s, args, 0);
+        break;
+    case INDEX_op_qemu_st16:
+        tcg_out_qemu_st(s, args, 1);
+        break;
+    case INDEX_op_qemu_st32:
+        tcg_out_qemu_st(s, args, 2);
+        break;
+    case INDEX_op_qemu_st64:
+        tcg_out_qemu_st(s, args, 3);
+        break;
+
+    default:
+        tcg_abort(); /* opcode not implemented */
+    }
+}
+
+static const TCGTargetOpDef aarch64_op_defs[] = {
+    { INDEX_op_exit_tb, { } },
+    { INDEX_op_goto_tb, { } },
+    { INDEX_op_call, { "ri" } },
+    { INDEX_op_br, { } },
+
+    { INDEX_op_mov_i32, { "r", "r" } },
+    { INDEX_op_mov_i64, { "r", "r" } },
+
+    { INDEX_op_movi_i32, { "r" } },
+    { INDEX_op_movi_i64, { "r" } },
+
+    { INDEX_op_ld8u_i32, { "r", "r" } },
+    { INDEX_op_ld8s_i32, { "r", "r" } },
+    { INDEX_op_ld16u_i32, { "r", "r" } },
+    { INDEX_op_ld16s_i32, { "r", "r" } },
+    { INDEX_op_ld_i32, { "r", "r" } },
+    { INDEX_op_ld8u_i64, { "r", "r" } },
+    { INDEX_op_ld8s_i64, { "r", "r" } },
+    { INDEX_op_ld16u_i64, { "r", "r" } },
+    { INDEX_op_ld16s_i64, { "r", "r" } },
+    { INDEX_op_ld32u_i64, { "r", "r" } },
+    { INDEX_op_ld32s_i64, { "r", "r" } },
+    { INDEX_op_ld_i64, { "r", "r" } },
+
+    { INDEX_op_st8_i32, { "r", "r" } },
+    { INDEX_op_st16_i32, { "r", "r" } },
+    { INDEX_op_st_i32, { "r", "r" } },
+    { INDEX_op_st8_i64, { "r", "r" } },
+    { INDEX_op_st16_i64, { "r", "r" } },
+    { INDEX_op_st32_i64, { "r", "r" } },
+    { INDEX_op_st_i64, { "r", "r" } },
+
+    { INDEX_op_add_i32, { "r", "r", "r" } },
+    { INDEX_op_add_i64, { "r", "r", "r" } },
+    { INDEX_op_sub_i32, { "r", "r", "r" } },
+    { INDEX_op_sub_i64, { "r", "r", "r" } },
+    { INDEX_op_mul_i32, { "r", "r", "r" } },
+    { INDEX_op_mul_i64, { "r", "r", "r" } },
+    { INDEX_op_and_i32, { "r", "r", "r" } },
+    { INDEX_op_and_i64, { "r", "r", "r" } },
+    { INDEX_op_or_i32, { "r", "r", "r" } },
+    { INDEX_op_or_i64, { "r", "r", "r" } },
+    { INDEX_op_xor_i32, { "r", "r", "r" } },
+    { INDEX_op_xor_i64, { "r", "r", "r" } },
+
+    { INDEX_op_shl_i32, { "r", "r", "ri" } },
+    { INDEX_op_shr_i32, { "r", "r", "ri" } },
+    { INDEX_op_sar_i32, { "r", "r", "ri" } },
+    { INDEX_op_rotl_i32, { "r", "r", "ri" } },
+    { INDEX_op_rotr_i32, { "r", "r", "ri" } },
+    { INDEX_op_shl_i64, { "r", "r", "ri" } },
+    { INDEX_op_shr_i64, { "r", "r", "ri" } },
+    { INDEX_op_sar_i64, { "r", "r", "ri" } },
+    { INDEX_op_rotl_i64, { "r", "r", "ri" } },
+    { INDEX_op_rotr_i64, { "r", "r", "ri" } },
+
+    { INDEX_op_brcond_i32, { "r", "r" } },
+    { INDEX_op_setcond_i32, { "r", "r", "r" } },
+    { INDEX_op_brcond_i64, { "r", "r" } },
+    { INDEX_op_setcond_i64, { "r", "r", "r" } },
+
+    { INDEX_op_qemu_ld8u, { "r", "l" } },
+    { INDEX_op_qemu_ld8s, { "r", "l" } },
+    { INDEX_op_qemu_ld16u, { "r", "l" } },
+    { INDEX_op_qemu_ld16s, { "r", "l" } },
+    { INDEX_op_qemu_ld32u, { "r", "l" } },
+    { INDEX_op_qemu_ld32s, { "r", "l" } },
+
+    { INDEX_op_qemu_ld32, { "r", "l" } },
+    { INDEX_op_qemu_ld64, { "r", "l" } },
+
+    { INDEX_op_qemu_st8, { "l", "l" } },
+    { INDEX_op_qemu_st16, { "l", "l" } },
+    { INDEX_op_qemu_st32, { "l", "l" } },
+    { INDEX_op_qemu_st64, { "l", "l" } },
+    { -1 },
+};
+
+static void tcg_target_init(TCGContext *s)
+{
+#if !defined(CONFIG_USER_ONLY)
+    /* fail safe */
+    if ((1ULL << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry)) {
+        tcg_abort();
+    }
+#endif
+    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
+    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
+
+    tcg_regset_set32(tcg_target_call_clobber_regs, 0,
+                     (1 << TCG_REG_X0) | (1 << TCG_REG_X1) |
+                     (1 << TCG_REG_X2) | (1 << TCG_REG_X3) |
+                     (1 << TCG_REG_X4) | (1 << TCG_REG_X5) |
+                     (1 << TCG_REG_X6) | (1 << TCG_REG_X7) |
+                     (1 << TCG_REG_X8) | (1 << TCG_REG_X9) |
+                     (1 << TCG_REG_X10) | (1 << TCG_REG_X11) |
+                     (1 << TCG_REG_X12) | (1 << TCG_REG_X13) |
+                     (1 << TCG_REG_X14) | (1 << TCG_REG_X15) |
+                     (1 << TCG_REG_X16) | (1 << TCG_REG_X17) |
+                     (1 << TCG_REG_X18));
+
+    tcg_regset_clear(s->reserved_regs);
+    tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);
+    tcg_regset_set_reg(s->reserved_regs, TCG_REG_FP);
+    tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP);
+    tcg_regset_set_reg(s->reserved_regs, TCG_REG_X18); /* platform register */
+
+    tcg_add_target_add_op_defs(aarch64_op_defs);
+}
+
+static inline void tcg_out_addi(TCGContext *s, int ext,
+                                TCGReg rd, TCGReg rn, unsigned int aimm)
+{
+    /* add immediate aimm unsigned 12bit value (we use LSL 0 - no shift) */
+    /* using ADD 0x11000000 | (ext) | (aimm << 10) | (rn << 5) | rd */
+    unsigned int base = ext ? 0x91000000 : 0x11000000;
+    assert(aimm <= 0xfff);
+    tcg_out32(s, base | (aimm << 10) | (rn << 5) | rd);
+}
+
+static inline void tcg_out_subi(TCGContext *s, int ext,
+                                TCGReg rd, TCGReg rn, unsigned int aimm)
+{
+    /* sub immediate aimm unsigned 12bit value (we use LSL 0 - no shift) */
+    /* using SUB 0x51000000 | (ext) | (aimm << 10) | (rn << 5) | rd */
+    unsigned int base = ext ? 0xd1000000 : 0x51000000;
+    assert(aimm <= 0xfff);
+    tcg_out32(s, base | (aimm << 10) | (rn << 5) | rd);
+}
+
+static void tcg_target_qemu_prologue(TCGContext *s)
+{
+    /* NB: frame sizes are in 16 byte stack units! */
+    int frame_size_callee_saved, frame_size_tcg_locals;
+    TCGReg r;
+
+    /* save pairs             (FP, LR) and (X19, X20) .. (X27, X28) */
+    frame_size_callee_saved = (1) + (TCG_REG_X28 - TCG_REG_X19) / 2 + 1;
+
+    /* frame size requirement for TCG local variables */
+    frame_size_tcg_locals = TCG_STATIC_CALL_ARGS_SIZE
+        + CPU_TEMP_BUF_NLONGS * sizeof(long)
+        + (TCG_TARGET_STACK_ALIGN - 1);
+    frame_size_tcg_locals &= ~(TCG_TARGET_STACK_ALIGN - 1);
+    frame_size_tcg_locals /= TCG_TARGET_STACK_ALIGN;
+
+    /* push (FP, LR) and update sp */
+    tcg_out_push_pair(s, TCG_REG_SP,
+                      TCG_REG_FP, TCG_REG_LR, frame_size_callee_saved);
+
+    /* FP -> callee_saved */
+    tcg_out_movr_sp(s, 1, TCG_REG_FP, TCG_REG_SP);
+
+    /* store callee-preserved regs x19..x28 using FP -> callee_saved */
+    for (r = TCG_REG_X19; r <= TCG_REG_X27; r += 2) {
+        int idx = (r - TCG_REG_X19) / 2 + 1;
+        tcg_out_store_pair(s, TCG_REG_FP, r, r + 1, idx);
+    }
+
+    /* make stack space for TCG locals */
+    tcg_out_subi(s, 1, TCG_REG_SP, TCG_REG_SP,
+                 frame_size_tcg_locals * TCG_TARGET_STACK_ALIGN);
+    /* inform TCG about how to find TCG locals with register, offset, size */
+    tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE,
+                  CPU_TEMP_BUF_NLONGS * sizeof(long));
+
+    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+    tcg_out_gotor(s, tcg_target_call_iarg_regs[1]);
+
+    tb_ret_addr = s->code_ptr;
+
+    /* remove TCG locals stack space */
+    tcg_out_addi(s, 1, TCG_REG_SP, TCG_REG_SP,
+                 frame_size_tcg_locals * TCG_TARGET_STACK_ALIGN);
+
+    /* restore registers x19..x28.
+       FP must be preserved, so it still points to callee_saved area */
+    for (r = TCG_REG_X19; r <= TCG_REG_X27; r += 2) {
+        int idx = (r - TCG_REG_X19) / 2 + 1;
+        tcg_out_load_pair(s, TCG_REG_FP, r, r + 1, idx);
+    }
+
+    /* pop (FP, LR), restore SP to previous frame, return */
+    tcg_out_pop_pair(s, TCG_REG_SP,
+                     TCG_REG_FP, TCG_REG_LR, frame_size_callee_saved);
+    tcg_out_ret(s);
+}
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
new file mode 100644
index 0000000..075ab2a
--- /dev/null
+++ b/tcg/aarch64/tcg-target.h
@@ -0,0 +1,99 @@
+/*
+ * Initial TCG Implementation for aarch64
+ *
+ * Copyright (c) 2013 Huawei Technologies Duesseldorf GmbH
+ * Written by Claudio Fontana
+ *
+ * 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 for details.
+ */
+
+#ifndef TCG_TARGET_AARCH64
+#define TCG_TARGET_AARCH64 1
+
+#undef TCG_TARGET_WORDS_BIGENDIAN
+#undef TCG_TARGET_STACK_GROWSUP
+
+typedef enum {
+    TCG_REG_X0, TCG_REG_X1, TCG_REG_X2, TCG_REG_X3, TCG_REG_X4,
+    TCG_REG_X5, TCG_REG_X6, TCG_REG_X7, TCG_REG_X8, TCG_REG_X9,
+    TCG_REG_X10, TCG_REG_X11, TCG_REG_X12, TCG_REG_X13, TCG_REG_X14,
+    TCG_REG_X15, TCG_REG_X16, TCG_REG_X17, TCG_REG_X18, TCG_REG_X19,
+    TCG_REG_X20, TCG_REG_X21, TCG_REG_X22, TCG_REG_X23, TCG_REG_X24,
+    TCG_REG_X25, TCG_REG_X26, TCG_REG_X27, TCG_REG_X28,
+    TCG_REG_FP,  /* frame pointer */
+    TCG_REG_LR, /* link register */
+    TCG_REG_SP,  /* stack pointer or zero register */
+    TCG_REG_XZR = TCG_REG_SP /* same register number */
+    /* program counter is not directly accessible! */
+} TCGReg;
+
+#define TCG_TARGET_NB_REGS 32
+
+/* used for function call generation */
+#define TCG_REG_CALL_STACK              TCG_REG_SP
+#define TCG_TARGET_STACK_ALIGN          16
+#define TCG_TARGET_CALL_ALIGN_ARGS      1
+#define TCG_TARGET_CALL_STACK_OFFSET    0
+
+/* optional instructions */
+#define TCG_TARGET_HAS_div_i32          0
+#define TCG_TARGET_HAS_ext8s_i32        0
+#define TCG_TARGET_HAS_ext16s_i32       0
+#define TCG_TARGET_HAS_ext8u_i32        0
+#define TCG_TARGET_HAS_ext16u_i32       0
+#define TCG_TARGET_HAS_bswap16_i32      0
+#define TCG_TARGET_HAS_bswap32_i32      0
+#define TCG_TARGET_HAS_not_i32          0
+#define TCG_TARGET_HAS_neg_i32          0
+#define TCG_TARGET_HAS_rot_i32          1
+#define TCG_TARGET_HAS_andc_i32         0
+#define TCG_TARGET_HAS_orc_i32          0
+#define TCG_TARGET_HAS_eqv_i32          0
+#define TCG_TARGET_HAS_nand_i32         0
+#define TCG_TARGET_HAS_nor_i32          0
+#define TCG_TARGET_HAS_deposit_i32      0
+#define TCG_TARGET_HAS_movcond_i32      0
+#define TCG_TARGET_HAS_add2_i32         0
+#define TCG_TARGET_HAS_sub2_i32         0
+#define TCG_TARGET_HAS_mulu2_i32        0
+#define TCG_TARGET_HAS_muls2_i32        0
+
+#define TCG_TARGET_HAS_div_i64          0
+#define TCG_TARGET_HAS_ext8s_i64        0
+#define TCG_TARGET_HAS_ext16s_i64       0
+#define TCG_TARGET_HAS_ext32s_i64       0
+#define TCG_TARGET_HAS_ext8u_i64        0
+#define TCG_TARGET_HAS_ext16u_i64       0
+#define TCG_TARGET_HAS_ext32u_i64       0
+#define TCG_TARGET_HAS_bswap16_i64      0
+#define TCG_TARGET_HAS_bswap32_i64      0
+#define TCG_TARGET_HAS_bswap64_i64      0
+#define TCG_TARGET_HAS_not_i64          0
+#define TCG_TARGET_HAS_neg_i64          0
+#define TCG_TARGET_HAS_rot_i64          1
+#define TCG_TARGET_HAS_andc_i64         0
+#define TCG_TARGET_HAS_orc_i64          0
+#define TCG_TARGET_HAS_eqv_i64          0
+#define TCG_TARGET_HAS_nand_i64         0
+#define TCG_TARGET_HAS_nor_i64          0
+#define TCG_TARGET_HAS_deposit_i64      0
+#define TCG_TARGET_HAS_movcond_i64      0
+#define TCG_TARGET_HAS_add2_i64         0
+#define TCG_TARGET_HAS_sub2_i64         0
+#define TCG_TARGET_HAS_mulu2_i64        0
+#define TCG_TARGET_HAS_muls2_i64        0
+
+enum {
+    TCG_AREG0 = TCG_REG_X19,
+};
+
+static inline void flush_icache_range(tcg_target_ulong start,
+                                      tcg_target_ulong stop)
+{
+    __builtin___clear_cache((char *)start, (char *)stop);
+}
+
+#endif /* TCG_TARGET_AARCH64 */
diff --git a/translate-all.c b/translate-all.c
index 40b8f3d..df7c697 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -460,6 +460,8 @@ static inline PageDesc *page_find(tb_page_addr_t index)
 # define MAX_CODE_GEN_BUFFER_SIZE  (2ul * 1024 * 1024 * 1024)
 #elif defined(__sparc__)
 # define MAX_CODE_GEN_BUFFER_SIZE  (2ul * 1024 * 1024 * 1024)
+#elif defined(__aarch64__)
+# define MAX_CODE_GEN_BUFFER_SIZE  (128ul * 1024 * 1024)
 #elif defined(__arm__)
 # define MAX_CODE_GEN_BUFFER_SIZE  (16u * 1024 * 1024)
 #elif defined(__s390x__)
commit 1d256776c77c211a6f60a36e700f549f3a544cc6
Author: Claudio Fontana <claudio.fontana at huawei.com>
Date:   Wed Jun 12 16:20:22 2013 +0100

    include/elf.h: add aarch64 ELF machine and relocs
    
    we will use the 26bit relative relocs in the aarch64 tcg target.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Claudio Fontana <claudio.fontana at huawei.com>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Message-id: 51A5C52A.4080001 at huawei.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/include/elf.h b/include/elf.h
index a21ea53..cf0d3e2 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -129,6 +129,8 @@ typedef int64_t  Elf64_Sxword;
 
 #define EM_XTENSA   94      /* Tensilica Xtensa */
 
+#define EM_AARCH64  183
+
 /* This is the info that is needed to parse the dynamic section of the file */
 #define DT_NULL		0
 #define DT_NEEDED	1
@@ -616,6 +618,133 @@ typedef struct {
 /* Keep this the last entry.  */
 #define R_ARM_NUM		256
 
+/* ARM Aarch64 relocation types */
+#define R_AARCH64_NONE                256 /* also accepts R_ARM_NONE (0) */
+/* static data relocations */
+#define R_AARCH64_ABS64               257
+#define R_AARCH64_ABS32               258
+#define R_AARCH64_ABS16               259
+#define R_AARCH64_PREL64              260
+#define R_AARCH64_PREL32              261
+#define R_AARCH64_PREL16              262
+/* static aarch64 group relocations */
+/* group relocs to create unsigned data value or address inline */
+#define R_AARCH64_MOVW_UABS_G0        263
+#define R_AARCH64_MOVW_UABS_G0_NC     264
+#define R_AARCH64_MOVW_UABS_G1        265
+#define R_AARCH64_MOVW_UABS_G1_NC     266
+#define R_AARCH64_MOVW_UABS_G2        267
+#define R_AARCH64_MOVW_UABS_G2_NC     268
+#define R_AARCH64_MOVW_UABS_G3        269
+/* group relocs to create signed data or offset value inline */
+#define R_AARCH64_MOVW_SABS_G0        270
+#define R_AARCH64_MOVW_SABS_G1        271
+#define R_AARCH64_MOVW_SABS_G2        272
+/* relocs to generate 19, 21, and 33 bit PC-relative addresses */
+#define R_AARCH64_LD_PREL_LO19        273
+#define R_AARCH64_ADR_PREL_LO21       274
+#define R_AARCH64_ADR_PREL_PG_HI21    275
+#define R_AARCH64_ADR_PREL_PG_HI21_NC 276
+#define R_AARCH64_ADD_ABS_LO12_NC     277
+#define R_AARCH64_LDST8_ABS_LO12_NC   278
+#define R_AARCH64_LDST16_ABS_LO12_NC  284
+#define R_AARCH64_LDST32_ABS_LO12_NC  285
+#define R_AARCH64_LDST64_ABS_LO12_NC  286
+#define R_AARCH64_LDST128_ABS_LO12_NC 299
+/* relocs for control-flow - all offsets as multiple of 4 */
+#define R_AARCH64_TSTBR14             279
+#define R_AARCH64_CONDBR19            280
+#define R_AARCH64_JUMP26              282
+#define R_AARCH64_CALL26              283
+/* group relocs to create pc-relative offset inline */
+#define R_AARCH64_MOVW_PREL_G0        287
+#define R_AARCH64_MOVW_PREL_G0_NC     288
+#define R_AARCH64_MOVW_PREL_G1        289
+#define R_AARCH64_MOVW_PREL_G1_NC     290
+#define R_AARCH64_MOVW_PREL_G2        291
+#define R_AARCH64_MOVW_PREL_G2_NC     292
+#define R_AARCH64_MOVW_PREL_G3        293
+/* group relocs to create a GOT-relative offset inline */
+#define R_AARCH64_MOVW_GOTOFF_G0      300
+#define R_AARCH64_MOVW_GOTOFF_G0_NC   301
+#define R_AARCH64_MOVW_GOTOFF_G1      302
+#define R_AARCH64_MOVW_GOTOFF_G1_NC   303
+#define R_AARCH64_MOVW_GOTOFF_G2      304
+#define R_AARCH64_MOVW_GOTOFF_G2_NC   305
+#define R_AARCH64_MOVW_GOTOFF_G3      306
+/* GOT-relative data relocs */
+#define R_AARCH64_GOTREL64            307
+#define R_AARCH64_GOTREL32            308
+/* GOT-relative instr relocs */
+#define R_AARCH64_GOT_LD_PREL19       309
+#define R_AARCH64_LD64_GOTOFF_LO15    310
+#define R_AARCH64_ADR_GOT_PAGE        311
+#define R_AARCH64_LD64_GOT_LO12_NC    312
+#define R_AARCH64_LD64_GOTPAGE_LO15   313
+/* General Dynamic TLS relocations */
+#define R_AARCH64_TLSGD_ADR_PREL21            512
+#define R_AARCH64_TLSGD_ADR_PAGE21            513
+#define R_AARCH64_TLSGD_ADD_LO12_NC           514
+#define R_AARCH64_TLSGD_MOVW_G1               515
+#define R_AARCH64_TLSGD_MOVW_G0_NC            516
+/* Local Dynamic TLS relocations */
+#define R_AARCH64_TLSLD_ADR_PREL21            517
+#define R_AARCH64_TLSLD_ADR_PAGE21            518
+#define R_AARCH64_TLSLD_ADD_LO12_NC           519
+#define R_AARCH64_TLSLD_MOVW_G1               520
+#define R_AARCH64_TLSLD_MOVW_G0_NC            521
+#define R_AARCH64_TLSLD_LD_PREL19             522
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G2        523
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1        524
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC     525
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0        526
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC     527
+#define R_AARCH64_TLSLD_ADD_DTPREL_HI12       528
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12       529
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC    530
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12     531
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC  532
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12    533
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12    535
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12    537
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538
+/* initial exec TLS relocations */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1      539
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC   540
+#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21   541
+#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542
+#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19    543
+/* local exec TLS relocations */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G2         544
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1         545
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC      546
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0         547
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC      548
+#define R_AARCH64_TLSLE_ADD_TPREL_HI12        549
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12        550
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC     551
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12      552
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC   553
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12     554
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC  555
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12     556
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC  557
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12     558
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC  559
+/* Dynamic Relocations */
+#define R_AARCH64_COPY         1024
+#define R_AARCH64_GLOB_DAT     1025
+#define R_AARCH64_JUMP_SLOT    1026
+#define R_AARCH64_RELATIVE     1027
+#define R_AARCH64_TLS_DTPREL64 1028
+#define R_AARCH64_TLS_DTPMOD64 1029
+#define R_AARCH64_TLS_TPREL64  1030
+#define R_AARCH64_TLS_DTPREL32 1031
+#define R_AARCH64_TLS_DTPMOD32 1032
+#define R_AARCH64_TLS_TPREL32  1033
+
 /* s390 relocations defined by the ABIs */
 #define R_390_NONE		0	/* No reloc.  */
 #define R_390_8			1	/* Direct 8 bit.  */
commit 66926895433a56b657f79d14f371831cf79fd43e
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Wed Jun 12 16:20:22 2013 +0100

    configure: Drop CONFIG_ATFILE test
    
    Nobody uses the CONFIG_ATFILE test now, so just drop it.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Tested-by: Claudio Fontana <claudio.fontana at huawei.com>
    Message-id: 1370126121-22975-3-git-send-email-peter.maydell at linaro.org

diff --git a/configure b/configure
index 1654413..bb413be 100755
--- a/configure
+++ b/configure
@@ -2557,29 +2557,6 @@ EOF
   fi
 fi
 
-#
-# Check for xxxat() functions when we are building linux-user
-# emulator.  This is done because older glibc versions don't
-# have syscall stubs for these implemented.
-#
-atfile=no
-cat > $TMPC << EOF
-#define _ATFILE_SOURCE
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-int
-main(void)
-{
-	/* try to unlink nonexisting file */
-	return (unlinkat(AT_FDCWD, "nonexistent_file", 0));
-}
-EOF
-if compile_prog "" "" ; then
-  atfile=yes
-fi
-
 # Check for inotify functions when we are building linux-user
 # emulator.  This is done because older glibc versions don't
 # have syscall stubs for these implemented.  In that case we
@@ -3722,9 +3699,6 @@ fi
 if test "$curses" = "yes" ; then
   echo "CONFIG_CURSES=y" >> $config_host_mak
 fi
-if test "$atfile" = "yes" ; then
-  echo "CONFIG_ATFILE=y" >> $config_host_mak
-fi
 if test "$utimens" = "yes" ; then
   echo "CONFIG_UTIMENSAT=y" >> $config_host_mak
 fi
commit c0d472b12e8c5ba81c69b28a1088ff52a59933f2
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Wed Jun 12 16:20:21 2013 +0100

    linux-user: Drop direct use of openat etc syscalls
    
    The linux-user syscall emulation layer currently supports the
    openat family of syscalls via two mechanisms: simply calling
    the corresponding libc functions, and making direct syscalls.
    Since glibc has supported these functions since at least glibc
    2.5, there's no real need to retain the (essentially untested)
    direct syscall fallback code, so simply delete it. This allows
    us to remove some ifdeffery that was attempting to disable
    provision of some of the syscalls if the host didn't seem to
    support them, which in some cases was actually wrong (eg where
    there are several flavours of the syscall and we only need
    one of them, not necessarily the exact one the guest has,
    as with the fstatat* calls).
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Tested-by: Claudio Fontana <claudio.fontana at huawei.com>
    Message-id: 1370126121-22975-2-git-send-email-peter.maydell at linaro.org

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 4151c78..cdd0c28 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -181,29 +181,14 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,	\
 
 
 #define __NR_sys_uname __NR_uname
-#define __NR_sys_faccessat __NR_faccessat
-#define __NR_sys_fchmodat __NR_fchmodat
-#define __NR_sys_fchownat __NR_fchownat
-#define __NR_sys_fstatat64 __NR_fstatat64
-#define __NR_sys_futimesat __NR_futimesat
 #define __NR_sys_getcwd1 __NR_getcwd
 #define __NR_sys_getdents __NR_getdents
 #define __NR_sys_getdents64 __NR_getdents64
 #define __NR_sys_getpriority __NR_getpriority
-#define __NR_sys_linkat __NR_linkat
-#define __NR_sys_mkdirat __NR_mkdirat
-#define __NR_sys_mknodat __NR_mknodat
-#define __NR_sys_newfstatat __NR_newfstatat
-#define __NR_sys_openat __NR_openat
-#define __NR_sys_readlinkat __NR_readlinkat
-#define __NR_sys_renameat __NR_renameat
 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
-#define __NR_sys_symlinkat __NR_symlinkat
 #define __NR_sys_syslog __NR_syslog
 #define __NR_sys_tgkill __NR_tgkill
 #define __NR_sys_tkill __NR_tkill
-#define __NR_sys_unlinkat __NR_unlinkat
-#define __NR_sys_utimensat __NR_utimensat
 #define __NR_sys_futex __NR_futex
 #define __NR_sys_inotify_init __NR_inotify_init
 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
@@ -339,72 +324,6 @@ static int sys_getcwd1(char *buf, size_t size)
   return strlen(buf)+1;
 }
 
-#ifdef CONFIG_ATFILE
-/*
- * Host system seems to have atfile syscall stubs available.  We
- * now enable them one by one as specified by target syscall_nr.h.
- */
-
-#ifdef TARGET_NR_faccessat
-static int sys_faccessat(int dirfd, const char *pathname, int mode)
-{
-  return (faccessat(dirfd, pathname, mode, 0));
-}
-#endif
-#ifdef TARGET_NR_fchmodat
-static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
-{
-  return (fchmodat(dirfd, pathname, mode, 0));
-}
-#endif
-#if defined(TARGET_NR_fchownat)
-static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
-    gid_t group, int flags)
-{
-  return (fchownat(dirfd, pathname, owner, group, flags));
-}
-#endif
-#ifdef __NR_fstatat64
-static int sys_fstatat64(int dirfd, const char *pathname, struct stat *buf,
-    int flags)
-{
-  return (fstatat(dirfd, pathname, buf, flags));
-}
-#endif
-#ifdef __NR_newfstatat
-static int sys_newfstatat(int dirfd, const char *pathname, struct stat *buf,
-    int flags)
-{
-  return (fstatat(dirfd, pathname, buf, flags));
-}
-#endif
-#ifdef TARGET_NR_futimesat
-static int sys_futimesat(int dirfd, const char *pathname,
-    const struct timeval times[2])
-{
-  return (futimesat(dirfd, pathname, times));
-}
-#endif
-#ifdef TARGET_NR_linkat
-static int sys_linkat(int olddirfd, const char *oldpath,
-    int newdirfd, const char *newpath, int flags)
-{
-  return (linkat(olddirfd, oldpath, newdirfd, newpath, flags));
-}
-#endif
-#ifdef TARGET_NR_mkdirat
-static int sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
-{
-  return (mkdirat(dirfd, pathname, mode));
-}
-#endif
-#ifdef TARGET_NR_mknodat
-static int sys_mknodat(int dirfd, const char *pathname, mode_t mode,
-    dev_t dev)
-{
-  return (mknodat(dirfd, pathname, mode, dev));
-}
-#endif
 #ifdef TARGET_NR_openat
 static int sys_openat(int dirfd, const char *pathname, int flags, mode_t mode)
 {
@@ -418,91 +337,6 @@ static int sys_openat(int dirfd, const char *pathname, int flags, mode_t mode)
   return (openat(dirfd, pathname, flags));
 }
 #endif
-#ifdef TARGET_NR_readlinkat
-static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
-{
-  return (readlinkat(dirfd, pathname, buf, bufsiz));
-}
-#endif
-#ifdef TARGET_NR_renameat
-static int sys_renameat(int olddirfd, const char *oldpath,
-    int newdirfd, const char *newpath)
-{
-  return (renameat(olddirfd, oldpath, newdirfd, newpath));
-}
-#endif
-#ifdef TARGET_NR_symlinkat
-static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
-{
-  return (symlinkat(oldpath, newdirfd, newpath));
-}
-#endif
-#ifdef TARGET_NR_unlinkat
-static int sys_unlinkat(int dirfd, const char *pathname, int flags)
-{
-  return (unlinkat(dirfd, pathname, flags));
-}
-#endif
-#else /* !CONFIG_ATFILE */
-
-/*
- * Try direct syscalls instead
- */
-#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
-_syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode)
-#endif
-#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
-_syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
-#endif
-#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
-_syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
-          uid_t,owner,gid_t,group,int,flags)
-#endif
-#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
-        defined(__NR_fstatat64)
-_syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
-          struct stat *,buf,int,flags)
-#endif
-#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
-_syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
-         const struct timeval *,times)
-#endif
-#if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
-        defined(__NR_newfstatat)
-_syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
-          struct stat *,buf,int,flags)
-#endif
-#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
-_syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
-      int,newdirfd,const char *,newpath,int,flags)
-#endif
-#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
-_syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
-#endif
-#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
-_syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
-          mode_t,mode,dev_t,dev)
-#endif
-#if defined(TARGET_NR_openat) && defined(__NR_openat)
-_syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
-#endif
-#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
-_syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
-          char *,buf,size_t,bufsize)
-#endif
-#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
-_syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
-          int,newdirfd,const char *,newpath)
-#endif
-#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
-_syscall3(int,sys_symlinkat,const char *,oldpath,
-          int,newdirfd,const char *,newpath)
-#endif
-#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
-_syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
-#endif
-
-#endif /* CONFIG_ATFILE */
 
 #ifdef CONFIG_UTIMENSAT
 static int sys_utimensat(int dirfd, const char *pathname,
@@ -5345,7 +5179,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             unlock_user(p, arg1, 0);
         }
         break;
-#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
+#if defined(TARGET_NR_linkat)
     case TARGET_NR_linkat:
         {
             void * p2 = NULL;
@@ -5356,7 +5190,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             if (!p || !p2)
                 ret = -TARGET_EFAULT;
             else
-                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
+                ret = get_errno(linkat(arg1, p, arg3, p2, arg5));
             unlock_user(p, arg2, 0);
             unlock_user(p2, arg4, 0);
         }
@@ -5368,11 +5202,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(unlink(p));
         unlock_user(p, arg1, 0);
         break;
-#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
+#if defined(TARGET_NR_unlinkat)
     case TARGET_NR_unlinkat:
         if (!(p = lock_user_string(arg2)))
             goto efault;
-        ret = get_errno(sys_unlinkat(arg1, p, arg3));
+        ret = get_errno(unlinkat(arg1, p, arg3));
         unlock_user(p, arg2, 0);
         break;
 #endif
@@ -5490,11 +5324,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(mknod(p, arg2, arg3));
         unlock_user(p, arg1, 0);
         break;
-#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
+#if defined(TARGET_NR_mknodat)
     case TARGET_NR_mknodat:
         if (!(p = lock_user_string(arg2)))
             goto efault;
-        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
+        ret = get_errno(mknodat(arg1, p, arg3, arg4));
         unlock_user(p, arg2, 0);
         break;
 #endif
@@ -5625,7 +5459,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             unlock_user(p, arg1, 0);
         }
         break;
-#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
+#if defined(TARGET_NR_futimesat)
     case TARGET_NR_futimesat:
         {
             struct timeval *tvp, tv[2];
@@ -5640,7 +5474,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             }
             if (!(p = lock_user_string(arg2)))
                 goto efault;
-            ret = get_errno(sys_futimesat(arg1, path(p), tvp));
+            ret = get_errno(futimesat(arg1, path(p), tvp));
             unlock_user(p, arg2, 0);
         }
         break;
@@ -5663,7 +5497,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_faccessat:
         if (!(p = lock_user_string(arg2)))
             goto efault;
-        ret = get_errno(sys_faccessat(arg1, p, arg3));
+        ret = get_errno(faccessat(arg1, p, arg3, 0));
         unlock_user(p, arg2, 0);
         break;
 #endif
@@ -5696,7 +5530,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             unlock_user(p, arg1, 0);
         }
         break;
-#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
+#if defined(TARGET_NR_renameat)
     case TARGET_NR_renameat:
         {
             void *p2;
@@ -5705,7 +5539,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             if (!p || !p2)
                 ret = -TARGET_EFAULT;
             else
-                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
+                ret = get_errno(renameat(arg1, p, arg3, p2));
             unlock_user(p2, arg4, 0);
             unlock_user(p, arg2, 0);
         }
@@ -5717,11 +5551,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(mkdir(p, arg2));
         unlock_user(p, arg1, 0);
         break;
-#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
+#if defined(TARGET_NR_mkdirat)
     case TARGET_NR_mkdirat:
         if (!(p = lock_user_string(arg2)))
             goto efault;
-        ret = get_errno(sys_mkdirat(arg1, p, arg3));
+        ret = get_errno(mkdirat(arg1, p, arg3));
         unlock_user(p, arg2, 0);
         break;
 #endif
@@ -6407,7 +6241,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             unlock_user(p, arg1, 0);
         }
         break;
-#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
+#if defined(TARGET_NR_symlinkat)
     case TARGET_NR_symlinkat:
         {
             void *p2;
@@ -6416,7 +6250,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             if (!p || !p2)
                 ret = -TARGET_EFAULT;
             else
-                ret = get_errno(sys_symlinkat(p, arg2, p2));
+                ret = get_errno(symlinkat(p, arg2, p2));
             unlock_user(p2, arg3, 0);
             unlock_user(p, arg1, 0);
         }
@@ -6447,7 +6281,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             unlock_user(p, arg1, 0);
         }
         break;
-#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
+#if defined(TARGET_NR_readlinkat)
     case TARGET_NR_readlinkat:
         {
             void *p2;
@@ -6456,7 +6290,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             if (!p || !p2)
         	ret = -TARGET_EFAULT;
             else
-                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
+                ret = get_errno(readlinkat(arg1, path(p), p2, arg4));
             unlock_user(p2, arg3, ret);
             unlock_user(p, arg2, 0);
         }
@@ -6591,11 +6425,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_fchmod:
         ret = get_errno(fchmod(arg1, arg2));
         break;
-#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
+#if defined(TARGET_NR_fchmodat)
     case TARGET_NR_fchmodat:
         if (!(p = lock_user_string(arg2)))
             goto efault;
-        ret = get_errno(sys_fchmodat(arg1, p, arg3));
+        ret = get_errno(fchmodat(arg1, p, arg3, 0));
         unlock_user(p, arg2, 0);
         break;
 #endif
@@ -7739,8 +7573,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             ret = host_to_target_stat64(cpu_env, arg2, &st);
         break;
 #endif
-#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
-        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
+#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat))
 #ifdef TARGET_NR_fstatat64
     case TARGET_NR_fstatat64:
 #endif
@@ -7749,11 +7582,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
         if (!(p = lock_user_string(arg2)))
             goto efault;
-#ifdef __NR_fstatat64
-        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
-#else
-        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
-#endif
+        ret = get_errno(fstatat(arg1, path(p), &st, arg4));
         if (!is_error(ret))
             ret = host_to_target_stat64(cpu_env, arg3, &st);
         break;
@@ -7835,11 +7664,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_fchown:
         ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
         break;
-#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
+#if defined(TARGET_NR_fchownat)
     case TARGET_NR_fchownat:
         if (!(p = lock_user_string(arg2))) 
             goto efault;
-        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
+        ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
+                                 low2highgid(arg4), arg5));
         unlock_user(p, arg2, 0);
         break;
 #endif
commit 3307e2363a812e4f68d02ec3b0114a9b510702b7
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Wed Jun 12 16:20:21 2013 +0100

    linux-user: Allow getdents to be provided by getdents64
    
    Newer architectures may only implement the getdents64 syscall, not
    getdents. Provide an implementation of getdents in terms of getdents64
    so that we can run getdents-using targets on a getdents64-only host.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Tested-by: Claudio Fontana <claudio.fontana at huawei.com>
    Message-id: 1370344377-27445-1-git-send-email-peter.maydell at linaro.org
    Message-id: 1370193044-24535-1-git-send-email-peter.maydell at linaro.org

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 0099d64..4151c78 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -223,8 +223,11 @@ static int gettid(void) {
     return -ENOSYS;
 }
 #endif
+#ifdef __NR_getdents
 _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
-#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
+#endif
+#if !defined(__NR_getdents) || \
+    (defined(TARGET_NR_getdents64) && defined(__NR_getdents64))
 _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
 #endif
 #if defined(TARGET_NR__llseek) && defined(__NR_llseek)
@@ -7123,6 +7126,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
 #endif
     case TARGET_NR_getdents:
+#ifdef __NR_getdents
 #if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
         {
             struct target_dirent *target_dirp;
@@ -7195,6 +7199,61 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             unlock_user(dirp, arg2, ret);
         }
 #endif
+#else
+        /* Implement getdents in terms of getdents64 */
+        {
+            struct linux_dirent64 *dirp;
+            abi_long count = arg3;
+
+            dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
+            if (!dirp) {
+                goto efault;
+            }
+            ret = get_errno(sys_getdents64(arg1, dirp, count));
+            if (!is_error(ret)) {
+                /* Convert the dirent64 structs to target dirent.  We do this
+                 * in-place, since we can guarantee that a target_dirent is no
+                 * larger than a dirent64; however this means we have to be
+                 * careful to read everything before writing in the new format.
+                 */
+                struct linux_dirent64 *de;
+                struct target_dirent *tde;
+                int len = ret;
+                int tlen = 0;
+
+                de = dirp;
+                tde = (struct target_dirent *)dirp;
+                while (len > 0) {
+                    int namelen, treclen;
+                    int reclen = de->d_reclen;
+                    uint64_t ino = de->d_ino;
+                    int64_t off = de->d_off;
+                    uint8_t type = de->d_type;
+
+                    namelen = strlen(de->d_name);
+                    treclen = offsetof(struct target_dirent, d_name)
+                        + namelen + 2;
+                    treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
+
+                    memmove(tde->d_name, de->d_name, namelen + 1);
+                    tde->d_ino = tswapal(ino);
+                    tde->d_off = tswapal(off);
+                    tde->d_reclen = tswap16(treclen);
+                    /* The target_dirent type is in what was formerly a padding
+                     * byte at the end of the structure:
+                     */
+                    *(((char *)tde) + treclen - 1) = type;
+
+                    de = (struct linux_dirent64 *)((char *)de + reclen);
+                    tde = (struct target_dirent *)((char *)tde + treclen);
+                    len -= reclen;
+                    tlen += treclen;
+                }
+                ret = tlen;
+            }
+            unlock_user(dirp, arg2, ret);
+        }
+#endif
         break;
 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
     case TARGET_NR_getdents64:
commit 520b6dd4d03742e285cc68cca308a2a74261c410
Author: Michael Tokarev <mjt at tls.msk.ru>
Date:   Wed Jun 12 16:31:44 2013 +0400

    main-loop: do not include slirp/slirp.h, use libslirp.h instead
    
    The header slirp/slirp.h is an internal header for slirp, and
    main-loop.c does not use internals from there.  Instead, it uses
    public functions (slirp_update_timeout(), slirp_pollfds_fill()
    etc) which are declared in slirp/libslirp.h.
    
    Including slirp/slirp.h is somewhat dangerous since it redefines
    errno on WIN32, so any file including it may misbehave wrt errno.
    
    Unfortunately libslirp isn't self-contained, it needs declaration
    of struct in_addr, which is provided by qemu/sockets.h.  Maybe
    instead of #including qemu/sockets.h before libslirp.h, it is
    better to make the latter self-contained.
    
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/main-loop.c b/main-loop.c
index cf36645..a44fff6 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -24,7 +24,8 @@
 
 #include "qemu-common.h"
 #include "qemu/timer.h"
-#include "slirp/slirp.h"
+#include "qemu/sockets.h"	// struct in_addr needed for libslirp.h
+#include "slirp/libslirp.h"
 #include "qemu/main-loop.h"
 #include "block/aio.h"
 
commit 581fe784c3adf85dc167a47a4a60fd1245a98217
Author: Alon Levy <alevy at redhat.com>
Date:   Tue Jun 4 16:23:37 2013 -0400

    libcacard/vscclient: fix leakage of socket on error paths
    
    Spotted by Coverity.
    
    Signed-off-by: Alon Levy <alevy at redhat.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c
index ac23647..5180d29 100644
--- a/libcacard/vscclient.c
+++ b/libcacard/vscclient.c
@@ -618,18 +618,22 @@ connect_to_qemu(
     if (ret != 0) {
         /* Error */
         fprintf(stderr, "getaddrinfo failed\n");
-        return -1;
+        goto cleanup_socket;
     }
 
     if (connect(sock, server->ai_addr, server->ai_addrlen) < 0) {
         /* Error */
         fprintf(stderr, "Could not connect\n");
-        return -1;
+        goto cleanup_socket;
     }
     if (verbose) {
         printf("Connected (sizeof Header=%zd)!\n", sizeof(VSCMsgHeader));
     }
     return sock;
+
+cleanup_socket:
+    closesocket(sock);
+    return -1;
 }
 
 int
@@ -759,5 +763,6 @@ main(
     g_io_channel_unref(channel_socket);
     g_byte_array_unref(socket_to_send);
 
+    closesocket(sock);
     return 0;
 }
commit e098b45386a86fecc1e573d305a240a2f4aa461d
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Wed Jun 12 17:26:55 2013 +1000

    linux-headers: Update to v3.10-rc5
    
    This adds symbols required for PPC64 pseries platform features:
    1. sPAPR live migration;
    2. in-kernel XICS interrupt controller.
    
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/linux-headers/asm-arm/kvm.h b/linux-headers/asm-arm/kvm.h
index 023bfeb..c1ee007 100644
--- a/linux-headers/asm-arm/kvm.h
+++ b/linux-headers/asm-arm/kvm.h
@@ -53,12 +53,12 @@
 #define KVM_ARM_FIQ_spsr	fiq_regs[7]
 
 struct kvm_regs {
-	struct pt_regs usr_regs;/* R0_usr - R14_usr, PC, CPSR */
-	__u32 svc_regs[3];	/* SP_svc, LR_svc, SPSR_svc */
-	__u32 abt_regs[3];	/* SP_abt, LR_abt, SPSR_abt */
-	__u32 und_regs[3];	/* SP_und, LR_und, SPSR_und */
-	__u32 irq_regs[3];	/* SP_irq, LR_irq, SPSR_irq */
-	__u32 fiq_regs[8];	/* R8_fiq - R14_fiq, SPSR_fiq */
+	struct pt_regs usr_regs;	/* R0_usr - R14_usr, PC, CPSR */
+	unsigned long svc_regs[3];	/* SP_svc, LR_svc, SPSR_svc */
+	unsigned long abt_regs[3];	/* SP_abt, LR_abt, SPSR_abt */
+	unsigned long und_regs[3];	/* SP_und, LR_und, SPSR_und */
+	unsigned long irq_regs[3];	/* SP_irq, LR_irq, SPSR_irq */
+	unsigned long fiq_regs[8];	/* R8_fiq - R14_fiq, SPSR_fiq */
 };
 
 /* Supported Processor Types */
diff --git a/linux-headers/asm-mips/kvm.h b/linux-headers/asm-mips/kvm.h
new file mode 100644
index 0000000..3f424f5
--- /dev/null
+++ b/linux-headers/asm-mips/kvm.h
@@ -0,0 +1,138 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2012  MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2013 Cavium, Inc.
+ * Authors: Sanjay Lal <sanjayl at kymasys.com>
+ */
+
+#ifndef __LINUX_KVM_MIPS_H
+#define __LINUX_KVM_MIPS_H
+
+#include <linux/types.h>
+
+/*
+ * KVM MIPS specific structures and definitions.
+ *
+ * Some parts derived from the x86 version of this file.
+ */
+
+/*
+ * for KVM_GET_REGS and KVM_SET_REGS
+ *
+ * If Config[AT] is zero (32-bit CPU), the register contents are
+ * stored in the lower 32-bits of the struct kvm_regs fields and sign
+ * extended to 64-bits.
+ */
+struct kvm_regs {
+	/* out (KVM_GET_REGS) / in (KVM_SET_REGS) */
+	__u64 gpr[32];
+	__u64 hi;
+	__u64 lo;
+	__u64 pc;
+};
+
+/*
+ * for KVM_GET_FPU and KVM_SET_FPU
+ *
+ * If Status[FR] is zero (32-bit FPU), the upper 32-bits of the FPRs
+ * are zero filled.
+ */
+struct kvm_fpu {
+	__u64 fpr[32];
+	__u32 fir;
+	__u32 fccr;
+	__u32 fexr;
+	__u32 fenr;
+	__u32 fcsr;
+	__u32 pad;
+};
+
+
+/*
+ * For MIPS, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access CP0
+ * registers.  The id field is broken down as follows:
+ *
+ *  bits[2..0]   - Register 'sel' index.
+ *  bits[7..3]   - Register 'rd'  index.
+ *  bits[15..8]  - Must be zero.
+ *  bits[63..16] - 1 -> CP0 registers.
+ *
+ * Other sets registers may be added in the future.  Each set would
+ * have its own identifier in bits[63..16].
+ *
+ * The addr field of struct kvm_one_reg must point to an aligned
+ * 64-bit wide location.  For registers that are narrower than
+ * 64-bits, the value is stored in the low order bits of the location,
+ * and sign extended to 64-bits.
+ *
+ * The registers defined in struct kvm_regs are also accessible, the
+ * id values for these are below.
+ */
+
+#define KVM_REG_MIPS_R0 0
+#define KVM_REG_MIPS_R1 1
+#define KVM_REG_MIPS_R2 2
+#define KVM_REG_MIPS_R3 3
+#define KVM_REG_MIPS_R4 4
+#define KVM_REG_MIPS_R5 5
+#define KVM_REG_MIPS_R6 6
+#define KVM_REG_MIPS_R7 7
+#define KVM_REG_MIPS_R8 8
+#define KVM_REG_MIPS_R9 9
+#define KVM_REG_MIPS_R10 10
+#define KVM_REG_MIPS_R11 11
+#define KVM_REG_MIPS_R12 12
+#define KVM_REG_MIPS_R13 13
+#define KVM_REG_MIPS_R14 14
+#define KVM_REG_MIPS_R15 15
+#define KVM_REG_MIPS_R16 16
+#define KVM_REG_MIPS_R17 17
+#define KVM_REG_MIPS_R18 18
+#define KVM_REG_MIPS_R19 19
+#define KVM_REG_MIPS_R20 20
+#define KVM_REG_MIPS_R21 21
+#define KVM_REG_MIPS_R22 22
+#define KVM_REG_MIPS_R23 23
+#define KVM_REG_MIPS_R24 24
+#define KVM_REG_MIPS_R25 25
+#define KVM_REG_MIPS_R26 26
+#define KVM_REG_MIPS_R27 27
+#define KVM_REG_MIPS_R28 28
+#define KVM_REG_MIPS_R29 29
+#define KVM_REG_MIPS_R30 30
+#define KVM_REG_MIPS_R31 31
+
+#define KVM_REG_MIPS_HI 32
+#define KVM_REG_MIPS_LO 33
+#define KVM_REG_MIPS_PC 34
+
+/*
+ * KVM MIPS specific structures and definitions
+ *
+ */
+struct kvm_debug_exit_arch {
+	__u64 epc;
+};
+
+/* for KVM_SET_GUEST_DEBUG */
+struct kvm_guest_debug_arch {
+};
+
+/* definition of registers in kvm_run */
+struct kvm_sync_regs {
+};
+
+/* dummy definition */
+struct kvm_sregs {
+};
+
+struct kvm_mips_interrupt {
+	/* in */
+	__u32 cpu;
+	__u32 irq;
+};
+
+#endif /* __LINUX_KVM_MIPS_H */
diff --git a/linux-headers/asm-mips/kvm_para.h b/linux-headers/asm-mips/kvm_para.h
new file mode 100644
index 0000000..14fab8f
--- /dev/null
+++ b/linux-headers/asm-mips/kvm_para.h
@@ -0,0 +1 @@
+#include <asm-generic/kvm_para.h>
diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
index ef072b1..0fb1a6e 100644
--- a/linux-headers/asm-powerpc/kvm.h
+++ b/linux-headers/asm-powerpc/kvm.h
@@ -25,6 +25,8 @@
 /* Select powerpc specific features in <linux/kvm.h> */
 #define __KVM_HAVE_SPAPR_TCE
 #define __KVM_HAVE_PPC_SMT
+#define __KVM_HAVE_IRQCHIP
+#define __KVM_HAVE_IRQ_LINE
 
 struct kvm_regs {
 	__u64 pc;
@@ -272,8 +274,31 @@ struct kvm_debug_exit_arch {
 
 /* for KVM_SET_GUEST_DEBUG */
 struct kvm_guest_debug_arch {
+	struct {
+		/* H/W breakpoint/watchpoint address */
+		__u64 addr;
+		/*
+		 * Type denotes h/w breakpoint, read watchpoint, write
+		 * watchpoint or watchpoint (both read and write).
+		 */
+#define KVMPPC_DEBUG_NONE		0x0
+#define KVMPPC_DEBUG_BREAKPOINT		(1UL << 1)
+#define KVMPPC_DEBUG_WATCH_WRITE	(1UL << 2)
+#define KVMPPC_DEBUG_WATCH_READ		(1UL << 3)
+		__u32 type;
+		__u32 reserved;
+	} bp[16];
 };
 
+/* Debug related defines */
+/*
+ * kvm_guest_debug->control is a 32 bit field. The lower 16 bits are generic
+ * and upper 16 bits are architecture specific. Architecture specific defines
+ * that ioctl is for setting hardware breakpoint or software breakpoint.
+ */
+#define KVM_GUESTDBG_USE_SW_BP		0x00010000
+#define KVM_GUESTDBG_USE_HW_BP		0x00020000
+
 /* definition of registers in kvm_run */
 struct kvm_sync_regs {
 };
@@ -299,6 +324,12 @@ struct kvm_allocate_rma {
 	__u64 rma_size;
 };
 
+/* for KVM_CAP_PPC_RTAS */
+struct kvm_rtas_token_args {
+	char name[120];
+	__u64 token;	/* Use a token of 0 to undefine a mapping */
+};
+
 struct kvm_book3e_206_tlb_entry {
 	__u32 mas8;
 	__u32 mas1;
@@ -359,6 +390,26 @@ struct kvm_get_htab_header {
 	__u16	n_invalid;
 };
 
+/* Per-vcpu XICS interrupt controller state */
+#define KVM_REG_PPC_ICP_STATE	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8c)
+
+#define  KVM_REG_PPC_ICP_CPPR_SHIFT	56	/* current proc priority */
+#define  KVM_REG_PPC_ICP_CPPR_MASK	0xff
+#define  KVM_REG_PPC_ICP_XISR_SHIFT	32	/* interrupt status field */
+#define  KVM_REG_PPC_ICP_XISR_MASK	0xffffff
+#define  KVM_REG_PPC_ICP_MFRR_SHIFT	24	/* pending IPI priority */
+#define  KVM_REG_PPC_ICP_MFRR_MASK	0xff
+#define  KVM_REG_PPC_ICP_PPRI_SHIFT	16	/* pending irq priority */
+#define  KVM_REG_PPC_ICP_PPRI_MASK	0xff
+
+/* Device control API: PPC-specific devices */
+#define KVM_DEV_MPIC_GRP_MISC		1
+#define   KVM_DEV_MPIC_BASE_ADDR	0	/* 64-bit */
+
+#define KVM_DEV_MPIC_GRP_REGISTER	2	/* 32-bit */
+#define KVM_DEV_MPIC_GRP_IRQ_ACTIVE	3	/* 32-bit */
+
+/* One-Reg API: PPC-specific registers */
 #define KVM_REG_PPC_HIOR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x1)
 #define KVM_REG_PPC_IAC1	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x2)
 #define KVM_REG_PPC_IAC2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x3)
@@ -422,4 +473,42 @@ struct kvm_get_htab_header {
 #define KVM_REG_PPC_CLEAR_TSR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x88)
 #define KVM_REG_PPC_TCR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x89)
 #define KVM_REG_PPC_TSR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8a)
+
+/* Debugging: Special instruction for software breakpoint */
+#define KVM_REG_PPC_DEBUG_INST	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b)
+
+/* MMU registers */
+#define KVM_REG_PPC_MAS0	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8c)
+#define KVM_REG_PPC_MAS1	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8d)
+#define KVM_REG_PPC_MAS2	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8e)
+#define KVM_REG_PPC_MAS7_3	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8f)
+#define KVM_REG_PPC_MAS4	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x90)
+#define KVM_REG_PPC_MAS6	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x91)
+#define KVM_REG_PPC_MMUCFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x92)
+/*
+ * TLBnCFG fields TLBnCFG_N_ENTRY and TLBnCFG_ASSOC can be changed only using
+ * KVM_CAP_SW_TLB ioctl
+ */
+#define KVM_REG_PPC_TLB0CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x93)
+#define KVM_REG_PPC_TLB1CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94)
+#define KVM_REG_PPC_TLB2CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95)
+#define KVM_REG_PPC_TLB3CFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x96)
+#define KVM_REG_PPC_TLB0PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x97)
+#define KVM_REG_PPC_TLB1PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98)
+#define KVM_REG_PPC_TLB2PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99)
+#define KVM_REG_PPC_TLB3PS	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a)
+#define KVM_REG_PPC_EPTCFG	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9b)
+
+/* PPC64 eXternal Interrupt Controller Specification */
+#define KVM_DEV_XICS_GRP_SOURCES	1	/* 64-bit source attributes */
+
+/* Layout of 64-bit source attribute values */
+#define  KVM_XICS_DESTINATION_SHIFT	0
+#define  KVM_XICS_DESTINATION_MASK	0xffffffffULL
+#define  KVM_XICS_PRIORITY_SHIFT	32
+#define  KVM_XICS_PRIORITY_MASK		0xff
+#define  KVM_XICS_LEVEL_SENSITIVE	(1ULL << 40)
+#define  KVM_XICS_MASKED		(1ULL << 41)
+#define  KVM_XICS_PENDING		(1ULL << 42)
+
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h
index a65ec29..5d9a303 100644
--- a/linux-headers/asm-x86/kvm.h
+++ b/linux-headers/asm-x86/kvm.h
@@ -29,7 +29,6 @@
 #define __KVM_HAVE_PIT
 #define __KVM_HAVE_IOAPIC
 #define __KVM_HAVE_IRQ_LINE
-#define __KVM_HAVE_DEVICE_ASSIGNMENT
 #define __KVM_HAVE_MSI
 #define __KVM_HAVE_USER_NMI
 #define __KVM_HAVE_GUEST_DEBUG
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index eb02d8a..c614070 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -561,9 +561,7 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_MP_STATE 14
 #define KVM_CAP_COALESCED_MMIO 15
 #define KVM_CAP_SYNC_MMU 16  /* Changes to host mmap are reflected in guest */
-#ifdef __KVM_HAVE_DEVICE_ASSIGNMENT
 #define KVM_CAP_DEVICE_ASSIGNMENT 17
-#endif
 #define KVM_CAP_IOMMU 18
 #ifdef __KVM_HAVE_MSI
 #define KVM_CAP_DEVICE_MSI 20
@@ -579,13 +577,9 @@ struct kvm_ppc_smmu_info {
 #ifdef __KVM_HAVE_PIT
 #define KVM_CAP_REINJECT_CONTROL 24
 #endif
-#ifdef __KVM_HAVE_IOAPIC
 #define KVM_CAP_IRQ_ROUTING 25
-#endif
 #define KVM_CAP_IRQ_INJECT_STATUS 26
-#ifdef __KVM_HAVE_DEVICE_ASSIGNMENT
 #define KVM_CAP_DEVICE_DEASSIGNMENT 27
-#endif
 #ifdef __KVM_HAVE_MSIX
 #define KVM_CAP_DEVICE_MSIX 28
 #endif
@@ -668,6 +662,10 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_PPC_EPR 86
 #define KVM_CAP_ARM_PSCI 87
 #define KVM_CAP_ARM_SET_DEVICE_ADDR 88
+#define KVM_CAP_DEVICE_CTRL 89
+#define KVM_CAP_IRQ_MPIC 90
+#define KVM_CAP_PPC_RTAS 91
+#define KVM_CAP_IRQ_XICS 92
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -821,6 +819,28 @@ struct kvm_arm_device_addr {
 };
 
 /*
+ * Device control API, available with KVM_CAP_DEVICE_CTRL
+ */
+#define KVM_CREATE_DEVICE_TEST		1
+
+struct kvm_create_device {
+	__u32	type;	/* in: KVM_DEV_TYPE_xxx */
+	__u32	fd;	/* out: device handle */
+	__u32	flags;	/* in: KVM_CREATE_DEVICE_xxx */
+};
+
+struct kvm_device_attr {
+	__u32	flags;		/* no flags currently defined */
+	__u32	group;		/* device-defined */
+	__u64	attr;		/* group-defined */
+	__u64	addr;		/* userspace address of attr data */
+};
+
+#define KVM_DEV_TYPE_FSL_MPIC_20	1
+#define KVM_DEV_TYPE_FSL_MPIC_42	2
+#define KVM_DEV_TYPE_XICS		3
+
+/*
  * ioctls for VM fds
  */
 #define KVM_SET_MEMORY_REGION     _IOW(KVMIO,  0x40, struct kvm_memory_region)
@@ -907,6 +927,16 @@ struct kvm_s390_ucas_mapping {
 #define KVM_PPC_GET_HTAB_FD	  _IOW(KVMIO,  0xaa, struct kvm_get_htab_fd)
 /* Available with KVM_CAP_ARM_SET_DEVICE_ADDR */
 #define KVM_ARM_SET_DEVICE_ADDR	  _IOW(KVMIO,  0xab, struct kvm_arm_device_addr)
+/* Available with KVM_CAP_PPC_RTAS */
+#define KVM_PPC_RTAS_DEFINE_TOKEN _IOW(KVMIO,  0xac, struct kvm_rtas_token_args)
+
+/* ioctl for vm fd */
+#define KVM_CREATE_DEVICE	  _IOWR(KVMIO,  0xe0, struct kvm_create_device)
+
+/* ioctls for fds returned by KVM_CREATE_DEVICE */
+#define KVM_SET_DEVICE_ATTR	  _IOW(KVMIO,  0xe1, struct kvm_device_attr)
+#define KVM_GET_DEVICE_ATTR	  _IOW(KVMIO,  0xe2, struct kvm_device_attr)
+#define KVM_HAS_DEVICE_ATTR	  _IOW(KVMIO,  0xe3, struct kvm_device_attr)
 
 /*
  * ioctls for vcpu fds
diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
index e094121..7ec1864 100644
--- a/linux-headers/linux/vfio.h
+++ b/linux-headers/linux/vfio.h
@@ -319,6 +319,7 @@ enum {
 	VFIO_PCI_INTX_IRQ_INDEX,
 	VFIO_PCI_MSI_IRQ_INDEX,
 	VFIO_PCI_MSIX_IRQ_INDEX,
+	VFIO_PCI_ERR_IRQ_INDEX,
 	VFIO_PCI_NUM_IRQS
 };
 
diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
index 165a484..c656f61 100644
--- a/linux-headers/linux/vhost.h
+++ b/linux-headers/linux/vhost.h
@@ -127,4 +127,32 @@ struct vhost_memory {
 /* vhost-net should add virtio_net_hdr for RX, and strip for TX packets. */
 #define VHOST_NET_F_VIRTIO_NET_HDR 27
 
+/* VHOST_SCSI specific definitions */
+
+/*
+ * Used by QEMU userspace to ensure a consistent vhost-scsi ABI.
+ *
+ * ABI Rev 0: July 2012 version starting point for v3.6-rc merge candidate +
+ *            RFC-v2 vhost-scsi userspace.  Add GET_ABI_VERSION ioctl usage
+ * ABI Rev 1: January 2013. Ignore vhost_tpgt filed in struct vhost_scsi_target.
+ *            All the targets under vhost_wwpn can be seen and used by guset.
+ */
+
+#define VHOST_SCSI_ABI_VERSION	1
+
+struct vhost_scsi_target {
+	int abi_version;
+	char vhost_wwpn[224]; /* TRANSPORT_IQN_LEN */
+	unsigned short vhost_tpgt;
+	unsigned short reserved;
+};
+
+#define VHOST_SCSI_SET_ENDPOINT _IOW(VHOST_VIRTIO, 0x40, struct vhost_scsi_target)
+#define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct vhost_scsi_target)
+/* Changing this breaks userspace. */
+#define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, int)
+/* Set and get the events missed flag */
+#define VHOST_SCSI_SET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x43, __u32)
+#define VHOST_SCSI_GET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x44, __u32)
+
 #endif
commit 821696600402e432f6f11ec355efd23f9bc6ce4f
Author: Scott Wood <scottwood at freescale.com>
Date:   Wed Jun 12 17:26:54 2013 +1000

    KVM: PPC: Add dummy kvm_arch_init_irq_routing()
    
    The common KVM code insists on calling kvm_arch_init_irq_routing()
    as soon as it sees kernel header support for it (regardless of whether
    QEMU supports it).  Provide a dummy function to satisfy this.
    
    Unlike x86, PPC does not have one default irqchip, so there's no common
    code that we'd stick here.  Even if you ignore the routes themselves,
    which even on x86 are not set up in this function, the initial XICS
    kernel implementation will not support IRQ routing, so it's best to
    leave even the general feature flags up to the specific irqchip code.
    
    Signed-off-by: Scott Wood <scottwood at freescale.com>
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 3ab2946..2bbc3b8 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1797,3 +1797,7 @@ int kvm_arch_on_sigbus(int code, void *addr)
 {
     return 1;
 }
+
+void kvm_arch_init_irq_routing(KVMState *s)
+{
+}
commit 48475e14841f3c3a245bc4c13f9115520c89f2d7
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Wed Jun 12 17:26:53 2013 +1000

    KVM: S390: Add dummy kvm_arch_init_irq_routing()
    
    The common KVM code insists on calling kvm_arch_init_irq_routing()
    as soon as it sees kernel header support for it (regardless of whether
    QEMU supports it).  Provide a dummy function to satisfy this.
    
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 862fb12..4d9ac4a 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -928,3 +928,7 @@ void kvm_s390_enable_css_support(S390CPU *cpu)
     r = kvm_vcpu_ioctl(CPU(cpu), KVM_ENABLE_CAP, &cap);
     assert(r == 0);
 }
+
+void kvm_arch_init_irq_routing(KVMState *s)
+{
+}
commit b3a1c626fc55e1dd87166a7b837e16ff6a1b0071
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Wed Jun 12 17:26:52 2013 +1000

    KVM: ARM: Add dummy kvm_arch_init_irq_routing()
    
    The common KVM code insists on calling kvm_arch_init_irq_routing()
    as soon as it sees kernel header support for it (regardless of whether
    QEMU supports it).  Provide a dummy function to satisfy this.
    
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index b7bdc03..27dcab9 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -491,3 +491,7 @@ void kvm_arch_remove_all_hw_breakpoints(void)
 {
     qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
 }
+
+void kvm_arch_init_irq_routing(KVMState *s)
+{
+}
commit baefb8bf8e4a708c601bbab898a6039cd9cd12e3
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Mon Jun 3 10:58:31 2013 +0200

    ivshmem: add missing error exit(2)
    
    If the user fails to specify 'chardev' or 'shm' then we cannot continue.
    Exit right away so that we don't invoke shm_open(3) with a NULL pointer.
    
    It would be nice to replace exit(1) with error returns in the PCI device
    .init() function, but leave that for another patch since exit(1) is
    currently used elsewhere.
    
    Spotted by Coverity.
    
    Cc: Cam Macdonell <cam at cs.ualberta.ca>
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index a19a6d6..5658f73 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -735,6 +735,7 @@ static int pci_ivshmem_init(PCIDevice *dev)
 
         if (s->shmobj == NULL) {
             fprintf(stderr, "Must specify 'chardev' or 'shm' to ivshmem\n");
+            exit(1);
         }
 
         IVSHMEM_DPRINTF("using shm_open (shm object = %s)\n", s->shmobj);
commit c5633d998a27502ad8cc10c2d46f91b02555ae7a
Author: Stefan Weil <sw at weilnetz.de>
Date:   Mon Jun 10 22:36:22 2013 +0200

    hw/xen: Use g_free instead of free and fix potential memory leaks
    
    The wrong functions and the missing calls of g_free were reported
    by cppcheck.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Acked-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
index 01872db..8ccc2e4 100644
--- a/hw/xen/xen_pt_config_init.c
+++ b/hw/xen/xen_pt_config_init.c
@@ -1777,12 +1777,12 @@ static int xen_pt_config_reg_init(XenPCIPassthroughState *s,
         rc = reg->init(s, reg_entry->reg,
                        reg_grp->base_offset + reg->offset, &data);
         if (rc < 0) {
-            free(reg_entry);
+            g_free(reg_entry);
             return rc;
         }
         if (data == XEN_PT_INVALID_REG) {
             /* free unused BAR register entry */
-            free(reg_entry);
+            g_free(reg_entry);
             return 0;
         }
         /* set register value */
diff --git a/xen-all.c b/xen-all.c
index bc105f1..1a1d7bb 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -389,7 +389,7 @@ static int xen_remove_from_physmap(XenIOState *state,
     if (state->log_for_dirtybit == physmap) {
         state->log_for_dirtybit = NULL;
     }
-    free(physmap);
+    g_free(physmap);
 
     return 0;
 }
@@ -1030,7 +1030,7 @@ static void xen_read_physmap(XenIOState *state)
                 xen_domid, entries[i]);
         value = xs_read(state->xenstore, 0, path, &len);
         if (value == NULL) {
-            free(physmap);
+            g_free(physmap);
             continue;
         }
         physmap->start_addr = strtoull(value, NULL, 16);
@@ -1041,7 +1041,7 @@ static void xen_read_physmap(XenIOState *state)
                 xen_domid, entries[i]);
         value = xs_read(state->xenstore, 0, path, &len);
         if (value == NULL) {
-            free(physmap);
+            g_free(physmap);
             continue;
         }
         physmap->size = strtoull(value, NULL, 16);
@@ -1069,12 +1069,14 @@ int xen_hvm_init(void)
     state->xce_handle = xen_xc_evtchn_open(NULL, 0);
     if (state->xce_handle == XC_HANDLER_INITIAL_VALUE) {
         perror("xen: event channel open");
+        g_free(state);
         return -errno;
     }
 
     state->xenstore = xs_daemon_open();
     if (state->xenstore == NULL) {
         perror("xen: xenstore open");
+        g_free(state);
         return -errno;
     }
 
commit 1e2a1d41f29adc8ae3013612c5a0114a87773773
Author: Stefan Weil <sw at weilnetz.de>
Date:   Mon Jun 10 22:40:52 2013 +0200

    target-sparc: Replace free by g_free
    
    The wrong function was reported by cppcheck.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 290b580..13bb7bb 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -614,7 +614,7 @@ static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
     return 0;
 
  error:
-    free(s);
+    g_free(s);
     return -1;
 }
 
commit dcb0780990f7d579b2d6f9c67ef841a75b3a758b
Author: Stefan Weil <sw at weilnetz.de>
Date:   Mon Jun 10 22:24:56 2013 +0200

    hw/scsi: Don't increment a boolean value
    
    This fixes a warning from cppcheck.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index 48d12f4..446f723 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -389,7 +389,7 @@ pvscsi_process_completion_queue(void *opaque)
         QTAILQ_REMOVE(&s->completion_queue, pvscsi_req, next);
         pvscsi_cmp_ring_put(s, &pvscsi_req->cmp);
         g_free(pvscsi_req);
-        has_completed++;
+        has_completed = true;
     }
 
     if (has_completed) {
commit 909a196d2754388d3b15a34b688095c655792124
Author: Stefan Weil <sw at weilnetz.de>
Date:   Mon Jun 10 22:12:25 2013 +0200

    device tree: Fix cppcheck warning
    
    Fix this cppcheck warning:
    
    Checking device_tree.c...
    device_tree.c:216: style:
     Checking if unsigned variable 'r' is less than zero.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/device_tree.c b/device_tree.c
index 56af24b..69be9da 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -213,7 +213,7 @@ uint32_t qemu_devtree_get_phandle(void *fdt, const char *path)
     uint32_t r;
 
     r = fdt_get_phandle(fdt, findnode_nofail(fdt, path));
-    if (r <= 0) {
+    if (r == 0) {
         fprintf(stderr, "%s: Couldn't get phandle for %s: %s\n", __func__,
                 path, fdt_strerror(r));
         exit(1);
commit 8a3e8f7fd8144343f6c83e810b988c1e8a99d50a
Author: Andreas Färber <afaerber at suse.de>
Date:   Tue Jun 11 13:13:58 2013 +0200

    Makefile: Install qemu-img and qemu-nbd man pages only if built
    
    When splitting openSUSE's qemu and qemu-linux-user packages we noticed
    that for linux-user-only builds unrelated man pages got installed.
    It's surely possible to delete them before packaging, but not installing
    them in the first place seems more logical.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/Makefile b/Makefile
index 306e7bd..3cfa7d0 100644
--- a/Makefile
+++ b/Makefile
@@ -306,10 +306,13 @@ install-doc: $(DOCS)
 	$(INSTALL_DATA) QMP/qmp-commands.txt "$(DESTDIR)$(qemu_docdir)"
 ifdef CONFIG_POSIX
 	$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
-	$(INSTALL_DATA) qemu.1 qemu-img.1 "$(DESTDIR)$(mandir)/man1"
+	$(INSTALL_DATA) qemu.1 "$(DESTDIR)$(mandir)/man1"
+ifneq ($(TOOLS),)
+	$(INSTALL_DATA) qemu-img.1 "$(DESTDIR)$(mandir)/man1"
 	$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man8"
 	$(INSTALL_DATA) qemu-nbd.8 "$(DESTDIR)$(mandir)/man8"
 endif
+endif
 ifdef CONFIG_VIRTFS
 	$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
 	$(INSTALL_DATA) fsdev/virtfs-proxy-helper.1 "$(DESTDIR)$(mandir)/man1"
commit 047d4e151dd462915786a4fddc12f774d0028af5
Author: Peter Wu <lekensteyn at gmail.com>
Date:   Tue Jun 11 10:55:08 2013 +0200

    Unbreak -no-quit for GTK, validate SDL options
    
    Certain options (-no-frame, -alt-grab, -ctrl-grab) only make sense with SDL.
    When compiling without SDL, these options (and -no-quit) print an error message
    and exit qemu.
    
    In case QEMU is compiled with SDL support, the three aforementioned options
    still do not make sense with other display types. This patch addresses that
    issue by printing a warning. I have chosen not to exit QEMU afterwards because
    having the option is not harmful and before this patch it would be ignored
    anyway.
    
    By delaying the sanity check from compile-time with some ifdefs to run-time,
    -no-quit is now also properly supported when compiling without SDL.
    
    Signed-off-by: Peter Wu <lekensteyn at gmail.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/vl.c b/vl.c
index 169c807..9f8fd6e 100644
--- a/vl.c
+++ b/vl.c
@@ -3524,7 +3524,6 @@ int main(int argc, char **argv, char **envp)
             case QEMU_OPTION_full_screen:
                 full_screen = 1;
                 break;
-#ifdef CONFIG_SDL
             case QEMU_OPTION_no_frame:
                 no_frame = 1;
                 break;
@@ -3537,14 +3536,11 @@ int main(int argc, char **argv, char **envp)
             case QEMU_OPTION_no_quit:
                 no_quit = 1;
                 break;
+#ifdef CONFIG_SDL
             case QEMU_OPTION_sdl:
                 display_type = DT_SDL;
                 break;
 #else
-            case QEMU_OPTION_no_frame:
-            case QEMU_OPTION_alt_grab:
-            case QEMU_OPTION_ctrl_grab:
-            case QEMU_OPTION_no_quit:
             case QEMU_OPTION_sdl:
                 fprintf(stderr, "SDL support is disabled\n");
                 exit(1);
@@ -4085,6 +4081,15 @@ int main(int argc, char **argv, char **envp)
 #endif
     }
 
+    if ((no_frame || alt_grab || ctrl_grab) && display_type != DT_SDL) {
+        fprintf(stderr, "-no-frame, -alt-grab and -ctrl-grab are only valid "
+                        "for SDL, ignoring option\n");
+    }
+    if (no_quit && (display_type != DT_GTK && display_type != DT_SDL)) {
+        fprintf(stderr, "-no-quit is only valid for GTK and SDL, "
+                        "ignoring option\n");
+    }
+
 #if defined(CONFIG_GTK)
     if (display_type == DT_GTK) {
         early_gtk_display_init();
commit 787ba4f026f54d4fc7787078b896f9c5432c9a9b
Author: Peter Wu <lekensteyn at gmail.com>
Date:   Mon Jun 10 20:04:43 2013 +0200

    gtk: implement -full-screen
    
    Aiming for GTK as replacement for SDL, a feature like -full-screen should also
    be implemented.
    
    Bringing the window into full-screen mode is done by activating the "Fullscreen"
    menu item. This is done after showing the windows to make the cursor and menu
    hidden.
    
    v2: drop -no-frame implementation, use booleans instead of ints and ensure
        consistency between ui state and menu.
    
    Signed-off-by: Peter Wu <lekensteyn at gmail.com>
    Reviewed-by: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/include/ui/console.h b/include/ui/console.h
index 4307b5f..f1d79f9 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -339,6 +339,6 @@ int index_from_keycode(int code);
 
 /* gtk.c */
 void early_gtk_display_init(void);
-void gtk_display_init(DisplayState *ds);
+void gtk_display_init(DisplayState *ds, bool full_screen);
 
 #endif
diff --git a/ui/gtk.c b/ui/gtk.c
index 63f6081..e314dba 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1435,7 +1435,7 @@ static const DisplayChangeListenerOps dcl_ops = {
     .dpy_cursor_define = gd_cursor_define,
 };
 
-void gtk_display_init(DisplayState *ds)
+void gtk_display_init(DisplayState *ds, bool full_screen)
 {
     GtkDisplayState *s = g_malloc0(sizeof(*s));
     char *filename;
@@ -1511,6 +1511,10 @@ void gtk_display_init(DisplayState *ds)
 
     gtk_widget_show_all(s->window);
 
+    if (full_screen) {
+        gtk_menu_item_activate(GTK_MENU_ITEM(s->full_screen_item));
+    }
+
     register_displaychangelistener(&s->dcl);
 
     global_state = s;
diff --git a/vl.c b/vl.c
index 180fdde..169c807 100644
--- a/vl.c
+++ b/vl.c
@@ -4348,7 +4348,7 @@ int main(int argc, char **argv, char **envp)
 #endif
 #if defined(CONFIG_GTK)
     case DT_GTK:
-        gtk_display_init(ds);
+        gtk_display_init(ds, full_screen);
         break;
 #endif
     default:
commit b5601df7624b461759651c49ac72a189951780b9
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 15:14:48 2013 +1000

    char/serial: serial_ioport_write: Factor out common code
    
    These three lines are common to both FIFO and regular mode. Just factor
    them out to outside the if rather than replicate the same lines inside
    both if and else.
    
    Cc: qemu-trivial at nongnu.org
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/char/serial.c b/hw/char/serial.c
index 0a2b6c9..017610e 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -285,15 +285,11 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
                     fifo8_pop(&s->xmit_fifo);
                 }
                 fifo8_push(&s->xmit_fifo, s->thr);
-                s->thr_ipending = 0;
                 s->lsr &= ~UART_LSR_TEMT;
-                s->lsr &= ~UART_LSR_THRE;
-                serial_update_irq(s);
-            } else {
-                s->thr_ipending = 0;
-                s->lsr &= ~UART_LSR_THRE;
-                serial_update_irq(s);
             }
+            s->thr_ipending = 0;
+            s->lsr &= ~UART_LSR_THRE;
+            serial_update_irq(s);
             serial_xmit(NULL, G_IO_OUT, s);
         }
         break;
commit 8e8638fa87ff045f5dadec7342301bf10de776ff
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 15:13:27 2013 +1000

    char/serial: Use generic Fifo8
    
    Use the generic Fifo8 helper provided by QEMU, rather than re-implement
    privately.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/char/serial.c b/hw/char/serial.c
index bd6813e..0a2b6c9 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -92,8 +92,6 @@
 #define UART_FCR_RFR        0x02    /* RCVR Fifo Reset */
 #define UART_FCR_FE         0x01    /* FIFO Enable */
 
-#define XMIT_FIFO           0
-#define RECV_FIFO           1
 #define MAX_XMIT_RETRY      4
 
 #ifdef DEBUG_SERIAL
@@ -106,50 +104,14 @@ do {} while (0)
 
 static void serial_receive1(void *opaque, const uint8_t *buf, int size);
 
-static void fifo_clear(SerialState *s, int fifo)
+static inline void recv_fifo_put(SerialState *s, uint8_t chr)
 {
-    SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
-    memset(f->data, 0, UART_FIFO_LENGTH);
-    f->count = 0;
-    f->head = 0;
-    f->tail = 0;
-}
-
-static int fifo_put(SerialState *s, int fifo, uint8_t chr)
-{
-    SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
-
     /* Receive overruns do not overwrite FIFO contents. */
-    if (fifo == XMIT_FIFO || f->count < UART_FIFO_LENGTH) {
-
-        f->data[f->head++] = chr;
-
-        if (f->head == UART_FIFO_LENGTH)
-            f->head = 0;
-    }
-
-    if (f->count < UART_FIFO_LENGTH)
-        f->count++;
-    else if (fifo == RECV_FIFO)
+    if (!fifo8_is_full(&s->recv_fifo)) {
+        fifo8_push(&s->recv_fifo, chr);
+    } else {
         s->lsr |= UART_LSR_OE;
-
-    return 1;
-}
-
-static uint8_t fifo_get(SerialState *s, int fifo)
-{
-    SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
-    uint8_t c;
-
-    if(f->count == 0)
-        return 0;
-
-    c = f->data[f->tail++];
-    if (f->tail == UART_FIFO_LENGTH)
-        f->tail = 0;
-    f->count--;
-
-    return c;
+    }
 }
 
 static void serial_update_irq(SerialState *s)
@@ -165,7 +127,7 @@ static void serial_update_irq(SerialState *s)
         tmp_iir = UART_IIR_CTI;
     } else if ((s->ier & UART_IER_RDI) && (s->lsr & UART_LSR_DR) &&
                (!(s->fcr & UART_FCR_FE) ||
-                s->recv_fifo.count >= s->recv_fifo.itl)) {
+                s->recv_fifo.num >= s->recv_fifo_itl)) {
         tmp_iir = UART_IIR_RDI;
     } else if ((s->ier & UART_IER_THRI) && s->thr_ipending) {
         tmp_iir = UART_IIR_THRI;
@@ -262,8 +224,9 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque)
 
     if (s->tsr_retry <= 0) {
         if (s->fcr & UART_FCR_FE) {
-            s->tsr = fifo_get(s,XMIT_FIFO);
-            if (!s->xmit_fifo.count) {
+            s->tsr = fifo8_is_full(&s->xmit_fifo) ?
+                        0 : fifo8_pop(&s->xmit_fifo);
+            if (!s->xmit_fifo.num) {
                 s->lsr |= UART_LSR_THRE;
             }
         } else if ((s->lsr & UART_LSR_THRE)) {
@@ -317,7 +280,11 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
         } else {
             s->thr = (uint8_t) val;
             if(s->fcr & UART_FCR_FE) {
-                fifo_put(s, XMIT_FIFO, s->thr);
+                /* xmit overruns overwrite data, so make space if needed */
+                if (fifo8_is_full(&s->xmit_fifo)) {
+                    fifo8_pop(&s->xmit_fifo);
+                }
+                fifo8_push(&s->xmit_fifo, s->thr);
                 s->thr_ipending = 0;
                 s->lsr &= ~UART_LSR_TEMT;
                 s->lsr &= ~UART_LSR_THRE;
@@ -368,28 +335,28 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
         if (val & UART_FCR_RFR) {
             qemu_del_timer(s->fifo_timeout_timer);
             s->timeout_ipending=0;
-            fifo_clear(s,RECV_FIFO);
+            fifo8_reset(&s->recv_fifo);
         }
 
         if (val & UART_FCR_XFR) {
-            fifo_clear(s,XMIT_FIFO);
+            fifo8_reset(&s->xmit_fifo);
         }
 
         if (val & UART_FCR_FE) {
             s->iir |= UART_IIR_FE;
-            /* Set RECV_FIFO trigger Level */
+            /* Set recv_fifo trigger Level */
             switch (val & 0xC0) {
             case UART_FCR_ITL_1:
-                s->recv_fifo.itl = 1;
+                s->recv_fifo_itl = 1;
                 break;
             case UART_FCR_ITL_2:
-                s->recv_fifo.itl = 4;
+                s->recv_fifo_itl = 4;
                 break;
             case UART_FCR_ITL_3:
-                s->recv_fifo.itl = 8;
+                s->recv_fifo_itl = 8;
                 break;
             case UART_FCR_ITL_4:
-                s->recv_fifo.itl = 14;
+                s->recv_fifo_itl = 14;
                 break;
             }
         } else
@@ -461,8 +428,9 @@ static uint64_t serial_ioport_read(void *opaque, hwaddr addr, unsigned size)
             ret = s->divider & 0xff;
         } else {
             if(s->fcr & UART_FCR_FE) {
-                ret = fifo_get(s,RECV_FIFO);
-                if (s->recv_fifo.count == 0) {
+                ret = fifo8_is_full(&s->recv_fifo) ?
+                            0 : fifo8_pop(&s->recv_fifo);
+                if (s->recv_fifo.num == 0) {
                     s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
                 } else {
                     qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock_ns (vm_clock) + s->char_transmit_time * 4);
@@ -536,7 +504,7 @@ static uint64_t serial_ioport_read(void *opaque, hwaddr addr, unsigned size)
 static int serial_can_receive(SerialState *s)
 {
     if(s->fcr & UART_FCR_FE) {
-        if (s->recv_fifo.count < UART_FIFO_LENGTH) {
+        if (s->recv_fifo.num < UART_FIFO_LENGTH) {
             /*
              * Advertise (fifo.itl - fifo.count) bytes when count < ITL, and 1
              * if above. If UART_FIFO_LENGTH - fifo.count is advertised the
@@ -544,8 +512,8 @@ static int serial_can_receive(SerialState *s)
              * the guest has a chance to respond, effectively overriding the ITL
              * that the guest has set.
              */
-            return (s->recv_fifo.count <= s->recv_fifo.itl) ?
-                        s->recv_fifo.itl - s->recv_fifo.count : 1;
+            return (s->recv_fifo.num <= s->recv_fifo_itl) ?
+                        s->recv_fifo_itl - s->recv_fifo.num : 1;
         } else {
             return 0;
         }
@@ -558,7 +526,7 @@ static void serial_receive_break(SerialState *s)
 {
     s->rbr = 0;
     /* When the LSR_DR is set a null byte is pushed into the fifo */
-    fifo_put(s, RECV_FIFO, '\0');
+    recv_fifo_put(s, '\0');
     s->lsr |= UART_LSR_BI | UART_LSR_DR;
     serial_update_irq(s);
 }
@@ -566,7 +534,7 @@ static void serial_receive_break(SerialState *s)
 /* There's data in recv_fifo and s->rbr has not been read for 4 char transmit times */
 static void fifo_timeout_int (void *opaque) {
     SerialState *s = opaque;
-    if (s->recv_fifo.count) {
+    if (s->recv_fifo.num) {
         s->timeout_ipending = 1;
         serial_update_irq(s);
     }
@@ -588,7 +556,7 @@ static void serial_receive1(void *opaque, const uint8_t *buf, int size)
     if(s->fcr & UART_FCR_FE) {
         int i;
         for (i = 0; i < size; i++) {
-            fifo_put(s, RECV_FIFO, buf[i]);
+            recv_fifo_put(s, buf[i]);
         }
         s->lsr |= UART_LSR_DR;
         /* call the timeout receive callback in 4 char transmit time */
@@ -668,8 +636,8 @@ static void serial_reset(void *opaque)
     s->char_transmit_time = (get_ticks_per_sec() / 9600) * 10;
     s->poll_msl = 0;
 
-    fifo_clear(s,RECV_FIFO);
-    fifo_clear(s,XMIT_FIFO);
+    fifo8_reset(&s->recv_fifo);
+    fifo8_reset(&s->xmit_fifo);
 
     s->last_xmit_ts = qemu_get_clock_ns(vm_clock);
 
@@ -692,6 +660,8 @@ void serial_init_core(SerialState *s)
 
     qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
                           serial_event, s);
+    fifo8_create(&s->recv_fifo, UART_FIFO_LENGTH);
+    fifo8_create(&s->xmit_fifo, UART_FIFO_LENGTH);
 }
 
 void serial_exit_core(SerialState *s)
diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h
index bca79f1..9ab81f6 100644
--- a/include/hw/char/serial.h
+++ b/include/hw/char/serial.h
@@ -28,17 +28,10 @@
 #include "hw/hw.h"
 #include "sysemu/sysemu.h"
 #include "exec/memory.h"
+#include "qemu/fifo8.h"
 
 #define UART_FIFO_LENGTH    16      /* 16550A Fifo Length */
 
-typedef struct SerialFIFO {
-    uint8_t data[UART_FIFO_LENGTH];
-    uint8_t count;
-    uint8_t itl;                        /* Interrupt Trigger Level */
-    uint8_t tail;
-    uint8_t head;
-} SerialFIFO;
-
 struct SerialState {
     uint16_t divider;
     uint8_t rbr; /* receive register */
@@ -67,8 +60,10 @@ struct SerialState {
 
     /* Time when the last byte was successfully sent out of the tsr */
     uint64_t last_xmit_ts;
-    SerialFIFO recv_fifo;
-    SerialFIFO xmit_fifo;
+    Fifo8 recv_fifo;
+    Fifo8 xmit_fifo;
+    /* Interrupt trigger level for recv_fifo */
+    uint8_t recv_fifo_itl;
 
     struct QEMUTimer *fifo_timeout_timer;
     int timeout_ipending;           /* timeout interrupt pending state */
commit 7f4f0a227fe0b24c35d0898f9ae7d5909fb51137
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 15:12:09 2013 +1000

    char/serial: cosmetic fixes.
    
    Some cosmetic fixes to char/serial fixing some checkpatch errors.
    
    Cc: qemu-trivial at nongnu.org
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/char/serial.c b/hw/char/serial.c
index 66b6348..bd6813e 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -263,8 +263,9 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque)
     if (s->tsr_retry <= 0) {
         if (s->fcr & UART_FCR_FE) {
             s->tsr = fifo_get(s,XMIT_FIFO);
-            if (!s->xmit_fifo.count)
+            if (!s->xmit_fifo.count) {
                 s->lsr |= UART_LSR_THRE;
+            }
         } else if ((s->lsr & UART_LSR_THRE)) {
             return FALSE;
         } else {
@@ -461,10 +462,11 @@ static uint64_t serial_ioport_read(void *opaque, hwaddr addr, unsigned size)
         } else {
             if(s->fcr & UART_FCR_FE) {
                 ret = fifo_get(s,RECV_FIFO);
-                if (s->recv_fifo.count == 0)
+                if (s->recv_fifo.count == 0) {
                     s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
-                else
+                } else {
                     qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock_ns (vm_clock) + s->char_transmit_time * 4);
+                }
                 s->timeout_ipending = 0;
             } else {
                 ret = s->rbr;
@@ -534,15 +536,21 @@ static uint64_t serial_ioport_read(void *opaque, hwaddr addr, unsigned size)
 static int serial_can_receive(SerialState *s)
 {
     if(s->fcr & UART_FCR_FE) {
-        if(s->recv_fifo.count < UART_FIFO_LENGTH)
-        /* Advertise (fifo.itl - fifo.count) bytes when count < ITL, and 1 if above. If UART_FIFO_LENGTH - fifo.count is
-        advertised the effect will be to almost always fill the fifo completely before the guest has a chance to respond,
-        effectively overriding the ITL that the guest has set. */
-             return (s->recv_fifo.count <= s->recv_fifo.itl) ? s->recv_fifo.itl - s->recv_fifo.count : 1;
-        else
-             return 0;
+        if (s->recv_fifo.count < UART_FIFO_LENGTH) {
+            /*
+             * Advertise (fifo.itl - fifo.count) bytes when count < ITL, and 1
+             * if above. If UART_FIFO_LENGTH - fifo.count is advertised the
+             * effect will be to almost always fill the fifo completely before
+             * the guest has a chance to respond, effectively overriding the ITL
+             * that the guest has set.
+             */
+            return (s->recv_fifo.count <= s->recv_fifo.itl) ?
+                        s->recv_fifo.itl - s->recv_fifo.count : 1;
+        } else {
+            return 0;
+        }
     } else {
-    return !(s->lsr & UART_LSR_DR);
+        return !(s->lsr & UART_LSR_DR);
     }
 }
 
commit 9e5e2b23d301b1562677c6c115165eed6ce20a68
Author: Richard W.M. Jones <rjones at redhat.com>
Date:   Mon Jun 10 14:14:35 2013 +0100

    curl: Whitespace only changes.
    
    Trivial patch to remove odd whitespace.
    
    Signed-off-by: Richard W.M. Jones <rjones at redhat.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/block/curl.c b/block/curl.c
index b8935fd..4dc3b4b 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -462,8 +462,8 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags)
     // initialize the multi interface!
 
     s->multi = curl_multi_init();
-    curl_multi_setopt( s->multi, CURLMOPT_SOCKETDATA, s); 
-    curl_multi_setopt( s->multi, CURLMOPT_SOCKETFUNCTION, curl_sock_cb ); 
+    curl_multi_setopt(s->multi, CURLMOPT_SOCKETDATA, s);
+    curl_multi_setopt(s->multi, CURLMOPT_SOCKETFUNCTION, curl_sock_cb);
     curl_multi_do(s);
 
     qemu_opts_del(opts);
commit 5c9f43363a84fa13861ebc949ea2453cf7ab4ae3
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Thu Jun 6 16:38:03 2013 +0000

    intc/xilinx_intc: Use qemu_set_irq
    
    Use qemu_set_irq rather than if-elsing qemu_irq_(lower|raise). No
    functional change, just reduces verbosity.
    
    Cc: qemu-trivial at nongnu.org
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/intc/xilinx_intc.c b/hw/intc/xilinx_intc.c
index b106e72..5df7008 100644
--- a/hw/intc/xilinx_intc.c
+++ b/hw/intc/xilinx_intc.c
@@ -66,11 +66,7 @@ static void update_irq(struct xlx_pic *p)
         i = ~0;
 
     p->regs[R_IVR] = i;
-    if ((p->regs[R_MER] & 1) && p->regs[R_IPR]) {
-        qemu_irq_raise(p->parent_irq);
-    } else {
-        qemu_irq_lower(p->parent_irq);
-    }
+    qemu_set_irq(p->parent_irq, (p->regs[R_MER] & 1) && p->regs[R_IPR]);
 }
 
 static uint64_t
commit 45f0b0434d51d4c7e4db05fe721fc61b9b6ef17d
Author: Ed Maste <emaste at freebsd.org>
Date:   Thu Jun 6 09:18:44 2013 -0400

    configure: Disable host-bsd USB on FreeBSD
    
    It hasn't built since FreeBSD 8.x, and is disabled by a patch in the
    FreeBSD ports tree.  FreeBSD is migrating to QEMU's libusb support.
    
    Signed-off-by: Ed Maste <emaste at freebsd.org>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/configure b/configure
index e197b91..a3f0b7a 100755
--- a/configure
+++ b/configure
@@ -553,7 +553,9 @@ esac
 
 if [ "$bsd" = "yes" ] ; then
   if [ "$darwin" != "yes" ] ; then
-    usb="bsd"
+    if [ "$targetos" != "FreeBSD" ]; then
+      usb="bsd"
+    fi
     bsd_user="yes"
   fi
 fi
commit 224ead2690cb89bf8edcca493e3b49857eac0d12
Author: Ed Maste <emaste at freebsd.org>
Date:   Thu Jun 6 08:53:35 2013 -0400

    configure: remove ${config_host_ld} variable
    
    It was only used in one place (and already expanded in one other).
    
    Signed-off-by: Ed Maste <emaste at freebsd.org>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/configure b/configure
index 1654413..e197b91 100755
--- a/configure
+++ b/configure
@@ -3556,7 +3556,6 @@ echo "-> Your SDL version is too old - please upgrade to have SDL support"
 fi
 
 config_host_mak="config-host.mak"
-config_host_ld="config-host.ld"
 
 echo "# Automatically generated by configure - do not modify" >config-all-disas.mak
 
@@ -4071,7 +4070,7 @@ if test "$gcov" = "yes" ; then
 fi
 
 # generate list of library paths for linker script
-$ld --verbose -v 2> /dev/null | grep SEARCH_DIR > ${config_host_ld}
+$ld --verbose -v 2> /dev/null | grep SEARCH_DIR > config-host.ld
 
 # use included Linux headers
 if test "$linux" = "yes" ; then
commit f3a22014e94dfaacb57277dafce66b41cd994869
Author: Michael Tokarev <mjt at tls.msk.ru>
Date:   Thu Jun 6 01:14:54 2013 +0400

    gitignore: unignore *.patch
    
    This partially reverts:
    
     commit 082369e62c5bbaba89f173c2b803bc24115bb111
     Author: liguang <lig.fnst at cn.fujitsu.com>
     Date:   Fri Mar 22 16:44:13 2013 +0800
    
        gitignore: ignore more files
    
    I'm not sure how this went in.  The thing is that
    ignoring *.patch, in my opinion, is just wrong.
    Especially for downstreams who apply patches for
    real.
    
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/.gitignore b/.gitignore
index 64e9466..0fe114d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -82,7 +82,6 @@ fsdev/virtfs-proxy-helper.pod
 *.swp
 *.orig
 .pc
-*.patch
 *.gcda
 *.gcno
 patches
commit c58e6201fa38191313cd95c5342d3733bd3f612d
Author: Michael Tokarev <mjt at tls.msk.ru>
Date:   Wed Jun 5 19:08:59 2013 +0400

    qemu-char: remove a few needless #includes
    
    This removes <syslog.h> since we don't use
    syslogging, and removes second, solaris-specific,
    include of <net/if.h> (which is included in
    a common part of the file)
    
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/qemu-char.c b/qemu-char.c
index 0b6ae95..596bf9e 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -76,8 +76,6 @@
 #include <netinet/ip_icmp.h> // must come after ip.h
 #include <netinet/udp.h>
 #include <netinet/tcp.h>
-#include <net/if.h>
-#include <syslog.h>
 #endif
 #endif
 #endif
commit 11ed09cf0753c1288a97f00138fc4534135442bb
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed May 29 21:54:03 2013 +0200

    memory_mapping: Improve qemu_get_guest_memory_mapping() error reporting
    
    Pass any Error out into dump_init() and have it actually stop on errors.
    Whether it is unsupported on a certain CPU can be checked by looking for
    a NULL CPUClass::get_memory_mapping field.
    
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
    [AF: Reverted changes to CPU loops]
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/dump.c b/dump.c
index 87ca12c..44a1339 100644
--- a/dump.c
+++ b/dump.c
@@ -707,6 +707,7 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
 {
     CPUArchState *env;
     int nr_cpus;
+    Error *err = NULL;
     int ret;
 
     if (runstate_is_running()) {
@@ -757,7 +758,11 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
     /* get memory mapping */
     memory_mapping_list_init(&s->list);
     if (paging) {
-        qemu_get_guest_memory_mapping(&s->list);
+        qemu_get_guest_memory_mapping(&s->list, &err);
+        if (err != NULL) {
+            error_propagate(errp, err);
+            goto cleanup;
+        }
     } else {
         qemu_get_guest_simple_memory_mapping(&s->list);
     }
diff --git a/include/sysemu/memory_mapping.h b/include/sysemu/memory_mapping.h
index c47e6ee..6dfb68d 100644
--- a/include/sysemu/memory_mapping.h
+++ b/include/sysemu/memory_mapping.h
@@ -45,13 +45,7 @@ void memory_mapping_list_free(MemoryMappingList *list);
 
 void memory_mapping_list_init(MemoryMappingList *list);
 
-/*
- * Return value:
- *    0: success
- *   -1: failed
- *   -2: unsupported
- */
-int qemu_get_guest_memory_mapping(MemoryMappingList *list);
+void qemu_get_guest_memory_mapping(MemoryMappingList *list, Error **errp);
 
 /* get guest's memory mapping without do paging(virtual address is 0). */
 void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list);
diff --git a/memory_mapping.c b/memory_mapping.c
index 9bd24ce..5634f81 100644
--- a/memory_mapping.c
+++ b/memory_mapping.c
@@ -178,7 +178,7 @@ static CPUArchState *find_paging_enabled_cpu(CPUArchState *start_cpu)
     return NULL;
 }
 
-int qemu_get_guest_memory_mapping(MemoryMappingList *list)
+void qemu_get_guest_memory_mapping(MemoryMappingList *list, Error **errp)
 {
     CPUArchState *env, *first_paging_enabled_cpu;
     RAMBlock *block;
@@ -190,11 +190,11 @@ int qemu_get_guest_memory_mapping(MemoryMappingList *list)
             Error *err = NULL;
             cpu_get_memory_mapping(ENV_GET_CPU(env), list, &err);
             if (err) {
-                error_free(err);
-                return -1;
+                error_propagate(errp, err);
+                return;
             }
         }
-        return 0;
+        return;
     }
 
     /*
@@ -206,8 +206,6 @@ int qemu_get_guest_memory_mapping(MemoryMappingList *list)
         length = block->length;
         create_new_memory_mapping(list, offset, offset, length);
     }
-
-    return 0;
 }
 
 void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list)
commit 1b3509ca5bbd8e7d2be92ac42196a3ee2e31cb03
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Jun 9 16:48:29 2013 +0200

    dump: Abstract dump_init() with cpu_synchronize_all_states()
    
    Instead of calling cpu_synchronize_state() for each CPU, call the
    existing cpu_synchronize_all_states() helper.
    
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/dump.c b/dump.c
index c0d3da5..87ca12c 100644
--- a/dump.c
+++ b/dump.c
@@ -21,6 +21,7 @@
 #include "sysemu/dump.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/memory_mapping.h"
+#include "sysemu/cpus.h"
 #include "qapi/error.h"
 #include "qmp-commands.h"
 
@@ -731,12 +732,12 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
      * If the target architecture is not supported, cpu_get_dump_info() will
      * return -1.
      *
-     * if we use kvm, we should synchronize the register before we get dump
+     * If we use KVM, we should synchronize the registers before we get dump
      * info.
      */
+    cpu_synchronize_all_states();
     nr_cpus = 0;
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        cpu_synchronize_state(env);
         nr_cpus++;
     }
 
commit 6db297ea361f4e03c096a0f28f26b060f0060de5
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Jun 9 16:03:46 2013 +0200

    cpu: Change default for CPUClass::get_paging_enabled()
    
    qemu_get_guest_memory_mapping() uses cpu_paging_enabled() to determine
    whether to use cpu_get_memory_mapping() to return mappings or whether to
    fall back to a simple identity map.
    
    Since by default CPUClass::get_memory_mapping() is not implemented,
    change the default to false to use the identity map by default.
    
    Reviewed-by: Jens Freimann <jfrei at linux.vnet.ibm.com>
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/qom/cpu.c b/qom/cpu.c
index b25fbc9..dba4a11 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -59,7 +59,7 @@ bool cpu_paging_enabled(const CPUState *cpu)
 
 static bool cpu_common_get_paging_enabled(const CPUState *cpu)
 {
-    return true;
+    return false;
 }
 
 void cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
commit 2a78636bd204e389068d203473ec76558083b44b
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri May 17 11:54:40 2013 +0200

    dump: Drop qmp_dump_guest_memory() stub and build for all targets
    
    qmp_dump_guest_memory() calls dump_init() and returns an Error when
    cpu_get_dump_info() returns an error, as done by the stub.
    So there is no need to have a stub for qmp_dump_guest_memory().
    
    Enable the documentation of the always-present dump-guest-memory command.
    
    That way we can drop CONFIG_HAVE_CORE_DUMP and leave configure
    completely out of the picture for target CPU features.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/Makefile.target b/Makefile.target
index f9e1d89..b0be124 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -110,7 +110,7 @@ obj-$(CONFIG_FDT) += device_tree.o
 obj-$(CONFIG_KVM) += kvm-all.o
 obj-y += memory.o savevm.o cputlb.o
 obj-y += memory_mapping.o
-obj-$(CONFIG_HAVE_CORE_DUMP) += dump.o
+obj-y += dump.o
 LIBS+=$(libs_softmmu)
 
 # xen support
diff --git a/configure b/configure
index 6401762..c61d862 100755
--- a/configure
+++ b/configure
@@ -4303,10 +4303,6 @@ if test "$target_bigendian" = "yes" ; then
 fi
 if test "$target_softmmu" = "yes" ; then
   echo "CONFIG_SOFTMMU=y" >> $config_target_mak
-  case "$target_arch2" in
-    i386|x86_64)
-      echo "CONFIG_HAVE_CORE_DUMP=y" >> $config_target_mak
-  esac
 fi
 if test "$target_user_only" = "yes" ; then
   echo "CONFIG_USER_ONLY=y" >> $config_target_mak
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 396691a..915b0d1 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -991,7 +991,6 @@ server will ask the spice/vnc client to automatically reconnect using the
 new parameters (if specified) once the vm migration finished successfully.
 ETEXI
 
-#if defined(CONFIG_HAVE_CORE_DUMP)
     {
         .name       = "dump-guest-memory",
         .args_type  = "paging:-p,filename:F,begin:i?,length:i?",
@@ -1015,7 +1014,6 @@ gdb.
     length: the memory size, in bytes. It's optional, and should be specified
             with begin together.
 ETEXI
-#endif
 
     {
         .name       = "snapshot_blkdev",
diff --git a/stubs/dump.c b/stubs/dump.c
index b3f42cb..43c9a3f 100644
--- a/stubs/dump.c
+++ b/stubs/dump.c
@@ -16,14 +16,6 @@
 #include "qapi/qmp/qerror.h"
 #include "qmp-commands.h"
 
-/* we need this function in hmp.c */
-void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
-                           int64_t begin, bool has_length, int64_t length,
-                           Error **errp)
-{
-    error_set(errp, QERR_UNSUPPORTED);
-}
-
 int cpu_get_dump_info(ArchDumpInfo *info)
 {
     return -1;
commit c22d8e0448aecb48a91f3936419ad1b63fbb4a6a
Author: Andreas Färber <afaerber at suse.de>
Date:   Tue May 28 14:53:32 2013 +0200

    memory_mapping: Drop qemu_get_memory_mapping() stub
    
    dump.c:dump_init() never checked for the return code anyway.
    If paging is not enabled, it will fall back to an identity map.
    If paging is enabled and getting memory mapping list is not
    implemented, qemu_get_guest_memory_mapping() will return an error.
    
    Since the targets not implementing memory mapping also don't implement
    dump support, we will not reach this code today and can worry about
    changing cpu_paging_enabled() default when the need arises.
    
    This allows us to drop CONFIG_HAVE_GET_MEMORY_SUPPORT.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/Makefile.target b/Makefile.target
index 1cafb17..f9e1d89 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -63,7 +63,6 @@ all: $(PROGS) stap
 CONFIG_NO_PCI = $(if $(subst n,,$(CONFIG_PCI)),n,y)
 CONFIG_NO_KVM = $(if $(subst n,,$(CONFIG_KVM)),n,y)
 CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),n,y)
-CONFIG_NO_GET_MEMORY_MAPPING = $(if $(subst n,,$(CONFIG_HAVE_GET_MEMORY_MAPPING)),n,y)
 
 #########################################################
 # cpu emulator library
@@ -110,9 +109,8 @@ obj-y += hw/
 obj-$(CONFIG_FDT) += device_tree.o
 obj-$(CONFIG_KVM) += kvm-all.o
 obj-y += memory.o savevm.o cputlb.o
-obj-$(CONFIG_HAVE_GET_MEMORY_MAPPING) += memory_mapping.o
+obj-y += memory_mapping.o
 obj-$(CONFIG_HAVE_CORE_DUMP) += dump.o
-obj-$(CONFIG_NO_GET_MEMORY_MAPPING) += memory_mapping-stub.o
 LIBS+=$(libs_softmmu)
 
 # xen support
diff --git a/configure b/configure
index 1654413..6401762 100755
--- a/configure
+++ b/configure
@@ -4298,10 +4298,6 @@ case "$target_arch2" in
       fi
     fi
 esac
-case "$target_arch2" in
-  i386|x86_64)
-    echo "CONFIG_HAVE_GET_MEMORY_MAPPING=y" >> $config_target_mak
-esac
 if test "$target_bigendian" = "yes" ; then
   echo "TARGET_WORDS_BIGENDIAN=y" >> $config_target_mak
 fi
diff --git a/memory_mapping-stub.c b/memory_mapping-stub.c
deleted file mode 100644
index 989dc00..0000000
--- a/memory_mapping-stub.c
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * QEMU memory mapping
- *
- * Copyright Fujitsu, Corp. 2011, 2012
- *
- * Authors:
- *     Wen Congyang <wency at cn.fujitsu.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#include "cpu.h"
-#include "exec/cpu-all.h"
-#include "sysemu/memory_mapping.h"
-
-int qemu_get_guest_memory_mapping(MemoryMappingList *list)
-{
-    return -2;
-}
commit a23bbfda75118eb738acce84afd64965934828f0
Author: Andreas Färber <afaerber at suse.de>
Date:   Tue May 28 13:52:01 2013 +0200

    cpu: Turn cpu_get_memory_mapping() into a CPUState hook
    
    Change error reporting from return value to Error argument.
    
    Reviewed-by: Jens Freimann <jfrei at linux.vnet.ibm.com>
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
    [AF: Fixed cpu_get_memory_mapping() documentation]
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 1f70240..a5bb515 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -23,6 +23,7 @@
 #include <signal.h>
 #include "hw/qdev-core.h"
 #include "qemu/thread.h"
+#include "qemu/typedefs.h"
 
 typedef int (*WriteCoreDumpFunction)(void *buf, size_t size, void *opaque);
 
@@ -49,6 +50,7 @@ typedef struct CPUState CPUState;
  * @do_interrupt: Callback for interrupt handling.
  * @get_arch_id: Callback for getting architecture-dependent CPU ID.
  * @get_paging_enabled: Callback for inquiring whether paging is enabled.
+ * @get_memory_mapping: Callback for obtaining the memory mappings.
  * @vmsd: State description for migration.
  *
  * Represents a CPU family or model.
@@ -64,6 +66,8 @@ typedef struct CPUClass {
     void (*do_interrupt)(CPUState *cpu);
     int64_t (*get_arch_id)(CPUState *cpu);
     bool (*get_paging_enabled)(const CPUState *cpu);
+    void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
+                               Error **errp);
 
     const struct VMStateDescription *vmsd;
     int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
@@ -148,6 +152,15 @@ struct CPUState {
 bool cpu_paging_enabled(const CPUState *cpu);
 
 /**
+ * cpu_get_memory_mapping:
+ * @cpu: The CPU whose memory mappings are to be obtained.
+ * @list: Where to write the memory mappings to.
+ * @errp: Pointer for reporting an #Error.
+ */
+void cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
+                            Error **errp);
+
+/**
  * cpu_write_elf64_note:
  * @f: pointer to a function that writes memory to a file
  * @cpu: The CPU whose memory is to be dumped
diff --git a/include/sysemu/memory_mapping.h b/include/sysemu/memory_mapping.h
index 1f71c32..c47e6ee 100644
--- a/include/sysemu/memory_mapping.h
+++ b/include/sysemu/memory_mapping.h
@@ -31,8 +31,6 @@ struct MemoryMappingList {
     QTAILQ_HEAD(, MemoryMapping) head;
 };
 
-int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env);
-
 /*
  * add or merge the memory region [phys_addr, phys_addr + length) into the
  * memory mapping's list. The region's virtual address starts with virt_addr,
diff --git a/memory_mapping-stub.c b/memory_mapping-stub.c
index 6c0dfeb..989dc00 100644
--- a/memory_mapping-stub.c
+++ b/memory_mapping-stub.c
@@ -19,9 +19,3 @@ int qemu_get_guest_memory_mapping(MemoryMappingList *list)
 {
     return -2;
 }
-
-int cpu_get_memory_mapping(MemoryMappingList *list,
-					                                          CPUArchState *env)
-{
-    return -1;
-}
diff --git a/memory_mapping.c b/memory_mapping.c
index 0790aac..9bd24ce 100644
--- a/memory_mapping.c
+++ b/memory_mapping.c
@@ -183,13 +183,14 @@ int qemu_get_guest_memory_mapping(MemoryMappingList *list)
     CPUArchState *env, *first_paging_enabled_cpu;
     RAMBlock *block;
     ram_addr_t offset, length;
-    int ret;
 
     first_paging_enabled_cpu = find_paging_enabled_cpu(first_cpu);
     if (first_paging_enabled_cpu) {
         for (env = first_paging_enabled_cpu; env != NULL; env = env->next_cpu) {
-            ret = cpu_get_memory_mapping(list, env);
-            if (ret < 0) {
+            Error *err = NULL;
+            cpu_get_memory_mapping(ENV_GET_CPU(env), list, &err);
+            if (err) {
+                error_free(err);
                 return -1;
             }
         }
diff --git a/qom/cpu.c b/qom/cpu.c
index 9f6da0f..b25fbc9 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -62,6 +62,21 @@ static bool cpu_common_get_paging_enabled(const CPUState *cpu)
     return true;
 }
 
+void cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
+                            Error **errp)
+{
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
+    return cc->get_memory_mapping(cpu, list, errp);
+}
+
+static void cpu_common_get_memory_mapping(CPUState *cpu,
+                                          MemoryMappingList *list,
+                                          Error **errp)
+{
+    error_setg(errp, "Obtaining memory mappings is unsupported on this CPU.");
+}
+
 /* CPU hot-plug notifiers */
 static NotifierList cpu_added_notifiers =
     NOTIFIER_LIST_INITIALIZER(cpu_add_notifiers);
@@ -189,6 +204,7 @@ static void cpu_class_init(ObjectClass *klass, void *data)
     k->reset = cpu_common_reset;
     k->get_arch_id = cpu_common_get_arch_id;
     k->get_paging_enabled = cpu_common_get_paging_enabled;
+    k->get_memory_mapping = cpu_common_get_memory_mapping;
     k->write_elf32_qemunote = cpu_common_write_elf32_qemunote;
     k->write_elf32_note = cpu_common_write_elf32_note;
     k->write_elf64_qemunote = cpu_common_write_elf64_qemunote;
diff --git a/target-i386/arch_memory_mapping.c b/target-i386/arch_memory_mapping.c
index c5a10ec..2566a04 100644
--- a/target-i386/arch_memory_mapping.c
+++ b/target-i386/arch_memory_mapping.c
@@ -239,11 +239,15 @@ static void walk_pml4e(MemoryMappingList *list,
 }
 #endif
 
-int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env)
+void x86_cpu_get_memory_mapping(CPUState *cs, MemoryMappingList *list,
+                                Error **errp)
 {
-    if (!cpu_paging_enabled(ENV_GET_CPU(env))) {
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
+
+    if (!cpu_paging_enabled(cs)) {
         /* paging is disabled */
-        return 0;
+        return;
     }
 
     if (env->cr[4] & CR4_PAE_MASK) {
@@ -269,7 +273,5 @@ int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env)
         pse = !!(env->cr[4] & CR4_PSE_MASK);
         walk_pde2(list, pde_addr, env->a20_mask, pse);
     }
-
-    return 0;
 }
 
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 849cedf..e0ac072 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -98,4 +98,7 @@ int x86_cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
 int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
                                  void *opaque);
 
+void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
+                                Error **errp);
+
 #endif
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index f6fa7fa..a7154af 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2529,6 +2529,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->get_arch_id = x86_cpu_get_arch_id;
     cc->get_paging_enabled = x86_cpu_get_paging_enabled;
 #ifndef CONFIG_USER_ONLY
+    cc->get_memory_mapping = x86_cpu_get_memory_mapping;
     cc->write_elf64_note = x86_cpu_write_elf64_note;
     cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
     cc->write_elf32_note = x86_cpu_write_elf32_note;
commit 6d4d3ae77dbb756d454c2deb2ef844b0cc7bde7b
Author: Andreas Färber <afaerber at suse.de>
Date:   Tue May 28 14:20:15 2013 +0200

    memory_mapping: Move MemoryMappingList typedef to qemu/typedefs.h
    
    This will avoid issues with hwaddr and ram_addr_t when including
    sysemu/memory_mapping.h for CONFIG_USER_ONLY, e.g., from qom/cpu.h.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index afe4ec7..698fc03 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -22,6 +22,8 @@ typedef struct AddressSpace AddressSpace;
 typedef struct MemoryRegion MemoryRegion;
 typedef struct MemoryRegionSection MemoryRegionSection;
 
+typedef struct MemoryMappingList MemoryMappingList;
+
 typedef struct NICInfo NICInfo;
 typedef struct HCIInfo HCIInfo;
 typedef struct AudioState AudioState;
diff --git a/include/sysemu/memory_mapping.h b/include/sysemu/memory_mapping.h
index 6f01524..1f71c32 100644
--- a/include/sysemu/memory_mapping.h
+++ b/include/sysemu/memory_mapping.h
@@ -15,6 +15,7 @@
 #define MEMORY_MAPPING_H
 
 #include "qemu/queue.h"
+#include "qemu/typedefs.h"
 
 /* The physical and virtual address in the memory mapping are contiguous. */
 typedef struct MemoryMapping {
@@ -24,11 +25,11 @@ typedef struct MemoryMapping {
     QTAILQ_ENTRY(MemoryMapping) next;
 } MemoryMapping;
 
-typedef struct MemoryMappingList {
+struct MemoryMappingList {
     unsigned int num;
     MemoryMapping *last_mapping;
     QTAILQ_HEAD(, MemoryMapping) head;
-} MemoryMappingList;
+};
 
 int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env);
 
commit 444d55907871f88276a654fc7fdc8c7db95f4b59
Author: Andreas Färber <afaerber at suse.de>
Date:   Tue May 28 13:28:38 2013 +0200

    cpu: Turn cpu_paging_enabled() into a CPUState hook
    
    Relocate assignment of x86 get_arch_id to have all hooks in one place.
    
    Reviewed-by: Jens Freimann <jfrei at linux.vnet.ibm.com>
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 7cd9442..1f70240 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -48,6 +48,7 @@ typedef struct CPUState CPUState;
  * @reset: Callback to reset the #CPUState to its initial state.
  * @do_interrupt: Callback for interrupt handling.
  * @get_arch_id: Callback for getting architecture-dependent CPU ID.
+ * @get_paging_enabled: Callback for inquiring whether paging is enabled.
  * @vmsd: State description for migration.
  *
  * Represents a CPU family or model.
@@ -62,6 +63,7 @@ typedef struct CPUClass {
     void (*reset)(CPUState *cpu);
     void (*do_interrupt)(CPUState *cpu);
     int64_t (*get_arch_id)(CPUState *cpu);
+    bool (*get_paging_enabled)(const CPUState *cpu);
 
     const struct VMStateDescription *vmsd;
     int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
@@ -138,6 +140,14 @@ struct CPUState {
 };
 
 /**
+ * cpu_paging_enabled:
+ * @cpu: The CPU whose state is to be inspected.
+ *
+ * Returns: %true if paging is enabled, %false otherwise.
+ */
+bool cpu_paging_enabled(const CPUState *cpu);
+
+/**
  * cpu_write_elf64_note:
  * @f: pointer to a function that writes memory to a file
  * @cpu: The CPU whose memory is to be dumped
diff --git a/include/sysemu/memory_mapping.h b/include/sysemu/memory_mapping.h
index 1256125..6f01524 100644
--- a/include/sysemu/memory_mapping.h
+++ b/include/sysemu/memory_mapping.h
@@ -31,7 +31,6 @@ typedef struct MemoryMappingList {
 } MemoryMappingList;
 
 int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env);
-bool cpu_paging_enabled(CPUArchState *env);
 
 /*
  * add or merge the memory region [phys_addr, phys_addr + length) into the
diff --git a/memory_mapping-stub.c b/memory_mapping-stub.c
index 24d5d67..6c0dfeb 100644
--- a/memory_mapping-stub.c
+++ b/memory_mapping-stub.c
@@ -25,9 +25,3 @@ int cpu_get_memory_mapping(MemoryMappingList *list,
 {
     return -1;
 }
-
-bool cpu_paging_enabled(CPUArchState *env)
-{
-    return true;
-}
-
diff --git a/memory_mapping.c b/memory_mapping.c
index ff45b3a..0790aac 100644
--- a/memory_mapping.c
+++ b/memory_mapping.c
@@ -170,7 +170,7 @@ static CPUArchState *find_paging_enabled_cpu(CPUArchState *start_cpu)
     CPUArchState *env;
 
     for (env = start_cpu; env != NULL; env = env->next_cpu) {
-        if (cpu_paging_enabled(env)) {
+        if (cpu_paging_enabled(ENV_GET_CPU(env))) {
             return env;
         }
     }
diff --git a/qom/cpu.c b/qom/cpu.c
index 04aefbb..9f6da0f 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -50,6 +50,18 @@ bool cpu_exists(int64_t id)
     return data.found;
 }
 
+bool cpu_paging_enabled(const CPUState *cpu)
+{
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
+    return cc->get_paging_enabled(cpu);
+}
+
+static bool cpu_common_get_paging_enabled(const CPUState *cpu)
+{
+    return true;
+}
+
 /* CPU hot-plug notifiers */
 static NotifierList cpu_added_notifiers =
     NOTIFIER_LIST_INITIALIZER(cpu_add_notifiers);
@@ -176,6 +188,7 @@ static void cpu_class_init(ObjectClass *klass, void *data)
     k->class_by_name = cpu_common_class_by_name;
     k->reset = cpu_common_reset;
     k->get_arch_id = cpu_common_get_arch_id;
+    k->get_paging_enabled = cpu_common_get_paging_enabled;
     k->write_elf32_qemunote = cpu_common_write_elf32_qemunote;
     k->write_elf32_note = cpu_common_write_elf32_note;
     k->write_elf64_qemunote = cpu_common_write_elf64_qemunote;
diff --git a/target-i386/arch_memory_mapping.c b/target-i386/arch_memory_mapping.c
index 5096fbd..c5a10ec 100644
--- a/target-i386/arch_memory_mapping.c
+++ b/target-i386/arch_memory_mapping.c
@@ -241,7 +241,7 @@ static void walk_pml4e(MemoryMappingList *list,
 
 int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env)
 {
-    if (!cpu_paging_enabled(env)) {
+    if (!cpu_paging_enabled(ENV_GET_CPU(env))) {
         /* paging is disabled */
         return 0;
     }
@@ -273,7 +273,3 @@ int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env)
     return 0;
 }
 
-bool cpu_paging_enabled(CPUArchState *env)
-{
-    return env->cr[0] & CR0_PG_MASK;
-}
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 4b2da0d..f6fa7fa 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2505,6 +2505,13 @@ static int64_t x86_cpu_get_arch_id(CPUState *cs)
     return env->cpuid_apic_id;
 }
 
+static bool x86_cpu_get_paging_enabled(const CPUState *cs)
+{
+    X86CPU *cpu = X86_CPU(cs);
+
+    return cpu->env.cr[0] & CR0_PG_MASK;
+}
+
 static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
 {
     X86CPUClass *xcc = X86_CPU_CLASS(oc);
@@ -2519,6 +2526,8 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->reset = x86_cpu_reset;
 
     cc->do_interrupt = x86_cpu_do_interrupt;
+    cc->get_arch_id = x86_cpu_get_arch_id;
+    cc->get_paging_enabled = x86_cpu_get_paging_enabled;
 #ifndef CONFIG_USER_ONLY
     cc->write_elf64_note = x86_cpu_write_elf64_note;
     cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
@@ -2526,8 +2535,6 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
 #endif
     cpu_class_set_vmsd(cc, &vmstate_x86_cpu);
-
-    cc->get_arch_id = x86_cpu_get_arch_id;
 }
 
 static const TypeInfo x86_cpu_type_info = {
commit c51a944b7505ba827adc897d5452d2b54dbf86bb
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri May 17 16:57:52 2013 +0200

    monitor: Simplify do_inject_mce() with qemu_get_cpu()
    
    Avoids an open-coded CPU loop.
    
    Reviewed-by: liguang <lig.fnst at cn.fujitsu.com>
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/monitor.c b/monitor.c
index 017411f..70ae8f5 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2013,7 +2013,6 @@ static void do_acl_remove(Monitor *mon, const QDict *qdict)
 static void do_inject_mce(Monitor *mon, const QDict *qdict)
 {
     X86CPU *cpu;
-    CPUX86State *cenv;
     CPUState *cs;
     int cpu_index = qdict_get_int(qdict, "cpu_index");
     int bank = qdict_get_int(qdict, "bank");
@@ -2026,14 +2025,11 @@ static void do_inject_mce(Monitor *mon, const QDict *qdict)
     if (qdict_get_try_bool(qdict, "broadcast", 0)) {
         flags |= MCE_INJECT_BROADCAST;
     }
-    for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
-        cpu = x86_env_get_cpu(cenv);
-        cs = CPU(cpu);
-        if (cs->cpu_index == cpu_index) {
-            cpu_x86_inject_mce(mon, cpu, bank, status, mcg_status, addr, misc,
-                               flags);
-            break;
-        }
+    cs = qemu_get_cpu(cpu_index);
+    if (cs != NULL) {
+        cpu = X86_CPU(cs);
+        cpu_x86_inject_mce(mon, cpu, bank, status, mcg_status, addr, misc,
+                           flags);
     }
 }
 #endif
commit 31ccdde298d98b08526dc23059071c9086dec6c2
Author: Igor Mammedov <imammedo at redhat.com>
Date:   Mon Jun 3 18:23:27 2013 +0200

    target-i386: cpu: Fix potential buffer overrun in get_register_name_32()
    
    Spotted by Coverity,
    x86_reg_info_32[] is CPU_NB_REGS32 elements long, so accessing
    x86_reg_info_32[CPU_NB_REGS32] will be one element off array.
    
    Signed-off-by: Igor Mammedov <imammedo at redhat.com>
    Reviewed-by: liguang <lig.fnst at cn.fujitsu.com>
    Reviewed by: Jesse Larrew <jlarrew at linux.vnet.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 762baad..4b2da0d 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -221,7 +221,7 @@ X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
 
 const char *get_register_name_32(unsigned int reg)
 {
-    if (reg > CPU_NB_REGS32) {
+    if (reg >= CPU_NB_REGS32) {
         return NULL;
     }
     return x86_reg_info_32[reg].name;
commit 6b11322e0f724eb0649fdc324a44288b783023ad
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Mon May 27 17:23:55 2013 -0300

    target-i386: Set level=4 on Conroe/Penryn/Nehalem
    
    The CPUID level value on Conroe, Penryn, and Nehalem are too low. This
    causes at least one known problem: the -smp "threads" option doesn't
    work as expect if level is < 4, because thread count information is
    provided to the guest on CPUID[EAX=4,ECX=2].EAX
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index f232d75..fab9be5 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -191,13 +191,25 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
             .property = "model",\
             .value    = stringify(2),\
         },{\
+            .driver   = "Conroe-" TYPE_X86_CPU,\
+            .property = "level",\
+            .value    = stringify(2),\
+        },{\
             .driver   = "Penryn-" TYPE_X86_CPU,\
             .property = "model",\
             .value    = stringify(2),\
         },{\
+            .driver   = "Penryn-" TYPE_X86_CPU,\
+            .property = "level",\
+            .value    = stringify(2),\
+        },{\
             .driver   = "Nehalem-" TYPE_X86_CPU,\
             .property = "model",\
             .value    = stringify(2),\
+        },{\
+            .driver   = "Nehalem-" TYPE_X86_CPU,\
+            .property = "level",\
+            .value    = stringify(2),\
         }
 
 #define PC_COMPAT_1_4 \
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 6b48562..762baad 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -669,7 +669,7 @@ static x86_def_t builtin_x86_defs[] = {
     },
     {
         .name = "Conroe",
-        .level = 2,
+        .level = 4,
         .vendor = CPUID_VENDOR_INTEL,
         .family = 6,
         .model = 15,
@@ -691,7 +691,7 @@ static x86_def_t builtin_x86_defs[] = {
     },
     {
         .name = "Penryn",
-        .level = 2,
+        .level = 4,
         .vendor = CPUID_VENDOR_INTEL,
         .family = 6,
         .model = 23,
@@ -714,7 +714,7 @@ static x86_def_t builtin_x86_defs[] = {
     },
     {
         .name = "Nehalem",
-        .level = 2,
+        .level = 4,
         .vendor = CPUID_VENDOR_INTEL,
         .family = 6,
         .model = 26,
commit ffce9ebbb69363dfe7605585cdad58ea3847edf4
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Mon May 27 17:23:54 2013 -0300

    target-i386: Update model values on Conroe/Penryn/Nehalem CPU models
    
    The CPUID model values on Conroe, Penryn, and Nehalem are too
    conservative and don't reflect the values found on real Conroe, Penryn,
    and Nehalem CPUs.
    
    This causes at least one known problems: Windows XP disables sysenter
    when (family == 6 && model <= 2), but Skype tries to use the sysenter
    instruction anyway because it is reported as available on CPUID, making
    it crash.
    
    This patch sets appropriate model values that correspond to real Conroe,
    Penryn, and Nehalem CPUs.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 7fb2bce..69eb2a1 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -344,6 +344,10 @@ static QEMUMachine pc_i440fx_machine_v1_5 = {
     .init = pc_init_pci,
     .hot_add_cpu = pc_hot_add_cpu,
     .max_cpus = 255,
+    .compat_props = (GlobalProperty[]) {
+        PC_COMPAT_1_5,
+        { /* end of list */ }
+    },
     DEFAULT_MACHINE_OPTIONS,
 };
 
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index db5c46e..bb0ce6a 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -231,6 +231,10 @@ static QEMUMachine pc_q35_machine_v1_5 = {
     .init = pc_q35_init,
     .hot_add_cpu = pc_hot_add_cpu,
     .max_cpus = 255,
+    .compat_props = (GlobalProperty[]) {
+        PC_COMPAT_1_5,
+        { /* end of list */ }
+    },
     DEFAULT_MACHINE_OPTIONS,
 };
 
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 6154058..f232d75 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -185,7 +185,23 @@ int pvpanic_init(ISABus *bus);
 
 int e820_add_entry(uint64_t, uint64_t, uint32_t);
 
+#define PC_COMPAT_1_5 \
+        {\
+            .driver   = "Conroe-" TYPE_X86_CPU,\
+            .property = "model",\
+            .value    = stringify(2),\
+        },{\
+            .driver   = "Penryn-" TYPE_X86_CPU,\
+            .property = "model",\
+            .value    = stringify(2),\
+        },{\
+            .driver   = "Nehalem-" TYPE_X86_CPU,\
+            .property = "model",\
+            .value    = stringify(2),\
+        }
+
 #define PC_COMPAT_1_4 \
+        PC_COMPAT_1_5, \
         {\
             .driver   = "scsi-hd",\
             .property = "discard_granularity",\
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 1a501d9..6b48562 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -672,7 +672,7 @@ static x86_def_t builtin_x86_defs[] = {
         .level = 2,
         .vendor = CPUID_VENDOR_INTEL,
         .family = 6,
-        .model = 2,
+        .model = 15,
         .stepping = 3,
         .features[FEAT_1_EDX] =
             CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
@@ -694,7 +694,7 @@ static x86_def_t builtin_x86_defs[] = {
         .level = 2,
         .vendor = CPUID_VENDOR_INTEL,
         .family = 6,
-        .model = 2,
+        .model = 23,
         .stepping = 3,
         .features[FEAT_1_EDX] =
             CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
@@ -717,7 +717,7 @@ static x86_def_t builtin_x86_defs[] = {
         .level = 2,
         .vendor = CPUID_VENDOR_INTEL,
         .family = 6,
-        .model = 2,
+        .model = 26,
         .stepping = 3,
         .features[FEAT_1_EDX] =
             CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
commit 45053fdef54fa9aac1cc9b09f2a1d08af90b7b43
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Mon May 27 17:23:53 2013 -0300

    pc: Create pc-*-1.6 machine-types
    
    Some CPU model fixes are going to be included and they will require
    compatibility properties in the pc-*-1.5 machine-types.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index d618570..7fb2bce 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -327,8 +327,8 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
 }
 #endif
 
-static QEMUMachine pc_i440fx_machine_v1_5 = {
-    .name = "pc-i440fx-1.5",
+static QEMUMachine pc_i440fx_machine_v1_6 = {
+    .name = "pc-i440fx-1.6",
     .alias = "pc",
     .desc = "Standard PC (i440FX + PIIX, 1996)",
     .init = pc_init_pci,
@@ -338,6 +338,15 @@ static QEMUMachine pc_i440fx_machine_v1_5 = {
     DEFAULT_MACHINE_OPTIONS,
 };
 
+static QEMUMachine pc_i440fx_machine_v1_5 = {
+    .name = "pc-i440fx-1.5",
+    .desc = "Standard PC (i440FX + PIIX, 1996)",
+    .init = pc_init_pci,
+    .hot_add_cpu = pc_hot_add_cpu,
+    .max_cpus = 255,
+    DEFAULT_MACHINE_OPTIONS,
+};
+
 static QEMUMachine pc_i440fx_machine_v1_4 = {
     .name = "pc-i440fx-1.4",
     .desc = "Standard PC (i440FX + PIIX, 1996)",
@@ -735,6 +744,7 @@ static QEMUMachine xenfv_machine = {
 
 static void pc_machine_init(void)
 {
+    qemu_register_machine(&pc_i440fx_machine_v1_6);
     qemu_register_machine(&pc_i440fx_machine_v1_5);
     qemu_register_machine(&pc_i440fx_machine_v1_4);
     qemu_register_machine(&pc_machine_v1_3);
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 7888dfe..db5c46e 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -215,9 +215,18 @@ static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
     pc_q35_init(args);
 }
 
+static QEMUMachine pc_q35_machine_v1_6 = {
+    .name = "pc-q35-1.6",
+    .alias = "q35",
+    .desc = "Standard PC (Q35 + ICH9, 2009)",
+    .init = pc_q35_init,
+    .hot_add_cpu = pc_hot_add_cpu,
+    .max_cpus = 255,
+    DEFAULT_MACHINE_OPTIONS,
+};
+
 static QEMUMachine pc_q35_machine_v1_5 = {
     .name = "pc-q35-1.5",
-    .alias = "q35",
     .desc = "Standard PC (Q35 + ICH9, 2009)",
     .init = pc_q35_init,
     .hot_add_cpu = pc_hot_add_cpu,
@@ -239,6 +248,7 @@ static QEMUMachine pc_q35_machine_v1_4 = {
 
 static void pc_q35_machine_init(void)
 {
+    qemu_register_machine(&pc_q35_machine_v1_6);
     qemu_register_machine(&pc_q35_machine_v1_5);
     qemu_register_machine(&pc_q35_machine_v1_4);
 }
commit 8de433cb0820dc1f387a2d580d255744aacd60cc
Author: Igor Mammedov <imammedo at redhat.com>
Date:   Thu May 30 17:09:34 2013 +0200

    pc: Fix crash when attempting to hotplug CPU with negative ID
    
    QMP command "{ 'execute': 'cpu-add', 'arguments': { 'id': -1 }}" may cause
    QEMU SIGSEGV at:
     piix4_cpu_hotplug_req ()
        ...
        g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
        ...
    
    Since for PC in current implementation id should be in range [0...maxcpus)
    and maxcpus is already checked, add check for lower bound and error out
    on incorrect value.
    
    Signed-off-by: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 4844a6b..553becb 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -927,6 +927,11 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
     DeviceState *icc_bridge;
     int64_t apic_id = x86_cpu_apic_id_from_index(id);
 
+    if (id < 0) {
+        error_setg(errp, "Invalid CPU id: %" PRIi64, id);
+        return;
+    }
+
     if (cpu_exists(apic_id)) {
         error_setg(errp, "Unable to add CPU: %" PRIi64
                    ", it already exists", id);
commit 88f62c2b1deb466749e340a8a241975c509bd9b6
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri May 17 10:41:20 2013 +0200

    dump: Move stubs into libqemustub.a
    
    This allows us to drop CONFIG_NO_CORE_DUMP with its indirect dependency
    on CONFIG_HAVE_CORE_DUMP.
    
    Acked-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/Makefile.target b/Makefile.target
index ce4391f..1cafb17 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -64,7 +64,6 @@ CONFIG_NO_PCI = $(if $(subst n,,$(CONFIG_PCI)),n,y)
 CONFIG_NO_KVM = $(if $(subst n,,$(CONFIG_KVM)),n,y)
 CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),n,y)
 CONFIG_NO_GET_MEMORY_MAPPING = $(if $(subst n,,$(CONFIG_HAVE_GET_MEMORY_MAPPING)),n,y)
-CONFIG_NO_CORE_DUMP = $(if $(subst n,,$(CONFIG_HAVE_CORE_DUMP)),n,y)
 
 #########################################################
 # cpu emulator library
@@ -114,7 +113,6 @@ obj-y += memory.o savevm.o cputlb.o
 obj-$(CONFIG_HAVE_GET_MEMORY_MAPPING) += memory_mapping.o
 obj-$(CONFIG_HAVE_CORE_DUMP) += dump.o
 obj-$(CONFIG_NO_GET_MEMORY_MAPPING) += memory_mapping-stub.o
-obj-$(CONFIG_NO_CORE_DUMP) += dump-stub.o
 LIBS+=$(libs_softmmu)
 
 # xen support
diff --git a/dump-stub.c b/dump-stub.c
deleted file mode 100644
index b3f42cb..0000000
--- a/dump-stub.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * QEMU dump
- *
- * Copyright Fujitsu, Corp. 2011, 2012
- *
- * Authors:
- *     Wen Congyang <wency at cn.fujitsu.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu-common.h"
-#include "sysemu/dump.h"
-#include "qapi/qmp/qerror.h"
-#include "qmp-commands.h"
-
-/* we need this function in hmp.c */
-void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
-                           int64_t begin, bool has_length, int64_t length,
-                           Error **errp)
-{
-    error_set(errp, QERR_UNSUPPORTED);
-}
-
-int cpu_get_dump_info(ArchDumpInfo *info)
-{
-    return -1;
-}
-
-ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
-{
-    return -1;
-}
-
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 03dff20..9b701b4 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -2,6 +2,7 @@ stub-obj-y += arch-query-cpu-def.o
 stub-obj-y += clock-warp.o
 stub-obj-y += cpu-get-clock.o
 stub-obj-y += cpu-get-icount.o
+stub-obj-y += dump.o
 stub-obj-y += fdset-add-fd.o
 stub-obj-y += fdset-find-fd.o
 stub-obj-y += fdset-get-fd.o
diff --git a/stubs/dump.c b/stubs/dump.c
new file mode 100644
index 0000000..b3f42cb
--- /dev/null
+++ b/stubs/dump.c
@@ -0,0 +1,36 @@
+/*
+ * QEMU dump
+ *
+ * Copyright Fujitsu, Corp. 2011, 2012
+ *
+ * Authors:
+ *     Wen Congyang <wency at cn.fujitsu.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu-common.h"
+#include "sysemu/dump.h"
+#include "qapi/qmp/qerror.h"
+#include "qmp-commands.h"
+
+/* we need this function in hmp.c */
+void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
+                           int64_t begin, bool has_length, int64_t length,
+                           Error **errp)
+{
+    error_set(errp, QERR_UNSUPPORTED);
+}
+
+int cpu_get_dump_info(ArchDumpInfo *info)
+{
+    return -1;
+}
+
+ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
+{
+    return -1;
+}
+
commit bd5c51ee6c4f1c79cae5ad2516d711a27b4ea8ec
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Fri Jun 7 15:19:53 2013 -0500

    qemu-char: don't issue CHR_EVENT_OPEN in a BH
    
    When CHR_EVENT_OPENED was initially added, it was CHR_EVENT_RESET,
    and it was issued as a bottom-half:
    
    86e94dea5b740dad65446c857f6959eae43e0ba6
    
    Which we basically used to print out a greeting/prompt for the
    monitor.
    
    AFAICT the only reason this was ever done in a BH was because in
    some cases we'd modify the chr_write handler for a new chardev
    backend *after* the site where we issued the reset (see:
    86e94d:qemu_chr_open_stdio())
    
    At some point this event was renamed to CHR_EVENT_OPENED, and we've
    maintained the use of this BH ever since.
    
    However, due to 9f939df955a4152aad69a19a77e0898631bb2c18, we schedule
    the BH via g_idle_add(), which is causing events to sometimes be
    delivered after we've already begun processing data from backends,
    leading to:
    
     known bugs:
    
      QMP:
        session negotation resets with OPENED event, in some cases this
        is causing new sessions to get sporadically reset
    
     potential bugs:
    
      hw/usb/redirect.c:
        can_read handler checks for dev->parser != NULL, which may be
        true if CLOSED BH has not been executed yet. In the past, OPENED
        quiesced outstanding CLOSED events prior to us reading client
        data. If it's delayed, our check may allow reads to occur even
        though we haven't processed the OPENED event yet, and when we
        do finally get the OPENED event, our state may get reset.
    
      qtest.c:
        can begin session before OPENED event is processed, leading to
        a spurious reset of the system and irq_levels
    
      gdbstub.c:
        may start a gdb session prior to the machine being paused
    
    To fix these, let's just drop the BH.
    
    Since the initial reasoning for using it still applies to an extent,
    work around that by deferring the delivery of CHR_EVENT_OPENED until
    after the chardevs have been fully initialized, toward the end of
    qmp_chardev_add() (or some cases, qemu_chr_new_from_opts()). This
    defers delivery long enough that we can be assured a CharDriverState
    is fully initialized before CHR_EVENT_OPENED is sent.
    
    Also, rather than requiring each chardev to do an explicit open, do it
    automatically, and allow the small few who don't desire such behavior to
    suppress the OPENED-on-init behavior by setting a 'explicit_be_open'
    flag.
    
    We additionally add missing OPENED events for stdio backends on w32,
    which were previously not being issued, causing us to not recieve the
    banner and initial prompts for qmp/hmp.
    
    Reported-by: Stefan Priebe <s.priebe at profihost.ag>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Message-id: 1370636393-21044-1-git-send-email-mdroth at linux.vnet.ibm.com
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/backends/baum.c b/backends/baum.c
index 4cba79f..62aa784 100644
--- a/backends/baum.c
+++ b/backends/baum.c
@@ -611,8 +611,6 @@ CharDriverState *chr_baum_init(void)
 
     qemu_set_fd_handler(baum->brlapi_fd, baum_chr_read, NULL, baum);
 
-    qemu_chr_be_generic_open(chr);
-
     return chr;
 
 fail:
diff --git a/backends/msmouse.c b/backends/msmouse.c
index 0ac05a0..c0dbfcd 100644
--- a/backends/msmouse.c
+++ b/backends/msmouse.c
@@ -70,6 +70,7 @@ CharDriverState *qemu_chr_open_msmouse(void)
     chr = g_malloc0(sizeof(CharDriverState));
     chr->chr_write = msmouse_chr_write;
     chr->chr_close = msmouse_chr_close;
+    chr->explicit_be_open = true;
 
     qemu_add_mouse_event_handler(msmouse_event, chr, 0, "QEMU Microsoft Mouse");
 
diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index 5e42c90..066c216 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -70,12 +70,12 @@ struct CharDriverState {
     void (*chr_set_echo)(struct CharDriverState *chr, bool echo);
     void (*chr_set_fe_open)(struct CharDriverState *chr, int fe_open);
     void *opaque;
-    int idle_tag;
     char *label;
     char *filename;
     int be_open;
     int fe_open;
     int explicit_fe_open;
+    int explicit_be_open;
     int avail_connections;
     QemuOpts *opts;
     QTAILQ_ENTRY(CharDriverState) next;
diff --git a/qemu-char.c b/qemu-char.c
index d04b429..0b6ae95 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -110,19 +110,9 @@ void qemu_chr_be_event(CharDriverState *s, int event)
     s->chr_event(s->handler_opaque, event);
 }
 
-static gboolean qemu_chr_be_generic_open_bh(gpointer opaque)
-{
-    CharDriverState *s = opaque;
-    qemu_chr_be_event(s, CHR_EVENT_OPENED);
-    s->idle_tag = 0;
-    return FALSE;
-}
-
 void qemu_chr_be_generic_open(CharDriverState *s)
 {
-    if (s->idle_tag == 0) {
-        s->idle_tag = g_idle_add(qemu_chr_be_generic_open_bh, s);
-    }
+    qemu_chr_be_event(s, CHR_EVENT_OPENED);
 }
 
 int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len)
@@ -247,6 +237,7 @@ static CharDriverState *qemu_chr_open_null(void)
 
     chr = g_malloc0(sizeof(CharDriverState));
     chr->chr_write = null_chr_write;
+    chr->explicit_be_open = true;
     return chr;
 }
 
@@ -504,9 +495,6 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
     /* Frontend guest-open / -close notification is not support with muxes */
     chr->chr_set_fe_open = NULL;
 
-    /* Muxes are always open on creation */
-    qemu_chr_be_generic_open(chr);
-
     return chr;
 }
 
@@ -883,8 +871,6 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
     chr->chr_update_read_handler = fd_chr_update_read_handler;
     chr->chr_close = fd_chr_close;
 
-    qemu_chr_be_generic_open(chr);
-
     return chr;
 }
 
@@ -1243,6 +1229,7 @@ static CharDriverState *qemu_chr_open_pty(const char *id,
     chr->chr_update_read_handler = pty_chr_update_read_handler;
     chr->chr_close = pty_chr_close;
     chr->chr_add_watch = pty_chr_add_watch;
+    chr->explicit_be_open = true;
 
     s->fd = io_channel_from_fd(master_fd);
     s->timer_tag = 0;
@@ -1595,8 +1582,6 @@ static CharDriverState *qemu_chr_open_pp_fd(int fd)
     chr->chr_close = pp_close;
     chr->opaque = drv;
 
-    qemu_chr_be_generic_open(chr);
-
     return chr;
 }
 #endif /* __linux__ */
@@ -1650,6 +1635,7 @@ static CharDriverState *qemu_chr_open_pp_fd(int fd)
     chr->opaque = (void *)(intptr_t)fd;
     chr->chr_write = null_chr_write;
     chr->chr_ioctl = pp_ioctl;
+    chr->explicit_be_open = true;
     return chr;
 }
 #endif
@@ -1880,7 +1866,6 @@ static CharDriverState *qemu_chr_open_win_path(const char *filename)
         g_free(chr);
         return NULL;
     }
-    qemu_chr_be_generic_open(chr);
     return chr;
 }
 
@@ -1980,7 +1965,6 @@ static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts)
         g_free(chr);
         return NULL;
     }
-    qemu_chr_be_generic_open(chr);
     return chr;
 }
 
@@ -1994,7 +1978,6 @@ static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
     s->hcom = fd_out;
     chr->opaque = s;
     chr->chr_write = win_chr_write;
-    qemu_chr_be_generic_open(chr);
     return chr;
 }
 
@@ -2329,6 +2312,8 @@ static CharDriverState *qemu_chr_open_udp_fd(int fd)
     chr->chr_write = udp_chr_write;
     chr->chr_update_read_handler = udp_chr_update_read_handler;
     chr->chr_close = udp_chr_close;
+    /* be isn't opened until we get a connection */
+    chr->explicit_be_open = true;
     return chr;
 }
 
@@ -2731,6 +2716,8 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
     chr->get_msgfd = tcp_get_msgfd;
     chr->chr_add_client = tcp_chr_add_client;
     chr->chr_add_watch = tcp_chr_add_watch;
+    /* be isn't opened until we get a connection */
+    chr->explicit_be_open = true;
 
     if (is_listen) {
         s->listen_fd = fd;
@@ -3325,6 +3312,12 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
     if (!chr->filename)
         chr->filename = g_strdup(qemu_opt_get(opts, "backend"));
     chr->init = init;
+    /* if we didn't create the chardev via qmp_chardev_add, we
+     * need to send the OPENED event here
+     */
+    if (!chr->explicit_be_open) {
+        qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+    }
     QTAILQ_INSERT_TAIL(&chardevs, chr, next);
 
     if (qemu_opt_get_bool(opts, "mux", 0)) {
@@ -3804,6 +3797,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
         if (!chr->filename) {
             chr->filename = g_strdup(ChardevBackendKind_lookup[backend->kind]);
         }
+        if (!chr->explicit_be_open) {
+            qemu_chr_be_event(chr, CHR_EVENT_OPENED);
+        }
         QTAILQ_INSERT_TAIL(&chardevs, chr, next);
         return ret;
     } else {
diff --git a/spice-qemu-char.c b/spice-qemu-char.c
index f10970c..6d147a7 100644
--- a/spice-qemu-char.c
+++ b/spice-qemu-char.c
@@ -255,6 +255,7 @@ static CharDriverState *chr_open(const char *subtype)
     chr->chr_add_watch = spice_chr_add_watch;
     chr->chr_close = spice_chr_close;
     chr->chr_set_fe_open = spice_chr_set_fe_open;
+    chr->explicit_be_open = true;
 
     QLIST_INSERT_HEAD(&spice_chars, s, next);
 
diff --git a/ui/console.c b/ui/console.c
index b30853f..28bba6d 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1788,6 +1788,10 @@ static CharDriverState *text_console_init(ChardevVC *vc)
     s->chr = chr;
     chr->opaque = s;
     chr->chr_set_echo = text_console_set_echo;
+    /* console/chardev init sometimes completes elsewhere in a 2nd
+     * stage, so defer OPENED events until they are fully initialized
+     */
+    chr->explicit_be_open = true;
 
     if (display_state) {
         text_console_do_init(chr, display_state);
diff --git a/ui/gtk.c b/ui/gtk.c
index efd7836..63f6081 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1119,6 +1119,8 @@ static CharDriverState *gd_vc_handler(ChardevVC *unused)
 
     chr = g_malloc0(sizeof(*chr));
     chr->chr_write = gd_vc_chr_write;
+    /* defer OPENED events until our vc is fully initialized */
+    chr->explicit_be_open = true;
 
     vcs[nb_vcs++] = chr;
 
commit b62cd318daaa3d94c150d87dc2c8466b9463cef5
Merge: 97f31cb 9914fbe
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Jun 10 11:37:47 2013 -0500

    Merge remote-tracking branch 'luiz/queue/qmp' into staging
    
    # By Luiz Capitulino (2) and Marcelo Tosatti (1)
    # Via Luiz Capitulino
    * luiz/queue/qmp:
      correct RTC_CHANGE_EVENT description (v2)
      MAINTAINERS: split Monitor (QMP/HMP) entry
      MAINTAINERS: new maintainers for qapi-schema.json
    
    Message-id: 1370634855-18337-1-git-send-email-lcapitulino at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 97f31cbc71fc13b3091893313a555c3cf1ecb798
Merge: f7da9c1 c87826a
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Jun 10 11:37:39 2013 -0500

    Merge remote-tracking branch 'stefanha/net' into staging
    
    # By Jason Wang (1) and Stefan Hajnoczi (1)
    # Via Stefan Hajnoczi
    * stefanha/net:
      tap: fix NULL dereference when passing invalid parameters to tap
      vmxnet3: fix NICState cleanup
    
    Message-id: 1370613288-14933-1-git-send-email-stefanha at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit f7da9c17c114417911ac2008d0401084a5030391
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Jun 7 13:24:17 2013 -0500

    gtk: use better icon
    
    The current icon looks pretty terrible rendered in Gnome.  This
    switches to a transparent SVG which looks much nicer.
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/Makefile b/Makefile
index 9a77ae0..306e7bd 100644
--- a/Makefile
+++ b/Makefile
@@ -289,7 +289,7 @@ pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \
 pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \
 efi-e1000.rom efi-eepro100.rom efi-ne2k_pci.rom \
 efi-pcnet.rom efi-rtl8139.rom efi-virtio.rom \
-qemu-icon.bmp \
+qemu-icon.bmp qemu_logo_no_text.svg \
 bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
 multiboot.bin linuxboot.bin kvmvapic.bin \
 s390-zipl.rom \
diff --git a/pc-bios/qemu_logo_no_text.svg b/pc-bios/qemu_logo_no_text.svg
new file mode 100644
index 0000000..24ca23a
--- /dev/null
+++ b/pc-bios/qemu_logo_no_text.svg
@@ -0,0 +1,976 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="111.71874"
+   height="111.12498"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.2 r9819"
+   sodipodi:docname="qemu_logo_no_text.svg">
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient4686">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop4688" />
+      <stop
+         id="stop3956"
+         offset="0.75"
+         style="stop-color:#000000;stop-opacity:0.87843138;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.43921569;"
+         offset="0.75"
+         id="stop3958" />
+      <stop
+         id="stop3960"
+         offset="0.88"
+         style="stop-color:#181818;stop-opacity:1;" />
+      <stop
+         style="stop-color:#242424;stop-opacity:1;"
+         offset="0.88"
+         id="stop3962" />
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="1"
+         id="stop4690" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4467">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop4469" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.8974359;"
+         offset="1"
+         id="stop4471" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4431">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4433" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4435" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4466">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4468" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4470" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4321">
+      <stop
+         style="stop-color:#ff6702;stop-opacity:1;"
+         offset="0"
+         id="stop4323" />
+      <stop
+         style="stop-color:#ff9a55;stop-opacity:1;"
+         offset="1"
+         id="stop4325" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4283">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop4285" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop4287" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4251">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop4253" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop4255" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4007">
+      <stop
+         style="stop-color:#ff6600;stop-opacity:1;"
+         offset="0"
+         id="stop4009" />
+      <stop
+         style="stop-color:#ff9148;stop-opacity:1;"
+         offset="1"
+         id="stop4011" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3999">
+      <stop
+         style="stop-color:#fff7f2;stop-opacity:1;"
+         offset="0"
+         id="stop4001" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4003" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3890">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3892" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3894" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3880">
+      <stop
+         style="stop-color:#eb7400;stop-opacity:1;"
+         offset="0"
+         id="stop3882" />
+      <stop
+         style="stop-color:#f7b06a;stop-opacity:1;"
+         offset="1"
+         id="stop3884" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4011">
+      <stop
+         style="stop-color:#042dc8;stop-opacity:1;"
+         offset="0"
+         id="stop4013" />
+      <stop
+         style="stop-color:#4260d5;stop-opacity:1;"
+         offset="1"
+         id="stop4015" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3879">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.90598291;"
+         offset="0"
+         id="stop3881" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3883" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3869">
+      <stop
+         style="stop-color:#c95000;stop-opacity:1;"
+         offset="0"
+         id="stop3871" />
+      <stop
+         style="stop-color:#ff9e5e;stop-opacity:1;"
+         offset="1"
+         id="stop3873" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3861">
+      <stop
+         style="stop-color:#f06000;stop-opacity:1;"
+         offset="0"
+         id="stop3863" />
+      <stop
+         style="stop-color:#ffccaa;stop-opacity:1;"
+         offset="1"
+         id="stop3865" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3826">
+      <stop
+         style="stop-color:#ff6600;stop-opacity:1;"
+         offset="0"
+         id="stop3828" />
+      <stop
+         style="stop-color:#ff893b;stop-opacity:1;"
+         offset="1"
+         id="stop3830" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3879-6">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.90598291;"
+         offset="0"
+         id="stop3881-4" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3883-7" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3869-5">
+      <stop
+         style="stop-color:#c95000;stop-opacity:1;"
+         offset="0"
+         id="stop3871-9" />
+      <stop
+         style="stop-color:#ff9e5e;stop-opacity:1;"
+         offset="1"
+         id="stop3873-4" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3879-4"
+       id="linearGradient3885-6"
+       x1="76.025352"
+       y1="124.8497"
+       x2="75.874107"
+       y2="143.03978"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient3879-4">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.93162394;"
+         offset="0"
+         id="stop3881-6" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3883-74" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3869-2">
+      <stop
+         style="stop-color:#c95000;stop-opacity:1;"
+         offset="0"
+         id="stop3871-99" />
+      <stop
+         style="stop-color:#ff9e5e;stop-opacity:1;"
+         offset="1"
+         id="stop3873-6" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4011"
+       id="radialGradient4017"
+       cx="66.639"
+       cy="93.096375"
+       fx="66.639"
+       fy="93.096375"
+       r="11.515625"
+       gradientTransform="matrix(0.23244854,1.600893,-1.0124495,0.14700695,145.40424,-26.300303)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3879-4-7"
+       id="linearGradient3885-6-2"
+       x1="76.025352"
+       y1="124.8497"
+       x2="75.874107"
+       y2="143.03978"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient3879-4-7">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.93162394;"
+         offset="0"
+         id="stop3881-6-7" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3883-74-6" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4011-5"
+       id="radialGradient4017-7"
+       cx="66.639"
+       cy="93.096375"
+       fx="66.639"
+       fy="93.096375"
+       r="11.515625"
+       gradientTransform="matrix(0.99779178,6.8718773,-4.3459674,0.6310314,452.75975,-225.98471)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4011-5">
+      <stop
+         style="stop-color:#042dc8;stop-opacity:1;"
+         offset="0"
+         id="stop4013-1" />
+      <stop
+         style="stop-color:#4260d5;stop-opacity:1;"
+         offset="1"
+         id="stop4015-3" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3879-4-75"
+       id="linearGradient3885-6-8"
+       x1="76.025352"
+       y1="124.8497"
+       x2="75.874107"
+       y2="143.03978"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient3879-4-75">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.93162394;"
+         offset="0"
+         id="stop3881-6-1" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3883-74-4" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4011-0"
+       id="radialGradient4017-5"
+       cx="66.639"
+       cy="93.096375"
+       fx="66.639"
+       fy="93.096375"
+       r="11.515625"
+       gradientTransform="matrix(0.23244854,1.600893,-1.0124495,0.14700695,146.34996,53.681728)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4011-0">
+      <stop
+         style="stop-color:#042dc8;stop-opacity:1;"
+         offset="0"
+         id="stop4013-4" />
+      <stop
+         style="stop-color:#4260d5;stop-opacity:1;"
+         offset="1"
+         id="stop4015-0" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4011-0"
+       id="linearGradient4117"
+       x1="107.03001"
+       y1="189.72537"
+       x2="107.18476"
+       y2="173.47537"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3879-4-7-2"
+       id="linearGradient3885-6-2-8"
+       x1="76.025352"
+       y1="124.8497"
+       x2="75.874107"
+       y2="143.03978"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient3879-4-7-2">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.93162394;"
+         offset="0"
+         id="stop3881-6-7-9" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3883-74-6-9" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4011-5-1"
+       id="radialGradient4017-7-9"
+       cx="66.639"
+       cy="93.096375"
+       fx="66.639"
+       fy="93.096375"
+       r="11.515625"
+       gradientTransform="matrix(0.99779178,6.8718773,-4.3459674,0.6310314,448.94742,-406.99277)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4011-5-1">
+      <stop
+         style="stop-color:#042dc8;stop-opacity:1;"
+         offset="0"
+         id="stop4013-1-9" />
+      <stop
+         style="stop-color:#4260d5;stop-opacity:1;"
+         offset="1"
+         id="stop4015-3-8" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3879-4-7-2-7"
+       id="linearGradient3885-6-2-8-0"
+       x1="76.025352"
+       y1="124.8497"
+       x2="75.874107"
+       y2="143.03978"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient3879-4-7-2-7">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.93162394;"
+         offset="0"
+         id="stop3881-6-7-9-3" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3883-74-6-9-6" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4011-5-1-5"
+       id="radialGradient4017-7-9-5"
+       cx="66.639"
+       cy="93.096375"
+       fx="66.639"
+       fy="93.096375"
+       r="11.515625"
+       gradientTransform="matrix(0.55965334,3.8543806,-2.4376181,0.3539404,454.75182,-145.44353)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4011-5-1-5">
+      <stop
+         style="stop-color:#042dc8;stop-opacity:1;"
+         offset="0"
+         id="stop4013-1-9-6" />
+      <stop
+         style="stop-color:#4260d5;stop-opacity:1;"
+         offset="1"
+         id="stop4015-3-8-9" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3879-4-7-2-4"
+       id="linearGradient3885-6-2-8-4"
+       x1="76.025352"
+       y1="124.8497"
+       x2="75.874107"
+       y2="143.03978"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient3879-4-7-2-4">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.93162394;"
+         offset="0"
+         id="stop3881-6-7-9-9" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3883-74-6-9-3" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4011-5-1-7"
+       id="radialGradient4017-7-9-7"
+       cx="66.639"
+       cy="93.096375"
+       fx="66.639"
+       fy="93.096375"
+       r="11.515625"
+       gradientTransform="matrix(0.26837158,1.8482981,-1.1689154,0.16972569,466.57614,26.180822)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4011-5-1-7">
+      <stop
+         style="stop-color:#042dc8;stop-opacity:1;"
+         offset="0"
+         id="stop4013-1-9-1" />
+      <stop
+         style="stop-color:#4260d5;stop-opacity:1;"
+         offset="1"
+         id="stop4015-3-8-5" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3879-4-7-2-0">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.93162394;"
+         offset="0"
+         id="stop3881-6-7-9-7" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3883-74-6-9-8" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4011-5-1-55">
+      <stop
+         style="stop-color:#000a30;stop-opacity:1;"
+         offset="0"
+         id="stop4013-1-9-8" />
+      <stop
+         style="stop-color:#4260d5;stop-opacity:1;"
+         offset="1"
+         id="stop4015-3-8-3" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3890-9">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3892-0" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3894-9" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3880-4">
+      <stop
+         style="stop-color:#eb7400;stop-opacity:1;"
+         offset="0"
+         id="stop3882-5" />
+      <stop
+         style="stop-color:#f7b06a;stop-opacity:1;"
+         offset="1"
+         id="stop3884-1" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3999-7">
+      <stop
+         style="stop-color:#fff7f2;stop-opacity:1;"
+         offset="0"
+         id="stop4001-9" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4003-4" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4007-9">
+      <stop
+         style="stop-color:#ff6600;stop-opacity:1;"
+         offset="0"
+         id="stop4009-1" />
+      <stop
+         style="stop-color:#ff9148;stop-opacity:1;"
+         offset="1"
+         id="stop4011-9" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4007-9-5">
+      <stop
+         style="stop-color:#ff6600;stop-opacity:1;"
+         offset="0"
+         id="stop4009-1-9" />
+      <stop
+         style="stop-color:#ff9148;stop-opacity:1;"
+         offset="1"
+         id="stop4011-9-5" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3999-7-1">
+      <stop
+         style="stop-color:#fff7f2;stop-opacity:1;"
+         offset="0"
+         id="stop4001-9-1" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4003-4-4" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4007-9-5-3">
+      <stop
+         style="stop-color:#ff6600;stop-opacity:1;"
+         offset="0"
+         id="stop4009-1-9-3" />
+      <stop
+         style="stop-color:#ff9148;stop-opacity:1;"
+         offset="1"
+         id="stop4011-9-5-9" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3999-7-1-4">
+      <stop
+         style="stop-color:#fff7f2;stop-opacity:1;"
+         offset="0"
+         id="stop4001-9-1-4" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4003-4-4-4" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3879-4-7-2-3">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.93162394;"
+         offset="0"
+         id="stop3881-6-7-9-1" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop3883-74-6-9-87" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4011-5-1-1">
+      <stop
+         style="stop-color:#fde8a1;stop-opacity:1;"
+         offset="0"
+         id="stop4013-1-9-63" />
+      <stop
+         style="stop-color:#2947b9;stop-opacity:1;"
+         offset="1"
+         id="stop4015-3-8-8" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4466"
+       id="linearGradient4472"
+       x1="161.7561"
+       y1="540.72662"
+       x2="161.7561"
+       y2="579.80206"
+       gradientUnits="userSpaceOnUse" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4321"
+       id="radialGradient4474"
+       cx="130.8242"
+       cy="575.27838"
+       fx="130.8242"
+       fy="575.27838"
+       r="49.498173"
+       gradientTransform="matrix(0.95670828,0.96684666,-0.72623533,0.71862001,423.45109,35.05138)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4466-5"
+       id="linearGradient4472-9"
+       x1="161.7561"
+       y1="540.72662"
+       x2="161.7561"
+       y2="579.80206"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4466-5">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4468-2" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4470-3" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4321-0"
+       id="radialGradient4474-6"
+       cx="130.8242"
+       cy="575.27838"
+       fx="130.8242"
+       fy="575.27838"
+       r="49.498173"
+       gradientTransform="matrix(0.95670828,0.96684666,-0.72623533,0.71862001,442.64399,170.9169)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4321-0">
+      <stop
+         style="stop-color:#ff6702;stop-opacity:1;"
+         offset="0"
+         id="stop4323-3" />
+      <stop
+         style="stop-color:#ff9a55;stop-opacity:1;"
+         offset="1"
+         id="stop4325-1" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4466-5-5">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4468-2-9" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4470-3-4" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4321-0-0">
+      <stop
+         style="stop-color:#ff6702;stop-opacity:1;"
+         offset="0"
+         id="stop4323-3-9" />
+      <stop
+         style="stop-color:#ff9a55;stop-opacity:1;"
+         offset="1"
+         id="stop4325-1-1" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4466-5-9">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4468-2-7" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4470-3-7" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4321-0-7">
+      <stop
+         style="stop-color:#ff6702;stop-opacity:1;"
+         offset="0"
+         id="stop4323-3-3" />
+      <stop
+         style="stop-color:#ff9a55;stop-opacity:1;"
+         offset="1"
+         id="stop4325-1-6" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4431"
+       id="linearGradient4437"
+       x1="142.81854"
+       y1="831.52283"
+       x2="142.81854"
+       y2="878.90735"
+       gradientUnits="userSpaceOnUse" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4467"
+       id="radialGradient4475"
+       cx="116.51958"
+       cy="98.282051"
+       fx="116.51958"
+       fy="98.282051"
+       r="55.859375"
+       gradientTransform="matrix(0.97442557,1.5088911,-0.83559154,0.53961599,79.641615,-130.28522)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4431-3"
+       id="linearGradient4437-6"
+       x1="142.81854"
+       y1="831.52283"
+       x2="142.81854"
+       y2="878.90735"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4431-3">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4433-0" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4435-2" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4467-7"
+       id="radialGradient4475-0"
+       cx="116.51958"
+       cy="98.282051"
+       fx="116.51958"
+       fy="98.282051"
+       r="55.859375"
+       gradientTransform="matrix(0.97442557,1.5088911,-0.83559154,0.53961599,225.10358,63.664066)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient4467-7">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop4469-4" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0.8974359;"
+         offset="1"
+         id="stop4471-7" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4467"
+       id="radialGradient3262"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.97442557,1.5088911,-0.83559154,0.53961599,59.641615,-150.28522)"
+       cx="116.51958"
+       cy="98.282051"
+       fx="116.51958"
+       fy="98.282051"
+       r="55.859375" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4431"
+       id="linearGradient3264"
+       gradientUnits="userSpaceOnUse"
+       x1="142.81854"
+       y1="831.52283"
+       x2="142.81854"
+       y2="878.90735" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="5.6"
+     inkscape:cx="31.144191"
+     inkscape:cy="38.335716"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     showguides="false"
+     inkscape:guide-bbox="true"
+     inkscape:window-width="1920"
+     inkscape:window-height="1056"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     fit-margin-top="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     fit-margin-left="0">
+    <sodipodi:guide
+       orientation="0,1"
+       position="72.563745,37.346999"
+       id="guide2989" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="74.584055,7.2949693"
+       id="guide2991" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="71.048515,20.426949"
+       id="guide2993" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="97.817565,20.174409"
+       id="guide2995" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="71.048515,20.426949"
+       id="guide3017" />
+    <inkscape:grid
+       type="xygrid"
+       id="grid3019"
+       empspacing="5"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="105.6589,-12.377861"
+       id="guide3021" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="126.6589,-16.377861"
+       id="guide3023" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="110.6589,-3.3778607"
+       id="guide3025" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="110.6589,-27.377861"
+       id="guide3027" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="19.658895,-35.37786"
+       id="guide3810" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="21.658895,-70.377861"
+       id="guide3814" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="2.301752,-9.4850007"
+       id="guide3856" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="26.601806,-9.4850007"
+       id="guide3887" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="44.658283,37.346999"
+       id="guide4019" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="126.6589,-27.377861"
+       id="guide4481" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="159.08747,-213.94929"
+       id="guide4483" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-42.341105,-35.859333)">
+    <path
+       inkscape:connector-curvature="0"
+       style="fill:url(#radialGradient3262);fill-opacity:1;stroke:none"
+       d="m 98.2161,35.859333 c -30.850815,0 -55.874995,24.87043 -55.874995,55.562497 0,30.69207 25.02418,55.56249 55.874995,55.56249 10.09496,0 19.54625,-2.6525 27.71875,-7.3125 l 2.90625,7.3125 2.40625,0 20,0 0.125,0 -8.8125,-21.78124 c 7.21537,-9.3622 11.5,-21.07236 11.5,-33.78125 0,-30.692067 -24.99293,-55.562497 -55.84375,-55.562497 z"
+       id="path3834-7-7-2-5-5-0-5-4" />
+    <path
+       sodipodi:type="arc"
+       style="fill:url(#linearGradient3264);fill-opacity:1;stroke:none"
+       id="path3661"
+       sodipodi:cx="142.5"
+       sodipodi:cy="856.29077"
+       sodipodi:rx="35.357143"
+       sodipodi:ry="24.642857"
+       d="m 177.85714,856.29077 c 0,13.60988 -15.82993,24.64286 -35.35714,24.64286 -19.52721,0 -35.35714,-11.03298 -35.35714,-24.64286 0,-13.60987 15.82993,-24.64286 35.35714,-24.64286 19.52721,0 35.35714,11.03299 35.35714,24.64286 z"
+       transform="matrix(1.0465082,0,0,1.2920463,-51.641235,-1036.8612)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:none"
+       id="path4442"
+       sodipodi:cx="115.66247"
+       sodipodi:cy="856.39258"
+       sodipodi:rx="6.5659914"
+       sodipodi:ry="6.5659914"
+       d="m 122.22846,856.39258 c 0,3.6263 -2.9397,6.56599 -6.56599,6.56599 -3.6263,0 -6.56599,-2.93969 -6.56599,-6.56599 0,-3.6263 2.93969,-6.56599 6.56599,-6.56599 3.62629,0 6.56599,2.93969 6.56599,6.56599 z"
+       transform="translate(-12.329975,-797.60351)" />
+    <rect
+       style="fill:#000000;fill-opacity:1;stroke:none"
+       id="rect4444"
+       width="37.643608"
+       height="5.5005069"
+       x="101.55376"
+       y="48.297417"
+       transform="matrix(0.98974903,0.14281759,-0.18972639,0.981837,0,0)" />
+    <rect
+       style="fill:#000000;fill-opacity:1;stroke:none"
+       id="rect4446"
+       width="6.5659914"
+       height="2.9041886"
+       x="124.92451"
+       y="69.016899" />
+    <path
+       style="fill:#ff6600;fill-opacity:1"
+       d="m 83.38797,45.010543 c -0.057,2.18531 -3.865755,0.28296 -4.031245,2.78125 -4.22387,-1.88052 0.32884,2.87188 -0.0937,3.3125 l -0.0312,0 -0.3125,-0.0312 c -0.20386,-0.0728 -0.49977,-0.19904 -0.9375,-0.46875 -2.9499,2.35025 -3.02157,7.23369 -6.0625,9.9375 -1.99467,4.30504 -2.47977,8.98337 -3.9375,13.46875 -0.71796,4.30292 -1.34881,8.597857 -0.28125,12.906247 0.32053,3.50159 -0.68919,8.25865 2.5,10.71875 4.72728,3.88304 8.65575,8.79543 12.624995,13.46875 6.21914,7.65333 11.72948,15.86251 16.59375,24.4375 0.32431,-2.11756 1.10954,4.26459 2.53125,4.6875 -0.49161,-3.19231 -1.13213,-8.26328 -1.4375,-12.1875 -1.5814,-10.2909 -6.65305,-19.64903 -8.5625,-29.84375 -0.0587,-0.43037 -0.12809,-0.87203 -0.1875,-1.3125 l 0,-1.28125 -0.15625,0 c -0.62551,-5.04297 -0.8504,-10.46546 2.8125,-14.40625 3.73968,-3.772097 9.30633,-4.722447 13.8125,-7.343747 1.00194,-0.59119 2.04921,-1.07174 3.125,-1.40625 0.009,-0.003 0.0228,0.003 0.0312,0 3.11701,-0.96341 6.44862,-0.93323 9.6875,-0.40625 
 0.0479,0.008 0.10841,0.0233 0.15625,0.0312 0.29455,0.0493 0.61389,0.099 0.90625,0.15625 2.37136,0.21133 7.14463,1.13687 8,-0.5 -3.27225,-2.78631 -7.98526,-2.59211 -11.96875,-3.6875 -0.63059,-0.11469 -1.41182,-0.24041 -2.1875,-0.3125 l -3.90625,-0.875 -0.96875,-0.25 0,0.0312 -13.96875,-2.71875 c -0.22212,-0.20226 -0.46434,-0.40933 -0.6875,-0.5625 l 13.625,1.6875 0,-0.0625 c 0.48011,0.10699 0.95576,0.19361 1.4375,0.25 l 0,0.0312 9.625,1.78125 c 1.66103,0.61952 3.4322,1.08374 5.09375,1.1875 2.74263,0.39907 6.22526,4.49092 7.125,4.6875 -0.44096,-4.307 -4.7422,-6.23586 -8.3125,-7.5 -4.1712,-2.02803 -10.4023,-1.95417 -11.0625,-7.5625 -0.1756,-0.39076 -0.34902,-0.78118 -0.5625,-1.15625 l -1.625,-2.15625 0.0625,-0.0312 c -2.21724,-2.61691 -5.34011,-4.52196 -8.65625,-5.25 -3.2914,-1.13611 -6.98773,-2.2671 -10.46875,-2.71875 -1.18132,3.47826 -2.5031,-2.75561 -5.34375,-0.90625 -2.48996,0.29488 -2.14614,0.95256 -4,-0.625 z m 17.90625,10.15625 c 0.90187,-0.0238 1.93277,0.14208 2.96875,0.
 5 2.76259,0.95447 4.56151,2.96523 4.03125,4.5 -0.53026,1.53477 -3.20616,1.98572 -5.96875,1.03125 -2.76259,-0.95447 -4.5615,-2.93398 -4.03125,-4.46875 0.33141,-0.95923 1.49689,-1.52281 3,-1.5625 z"
+       id="path3499-9-7"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/ui/gtk.c b/ui/gtk.c
index 3bc2842..efd7836 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1469,7 +1469,7 @@ void gtk_display_init(DisplayState *ds)
 
     gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook), s->drawing_area, gtk_label_new("VGA"));
 
-    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "qemu-icon.bmp");
+    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "qemu_logo_no_text.svg");
     if (filename) {
         GError *error = NULL;
         GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(filename, &error);
commit 4039736e6f7867a4f937145afec7ab56531c0be4
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sun Jun 2 16:17:49 2013 +0100

    softfloat: Fix shift128Right for shift counts 64..127
    
    shift128Right would give the wrong result for a shift count
    between 64 and 127. This was never noticed because all of
    our uses of this function are guaranteed not to use shift
    counts in this range.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 1370186269-24353-1-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/fpu/softfloat-macros.h b/fpu/softfloat-macros.h
index b5164af..9b09545 100644
--- a/fpu/softfloat-macros.h
+++ b/fpu/softfloat-macros.h
@@ -168,7 +168,7 @@ INLINE void
         z0 = a0>>count;
     }
     else {
-        z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0;
+        z1 = (count < 128) ? (a0 >> (count & 63)) : 0;
         z0 = 0;
     }
     *z1Ptr = z1;
commit bc7d0e66741724216cc104034838eb34f0e94b8d
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Jun 3 17:06:55 2013 +0200

    gdbstub: let the debugger resume from guest panicked state
    
    While in general we forbid a "continue" from the guest panicked
    state, it makes sense to have an exception for that when continuing
    in the debugger.  Perhaps the guest entered that state due to a bug,
    for example, and we want to continue no matter what.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
    Message-id: 1370272015-9659-3-git-send-email-pbonzini at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/gdbstub.c b/gdbstub.c
index e8541f3..94c78ce 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -371,6 +371,9 @@ static inline void gdb_continue(GDBState *s)
 #ifdef CONFIG_USER_ONLY
     s->running_state = 1;
 #else
+    if (runstate_check(RUN_STATE_GUEST_PANICKED)) {
+        runstate_set(RUN_STATE_DEBUG);
+    }
     if (!runstate_needs_reset()) {
         vm_start();
     }
diff --git a/vl.c b/vl.c
index 47ab45d..180fdde 100644
--- a/vl.c
+++ b/vl.c
@@ -610,6 +610,7 @@ static const RunStateTransition runstate_transitions_def[] = {
 
     { RUN_STATE_GUEST_PANICKED, RUN_STATE_PAUSED },
     { RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
+    { RUN_STATE_GUEST_PANICKED, RUN_STATE_DEBUG },
 
     { RUN_STATE_MAX, RUN_STATE_MAX },
 };
commit 26ac7a31fbf5522d2ca3f0e2e5b5c8e915701f66
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Jun 3 17:06:54 2013 +0200

    gdbstub: fix for commit 87f25c12bfeaaa0c41fb857713bbc7e8a9b757dc
    
    This commit used the wrong check to prevent an assertion failure.
    After this commit, you need to start a guest in the monitor, you
    cannot use anymore the "c" command in the debugger.  This is
    undesirable.  The commit's aim was to prevent a restart
    after a KVM internal error or something like that; use
    runstate_needs_reset() for that.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
    Message-id: 1370272015-9659-2-git-send-email-pbonzini at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/gdbstub.c b/gdbstub.c
index 90e54cb..e8541f3 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -371,7 +371,7 @@ static inline void gdb_continue(GDBState *s)
 #ifdef CONFIG_USER_ONLY
     s->running_state = 1;
 #else
-    if (runstate_check(RUN_STATE_DEBUG)) {
+    if (!runstate_needs_reset()) {
         vm_start();
     }
 #endif
commit 4f293bd6e53739e089f33b458f70a9c4ac136b92
Author: Wendy Liang <jliang at xilinx.com>
Date:   Fri Jun 7 13:05:38 2013 +1000

    xilinx_axidma: Do not set DMA .notify to NULL after notify
    
    If a stream notify function is not ready, it may re-populate the notify call-
    back to indicate it should be re-polled later. This break in this usage, as
    immediately following the notify() call, .notify is set to NULL. reverse the
    ordering of the notify call and NULL assignment accordingly.
    
    [PC: Reworked commit message]
    
    Signed-off-by: Wendy Liang <jliang at xilinx.com>
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
index 3a3ef8a..50054cf 100644
--- a/hw/dma/xilinx_axidma.c
+++ b/hw/dma/xilinx_axidma.c
@@ -514,8 +514,9 @@ static void axidma_write(void *opaque, hwaddr addr,
             break;
     }
     if (sid == 1 && d->notify) {
-        d->notify(d->notify_opaque);
+        StreamCanPushNotifyFn notifytmp = d->notify;
         d->notify = NULL;
+        notifytmp(d->notify_opaque);
     }
     stream_update_irq(s);
 }
commit 4e298e46ddcbb3a2a653a582b54557b75180c625
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sun Jun 9 22:56:20 2013 +0200

    xilinx_axienet: Fix bit mask code
    
    Obviously the code wanted to mask the lower bits but failed to do so
    because of a missing "<".
    
    cppcheck detected a conditional expression which was always true (1 < 7).
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index 8989e95..2ca1511 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -575,7 +575,7 @@ static void enet_write(void *opaque, hwaddr addr,
             break;
 
         case R_MC:
-             value &= ((1 < 7) - 1);
+             value &= ((1 << 7) - 1);
 
              /* Enable the MII.  */
              if (value & MC_EN) {
commit 9914fbedf21f1ffd45af67c8f3fe8a2e8f7e7785
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Fri Jun 7 16:52:43 2013 -0300

    correct RTC_CHANGE_EVENT description (v2)
    
    Fix RTC_CHANGE event description to match implementation.
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/QMP/qmp-events.txt b/QMP/qmp-events.txt
index 92fe5fb..24e804e9 100644
--- a/QMP/qmp-events.txt
+++ b/QMP/qmp-events.txt
@@ -203,7 +203,8 @@ Emitted when the guest changes the RTC time.
 
 Data:
 
-- "offset": delta against the host UTC in seconds (json-number)
+- "offset": Offset between base RTC clock (as specified by -rtc base), and
+new RTC clock value (json-number)
 
 Example:
 
commit 8899b4ae2d792967b7655d3081fb2994426e4658
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Mon Jun 3 11:14:26 2013 -0400

    MAINTAINERS: split Monitor (QMP/HMP) entry
    
    This entry doesn't reflect reality for a few years now. This commit
    splits it into Human Monitor (HMP), QAPI and QMP. Markus is dropped
    as a maintainer.
    
    This is what we have been for the last few years. Also, it's going
    to help me to offload some of this work to someone else in the near
    future.
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Acked-by: Markus Armbruster <armbru at redhat.com>

diff --git a/MAINTAINERS b/MAINTAINERS
index 432185a..13c0cc5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -685,11 +685,12 @@ M: Anthony Liguori <aliguori at us.ibm.com>
 S: Supported
 F: vl.c
 
-Monitor (QMP/HMP)
+Human Monitor (HMP)
 M: Luiz Capitulino <lcapitulino at redhat.com>
-M: Markus Armbruster <armbru at redhat.com>
 S: Supported
 F: monitor.c
+F: hmp.c
+F: hmp-commands.hx
 
 Network device layer
 M: Anthony Liguori <aliguori at us.ibm.com>
@@ -706,6 +707,12 @@ F: nbd.*
 F: qemu-nbd.c
 T: git git://github.com/bonzini/qemu.git nbd-next
 
+QAPI
+M: Luiz Capitulino <lcapitulino at redhat.com>
+M: Michael Roth <mdroth at linux.vnet.ibm.com>
+S: Supported
+F: qapi/
+
 QAPI Schema
 M: Eric Blake <eblake at redhat.com>
 M: Luiz Capitulino <lcapitulino at redhat.com>
@@ -713,6 +720,14 @@ M: Markus Armbruster <armbru at redhat.com>
 S: Supported
 F: qapi-schema.json
 
+QMP
+M: Luiz Capitulino <lcapitulino at redhat.com>
+S: Supported
+F: qmp.c
+F: monitor.c
+F: qmp-commands.hx
+F: QMP/
+
 SLIRP
 M: Jan Kiszka <jan.kiszka at siemens.com>
 S: Maintained
commit 7810d29198790a805936e7a2f44c055184a56b0a
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Mon Jun 3 11:11:53 2013 -0400

    MAINTAINERS: new maintainers for qapi-schema.json
    
    I'm facing two problems lately wrt QMP patch review: increasingly
    lack of bandwidth and lack of background in so many different areas
    that are getting new QMP commands almost every week.
    
    In order to help me mitigate this problem, I'm adding Eric and Markus
    (besides me) as maintainers of the qapi-schema.json file.
    
    Markus has been an old timer reviewer. Eric is being the most active
    and prolific reviewer of QMP patches for some time now.
    
    I believe Markus and Eric will keep doing their work as before, but
    starting now I'll require the ACK of at least one of them before
    appling a patch/series that touches the qapi-schema.json file.
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Acked-by: Markus Armbruster <armbru at redhat.com>

diff --git a/MAINTAINERS b/MAINTAINERS
index be02724..432185a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -706,6 +706,13 @@ F: nbd.*
 F: qemu-nbd.c
 T: git git://github.com/bonzini/qemu.git nbd-next
 
+QAPI Schema
+M: Eric Blake <eblake at redhat.com>
+M: Luiz Capitulino <lcapitulino at redhat.com>
+M: Markus Armbruster <armbru at redhat.com>
+S: Supported
+F: qapi-schema.json
+
 SLIRP
 M: Jan Kiszka <jan.kiszka at siemens.com>
 S: Maintained
commit c87826a878be05208c3906eb9d5e1f37cff5e98e
Author: Jason Wang <jasowang at redhat.com>
Date:   Tue Jun 4 13:18:17 2013 +0800

    tap: fix NULL dereference when passing invalid parameters to tap
    
    This patch forbid the following invalid parameters to tap:
    
    1) fd and vhostfds were specified but vhostfd were not specified
    2) vhostfds were specified but fds were not specified
    3) fds and vhostfd were specified
    
    For 1 and 2, net_init_tap_one() will still pass NULL as vhostfdname to
    monitor_handle_fd_param(), which may crash the qemu.
    
    Also remove the unnecessary has_fd check.
    
    Cc: Paolo Bonzini <pbonzini at redhat.com>
    Cc: Stefan Hajnoczi <shajnocz at redhat.com>
    Cc: Laszlo Ersek <lersek at redhat.com>
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Jason Wang <jasowang at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/net/tap.c b/net/tap.c
index e0b7a2a..39c1cda 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -698,9 +698,10 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
     if (tap->has_fd) {
         if (tap->has_ifname || tap->has_script || tap->has_downscript ||
             tap->has_vnet_hdr || tap->has_helper || tap->has_queues ||
-            tap->has_fds) {
+            tap->has_fds || tap->has_vhostfds) {
             error_report("ifname=, script=, downscript=, vnet_hdr=, "
-                         "helper=, queues=, and fds= are invalid with fd=");
+                         "helper=, queues=, fds=, and vhostfds= "
+                         "are invalid with fd=");
             return -1;
         }
 
@@ -725,9 +726,10 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
 
         if (tap->has_ifname || tap->has_script || tap->has_downscript ||
             tap->has_vnet_hdr || tap->has_helper || tap->has_queues ||
-            tap->has_fd) {
+            tap->has_vhostfd) {
             error_report("ifname=, script=, downscript=, vnet_hdr=, "
-                         "helper=, queues=, and fd= are invalid with fds=");
+                         "helper=, queues=, and vhostfd= "
+                         "are invalid with fds=");
             return -1;
         }
 
@@ -765,9 +767,9 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
         }
     } else if (tap->has_helper) {
         if (tap->has_ifname || tap->has_script || tap->has_downscript ||
-            tap->has_vnet_hdr || tap->has_queues || tap->has_fds) {
+            tap->has_vnet_hdr || tap->has_queues || tap->has_vhostfds) {
             error_report("ifname=, script=, downscript=, and vnet_hdr= "
-                         "queues=, and fds= are invalid with helper=");
+                         "queues=, and vhostfds= are invalid with helper=");
             return -1;
         }
 
@@ -785,6 +787,10 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
             return -1;
         }
     } else {
+        if (tap->has_vhostfds) {
+            error_report("vhostfds= is invalid if fds= wasn't specified");
+            return -1;
+        }
         script = tap->has_script ? tap->script : DEFAULT_NETWORK_SCRIPT;
         downscript = tap->has_downscript ? tap->downscript :
             DEFAULT_NETWORK_DOWN_SCRIPT;
commit 7387de16d0e4d2988df350926537cd12a8e34206
Merge: b8a75b6 e73fe2b
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Jun 7 08:40:52 2013 -0500

    Merge remote-tracking branch 'stefanha/block' into staging
    
    # By Kevin Wolf (19) and others
    # Via Stefan Hajnoczi
    * stefanha/block: (26 commits)
      hmp: add parameters device and -v for info block
      hmp: show ImageInfo in 'info block'
      qmp: add ImageInfo in BlockDeviceInfo used by query-block
      block: add image info query function bdrv_query_image_info()
      block: add snapshot info query function bdrv_query_snapshot_info_list()
      ide-test: Add FLUSH CACHE test case
      ide: Set BSY bit during FLUSH
      ide-test: Add enum value for DEV
      blkdebug: Add BLKDBG_FLUSH_TO_OS/DISK events
      Make qemu-io commands available in HMP
      qemu-io: Use the qemu version for -V
      qemu-io: Interface cleanup
      qemu-io: Move remaining helpers from cmd.c
      qemu-io: Move command_loop() and friends
      qemu-io: Move functions for registering and running commands
      qemu-io: Move qemu_strsep() to cutils.c
      qemu-io: Move 'quit' function
      qemu-io: Move 'help' function
      qemu-io: Factor out qemuio_command
      qemu-io: Split off commands to qemu-io-cmds.c
      ...
    
    Message-id: 1370606325-10680-1-git-send-email-stefanha at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit b8a75b6093309a43f9837bc2ce63bcf15a7b305f
Merge: 8819c10 d1db1fa
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Jun 7 08:40:24 2013 -0500

    Merge remote-tracking branch 'cohuck/virtio-ccw-upstr' into staging
    
    # By Cornelia Huck
    # Via Cornelia Huck
    * cohuck/virtio-ccw-upstr:
      virtio-ccw: Fix unsetting of indicators.
      s390x/css: Fix concurrent sense.
    
    Message-id: 1370592676-22532-1-git-send-email-cornelia.huck at de.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit fef7fbc92496f5f6d2b7395263830bce15ebf410
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Jun 7 14:45:17 2013 +0200

    qdev: Drop FROM_QBUS() macro
    
    Use QOM cast macros I2C_BUS(), SSI_BUS(), PCI_BUS() instead.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index 0c4fc1d..22ef3b9 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -66,7 +66,7 @@ i2c_bus *i2c_init_bus(DeviceState *parent, const char *name)
 {
     i2c_bus *bus;
 
-    bus = FROM_QBUS(i2c_bus, qbus_create(TYPE_I2C_BUS, parent, name));
+    bus = I2C_BUS(qbus_create(TYPE_I2C_BUS, parent, name));
     vmstate_register(NULL, -1, &vmstate_i2c_bus, bus);
     return bus;
 }
@@ -183,7 +183,7 @@ static int i2c_slave_post_load(void *opaque, int version_id)
 {
     I2CSlave *dev = opaque;
     i2c_bus *bus;
-    bus = FROM_QBUS(i2c_bus, qdev_get_parent_bus(&dev->qdev));
+    bus = I2C_BUS(qdev_get_parent_bus(DEVICE(dev)));
     if (bus->saved_address == dev->address) {
         bus->current_dev = dev;
     }
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index bb3879b..a3eb19e 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1700,7 +1700,7 @@ static int pci_qdev_init(DeviceState *qdev)
         pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
     }
 
-    bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
+    bus = PCI_BUS(qdev_get_parent_bus(qdev));
     pci_dev = do_pci_register_device(pci_dev, bus,
                                      object_get_typename(OBJECT(qdev)),
                                      pci_dev->devfn);
diff --git a/hw/ssi/ssi.c b/hw/ssi/ssi.c
index 1264d9d..2c25260 100644
--- a/hw/ssi/ssi.c
+++ b/hw/ssi/ssi.c
@@ -103,7 +103,7 @@ SSIBus *ssi_create_bus(DeviceState *parent, const char *name)
 {
     BusState *bus;
     bus = qbus_create(TYPE_SSI_BUS, parent, name);
-    return FROM_QBUS(SSIBus, bus);
+    return SSI_BUS(bus);
 }
 
 uint32_t ssi_transfer(SSIBus *bus, uint32_t val)
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index cf83d54..7fbffcb 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -261,8 +261,6 @@ void qbus_reset_all_fn(void *opaque);
 
 void qbus_free(BusState *bus);
 
-#define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev)
-
 /* This should go away once we get rid of the NULL bus hack */
 BusState *sysbus_get_default(void);
 
commit 4a17cc4f285d7ffe41847bf728cd88c736237416
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Jun 7 13:49:13 2013 +0200

    isa: QOM'ify ISADevice
    
    Rename its parent field and use DEVICE() where necessary.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 79ea625..930f191 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -2022,22 +2022,24 @@ static int fdctrl_connect_drives(FDCtrl *fdctrl)
 
 ISADevice *fdctrl_init_isa(ISABus *bus, DriveInfo **fds)
 {
-    ISADevice *dev;
+    DeviceState *dev;
+    ISADevice *isadev;
 
-    dev = isa_try_create(bus, TYPE_ISA_FDC);
-    if (!dev) {
+    isadev = isa_try_create(bus, TYPE_ISA_FDC);
+    if (!isadev) {
         return NULL;
     }
+    dev = DEVICE(isadev);
 
     if (fds[0]) {
-        qdev_prop_set_drive_nofail(&dev->qdev, "driveA", fds[0]->bdrv);
+        qdev_prop_set_drive_nofail(dev, "driveA", fds[0]->bdrv);
     }
     if (fds[1]) {
-        qdev_prop_set_drive_nofail(&dev->qdev, "driveB", fds[1]->bdrv);
+        qdev_prop_set_drive_nofail(dev, "driveB", fds[1]->bdrv);
     }
-    qdev_init_nofail(&dev->qdev);
+    qdev_init_nofail(dev);
 
-    return dev;
+    return isadev;
 }
 
 void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c
index 6e7e0dd..e06a802 100644
--- a/hw/char/serial-isa.c
+++ b/hw/char/serial-isa.c
@@ -120,15 +120,17 @@ type_init(serial_register_types)
 
 bool serial_isa_init(ISABus *bus, int index, CharDriverState *chr)
 {
-    ISADevice *dev;
+    DeviceState *dev;
+    ISADevice *isadev;
 
-    dev = isa_try_create(bus, TYPE_ISA_SERIAL);
-    if (!dev) {
+    isadev = isa_try_create(bus, TYPE_ISA_SERIAL);
+    if (!isadev) {
         return false;
     }
-    qdev_prop_set_uint32(&dev->qdev, "index", index);
-    qdev_prop_set_chr(&dev->qdev, "chardev", chr);
-    if (qdev_init(&dev->qdev) < 0) {
+    dev = DEVICE(isadev);
+    qdev_prop_set_uint32(dev, "index", index);
+    qdev_prop_set_chr(dev, "chardev", chr);
+    if (qdev_init(dev) < 0) {
         return false;
     }
     return true;
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index e9c91e4..0ad062c 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1095,7 +1095,7 @@ DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus)
         dev = pcidev ? &pcidev->qdev : NULL;
     } else if (isa_bus) {
         ISADevice *isadev = isa_vga_init(isa_bus);
-        dev = isadev ? &isadev->qdev : NULL;
+        dev = isadev ? DEVICE(isadev) : NULL;
     }
     return dev;
 }
@@ -1182,7 +1182,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
         }
         if (hpet) {
             /* connect PIT to output control line of the HPET */
-            qdev_connect_gpio_out(hpet, 0, qdev_get_gpio_in(&pit->qdev, 0));
+            qdev_connect_gpio_out(hpet, 0, qdev_get_gpio_in(DEVICE(pit), 0));
         }
         pcspk_init(isa_bus, pit);
     }
@@ -1210,8 +1210,9 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
         vmmouse = NULL;
     }
     if (vmmouse) {
-        qdev_prop_set_ptr(&vmmouse->qdev, "ps2_mouse", i8042);
-        qdev_init_nofail(&vmmouse->qdev);
+        DeviceState *dev = DEVICE(vmmouse);
+        qdev_prop_set_ptr(dev, "ps2_mouse", i8042);
+        qdev_init_nofail(dev);
     }
     port92 = isa_create_simple(isa_bus, "port92");
     port92_init(port92, &a20_line[1]);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index d618570..af1e9af 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -199,7 +199,7 @@ static void pc_init1(MemoryRegion *system_memory,
             dev = isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i],
                                ide_irq[i],
                                hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
-            idebus[i] = qdev_get_child_bus(&dev->qdev, "ide.0");
+            idebus[i] = qdev_get_child_bus(DEVICE(dev), "ide.0");
         }
     }
 
diff --git a/hw/intc/i8259_common.c b/hw/intc/i8259_common.c
index 7613547..803d037 100644
--- a/hw/intc/i8259_common.c
+++ b/hw/intc/i8259_common.c
@@ -80,16 +80,18 @@ static void pic_common_realize(DeviceState *dev, Error **errp)
 
 ISADevice *i8259_init_chip(const char *name, ISABus *bus, bool master)
 {
-    ISADevice *dev;
-
-    dev = isa_create(bus, name);
-    qdev_prop_set_uint32(&dev->qdev, "iobase", master ? 0x20 : 0xa0);
-    qdev_prop_set_uint32(&dev->qdev, "elcr_addr", master ? 0x4d0 : 0x4d1);
-    qdev_prop_set_uint8(&dev->qdev, "elcr_mask", master ? 0xf8 : 0xde);
-    qdev_prop_set_bit(&dev->qdev, "master", master);
-    qdev_init_nofail(&dev->qdev);
-
-    return dev;
+    DeviceState *dev;
+    ISADevice *isadev;
+
+    isadev = isa_create(bus, name);
+    dev = DEVICE(isadev);
+    qdev_prop_set_uint32(dev, "iobase", master ? 0x20 : 0xa0);
+    qdev_prop_set_uint32(dev, "elcr_addr", master ? 0x4d0 : 0x4d1);
+    qdev_prop_set_uint8(dev, "elcr_mask", master ? 0xf8 : 0xde);
+    qdev_prop_set_bit(dev, "master", master);
+    qdev_init_nofail(dev);
+
+    return isadev;
 }
 
 static const VMStateDescription vmstate_pic_common = {
diff --git a/hw/isa/i82378.c b/hw/isa/i82378.c
index 278e178..a24cb98 100644
--- a/hw/isa/i82378.c
+++ b/hw/isa/i82378.c
@@ -201,7 +201,7 @@ static void i82378_init(DeviceState *dev, I82378State *s)
 
     /* 2 82C37 (dma) */
     isa = isa_create_simple(isabus, "i82374");
-    qdev_connect_gpio_out(&isa->qdev, 0, s->out[1]);
+    qdev_connect_gpio_out(DEVICE(isa), 0, s->out[1]);
 
     /* timer */
     isa_create_simple(isabus, "mc146818rtc");
diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index 7aa9b89..136d17e 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -156,7 +156,7 @@ ISADevice *isa_create_simple(ISABus *bus, const char *name)
     ISADevice *dev;
 
     dev = isa_create(bus, name);
-    qdev_init_nofail(&dev->qdev);
+    qdev_init_nofail(DEVICE(dev));
     return dev;
 }
 
@@ -240,7 +240,7 @@ static void isabus_register_types(void)
 
 static char *isabus_get_fw_dev_path(DeviceState *dev)
 {
-    ISADevice *d = (ISADevice*)dev;
+    ISADevice *d = ISA_DEVICE(dev);
     char path[40];
     int off;
 
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 9e770ab..4fdc164 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -605,8 +605,9 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
 
     /* Super I/O (parallel + serial ports) */
     isa = isa_create(isa_bus, TYPE_PC87312);
-    qdev_prop_set_uint8(&isa->qdev, "config", 13); /* fdc, ser0, ser1, par0 */
-    qdev_init_nofail(&isa->qdev);
+    dev = DEVICE(isa);
+    qdev_prop_set_uint8(dev, "config", 13); /* fdc, ser0, ser1, par0 */
+    qdev_init_nofail(dev);
 
     /* Register 8 MB of ISA IO space (needed for non-contiguous map) */
     memory_region_init_io(PPC_io_memory, &PPC_prep_io_ops, sysctrl,
diff --git a/include/hw/audio/pcspk.h b/include/hw/audio/pcspk.h
index 7625137..ef95dd1 100644
--- a/include/hw/audio/pcspk.h
+++ b/include/hw/audio/pcspk.h
@@ -32,14 +32,16 @@
 
 static inline ISADevice *pcspk_init(ISABus *bus, ISADevice *pit)
 {
-    ISADevice *dev;
+    DeviceState *dev;
+    ISADevice *isadev;
 
-    dev = isa_create(bus, TYPE_PC_SPEAKER);
-    qdev_prop_set_uint32(&dev->qdev, "iobase", 0x61);
-    qdev_prop_set_ptr(&dev->qdev, "pit", pit);
-    qdev_init_nofail(&dev->qdev);
+    isadev = isa_create(bus, TYPE_PC_SPEAKER);
+    dev = DEVICE(isadev);
+    qdev_prop_set_uint32(dev, "iobase", 0x61);
+    qdev_prop_set_ptr(dev, "pit", pit);
+    qdev_init_nofail(dev);
 
-    return dev;
+    return isadev;
 }
 
 #endif /* !HW_PCSPK_H */
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 6154058..5d883eb 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -14,15 +14,17 @@
 /* parallel.c */
 static inline bool parallel_init(ISABus *bus, int index, CharDriverState *chr)
 {
-    ISADevice *dev;
+    DeviceState *dev;
+    ISADevice *isadev;
 
-    dev = isa_try_create(bus, "isa-parallel");
-    if (!dev) {
+    isadev = isa_try_create(bus, "isa-parallel");
+    if (!isadev) {
         return false;
     }
-    qdev_prop_set_uint32(&dev->qdev, "index", index);
-    qdev_prop_set_chr(&dev->qdev, "chardev", chr);
-    if (qdev_init(&dev->qdev) < 0) {
+    dev = DEVICE(isadev);
+    qdev_prop_set_uint32(dev, "index", index);
+    qdev_prop_set_chr(dev, "chardev", chr);
+    if (qdev_init(dev) < 0) {
         return false;
     }
     return true;
@@ -155,18 +157,20 @@ int isa_vga_mm_init(hwaddr vram_base,
 /* ne2000.c */
 static inline bool isa_ne2000_init(ISABus *bus, int base, int irq, NICInfo *nd)
 {
-    ISADevice *dev;
+    DeviceState *dev;
+    ISADevice *isadev;
 
     qemu_check_nic_model(nd, "ne2k_isa");
 
-    dev = isa_try_create(bus, "ne2k_isa");
-    if (!dev) {
+    isadev = isa_try_create(bus, "ne2k_isa");
+    if (!isadev) {
         return false;
     }
-    qdev_prop_set_uint32(&dev->qdev, "iobase", base);
-    qdev_prop_set_uint32(&dev->qdev, "irq",    irq);
-    qdev_set_nic_properties(&dev->qdev, nd);
-    qdev_init_nofail(&dev->qdev);
+    dev = DEVICE(isadev);
+    qdev_prop_set_uint32(dev, "iobase", base);
+    qdev_prop_set_uint32(dev, "irq",    irq);
+    qdev_set_nic_properties(dev, nd);
+    qdev_init_nofail(dev);
     return true;
 }
 
diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index da731d7..e1bf96c 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -34,7 +34,10 @@ struct ISABus {
 };
 
 struct ISADevice {
-    DeviceState qdev;
+    /*< private >*/
+    DeviceState parent_obj;
+    /*< public >*/
+
     uint32_t isairq[2];
     int nirqs;
     int ioport_id;
commit 2ae0e48d5fd2cb7c5bc5c392edf2dc33ac2959d0
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Jun 7 14:11:07 2013 +0200

    isa: QOM'ify ISABus
    
    Rename its parent field and use ISA_BUS() where necessary.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/isa/i82378.c b/hw/isa/i82378.c
index cced9af..278e178 100644
--- a/hw/isa/i82378.c
+++ b/hw/isa/i82378.c
@@ -168,7 +168,7 @@ static void i82378_request_pic_irq(void *opaque, int irq, int level)
 
 static void i82378_init(DeviceState *dev, I82378State *s)
 {
-    ISABus *isabus = DO_UPCAST(ISABus, qbus, qdev_get_child_bus(dev, "isa.0"));
+    ISABus *isabus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
     ISADevice *pit;
     ISADevice *isa;
     qemu_irq *out0_irq;
diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index f12b15d..7aa9b89 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -55,7 +55,7 @@ ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space_io)
         qdev_init_nofail(dev);
     }
 
-    isabus = FROM_QBUS(ISABus, qbus_create(TYPE_ISA_BUS, dev, NULL));
+    isabus = ISA_BUS(qbus_create(TYPE_ISA_BUS, dev, NULL));
     isabus->address_space_io = address_space_io;
     return isabus;
 }
@@ -76,7 +76,7 @@ void isa_bus_irqs(ISABus *bus, qemu_irq *irqs)
  */
 qemu_irq isa_get_irq(ISADevice *dev, int isairq)
 {
-    assert(!dev || DO_UPCAST(ISABus, qbus, dev->qdev.parent_bus) == isabus);
+    assert(!dev || ISA_BUS(qdev_get_parent_bus(DEVICE(dev))) == isabus);
     if (isairq < 0 || isairq > 15) {
         hw_error("isa irq %d invalid", isairq);
     }
@@ -135,7 +135,7 @@ ISADevice *isa_create(ISABus *bus, const char *name)
         hw_error("Tried to create isa device %s with no isa bus present.",
                  name);
     }
-    dev = qdev_create(&bus->qbus, name);
+    dev = qdev_create(BUS(bus), name);
     return ISA_DEVICE(dev);
 }
 
@@ -147,7 +147,7 @@ ISADevice *isa_try_create(ISABus *bus, const char *name)
         hw_error("Tried to create isa device %s with no isa bus present.",
                  name);
     }
-    dev = qdev_try_create(&bus->qbus, name);
+    dev = qdev_try_create(BUS(bus), name);
     return ISA_DEVICE(dev);
 }
 
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index d750413..1a1d451 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -98,7 +98,7 @@ int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn)
     PCIDevice *d;
 
     d = pci_create_simple_multifunction(bus, devfn, true, "PIIX4");
-    *isa_bus = DO_UPCAST(ISABus, qbus, qdev_get_child_bus(&d->qdev, "isa.0"));
+    *isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(d), "isa.0"));
     return d->devfn;
 }
 
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 5261927..391d90d 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -450,7 +450,7 @@ ISABus *vt82c686b_init(PCIBus *bus, int devfn)
 
     d = pci_create_simple_multifunction(bus, devfn, true, "VT82C686B");
 
-    return DO_UPCAST(ISABus, qbus, qdev_get_child_bus(&d->qdev, "isa.0"));
+    return ISA_BUS(qdev_get_child_bus(DEVICE(d), "isa.0"));
 }
 
 static void via_class_init(ObjectClass *klass, void *data)
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index be8a50e..9e770ab 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -601,7 +601,7 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
     sysbus_connect_irq(&pcihost->busdev, 1, qdev_get_gpio_in(&pci->qdev, 11));
     sysbus_connect_irq(&pcihost->busdev, 2, qdev_get_gpio_in(&pci->qdev, 9));
     sysbus_connect_irq(&pcihost->busdev, 3, qdev_get_gpio_in(&pci->qdev, 11));
-    isa_bus = DO_UPCAST(ISABus, qbus, qdev_get_child_bus(&pci->qdev, "isa.0"));
+    isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(pci), "isa.0"));
 
     /* Super I/O (parallel + serial ports) */
     isa = isa_create(isa_bus, TYPE_PC87312);
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 2c2a111..a6a3b76 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -585,8 +585,7 @@ pci_ebus_init(PCIBus *bus, int devfn, qemu_irq *irqs)
     ISABus *isa_bus;
 
     pci_dev = pci_create_simple(bus, devfn, "ebus");
-    isa_bus = DO_UPCAST(ISABus, qbus,
-                        qdev_get_child_bus(&pci_dev->qdev, "isa.0"));
+    isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(pci_dev), "isa.0"));
     isa_irq = qemu_allocate_irqs(isa_irq_handler, irqs, 16);
     isa_bus_irqs(isa_bus, isa_irq);
     return isa_bus;
diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index 1f6ff55..da731d7 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -25,7 +25,10 @@ typedef struct ISADeviceClass {
 } ISADeviceClass;
 
 struct ISABus {
-    BusState qbus;
+    /*< private >*/
+    BusState parent_obj;
+    /*< public >*/
+
     MemoryRegion *address_space_io;
     qemu_irq *irqs;
 };
commit d2628b7d18521dacd3d4d246602e9bb3fc2a43dd
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Nov 25 22:54:47 2012 +0100

    i8259: Convert PICCommonState to use QOM realizefn
    
    Instead of having the parent provide PICCommonClass::init,
    let the children override DeviceClass::realize themselves.
    This pushes the responsibility of saving and calling the parent's
    realizefn to the children.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/i386/kvm/i8259.c b/hw/i386/kvm/i8259.c
index 0bfbe34..1250224 100644
--- a/hw/i386/kvm/i8259.c
+++ b/hw/i386/kvm/i8259.c
@@ -14,6 +14,20 @@
 #include "sysemu/kvm.h"
 
 #define TYPE_KVM_I8259 "kvm-i8259"
+#define KVM_PIC_CLASS(class) \
+    OBJECT_CLASS_CHECK(KVMPICClass, (class), TYPE_KVM_I8259)
+#define KVM_PIC_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(KVMPICClass, (obj), TYPE_KVM_I8259)
+
+/**
+ * KVMPICClass:
+ * @parent_realize: The parent's realizefn.
+ */
+typedef struct KVMPICClass {
+    PICCommonClass parent_class;
+
+    DeviceRealize parent_realize;
+} KVMPICClass;
 
 static void kvm_pic_get(PICCommonState *s)
 {
@@ -100,10 +114,15 @@ static void kvm_pic_set_irq(void *opaque, int irq, int level)
     apic_report_irq_delivered(delivered);
 }
 
-static void kvm_pic_init(PICCommonState *s)
+static void kvm_pic_realize(DeviceState *dev, Error **errp)
 {
+    PICCommonState *s = PIC_COMMON(dev);
+    KVMPICClass *kpc = KVM_PIC_GET_CLASS(dev);
+
     memory_region_init_reservation(&s->base_io, "kvm-pic", 2);
     memory_region_init_reservation(&s->elcr_io, "kvm-elcr", 1);
+
+    kpc->parent_realize(dev, errp);
 }
 
 qemu_irq *kvm_i8259_init(ISABus *bus)
@@ -116,11 +135,13 @@ qemu_irq *kvm_i8259_init(ISABus *bus)
 
 static void kvm_i8259_class_init(ObjectClass *klass, void *data)
 {
+    KVMPICClass *kpc = KVM_PIC_CLASS(klass);
     PICCommonClass *k = PIC_COMMON_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->reset     = kvm_pic_reset;
-    k->init       = kvm_pic_init;
+    kpc->parent_realize = dc->realize;
+    dc->realize   = kvm_pic_realize;
     k->pre_save   = kvm_pic_get;
     k->post_load  = kvm_pic_put;
 }
@@ -130,6 +151,7 @@ static const TypeInfo kvm_i8259_info = {
     .parent = TYPE_PIC_COMMON,
     .instance_size = sizeof(PICCommonState),
     .class_init = kvm_i8259_class_init,
+    .class_size = sizeof(KVMPICClass),
 };
 
 static void kvm_pic_register_types(void)
diff --git a/hw/intc/i8259.c b/hw/intc/i8259.c
index 1b513ff..192a0ba 100644
--- a/hw/intc/i8259.c
+++ b/hw/intc/i8259.c
@@ -42,6 +42,18 @@
 //#define DEBUG_IRQ_COUNT
 
 #define TYPE_I8259 "isa-i8259"
+#define PIC_CLASS(class) OBJECT_CLASS_CHECK(PICClass, (class), TYPE_I8259)
+#define PIC_GET_CLASS(obj) OBJECT_GET_CLASS(PICClass, (obj), TYPE_I8259)
+
+/**
+ * PICClass:
+ * @parent_realize: The parent's realizefn.
+ */
+typedef struct PICClass {
+    PICCommonClass parent_class;
+
+    DeviceRealize parent_realize;
+} PICClass;
 
 #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
 static int irq_level[16];
@@ -400,15 +412,18 @@ static const MemoryRegionOps pic_elcr_ioport_ops = {
     },
 };
 
-static void pic_init(PICCommonState *s)
+static void pic_realize(DeviceState *dev, Error **err)
 {
-    DeviceState *dev = DEVICE(s);
+    PICCommonState *s = PIC_COMMON(dev);
+    PICClass *pc = PIC_GET_CLASS(dev);
 
     memory_region_init_io(&s->base_io, &pic_base_ioport_ops, s, "pic", 2);
     memory_region_init_io(&s->elcr_io, &pic_elcr_ioport_ops, s, "elcr", 1);
 
     qdev_init_gpio_out(dev, s->int_out, ARRAY_SIZE(s->int_out));
     qdev_init_gpio_in(dev, pic_set_irq, 8);
+
+    pc->parent_realize(dev, err);
 }
 
 void pic_info(Monitor *mon, const QDict *qdict)
@@ -481,10 +496,11 @@ qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq)
 
 static void i8259_class_init(ObjectClass *klass, void *data)
 {
-    PICCommonClass *k = PIC_COMMON_CLASS(klass);
+    PICClass *k = PIC_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
-    k->init = pic_init;
+    k->parent_realize = dc->realize;
+    dc->realize = pic_realize;
     dc->reset = pic_reset;
 }
 
@@ -493,6 +509,7 @@ static const TypeInfo i8259_info = {
     .instance_size = sizeof(PICCommonState),
     .parent     = TYPE_PIC_COMMON,
     .class_init = i8259_class_init,
+    .class_size = sizeof(PICClass),
 };
 
 static void pic_register_types(void)
diff --git a/hw/intc/i8259_common.c b/hw/intc/i8259_common.c
index a3dee38..7613547 100644
--- a/hw/intc/i8259_common.c
+++ b/hw/intc/i8259_common.c
@@ -69,9 +69,6 @@ static int pic_dispatch_post_load(void *opaque, int version_id)
 static void pic_common_realize(DeviceState *dev, Error **errp)
 {
     PICCommonState *s = PIC_COMMON(dev);
-    PICCommonClass *info = PIC_COMMON_GET_CLASS(s);
-
-    info->init(s);
 
     isa_register_ioport(NULL, &s->base_io, s->iobase);
     if (s->elcr_addr != -1) {
diff --git a/include/hw/isa/i8259_internal.h b/include/hw/isa/i8259_internal.h
index b4e757a..cded509 100644
--- a/include/hw/isa/i8259_internal.h
+++ b/include/hw/isa/i8259_internal.h
@@ -42,7 +42,7 @@ typedef struct PICCommonState PICCommonState;
 typedef struct PICCommonClass
 {
     ISADeviceClass parent_class;
-    void (*init)(PICCommonState *s);
+
     void (*pre_save)(PICCommonState *s);
     void (*post_load)(PICCommonState *s);
 } PICCommonClass;
commit 49fdb0c1c42f02ab163206f34fcf59bb0815afa2
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Nov 25 22:38:13 2012 +0100

    kvm/i8259: QOM'ify some more
    
    Introduce type constant.
    
    Prepares for PIC realizefn.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/i386/kvm/i8259.c b/hw/i386/kvm/i8259.c
index d961eca..0bfbe34 100644
--- a/hw/i386/kvm/i8259.c
+++ b/hw/i386/kvm/i8259.c
@@ -13,6 +13,8 @@
 #include "hw/i386/apic_internal.h"
 #include "sysemu/kvm.h"
 
+#define TYPE_KVM_I8259 "kvm-i8259"
+
 static void kvm_pic_get(PICCommonState *s)
 {
     struct kvm_irqchip chip;
@@ -106,8 +108,8 @@ static void kvm_pic_init(PICCommonState *s)
 
 qemu_irq *kvm_i8259_init(ISABus *bus)
 {
-    i8259_init_chip("kvm-i8259", bus, true);
-    i8259_init_chip("kvm-i8259", bus, false);
+    i8259_init_chip(TYPE_KVM_I8259, bus, true);
+    i8259_init_chip(TYPE_KVM_I8259, bus, false);
 
     return qemu_allocate_irqs(kvm_pic_set_irq, NULL, ISA_NUM_IRQS);
 }
@@ -124,7 +126,7 @@ static void kvm_i8259_class_init(ObjectClass *klass, void *data)
 }
 
 static const TypeInfo kvm_i8259_info = {
-    .name  = "kvm-i8259",
+    .name = TYPE_KVM_I8259,
     .parent = TYPE_PIC_COMMON,
     .instance_size = sizeof(PICCommonState),
     .class_init = kvm_i8259_class_init,
commit d1eebf4e3df8882d7be6377e1251123b6c16b9b0
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Nov 25 22:35:49 2012 +0100

    i8259: QOM'ify some more
    
    Introduce type constant.
    
    Prepares for PIC realizefn.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/intc/i8259.c b/hw/intc/i8259.c
index fef00fc..1b513ff 100644
--- a/hw/intc/i8259.c
+++ b/hw/intc/i8259.c
@@ -41,6 +41,8 @@
 //#define DEBUG_IRQ_LATENCY
 //#define DEBUG_IRQ_COUNT
 
+#define TYPE_I8259 "isa-i8259"
+
 #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
 static int irq_level[16];
 #endif
@@ -448,25 +450,28 @@ void irq_info(Monitor *mon, const QDict *qdict)
 qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq)
 {
     qemu_irq *irq_set;
-    ISADevice *dev;
+    DeviceState *dev;
+    ISADevice *isadev;
     int i;
 
     irq_set = g_malloc(ISA_NUM_IRQS * sizeof(qemu_irq));
 
-    dev = i8259_init_chip("isa-i8259", bus, true);
+    isadev = i8259_init_chip(TYPE_I8259, bus, true);
+    dev = DEVICE(isadev);
 
-    qdev_connect_gpio_out(&dev->qdev, 0, parent_irq);
+    qdev_connect_gpio_out(dev, 0, parent_irq);
     for (i = 0 ; i < 8; i++) {
-        irq_set[i] = qdev_get_gpio_in(&dev->qdev, i);
+        irq_set[i] = qdev_get_gpio_in(dev, i);
     }
 
-    isa_pic = &dev->qdev;
+    isa_pic = dev;
 
-    dev = i8259_init_chip("isa-i8259", bus, false);
+    isadev = i8259_init_chip(TYPE_I8259, bus, false);
+    dev = DEVICE(isadev);
 
-    qdev_connect_gpio_out(&dev->qdev, 0, irq_set[2]);
+    qdev_connect_gpio_out(dev, 0, irq_set[2]);
     for (i = 0 ; i < 8; i++) {
-        irq_set[i + 8] = qdev_get_gpio_in(&dev->qdev, i);
+        irq_set[i + 8] = qdev_get_gpio_in(dev, i);
     }
 
     slave_pic = PIC_COMMON(dev);
@@ -484,7 +489,7 @@ static void i8259_class_init(ObjectClass *klass, void *data)
 }
 
 static const TypeInfo i8259_info = {
-    .name       = "isa-i8259",
+    .name       = TYPE_I8259,
     .instance_size = sizeof(PICCommonState),
     .parent     = TYPE_PIC_COMMON,
     .class_init = i8259_class_init,
commit a15d09127b104d1c35fc22bdd65263fe62462b30
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Nov 25 18:47:58 2012 +0100

    i8254: Convert PITCommonState to QOM realizefn
    
    Instead of having the parent provide PITCommonClass::init,
    let the children override DeviceClass::realize themselves.
    This pushes the responsibility for saving and calling the parent's
    realizefn to the children.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c
index 4ac5551..93a3669 100644
--- a/hw/i386/kvm/i8254.c
+++ b/hw/i386/kvm/i8254.c
@@ -33,6 +33,10 @@
 #define CALIBRATION_ROUNDS   3
 
 #define KVM_PIT(obj) OBJECT_CHECK(KVMPITState, (obj), TYPE_KVM_I8254)
+#define KVM_PIT_CLASS(class) \
+    OBJECT_CLASS_CHECK(KVMPITClass, (class), TYPE_KVM_I8254)
+#define KVM_PIT_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(KVMPITClass, (obj), TYPE_KVM_I8254)
 
 typedef struct KVMPITState {
     PITCommonState parent_obj;
@@ -42,6 +46,12 @@ typedef struct KVMPITState {
     int64_t kernel_clock_offset;
 } KVMPITState;
 
+typedef struct KVMPITClass {
+    PITCommonClass parent_class;
+
+    DeviceRealize parent_realize;
+} KVMPITClass;
+
 static int64_t abs64(int64_t v)
 {
     return v < 0 ? -v : v;
@@ -237,8 +247,10 @@ static void kvm_pit_vm_state_change(void *opaque, int running,
     }
 }
 
-static int kvm_pit_initfn(PITCommonState *pit)
+static void kvm_pit_realizefn(DeviceState *dev, Error **errp)
 {
+    PITCommonState *pit = PIT_COMMON(dev);
+    KVMPITClass *kpc = KVM_PIT_GET_CLASS(dev);
     KVMPITState *s = KVM_PIT(pit);
     struct kvm_pit_config config = {
         .flags = 0,
@@ -251,9 +263,9 @@ static int kvm_pit_initfn(PITCommonState *pit)
         ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_PIT);
     }
     if (ret < 0) {
-        fprintf(stderr, "Create kernel PIC irqchip failed: %s\n",
-                strerror(ret));
-        return ret;
+        error_setg(errp, "Create kernel PIC irqchip failed: %s",
+                   strerror(ret));
+        return;
     }
     switch (s->lost_tick_policy) {
     case LOST_TICK_DELAY:
@@ -264,24 +276,25 @@ static int kvm_pit_initfn(PITCommonState *pit)
 
             ret = kvm_vm_ioctl(kvm_state, KVM_REINJECT_CONTROL, &control);
             if (ret < 0) {
-                fprintf(stderr,
-                        "Can't disable in-kernel PIT reinjection: %s\n",
-                        strerror(ret));
-                return ret;
+                error_setg(errp,
+                           "Can't disable in-kernel PIT reinjection: %s",
+                           strerror(ret));
+                return;
             }
         }
         break;
     default:
-        return -EINVAL;
+        error_setg(errp, "Lost tick policy not supported.");
+        return;
     }
 
     memory_region_init_reservation(&pit->ioports, "kvm-pit", 4);
 
-    qdev_init_gpio_in(&pit->dev.qdev, kvm_pit_irq_control, 1);
+    qdev_init_gpio_in(dev, kvm_pit_irq_control, 1);
 
     qemu_add_vm_change_state_handler(kvm_pit_vm_state_change, s);
 
-    return 0;
+    kpc->parent_realize(dev, errp);
 }
 
 static Property kvm_pit_properties[] = {
@@ -293,10 +306,12 @@ static Property kvm_pit_properties[] = {
 
 static void kvm_pit_class_init(ObjectClass *klass, void *data)
 {
+    KVMPITClass *kpc = KVM_PIT_CLASS(klass);
     PITCommonClass *k = PIT_COMMON_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
-    k->init = kvm_pit_initfn;
+    kpc->parent_realize = dc->realize;
+    dc->realize = kvm_pit_realizefn;
     k->set_channel_gate = kvm_pit_set_gate;
     k->get_channel_info = kvm_pit_get_channel_info;
     k->pre_save = kvm_pit_get;
@@ -310,6 +325,7 @@ static const TypeInfo kvm_pit_info = {
     .parent        = TYPE_PIT_COMMON,
     .instance_size = sizeof(KVMPITState),
     .class_init = kvm_pit_class_init,
+    .class_size = sizeof(KVMPITClass),
 };
 
 static void kvm_pit_register(void)
diff --git a/hw/timer/i8254.c b/hw/timer/i8254.c
index efbca19..16c8dd6 100644
--- a/hw/timer/i8254.c
+++ b/hw/timer/i8254.c
@@ -35,6 +35,15 @@
 #define RW_STATE_WORD0 3
 #define RW_STATE_WORD1 4
 
+#define PIT_CLASS(class) OBJECT_CLASS_CHECK(PITClass, (class), TYPE_I8254)
+#define PIT_GET_CLASS(obj) OBJECT_GET_CLASS(PITClass, (obj), TYPE_I8254)
+
+typedef struct PITClass {
+    PITCommonClass parent_class;
+
+    DeviceRealize parent_realize;
+} PITClass;
+
 static void pit_irq_timer_update(PITChannelState *s, int64_t current_time);
 
 static int pit_get_count(PITChannelState *s)
@@ -313,20 +322,22 @@ static void pit_post_load(PITCommonState *s)
     }
 }
 
-static int pit_initfn(PITCommonState *pit)
+static void pit_realizefn(DeviceState *dev, Error **err)
 {
+    PITCommonState *pit = PIT_COMMON(dev);
+    PITClass *pc = PIT_GET_CLASS(dev);
     PITChannelState *s;
 
     s = &pit->channels[0];
     /* the timer 0 is connected to an IRQ */
     s->irq_timer = qemu_new_timer_ns(vm_clock, pit_irq_timer, s);
-    qdev_init_gpio_out(&pit->dev.qdev, &s->irq, 1);
+    qdev_init_gpio_out(dev, &s->irq, 1);
 
     memory_region_init_io(&pit->ioports, &pit_ioport_ops, pit, "pit", 4);
 
-    qdev_init_gpio_in(&pit->dev.qdev, pit_irq_control, 1);
+    qdev_init_gpio_in(dev, pit_irq_control, 1);
 
-    return 0;
+    pc->parent_realize(dev, err);
 }
 
 static Property pit_properties[] = {
@@ -336,10 +347,12 @@ static Property pit_properties[] = {
 
 static void pit_class_initfn(ObjectClass *klass, void *data)
 {
+    PITClass *pc = PIT_CLASS(klass);
     PITCommonClass *k = PIT_COMMON_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
-    k->init = pit_initfn;
+    pc->parent_realize = dc->realize;
+    dc->realize = pit_realizefn;
     k->set_channel_gate = pit_set_channel_gate;
     k->get_channel_info = pit_get_channel_info_common;
     k->post_load = pit_post_load;
@@ -352,6 +365,7 @@ static const TypeInfo pit_info = {
     .parent        = TYPE_PIT_COMMON,
     .instance_size = sizeof(PITCommonState),
     .class_init    = pit_class_initfn,
+    .class_size    = sizeof(PITClass),
 };
 
 static void pit_register_types(void)
diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c
index 36eed80..4e5bf0b 100644
--- a/hw/timer/i8254_common.c
+++ b/hw/timer/i8254_common.c
@@ -170,14 +170,6 @@ static void pit_common_realize(DeviceState *dev, Error **errp)
 {
     ISADevice *isadev = ISA_DEVICE(dev);
     PITCommonState *pit = PIT_COMMON(dev);
-    PITCommonClass *c = PIT_COMMON_GET_CLASS(pit);
-    int ret;
-
-    ret = c->init(pit);
-    if (ret < 0) {
-        error_setg(errp, "PIT init failed.");
-        return;
-    }
 
     isa_register_ioport(isadev, &pit->ioports, pit->iobase);
 
diff --git a/include/hw/timer/i8254_internal.h b/include/hw/timer/i8254_internal.h
index e0cff0c..61a1bfb 100644
--- a/include/hw/timer/i8254_internal.h
+++ b/include/hw/timer/i8254_internal.h
@@ -68,7 +68,6 @@ typedef struct PITCommonState {
 typedef struct PITCommonClass {
     ISADeviceClass parent_class;
 
-    int (*init)(PITCommonState *s);
     void (*set_channel_gate)(PITCommonState *s, PITChannelState *sc, int val);
     void (*get_channel_info)(PITCommonState *s, PITChannelState *sc,
                              PITChannelInfo *info);
commit 58cd986422d7353e7fac56969ac59daab3cdca67
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Nov 25 18:13:38 2012 +0100

    kvm/i8254: QOM'ify some more
    
    Introduce type constant and cast macro to obsolete DO_UPCAST().
    
    Prepares for PIT realizefn.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c
index da90711..4ac5551 100644
--- a/hw/i386/kvm/i8254.c
+++ b/hw/i386/kvm/i8254.c
@@ -32,8 +32,11 @@
 
 #define CALIBRATION_ROUNDS   3
 
+#define KVM_PIT(obj) OBJECT_CHECK(KVMPITState, (obj), TYPE_KVM_I8254)
+
 typedef struct KVMPITState {
-    PITCommonState pit;
+    PITCommonState parent_obj;
+
     LostTickPolicy lost_tick_policy;
     bool vm_stopped;
     int64_t kernel_clock_offset;
@@ -70,7 +73,7 @@ static void kvm_pit_update_clock_offset(KVMPITState *s)
 
 static void kvm_pit_get(PITCommonState *pit)
 {
-    KVMPITState *s = DO_UPCAST(KVMPITState, pit, pit);
+    KVMPITState *s = KVM_PIT(pit);
     struct kvm_pit_state2 kpit;
     struct kvm_pit_channel_state *kchan;
     struct PITChannelState *sc;
@@ -124,7 +127,7 @@ static void kvm_pit_get(PITCommonState *pit)
 
 static void kvm_pit_put(PITCommonState *pit)
 {
-    KVMPITState *s = DO_UPCAST(KVMPITState, pit, pit);
+    KVMPITState *s = KVM_PIT(pit);
     struct kvm_pit_state2 kpit;
     struct kvm_pit_channel_state *kchan;
     struct PITChannelState *sc;
@@ -200,7 +203,7 @@ static void kvm_pit_get_channel_info(PITCommonState *s, PITChannelState *sc,
 
 static void kvm_pit_reset(DeviceState *dev)
 {
-    PITCommonState *s = DO_UPCAST(PITCommonState, dev.qdev, dev);
+    PITCommonState *s = PIT_COMMON(dev);
 
     pit_reset_common(s);
 
@@ -229,14 +232,14 @@ static void kvm_pit_vm_state_change(void *opaque, int running,
         s->vm_stopped = false;
     } else {
         kvm_pit_update_clock_offset(s);
-        kvm_pit_get(&s->pit);
+        kvm_pit_get(PIT_COMMON(s));
         s->vm_stopped = true;
     }
 }
 
 static int kvm_pit_initfn(PITCommonState *pit)
 {
-    KVMPITState *s = DO_UPCAST(KVMPITState, pit, pit);
+    KVMPITState *s = KVM_PIT(pit);
     struct kvm_pit_config config = {
         .flags = 0,
     };
@@ -282,7 +285,7 @@ static int kvm_pit_initfn(PITCommonState *pit)
 }
 
 static Property kvm_pit_properties[] = {
-    DEFINE_PROP_HEX32("iobase", KVMPITState, pit.iobase,  -1),
+    DEFINE_PROP_HEX32("iobase", PITCommonState, iobase,  -1),
     DEFINE_PROP_LOSTTICKPOLICY("lost_tick_policy", KVMPITState,
                                lost_tick_policy, LOST_TICK_DELAY),
     DEFINE_PROP_END_OF_LIST(),
@@ -303,7 +306,7 @@ static void kvm_pit_class_init(ObjectClass *klass, void *data)
 }
 
 static const TypeInfo kvm_pit_info = {
-    .name          = "kvm-pit",
+    .name          = TYPE_KVM_I8254,
     .parent        = TYPE_PIT_COMMON,
     .instance_size = sizeof(KVMPITState),
     .class_init = kvm_pit_class_init,
diff --git a/include/hw/timer/i8254.h b/include/hw/timer/i8254.h
index 016f990..4349033 100644
--- a/include/hw/timer/i8254.h
+++ b/include/hw/timer/i8254.h
@@ -38,6 +38,7 @@ typedef struct PITChannelInfo {
 } PITChannelInfo;
 
 #define TYPE_I8254 "isa-pit"
+#define TYPE_KVM_I8254 "kvm-pit"
 
 static inline ISADevice *pit_init(ISABus *bus, int base, int isa_irq,
                                   qemu_irq alt_irq)
@@ -57,13 +58,15 @@ static inline ISADevice *pit_init(ISABus *bus, int base, int isa_irq,
 
 static inline ISADevice *kvm_pit_init(ISABus *bus, int base)
 {
-    ISADevice *dev;
+    DeviceState *dev;
+    ISADevice *d;
 
-    dev = isa_create(bus, "kvm-pit");
-    qdev_prop_set_uint32(&dev->qdev, "iobase", base);
-    qdev_init_nofail(&dev->qdev);
+    d = isa_create(bus, TYPE_KVM_I8254);
+    dev = DEVICE(d);
+    qdev_prop_set_uint32(dev, "iobase", base);
+    qdev_init_nofail(dev);
 
-    return dev;
+    return d;
 }
 
 void pit_set_gate(ISADevice *dev, int channel, int val);
commit 3afe7e14a42309578d324df5fe1b303a496a8466
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Nov 25 18:05:53 2012 +0100

    i8254: QOM'ify some more
    
    Introduce type constant and avoid DO_UPCAST().
    
    Prepares for PIT realizefn.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/timer/i8254.c b/hw/timer/i8254.c
index 20c0c36..efbca19 100644
--- a/hw/timer/i8254.c
+++ b/hw/timer/i8254.c
@@ -265,7 +265,7 @@ static void pit_irq_timer(void *opaque)
 
 static void pit_reset(DeviceState *dev)
 {
-    PITCommonState *pit = DO_UPCAST(PITCommonState, dev.qdev, dev);
+    PITCommonState *pit = PIT_COMMON(dev);
     PITChannelState *s;
 
     pit_reset_common(pit);
@@ -348,7 +348,7 @@ static void pit_class_initfn(ObjectClass *klass, void *data)
 }
 
 static const TypeInfo pit_info = {
-    .name          = "isa-pit",
+    .name          = TYPE_I8254,
     .parent        = TYPE_PIT_COMMON,
     .instance_size = sizeof(PITCommonState),
     .class_init    = pit_class_initfn,
diff --git a/include/hw/timer/i8254.h b/include/hw/timer/i8254.h
index 75bb530..016f990 100644
--- a/include/hw/timer/i8254.h
+++ b/include/hw/timer/i8254.h
@@ -37,18 +37,22 @@ typedef struct PITChannelInfo {
     int out;
 } PITChannelInfo;
 
+#define TYPE_I8254 "isa-pit"
+
 static inline ISADevice *pit_init(ISABus *bus, int base, int isa_irq,
                                   qemu_irq alt_irq)
 {
-    ISADevice *dev;
+    DeviceState *dev;
+    ISADevice *d;
 
-    dev = isa_create(bus, "isa-pit");
-    qdev_prop_set_uint32(&dev->qdev, "iobase", base);
-    qdev_init_nofail(&dev->qdev);
-    qdev_connect_gpio_out(&dev->qdev, 0,
-                          isa_irq >= 0 ? isa_get_irq(dev, isa_irq) : alt_irq);
+    d = isa_create(bus, TYPE_I8254);
+    dev = DEVICE(d);
+    qdev_prop_set_uint32(dev, "iobase", base);
+    qdev_init_nofail(dev);
+    qdev_connect_gpio_out(dev, 0,
+                          isa_irq >= 0 ? isa_get_irq(d, isa_irq) : alt_irq);
 
-    return dev;
+    return d;
 }
 
 static inline ISADevice *kvm_pit_init(ISABus *bus, int base)
commit e73fe2b46c38776288415ce7bc8ba3fcd23721c4
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Thu Jun 6 12:28:01 2013 +0800

    hmp: add parameters device and -v for info block
    
    With these parameters, user can choose the information to be showed,
    to avoid message flood in the monitor.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hmp.c b/hmp.c
index 4fc3bfe..494a9aa 100644
--- a/hmp.c
+++ b/hmp.c
@@ -280,10 +280,15 @@ void hmp_info_block(Monitor *mon, const QDict *qdict)
 {
     BlockInfoList *block_list, *info;
     ImageInfo *image_info;
+    const char *device = qdict_get_try_str(qdict, "device");
+    bool verbose = qdict_get_try_bool(qdict, "verbose", 0);
 
     block_list = qmp_query_block(NULL);
 
     for (info = block_list; info; info = info->next) {
+        if (device && strcmp(device, info->value->device)) {
+            continue;
+        }
         monitor_printf(mon, "%s: removable=%d",
                        info->value->device, info->value->removable);
 
@@ -322,15 +327,17 @@ void hmp_info_block(Monitor *mon, const QDict *qdict)
                             info->value->inserted->iops_rd,
                             info->value->inserted->iops_wr);
 
-            monitor_printf(mon, " images:\n");
-            image_info = info->value->inserted->image;
-            while (1) {
-                bdrv_image_info_dump((fprintf_function)monitor_printf, mon,
-                                     image_info);
-                if (image_info->has_backing_image) {
-                    image_info = image_info->backing_image;
-                } else {
-                    break;
+            if (verbose) {
+                monitor_printf(mon, " images:\n");
+                image_info = info->value->inserted->image;
+                while (1) {
+                        bdrv_image_info_dump((fprintf_function)monitor_printf,
+                                             mon, image_info);
+                    if (image_info->has_backing_image) {
+                        image_info = image_info->backing_image;
+                    } else {
+                        break;
+                    }
                 }
             }
         } else {
diff --git a/monitor.c b/monitor.c
index 9d279b8..017411f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2472,9 +2472,10 @@ static mon_cmd_t info_cmds[] = {
     },
     {
         .name       = "block",
-        .args_type  = "",
-        .params     = "",
-        .help       = "show the block devices",
+        .args_type  = "verbose:-v,device:B?",
+        .params     = "[-v] [device]",
+        .help       = "show info of one block device or all block devices "
+                      "(and details of images with -v option)",
         .mhandler.cmd = hmp_info_block,
     },
     {
commit bd093a365e8d1437f437a48ddca3ed08283b3090
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Thu Jun 6 12:28:00 2013 +0800

    hmp: show ImageInfo in 'info block'
    
    Now human monitor can show image details, include internal
    snapshot and backing chain info for every block device.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hmp.c b/hmp.c
index 64e0baa..4fc3bfe 100644
--- a/hmp.c
+++ b/hmp.c
@@ -22,6 +22,7 @@
 #include "qemu/sockets.h"
 #include "monitor/monitor.h"
 #include "ui/console.h"
+#include "block/qapi.h"
 #include "qemu-io.h"
 
 static void hmp_handle_error(Monitor *mon, Error **errp)
@@ -278,6 +279,7 @@ void hmp_info_cpus(Monitor *mon, const QDict *qdict)
 void hmp_info_block(Monitor *mon, const QDict *qdict)
 {
     BlockInfoList *block_list, *info;
+    ImageInfo *image_info;
 
     block_list = qmp_query_block(NULL);
 
@@ -319,6 +321,18 @@ void hmp_info_block(Monitor *mon, const QDict *qdict)
                             info->value->inserted->iops,
                             info->value->inserted->iops_rd,
                             info->value->inserted->iops_wr);
+
+            monitor_printf(mon, " images:\n");
+            image_info = info->value->inserted->image;
+            while (1) {
+                bdrv_image_info_dump((fprintf_function)monitor_printf, mon,
+                                     image_info);
+                if (image_info->has_backing_image) {
+                    image_info = image_info->backing_image;
+                } else {
+                    break;
+                }
+            }
         } else {
             monitor_printf(mon, " [not inserted]");
         }
commit 553a7e871822d933beaefbd596f0e4eed1614373
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Thu Jun 6 12:27:59 2013 +0800

    qmp: add ImageInfo in BlockDeviceInfo used by query-block
    
    Now image info will be retrieved as an embbed json object inside
    BlockDeviceInfo, backing chain info and all related internal snapshot
    info can be got in the enhanced recursive structure of ImageInfo. New
    recursive member *backing-image is added to reflect the backing chain
    status.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/qapi.c b/block/qapi.c
index e9d8b74..a4bc411 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -94,6 +94,13 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs,
  * @p_info: location to store image information
  * @errp: location to store error information
  *
+ * Store "flat" image information in @p_info.
+ *
+ * "Flat" means it does *not* query backing image information,
+ * i.e. (*pinfo)->has_backing_image will be set to false and
+ * (*pinfo)->backing_image to NULL even when the image does in fact have
+ * a backing image.
+ *
  * @p_info will be set only on success. On error, store error in @errp.
  */
 void bdrv_query_image_info(BlockDriverState *bs,
@@ -167,9 +174,15 @@ void bdrv_query_image_info(BlockDriverState *bs,
     *p_info = info;
 }
 
-BlockInfo *bdrv_query_info(BlockDriverState *bs)
+/* @p_info will be set only on success. */
+void bdrv_query_info(BlockDriverState *bs,
+                     BlockInfo **p_info,
+                     Error **errp)
 {
     BlockInfo *info = g_malloc0(sizeof(*info));
+    BlockDriverState *bs0;
+    ImageInfo **p_image_info;
+    Error *local_err = NULL;
     info->device = g_strdup(bs->device_name);
     info->type = g_strdup("unknown");
     info->locked = bdrv_dev_is_medium_locked(bs);
@@ -223,8 +236,30 @@ BlockInfo *bdrv_query_info(BlockDriverState *bs)
             info->inserted->iops_wr =
                            bs->io_limits.iops[BLOCK_IO_LIMIT_WRITE];
         }
+
+        bs0 = bs;
+        p_image_info = &info->inserted->image;
+        while (1) {
+            bdrv_query_image_info(bs0, p_image_info, &local_err);
+            if (error_is_set(&local_err)) {
+                error_propagate(errp, local_err);
+                goto err;
+            }
+            if (bs0->drv && bs0->backing_hd) {
+                bs0 = bs0->backing_hd;
+                (*p_image_info)->has_backing_image = true;
+                p_image_info = &((*p_image_info)->backing_image);
+            } else {
+                break;
+            }
+        }
     }
-    return info;
+
+    *p_info = info;
+    return;
+
+ err:
+    qapi_free_BlockInfo(info);
 }
 
 BlockStats *bdrv_query_stats(const BlockDriverState *bs)
@@ -261,16 +296,25 @@ BlockInfoList *qmp_query_block(Error **errp)
 {
     BlockInfoList *head = NULL, **p_next = &head;
     BlockDriverState *bs = NULL;
+    Error *local_err = NULL;
 
      while ((bs = bdrv_next(bs))) {
         BlockInfoList *info = g_malloc0(sizeof(*info));
-        info->value = bdrv_query_info(bs);
+        bdrv_query_info(bs, &info->value, &local_err);
+        if (error_is_set(&local_err)) {
+            error_propagate(errp, local_err);
+            goto err;
+        }
 
         *p_next = info;
         p_next = &info->next;
     }
 
     return head;
+
+ err:
+    qapi_free_BlockInfoList(head);
+    return NULL;
 }
 
 BlockStatsList *qmp_query_blockstats(Error **errp)
diff --git a/include/block/qapi.h b/include/block/qapi.h
index ab1f48f..0496cc9 100644
--- a/include/block/qapi.h
+++ b/include/block/qapi.h
@@ -35,7 +35,9 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs,
 void bdrv_query_image_info(BlockDriverState *bs,
                            ImageInfo **p_info,
                            Error **errp);
-BlockInfo *bdrv_query_info(BlockDriverState *s);
+void bdrv_query_info(BlockDriverState *bs,
+                     BlockInfo **p_info,
+                     Error **errp);
 BlockStats *bdrv_query_stats(const BlockDriverState *bs);
 
 void bdrv_snapshot_dump(fprintf_function func_fprintf, void *f,
diff --git a/qapi-schema.json b/qapi-schema.json
index ef1f657..5ad6894 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -236,6 +236,8 @@
 #
 # @snapshots: #optional list of VM snapshots
 #
+# @backing-image: #optional info of the backing image (since 1.6)
+#
 # Since: 1.3
 #
 ##
@@ -245,7 +247,8 @@
            '*actual-size': 'int', 'virtual-size': 'int',
            '*cluster-size': 'int', '*encrypted': 'bool',
            '*backing-filename': 'str', '*full-backing-filename': 'str',
-           '*backing-filename-format': 'str', '*snapshots': ['SnapshotInfo'] } }
+           '*backing-filename-format': 'str', '*snapshots': ['SnapshotInfo'],
+           '*backing-image': 'ImageInfo' } }
 
 ##
 # @ImageCheck:
@@ -756,6 +759,8 @@
 #
 # @iops_wr: write I/O operations per second is specified
 #
+# @image: the info of image used (since: 1.6)
+#
 # Since: 0.14.0
 #
 # Notes: This interface is only found in @BlockInfo.
@@ -765,7 +770,8 @@
             '*backing_file': 'str', 'backing_file_depth': 'int',
             'encrypted': 'bool', 'encryption_key_missing': 'bool',
             'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',
-            'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int'} }
+            'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int',
+            'image': 'ImageInfo' } }
 
 ##
 # @BlockDeviceIoStatus:
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ffd130e..8cea5e5 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1704,6 +1704,47 @@ Each json-object contain the following:
          - "iops": limit total I/O operations per second (json-int)
          - "iops_rd": limit read operations per second (json-int)
          - "iops_wr": limit write operations per second (json-int)
+         - "image": the detail of the image, it is a json-object containing
+            the following:
+             - "filename": image file name (json-string)
+             - "format": image format (json-string)
+             - "virtual-size": image capacity in bytes (json-int)
+             - "dirty-flag": true if image is not cleanly closed, not present
+                             means clean (json-bool, optional)
+             - "actual-size": actual size on disk in bytes of the image, not
+                              present when image does not support thin
+                              provision (json-int, optional)
+             - "cluster-size": size of a cluster in bytes, not present if image
+                               format does not support it (json-int, optional)
+             - "encrypted": true if the image is encrypted, not present means
+                            false or the image format does not support
+                            encryption (json-bool, optional)
+             - "backing_file": backing file name, not present means no backing
+                               file is used or the image format does not
+                               support backing file chain
+                               (json-string, optional)
+             - "full-backing-filename": full path of the backing file, not
+                                        present if it equals backing_file or no
+                                        backing file is used
+                                        (json-string, optional)
+             - "backing-filename-format": the format of the backing file, not
+                                          present means unknown or no backing
+                                          file (json-string, optional)
+             - "snapshots": the internal snapshot info, it is an optional list
+                of json-object containing the following:
+                 - "id": unique snapshot id (json-string)
+                 - "name": snapshot name (json-string)
+                 - "vm-state-size": size of the VM state in bytes (json-int)
+                 - "date-sec": UTC date of the snapshot in seconds (json-int)
+                 - "date-nsec": fractional part in nanoseconds to be used with
+                                date-sec(json-int)
+                 - "vm-clock-sec": VM clock relative to boot in seconds
+                                   (json-int)
+                 - "vm-clock-nsec": fractional part in nanoseconds to be used
+                                    with vm-clock-sec (json-int)
+             - "backing-image": the detail of the backing image, it is an
+                                optional json-object only present when a
+                                backing image present for this image
 
 - "io-status": I/O operation status, only present if the device supports it
                and the VM is configured to stop on errors. It's always reset
@@ -1724,14 +1765,38 @@ Example:
                "ro":false,
                "drv":"qcow2",
                "encrypted":false,
-               "file":"disks/test.img",
-               "backing_file_depth":0,
+               "file":"disks/test.qcow2",
+               "backing_file_depth":1,
                "bps":1000000,
                "bps_rd":0,
                "bps_wr":0,
                "iops":1000000,
                "iops_rd":0,
                "iops_wr":0,
+               "image":{
+                  "filename":"disks/test.qcow2",
+                  "format":"qcow2",
+                  "virtual-size":2048000,
+                  "backing_file":"base.qcow2",
+                  "full-backing-filename":"disks/base.qcow2",
+                  "backing-filename-format:"qcow2",
+                  "snapshots":[
+                     {
+                        "id": "1",
+                        "name": "snapshot1",
+                        "vm-state-size": 0,
+                        "date-sec": 10000200,
+                        "date-nsec": 12,
+                        "vm-clock-sec": 206,
+                        "vm-clock-nsec": 30
+                     }
+                  ],
+                  "backing-image":{
+                      "filename":"disks/base.qcow2",
+                      "format":"qcow2",
+                      "virtual-size":2048000
+                  }
+               }
             },
             "type":"unknown"
          },
commit 43526ec8d1395fe4efbed15e9764b64641b95bcc
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Thu Jun 6 12:27:58 2013 +0800

    block: add image info query function bdrv_query_image_info()
    
    This patch adds function bdrv_query_image_info(), which will
    retrieve image info in qmp object format. The implementation is
    based on the code moved from qemu-img.c, but uses block layer
    function to get snapshot info.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/qapi.c b/block/qapi.c
index 1ed56da..e9d8b74 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -88,18 +88,29 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs,
     return 0;
 }
 
-void bdrv_collect_image_info(BlockDriverState *bs,
-                             ImageInfo *info,
-                             const char *filename)
+/**
+ * bdrv_query_image_info:
+ * @bs: block device to examine
+ * @p_info: location to store image information
+ * @errp: location to store error information
+ *
+ * @p_info will be set only on success. On error, store error in @errp.
+ */
+void bdrv_query_image_info(BlockDriverState *bs,
+                           ImageInfo **p_info,
+                           Error **errp)
 {
     uint64_t total_sectors;
-    char backing_filename[1024];
+    const char *backing_filename;
     char backing_filename2[1024];
     BlockDriverInfo bdi;
+    int ret;
+    Error *err = NULL;
+    ImageInfo *info = g_new0(ImageInfo, 1);
 
     bdrv_get_geometry(bs, &total_sectors);
 
-    info->filename        = g_strdup(filename);
+    info->filename        = g_strdup(bs->filename);
     info->format          = g_strdup(bdrv_get_format_name(bs));
     info->virtual_size    = total_sectors * 512;
     info->actual_size     = bdrv_get_allocated_file_size(bs);
@@ -116,7 +127,7 @@ void bdrv_collect_image_info(BlockDriverState *bs,
         info->dirty_flag = bdi.is_dirty;
         info->has_dirty_flag = true;
     }
-    bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
+    backing_filename = bs->backing_file;
     if (backing_filename[0] != '\0') {
         info->backing_filename = g_strdup(backing_filename);
         info->has_backing_filename = true;
@@ -134,6 +145,26 @@ void bdrv_collect_image_info(BlockDriverState *bs,
             info->has_backing_filename_format = true;
         }
     }
+
+    ret = bdrv_query_snapshot_info_list(bs, &info->snapshots, &err);
+    switch (ret) {
+    case 0:
+        if (info->snapshots) {
+            info->has_snapshots = true;
+        }
+        break;
+    /* recoverable error */
+    case -ENOMEDIUM:
+    case -ENOTSUP:
+        error_free(err);
+        break;
+    default:
+        error_propagate(errp, err);
+        qapi_free_ImageInfo(info);
+        return;
+    }
+
+    *p_info = info;
 }
 
 BlockInfo *bdrv_query_info(BlockDriverState *bs)
diff --git a/include/block/qapi.h b/include/block/qapi.h
index 4f223d1..ab1f48f 100644
--- a/include/block/qapi.h
+++ b/include/block/qapi.h
@@ -32,9 +32,9 @@
 int bdrv_query_snapshot_info_list(BlockDriverState *bs,
                                   SnapshotInfoList **p_list,
                                   Error **errp);
-void bdrv_collect_image_info(BlockDriverState *bs,
-                             ImageInfo *info,
-                             const char *filename);
+void bdrv_query_image_info(BlockDriverState *bs,
+                           ImageInfo **p_info,
+                           Error **errp);
 BlockInfo *bdrv_query_info(BlockDriverState *s);
 BlockStats *bdrv_query_stats(const BlockDriverState *bs);
 
diff --git a/qemu-img.c b/qemu-img.c
index e3d8fe3..809b4f1 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1644,6 +1644,7 @@ static ImageInfoList *collect_image_info_list(const char *filename,
     ImageInfoList *head = NULL;
     ImageInfoList **last = &head;
     GHashTable *filenames;
+    Error *err = NULL;
 
     filenames = g_hash_table_new_full(g_str_hash, str_equal_func, NULL, NULL);
 
@@ -1665,11 +1666,11 @@ static ImageInfoList *collect_image_info_list(const char *filename,
             goto err;
         }
 
-        info = g_new0(ImageInfo, 1);
-        bdrv_collect_image_info(bs, info, filename);
-        bdrv_query_snapshot_info_list(bs, &info->snapshots, NULL);
-        if (info->snapshots) {
-            info->has_snapshots = true;
+        bdrv_query_image_info(bs, &info, &err);
+        if (error_is_set(&err)) {
+            error_report("%s", error_get_pretty(err));
+            error_free(err);
+            goto err;
         }
 
         elem = g_new0(ImageInfoList, 1);
commit fb0ed4539c6f02fa9e5a3cf9df2549713451eeca
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Thu Jun 6 12:27:57 2013 +0800

    block: add snapshot info query function bdrv_query_snapshot_info_list()
    
    This patch adds function bdrv_query_snapshot_info_list(), which will
    retrieve snapshot info of an image in qmp object format. The implementation
    is based on the code moved from qemu-img.c with modification to fit more
    for qmp based block layer API.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/qapi.c b/block/qapi.c
index 794dbf8..1ed56da 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -26,29 +26,56 @@
 #include "block/block_int.h"
 #include "qmp-commands.h"
 
-void bdrv_collect_snapshots(BlockDriverState *bs , ImageInfo *info)
+/*
+ * Returns 0 on success, with *p_list either set to describe snapshot
+ * information, or NULL because there are no snapshots.  Returns -errno on
+ * error, with *p_list untouched.
+ */
+int bdrv_query_snapshot_info_list(BlockDriverState *bs,
+                                  SnapshotInfoList **p_list,
+                                  Error **errp)
 {
     int i, sn_count;
     QEMUSnapshotInfo *sn_tab = NULL;
-    SnapshotInfoList *info_list, *cur_item = NULL;
+    SnapshotInfoList *info_list, *cur_item = NULL, *head = NULL;
+    SnapshotInfo *info;
+
     sn_count = bdrv_snapshot_list(bs, &sn_tab);
+    if (sn_count < 0) {
+        const char *dev = bdrv_get_device_name(bs);
+        switch (sn_count) {
+        case -ENOMEDIUM:
+            error_setg(errp, "Device '%s' is not inserted", dev);
+            break;
+        case -ENOTSUP:
+            error_setg(errp,
+                       "Device '%s' does not support internal snapshots",
+                       dev);
+            break;
+        default:
+            error_setg_errno(errp, -sn_count,
+                             "Can't list snapshots of device '%s'", dev);
+            break;
+        }
+        return sn_count;
+    }
 
     for (i = 0; i < sn_count; i++) {
-        info->has_snapshots = true;
-        info_list = g_new0(SnapshotInfoList, 1);
+        info = g_new0(SnapshotInfo, 1);
+        info->id            = g_strdup(sn_tab[i].id_str);
+        info->name          = g_strdup(sn_tab[i].name);
+        info->vm_state_size = sn_tab[i].vm_state_size;
+        info->date_sec      = sn_tab[i].date_sec;
+        info->date_nsec     = sn_tab[i].date_nsec;
+        info->vm_clock_sec  = sn_tab[i].vm_clock_nsec / 1000000000;
+        info->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000;
 
-        info_list->value                = g_new0(SnapshotInfo, 1);
-        info_list->value->id            = g_strdup(sn_tab[i].id_str);
-        info_list->value->name          = g_strdup(sn_tab[i].name);
-        info_list->value->vm_state_size = sn_tab[i].vm_state_size;
-        info_list->value->date_sec      = sn_tab[i].date_sec;
-        info_list->value->date_nsec     = sn_tab[i].date_nsec;
-        info_list->value->vm_clock_sec  = sn_tab[i].vm_clock_nsec / 1000000000;
-        info_list->value->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000;
+        info_list = g_new0(SnapshotInfoList, 1);
+        info_list->value = info;
 
         /* XXX: waiting for the qapi to support qemu-queue.h types */
         if (!cur_item) {
-            info->snapshots = cur_item = info_list;
+            head = cur_item = info_list;
         } else {
             cur_item->next = info_list;
             cur_item = info_list;
@@ -57,6 +84,8 @@ void bdrv_collect_snapshots(BlockDriverState *bs , ImageInfo *info)
     }
 
     g_free(sn_tab);
+    *p_list = head;
+    return 0;
 }
 
 void bdrv_collect_image_info(BlockDriverState *bs,
diff --git a/include/block/qapi.h b/include/block/qapi.h
index e6e568d..4f223d1 100644
--- a/include/block/qapi.h
+++ b/include/block/qapi.h
@@ -29,7 +29,9 @@
 #include "block/block.h"
 #include "block/snapshot.h"
 
-void bdrv_collect_snapshots(BlockDriverState *bs , ImageInfo *info);
+int bdrv_query_snapshot_info_list(BlockDriverState *bs,
+                                  SnapshotInfoList **p_list,
+                                  Error **errp);
 void bdrv_collect_image_info(BlockDriverState *bs,
                              ImageInfo *info,
                              const char *filename);
diff --git a/qemu-img.c b/qemu-img.c
index e089c78..e3d8fe3 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1667,7 +1667,10 @@ static ImageInfoList *collect_image_info_list(const char *filename,
 
         info = g_new0(ImageInfo, 1);
         bdrv_collect_image_info(bs, info, filename);
-        bdrv_collect_snapshots(bs, info);
+        bdrv_query_snapshot_info_list(bs, &info->snapshots, NULL);
+        if (info->snapshots) {
+            info->has_snapshots = true;
+        }
 
         elem = g_new0(ImageInfoList, 1);
         elem->value = info;
commit db895a1e6a97e919f9b86d60c969377357b05066
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Nov 25 02:37:14 2012 +0100

    isa: Use realizefn for ISADevice
    
    Drop ISADeviceClass::init and the resulting no-op initfn and let
    children implement their own realizefn. Adapt error handling.
    Split off an instance_init where sensible.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c
index fc20857..6a7d377 100644
--- a/hw/audio/adlib.c
+++ b/hw/audio/adlib.c
@@ -283,21 +283,21 @@ static void Adlib_fini (AdlibState *s)
     AUD_remove_card (&s->card);
 }
 
-static int Adlib_initfn (ISADevice *dev)
+static void adlib_realizefn (DeviceState *dev, Error **errp)
 {
     AdlibState *s = ADLIB(dev);
     struct audsettings as;
 
     if (glob_adlib) {
-        dolog ("Cannot create more than 1 adlib device\n");
-        return -1;
+        error_setg (errp, "Cannot create more than 1 adlib device");
+        return;
     }
     glob_adlib = s;
 
 #ifdef HAS_YMF262
     if (YMF262Init (1, 14318180, s->freq)) {
-        dolog ("YMF262Init %d failed\n", s->freq);
-        return -1;
+        error_setg (errp, "YMF262Init %d failed", s->freq);
+        return;
     }
     else {
         YMF262SetTimerHandler (0, timer_handler, 0);
@@ -306,8 +306,8 @@ static int Adlib_initfn (ISADevice *dev)
 #else
     s->opl = OPLCreate (OPL_TYPE_YM3812, 3579545, s->freq);
     if (!s->opl) {
-        dolog ("OPLCreate %d failed\n", s->freq);
-        return -1;
+        error_setg (errp, "OPLCreate %d failed", s->freq);
+        return;
     }
     else {
         OPLSetTimerHandler (s->opl, timer_handler, 0);
@@ -332,7 +332,8 @@ static int Adlib_initfn (ISADevice *dev)
         );
     if (!s->voice) {
         Adlib_fini (s);
-        return -1;
+        error_setg (errp, "Initializing audio voice failed");
+        return;
     }
 
     s->samples = AUD_get_buffer_size_out (s->voice) >> SHIFT;
@@ -346,8 +347,6 @@ static int Adlib_initfn (ISADevice *dev)
 
     register_ioport_read (s->port + 8, 2, 1, adlib_read, s);
     register_ioport_write (s->port + 8, 2, 1, adlib_write, s);
-
-    return 0;
 }
 
 static Property adlib_properties[] = {
@@ -359,8 +358,8 @@ static Property adlib_properties[] = {
 static void adlib_class_initfn (ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS (klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS (klass);
-    ic->init = Adlib_initfn;
+
+    dc->realize = adlib_realizefn;
     dc->desc = ADLIB_DESC;
     dc->props = adlib_properties;
 }
diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c
index d3ce739..605dad4 100644
--- a/hw/audio/cs4231a.c
+++ b/hw/audio/cs4231a.c
@@ -644,19 +644,25 @@ static const MemoryRegionOps cs_ioport_ops = {
     }
 };
 
-static int cs4231a_initfn (ISADevice *dev)
+static void cs4231a_initfn (Object *obj)
 {
+    CSState *s = CS4231A (obj);
+
+    memory_region_init_io (&s->ioports, &cs_ioport_ops, s, "cs4231a", 4);
+}
+
+static void cs4231a_realizefn (DeviceState *dev, Error **errp)
+{
+    ISADevice *d = ISA_DEVICE (dev);
     CSState *s = CS4231A (dev);
 
-    isa_init_irq (dev, &s->pic, s->irq);
+    isa_init_irq (d, &s->pic, s->irq);
 
-    memory_region_init_io (&s->ioports, &cs_ioport_ops, s, "cs4231a", 4);
-    isa_register_ioport (dev, &s->ioports, s->port);
+    isa_register_ioport (d, &s->ioports, s->port);
 
     DMA_register_channel (s->dma, cs_dma_read, s);
 
     AUD_register_card ("cs4231a", &s->card);
-    return 0;
 }
 
 static int cs4231a_init (ISABus *bus)
@@ -675,8 +681,8 @@ static Property cs4231a_properties[] = {
 static void cs4231a_class_initfn (ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS (klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS (klass);
-    ic->init = cs4231a_initfn;
+
+    dc->realize = cs4231a_realizefn;
     dc->reset = cs4231a_reset;
     dc->desc = "Crystal Semiconductor CS4231A";
     dc->vmsd = &vmstate_cs4231a;
@@ -687,6 +693,7 @@ static const TypeInfo cs4231a_info = {
     .name          = TYPE_CS4231A,
     .parent        = TYPE_ISA_DEVICE,
     .instance_size = sizeof (CSState),
+    .instance_init = cs4231a_initfn,
     .class_init    = cs4231a_class_initfn,
 };
 
diff --git a/hw/audio/gus.c b/hw/audio/gus.c
index e0aea26..f45ed0b 100644
--- a/hw/audio/gus.c
+++ b/hw/audio/gus.c
@@ -251,8 +251,9 @@ static const MemoryRegionPortio gus_portio_list2[] = {
     PORTIO_END_OF_LIST (),
 };
 
-static int gus_initfn (ISADevice *dev)
+static void gus_realizefn (DeviceState *dev, Error **errp)
 {
+    ISADevice *d = ISA_DEVICE(dev);
     GUSState *s = GUS (dev);
     struct audsettings as;
 
@@ -274,26 +275,25 @@ static int gus_initfn (ISADevice *dev)
 
     if (!s->voice) {
         AUD_remove_card (&s->card);
-        return -1;
+        error_setg(errp, "No voice");
+        return;
     }
 
     s->shift = 2;
     s->samples = AUD_get_buffer_size_out (s->voice) >> s->shift;
     s->mixbuf = g_malloc0 (s->samples << s->shift);
 
-    isa_register_portio_list (dev, s->port, gus_portio_list1, s, "gus");
-    isa_register_portio_list (dev, (s->port + 0x100) & 0xf00,
+    isa_register_portio_list (d, s->port, gus_portio_list1, s, "gus");
+    isa_register_portio_list (d, (s->port + 0x100) & 0xf00,
                               gus_portio_list2, s, "gus");
 
     DMA_register_channel (s->emu.gusdma, GUS_read_DMA, s);
     s->emu.himemaddr = s->himem;
     s->emu.gusdatapos = s->emu.himemaddr + 1024 * 1024 + 32;
     s->emu.opaque = s;
-    isa_init_irq (dev, &s->pic, s->emu.gusirq);
+    isa_init_irq (d, &s->pic, s->emu.gusirq);
 
     AUD_set_active_out (s->voice, 1);
-
-    return 0;
 }
 
 static int GUS_init (ISABus *bus)
@@ -313,8 +313,8 @@ static Property gus_properties[] = {
 static void gus_class_initfn (ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS (klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS (klass);
-    ic->init = gus_initfn;
+
+    dc->realize = gus_realizefn;
     dc->desc = "Gravis Ultrasound GF1";
     dc->vmsd = &vmstate_gus;
     dc->props = gus_properties;
diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c
index 3a7285f..5dde0e7 100644
--- a/hw/audio/pcspk.c
+++ b/hw/audio/pcspk.c
@@ -163,16 +163,21 @@ static const MemoryRegionOps pcspk_io_ops = {
     },
 };
 
-static int pcspk_initfn(ISADevice *dev)
+static void pcspk_initfn(Object *obj)
 {
-    PCSpkState *s = PC_SPEAKER(dev);
+    PCSpkState *s = PC_SPEAKER(obj);
 
     memory_region_init_io(&s->ioport, &pcspk_io_ops, s, "elcr", 1);
-    isa_register_ioport(dev, &s->ioport, s->iobase);
+}
 
-    pcspk_state = s;
+static void pcspk_realizefn(DeviceState *dev, Error **errp)
+{
+    ISADevice *isadev = ISA_DEVICE(dev);
+    PCSpkState *s = PC_SPEAKER(dev);
 
-    return 0;
+    isa_register_ioport(isadev, &s->ioport, s->iobase);
+
+    pcspk_state = s;
 }
 
 static Property pcspk_properties[] = {
@@ -184,9 +189,8 @@ static Property pcspk_properties[] = {
 static void pcspk_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
 
-    ic->init = pcspk_initfn;
+    dc->realize = pcspk_realizefn;
     dc->no_user = 1;
     dc->props = pcspk_properties;
 }
@@ -195,6 +199,7 @@ static const TypeInfo pcspk_info = {
     .name           = TYPE_PC_SPEAKER,
     .parent         = TYPE_ISA_DEVICE,
     .instance_size  = sizeof(PCSpkState),
+    .instance_init  = pcspk_initfn,
     .class_init     = pcspk_class_initfn,
 };
 
diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c
index 6ddc0ac..e697bc1 100644
--- a/hw/audio/sb16.c
+++ b/hw/audio/sb16.c
@@ -1356,12 +1356,19 @@ static const MemoryRegionPortio sb16_ioport_list[] = {
 };
 
 
-static int sb16_initfn (ISADevice *dev)
+static void sb16_initfn (Object *obj)
 {
-    SB16State *s = SB16 (dev);
+    SB16State *s = SB16 (obj);
 
     s->cmd = -1;
-    isa_init_irq (dev, &s->pic, s->irq);
+}
+
+static void sb16_realizefn (DeviceState *dev, Error **errp)
+{
+    ISADevice *isadev = ISA_DEVICE (dev);
+    SB16State *s = SB16 (dev);
+
+    isa_init_irq (isadev, &s->pic, s->irq);
 
     s->mixer_regs[0x80] = magic_of_irq (s->irq);
     s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
@@ -1376,14 +1383,13 @@ static int sb16_initfn (ISADevice *dev)
         dolog ("warning: Could not create auxiliary timer\n");
     }
 
-    isa_register_portio_list (dev, s->port, sb16_ioport_list, s, "sb16");
+    isa_register_portio_list (isadev, s->port, sb16_ioport_list, s, "sb16");
 
     DMA_register_channel (s->hdma, SB_read_DMA, s);
     DMA_register_channel (s->dma, SB_read_DMA, s);
     s->can_write = 1;
 
     AUD_register_card ("sb16", &s->card);
-    return 0;
 }
 
 static int SB16_init (ISABus *bus)
@@ -1404,8 +1410,8 @@ static Property sb16_properties[] = {
 static void sb16_class_initfn (ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS (klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS (klass);
-    ic->init = sb16_initfn;
+
+    dc->realize = sb16_realizefn;
     dc->desc = "Creative Sound Blaster 16";
     dc->vmsd = &vmstate_sb16;
     dc->props = sb16_properties;
@@ -1415,6 +1421,7 @@ static const TypeInfo sb16_info = {
     .name          = TYPE_SB16,
     .parent        = TYPE_ISA_DEVICE,
     .instance_size = sizeof (SB16State),
+    .instance_init = sb16_initfn,
     .class_init    = sb16_class_initfn,
 };
 
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 0888652..79ea625 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -2117,24 +2117,28 @@ static const MemoryRegionPortio fdc_portio_list[] = {
     PORTIO_END_OF_LIST(),
 };
 
-static int isabus_fdc_init1(ISADevice *dev)
+static void isabus_fdc_realize(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     FDCtrlISABus *isa = ISA_FDC(dev);
     FDCtrl *fdctrl = &isa->state;
     int ret;
 
-    isa_register_portio_list(dev, isa->iobase, fdc_portio_list, fdctrl, "fdc");
+    isa_register_portio_list(isadev, isa->iobase, fdc_portio_list, fdctrl,
+                             "fdc");
 
-    isa_init_irq(dev, &fdctrl->irq, isa->irq);
+    isa_init_irq(isadev, &fdctrl->irq, isa->irq);
     fdctrl->dma_chann = isa->dma;
 
-    qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 2);
+    qdev_set_legacy_instance_id(dev, isa->iobase, 2);
     ret = fdctrl_init_common(fdctrl);
+    if (ret < 0) {
+        error_setg(errp, "Floppy init failed.");
+        return;
+    }
 
-    add_boot_device_path(isa->bootindexA, &dev->qdev, "/floppy at 0");
-    add_boot_device_path(isa->bootindexB, &dev->qdev, "/floppy at 1");
-
-    return ret;
+    add_boot_device_path(isa->bootindexA, dev, "/floppy at 0");
+    add_boot_device_path(isa->bootindexB, dev, "/floppy at 1");
 }
 
 static int sysbus_fdc_init1(SysBusDevice *dev)
@@ -2203,8 +2207,8 @@ static Property isa_fdc_properties[] = {
 static void isabus_fdc_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = isabus_fdc_init1;
+
+    dc->realize = isabus_fdc_realize;
     dc->fw_name = "fdc";
     dc->no_user = 1;
     dc->reset = fdctrl_external_reset_isa;
diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c
index 3b0637d..f254841 100644
--- a/hw/char/debugcon.c
+++ b/hw/char/debugcon.c
@@ -81,27 +81,32 @@ static const MemoryRegionOps debugcon_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static void debugcon_init_core(DebugconState *s)
+static void debugcon_realize_core(DebugconState *s, Error **errp)
 {
     if (!s->chr) {
-        fprintf(stderr, "Can't create debugcon device, empty char device\n");
-        exit(1);
+        error_setg(errp, "Can't create debugcon device, empty char device");
+        return;
     }
 
     qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, s);
 }
 
-static int debugcon_isa_initfn(ISADevice *dev)
+static void debugcon_isa_realizefn(DeviceState *dev, Error **errp)
 {
+    ISADevice *d = ISA_DEVICE(dev);
     ISADebugconState *isa = ISA_DEBUGCON_DEVICE(dev);
     DebugconState *s = &isa->state;
+    Error *err = NULL;
 
-    debugcon_init_core(s);
+    debugcon_realize_core(s, &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
     memory_region_init_io(&s->io, &debugcon_ops, s,
                           TYPE_ISA_DEBUGCON_DEVICE, 1);
-    memory_region_add_subregion(isa_address_space_io(dev),
+    memory_region_add_subregion(isa_address_space_io(d),
                                 isa->iobase, &s->io);
-    return 0;
 }
 
 static Property debugcon_isa_properties[] = {
@@ -114,8 +119,8 @@ static Property debugcon_isa_properties[] = {
 static void debugcon_isa_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = debugcon_isa_initfn;
+
+    dc->realize = debugcon_isa_realizefn;
     dc->props = debugcon_isa_properties;
 }
 
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index 8e48284..caa9eb4 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -477,29 +477,35 @@ static const MemoryRegionPortio isa_parallel_portio_sw_list[] = {
     PORTIO_END_OF_LIST(),
 };
 
-static int parallel_isa_initfn(ISADevice *dev)
+static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
 {
     static int index;
+    ISADevice *isadev = ISA_DEVICE(dev);
     ISAParallelState *isa = ISA_PARALLEL(dev);
     ParallelState *s = &isa->state;
     int base;
     uint8_t dummy;
 
     if (!s->chr) {
-        fprintf(stderr, "Can't create parallel device, empty char device\n");
-        exit(1);
+        error_setg(errp, "Can't create parallel device, empty char device");
+        return;
     }
 
-    if (isa->index == -1)
+    if (isa->index == -1) {
         isa->index = index;
-    if (isa->index >= MAX_PARALLEL_PORTS)
-        return -1;
-    if (isa->iobase == -1)
+    }
+    if (isa->index >= MAX_PARALLEL_PORTS) {
+        error_setg(errp, "Max. supported number of parallel ports is %d.",
+                   MAX_PARALLEL_PORTS);
+        return;
+    }
+    if (isa->iobase == -1) {
         isa->iobase = isa_parallel_io[isa->index];
+    }
     index++;
 
     base = isa->iobase;
-    isa_init_irq(dev, &s->irq, isa->isairq);
+    isa_init_irq(isadev, &s->irq, isa->isairq);
     qemu_register_reset(parallel_reset, s);
 
     if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
@@ -507,12 +513,11 @@ static int parallel_isa_initfn(ISADevice *dev)
         s->status = dummy;
     }
 
-    isa_register_portio_list(dev, base,
+    isa_register_portio_list(isadev, base,
                              (s->hw_driver
                               ? &isa_parallel_portio_hw_list[0]
                               : &isa_parallel_portio_sw_list[0]),
                              s, "parallel");
-    return 0;
 }
 
 /* Memory mapped interface */
@@ -599,8 +604,8 @@ static Property parallel_isa_properties[] = {
 static void parallel_isa_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = parallel_isa_initfn;
+
+    dc->realize = parallel_isa_realizefn;
     dc->props = parallel_isa_properties;
 }
 
diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c
index 342b4cc..6e7e0dd 100644
--- a/hw/char/serial-isa.c
+++ b/hw/char/serial-isa.c
@@ -44,9 +44,10 @@ static const int isa_serial_irq[MAX_SERIAL_PORTS] = {
     4, 3, 4, 3
 };
 
-static int serial_isa_initfn(ISADevice *dev)
+static void serial_isa_realizefn(DeviceState *dev, Error **errp)
 {
     static int index;
+    ISADevice *isadev = ISA_DEVICE(dev);
     ISASerialState *isa = ISA_SERIAL(dev);
     SerialState *s = &isa->state;
 
@@ -54,7 +55,9 @@ static int serial_isa_initfn(ISADevice *dev)
         isa->index = index;
     }
     if (isa->index >= MAX_SERIAL_PORTS) {
-        return -1;
+        error_setg(errp, "Max. supported number of ISA serial ports is %d.",
+                   MAX_SERIAL_PORTS);
+        return;
     }
     if (isa->iobase == -1) {
         isa->iobase = isa_serial_io[isa->index];
@@ -65,13 +68,12 @@ static int serial_isa_initfn(ISADevice *dev)
     index++;
 
     s->baudbase = 115200;
-    isa_init_irq(dev, &s->irq, isa->isairq);
-    serial_init_core(s);
-    qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 3);
+    isa_init_irq(isadev, &s->irq, isa->isairq);
+    serial_realize_core(s, errp);
+    qdev_set_legacy_instance_id(dev, isa->iobase, 3);
 
     memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8);
-    isa_register_ioport(dev, &s->io, isa->iobase);
-    return 0;
+    isa_register_ioport(isadev, &s->io, isa->iobase);
 }
 
 static const VMStateDescription vmstate_isa_serial = {
@@ -96,8 +98,8 @@ static Property serial_isa_properties[] = {
 static void serial_isa_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = serial_isa_initfn;
+
+    dc->realize = serial_isa_realizefn;
     dc->vmsd = &vmstate_isa_serial;
     dc->props = serial_isa_properties;
 }
diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c
index 2138e35..3bec8eb 100644
--- a/hw/char/serial-pci.c
+++ b/hw/char/serial-pci.c
@@ -27,6 +27,7 @@
 
 #include "hw/char/serial.h"
 #include "hw/pci/pci.h"
+#include "qapi/qmp/qerror.h"
 
 #define PCI_SERIAL_MAX_PORTS 4
 
@@ -49,9 +50,15 @@ static int serial_pci_init(PCIDevice *dev)
 {
     PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
     SerialState *s = &pci->state;
+    Error *err = NULL;
 
     s->baudbase = 115200;
-    serial_init_core(s);
+    serial_realize_core(s, &err);
+    if (err != NULL) {
+        qerror_report_err(err);
+        error_free(err);
+        return -1;
+    }
 
     pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
     s->irq = pci->dev.irq[0];
@@ -80,6 +87,7 @@ static int multi_serial_pci_init(PCIDevice *dev)
     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
     PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev);
     SerialState *s;
+    Error *err = NULL;
     int i;
 
     switch (pc->device_id) {
@@ -102,7 +110,12 @@ static int multi_serial_pci_init(PCIDevice *dev)
     for (i = 0; i < pci->ports; i++) {
         s = pci->state + i;
         s->baudbase = 115200;
-        serial_init_core(s);
+        serial_realize_core(s, &err);
+        if (err != NULL) {
+            qerror_report_err(err);
+            error_free(err);
+            return -1;
+        }
         s->irq = pci->irqs[i];
         pci->name[i] = g_strdup_printf("uart #%d", i+1);
         memory_region_init_io(&s->io, &serial_io_ops, s, pci->name[i], 8);
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 66b6348..f2701e8 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -670,11 +670,11 @@ static void serial_reset(void *opaque)
     qemu_irq_lower(s->irq);
 }
 
-void serial_init_core(SerialState *s)
+void serial_realize_core(SerialState *s, Error **errp)
 {
     if (!s->chr) {
-        fprintf(stderr, "Can't create serial device, empty char device\n");
-	exit(1);
+        error_setg(errp, "Can't create serial device, empty char device");
+        return;
     }
 
     s->modem_status_poll = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) serial_update_msl, s);
@@ -713,13 +713,19 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
                          CharDriverState *chr, MemoryRegion *system_io)
 {
     SerialState *s;
+    Error *err = NULL;
 
     s = g_malloc0(sizeof(SerialState));
 
     s->irq = irq;
     s->baudbase = baudbase;
     s->chr = chr;
-    serial_init_core(s);
+    serial_realize_core(s, &err);
+    if (err != NULL) {
+        fprintf(stderr, "%s\n", error_get_pretty(err));
+        error_free(err);
+        exit(1);
+    }
 
     vmstate_register(NULL, base, &vmstate_serial, s);
 
@@ -769,6 +775,7 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
                             CharDriverState *chr, enum device_endian end)
 {
     SerialState *s;
+    Error *err = NULL;
 
     s = g_malloc0(sizeof(SerialState));
 
@@ -777,7 +784,12 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
     s->baudbase = baudbase;
     s->chr = chr;
 
-    serial_init_core(s);
+    serial_realize_core(s, &err);
+    if (err != NULL) {
+        fprintf(stderr, "%s\n", error_get_pretty(err));
+        error_free(err);
+        exit(1);
+    }
     vmstate_register(NULL, base, &vmstate_serial, s);
 
     memory_region_init_io(&s->io, &serial_mm_ops[end], s,
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
index a5dbc39..0d9eee8 100644
--- a/hw/display/cirrus_vga.c
+++ b/hw/display/cirrus_vga.c
@@ -2906,19 +2906,20 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci,
  *
  ***************************************/
 
-static int vga_initfn(ISADevice *dev)
+static void isa_cirrus_vga_realizefn(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     ISACirrusVGAState *d = ISA_CIRRUS_VGA(dev);
     VGACommonState *s = &d->cirrus_vga.vga;
 
     vga_common_init(s);
     cirrus_init_common(&d->cirrus_vga, CIRRUS_ID_CLGD5430, 0,
-                       isa_address_space(dev), isa_address_space_io(dev));
-    s->con = graphic_console_init(DEVICE(dev), s->hw_ops, s);
+                       isa_address_space(isadev),
+                       isa_address_space_io(isadev));
+    s->con = graphic_console_init(dev, s->hw_ops, s);
     rom_add_vga(VGABIOS_CIRRUS_FILENAME);
     /* XXX ISA-LFB support */
     /* FIXME not qdev yet */
-    return 0;
 }
 
 static Property isa_cirrus_vga_properties[] = {
@@ -2929,11 +2930,10 @@ static Property isa_cirrus_vga_properties[] = {
 
 static void isa_cirrus_vga_class_init(ObjectClass *klass, void *data)
 {
-    ISADeviceClass *k = ISA_DEVICE_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->vmsd  = &vmstate_cirrus_vga;
-    k->init   = vga_initfn;
+    dc->realize = isa_cirrus_vga_realizefn;
     dc->props = isa_cirrus_vga_properties;
 }
 
diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c
index 9e63b69..d1691a9 100644
--- a/hw/display/vga-isa.c
+++ b/hw/display/vga-isa.c
@@ -48,30 +48,30 @@ static void vga_isa_reset(DeviceState *dev)
     vga_common_reset(s);
 }
 
-static int vga_initfn(ISADevice *dev)
+static void vga_isa_realizefn(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     ISAVGAState *d = ISA_VGA(dev);
     VGACommonState *s = &d->state;
     MemoryRegion *vga_io_memory;
     const MemoryRegionPortio *vga_ports, *vbe_ports;
 
     vga_common_init(s);
-    s->legacy_address_space = isa_address_space(dev);
+    s->legacy_address_space = isa_address_space(isadev);
     vga_io_memory = vga_init_io(s, &vga_ports, &vbe_ports);
-    isa_register_portio_list(dev, 0x3b0, vga_ports, s, "vga");
+    isa_register_portio_list(isadev, 0x3b0, vga_ports, s, "vga");
     if (vbe_ports) {
-        isa_register_portio_list(dev, 0x1ce, vbe_ports, s, "vbe");
+        isa_register_portio_list(isadev, 0x1ce, vbe_ports, s, "vbe");
     }
-    memory_region_add_subregion_overlap(isa_address_space(dev),
+    memory_region_add_subregion_overlap(isa_address_space(isadev),
                                         isa_mem_base + 0x000a0000,
                                         vga_io_memory, 1);
     memory_region_set_coalescing(vga_io_memory);
     s->con = graphic_console_init(DEVICE(dev), s->hw_ops, s);
 
-    vga_init_vbe(s, isa_address_space(dev));
+    vga_init_vbe(s, isa_address_space(isadev));
     /* ROM BIOS */
     rom_add_vga(VGABIOS_FILENAME);
-    return 0;
 }
 
 static Property vga_isa_properties[] = {
@@ -82,9 +82,8 @@ static Property vga_isa_properties[] = {
 static void vga_isa_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
 
-    ic->init = vga_initfn;
+    dc->realize = vga_isa_realizefn;
     dc->reset = vga_isa_reset;
     dc->vmsd = &vmstate_vga_common;
     dc->props = vga_isa_properties;
diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c
index f3d1924..6192780 100644
--- a/hw/dma/i82374.c
+++ b/hw/dma/i82374.c
@@ -98,7 +98,7 @@ static uint32_t i82374_read_descriptor(void *opaque, uint32_t nport)
     return val;
 }
 
-static void i82374_init(I82374State *s)
+static void i82374_realize(I82374State *s, Error **errp)
 {
     DMA_init(1, &s->out);
     memset(s->commands, 0, sizeof(s->commands));
@@ -124,7 +124,7 @@ static const VMStateDescription vmstate_isa_i82374 = {
     },
 };
 
-static int i82374_isa_init(ISADevice *dev)
+static void i82374_isa_realize(DeviceState *dev, Error **errp)
 {
     ISAi82374State *isa = I82374(dev);
     I82374State *s = &isa->state;
@@ -135,11 +135,9 @@ static int i82374_isa_init(ISADevice *dev)
     register_ioport_write(isa->iobase + 0x20, 0x20, 1, i82374_write_descriptor, s);
     register_ioport_read(isa->iobase + 0x20, 0x20, 1, i82374_read_descriptor, s);
 
-    i82374_init(s);
+    i82374_realize(s, errp);
 
-    qdev_init_gpio_out(&dev->qdev, &s->out, 1);
-
-    return 0;
+    qdev_init_gpio_out(dev, &s->out, 1);
 }
 
 static Property i82374_properties[] = {
@@ -149,10 +147,9 @@ static Property i82374_properties[] = {
 
 static void i82374_class_init(ObjectClass *klass, void *data)
 {
-    ISADeviceClass *k = ISA_DEVICE_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
     
-    k->init  = i82374_isa_init;
+    dc->realize = i82374_isa_realize;
     dc->vmsd = &vmstate_isa_i82374;
     dc->props = i82374_properties;
 }
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 4844a6b..e9c91e4 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -522,23 +522,29 @@ static const MemoryRegionOps port92_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static int port92_initfn(ISADevice *dev)
+static void port92_initfn(Object *obj)
 {
-    Port92State *s = PORT92(dev);
+    Port92State *s = PORT92(obj);
 
     memory_region_init_io(&s->io, &port92_ops, s, "port92", 1);
-    isa_register_ioport(dev, &s->io, 0x92);
 
     s->outport = 0;
-    return 0;
+}
+
+static void port92_realizefn(DeviceState *dev, Error **errp)
+{
+    ISADevice *isadev = ISA_DEVICE(dev);
+    Port92State *s = PORT92(dev);
+
+    isa_register_ioport(isadev, &s->io, 0x92);
 }
 
 static void port92_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = port92_initfn;
+
     dc->no_user = 1;
+    dc->realize = port92_realizefn;
     dc->reset = port92_reset;
     dc->vmsd = &vmstate_port92_isa;
 }
@@ -547,6 +553,7 @@ static const TypeInfo port92_info = {
     .name          = TYPE_PORT92,
     .parent        = TYPE_ISA_DEVICE,
     .instance_size = sizeof(Port92State),
+    .instance_init = port92_initfn,
     .class_init    = port92_class_initfn,
 };
 
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 369a7fa..7243c82 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -65,16 +65,16 @@ static const VMStateDescription vmstate_ide_isa = {
     }
 };
 
-static int isa_ide_initfn(ISADevice *dev)
+static void isa_ide_realizefn(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     ISAIDEState *s = ISA_IDE(dev);
 
-    ide_bus_new(&s->bus, DEVICE(dev), 0, 2);
-    ide_init_ioport(&s->bus, dev, s->iobase, s->iobase2);
-    isa_init_irq(dev, &s->irq, s->isairq);
+    ide_bus_new(&s->bus, dev, 0, 2);
+    ide_init_ioport(&s->bus, isadev, s->iobase, s->iobase2);
+    isa_init_irq(isadev, &s->irq, s->isairq);
     ide_init2(&s->bus, s->irq);
-    vmstate_register(&dev->qdev, 0, &vmstate_ide_isa, s);
-    return 0;
+    vmstate_register(dev, 0, &vmstate_ide_isa, s);
 };
 
 ISADevice *isa_ide_init(ISABus *bus, int iobase, int iobase2, int isairq,
@@ -113,8 +113,8 @@ static Property isa_ide_properties[] = {
 static void isa_ide_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = isa_ide_initfn;
+
+    dc->realize = isa_ide_realizefn;
     dc->fw_name = "ide";
     dc->reset = isa_ide_reset;
     dc->props = isa_ide_properties;
diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
index 17a5614..fff0a4d 100644
--- a/hw/input/pckbd.c
+++ b/hw/input/pckbd.c
@@ -489,31 +489,37 @@ static const MemoryRegionOps i8042_cmd_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static int i8042_initfn(ISADevice *dev)
+static void i8042_initfn(Object *obj)
 {
-    ISAKBDState *isa_s = I8042(dev);
+    ISAKBDState *isa_s = I8042(obj);
     KBDState *s = &isa_s->kbd;
 
-    isa_init_irq(dev, &s->irq_kbd, 1);
-    isa_init_irq(dev, &s->irq_mouse, 12);
-
     memory_region_init_io(isa_s->io + 0, &i8042_data_ops, s, "i8042-data", 1);
-    isa_register_ioport(dev, isa_s->io + 0, 0x60);
-
     memory_region_init_io(isa_s->io + 1, &i8042_cmd_ops, s, "i8042-cmd", 1);
-    isa_register_ioport(dev, isa_s->io + 1, 0x64);
+}
+
+static void i8042_realizefn(DeviceState *dev, Error **errp)
+{
+    ISADevice *isadev = ISA_DEVICE(dev);
+    ISAKBDState *isa_s = I8042(dev);
+    KBDState *s = &isa_s->kbd;
+
+    isa_init_irq(isadev, &s->irq_kbd, 1);
+    isa_init_irq(isadev, &s->irq_mouse, 12);
+
+    isa_register_ioport(isadev, isa_s->io + 0, 0x60);
+    isa_register_ioport(isadev, isa_s->io + 1, 0x64);
 
     s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s);
     s->mouse = ps2_mouse_init(kbd_update_aux_irq, s);
     qemu_register_reset(kbd_reset, s);
-    return 0;
 }
 
 static void i8042_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = i8042_initfn;
+
+    dc->realize = i8042_realizefn;
     dc->no_user = 1;
     dc->vmsd = &vmstate_kbd_isa;
 }
@@ -522,6 +528,7 @@ static const TypeInfo i8042_info = {
     .name          = TYPE_I8042,
     .parent        = TYPE_ISA_DEVICE,
     .instance_size = sizeof(ISAKBDState),
+    .instance_init = i8042_initfn,
     .class_init    = i8042_class_initfn,
 };
 
diff --git a/hw/input/vmmouse.c b/hw/input/vmmouse.c
index a610738..abd032b 100644
--- a/hw/input/vmmouse.c
+++ b/hw/input/vmmouse.c
@@ -261,7 +261,7 @@ static void vmmouse_reset(DeviceState *d)
     vmmouse_disable(s);
 }
 
-static int vmmouse_initfn(ISADevice *dev)
+static void vmmouse_realizefn(DeviceState *dev, Error **errp)
 {
     VMMouseState *s = VMMOUSE(dev);
 
@@ -270,8 +270,6 @@ static int vmmouse_initfn(ISADevice *dev)
     vmport_register(VMMOUSE_STATUS, vmmouse_ioport_read, s);
     vmport_register(VMMOUSE_COMMAND, vmmouse_ioport_read, s);
     vmport_register(VMMOUSE_DATA, vmmouse_ioport_read, s);
-
-    return 0;
 }
 
 static Property vmmouse_properties[] = {
@@ -282,8 +280,8 @@ static Property vmmouse_properties[] = {
 static void vmmouse_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = vmmouse_initfn;
+
+    dc->realize = vmmouse_realizefn;
     dc->no_user = 1;
     dc->reset = vmmouse_reset;
     dc->vmsd = &vmstate_vmmouse;
diff --git a/hw/intc/i8259_common.c b/hw/intc/i8259_common.c
index c2ba6a5..a3dee38 100644
--- a/hw/intc/i8259_common.c
+++ b/hw/intc/i8259_common.c
@@ -66,7 +66,7 @@ static int pic_dispatch_post_load(void *opaque, int version_id)
     return 0;
 }
 
-static int pic_init_common(ISADevice *dev)
+static void pic_common_realize(DeviceState *dev, Error **errp)
 {
     PICCommonState *s = PIC_COMMON(dev);
     PICCommonClass *info = PIC_COMMON_GET_CLASS(s);
@@ -78,9 +78,7 @@ static int pic_init_common(ISADevice *dev)
         isa_register_ioport(NULL, &s->elcr_io, s->elcr_addr);
     }
 
-    qdev_set_legacy_instance_id(DEVICE(dev), s->iobase, 1);
-
-    return 0;
+    qdev_set_legacy_instance_id(dev, s->iobase, 1);
 }
 
 ISADevice *i8259_init_chip(const char *name, ISABus *bus, bool master)
@@ -135,13 +133,12 @@ static Property pic_properties_common[] = {
 
 static void pic_common_class_init(ObjectClass *klass, void *data)
 {
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->vmsd = &vmstate_pic_common;
     dc->no_user = 1;
     dc->props = pic_properties_common;
-    ic->init = pic_init_common;
+    dc->realize = pic_common_realize;
 }
 
 static const TypeInfo pic_common_type = {
diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index 7860b17..f12b15d 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -119,18 +119,6 @@ void isa_register_portio_list(ISADevice *dev, uint16_t start,
     portio_list_add(piolist, isabus->address_space_io, start);
 }
 
-static int isa_qdev_init(DeviceState *qdev)
-{
-    ISADevice *dev = ISA_DEVICE(qdev);
-    ISADeviceClass *klass = ISA_DEVICE_GET_CLASS(dev);
-
-    if (klass->init) {
-        return klass->init(dev);
-    }
-
-    return 0;
-}
-
 static void isa_device_init(Object *obj)
 {
     ISADevice *dev = ISA_DEVICE(obj);
@@ -230,7 +218,6 @@ static const TypeInfo isabus_bridge_info = {
 static void isa_device_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *k = DEVICE_CLASS(klass);
-    k->init = isa_qdev_init;
     k->bus_type = TYPE_ISA_BUS;
 }
 
diff --git a/hw/isa/pc87312.c b/hw/isa/pc87312.c
index 82f7c80..cc426df 100644
--- a/hw/isa/pc87312.c
+++ b/hw/isa/pc87312.c
@@ -264,7 +264,7 @@ static void pc87312_reset(DeviceState *d)
     pc87312_soft_reset(s);
 }
 
-static int pc87312_init(ISADevice *dev)
+static void pc87312_realize(DeviceState *dev, Error **errp)
 {
     PC87312State *s;
     DeviceState *d;
@@ -276,9 +276,10 @@ static int pc87312_init(ISADevice *dev)
     int i;
 
     s = PC87312(dev);
-    bus = isa_bus_from_device(dev);
+    isa = ISA_DEVICE(dev);
+    bus = isa_bus_from_device(isa);
+    isa_register_ioport(isa, &s->io, s->iobase);
     pc87312_hard_reset(s);
-    isa_register_ioport(dev, &s->io, s->iobase);
 
     if (is_parallel_enabled(s)) {
         chr = parallel_hds[0];
@@ -345,8 +346,6 @@ static int pc87312_init(ISADevice *dev)
         s->ide.dev = isa;
         trace_pc87312_info_ide(get_ide_iobase(s));
     }
-
-    return 0;
 }
 
 static void pc87312_initfn(Object *obj)
@@ -378,9 +377,8 @@ static Property pc87312_properties[] = {
 static void pc87312_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
 
-    ic->init = pc87312_init;
+    dc->realize = pc87312_realize;
     dc->reset = pc87312_reset;
     dc->vmsd = &vmstate_pc87312;
     dc->props = pc87312_properties;
diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 78904a8..46f4fbd 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -201,7 +201,7 @@ static void qdev_applesmc_isa_reset(DeviceState *dev)
     applesmc_add_key(s, "MSSD", 1, "\0x3");
 }
 
-static int applesmc_isa_init(ISADevice *dev)
+static void applesmc_isa_realize(DeviceState *dev, Error **errp)
 {
     AppleSMCState *s = APPLE_SMC(dev);
 
@@ -220,9 +220,7 @@ static int applesmc_isa_init(ISADevice *dev)
     }
 
     QLIST_INIT(&s->data_def);
-    qdev_applesmc_isa_reset(&dev->qdev);
-
-    return 0;
+    qdev_applesmc_isa_reset(dev);
 }
 
 static Property applesmc_isa_properties[] = {
@@ -235,8 +233,8 @@ static Property applesmc_isa_properties[] = {
 static void qdev_applesmc_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = applesmc_isa_init;
+
+    dc->realize = applesmc_isa_realize;
     dc->reset = qdev_applesmc_isa_reset;
     dc->props = applesmc_isa_properties;
 }
diff --git a/hw/misc/debugexit.c b/hw/misc/debugexit.c
index 59bed5b..ee254e4 100644
--- a/hw/misc/debugexit.c
+++ b/hw/misc/debugexit.c
@@ -35,15 +35,15 @@ static const MemoryRegionOps debug_exit_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static int debug_exit_initfn(ISADevice *dev)
+static void debug_exit_realizefn(DeviceState *d, Error **errp)
 {
-    ISADebugExitState *isa = ISA_DEBUG_EXIT_DEVICE(dev);
+    ISADevice *dev = ISA_DEVICE(d);
+    ISADebugExitState *isa = ISA_DEBUG_EXIT_DEVICE(d);
 
     memory_region_init_io(&isa->io, &debug_exit_ops, isa,
                           TYPE_ISA_DEBUG_EXIT_DEVICE, isa->iosize);
     memory_region_add_subregion(isa_address_space_io(dev),
                                 isa->iobase, &isa->io);
-    return 0;
 }
 
 static Property debug_exit_properties[] = {
@@ -55,8 +55,8 @@ static Property debug_exit_properties[] = {
 static void debug_exit_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = debug_exit_initfn;
+
+    dc->realize = debug_exit_realizefn;
     dc->props = debug_exit_properties;
 }
 
diff --git a/hw/misc/pc-testdev.c b/hw/misc/pc-testdev.c
index 32df175..e6707d6 100644
--- a/hw/misc/pc-testdev.c
+++ b/hw/misc/pc-testdev.c
@@ -142,9 +142,10 @@ static const MemoryRegionOps test_iomem_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static int init_test_device(ISADevice *isa)
+static void testdev_realizefn(DeviceState *d, Error **errp)
 {
-    PCTestdev *dev = TESTDEV(isa);
+    ISADevice *isa = ISA_DEVICE(d);
+    PCTestdev *dev = TESTDEV(d);
     MemoryRegion *mem = isa_address_space(isa);
     MemoryRegion *io = isa_address_space_io(isa);
 
@@ -161,15 +162,13 @@ static int init_test_device(ISADevice *isa)
     memory_region_add_subregion(io,  0xe4,       &dev->flush);
     memory_region_add_subregion(io,  0x2000,     &dev->irq);
     memory_region_add_subregion(mem, 0xff000000, &dev->iomem);
-
-    return 0;
 }
 
 static void testdev_class_init(ObjectClass *klass, void *data)
 {
-    ISADeviceClass *k = ISA_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
-    k->init = init_test_device;
+    dc->realize = testdev_realizefn;
 }
 
 static const TypeInfo testdev_info = {
diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 910e44f..060099b 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -86,14 +86,21 @@ static const MemoryRegionOps pvpanic_ops = {
     },
 };
 
-static int pvpanic_isa_initfn(ISADevice *dev)
+static void pvpanic_isa_initfn(Object *obj)
 {
+    PVPanicState *s = ISA_PVPANIC_DEVICE(obj);
+
+    memory_region_init_io(&s->io, &pvpanic_ops, s, "pvpanic", 1);
+}
+
+static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp)
+{
+    ISADevice *d = ISA_DEVICE(dev);
     PVPanicState *s = ISA_PVPANIC_DEVICE(dev);
     static bool port_configured;
     FWCfgState *fw_cfg;
 
-    memory_region_init_io(&s->io, &pvpanic_ops, s, "pvpanic", 1);
-    isa_register_ioport(dev, &s->io, s->ioport);
+    isa_register_ioport(d, &s->io, s->ioport);
 
     if (!port_configured) {
         fw_cfg = fw_cfg_find();
@@ -104,8 +111,6 @@ static int pvpanic_isa_initfn(ISADevice *dev)
             port_configured = true;
         }
     }
-
-    return 0;
 }
 
 int pvpanic_init(ISABus *bus)
@@ -122,9 +127,8 @@ static Property pvpanic_isa_properties[] = {
 static void pvpanic_isa_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
 
-    ic->init = pvpanic_isa_initfn;
+    dc->realize = pvpanic_isa_realizefn;
     dc->no_user = 1;
     dc->props = pvpanic_isa_properties;
 }
@@ -133,6 +137,7 @@ static TypeInfo pvpanic_isa_info = {
     .name          = TYPE_ISA_PVPANIC_DEVICE,
     .parent        = TYPE_ISA_DEVICE,
     .instance_size = sizeof(PVPanicState),
+    .instance_init = pvpanic_isa_initfn,
     .class_init    = pvpanic_isa_class_init,
 };
 
diff --git a/hw/misc/sga.c b/hw/misc/sga.c
index c842190..08803e7 100644
--- a/hw/misc/sga.c
+++ b/hw/misc/sga.c
@@ -38,17 +38,16 @@ typedef struct ISASGAState {
     ISADevice parent_obj;
 } ISASGAState;
 
-static int sga_initfn(ISADevice *dev)
+static void sga_realizefn(DeviceState *dev, Error **errp)
 {
     rom_add_vga(SGABIOS_FILENAME);
-    return 0;
 }
 
 static void sga_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = sga_initfn;
+
+    dc->realize = sga_realizefn;
     dc->desc = "Serial Graphics Adapter";
 }
 
diff --git a/hw/misc/vmport.c b/hw/misc/vmport.c
index c146129..57b71f5 100644
--- a/hw/misc/vmport.c
+++ b/hw/misc/vmport.c
@@ -137,25 +137,25 @@ static const MemoryRegionOps vmport_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static int vmport_initfn(ISADevice *dev)
+static void vmport_realizefn(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     VMPortState *s = VMPORT(dev);
 
     memory_region_init_io(&s->io, &vmport_ops, s, "vmport", 1);
-    isa_register_ioport(dev, &s->io, 0x5658);
+    isa_register_ioport(isadev, &s->io, 0x5658);
 
     port_state = s;
     /* Register some generic port commands */
     vmport_register(VMPORT_CMD_GETVERSION, vmport_cmd_get_version, NULL);
     vmport_register(VMPORT_CMD_GETRAMSIZE, vmport_cmd_ram_size, NULL);
-    return 0;
 }
 
 static void vmport_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = vmport_initfn;
+
+    dc->realize = vmport_realizefn;
     dc->no_user = 1;
 }
 
diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c
index f8e610c..9232abd 100644
--- a/hw/net/ne2000-isa.c
+++ b/hw/net/ne2000-isa.c
@@ -66,24 +66,23 @@ static const VMStateDescription vmstate_isa_ne2000 = {
     }
 };
 
-static int isa_ne2000_initfn(ISADevice *dev)
+static void isa_ne2000_realizefn(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     ISANE2000State *isa = ISA_NE2000(dev);
     NE2000State *s = &isa->ne2000;
 
     ne2000_setup_io(s, 0x20);
-    isa_register_ioport(dev, &s->io, isa->iobase);
+    isa_register_ioport(isadev, &s->io, isa->iobase);
 
-    isa_init_irq(dev, &s->irq, isa->isairq);
+    isa_init_irq(isadev, &s->irq, isa->isairq);
 
     qemu_macaddr_default_if_unset(&s->c.macaddr);
     ne2000_reset(s);
 
     s->nic = qemu_new_nic(&net_ne2000_isa_info, &s->c,
-                          object_get_typename(OBJECT(dev)), dev->qdev.id, s);
+                          object_get_typename(OBJECT(dev)), dev->id, s);
     qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
-
-    return 0;
 }
 
 static Property ne2000_isa_properties[] = {
@@ -96,8 +95,8 @@ static Property ne2000_isa_properties[] = {
 static void isa_ne2000_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = isa_ne2000_initfn;
+
+    dc->realize = isa_ne2000_realizefn;
     dc->props = ne2000_isa_properties;
 }
 
diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c
index 5342df4..36eed80 100644
--- a/hw/timer/i8254_common.c
+++ b/hw/timer/i8254_common.c
@@ -166,22 +166,22 @@ void pit_reset_common(PITCommonState *pit)
     }
 }
 
-static int pit_init_common(ISADevice *dev)
+static void pit_common_realize(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     PITCommonState *pit = PIT_COMMON(dev);
     PITCommonClass *c = PIT_COMMON_GET_CLASS(pit);
     int ret;
 
     ret = c->init(pit);
     if (ret < 0) {
-        return ret;
+        error_setg(errp, "PIT init failed.");
+        return;
     }
 
-    isa_register_ioport(dev, &pit->ioports, pit->iobase);
+    isa_register_ioport(isadev, &pit->ioports, pit->iobase);
 
-    qdev_set_legacy_instance_id(&dev->qdev, pit->iobase, 2);
-
-    return 0;
+    qdev_set_legacy_instance_id(dev, pit->iobase, 2);
 }
 
 static const VMStateDescription vmstate_pit_channel = {
@@ -286,10 +286,9 @@ static const VMStateDescription vmstate_pit_common = {
 
 static void pit_common_class_init(ObjectClass *klass, void *data)
 {
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
-    ic->init = pit_init_common;
+    dc->realize = pit_common_realize;
     dc->vmsd = &vmstate_pit_common;
     dc->no_user = 1;
 }
diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
index 45753d8..bf6c4c8 100644
--- a/hw/timer/m48t59.c
+++ b/hw/timer/m48t59.c
@@ -691,7 +691,7 @@ M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
     return s;
 }
 
-static void m48t59_init_common(M48t59State *s)
+static void m48t59_realize_common(M48t59State *s, Error **errp)
 {
     s->buffer = g_malloc0(s->size);
     if (s->model == 59) {
@@ -703,27 +703,31 @@ static void m48t59_init_common(M48t59State *s)
     vmstate_register(NULL, -1, &vmstate_m48t59, s);
 }
 
-static int m48t59_init_isa1(ISADevice *dev)
+static void m48t59_isa_realize(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     M48t59ISAState *d = ISA_M48T59(dev);
     M48t59State *s = &d->state;
 
-    isa_init_irq(dev, &s->IRQ, 8);
-    m48t59_init_common(s);
-
-    return 0;
+    isa_init_irq(isadev, &s->IRQ, 8);
+    m48t59_realize_common(s, errp);
 }
 
 static int m48t59_init1(SysBusDevice *dev)
 {
     M48t59SysBusState *d = FROM_SYSBUS(M48t59SysBusState, dev);
     M48t59State *s = &d->state;
+    Error *err = NULL;
 
     sysbus_init_irq(dev, &s->IRQ);
 
     memory_region_init_io(&s->iomem, &nvram_ops, s, "m48t59.nvram", s->size);
     sysbus_init_mmio(dev, &s->iomem);
-    m48t59_init_common(s);
+    m48t59_realize_common(s, &err);
+    if (err != NULL) {
+        error_free(err);
+        return -1;
+    }
 
     return 0;
 }
@@ -738,8 +742,8 @@ static Property m48t59_isa_properties[] = {
 static void m48t59_isa_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = m48t59_init_isa1;
+
+    dc->realize = m48t59_isa_realize;
     dc->no_user = 1;
     dc->reset = m48t59_reset_isa;
     dc->props = m48t59_isa_properties;
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 481604d..9c4a7bd 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -814,8 +814,9 @@ static void rtc_get_date(Object *obj, Visitor *v, void *opaque,
     visit_end_struct(v, errp);
 }
 
-static int rtc_initfn(ISADevice *dev)
+static void rtc_realizefn(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     RTCState *s = MC146818_RTC(dev);
     int base = 0x70;
 
@@ -836,7 +837,7 @@ static int rtc_initfn(ISADevice *dev)
         s->base_year = 0;
     }
 
-    rtc_set_date_from_host(dev);
+    rtc_set_date_from_host(isadev);
 
 #ifdef TARGET_I386
     switch (s->lost_tick_policy) {
@@ -847,7 +848,8 @@ static int rtc_initfn(ISADevice *dev)
     case LOST_TICK_DISCARD:
         break;
     default:
-        return -EINVAL;
+        error_setg(errp, "Invalid lost tick policy.");
+        return;
     }
 #endif
 
@@ -862,15 +864,13 @@ static int rtc_initfn(ISADevice *dev)
     qemu_register_suspend_notifier(&s->suspend_notifier);
 
     memory_region_init_io(&s->io, &cmos_ops, s, "rtc", 2);
-    isa_register_ioport(dev, &s->io, base);
+    isa_register_ioport(isadev, &s->io, base);
 
-    qdev_set_legacy_instance_id(&dev->qdev, base, 3);
+    qdev_set_legacy_instance_id(dev, base, 3);
     qemu_register_reset(rtc_reset, s);
 
     object_property_add(OBJECT(s), "date", "struct tm",
                         rtc_get_date, NULL, NULL, s, NULL);
-
-    return 0;
 }
 
 ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq)
@@ -902,8 +902,8 @@ static Property mc146818rtc_properties[] = {
 static void rtc_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = rtc_initfn;
+
+    dc->realize = rtc_realizefn;
     dc->no_user = 1;
     dc->vmsd = &vmstate_rtc;
     dc->props = mc146818rtc_properties;
diff --git a/hw/watchdog/wdt_ib700.c b/hw/watchdog/wdt_ib700.c
index 6b8e33a..d85c894 100644
--- a/hw/watchdog/wdt_ib700.c
+++ b/hw/watchdog/wdt_ib700.c
@@ -97,7 +97,7 @@ static const VMStateDescription vmstate_ib700 = {
     }
 };
 
-static int wdt_ib700_init(ISADevice *dev)
+static void wdt_ib700_realize(DeviceState *dev, Error **errp)
 {
     IB700State *s = IB700(dev);
 
@@ -106,8 +106,6 @@ static int wdt_ib700_init(ISADevice *dev)
     s->timer = qemu_new_timer_ns(vm_clock, ib700_timer_expired, s);
     register_ioport_write(0x441, 2, 1, ib700_write_disable_reg, s);
     register_ioport_write(0x443, 2, 1, ib700_write_enable_reg, s);
-
-    return 0;
 }
 
 static void wdt_ib700_reset(DeviceState *dev)
@@ -127,8 +125,8 @@ static WatchdogTimerModel model = {
 static void wdt_ib700_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = wdt_ib700_init;
+
+    dc->realize = wdt_ib700_realize;
     dc->reset = wdt_ib700_reset;
     dc->vmsd = &vmstate_ib700;
 }
diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h
index bca79f1..c15354a 100644
--- a/include/hw/char/serial.h
+++ b/include/hw/char/serial.h
@@ -83,7 +83,7 @@ struct SerialState {
 extern const VMStateDescription vmstate_serial;
 extern const MemoryRegionOps serial_io_ops;
 
-void serial_init_core(SerialState *s);
+void serial_realize_core(SerialState *s, Error **errp);
 void serial_exit_core(SerialState *s);
 void serial_set_frequency(SerialState *s, uint32_t frequency);
 
diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index 82da37c..1f6ff55 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -22,7 +22,6 @@
 
 typedef struct ISADeviceClass {
     DeviceClass parent_class;
-    int (*init)(ISADevice *dev);
 } ISADeviceClass;
 
 struct ISABus {
commit a3dcca567a1d4a5c79fb9c8fe2d9a21a4a7cebd5
Author: Andreas Färber <afaerber at suse.de>
Date:   Thu Jun 6 16:40:02 2013 +0200

    cs4231a: QOM'ify some more
    
    Introduce type constant and cast macro.
    Replace reset hook with DeviceClass::reset callback.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c
index cc605e5..d3ce739 100644
--- a/hw/audio/cs4231a.c
+++ b/hw/audio/cs4231a.c
@@ -56,6 +56,9 @@ static struct {
 #define CS_REGS 16
 #define CS_DREGS 32
 
+#define TYPE_CS4231A "cs4231a"
+#define CS4231A(obj) OBJECT_CHECK (CSState, (obj), TYPE_CS4231A)
+
 typedef struct CSState {
     ISADevice dev;
     QEMUSoundCard card;
@@ -208,9 +211,9 @@ static int16_t ALawDecompressTable[256] =
       944,   912,  1008,   976,   816,   784,   880,   848
 };
 
-static void cs_reset (void *opaque)
+static void cs4231a_reset (DeviceState *dev)
 {
-    CSState *s = opaque;
+    CSState *s = CS4231A (dev);
 
     s->regs[Index_Address] = 0x40;
     s->regs[Index_Data]    = 0x00;
@@ -643,7 +646,7 @@ static const MemoryRegionOps cs_ioport_ops = {
 
 static int cs4231a_initfn (ISADevice *dev)
 {
-    CSState *s = DO_UPCAST (CSState, dev, dev);
+    CSState *s = CS4231A (dev);
 
     isa_init_irq (dev, &s->pic, s->irq);
 
@@ -652,16 +655,13 @@ static int cs4231a_initfn (ISADevice *dev)
 
     DMA_register_channel (s->dma, cs_dma_read, s);
 
-    qemu_register_reset (cs_reset, s);
-    cs_reset (s);
-
     AUD_register_card ("cs4231a", &s->card);
     return 0;
 }
 
 static int cs4231a_init (ISABus *bus)
 {
-    isa_create_simple (bus, "cs4231a");
+    isa_create_simple (bus, TYPE_CS4231A);
     return 0;
 }
 
@@ -677,13 +677,14 @@ static void cs4231a_class_initfn (ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS (klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS (klass);
     ic->init = cs4231a_initfn;
+    dc->reset = cs4231a_reset;
     dc->desc = "Crystal Semiconductor CS4231A";
     dc->vmsd = &vmstate_cs4231a;
     dc->props = cs4231a_properties;
 }
 
 static const TypeInfo cs4231a_info = {
-    .name          = "cs4231a",
+    .name          = TYPE_CS4231A,
     .parent        = TYPE_ISA_DEVICE,
     .instance_size = sizeof (CSState),
     .class_init    = cs4231a_class_initfn,
commit 11c7549d836b3d3a4ccd903bbfdbdc942b9add52
Author: Andreas Färber <afaerber at suse.de>
Date:   Thu Jun 6 16:02:26 2013 +0200

    gus: QOM'ify some more
    
    Add type constant and cast macro.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/audio/gus.c b/hw/audio/gus.c
index a91921c..e0aea26 100644
--- a/hw/audio/gus.c
+++ b/hw/audio/gus.c
@@ -46,6 +46,9 @@
 #define IO_WRITE_PROTO(name) \
     static void name (void *opaque, uint32_t nport, uint32_t val)
 
+#define TYPE_GUS "gus"
+#define GUS(obj) OBJECT_CHECK (GUSState, (obj), TYPE_GUS)
+
 typedef struct GUSState {
     ISADevice dev;
     GUSEmuState emu;
@@ -250,7 +253,7 @@ static const MemoryRegionPortio gus_portio_list2[] = {
 
 static int gus_initfn (ISADevice *dev)
 {
-    GUSState *s = DO_UPCAST (GUSState, dev, dev);
+    GUSState *s = GUS (dev);
     struct audsettings as;
 
     AUD_register_card ("gus", &s->card);
@@ -295,7 +298,7 @@ static int gus_initfn (ISADevice *dev)
 
 static int GUS_init (ISABus *bus)
 {
-    isa_create_simple (bus, "gus");
+    isa_create_simple (bus, TYPE_GUS);
     return 0;
 }
 
@@ -318,7 +321,7 @@ static void gus_class_initfn (ObjectClass *klass, void *data)
 }
 
 static const TypeInfo gus_info = {
-    .name          = "gus",
+    .name          = TYPE_GUS,
     .parent        = TYPE_ISA_DEVICE,
     .instance_size = sizeof (GUSState),
     .class_init    = gus_class_initfn,
commit bd07684aacfb61668ae2c25b7dd00b64f3d7c7f3
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 15:17:58 2013 +0200

    ide-test: Add FLUSH CACHE test case
    
    This checks in particular that BSY is set while the flush request is in
    flight.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/tests/ide-test.c b/tests/ide-test.c
index 1c31a2e..828e71a 100644
--- a/tests/ide-test.c
+++ b/tests/ide-test.c
@@ -77,6 +77,7 @@ enum {
 enum {
     CMD_READ_DMA    = 0xc8,
     CMD_WRITE_DMA   = 0xca,
+    CMD_FLUSH_CACHE = 0xe7,
     CMD_IDENTIFY    = 0xec,
 
     CMDF_ABORT      = 0x100,
@@ -424,6 +425,43 @@ static void test_identify(void)
     ide_test_quit();
 }
 
+static void test_flush(void)
+{
+    uint8_t data;
+
+    ide_test_start(
+        "-vnc none "
+        "-drive file=blkdebug::%s,if=ide,cache=writeback",
+        tmp_path);
+
+    /* Delay the completion of the flush request until we explicitly do it */
+    qmp("{'execute':'human-monitor-command', 'arguments': { "
+        "'command-line': 'qemu-io ide0-hd0 \"break flush_to_os A\"'} }");
+
+    /* FLUSH CACHE command on device 0*/
+    outb(IDE_BASE + reg_device, 0);
+    outb(IDE_BASE + reg_command, CMD_FLUSH_CACHE);
+
+    /* Check status while request is in flight*/
+    data = inb(IDE_BASE + reg_status);
+    assert_bit_set(data, BSY | DRDY);
+    assert_bit_clear(data, DF | ERR | DRQ);
+
+    /* Complete the command */
+    qmp("{'execute':'human-monitor-command', 'arguments': { "
+        "'command-line': 'qemu-io ide0-hd0 \"resume A\"'} }");
+
+    /* Check registers */
+    data = inb(IDE_BASE + reg_device);
+    g_assert_cmpint(data & DEV, ==, 0);
+
+    data = inb(IDE_BASE + reg_status);
+    assert_bit_set(data, DRDY);
+    assert_bit_clear(data, BSY | DF | ERR | DRQ);
+
+    ide_test_quit();
+}
+
 int main(int argc, char **argv)
 {
     const char *arch = qtest_get_arch();
@@ -454,6 +492,8 @@ int main(int argc, char **argv)
     qtest_add_func("/ide/bmdma/long_prdt", test_bmdma_long_prdt);
     qtest_add_func("/ide/bmdma/teardown", test_bmdma_teardown);
 
+    qtest_add_func("/ide/flush", test_flush);
+
     ret = g_test_run();
 
     /* Cleanup */
commit f68ec8379e88502b4841a110c070e9b118d3151c
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Jun 5 15:17:57 2013 +0200

    ide: Set BSY bit during FLUSH
    
    The implementation of the ATA FLUSH command invokes a flush at the block
    layer, which may on raw files on POSIX entail a synchronous fdatasync().
    This may in some cases take so long that the SLES 11 SP1 guest driver
    reports I/O errors and filesystems get corrupted or remounted read-only.
    
    Avoid this by setting BUSY_STAT, so that the guest is made aware we are
    in the middle of an operation and no ATA commands are attempted to be
    processed concurrently.
    
    Addresses BNC#637297.
    
    Suggested-by: Gonglei (Arei) <arei.gonglei at huawei.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/ide/core.c b/hw/ide/core.c
index c7a8041..9926d92 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -814,6 +814,7 @@ void ide_flush_cache(IDEState *s)
         return;
     }
 
+    s->status |= BUSY_STAT;
     bdrv_acct_start(s->bs, &s->acct, 0, BDRV_ACCT_FLUSH);
     bdrv_aio_flush(s->bs, ide_flush_cb, s);
 }
commit c27d565604038c1572b16dd1cd06e277e6ef02e2
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 15:17:56 2013 +0200

    ide-test: Add enum value for DEV
    
    Get rid of the magic number.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/tests/ide-test.c b/tests/ide-test.c
index 365e995..1c31a2e 100644
--- a/tests/ide-test.c
+++ b/tests/ide-test.c
@@ -64,6 +64,7 @@ enum {
 };
 
 enum {
+    DEV     = 0x10,
     LBA     = 0x40,
 };
 
@@ -394,7 +395,7 @@ static void test_identify(void)
 
     /* Read in the IDENTIFY buffer and check registers */
     data = inb(IDE_BASE + reg_device);
-    g_assert_cmpint(data & 0x10, ==, 0);
+    g_assert_cmpint(data & DEV, ==, 0);
 
     for (i = 0; i < 256; i++) {
         data = inb(IDE_BASE + reg_status);
commit bf736fe34caba0688c9095c31b9d097ea15c1296
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 15:17:55 2013 +0200

    blkdebug: Add BLKDBG_FLUSH_TO_OS/DISK events
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block.c b/block.c
index 3f616de..79ad33d 100644
--- a/block.c
+++ b/block.c
@@ -3186,13 +3186,11 @@ int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
 
 void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event)
 {
-    BlockDriver *drv = bs->drv;
-
-    if (!drv || !drv->bdrv_debug_event) {
+    if (!bs || !bs->drv || !bs->drv->bdrv_debug_event) {
         return;
     }
 
-    drv->bdrv_debug_event(bs, event);
+    bs->drv->bdrv_debug_event(bs, event);
 }
 
 int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
@@ -4024,6 +4022,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
     }
 
     /* Write back cached data to the OS even with cache=unsafe */
+    BLKDBG_EVENT(bs->file, BLKDBG_FLUSH_TO_OS);
     if (bs->drv->bdrv_co_flush_to_os) {
         ret = bs->drv->bdrv_co_flush_to_os(bs);
         if (ret < 0) {
@@ -4036,6 +4035,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
         goto flush_parent;
     }
 
+    BLKDBG_EVENT(bs->file, BLKDBG_FLUSH_TO_DISK);
     if (bs->drv->bdrv_co_flush_to_disk) {
         ret = bs->drv->bdrv_co_flush_to_disk(bs);
     } else if (bs->drv->bdrv_aio_flush) {
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 71f99e4..ccb627a 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -182,6 +182,9 @@ static const char *event_names[BLKDBG_EVENT_MAX] = {
     [BLKDBG_CLUSTER_ALLOC]                  = "cluster_alloc",
     [BLKDBG_CLUSTER_ALLOC_BYTES]            = "cluster_alloc_bytes",
     [BLKDBG_CLUSTER_FREE]                   = "cluster_free",
+
+    [BLKDBG_FLUSH_TO_OS]                    = "flush_to_os",
+    [BLKDBG_FLUSH_TO_DISK]                  = "flush_to_disk",
 };
 
 static int get_event_by_name(const char *name, BlkDebugEvent *event)
diff --git a/include/block/block.h b/include/block/block.h
index dc5b388..2307f67 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -424,6 +424,9 @@ typedef enum {
     BLKDBG_CLUSTER_ALLOC_BYTES,
     BLKDBG_CLUSTER_FREE,
 
+    BLKDBG_FLUSH_TO_OS,
+    BLKDBG_FLUSH_TO_DISK,
+
     BLKDBG_EVENT_MAX,
 } BlkDebugEvent;
 
commit 587da2c39c9ace168f4d01fa446a54ae998a2553
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 14:19:41 2013 +0200

    Make qemu-io commands available in HMP
    
    It was decided to not make this command available in QMP in order to
    make clear that this is not supposed to be a stable API and should be
    used only for testing and debugging purposes.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/Makefile b/Makefile
index 87298e5..9a77ae0 100644
--- a/Makefile
+++ b/Makefile
@@ -186,7 +186,7 @@ qemu-img.o: qemu-img-cmds.h
 
 qemu-img$(EXESUF): qemu-img.o $(block-obj-y) libqemuutil.a libqemustub.a
 qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) libqemuutil.a libqemustub.a
-qemu-io$(EXESUF): qemu-io.o qemu-io-cmds.o $(block-obj-y) libqemuutil.a libqemustub.a
+qemu-io$(EXESUF): qemu-io.o $(block-obj-y) libqemuutil.a libqemustub.a
 
 qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
 
diff --git a/Makefile.objs b/Makefile.objs
index 286ce06..5b288ba 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -13,6 +13,7 @@ block-obj-$(CONFIG_POSIX) += aio-posix.o
 block-obj-$(CONFIG_WIN32) += aio-win32.o
 block-obj-y += block/
 block-obj-y += qapi-types.o qapi-visit.o
+block-obj-y += qemu-io-cmds.o
 
 block-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o
 block-obj-y += qemu-coroutine-sleep.o
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 4f5a3fd..396691a 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1553,6 +1553,22 @@ Removes the chardev @var{id}.
 ETEXI
 
     {
+        .name       = "qemu-io",
+        .args_type  = "device:B,command:s",
+        .params     = "[device] \"[command]\"",
+        .help       = "run a qemu-io command on a block device",
+        .mhandler.cmd = hmp_qemu_io,
+    },
+
+STEXI
+ at item qemu-io @var{device} @var{command}
+ at findex qemu-io
+
+Executes a qemu-io command on the given block device.
+
+ETEXI
+
+    {
         .name       = "info",
         .args_type  = "item:s?",
         .params     = "[subcommand]",
diff --git a/hmp.c b/hmp.c
index 4fb76ec..64e0baa 100644
--- a/hmp.c
+++ b/hmp.c
@@ -22,6 +22,7 @@
 #include "qemu/sockets.h"
 #include "monitor/monitor.h"
 #include "ui/console.h"
+#include "qemu-io.h"
 
 static void hmp_handle_error(Monitor *mon, Error **errp)
 {
@@ -1425,3 +1426,20 @@ void hmp_chardev_remove(Monitor *mon, const QDict *qdict)
     qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err);
     hmp_handle_error(mon, &local_err);
 }
+
+void hmp_qemu_io(Monitor *mon, const QDict *qdict)
+{
+    BlockDriverState *bs;
+    const char* device = qdict_get_str(qdict, "device");
+    const char* command = qdict_get_str(qdict, "command");
+    Error *err = NULL;
+
+    bs = bdrv_find(device);
+    if (bs) {
+        qemuio_command(bs, command);
+    } else {
+        error_set(&err, QERR_DEVICE_NOT_FOUND, device);
+    }
+
+    hmp_handle_error(mon, &err);
+}
diff --git a/hmp.h b/hmp.h
index 95fe76e..56d2e92 100644
--- a/hmp.h
+++ b/hmp.h
@@ -85,5 +85,6 @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict);
 void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict);
 void hmp_chardev_add(Monitor *mon, const QDict *qdict);
 void hmp_chardev_remove(Monitor *mon, const QDict *qdict);
+void hmp_qemu_io(Monitor *mon, const QDict *qdict);
 
 #endif
commit 02da386a2d7a020e80b0aed64769efa9dd42072a
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 14:19:40 2013 +0200

    qemu-io: Use the qemu version for -V
    
    Always printing 0.0.1 and never updating the version number wasn't very
    useful. qemu-io is released with qemu, so using the same version number
    makes most sense.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/qemu-io.c b/qemu-io.c
index 514edcb..cb9def5 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -19,8 +19,6 @@
 #include "block/block_int.h"
 #include "trace/control.h"
 
-#define VERSION	"0.0.1"
-
 #define CMD_NOFILE_OK   0x01
 
 char *progname;
@@ -380,7 +378,7 @@ int main(int argc, char **argv)
             }
             break;
         case 'V':
-            printf("%s version %s\n", progname, VERSION);
+            printf("%s version %s\n", progname, QEMU_VERSION);
             exit(0);
         case 'h':
             usage(progname);
commit 3d21994f9c511cb63220fef5abea164b83fbb997
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 14:19:39 2013 +0200

    qemu-io: Interface cleanup
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/cmd.h b/cmd.h
deleted file mode 100644
index 9907795..0000000
--- a/cmd.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef __COMMAND_H__
-#define __COMMAND_H__
-
-#include "qemu-common.h"
-
-#define CMD_FLAG_GLOBAL	((int)0x80000000)	/* don't iterate "args" */
-
-extern BlockDriverState *qemuio_bs;
-
-typedef int (*cfunc_t)(BlockDriverState *bs, int argc, char **argv);
-typedef void (*helpfunc_t)(void);
-
-typedef struct cmdinfo {
-	const char	*name;
-	const char	*altname;
-	cfunc_t		cfunc;
-	int		argmin;
-	int		argmax;
-	int		canpush;
-	int		flags;
-	const char	*args;
-	const char	*oneline;
-	helpfunc_t      help;
-} cmdinfo_t;
-
-void qemuio_add_command(const cmdinfo_t *ci);
-
-int qemuio_command_usage(const cmdinfo_t *ci);
-
-bool qemuio_command(const char *cmd);
-
-#endif	/* __COMMAND_H__ */
diff --git a/include/qemu-io.h b/include/qemu-io.h
new file mode 100644
index 0000000..a418b46
--- /dev/null
+++ b/include/qemu-io.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef QEMU_IO_H
+#define QEMU_IO_H
+
+#include "qemu-common.h"
+
+#define CMD_FLAG_GLOBAL ((int)0x80000000) /* don't iterate "args" */
+
+typedef int (*cfunc_t)(BlockDriverState *bs, int argc, char **argv);
+typedef void (*helpfunc_t)(void);
+
+typedef struct cmdinfo {
+    const char* name;
+    const char* altname;
+    cfunc_t     cfunc;
+    int         argmin;
+    int         argmax;
+    int         canpush;
+    int         flags;
+    const char  *args;
+    const char  *oneline;
+    helpfunc_t  help;
+} cmdinfo_t;
+
+bool qemuio_command(BlockDriverState *bs, const char *cmd);
+
+void qemuio_add_command(const cmdinfo_t *ci);
+int qemuio_command_usage(const cmdinfo_t *ci);
+
+#endif /* QEMU_IO_H */
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 05ce342..ffbcf31 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -8,9 +8,8 @@
  * See the COPYING file in the top-level directory.
  */
 
-#include "qemu-common.h"
+#include "qemu-io.h"
 #include "block/block_int.h"
-#include "cmd.h"
 
 #define CMD_NOFILE_OK   0x01
 
@@ -50,11 +49,12 @@ static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
     return 1;
 }
 
-static int command(const cmdinfo_t *ct, int argc, char **argv)
+static int command(BlockDriverState *bs, const cmdinfo_t *ct, int argc,
+                   char **argv)
 {
     char *cmd = argv[0];
 
-    if (!init_check_command(qemuio_bs, ct)) {
+    if (!init_check_command(bs, ct)) {
         return 0;
     }
 
@@ -75,7 +75,7 @@ static int command(const cmdinfo_t *ct, int argc, char **argv)
         return 0;
     }
     optind = 0;
-    return ct->cfunc(qemuio_bs, argc, argv);
+    return ct->cfunc(bs, argc, argv);
 }
 
 static const cmdinfo_t *find_command(const char *cmd)
@@ -2068,7 +2068,7 @@ static const cmdinfo_t help_cmd = {
     .oneline    = "help for one or all commands",
 };
 
-bool qemuio_command(const char *cmd)
+bool qemuio_command(BlockDriverState *bs, const char *cmd)
 {
     char *input;
     const cmdinfo_t *ct;
@@ -2081,7 +2081,7 @@ bool qemuio_command(const char *cmd)
     if (c) {
         ct = find_command(v[0]);
         if (ct) {
-            done = command(ct, c, v);
+            done = command(bs, ct, c, v);
         } else {
             fprintf(stderr, "command \"%s\" not found\n", v[0]);
         }
diff --git a/qemu-io.c b/qemu-io.c
index eec8cbc..514edcb 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -14,10 +14,9 @@
 #include <getopt.h>
 #include <libgen.h>
 
-#include "qemu-common.h"
+#include "qemu-io.h"
 #include "qemu/main-loop.h"
 #include "block/block_int.h"
-#include "cmd.h"
 #include "trace/control.h"
 
 #define VERSION	"0.0.1"
@@ -273,7 +272,7 @@ static void command_loop(void)
     char *input;
 
     for (i = 0; !done && i < ncmdline; i++) {
-        done = qemuio_command(cmdline[i]);
+        done = qemuio_command(qemuio_bs, cmdline[i]);
     }
     if (cmdline) {
         g_free(cmdline);
@@ -298,7 +297,7 @@ static void command_loop(void)
         if (input == NULL) {
             break;
         }
-        done = qemuio_command(input);
+        done = qemuio_command(qemuio_bs, input);
         g_free(input);
 
         prompted = 0;
commit 0b613881ae8fc59359b3d91e666fea6c9b1e731b
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 14:19:38 2013 +0200

    qemu-io: Move remaining helpers from cmd.c
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/Makefile b/Makefile
index cf932eb..87298e5 100644
--- a/Makefile
+++ b/Makefile
@@ -186,7 +186,7 @@ qemu-img.o: qemu-img-cmds.h
 
 qemu-img$(EXESUF): qemu-img.o $(block-obj-y) libqemuutil.a libqemustub.a
 qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) libqemuutil.a libqemustub.a
-qemu-io$(EXESUF): qemu-io.o qemu-io-cmds.o cmd.o $(block-obj-y) libqemuutil.a libqemustub.a
+qemu-io$(EXESUF): qemu-io.o qemu-io-cmds.o $(block-obj-y) libqemuutil.a libqemustub.a
 
 qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
 
diff --git a/cmd.c b/cmd.c
deleted file mode 100644
index 26d38a8..0000000
--- a/cmd.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2003-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <getopt.h>
-
-#include "cmd.h"
-#include "block/aio.h"
-#include "qemu/main-loop.h"
-
-#define _(x)	x	/* not gettext support yet */
-
-/* from libxcmd/command.c */
-
-#define EXABYTES(x)	((long long)(x) << 60)
-#define PETABYTES(x)	((long long)(x) << 50)
-#define TERABYTES(x)	((long long)(x) << 40)
-#define GIGABYTES(x)	((long long)(x) << 30)
-#define MEGABYTES(x)	((long long)(x) << 20)
-#define KILOBYTES(x)	((long long)(x) << 10)
-
-#define TO_EXABYTES(x)	((x) / EXABYTES(1))
-#define TO_PETABYTES(x)	((x) / PETABYTES(1))
-#define TO_TERABYTES(x)	((x) / TERABYTES(1))
-#define TO_GIGABYTES(x)	((x) / GIGABYTES(1))
-#define TO_MEGABYTES(x)	((x) / MEGABYTES(1))
-#define TO_KILOBYTES(x)	((x) / KILOBYTES(1))
-
-void
-cvtstr(
-	double		value,
-	char		*str,
-	size_t		size)
-{
-	char		*trim;
-	const char	*suffix;
-
-	if (value >= EXABYTES(1)) {
-		suffix = " EiB";
-		snprintf(str, size - 4, "%.3f", TO_EXABYTES(value));
-	} else if (value >= PETABYTES(1)) {
-		suffix = " PiB";
-		snprintf(str, size - 4, "%.3f", TO_PETABYTES(value));
-	} else if (value >= TERABYTES(1)) {
-		suffix = " TiB";
-		snprintf(str, size - 4, "%.3f", TO_TERABYTES(value));
-	} else if (value >= GIGABYTES(1)) {
-		suffix = " GiB";
-		snprintf(str, size - 4, "%.3f", TO_GIGABYTES(value));
-	} else if (value >= MEGABYTES(1)) {
-		suffix = " MiB";
-		snprintf(str, size - 4, "%.3f", TO_MEGABYTES(value));
-	} else if (value >= KILOBYTES(1)) {
-		suffix = " KiB";
-		snprintf(str, size - 4, "%.3f", TO_KILOBYTES(value));
-	} else {
-		suffix = " bytes";
-		snprintf(str, size - 6, "%f", value);
-	}
-
-	trim = strstr(str, ".000");
-	if (trim) {
-		strcpy(trim, suffix);
-	} else {
-		strcat(str, suffix);
-	}
-}
-
-struct timeval
-tsub(struct timeval t1, struct timeval t2)
-{
-	t1.tv_usec -= t2.tv_usec;
-	if (t1.tv_usec < 0) {
-		t1.tv_usec += 1000000;
-		t1.tv_sec--;
-	}
-	t1.tv_sec -= t2.tv_sec;
-	return t1;
-}
-
-double
-tdiv(double value, struct timeval tv)
-{
-	return value / ((double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0));
-}
-
-#define HOURS(sec)	((sec) / (60 * 60))
-#define MINUTES(sec)	(((sec) % (60 * 60)) / 60)
-#define SECONDS(sec)	((sec) % 60)
-
-void
-timestr(
-	struct timeval	*tv,
-	char		*ts,
-	size_t		size,
-	int		format)
-{
-	double		usec = (double)tv->tv_usec / 1000000.0;
-
-	if (format & TERSE_FIXED_TIME) {
-		if (!HOURS(tv->tv_sec)) {
-			snprintf(ts, size, "%u:%02u.%02u",
-				(unsigned int) MINUTES(tv->tv_sec),
-				(unsigned int) SECONDS(tv->tv_sec),
-				(unsigned int) (usec * 100));
-			return;
-		}
-		format |= VERBOSE_FIXED_TIME;	/* fallback if hours needed */
-	}
-
-	if ((format & VERBOSE_FIXED_TIME) || tv->tv_sec) {
-		snprintf(ts, size, "%u:%02u:%02u.%02u",
-			(unsigned int) HOURS(tv->tv_sec),
-			(unsigned int) MINUTES(tv->tv_sec),
-			(unsigned int) SECONDS(tv->tv_sec),
-			(unsigned int) (usec * 100));
-	} else {
-		snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000));
-	}
-}
diff --git a/cmd.h b/cmd.h
index da0c7cf..9907795 100644
--- a/cmd.h
+++ b/cmd.h
@@ -43,20 +43,6 @@ void qemuio_add_command(const cmdinfo_t *ci);
 
 int qemuio_command_usage(const cmdinfo_t *ci);
 
-/* from input.h */
-void cvtstr(double value, char *str, size_t sz);
-
-struct timeval tsub(struct timeval t1, struct timeval t2);
-double tdiv(double value, struct timeval tv);
-
-enum {
-	DEFAULT_TIME		= 0x0,
-	TERSE_FIXED_TIME	= 0x1,
-	VERBOSE_FIXED_TIME	= 0x2
-};
-
-void timestr(struct timeval *tv, char *str, size_t sz, int flags);
-
 bool qemuio_command(const char *cmd);
 
 #endif	/* __COMMAND_H__ */
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 8acc866..05ce342 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -126,6 +126,110 @@ static int64_t cvtnum(const char *s)
     return strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
 }
 
+#define EXABYTES(x)     ((long long)(x) << 60)
+#define PETABYTES(x)    ((long long)(x) << 50)
+#define TERABYTES(x)    ((long long)(x) << 40)
+#define GIGABYTES(x)    ((long long)(x) << 30)
+#define MEGABYTES(x)    ((long long)(x) << 20)
+#define KILOBYTES(x)    ((long long)(x) << 10)
+
+#define TO_EXABYTES(x)  ((x) / EXABYTES(1))
+#define TO_PETABYTES(x) ((x) / PETABYTES(1))
+#define TO_TERABYTES(x) ((x) / TERABYTES(1))
+#define TO_GIGABYTES(x) ((x) / GIGABYTES(1))
+#define TO_MEGABYTES(x) ((x) / MEGABYTES(1))
+#define TO_KILOBYTES(x) ((x) / KILOBYTES(1))
+
+static void cvtstr(double value, char *str, size_t size)
+{
+    char *trim;
+    const char *suffix;
+
+    if (value >= EXABYTES(1)) {
+        suffix = " EiB";
+        snprintf(str, size - 4, "%.3f", TO_EXABYTES(value));
+    } else if (value >= PETABYTES(1)) {
+        suffix = " PiB";
+        snprintf(str, size - 4, "%.3f", TO_PETABYTES(value));
+    } else if (value >= TERABYTES(1)) {
+        suffix = " TiB";
+        snprintf(str, size - 4, "%.3f", TO_TERABYTES(value));
+    } else if (value >= GIGABYTES(1)) {
+        suffix = " GiB";
+        snprintf(str, size - 4, "%.3f", TO_GIGABYTES(value));
+    } else if (value >= MEGABYTES(1)) {
+        suffix = " MiB";
+        snprintf(str, size - 4, "%.3f", TO_MEGABYTES(value));
+    } else if (value >= KILOBYTES(1)) {
+        suffix = " KiB";
+        snprintf(str, size - 4, "%.3f", TO_KILOBYTES(value));
+    } else {
+        suffix = " bytes";
+        snprintf(str, size - 6, "%f", value);
+    }
+
+    trim = strstr(str, ".000");
+    if (trim) {
+        strcpy(trim, suffix);
+    } else {
+        strcat(str, suffix);
+    }
+}
+
+
+
+static struct timeval tsub(struct timeval t1, struct timeval t2)
+{
+    t1.tv_usec -= t2.tv_usec;
+    if (t1.tv_usec < 0) {
+        t1.tv_usec += 1000000;
+        t1.tv_sec--;
+    }
+    t1.tv_sec -= t2.tv_sec;
+    return t1;
+}
+
+static double tdiv(double value, struct timeval tv)
+{
+    return value / ((double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0));
+}
+
+#define HOURS(sec)      ((sec) / (60 * 60))
+#define MINUTES(sec)    (((sec) % (60 * 60)) / 60)
+#define SECONDS(sec)    ((sec) % 60)
+
+enum {
+    DEFAULT_TIME        = 0x0,
+    TERSE_FIXED_TIME    = 0x1,
+    VERBOSE_FIXED_TIME  = 0x2,
+};
+
+static void timestr(struct timeval *tv, char *ts, size_t size, int format)
+{
+    double usec = (double)tv->tv_usec / 1000000.0;
+
+    if (format & TERSE_FIXED_TIME) {
+        if (!HOURS(tv->tv_sec)) {
+            snprintf(ts, size, "%u:%02u.%02u",
+                    (unsigned int) MINUTES(tv->tv_sec),
+                    (unsigned int) SECONDS(tv->tv_sec),
+                    (unsigned int) (usec * 100));
+            return;
+        }
+        format |= VERBOSE_FIXED_TIME; /* fallback if hours needed */
+    }
+
+    if ((format & VERBOSE_FIXED_TIME) || tv->tv_sec) {
+        snprintf(ts, size, "%u:%02u:%02u.%02u",
+                (unsigned int) HOURS(tv->tv_sec),
+                (unsigned int) MINUTES(tv->tv_sec),
+                (unsigned int) SECONDS(tv->tv_sec),
+                (unsigned int) (usec * 100));
+    } else {
+        snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000));
+    }
+}
+
 /*
  * Parse the pattern argument to various sub-commands.
  *
commit d1174f13e78e2f43f7ae33d59b62b0b94468c8db
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 14:19:37 2013 +0200

    qemu-io: Move command_loop() and friends
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/cmd.c b/cmd.c
index 6616d61..26d38a8 100644
--- a/cmd.c
+++ b/cmd.c
@@ -31,145 +31,6 @@
 
 /* from libxcmd/command.c */
 
-static int		ncmdline;
-static char		**cmdline;
-
-
-void add_user_command(char *optarg)
-{
-    cmdline = g_realloc(cmdline, ++ncmdline * sizeof(char *));
-    cmdline[ncmdline-1] = optarg;
-}
-
-static void prep_fetchline(void *opaque)
-{
-    int *fetchable = opaque;
-
-    qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
-    *fetchable= 1;
-}
-
-static char *get_prompt(void);
-
-void command_loop(void)
-{
-    int i, done = 0, fetchable = 0, prompted = 0;
-    char *input;
-
-    for (i = 0; !done && i < ncmdline; i++) {
-        done = qemuio_command(cmdline[i]);
-    }
-    if (cmdline) {
-        g_free(cmdline);
-        return;
-    }
-
-    while (!done) {
-        if (!prompted) {
-            printf("%s", get_prompt());
-            fflush(stdout);
-            qemu_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, &fetchable);
-            prompted = 1;
-        }
-
-        main_loop_wait(false);
-
-        if (!fetchable) {
-            continue;
-        }
-
-        input = fetchline();
-        if (input == NULL) {
-            break;
-        }
-        done = qemuio_command(input);
-        free(input);
-
-        prompted = 0;
-        fetchable = 0;
-    }
-    qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
-}
-
-/* from libxcmd/input.c */
-
-#if defined(ENABLE_READLINE)
-# include <readline/history.h>
-# include <readline/readline.h>
-#elif defined(ENABLE_EDITLINE)
-# include <histedit.h>
-#endif
-
-static char *
-get_prompt(void)
-{
-	static char	prompt[FILENAME_MAX + 2 /*"> "*/ + 1 /*"\0"*/ ];
-
-	if (!prompt[0])
-		snprintf(prompt, sizeof(prompt), "%s> ", progname);
-	return prompt;
-}
-
-#if defined(ENABLE_READLINE)
-char *
-fetchline(void)
-{
-	char	*line;
-
-	line = readline(get_prompt());
-	if (line && *line)
-		add_history(line);
-	return line;
-}
-#elif defined(ENABLE_EDITLINE)
-static char *el_get_prompt(EditLine *e) { return get_prompt(); }
-char *
-fetchline(void)
-{
-	static EditLine	*el;
-	static History	*hist;
-	HistEvent	hevent;
-	char		*line;
-	int		count;
-
-	if (!el) {
-		hist = history_init();
-		history(hist, &hevent, H_SETSIZE, 100);
-		el = el_init(progname, stdin, stdout, stderr);
-		el_source(el, NULL);
-		el_set(el, EL_SIGNAL, 1);
-		el_set(el, EL_PROMPT, el_get_prompt);
-		el_set(el, EL_HIST, history, (const char *)hist);
-	}
-	line = strdup(el_gets(el, &count));
-	if (line) {
-		if (count > 0)
-			line[count-1] = '\0';
-		if (*line)
-			history(hist, &hevent, H_ENTER, line);
-	}
-	return line;
-}
-#else
-# define MAXREADLINESZ	1024
-char *
-fetchline(void)
-{
-	char	*p, *line = malloc(MAXREADLINESZ);
-
-	if (!line)
-		return NULL;
-	if (!fgets(line, MAXREADLINESZ, stdin)) {
-		free(line);
-		return NULL;
-	}
-	p = line + strlen(line);
-	if (p != line && p[-1] == '\n')
-		p[-1] = '\0';
-	return line;
-}
-#endif
-
 #define EXABYTES(x)	((long long)(x) << 60)
 #define PETABYTES(x)	((long long)(x) << 50)
 #define TERABYTES(x)	((long long)(x) << 40)
diff --git a/cmd.h b/cmd.h
index 0d01a33..da0c7cf 100644
--- a/cmd.h
+++ b/cmd.h
@@ -39,18 +39,11 @@ typedef struct cmdinfo {
 	helpfunc_t      help;
 } cmdinfo_t;
 
-typedef int (*checkfunc_t)(BlockDriverState *bs, const cmdinfo_t *ci);
-
 void qemuio_add_command(const cmdinfo_t *ci);
-void add_user_command(char *optarg);
-void add_check_command(checkfunc_t cf);
 
-void command_loop(void);
 int qemuio_command_usage(const cmdinfo_t *ci);
 
 /* from input.h */
-char *fetchline(void);
-
 void cvtstr(double value, char *str, size_t sz);
 
 struct timeval tsub(struct timeval t1, struct timeval t2);
@@ -64,8 +57,6 @@ enum {
 
 void timestr(struct timeval *tv, char *str, size_t sz, int flags);
 
-extern char *progname;
-
 bool qemuio_command(const char *cmd);
 
 #endif	/* __COMMAND_H__ */
diff --git a/qemu-io.c b/qemu-io.c
index 3bf5aec..eec8cbc 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -29,6 +29,10 @@ char *progname;
 BlockDriverState *qemuio_bs;
 extern int qemuio_misalign;
 
+/* qemu-io commands passed using -c */
+static int ncmdline;
+static char **cmdline;
+
 static int close_f(BlockDriverState *bs, int argc, char **argv)
 {
     bdrv_delete(bs);
@@ -174,6 +178,141 @@ static void usage(const char *name)
 }
 
 
+#if defined(ENABLE_READLINE)
+# include <readline/history.h>
+# include <readline/readline.h>
+#elif defined(ENABLE_EDITLINE)
+# include <histedit.h>
+#endif
+
+static char *get_prompt(void)
+{
+    static char prompt[FILENAME_MAX + 2 /*"> "*/ + 1 /*"\0"*/ ];
+
+    if (!prompt[0]) {
+        snprintf(prompt, sizeof(prompt), "%s> ", progname);
+    }
+
+    return prompt;
+}
+
+#if defined(ENABLE_READLINE)
+static char *fetchline(void)
+{
+    char *line = readline(get_prompt());
+    if (line && *line) {
+        add_history(line);
+    }
+    return line;
+}
+#elif defined(ENABLE_EDITLINE)
+static char *el_get_prompt(EditLine *e)
+{
+    return get_prompt();
+}
+
+static char *fetchline(void)
+{
+    static EditLine *el;
+    static History *hist;
+    HistEvent hevent;
+    char *line;
+    int count;
+
+    if (!el) {
+        hist = history_init();
+        history(hist, &hevent, H_SETSIZE, 100);
+        el = el_init(progname, stdin, stdout, stderr);
+        el_source(el, NULL);
+        el_set(el, EL_SIGNAL, 1);
+        el_set(el, EL_PROMPT, el_get_prompt);
+        el_set(el, EL_HIST, history, (const char *)hist);
+    }
+    line = strdup(el_gets(el, &count));
+    if (line) {
+        if (count > 0) {
+            line[count-1] = '\0';
+        }
+        if (*line) {
+            history(hist, &hevent, H_ENTER, line);
+        }
+    }
+    return line;
+}
+#else
+# define MAXREADLINESZ 1024
+static char *fetchline(void)
+{
+    char *p, *line = g_malloc(MAXREADLINESZ);
+
+    if (!fgets(line, MAXREADLINESZ, stdin)) {
+        g_free(line);
+        return NULL;
+    }
+
+    p = line + strlen(line);
+    if (p != line && p[-1] == '\n') {
+        p[-1] = '\0';
+    }
+
+    return line;
+}
+#endif
+
+static void prep_fetchline(void *opaque)
+{
+    int *fetchable = opaque;
+
+    qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
+    *fetchable= 1;
+}
+
+static void command_loop(void)
+{
+    int i, done = 0, fetchable = 0, prompted = 0;
+    char *input;
+
+    for (i = 0; !done && i < ncmdline; i++) {
+        done = qemuio_command(cmdline[i]);
+    }
+    if (cmdline) {
+        g_free(cmdline);
+        return;
+    }
+
+    while (!done) {
+        if (!prompted) {
+            printf("%s", get_prompt());
+            fflush(stdout);
+            qemu_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, &fetchable);
+            prompted = 1;
+        }
+
+        main_loop_wait(false);
+
+        if (!fetchable) {
+            continue;
+        }
+
+        input = fetchline();
+        if (input == NULL) {
+            break;
+        }
+        done = qemuio_command(input);
+        g_free(input);
+
+        prompted = 0;
+        fetchable = 0;
+    }
+    qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
+}
+
+static void add_user_command(char *optarg)
+{
+    cmdline = g_realloc(cmdline, ++ncmdline * sizeof(char *));
+    cmdline[ncmdline-1] = optarg;
+}
+
 int main(int argc, char **argv)
 {
     int readonly = 0;
commit c2cdf5c5892165cbe7d3567bff5930521bc52669
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 14:19:36 2013 +0200

    qemu-io: Move functions for registering and running commands
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/cmd.c b/cmd.c
index f6bf2c5..6616d61 100644
--- a/cmd.c
+++ b/cmd.c
@@ -31,94 +31,9 @@
 
 /* from libxcmd/command.c */
 
-cmdinfo_t	*cmdtab;
-int		ncmds;
-
-static checkfunc_t	check_func;
 static int		ncmdline;
 static char		**cmdline;
 
-static int
-compare(const void *a, const void *b)
-{
-	return strcmp(((const cmdinfo_t *)a)->name,
-		      ((const cmdinfo_t *)b)->name);
-}
-
-void add_command(const cmdinfo_t *ci)
-{
-    cmdtab = g_realloc((void *)cmdtab, ++ncmds * sizeof(*cmdtab));
-    cmdtab[ncmds - 1] = *ci;
-    qsort(cmdtab, ncmds, sizeof(*cmdtab), compare);
-}
-
-static int
-check_command(
-	const cmdinfo_t	*ci)
-{
-	if (check_func)
-		return check_func(qemuio_bs, ci);
-	return 1;
-}
-
-void
-add_check_command(
-	checkfunc_t	cf)
-{
-	check_func = cf;
-}
-
-int
-command_usage(
-	const cmdinfo_t *ci)
-{
-	printf("%s %s -- %s\n", ci->name, ci->args, ci->oneline);
-	return 0;
-}
-
-int
-command(
-	const cmdinfo_t	*ct,
-	int		argc,
-	char		**argv)
-{
-	char		*cmd = argv[0];
-
-	if (!check_command(ct))
-		return 0;
-
-	if (argc-1 < ct->argmin || (ct->argmax != -1 && argc-1 > ct->argmax)) {
-		if (ct->argmax == -1)
-			fprintf(stderr,
-	_("bad argument count %d to %s, expected at least %d arguments\n"),
-				argc-1, cmd, ct->argmin);
-		else if (ct->argmin == ct->argmax)
-			fprintf(stderr,
-	_("bad argument count %d to %s, expected %d arguments\n"),
-				argc-1, cmd, ct->argmin);
-		else
-			fprintf(stderr,
-	_("bad argument count %d to %s, expected between %d and %d arguments\n"),
-			argc-1, cmd, ct->argmin, ct->argmax);
-		return 0;
-	}
-	optind = 0;
-	return ct->cfunc(qemuio_bs, argc, argv);
-}
-
-const cmdinfo_t *
-find_command(
-	const char	*cmd)
-{
-	cmdinfo_t	*ct;
-
-	for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
-		if (strcmp(ct->name, cmd) == 0 ||
-		    (ct->altname && strcmp(ct->altname, cmd) == 0))
-			return (const cmdinfo_t *)ct;
-	}
-	return NULL;
-}
 
 void add_user_command(char *optarg)
 {
@@ -255,34 +170,6 @@ fetchline(void)
 }
 #endif
 
-char **breakline(char *input, int *count)
-{
-    int c = 0;
-    char *p;
-    char **rval = calloc(sizeof(char *), 1);
-    char **tmp;
-
-    while (rval && (p = qemu_strsep(&input, " ")) != NULL) {
-        if (!*p) {
-            continue;
-        }
-        c++;
-        tmp = realloc(rval, sizeof(*rval) * (c + 1));
-        if (!tmp) {
-            free(rval);
-            rval = NULL;
-            c = 0;
-            break;
-        } else {
-            rval = tmp;
-        }
-        rval[c - 1] = p;
-        rval[c] = NULL;
-    }
-    *count = c;
-    return rval;
-}
-
 #define EXABYTES(x)	((long long)(x) << 60)
 #define PETABYTES(x)	((long long)(x) << 50)
 #define TERABYTES(x)	((long long)(x) << 40)
diff --git a/cmd.h b/cmd.h
index 5b6f61b..0d01a33 100644
--- a/cmd.h
+++ b/cmd.h
@@ -39,23 +39,16 @@ typedef struct cmdinfo {
 	helpfunc_t      help;
 } cmdinfo_t;
 
-extern cmdinfo_t	*cmdtab;
-extern int		ncmds;
-
 typedef int (*checkfunc_t)(BlockDriverState *bs, const cmdinfo_t *ci);
 
-void add_command(const cmdinfo_t *ci);
+void qemuio_add_command(const cmdinfo_t *ci);
 void add_user_command(char *optarg);
 void add_check_command(checkfunc_t cf);
 
-const cmdinfo_t *find_command(const char *cmd);
-
 void command_loop(void);
-int command_usage(const cmdinfo_t *ci);
-int command(const cmdinfo_t *ci, int argc, char **argv);
+int qemuio_command_usage(const cmdinfo_t *ci);
 
 /* from input.h */
-char **breakline(char *input, int *count);
 char *fetchline(void);
 
 void cvtstr(double value, char *str, size_t sz);
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index fa8d9a0..8acc866 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -16,6 +16,110 @@
 
 int qemuio_misalign;
 
+static cmdinfo_t *cmdtab;
+static int ncmds;
+
+static int compare_cmdname(const void *a, const void *b)
+{
+    return strcmp(((const cmdinfo_t *)a)->name,
+                  ((const cmdinfo_t *)b)->name);
+}
+
+void qemuio_add_command(const cmdinfo_t *ci)
+{
+    cmdtab = g_realloc(cmdtab, ++ncmds * sizeof(*cmdtab));
+    cmdtab[ncmds - 1] = *ci;
+    qsort(cmdtab, ncmds, sizeof(*cmdtab), compare_cmdname);
+}
+
+int qemuio_command_usage(const cmdinfo_t *ci)
+{
+    printf("%s %s -- %s\n", ci->name, ci->args, ci->oneline);
+    return 0;
+}
+
+static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
+{
+    if (ct->flags & CMD_FLAG_GLOBAL) {
+        return 1;
+    }
+    if (!(ct->flags & CMD_NOFILE_OK) && !bs) {
+        fprintf(stderr, "no file open, try 'help open'\n");
+        return 0;
+    }
+    return 1;
+}
+
+static int command(const cmdinfo_t *ct, int argc, char **argv)
+{
+    char *cmd = argv[0];
+
+    if (!init_check_command(qemuio_bs, ct)) {
+        return 0;
+    }
+
+    if (argc - 1 < ct->argmin || (ct->argmax != -1 && argc - 1 > ct->argmax)) {
+        if (ct->argmax == -1) {
+            fprintf(stderr,
+                    "bad argument count %d to %s, expected at least %d arguments\n",
+                    argc-1, cmd, ct->argmin);
+        } else if (ct->argmin == ct->argmax) {
+            fprintf(stderr,
+                    "bad argument count %d to %s, expected %d arguments\n",
+                    argc-1, cmd, ct->argmin);
+        } else {
+            fprintf(stderr,
+                    "bad argument count %d to %s, expected between %d and %d arguments\n",
+                    argc-1, cmd, ct->argmin, ct->argmax);
+        }
+        return 0;
+    }
+    optind = 0;
+    return ct->cfunc(qemuio_bs, argc, argv);
+}
+
+static const cmdinfo_t *find_command(const char *cmd)
+{
+    cmdinfo_t *ct;
+
+    for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
+        if (strcmp(ct->name, cmd) == 0 ||
+            (ct->altname && strcmp(ct->altname, cmd) == 0))
+        {
+            return (const cmdinfo_t *)ct;
+        }
+    }
+    return NULL;
+}
+
+static char **breakline(char *input, int *count)
+{
+    int c = 0;
+    char *p;
+    char **rval = g_malloc0(sizeof(char *));
+    char **tmp;
+
+    while (rval && (p = qemu_strsep(&input, " ")) != NULL) {
+        if (!*p) {
+            continue;
+        }
+        c++;
+        tmp = g_realloc(rval, sizeof(*rval) * (c + 1));
+        if (!tmp) {
+            g_free(rval);
+            rval = NULL;
+            c = 0;
+            break;
+        } else {
+            rval = tmp;
+        }
+        rval[c - 1] = p;
+        rval[c] = NULL;
+    }
+    *count = c;
+    return rval;
+}
+
 static int64_t cvtnum(const char *s)
 {
     char *end;
@@ -467,12 +571,12 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
             vflag = 1;
             break;
         default:
-            return command_usage(&read_cmd);
+            return qemuio_command_usage(&read_cmd);
         }
     }
 
     if (optind != argc - 2) {
-        return command_usage(&read_cmd);
+        return qemuio_command_usage(&read_cmd);
     }
 
     if (bflag && pflag) {
@@ -494,7 +598,7 @@ static int read_f(BlockDriverState *bs, int argc, char **argv)
     }
 
     if (!Pflag && (lflag || sflag)) {
-        return command_usage(&read_cmd);
+        return qemuio_command_usage(&read_cmd);
     }
 
     if (!lflag) {
@@ -629,12 +733,12 @@ static int readv_f(BlockDriverState *bs, int argc, char **argv)
             vflag = 1;
             break;
         default:
-            return command_usage(&readv_cmd);
+            return qemuio_command_usage(&readv_cmd);
         }
     }
 
     if (optind > argc - 2) {
-        return command_usage(&readv_cmd);
+        return qemuio_command_usage(&readv_cmd);
     }
 
 
@@ -769,12 +873,12 @@ static int write_f(BlockDriverState *bs, int argc, char **argv)
             zflag = 1;
             break;
         default:
-            return command_usage(&write_cmd);
+            return qemuio_command_usage(&write_cmd);
         }
     }
 
     if (optind != argc - 2) {
-        return command_usage(&write_cmd);
+        return qemuio_command_usage(&write_cmd);
     }
 
     if (bflag + pflag + zflag > 1) {
@@ -911,12 +1015,12 @@ static int writev_f(BlockDriverState *bs, int argc, char **argv)
             }
             break;
         default:
-            return command_usage(&writev_cmd);
+            return qemuio_command_usage(&writev_cmd);
         }
     }
 
     if (optind > argc - 2) {
-        return command_usage(&writev_cmd);
+        return qemuio_command_usage(&writev_cmd);
     }
 
     offset = cvtnum(argv[optind]);
@@ -1023,12 +1127,12 @@ static int multiwrite_f(BlockDriverState *bs, int argc, char **argv)
             }
             break;
         default:
-            return command_usage(&writev_cmd);
+            return qemuio_command_usage(&writev_cmd);
         }
     }
 
     if (optind > argc - 2) {
-        return command_usage(&writev_cmd);
+        return qemuio_command_usage(&writev_cmd);
     }
 
     nr_reqs = 1;
@@ -1257,13 +1361,13 @@ static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
             break;
         default:
             g_free(ctx);
-            return command_usage(&aio_read_cmd);
+            return qemuio_command_usage(&aio_read_cmd);
         }
     }
 
     if (optind > argc - 2) {
         g_free(ctx);
-        return command_usage(&aio_read_cmd);
+        return qemuio_command_usage(&aio_read_cmd);
     }
 
     ctx->offset = cvtnum(argv[optind]);
@@ -1349,13 +1453,13 @@ static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
             break;
         default:
             g_free(ctx);
-            return command_usage(&aio_write_cmd);
+            return qemuio_command_usage(&aio_write_cmd);
         }
     }
 
     if (optind > argc - 2) {
         g_free(ctx);
-        return command_usage(&aio_write_cmd);
+        return qemuio_command_usage(&aio_write_cmd);
     }
 
     ctx->offset = cvtnum(argv[optind]);
@@ -1547,12 +1651,12 @@ static int discard_f(BlockDriverState *bs, int argc, char **argv)
             qflag = 1;
             break;
         default:
-            return command_usage(&discard_cmd);
+            return qemuio_command_usage(&discard_cmd);
         }
     }
 
     if (optind != argc - 2) {
-        return command_usage(&discard_cmd);
+        return qemuio_command_usage(&discard_cmd);
     }
 
     offset = cvtnum(argv[optind]);
@@ -1860,18 +1964,6 @@ static const cmdinfo_t help_cmd = {
     .oneline    = "help for one or all commands",
 };
 
-static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
-{
-    if (ct->flags & CMD_FLAG_GLOBAL) {
-        return 1;
-    }
-    if (!(ct->flags & CMD_NOFILE_OK) && !bs) {
-        fprintf(stderr, "no file open, try 'help open'\n");
-        return 0;
-    }
-    return 1;
-}
-
 bool qemuio_command(const char *cmd)
 {
     char *input;
@@ -1899,26 +1991,24 @@ bool qemuio_command(const char *cmd)
 static void __attribute((constructor)) init_qemuio_commands(void)
 {
     /* initialize commands */
-    add_command(&help_cmd);
-    add_command(&read_cmd);
-    add_command(&readv_cmd);
-    add_command(&write_cmd);
-    add_command(&writev_cmd);
-    add_command(&multiwrite_cmd);
-    add_command(&aio_read_cmd);
-    add_command(&aio_write_cmd);
-    add_command(&aio_flush_cmd);
-    add_command(&flush_cmd);
-    add_command(&truncate_cmd);
-    add_command(&length_cmd);
-    add_command(&info_cmd);
-    add_command(&discard_cmd);
-    add_command(&alloc_cmd);
-    add_command(&map_cmd);
-    add_command(&break_cmd);
-    add_command(&resume_cmd);
-    add_command(&wait_break_cmd);
-    add_command(&abort_cmd);
-
-    add_check_command(init_check_command);
+    qemuio_add_command(&help_cmd);
+    qemuio_add_command(&read_cmd);
+    qemuio_add_command(&readv_cmd);
+    qemuio_add_command(&write_cmd);
+    qemuio_add_command(&writev_cmd);
+    qemuio_add_command(&multiwrite_cmd);
+    qemuio_add_command(&aio_read_cmd);
+    qemuio_add_command(&aio_write_cmd);
+    qemuio_add_command(&aio_flush_cmd);
+    qemuio_add_command(&flush_cmd);
+    qemuio_add_command(&truncate_cmd);
+    qemuio_add_command(&length_cmd);
+    qemuio_add_command(&info_cmd);
+    qemuio_add_command(&discard_cmd);
+    qemuio_add_command(&alloc_cmd);
+    qemuio_add_command(&map_cmd);
+    qemuio_add_command(&break_cmd);
+    qemuio_add_command(&resume_cmd);
+    qemuio_add_command(&wait_break_cmd);
+    qemuio_add_command(&abort_cmd);
 }
diff --git a/qemu-io.c b/qemu-io.c
index 8f6c57e..3bf5aec 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -122,7 +122,7 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
             growable = 1;
             break;
         default:
-            return command_usage(&open_cmd);
+            return qemuio_command_usage(&open_cmd);
         }
     }
 
@@ -131,7 +131,7 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
     }
 
     if (optind != argc - 1) {
-        return command_usage(&open_cmd);
+        return qemuio_command_usage(&open_cmd);
     }
 
     return openfile(argv[optind], flags, growable);
@@ -262,9 +262,9 @@ int main(int argc, char **argv)
     bdrv_init();
 
     /* initialize commands */
-    add_command(&quit_cmd);
-    add_command(&open_cmd);
-    add_command(&close_cmd);
+    qemuio_add_command(&quit_cmd);
+    qemuio_add_command(&open_cmd);
+    qemuio_add_command(&close_cmd);
 
     /* open the device */
     if (!readonly) {
commit a38ed811474e953371f848233208c2026c2d1195
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 14:19:35 2013 +0200

    qemu-io: Move qemu_strsep() to cutils.c
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/cmd.c b/cmd.c
index 8496e74..f6bf2c5 100644
--- a/cmd.c
+++ b/cmd.c
@@ -255,27 +255,6 @@ fetchline(void)
 }
 #endif
 
-static char *qemu_strsep(char **input, const char *delim)
-{
-    char *result = *input;
-    if (result != NULL) {
-        char *p;
-
-        for (p = result; *p != '\0'; p++) {
-            if (strchr(delim, *p)) {
-                break;
-            }
-        }
-        if (*p == '\0') {
-            *input = NULL;
-        } else {
-            *p = '\0';
-            *input = p + 1;
-        }
-    }
-    return result;
-}
-
 char **breakline(char *input, int *count)
 {
     int c = 0;
diff --git a/include/qemu-common.h b/include/qemu-common.h
index d95ea1e..ed8b6e2 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -174,6 +174,7 @@ char *pstrcat(char *buf, int buf_size, const char *s);
 int strstart(const char *str, const char *val, const char **ptr);
 int stristart(const char *str, const char *val, const char **ptr);
 int qemu_strnlen(const char *s, int max_len);
+char *qemu_strsep(char **input, const char *delim);
 time_t mktimegm(struct tm *tm);
 int qemu_fls(int i);
 int qemu_fdatasync(int fd);
diff --git a/util/cutils.c b/util/cutils.c
index 8f28896..0116fcd 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -107,6 +107,27 @@ int qemu_strnlen(const char *s, int max_len)
     return i;
 }
 
+char *qemu_strsep(char **input, const char *delim)
+{
+    char *result = *input;
+    if (result != NULL) {
+        char *p;
+
+        for (p = result; *p != '\0'; p++) {
+            if (strchr(delim, *p)) {
+                break;
+            }
+        }
+        if (*p == '\0') {
+            *input = NULL;
+        } else {
+            *p = '\0';
+            *input = p + 1;
+        }
+    }
+    return result;
+}
+
 time_t mktimegm(struct tm *tm)
 {
     time_t t;
commit e681be7eca0143fe7259ce8233fe5dd8898d072f
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 14:19:34 2013 +0200

    qemu-io: Move 'quit' function
    
    This one only makes sense in the context of the qemu-io tool, so move it
    to qemu-io.c. Adapt coding style and register it like other commands.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/cmd.c b/cmd.c
index 2941ad3..8496e74 100644
--- a/cmd.c
+++ b/cmd.c
@@ -410,32 +410,3 @@ timestr(
 		snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000));
 	}
 }
-
-
-/* from libxcmd/quit.c */
-
-static cmdinfo_t quit_cmd;
-
-/* ARGSUSED */
-static int
-quit_f(
-    BlockDriverState *bs,
-	int	argc,
-	char	**argv)
-{
-	return 1;
-}
-
-void
-quit_init(void)
-{
-	quit_cmd.name = _("quit");
-	quit_cmd.altname = _("q");
-	quit_cmd.cfunc = quit_f;
-	quit_cmd.argmin = -1;
-	quit_cmd.argmax = -1;
-	quit_cmd.flags = CMD_FLAG_GLOBAL;
-	quit_cmd.oneline = _("exit the program");
-
-	add_command(&quit_cmd);
-}
diff --git a/cmd.h b/cmd.h
index 89e7c6e..5b6f61b 100644
--- a/cmd.h
+++ b/cmd.h
@@ -42,8 +42,6 @@ typedef struct cmdinfo {
 extern cmdinfo_t	*cmdtab;
 extern int		ncmds;
 
-void quit_init(void);
-
 typedef int (*checkfunc_t)(BlockDriverState *bs, const cmdinfo_t *ci);
 
 void add_command(const cmdinfo_t *ci);
diff --git a/qemu-io.c b/qemu-io.c
index 14eef2c..8f6c57e 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -137,6 +137,21 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
     return openfile(argv[optind], flags, growable);
 }
 
+static int quit_f(BlockDriverState *bs, int argc, char **argv)
+{
+    return 1;
+}
+
+static const cmdinfo_t quit_cmd = {
+    .name       = "quit",
+    .altname    = "q",
+    .cfunc      = quit_f,
+    .argmin     = -1,
+    .argmax     = -1,
+    .flags      = CMD_FLAG_GLOBAL,
+    .oneline    = "exit the program",
+};
+
 static void usage(const char *name)
 {
     printf(
@@ -247,7 +262,7 @@ int main(int argc, char **argv)
     bdrv_init();
 
     /* initialize commands */
-    quit_init();
+    add_command(&quit_cmd);
     add_command(&open_cmd);
     add_command(&close_cmd);
 
commit f18a834a92f0b490cefeb71410f3f25b969d336f
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 14:19:33 2013 +0200

    qemu-io: Move 'help' function
    
    No reason to treat it different from other commands. Move it to
    qemu-io-cmds.c, adapt the coding style and register it like any other
    command.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/cmd.c b/cmd.c
index 7ae978f..2941ad3 100644
--- a/cmd.c
+++ b/cmd.c
@@ -439,82 +439,3 @@ quit_init(void)
 
 	add_command(&quit_cmd);
 }
-
-/* from libxcmd/help.c */
-
-static cmdinfo_t help_cmd;
-static void help_onecmd(const char *cmd, const cmdinfo_t *ct);
-static void help_oneline(const char *cmd, const cmdinfo_t *ct);
-
-static void
-help_all(void)
-{
-	const cmdinfo_t	*ct;
-
-	for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++)
-		help_oneline(ct->name, ct);
-	printf(_("\nUse 'help commandname' for extended help.\n"));
-}
-
-static int
-help_f(
-    BlockDriverState *bs,
-	int		argc,
-	char		**argv)
-{
-	const cmdinfo_t	*ct;
-
-	if (argc == 1) {
-		help_all();
-		return 0;
-	}
-	ct = find_command(argv[1]);
-	if (ct == NULL) {
-		printf(_("command %s not found\n"), argv[1]);
-		return 0;
-	}
-	help_onecmd(argv[1], ct);
-	return 0;
-}
-
-static void
-help_onecmd(
-	const char	*cmd,
-	const cmdinfo_t	*ct)
-{
-	help_oneline(cmd, ct);
-	if (ct->help)
-		ct->help();
-}
-
-static void
-help_oneline(
-	const char	*cmd,
-	const cmdinfo_t	*ct)
-{
-	if (cmd)
-		printf("%s ", cmd);
-	else {
-		printf("%s ", ct->name);
-		if (ct->altname)
-			printf("(or %s) ", ct->altname);
-	}
-	if (ct->args)
-		printf("%s ", ct->args);
-	printf("-- %s\n", ct->oneline);
-}
-
-void
-help_init(void)
-{
-	help_cmd.name = _("help");
-	help_cmd.altname = _("?");
-	help_cmd.cfunc = help_f;
-	help_cmd.argmin = 0;
-	help_cmd.argmax = 1;
-	help_cmd.flags = CMD_FLAG_GLOBAL;
-	help_cmd.args = _("[command]");
-	help_cmd.oneline = _("help for one or all commands");
-
-	add_command(&help_cmd);
-}
diff --git a/cmd.h b/cmd.h
index d676408..89e7c6e 100644
--- a/cmd.h
+++ b/cmd.h
@@ -42,7 +42,6 @@ typedef struct cmdinfo {
 extern cmdinfo_t	*cmdtab;
 extern int		ncmds;
 
-void help_init(void);
 void quit_init(void);
 
 typedef int (*checkfunc_t)(BlockDriverState *bs, const cmdinfo_t *ci);
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 8b12446..fa8d9a0 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -1795,6 +1795,71 @@ static const cmdinfo_t abort_cmd = {
        .oneline        = "simulate a program crash using abort(3)",
 };
 
+static void help_oneline(const char *cmd, const cmdinfo_t *ct)
+{
+    if (cmd) {
+        printf("%s ", cmd);
+    } else {
+        printf("%s ", ct->name);
+        if (ct->altname) {
+            printf("(or %s) ", ct->altname);
+        }
+    }
+
+    if (ct->args) {
+        printf("%s ", ct->args);
+    }
+    printf("-- %s\n", ct->oneline);
+}
+
+static void help_onecmd(const char *cmd, const cmdinfo_t *ct)
+{
+    help_oneline(cmd, ct);
+    if (ct->help) {
+        ct->help();
+    }
+}
+
+static void help_all(void)
+{
+    const cmdinfo_t *ct;
+
+    for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
+        help_oneline(ct->name, ct);
+    }
+    printf("\nUse 'help commandname' for extended help.\n");
+}
+
+static int help_f(BlockDriverState *bs, int argc, char **argv)
+{
+    const cmdinfo_t *ct;
+
+    if (argc == 1) {
+        help_all();
+        return 0;
+    }
+
+    ct = find_command(argv[1]);
+    if (ct == NULL) {
+        printf("command %s not found\n", argv[1]);
+        return 0;
+    }
+
+    help_onecmd(argv[1], ct);
+    return 0;
+}
+
+static const cmdinfo_t help_cmd = {
+    .name       = "help",
+    .altname    = "?",
+    .cfunc      = help_f,
+    .argmin     = 0,
+    .argmax     = 1,
+    .flags      = CMD_FLAG_GLOBAL,
+    .args       = "[command]",
+    .oneline    = "help for one or all commands",
+};
+
 static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
 {
     if (ct->flags & CMD_FLAG_GLOBAL) {
@@ -1834,7 +1899,7 @@ bool qemuio_command(const char *cmd)
 static void __attribute((constructor)) init_qemuio_commands(void)
 {
     /* initialize commands */
-    help_init();
+    add_command(&help_cmd);
     add_command(&read_cmd);
     add_command(&readv_cmd);
     add_command(&write_cmd);
commit dd5832967ac3fe96bd5bf9f199639176998ead69
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 14:19:32 2013 +0200

    qemu-io: Factor out qemuio_command
    
    It's duplicated code. Move it to qemu-io-cmds.c because it's not
    dependent on any static data of the qemu-io tool.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/cmd.c b/cmd.c
index d501aab..7ae978f 100644
--- a/cmd.c
+++ b/cmd.c
@@ -138,28 +138,11 @@ static char *get_prompt(void);
 
 void command_loop(void)
 {
-    int c, i, done = 0, fetchable = 0, prompted = 0;
+    int i, done = 0, fetchable = 0, prompted = 0;
     char *input;
-    char **v;
-    const cmdinfo_t *ct;
 
     for (i = 0; !done && i < ncmdline; i++) {
-        input = strdup(cmdline[i]);
-        if (!input) {
-            fprintf(stderr, _("cannot strdup command '%s': %s\n"),
-                    cmdline[i], strerror(errno));
-            exit(1);
-        }
-        v = breakline(input, &c);
-        if (c) {
-            ct = find_command(v[0]);
-            if (ct) {
-                done = command(ct, c, v);
-            } else {
-                fprintf(stderr, _("command \"%s\" not found\n"), v[0]);
-            }
-	}
-        doneline(input, v);
+        done = qemuio_command(cmdline[i]);
     }
     if (cmdline) {
         g_free(cmdline);
@@ -179,20 +162,13 @@ void command_loop(void)
         if (!fetchable) {
             continue;
         }
+
         input = fetchline();
         if (input == NULL) {
             break;
         }
-        v = breakline(input, &c);
-        if (c) {
-            ct = find_command(v[0]);
-            if (ct) {
-                done = command(ct, c, v);
-            } else {
-                fprintf(stderr, _("command \"%s\" not found\n"), v[0]);
-            }
-        }
-        doneline(input, v);
+        done = qemuio_command(input);
+        free(input);
 
         prompted = 0;
         fetchable = 0;
@@ -328,15 +304,6 @@ char **breakline(char *input, int *count)
     return rval;
 }
 
-void
-doneline(
-	char	*input,
-	char	**vec)
-{
-	free(input);
-	free(vec);
-}
-
 #define EXABYTES(x)	((long long)(x) << 60)
 #define PETABYTES(x)	((long long)(x) << 50)
 #define TERABYTES(x)	((long long)(x) << 40)
diff --git a/cmd.h b/cmd.h
index ccf6336..d676408 100644
--- a/cmd.h
+++ b/cmd.h
@@ -59,7 +59,6 @@ int command(const cmdinfo_t *ci, int argc, char **argv);
 
 /* from input.h */
 char **breakline(char *input, int *count);
-void doneline(char *input, char **vec);
 char *fetchline(void);
 
 void cvtstr(double value, char *str, size_t sz);
@@ -77,4 +76,6 @@ void timestr(struct timeval *tv, char *str, size_t sz, int flags);
 
 extern char *progname;
 
+bool qemuio_command(const char *cmd);
+
 #endif	/* __COMMAND_H__ */
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 0a3817a..8b12446 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -1807,6 +1807,30 @@ static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
     return 1;
 }
 
+bool qemuio_command(const char *cmd)
+{
+    char *input;
+    const cmdinfo_t *ct;
+    char **v;
+    int c;
+    bool done = false;
+
+    input = g_strdup(cmd);
+    v = breakline(input, &c);
+    if (c) {
+        ct = find_command(v[0]);
+        if (ct) {
+            done = command(ct, c, v);
+        } else {
+            fprintf(stderr, "command \"%s\" not found\n", v[0]);
+        }
+    }
+    g_free(input);
+    g_free(v);
+
+    return done;
+}
+
 static void __attribute((constructor)) init_qemuio_commands(void)
 {
     /* initialize commands */
commit 797ac58cb2093ab9192d8998a1fef85d87cc8661
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 14:19:31 2013 +0200

    qemu-io: Split off commands to qemu-io-cmds.c
    
    This is the implementation of all qemu-io commands that make sense to be
    called from the qemu monitor, i.e. everything except open, close and
    quit.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/Makefile b/Makefile
index a96736b..cf932eb 100644
--- a/Makefile
+++ b/Makefile
@@ -186,7 +186,7 @@ qemu-img.o: qemu-img-cmds.h
 
 qemu-img$(EXESUF): qemu-img.o $(block-obj-y) libqemuutil.a libqemustub.a
 qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) libqemuutil.a libqemustub.a
-qemu-io$(EXESUF): qemu-io.o cmd.o $(block-obj-y) libqemuutil.a libqemustub.a
+qemu-io$(EXESUF): qemu-io.o qemu-io-cmds.o cmd.o $(block-obj-y) libqemuutil.a libqemustub.a
 
 qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
 
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
new file mode 100644
index 0000000..0a3817a
--- /dev/null
+++ b/qemu-io-cmds.c
@@ -0,0 +1,1835 @@
+/*
+ * Command line utility to exercise the QEMU I/O path.
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (c) 2003-2005 Silicon Graphics, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu-common.h"
+#include "block/block_int.h"
+#include "cmd.h"
+
+#define CMD_NOFILE_OK   0x01
+
+int qemuio_misalign;
+
+static int64_t cvtnum(const char *s)
+{
+    char *end;
+    return strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
+}
+
+/*
+ * Parse the pattern argument to various sub-commands.
+ *
+ * Because the pattern is used as an argument to memset it must evaluate
+ * to an unsigned integer that fits into a single byte.
+ */
+static int parse_pattern(const char *arg)
+{
+    char *endptr = NULL;
+    long pattern;
+
+    pattern = strtol(arg, &endptr, 0);
+    if (pattern < 0 || pattern > UCHAR_MAX || *endptr != '\0') {
+        printf("%s is not a valid pattern byte\n", arg);
+        return -1;
+    }
+
+    return pattern;
+}
+
+/*
+ * Memory allocation helpers.
+ *
+ * Make sure memory is aligned by default, or purposefully misaligned if
+ * that is specified on the command line.
+ */
+
+#define MISALIGN_OFFSET     16
+static void *qemu_io_alloc(BlockDriverState *bs, size_t len, int pattern)
+{
+    void *buf;
+
+    if (qemuio_misalign) {
+        len += MISALIGN_OFFSET;
+    }
+    buf = qemu_blockalign(bs, len);
+    memset(buf, pattern, len);
+    if (qemuio_misalign) {
+        buf += MISALIGN_OFFSET;
+    }
+    return buf;
+}
+
+static void qemu_io_free(void *p)
+{
+    if (qemuio_misalign) {
+        p -= MISALIGN_OFFSET;
+    }
+    qemu_vfree(p);
+}
+
+static void dump_buffer(const void *buffer, int64_t offset, int len)
+{
+    int i, j;
+    const uint8_t *p;
+
+    for (i = 0, p = buffer; i < len; i += 16) {
+        const uint8_t *s = p;
+
+        printf("%08" PRIx64 ":  ", offset + i);
+        for (j = 0; j < 16 && i + j < len; j++, p++) {
+            printf("%02x ", *p);
+        }
+        printf(" ");
+        for (j = 0; j < 16 && i + j < len; j++, s++) {
+            if (isalnum(*s)) {
+                printf("%c", *s);
+            } else {
+                printf(".");
+            }
+        }
+        printf("\n");
+    }
+}
+
+static void print_report(const char *op, struct timeval *t, int64_t offset,
+                         int count, int total, int cnt, int Cflag)
+{
+    char s1[64], s2[64], ts[64];
+
+    timestr(t, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0);
+    if (!Cflag) {
+        cvtstr((double)total, s1, sizeof(s1));
+        cvtstr(tdiv((double)total, *t), s2, sizeof(s2));
+        printf("%s %d/%d bytes at offset %" PRId64 "\n",
+               op, total, count, offset);
+        printf("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n",
+               s1, cnt, ts, s2, tdiv((double)cnt, *t));
+    } else {/* bytes,ops,time,bytes/sec,ops/sec */
+        printf("%d,%d,%s,%.3f,%.3f\n",
+            total, cnt, ts,
+            tdiv((double)total, *t),
+            tdiv((double)cnt, *t));
+    }
+}
+
+/*
+ * Parse multiple length statements for vectored I/O, and construct an I/O
+ * vector matching it.
+ */
+static void *
+create_iovec(BlockDriverState *bs, QEMUIOVector *qiov, char **argv, int nr_iov,
+             int pattern)
+{
+    size_t *sizes = g_new0(size_t, nr_iov);
+    size_t count = 0;
+    void *buf = NULL;
+    void *p;
+    int i;
+
+    for (i = 0; i < nr_iov; i++) {
+        char *arg = argv[i];
+        int64_t len;
+
+        len = cvtnum(arg);
+        if (len < 0) {
+            printf("non-numeric length argument -- %s\n", arg);
+            goto fail;
+        }
+
+        /* should be SIZE_T_MAX, but that doesn't exist */
+        if (len > INT_MAX) {
+            printf("too large length argument -- %s\n", arg);
+            goto fail;
+        }
+
+        if (len & 0x1ff) {
+            printf("length argument %" PRId64
+                   " is not sector aligned\n", len);
+            goto fail;
+        }
+
+        sizes[i] = len;
+        count += len;
+    }
+
+    qemu_iovec_init(qiov, nr_iov);
+
+    buf = p = qemu_io_alloc(bs, count, pattern);
+
+    for (i = 0; i < nr_iov; i++) {
+        qemu_iovec_add(qiov, p, sizes[i]);
+        p += sizes[i];
+    }
+
+fail:
+    g_free(sizes);
+    return buf;
+}
+
+static int do_read(BlockDriverState *bs, char *buf, int64_t offset, int count,
+                   int *total)
+{
+    int ret;
+
+    ret = bdrv_read(bs, offset >> 9, (uint8_t *)buf, count >> 9);
+    if (ret < 0) {
+        return ret;
+    }
+    *total = count;
+    return 1;
+}
+
+static int do_write(BlockDriverState *bs, char *buf, int64_t offset, int count,
+                    int *total)
+{
+    int ret;
+
+    ret = bdrv_write(bs, offset >> 9, (uint8_t *)buf, count >> 9);
+    if (ret < 0) {
+        return ret;
+    }
+    *total = count;
+    return 1;
+}
+
+static int do_pread(BlockDriverState *bs, char *buf, int64_t offset, int count,
+                    int *total)
+{
+    *total = bdrv_pread(bs, offset, (uint8_t *)buf, count);
+    if (*total < 0) {
+        return *total;
+    }
+    return 1;
+}
+
+static int do_pwrite(BlockDriverState *bs, char *buf, int64_t offset, int count,
+                     int *total)
+{
+    *total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count);
+    if (*total < 0) {
+        return *total;
+    }
+    return 1;
+}
+
+typedef struct {
+    BlockDriverState *bs;
+    int64_t offset;
+    int count;
+    int *total;
+    int ret;
+    bool done;
+} CoWriteZeroes;
+
+static void coroutine_fn co_write_zeroes_entry(void *opaque)
+{
+    CoWriteZeroes *data = opaque;
+
+    data->ret = bdrv_co_write_zeroes(data->bs, data->offset / BDRV_SECTOR_SIZE,
+                                     data->count / BDRV_SECTOR_SIZE);
+    data->done = true;
+    if (data->ret < 0) {
+        *data->total = data->ret;
+        return;
+    }
+
+    *data->total = data->count;
+}
+
+static int do_co_write_zeroes(BlockDriverState *bs, int64_t offset, int count,
+                              int *total)
+{
+    Coroutine *co;
+    CoWriteZeroes data = {
+        .bs     = bs,
+        .offset = offset,
+        .count  = count,
+        .total  = total,
+        .done   = false,
+    };
+
+    co = qemu_coroutine_create(co_write_zeroes_entry);
+    qemu_coroutine_enter(co, &data);
+    while (!data.done) {
+        qemu_aio_wait();
+    }
+    if (data.ret < 0) {
+        return data.ret;
+    } else {
+        return 1;
+    }
+}
+
+static int do_write_compressed(BlockDriverState *bs, char *buf, int64_t offset,
+                               int count, int *total)
+{
+    int ret;
+
+    ret = bdrv_write_compressed(bs, offset >> 9, (uint8_t *)buf, count >> 9);
+    if (ret < 0) {
+        return ret;
+    }
+    *total = count;
+    return 1;
+}
+
+static int do_load_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
+                           int count, int *total)
+{
+    *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);
+    if (*total < 0) {
+        return *total;
+    }
+    return 1;
+}
+
+static int do_save_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
+                           int count, int *total)
+{
+    *total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count);
+    if (*total < 0) {
+        return *total;
+    }
+    return 1;
+}
+
+#define NOT_DONE 0x7fffffff
+static void aio_rw_done(void *opaque, int ret)
+{
+    *(int *)opaque = ret;
+}
+
+static int do_aio_readv(BlockDriverState *bs, QEMUIOVector *qiov,
+                        int64_t offset, int *total)
+{
+    int async_ret = NOT_DONE;
+
+    bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9,
+                   aio_rw_done, &async_ret);
+    while (async_ret == NOT_DONE) {
+        main_loop_wait(false);
+    }
+
+    *total = qiov->size;
+    return async_ret < 0 ? async_ret : 1;
+}
+
+static int do_aio_writev(BlockDriverState *bs, QEMUIOVector *qiov,
+                         int64_t offset, int *total)
+{
+    int async_ret = NOT_DONE;
+
+    bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9,
+                    aio_rw_done, &async_ret);
+    while (async_ret == NOT_DONE) {
+        main_loop_wait(false);
+    }
+
+    *total = qiov->size;
+    return async_ret < 0 ? async_ret : 1;
+}
+
+struct multiwrite_async_ret {
+    int num_done;
+    int error;
+};
+
+static void multiwrite_cb(void *opaque, int ret)
+{
+    struct multiwrite_async_ret *async_ret = opaque;
+
+    async_ret->num_done++;
+    if (ret < 0) {
+        async_ret->error = ret;
+    }
+}
+
+static int do_aio_multiwrite(BlockDriverState *bs, BlockRequest* reqs,
+                             int num_reqs, int *total)
+{
+    int i, ret;
+    struct multiwrite_async_ret async_ret = {
+        .num_done = 0,
+        .error = 0,
+    };
+
+    *total = 0;
+    for (i = 0; i < num_reqs; i++) {
+        reqs[i].cb = multiwrite_cb;
+        reqs[i].opaque = &async_ret;
+        *total += reqs[i].qiov->size;
+    }
+
+    ret = bdrv_aio_multiwrite(bs, reqs, num_reqs);
+    if (ret < 0) {
+        return ret;
+    }
+
+    while (async_ret.num_done < num_reqs) {
+        main_loop_wait(false);
+    }
+
+    return async_ret.error < 0 ? async_ret.error : 1;
+}
+
+static void read_help(void)
+{
+    printf(
+"\n"
+" reads a range of bytes from the given offset\n"
+"\n"
+" Example:\n"
+" 'read -v 512 1k' - dumps 1 kilobyte read from 512 bytes into the file\n"
+"\n"
+" Reads a segment of the currently open file, optionally dumping it to the\n"
+" standard output stream (with -v option) for subsequent inspection.\n"
+" -b, -- read from the VM state rather than the virtual disk\n"
+" -C, -- report statistics in a machine parsable format\n"
+" -l, -- length for pattern verification (only with -P)\n"
+" -p, -- use bdrv_pread to read the file\n"
+" -P, -- use a pattern to verify read data\n"
+" -q, -- quiet mode, do not show I/O statistics\n"
+" -s, -- start offset for pattern verification (only with -P)\n"
+" -v, -- dump buffer to standard output\n"
+"\n");
+}
+
+static int read_f(BlockDriverState *bs, int argc, char **argv);
+
+static const cmdinfo_t read_cmd = {
+    .name       = "read",
+    .altname    = "r",
+    .cfunc      = read_f,
+    .argmin     = 2,
+    .argmax     = -1,
+    .args       = "[-abCpqv] [-P pattern [-s off] [-l len]] off len",
+    .oneline    = "reads a number of bytes at a specified offset",
+    .help       = read_help,
+};
+
+static int read_f(BlockDriverState *bs, int argc, char **argv)
+{
+    struct timeval t1, t2;
+    int Cflag = 0, pflag = 0, qflag = 0, vflag = 0;
+    int Pflag = 0, sflag = 0, lflag = 0, bflag = 0;
+    int c, cnt;
+    char *buf;
+    int64_t offset;
+    int count;
+    /* Some compilers get confused and warn if this is not initialized.  */
+    int total = 0;
+    int pattern = 0, pattern_offset = 0, pattern_count = 0;
+
+    while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != EOF) {
+        switch (c) {
+        case 'b':
+            bflag = 1;
+            break;
+        case 'C':
+            Cflag = 1;
+            break;
+        case 'l':
+            lflag = 1;
+            pattern_count = cvtnum(optarg);
+            if (pattern_count < 0) {
+                printf("non-numeric length argument -- %s\n", optarg);
+                return 0;
+            }
+            break;
+        case 'p':
+            pflag = 1;
+            break;
+        case 'P':
+            Pflag = 1;
+            pattern = parse_pattern(optarg);
+            if (pattern < 0) {
+                return 0;
+            }
+            break;
+        case 'q':
+            qflag = 1;
+            break;
+        case 's':
+            sflag = 1;
+            pattern_offset = cvtnum(optarg);
+            if (pattern_offset < 0) {
+                printf("non-numeric length argument -- %s\n", optarg);
+                return 0;
+            }
+            break;
+        case 'v':
+            vflag = 1;
+            break;
+        default:
+            return command_usage(&read_cmd);
+        }
+    }
+
+    if (optind != argc - 2) {
+        return command_usage(&read_cmd);
+    }
+
+    if (bflag && pflag) {
+        printf("-b and -p cannot be specified at the same time\n");
+        return 0;
+    }
+
+    offset = cvtnum(argv[optind]);
+    if (offset < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        return 0;
+    }
+
+    optind++;
+    count = cvtnum(argv[optind]);
+    if (count < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        return 0;
+    }
+
+    if (!Pflag && (lflag || sflag)) {
+        return command_usage(&read_cmd);
+    }
+
+    if (!lflag) {
+        pattern_count = count - pattern_offset;
+    }
+
+    if ((pattern_count < 0) || (pattern_count + pattern_offset > count))  {
+        printf("pattern verification range exceeds end of read data\n");
+        return 0;
+    }
+
+    if (!pflag) {
+        if (offset & 0x1ff) {
+            printf("offset %" PRId64 " is not sector aligned\n",
+                   offset);
+            return 0;
+        }
+        if (count & 0x1ff) {
+            printf("count %d is not sector aligned\n",
+                   count);
+            return 0;
+        }
+    }
+
+    buf = qemu_io_alloc(bs, count, 0xab);
+
+    gettimeofday(&t1, NULL);
+    if (pflag) {
+        cnt = do_pread(bs, buf, offset, count, &total);
+    } else if (bflag) {
+        cnt = do_load_vmstate(bs, buf, offset, count, &total);
+    } else {
+        cnt = do_read(bs, buf, offset, count, &total);
+    }
+    gettimeofday(&t2, NULL);
+
+    if (cnt < 0) {
+        printf("read failed: %s\n", strerror(-cnt));
+        goto out;
+    }
+
+    if (Pflag) {
+        void *cmp_buf = g_malloc(pattern_count);
+        memset(cmp_buf, pattern, pattern_count);
+        if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
+            printf("Pattern verification failed at offset %"
+                   PRId64 ", %d bytes\n",
+                   offset + pattern_offset, pattern_count);
+        }
+        g_free(cmp_buf);
+    }
+
+    if (qflag) {
+        goto out;
+    }
+
+    if (vflag) {
+        dump_buffer(buf, offset, count);
+    }
+
+    /* Finally, report back -- -C gives a parsable format */
+    t2 = tsub(t2, t1);
+    print_report("read", &t2, offset, count, total, cnt, Cflag);
+
+out:
+    qemu_io_free(buf);
+
+    return 0;
+}
+
+static void readv_help(void)
+{
+    printf(
+"\n"
+" reads a range of bytes from the given offset into multiple buffers\n"
+"\n"
+" Example:\n"
+" 'readv -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
+"\n"
+" Reads a segment of the currently open file, optionally dumping it to the\n"
+" standard output stream (with -v option) for subsequent inspection.\n"
+" Uses multiple iovec buffers if more than one byte range is specified.\n"
+" -C, -- report statistics in a machine parsable format\n"
+" -P, -- use a pattern to verify read data\n"
+" -v, -- dump buffer to standard output\n"
+" -q, -- quiet mode, do not show I/O statistics\n"
+"\n");
+}
+
+static int readv_f(BlockDriverState *bs, int argc, char **argv);
+
+static const cmdinfo_t readv_cmd = {
+    .name       = "readv",
+    .cfunc      = readv_f,
+    .argmin     = 2,
+    .argmax     = -1,
+    .args       = "[-Cqv] [-P pattern ] off len [len..]",
+    .oneline    = "reads a number of bytes at a specified offset",
+    .help       = readv_help,
+};
+
+static int readv_f(BlockDriverState *bs, int argc, char **argv)
+{
+    struct timeval t1, t2;
+    int Cflag = 0, qflag = 0, vflag = 0;
+    int c, cnt;
+    char *buf;
+    int64_t offset;
+    /* Some compilers get confused and warn if this is not initialized.  */
+    int total = 0;
+    int nr_iov;
+    QEMUIOVector qiov;
+    int pattern = 0;
+    int Pflag = 0;
+
+    while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
+        switch (c) {
+        case 'C':
+            Cflag = 1;
+            break;
+        case 'P':
+            Pflag = 1;
+            pattern = parse_pattern(optarg);
+            if (pattern < 0) {
+                return 0;
+            }
+            break;
+        case 'q':
+            qflag = 1;
+            break;
+        case 'v':
+            vflag = 1;
+            break;
+        default:
+            return command_usage(&readv_cmd);
+        }
+    }
+
+    if (optind > argc - 2) {
+        return command_usage(&readv_cmd);
+    }
+
+
+    offset = cvtnum(argv[optind]);
+    if (offset < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        return 0;
+    }
+    optind++;
+
+    if (offset & 0x1ff) {
+        printf("offset %" PRId64 " is not sector aligned\n",
+               offset);
+        return 0;
+    }
+
+    nr_iov = argc - optind;
+    buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, 0xab);
+    if (buf == NULL) {
+        return 0;
+    }
+
+    gettimeofday(&t1, NULL);
+    cnt = do_aio_readv(bs, &qiov, offset, &total);
+    gettimeofday(&t2, NULL);
+
+    if (cnt < 0) {
+        printf("readv failed: %s\n", strerror(-cnt));
+        goto out;
+    }
+
+    if (Pflag) {
+        void *cmp_buf = g_malloc(qiov.size);
+        memset(cmp_buf, pattern, qiov.size);
+        if (memcmp(buf, cmp_buf, qiov.size)) {
+            printf("Pattern verification failed at offset %"
+                   PRId64 ", %zd bytes\n", offset, qiov.size);
+        }
+        g_free(cmp_buf);
+    }
+
+    if (qflag) {
+        goto out;
+    }
+
+    if (vflag) {
+        dump_buffer(buf, offset, qiov.size);
+    }
+
+    /* Finally, report back -- -C gives a parsable format */
+    t2 = tsub(t2, t1);
+    print_report("read", &t2, offset, qiov.size, total, cnt, Cflag);
+
+out:
+    qemu_iovec_destroy(&qiov);
+    qemu_io_free(buf);
+    return 0;
+}
+
+static void write_help(void)
+{
+    printf(
+"\n"
+" writes a range of bytes from the given offset\n"
+"\n"
+" Example:\n"
+" 'write 512 1k' - writes 1 kilobyte at 512 bytes into the open file\n"
+"\n"
+" Writes into a segment of the currently open file, using a buffer\n"
+" filled with a set pattern (0xcdcdcdcd).\n"
+" -b, -- write to the VM state rather than the virtual disk\n"
+" -c, -- write compressed data with bdrv_write_compressed\n"
+" -p, -- use bdrv_pwrite to write the file\n"
+" -P, -- use different pattern to fill file\n"
+" -C, -- report statistics in a machine parsable format\n"
+" -q, -- quiet mode, do not show I/O statistics\n"
+" -z, -- write zeroes using bdrv_co_write_zeroes\n"
+"\n");
+}
+
+static int write_f(BlockDriverState *bs, int argc, char **argv);
+
+static const cmdinfo_t write_cmd = {
+    .name       = "write",
+    .altname    = "w",
+    .cfunc      = write_f,
+    .argmin     = 2,
+    .argmax     = -1,
+    .args       = "[-bcCpqz] [-P pattern ] off len",
+    .oneline    = "writes a number of bytes at a specified offset",
+    .help       = write_help,
+};
+
+static int write_f(BlockDriverState *bs, int argc, char **argv)
+{
+    struct timeval t1, t2;
+    int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0;
+    int cflag = 0;
+    int c, cnt;
+    char *buf = NULL;
+    int64_t offset;
+    int count;
+    /* Some compilers get confused and warn if this is not initialized.  */
+    int total = 0;
+    int pattern = 0xcd;
+
+    while ((c = getopt(argc, argv, "bcCpP:qz")) != EOF) {
+        switch (c) {
+        case 'b':
+            bflag = 1;
+            break;
+        case 'c':
+            cflag = 1;
+            break;
+        case 'C':
+            Cflag = 1;
+            break;
+        case 'p':
+            pflag = 1;
+            break;
+        case 'P':
+            Pflag = 1;
+            pattern = parse_pattern(optarg);
+            if (pattern < 0) {
+                return 0;
+            }
+            break;
+        case 'q':
+            qflag = 1;
+            break;
+        case 'z':
+            zflag = 1;
+            break;
+        default:
+            return command_usage(&write_cmd);
+        }
+    }
+
+    if (optind != argc - 2) {
+        return command_usage(&write_cmd);
+    }
+
+    if (bflag + pflag + zflag > 1) {
+        printf("-b, -p, or -z cannot be specified at the same time\n");
+        return 0;
+    }
+
+    if (zflag && Pflag) {
+        printf("-z and -P cannot be specified at the same time\n");
+        return 0;
+    }
+
+    offset = cvtnum(argv[optind]);
+    if (offset < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        return 0;
+    }
+
+    optind++;
+    count = cvtnum(argv[optind]);
+    if (count < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        return 0;
+    }
+
+    if (!pflag) {
+        if (offset & 0x1ff) {
+            printf("offset %" PRId64 " is not sector aligned\n",
+                   offset);
+            return 0;
+        }
+
+        if (count & 0x1ff) {
+            printf("count %d is not sector aligned\n",
+                   count);
+            return 0;
+        }
+    }
+
+    if (!zflag) {
+        buf = qemu_io_alloc(bs, count, pattern);
+    }
+
+    gettimeofday(&t1, NULL);
+    if (pflag) {
+        cnt = do_pwrite(bs, buf, offset, count, &total);
+    } else if (bflag) {
+        cnt = do_save_vmstate(bs, buf, offset, count, &total);
+    } else if (zflag) {
+        cnt = do_co_write_zeroes(bs, offset, count, &total);
+    } else if (cflag) {
+        cnt = do_write_compressed(bs, buf, offset, count, &total);
+    } else {
+        cnt = do_write(bs, buf, offset, count, &total);
+    }
+    gettimeofday(&t2, NULL);
+
+    if (cnt < 0) {
+        printf("write failed: %s\n", strerror(-cnt));
+        goto out;
+    }
+
+    if (qflag) {
+        goto out;
+    }
+
+    /* Finally, report back -- -C gives a parsable format */
+    t2 = tsub(t2, t1);
+    print_report("wrote", &t2, offset, count, total, cnt, Cflag);
+
+out:
+    if (!zflag) {
+        qemu_io_free(buf);
+    }
+
+    return 0;
+}
+
+static void
+writev_help(void)
+{
+    printf(
+"\n"
+" writes a range of bytes from the given offset source from multiple buffers\n"
+"\n"
+" Example:\n"
+" 'write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
+"\n"
+" Writes into a segment of the currently open file, using a buffer\n"
+" filled with a set pattern (0xcdcdcdcd).\n"
+" -P, -- use different pattern to fill file\n"
+" -C, -- report statistics in a machine parsable format\n"
+" -q, -- quiet mode, do not show I/O statistics\n"
+"\n");
+}
+
+static int writev_f(BlockDriverState *bs, int argc, char **argv);
+
+static const cmdinfo_t writev_cmd = {
+    .name       = "writev",
+    .cfunc      = writev_f,
+    .argmin     = 2,
+    .argmax     = -1,
+    .args       = "[-Cq] [-P pattern ] off len [len..]",
+    .oneline    = "writes a number of bytes at a specified offset",
+    .help       = writev_help,
+};
+
+static int writev_f(BlockDriverState *bs, int argc, char **argv)
+{
+    struct timeval t1, t2;
+    int Cflag = 0, qflag = 0;
+    int c, cnt;
+    char *buf;
+    int64_t offset;
+    /* Some compilers get confused and warn if this is not initialized.  */
+    int total = 0;
+    int nr_iov;
+    int pattern = 0xcd;
+    QEMUIOVector qiov;
+
+    while ((c = getopt(argc, argv, "CqP:")) != EOF) {
+        switch (c) {
+        case 'C':
+            Cflag = 1;
+            break;
+        case 'q':
+            qflag = 1;
+            break;
+        case 'P':
+            pattern = parse_pattern(optarg);
+            if (pattern < 0) {
+                return 0;
+            }
+            break;
+        default:
+            return command_usage(&writev_cmd);
+        }
+    }
+
+    if (optind > argc - 2) {
+        return command_usage(&writev_cmd);
+    }
+
+    offset = cvtnum(argv[optind]);
+    if (offset < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        return 0;
+    }
+    optind++;
+
+    if (offset & 0x1ff) {
+        printf("offset %" PRId64 " is not sector aligned\n",
+               offset);
+        return 0;
+    }
+
+    nr_iov = argc - optind;
+    buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, pattern);
+    if (buf == NULL) {
+        return 0;
+    }
+
+    gettimeofday(&t1, NULL);
+    cnt = do_aio_writev(bs, &qiov, offset, &total);
+    gettimeofday(&t2, NULL);
+
+    if (cnt < 0) {
+        printf("writev failed: %s\n", strerror(-cnt));
+        goto out;
+    }
+
+    if (qflag) {
+        goto out;
+    }
+
+    /* Finally, report back -- -C gives a parsable format */
+    t2 = tsub(t2, t1);
+    print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag);
+out:
+    qemu_iovec_destroy(&qiov);
+    qemu_io_free(buf);
+    return 0;
+}
+
+static void multiwrite_help(void)
+{
+    printf(
+"\n"
+" writes a range of bytes from the given offset source from multiple buffers,\n"
+" in a batch of requests that may be merged by qemu\n"
+"\n"
+" Example:\n"
+" 'multiwrite 512 1k 1k ; 4k 1k'\n"
+"  writes 2 kB at 512 bytes and 1 kB at 4 kB into the open file\n"
+"\n"
+" Writes into a segment of the currently open file, using a buffer\n"
+" filled with a set pattern (0xcdcdcdcd). The pattern byte is increased\n"
+" by one for each request contained in the multiwrite command.\n"
+" -P, -- use different pattern to fill file\n"
+" -C, -- report statistics in a machine parsable format\n"
+" -q, -- quiet mode, do not show I/O statistics\n"
+"\n");
+}
+
+static int multiwrite_f(BlockDriverState *bs, int argc, char **argv);
+
+static const cmdinfo_t multiwrite_cmd = {
+    .name       = "multiwrite",
+    .cfunc      = multiwrite_f,
+    .argmin     = 2,
+    .argmax     = -1,
+    .args       = "[-Cq] [-P pattern ] off len [len..] [; off len [len..]..]",
+    .oneline    = "issues multiple write requests at once",
+    .help       = multiwrite_help,
+};
+
+static int multiwrite_f(BlockDriverState *bs, int argc, char **argv)
+{
+    struct timeval t1, t2;
+    int Cflag = 0, qflag = 0;
+    int c, cnt;
+    char **buf;
+    int64_t offset, first_offset = 0;
+    /* Some compilers get confused and warn if this is not initialized.  */
+    int total = 0;
+    int nr_iov;
+    int nr_reqs;
+    int pattern = 0xcd;
+    QEMUIOVector *qiovs;
+    int i;
+    BlockRequest *reqs;
+
+    while ((c = getopt(argc, argv, "CqP:")) != EOF) {
+        switch (c) {
+        case 'C':
+            Cflag = 1;
+            break;
+        case 'q':
+            qflag = 1;
+            break;
+        case 'P':
+            pattern = parse_pattern(optarg);
+            if (pattern < 0) {
+                return 0;
+            }
+            break;
+        default:
+            return command_usage(&writev_cmd);
+        }
+    }
+
+    if (optind > argc - 2) {
+        return command_usage(&writev_cmd);
+    }
+
+    nr_reqs = 1;
+    for (i = optind; i < argc; i++) {
+        if (!strcmp(argv[i], ";")) {
+            nr_reqs++;
+        }
+    }
+
+    reqs = g_malloc0(nr_reqs * sizeof(*reqs));
+    buf = g_malloc0(nr_reqs * sizeof(*buf));
+    qiovs = g_malloc(nr_reqs * sizeof(*qiovs));
+
+    for (i = 0; i < nr_reqs && optind < argc; i++) {
+        int j;
+
+        /* Read the offset of the request */
+        offset = cvtnum(argv[optind]);
+        if (offset < 0) {
+            printf("non-numeric offset argument -- %s\n", argv[optind]);
+            goto out;
+        }
+        optind++;
+
+        if (offset & 0x1ff) {
+            printf("offset %lld is not sector aligned\n",
+                   (long long)offset);
+            goto out;
+        }
+
+        if (i == 0) {
+            first_offset = offset;
+        }
+
+        /* Read lengths for qiov entries */
+        for (j = optind; j < argc; j++) {
+            if (!strcmp(argv[j], ";")) {
+                break;
+            }
+        }
+
+        nr_iov = j - optind;
+
+        /* Build request */
+        buf[i] = create_iovec(bs, &qiovs[i], &argv[optind], nr_iov, pattern);
+        if (buf[i] == NULL) {
+            goto out;
+        }
+
+        reqs[i].qiov = &qiovs[i];
+        reqs[i].sector = offset >> 9;
+        reqs[i].nb_sectors = reqs[i].qiov->size >> 9;
+
+        optind = j + 1;
+
+        pattern++;
+    }
+
+    /* If there were empty requests at the end, ignore them */
+    nr_reqs = i;
+
+    gettimeofday(&t1, NULL);
+    cnt = do_aio_multiwrite(bs, reqs, nr_reqs, &total);
+    gettimeofday(&t2, NULL);
+
+    if (cnt < 0) {
+        printf("aio_multiwrite failed: %s\n", strerror(-cnt));
+        goto out;
+    }
+
+    if (qflag) {
+        goto out;
+    }
+
+    /* Finally, report back -- -C gives a parsable format */
+    t2 = tsub(t2, t1);
+    print_report("wrote", &t2, first_offset, total, total, cnt, Cflag);
+out:
+    for (i = 0; i < nr_reqs; i++) {
+        qemu_io_free(buf[i]);
+        if (reqs[i].qiov != NULL) {
+            qemu_iovec_destroy(&qiovs[i]);
+        }
+    }
+    g_free(buf);
+    g_free(reqs);
+    g_free(qiovs);
+    return 0;
+}
+
+struct aio_ctx {
+    QEMUIOVector qiov;
+    int64_t offset;
+    char *buf;
+    int qflag;
+    int vflag;
+    int Cflag;
+    int Pflag;
+    int pattern;
+    struct timeval t1;
+};
+
+static void aio_write_done(void *opaque, int ret)
+{
+    struct aio_ctx *ctx = opaque;
+    struct timeval t2;
+
+    gettimeofday(&t2, NULL);
+
+
+    if (ret < 0) {
+        printf("aio_write failed: %s\n", strerror(-ret));
+        goto out;
+    }
+
+    if (ctx->qflag) {
+        goto out;
+    }
+
+    /* Finally, report back -- -C gives a parsable format */
+    t2 = tsub(t2, ctx->t1);
+    print_report("wrote", &t2, ctx->offset, ctx->qiov.size,
+                 ctx->qiov.size, 1, ctx->Cflag);
+out:
+    qemu_io_free(ctx->buf);
+    qemu_iovec_destroy(&ctx->qiov);
+    g_free(ctx);
+}
+
+static void aio_read_done(void *opaque, int ret)
+{
+    struct aio_ctx *ctx = opaque;
+    struct timeval t2;
+
+    gettimeofday(&t2, NULL);
+
+    if (ret < 0) {
+        printf("readv failed: %s\n", strerror(-ret));
+        goto out;
+    }
+
+    if (ctx->Pflag) {
+        void *cmp_buf = g_malloc(ctx->qiov.size);
+
+        memset(cmp_buf, ctx->pattern, ctx->qiov.size);
+        if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
+            printf("Pattern verification failed at offset %"
+                   PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
+        }
+        g_free(cmp_buf);
+    }
+
+    if (ctx->qflag) {
+        goto out;
+    }
+
+    if (ctx->vflag) {
+        dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size);
+    }
+
+    /* Finally, report back -- -C gives a parsable format */
+    t2 = tsub(t2, ctx->t1);
+    print_report("read", &t2, ctx->offset, ctx->qiov.size,
+                 ctx->qiov.size, 1, ctx->Cflag);
+out:
+    qemu_io_free(ctx->buf);
+    qemu_iovec_destroy(&ctx->qiov);
+    g_free(ctx);
+}
+
+static void aio_read_help(void)
+{
+    printf(
+"\n"
+" asynchronously reads a range of bytes from the given offset\n"
+"\n"
+" Example:\n"
+" 'aio_read -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
+"\n"
+" Reads a segment of the currently open file, optionally dumping it to the\n"
+" standard output stream (with -v option) for subsequent inspection.\n"
+" The read is performed asynchronously and the aio_flush command must be\n"
+" used to ensure all outstanding aio requests have been completed.\n"
+" -C, -- report statistics in a machine parsable format\n"
+" -P, -- use a pattern to verify read data\n"
+" -v, -- dump buffer to standard output\n"
+" -q, -- quiet mode, do not show I/O statistics\n"
+"\n");
+}
+
+static int aio_read_f(BlockDriverState *bs, int argc, char **argv);
+
+static const cmdinfo_t aio_read_cmd = {
+    .name       = "aio_read",
+    .cfunc      = aio_read_f,
+    .argmin     = 2,
+    .argmax     = -1,
+    .args       = "[-Cqv] [-P pattern ] off len [len..]",
+    .oneline    = "asynchronously reads a number of bytes",
+    .help       = aio_read_help,
+};
+
+static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
+{
+    int nr_iov, c;
+    struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
+
+    while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
+        switch (c) {
+        case 'C':
+            ctx->Cflag = 1;
+            break;
+        case 'P':
+            ctx->Pflag = 1;
+            ctx->pattern = parse_pattern(optarg);
+            if (ctx->pattern < 0) {
+                g_free(ctx);
+                return 0;
+            }
+            break;
+        case 'q':
+            ctx->qflag = 1;
+            break;
+        case 'v':
+            ctx->vflag = 1;
+            break;
+        default:
+            g_free(ctx);
+            return command_usage(&aio_read_cmd);
+        }
+    }
+
+    if (optind > argc - 2) {
+        g_free(ctx);
+        return command_usage(&aio_read_cmd);
+    }
+
+    ctx->offset = cvtnum(argv[optind]);
+    if (ctx->offset < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        g_free(ctx);
+        return 0;
+    }
+    optind++;
+
+    if (ctx->offset & 0x1ff) {
+        printf("offset %" PRId64 " is not sector aligned\n",
+               ctx->offset);
+        g_free(ctx);
+        return 0;
+    }
+
+    nr_iov = argc - optind;
+    ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, 0xab);
+    if (ctx->buf == NULL) {
+        g_free(ctx);
+        return 0;
+    }
+
+    gettimeofday(&ctx->t1, NULL);
+    bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
+                   ctx->qiov.size >> 9, aio_read_done, ctx);
+    return 0;
+}
+
+static void aio_write_help(void)
+{
+    printf(
+"\n"
+" asynchronously writes a range of bytes from the given offset source\n"
+" from multiple buffers\n"
+"\n"
+" Example:\n"
+" 'aio_write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
+"\n"
+" Writes into a segment of the currently open file, using a buffer\n"
+" filled with a set pattern (0xcdcdcdcd).\n"
+" The write is performed asynchronously and the aio_flush command must be\n"
+" used to ensure all outstanding aio requests have been completed.\n"
+" -P, -- use different pattern to fill file\n"
+" -C, -- report statistics in a machine parsable format\n"
+" -q, -- quiet mode, do not show I/O statistics\n"
+"\n");
+}
+
+static int aio_write_f(BlockDriverState *bs, int argc, char **argv);
+
+static const cmdinfo_t aio_write_cmd = {
+    .name       = "aio_write",
+    .cfunc      = aio_write_f,
+    .argmin     = 2,
+    .argmax     = -1,
+    .args       = "[-Cq] [-P pattern ] off len [len..]",
+    .oneline    = "asynchronously writes a number of bytes",
+    .help       = aio_write_help,
+};
+
+static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
+{
+    int nr_iov, c;
+    int pattern = 0xcd;
+    struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
+
+    while ((c = getopt(argc, argv, "CqP:")) != EOF) {
+        switch (c) {
+        case 'C':
+            ctx->Cflag = 1;
+            break;
+        case 'q':
+            ctx->qflag = 1;
+            break;
+        case 'P':
+            pattern = parse_pattern(optarg);
+            if (pattern < 0) {
+                g_free(ctx);
+                return 0;
+            }
+            break;
+        default:
+            g_free(ctx);
+            return command_usage(&aio_write_cmd);
+        }
+    }
+
+    if (optind > argc - 2) {
+        g_free(ctx);
+        return command_usage(&aio_write_cmd);
+    }
+
+    ctx->offset = cvtnum(argv[optind]);
+    if (ctx->offset < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        g_free(ctx);
+        return 0;
+    }
+    optind++;
+
+    if (ctx->offset & 0x1ff) {
+        printf("offset %" PRId64 " is not sector aligned\n",
+               ctx->offset);
+        g_free(ctx);
+        return 0;
+    }
+
+    nr_iov = argc - optind;
+    ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, pattern);
+    if (ctx->buf == NULL) {
+        g_free(ctx);
+        return 0;
+    }
+
+    gettimeofday(&ctx->t1, NULL);
+    bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
+                    ctx->qiov.size >> 9, aio_write_done, ctx);
+    return 0;
+}
+
+static int aio_flush_f(BlockDriverState *bs, int argc, char **argv)
+{
+    bdrv_drain_all();
+    return 0;
+}
+
+static const cmdinfo_t aio_flush_cmd = {
+    .name       = "aio_flush",
+    .cfunc      = aio_flush_f,
+    .oneline    = "completes all outstanding aio requests"
+};
+
+static int flush_f(BlockDriverState *bs, int argc, char **argv)
+{
+    bdrv_flush(bs);
+    return 0;
+}
+
+static const cmdinfo_t flush_cmd = {
+    .name       = "flush",
+    .altname    = "f",
+    .cfunc      = flush_f,
+    .oneline    = "flush all in-core file state to disk",
+};
+
+static int truncate_f(BlockDriverState *bs, int argc, char **argv)
+{
+    int64_t offset;
+    int ret;
+
+    offset = cvtnum(argv[1]);
+    if (offset < 0) {
+        printf("non-numeric truncate argument -- %s\n", argv[1]);
+        return 0;
+    }
+
+    ret = bdrv_truncate(bs, offset);
+    if (ret < 0) {
+        printf("truncate: %s\n", strerror(-ret));
+        return 0;
+    }
+
+    return 0;
+}
+
+static const cmdinfo_t truncate_cmd = {
+    .name       = "truncate",
+    .altname    = "t",
+    .cfunc      = truncate_f,
+    .argmin     = 1,
+    .argmax     = 1,
+    .args       = "off",
+    .oneline    = "truncates the current file at the given offset",
+};
+
+static int length_f(BlockDriverState *bs, int argc, char **argv)
+{
+    int64_t size;
+    char s1[64];
+
+    size = bdrv_getlength(bs);
+    if (size < 0) {
+        printf("getlength: %s\n", strerror(-size));
+        return 0;
+    }
+
+    cvtstr(size, s1, sizeof(s1));
+    printf("%s\n", s1);
+    return 0;
+}
+
+
+static const cmdinfo_t length_cmd = {
+    .name   = "length",
+    .altname    = "l",
+    .cfunc      = length_f,
+    .oneline    = "gets the length of the current file",
+};
+
+
+static int info_f(BlockDriverState *bs, int argc, char **argv)
+{
+    BlockDriverInfo bdi;
+    char s1[64], s2[64];
+    int ret;
+
+    if (bs->drv && bs->drv->format_name) {
+        printf("format name: %s\n", bs->drv->format_name);
+    }
+    if (bs->drv && bs->drv->protocol_name) {
+        printf("format name: %s\n", bs->drv->protocol_name);
+    }
+
+    ret = bdrv_get_info(bs, &bdi);
+    if (ret) {
+        return 0;
+    }
+
+    cvtstr(bdi.cluster_size, s1, sizeof(s1));
+    cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
+
+    printf("cluster size: %s\n", s1);
+    printf("vm state offset: %s\n", s2);
+
+    return 0;
+}
+
+
+
+static const cmdinfo_t info_cmd = {
+    .name       = "info",
+    .altname    = "i",
+    .cfunc      = info_f,
+    .oneline    = "prints information about the current file",
+};
+
+static void discard_help(void)
+{
+    printf(
+"\n"
+" discards a range of bytes from the given offset\n"
+"\n"
+" Example:\n"
+" 'discard 512 1k' - discards 1 kilobyte from 512 bytes into the file\n"
+"\n"
+" Discards a segment of the currently open file.\n"
+" -C, -- report statistics in a machine parsable format\n"
+" -q, -- quiet mode, do not show I/O statistics\n"
+"\n");
+}
+
+static int discard_f(BlockDriverState *bs, int argc, char **argv);
+
+static const cmdinfo_t discard_cmd = {
+    .name       = "discard",
+    .altname    = "d",
+    .cfunc      = discard_f,
+    .argmin     = 2,
+    .argmax     = -1,
+    .args       = "[-Cq] off len",
+    .oneline    = "discards a number of bytes at a specified offset",
+    .help       = discard_help,
+};
+
+static int discard_f(BlockDriverState *bs, int argc, char **argv)
+{
+    struct timeval t1, t2;
+    int Cflag = 0, qflag = 0;
+    int c, ret;
+    int64_t offset;
+    int count;
+
+    while ((c = getopt(argc, argv, "Cq")) != EOF) {
+        switch (c) {
+        case 'C':
+            Cflag = 1;
+            break;
+        case 'q':
+            qflag = 1;
+            break;
+        default:
+            return command_usage(&discard_cmd);
+        }
+    }
+
+    if (optind != argc - 2) {
+        return command_usage(&discard_cmd);
+    }
+
+    offset = cvtnum(argv[optind]);
+    if (offset < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        return 0;
+    }
+
+    optind++;
+    count = cvtnum(argv[optind]);
+    if (count < 0) {
+        printf("non-numeric length argument -- %s\n", argv[optind]);
+        return 0;
+    }
+
+    gettimeofday(&t1, NULL);
+    ret = bdrv_discard(bs, offset >> BDRV_SECTOR_BITS,
+                       count >> BDRV_SECTOR_BITS);
+    gettimeofday(&t2, NULL);
+
+    if (ret < 0) {
+        printf("discard failed: %s\n", strerror(-ret));
+        goto out;
+    }
+
+    /* Finally, report back -- -C gives a parsable format */
+    if (!qflag) {
+        t2 = tsub(t2, t1);
+        print_report("discard", &t2, offset, count, count, 1, Cflag);
+    }
+
+out:
+    return 0;
+}
+
+static int alloc_f(BlockDriverState *bs, int argc, char **argv)
+{
+    int64_t offset, sector_num;
+    int nb_sectors, remaining;
+    char s1[64];
+    int num, sum_alloc;
+    int ret;
+
+    offset = cvtnum(argv[1]);
+    if (offset < 0) {
+        printf("non-numeric offset argument -- %s\n", argv[1]);
+        return 0;
+    } else if (offset & 0x1ff) {
+        printf("offset %" PRId64 " is not sector aligned\n",
+               offset);
+        return 0;
+    }
+
+    if (argc == 3) {
+        nb_sectors = cvtnum(argv[2]);
+        if (nb_sectors < 0) {
+            printf("non-numeric length argument -- %s\n", argv[2]);
+            return 0;
+        }
+    } else {
+        nb_sectors = 1;
+    }
+
+    remaining = nb_sectors;
+    sum_alloc = 0;
+    sector_num = offset >> 9;
+    while (remaining) {
+        ret = bdrv_is_allocated(bs, sector_num, remaining, &num);
+        sector_num += num;
+        remaining -= num;
+        if (ret) {
+            sum_alloc += num;
+        }
+        if (num == 0) {
+            nb_sectors -= remaining;
+            remaining = 0;
+        }
+    }
+
+    cvtstr(offset, s1, sizeof(s1));
+
+    printf("%d/%d sectors allocated at offset %s\n",
+           sum_alloc, nb_sectors, s1);
+    return 0;
+}
+
+static const cmdinfo_t alloc_cmd = {
+    .name       = "alloc",
+    .altname    = "a",
+    .argmin     = 1,
+    .argmax     = 2,
+    .cfunc      = alloc_f,
+    .args       = "off [sectors]",
+    .oneline    = "checks if a sector is present in the file",
+};
+
+
+static int map_is_allocated(BlockDriverState *bs, int64_t sector_num,
+                            int64_t nb_sectors, int64_t *pnum)
+{
+    int num, num_checked;
+    int ret, firstret;
+
+    num_checked = MIN(nb_sectors, INT_MAX);
+    ret = bdrv_is_allocated(bs, sector_num, num_checked, &num);
+    if (ret < 0) {
+        return ret;
+    }
+
+    firstret = ret;
+    *pnum = num;
+
+    while (nb_sectors > 0 && ret == firstret) {
+        sector_num += num;
+        nb_sectors -= num;
+
+        num_checked = MIN(nb_sectors, INT_MAX);
+        ret = bdrv_is_allocated(bs, sector_num, num_checked, &num);
+        if (ret == firstret) {
+            *pnum += num;
+        } else {
+            break;
+        }
+    }
+
+    return firstret;
+}
+
+static int map_f(BlockDriverState *bs, int argc, char **argv)
+{
+    int64_t offset;
+    int64_t nb_sectors;
+    char s1[64];
+    int64_t num;
+    int ret;
+    const char *retstr;
+
+    offset = 0;
+    nb_sectors = bs->total_sectors;
+
+    do {
+        ret = map_is_allocated(bs, offset, nb_sectors, &num);
+        if (ret < 0) {
+            error_report("Failed to get allocation status: %s", strerror(-ret));
+            return 0;
+        }
+
+        retstr = ret ? "    allocated" : "not allocated";
+        cvtstr(offset << 9ULL, s1, sizeof(s1));
+        printf("[% 24" PRId64 "] % 8" PRId64 "/% 8" PRId64 " sectors %s "
+               "at offset %s (%d)\n",
+               offset << 9ULL, num, nb_sectors, retstr, s1, ret);
+
+        offset += num;
+        nb_sectors -= num;
+    } while (offset < bs->total_sectors);
+
+    return 0;
+}
+
+static const cmdinfo_t map_cmd = {
+       .name           = "map",
+       .argmin         = 0,
+       .argmax         = 0,
+       .cfunc          = map_f,
+       .args           = "",
+       .oneline        = "prints the allocated areas of a file",
+};
+
+static int break_f(BlockDriverState *bs, int argc, char **argv)
+{
+    int ret;
+
+    ret = bdrv_debug_breakpoint(bs, argv[1], argv[2]);
+    if (ret < 0) {
+        printf("Could not set breakpoint: %s\n", strerror(-ret));
+    }
+
+    return 0;
+}
+
+static const cmdinfo_t break_cmd = {
+       .name           = "break",
+       .argmin         = 2,
+       .argmax         = 2,
+       .cfunc          = break_f,
+       .args           = "event tag",
+       .oneline        = "sets a breakpoint on event and tags the stopped "
+                         "request as tag",
+};
+
+static int resume_f(BlockDriverState *bs, int argc, char **argv)
+{
+    int ret;
+
+    ret = bdrv_debug_resume(bs, argv[1]);
+    if (ret < 0) {
+        printf("Could not resume request: %s\n", strerror(-ret));
+    }
+
+    return 0;
+}
+
+static const cmdinfo_t resume_cmd = {
+       .name           = "resume",
+       .argmin         = 1,
+       .argmax         = 1,
+       .cfunc          = resume_f,
+       .args           = "tag",
+       .oneline        = "resumes the request tagged as tag",
+};
+
+static int wait_break_f(BlockDriverState *bs, int argc, char **argv)
+{
+    while (!bdrv_debug_is_suspended(bs, argv[1])) {
+        qemu_aio_wait();
+    }
+
+    return 0;
+}
+
+static const cmdinfo_t wait_break_cmd = {
+       .name           = "wait_break",
+       .argmin         = 1,
+       .argmax         = 1,
+       .cfunc          = wait_break_f,
+       .args           = "tag",
+       .oneline        = "waits for the suspension of a request",
+};
+
+static int abort_f(BlockDriverState *bs, int argc, char **argv)
+{
+    abort();
+}
+
+static const cmdinfo_t abort_cmd = {
+       .name           = "abort",
+       .cfunc          = abort_f,
+       .flags          = CMD_NOFILE_OK,
+       .oneline        = "simulate a program crash using abort(3)",
+};
+
+static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
+{
+    if (ct->flags & CMD_FLAG_GLOBAL) {
+        return 1;
+    }
+    if (!(ct->flags & CMD_NOFILE_OK) && !bs) {
+        fprintf(stderr, "no file open, try 'help open'\n");
+        return 0;
+    }
+    return 1;
+}
+
+static void __attribute((constructor)) init_qemuio_commands(void)
+{
+    /* initialize commands */
+    help_init();
+    add_command(&read_cmd);
+    add_command(&readv_cmd);
+    add_command(&write_cmd);
+    add_command(&writev_cmd);
+    add_command(&multiwrite_cmd);
+    add_command(&aio_read_cmd);
+    add_command(&aio_write_cmd);
+    add_command(&aio_flush_cmd);
+    add_command(&flush_cmd);
+    add_command(&truncate_cmd);
+    add_command(&length_cmd);
+    add_command(&info_cmd);
+    add_command(&discard_cmd);
+    add_command(&alloc_cmd);
+    add_command(&map_cmd);
+    add_command(&break_cmd);
+    add_command(&resume_cmd);
+    add_command(&wait_break_cmd);
+    add_command(&abort_cmd);
+
+    add_check_command(init_check_command);
+}
diff --git a/qemu-io.c b/qemu-io.c
index 39d7063..14eef2c 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -27,1786 +27,7 @@
 char *progname;
 
 BlockDriverState *qemuio_bs;
-static int misalign;
-
-static int64_t cvtnum(const char *s)
-{
-    char *end;
-    return strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
-}
-
-/*
- * Parse the pattern argument to various sub-commands.
- *
- * Because the pattern is used as an argument to memset it must evaluate
- * to an unsigned integer that fits into a single byte.
- */
-static int parse_pattern(const char *arg)
-{
-    char *endptr = NULL;
-    long pattern;
-
-    pattern = strtol(arg, &endptr, 0);
-    if (pattern < 0 || pattern > UCHAR_MAX || *endptr != '\0') {
-        printf("%s is not a valid pattern byte\n", arg);
-        return -1;
-    }
-
-    return pattern;
-}
-
-/*
- * Memory allocation helpers.
- *
- * Make sure memory is aligned by default, or purposefully misaligned if
- * that is specified on the command line.
- */
-
-#define MISALIGN_OFFSET     16
-static void *qemu_io_alloc(BlockDriverState *bs, size_t len, int pattern)
-{
-    void *buf;
-
-    if (misalign) {
-        len += MISALIGN_OFFSET;
-    }
-    buf = qemu_blockalign(bs, len);
-    memset(buf, pattern, len);
-    if (misalign) {
-        buf += MISALIGN_OFFSET;
-    }
-    return buf;
-}
-
-static void qemu_io_free(void *p)
-{
-    if (misalign) {
-        p -= MISALIGN_OFFSET;
-    }
-    qemu_vfree(p);
-}
-
-static void dump_buffer(const void *buffer, int64_t offset, int len)
-{
-    int i, j;
-    const uint8_t *p;
-
-    for (i = 0, p = buffer; i < len; i += 16) {
-        const uint8_t *s = p;
-
-        printf("%08" PRIx64 ":  ", offset + i);
-        for (j = 0; j < 16 && i + j < len; j++, p++) {
-            printf("%02x ", *p);
-        }
-        printf(" ");
-        for (j = 0; j < 16 && i + j < len; j++, s++) {
-            if (isalnum(*s)) {
-                printf("%c", *s);
-            } else {
-                printf(".");
-            }
-        }
-        printf("\n");
-    }
-}
-
-static void print_report(const char *op, struct timeval *t, int64_t offset,
-                         int count, int total, int cnt, int Cflag)
-{
-    char s1[64], s2[64], ts[64];
-
-    timestr(t, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0);
-    if (!Cflag) {
-        cvtstr((double)total, s1, sizeof(s1));
-        cvtstr(tdiv((double)total, *t), s2, sizeof(s2));
-        printf("%s %d/%d bytes at offset %" PRId64 "\n",
-               op, total, count, offset);
-        printf("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n",
-               s1, cnt, ts, s2, tdiv((double)cnt, *t));
-    } else {/* bytes,ops,time,bytes/sec,ops/sec */
-        printf("%d,%d,%s,%.3f,%.3f\n",
-            total, cnt, ts,
-            tdiv((double)total, *t),
-            tdiv((double)cnt, *t));
-    }
-}
-
-/*
- * Parse multiple length statements for vectored I/O, and construct an I/O
- * vector matching it.
- */
-static void *
-create_iovec(BlockDriverState *bs, QEMUIOVector *qiov, char **argv, int nr_iov,
-             int pattern)
-{
-    size_t *sizes = g_new0(size_t, nr_iov);
-    size_t count = 0;
-    void *buf = NULL;
-    void *p;
-    int i;
-
-    for (i = 0; i < nr_iov; i++) {
-        char *arg = argv[i];
-        int64_t len;
-
-        len = cvtnum(arg);
-        if (len < 0) {
-            printf("non-numeric length argument -- %s\n", arg);
-            goto fail;
-        }
-
-        /* should be SIZE_T_MAX, but that doesn't exist */
-        if (len > INT_MAX) {
-            printf("too large length argument -- %s\n", arg);
-            goto fail;
-        }
-
-        if (len & 0x1ff) {
-            printf("length argument %" PRId64
-                   " is not sector aligned\n", len);
-            goto fail;
-        }
-
-        sizes[i] = len;
-        count += len;
-    }
-
-    qemu_iovec_init(qiov, nr_iov);
-
-    buf = p = qemu_io_alloc(bs, count, pattern);
-
-    for (i = 0; i < nr_iov; i++) {
-        qemu_iovec_add(qiov, p, sizes[i]);
-        p += sizes[i];
-    }
-
-fail:
-    g_free(sizes);
-    return buf;
-}
-
-static int do_read(BlockDriverState *bs, char *buf, int64_t offset, int count,
-                   int *total)
-{
-    int ret;
-
-    ret = bdrv_read(bs, offset >> 9, (uint8_t *)buf, count >> 9);
-    if (ret < 0) {
-        return ret;
-    }
-    *total = count;
-    return 1;
-}
-
-static int do_write(BlockDriverState *bs, char *buf, int64_t offset, int count,
-                    int *total)
-{
-    int ret;
-
-    ret = bdrv_write(bs, offset >> 9, (uint8_t *)buf, count >> 9);
-    if (ret < 0) {
-        return ret;
-    }
-    *total = count;
-    return 1;
-}
-
-static int do_pread(BlockDriverState *bs, char *buf, int64_t offset, int count,
-                    int *total)
-{
-    *total = bdrv_pread(bs, offset, (uint8_t *)buf, count);
-    if (*total < 0) {
-        return *total;
-    }
-    return 1;
-}
-
-static int do_pwrite(BlockDriverState *bs, char *buf, int64_t offset, int count,
-                     int *total)
-{
-    *total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count);
-    if (*total < 0) {
-        return *total;
-    }
-    return 1;
-}
-
-typedef struct {
-    BlockDriverState *bs;
-    int64_t offset;
-    int count;
-    int *total;
-    int ret;
-    bool done;
-} CoWriteZeroes;
-
-static void coroutine_fn co_write_zeroes_entry(void *opaque)
-{
-    CoWriteZeroes *data = opaque;
-
-    data->ret = bdrv_co_write_zeroes(data->bs, data->offset / BDRV_SECTOR_SIZE,
-                                     data->count / BDRV_SECTOR_SIZE);
-    data->done = true;
-    if (data->ret < 0) {
-        *data->total = data->ret;
-        return;
-    }
-
-    *data->total = data->count;
-}
-
-static int do_co_write_zeroes(BlockDriverState *bs, int64_t offset, int count,
-                              int *total)
-{
-    Coroutine *co;
-    CoWriteZeroes data = {
-        .bs     = bs,
-        .offset = offset,
-        .count  = count,
-        .total  = total,
-        .done   = false,
-    };
-
-    co = qemu_coroutine_create(co_write_zeroes_entry);
-    qemu_coroutine_enter(co, &data);
-    while (!data.done) {
-        qemu_aio_wait();
-    }
-    if (data.ret < 0) {
-        return data.ret;
-    } else {
-        return 1;
-    }
-}
-
-static int do_write_compressed(BlockDriverState *bs, char *buf, int64_t offset,
-                               int count, int *total)
-{
-    int ret;
-
-    ret = bdrv_write_compressed(bs, offset >> 9, (uint8_t *)buf, count >> 9);
-    if (ret < 0) {
-        return ret;
-    }
-    *total = count;
-    return 1;
-}
-
-static int do_load_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
-                           int count, int *total)
-{
-    *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);
-    if (*total < 0) {
-        return *total;
-    }
-    return 1;
-}
-
-static int do_save_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
-                           int count, int *total)
-{
-    *total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count);
-    if (*total < 0) {
-        return *total;
-    }
-    return 1;
-}
-
-#define NOT_DONE 0x7fffffff
-static void aio_rw_done(void *opaque, int ret)
-{
-    *(int *)opaque = ret;
-}
-
-static int do_aio_readv(BlockDriverState *bs, QEMUIOVector *qiov,
-                        int64_t offset, int *total)
-{
-    int async_ret = NOT_DONE;
-
-    bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9,
-                   aio_rw_done, &async_ret);
-    while (async_ret == NOT_DONE) {
-        main_loop_wait(false);
-    }
-
-    *total = qiov->size;
-    return async_ret < 0 ? async_ret : 1;
-}
-
-static int do_aio_writev(BlockDriverState *bs, QEMUIOVector *qiov,
-                         int64_t offset, int *total)
-{
-    int async_ret = NOT_DONE;
-
-    bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9,
-                    aio_rw_done, &async_ret);
-    while (async_ret == NOT_DONE) {
-        main_loop_wait(false);
-    }
-
-    *total = qiov->size;
-    return async_ret < 0 ? async_ret : 1;
-}
-
-struct multiwrite_async_ret {
-    int num_done;
-    int error;
-};
-
-static void multiwrite_cb(void *opaque, int ret)
-{
-    struct multiwrite_async_ret *async_ret = opaque;
-
-    async_ret->num_done++;
-    if (ret < 0) {
-        async_ret->error = ret;
-    }
-}
-
-static int do_aio_multiwrite(BlockDriverState *bs, BlockRequest* reqs,
-                             int num_reqs, int *total)
-{
-    int i, ret;
-    struct multiwrite_async_ret async_ret = {
-        .num_done = 0,
-        .error = 0,
-    };
-
-    *total = 0;
-    for (i = 0; i < num_reqs; i++) {
-        reqs[i].cb = multiwrite_cb;
-        reqs[i].opaque = &async_ret;
-        *total += reqs[i].qiov->size;
-    }
-
-    ret = bdrv_aio_multiwrite(bs, reqs, num_reqs);
-    if (ret < 0) {
-        return ret;
-    }
-
-    while (async_ret.num_done < num_reqs) {
-        main_loop_wait(false);
-    }
-
-    return async_ret.error < 0 ? async_ret.error : 1;
-}
-
-static void read_help(void)
-{
-    printf(
-"\n"
-" reads a range of bytes from the given offset\n"
-"\n"
-" Example:\n"
-" 'read -v 512 1k' - dumps 1 kilobyte read from 512 bytes into the file\n"
-"\n"
-" Reads a segment of the currently open file, optionally dumping it to the\n"
-" standard output stream (with -v option) for subsequent inspection.\n"
-" -b, -- read from the VM state rather than the virtual disk\n"
-" -C, -- report statistics in a machine parsable format\n"
-" -l, -- length for pattern verification (only with -P)\n"
-" -p, -- use bdrv_pread to read the file\n"
-" -P, -- use a pattern to verify read data\n"
-" -q, -- quiet mode, do not show I/O statistics\n"
-" -s, -- start offset for pattern verification (only with -P)\n"
-" -v, -- dump buffer to standard output\n"
-"\n");
-}
-
-static int read_f(BlockDriverState *bs, int argc, char **argv);
-
-static const cmdinfo_t read_cmd = {
-    .name       = "read",
-    .altname    = "r",
-    .cfunc      = read_f,
-    .argmin     = 2,
-    .argmax     = -1,
-    .args       = "[-abCpqv] [-P pattern [-s off] [-l len]] off len",
-    .oneline    = "reads a number of bytes at a specified offset",
-    .help       = read_help,
-};
-
-static int read_f(BlockDriverState *bs, int argc, char **argv)
-{
-    struct timeval t1, t2;
-    int Cflag = 0, pflag = 0, qflag = 0, vflag = 0;
-    int Pflag = 0, sflag = 0, lflag = 0, bflag = 0;
-    int c, cnt;
-    char *buf;
-    int64_t offset;
-    int count;
-    /* Some compilers get confused and warn if this is not initialized.  */
-    int total = 0;
-    int pattern = 0, pattern_offset = 0, pattern_count = 0;
-
-    while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != EOF) {
-        switch (c) {
-        case 'b':
-            bflag = 1;
-            break;
-        case 'C':
-            Cflag = 1;
-            break;
-        case 'l':
-            lflag = 1;
-            pattern_count = cvtnum(optarg);
-            if (pattern_count < 0) {
-                printf("non-numeric length argument -- %s\n", optarg);
-                return 0;
-            }
-            break;
-        case 'p':
-            pflag = 1;
-            break;
-        case 'P':
-            Pflag = 1;
-            pattern = parse_pattern(optarg);
-            if (pattern < 0) {
-                return 0;
-            }
-            break;
-        case 'q':
-            qflag = 1;
-            break;
-        case 's':
-            sflag = 1;
-            pattern_offset = cvtnum(optarg);
-            if (pattern_offset < 0) {
-                printf("non-numeric length argument -- %s\n", optarg);
-                return 0;
-            }
-            break;
-        case 'v':
-            vflag = 1;
-            break;
-        default:
-            return command_usage(&read_cmd);
-        }
-    }
-
-    if (optind != argc - 2) {
-        return command_usage(&read_cmd);
-    }
-
-    if (bflag && pflag) {
-        printf("-b and -p cannot be specified at the same time\n");
-        return 0;
-    }
-
-    offset = cvtnum(argv[optind]);
-    if (offset < 0) {
-        printf("non-numeric length argument -- %s\n", argv[optind]);
-        return 0;
-    }
-
-    optind++;
-    count = cvtnum(argv[optind]);
-    if (count < 0) {
-        printf("non-numeric length argument -- %s\n", argv[optind]);
-        return 0;
-    }
-
-    if (!Pflag && (lflag || sflag)) {
-        return command_usage(&read_cmd);
-    }
-
-    if (!lflag) {
-        pattern_count = count - pattern_offset;
-    }
-
-    if ((pattern_count < 0) || (pattern_count + pattern_offset > count))  {
-        printf("pattern verification range exceeds end of read data\n");
-        return 0;
-    }
-
-    if (!pflag) {
-        if (offset & 0x1ff) {
-            printf("offset %" PRId64 " is not sector aligned\n",
-                   offset);
-            return 0;
-        }
-        if (count & 0x1ff) {
-            printf("count %d is not sector aligned\n",
-                   count);
-            return 0;
-        }
-    }
-
-    buf = qemu_io_alloc(bs, count, 0xab);
-
-    gettimeofday(&t1, NULL);
-    if (pflag) {
-        cnt = do_pread(bs, buf, offset, count, &total);
-    } else if (bflag) {
-        cnt = do_load_vmstate(bs, buf, offset, count, &total);
-    } else {
-        cnt = do_read(bs, buf, offset, count, &total);
-    }
-    gettimeofday(&t2, NULL);
-
-    if (cnt < 0) {
-        printf("read failed: %s\n", strerror(-cnt));
-        goto out;
-    }
-
-    if (Pflag) {
-        void *cmp_buf = g_malloc(pattern_count);
-        memset(cmp_buf, pattern, pattern_count);
-        if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
-            printf("Pattern verification failed at offset %"
-                   PRId64 ", %d bytes\n",
-                   offset + pattern_offset, pattern_count);
-        }
-        g_free(cmp_buf);
-    }
-
-    if (qflag) {
-        goto out;
-    }
-
-    if (vflag) {
-        dump_buffer(buf, offset, count);
-    }
-
-    /* Finally, report back -- -C gives a parsable format */
-    t2 = tsub(t2, t1);
-    print_report("read", &t2, offset, count, total, cnt, Cflag);
-
-out:
-    qemu_io_free(buf);
-
-    return 0;
-}
-
-static void readv_help(void)
-{
-    printf(
-"\n"
-" reads a range of bytes from the given offset into multiple buffers\n"
-"\n"
-" Example:\n"
-" 'readv -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
-"\n"
-" Reads a segment of the currently open file, optionally dumping it to the\n"
-" standard output stream (with -v option) for subsequent inspection.\n"
-" Uses multiple iovec buffers if more than one byte range is specified.\n"
-" -C, -- report statistics in a machine parsable format\n"
-" -P, -- use a pattern to verify read data\n"
-" -v, -- dump buffer to standard output\n"
-" -q, -- quiet mode, do not show I/O statistics\n"
-"\n");
-}
-
-static int readv_f(BlockDriverState *bs, int argc, char **argv);
-
-static const cmdinfo_t readv_cmd = {
-    .name       = "readv",
-    .cfunc      = readv_f,
-    .argmin     = 2,
-    .argmax     = -1,
-    .args       = "[-Cqv] [-P pattern ] off len [len..]",
-    .oneline    = "reads a number of bytes at a specified offset",
-    .help       = readv_help,
-};
-
-static int readv_f(BlockDriverState *bs, int argc, char **argv)
-{
-    struct timeval t1, t2;
-    int Cflag = 0, qflag = 0, vflag = 0;
-    int c, cnt;
-    char *buf;
-    int64_t offset;
-    /* Some compilers get confused and warn if this is not initialized.  */
-    int total = 0;
-    int nr_iov;
-    QEMUIOVector qiov;
-    int pattern = 0;
-    int Pflag = 0;
-
-    while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
-        switch (c) {
-        case 'C':
-            Cflag = 1;
-            break;
-        case 'P':
-            Pflag = 1;
-            pattern = parse_pattern(optarg);
-            if (pattern < 0) {
-                return 0;
-            }
-            break;
-        case 'q':
-            qflag = 1;
-            break;
-        case 'v':
-            vflag = 1;
-            break;
-        default:
-            return command_usage(&readv_cmd);
-        }
-    }
-
-    if (optind > argc - 2) {
-        return command_usage(&readv_cmd);
-    }
-
-
-    offset = cvtnum(argv[optind]);
-    if (offset < 0) {
-        printf("non-numeric length argument -- %s\n", argv[optind]);
-        return 0;
-    }
-    optind++;
-
-    if (offset & 0x1ff) {
-        printf("offset %" PRId64 " is not sector aligned\n",
-               offset);
-        return 0;
-    }
-
-    nr_iov = argc - optind;
-    buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, 0xab);
-    if (buf == NULL) {
-        return 0;
-    }
-
-    gettimeofday(&t1, NULL);
-    cnt = do_aio_readv(bs, &qiov, offset, &total);
-    gettimeofday(&t2, NULL);
-
-    if (cnt < 0) {
-        printf("readv failed: %s\n", strerror(-cnt));
-        goto out;
-    }
-
-    if (Pflag) {
-        void *cmp_buf = g_malloc(qiov.size);
-        memset(cmp_buf, pattern, qiov.size);
-        if (memcmp(buf, cmp_buf, qiov.size)) {
-            printf("Pattern verification failed at offset %"
-                   PRId64 ", %zd bytes\n", offset, qiov.size);
-        }
-        g_free(cmp_buf);
-    }
-
-    if (qflag) {
-        goto out;
-    }
-
-    if (vflag) {
-        dump_buffer(buf, offset, qiov.size);
-    }
-
-    /* Finally, report back -- -C gives a parsable format */
-    t2 = tsub(t2, t1);
-    print_report("read", &t2, offset, qiov.size, total, cnt, Cflag);
-
-out:
-    qemu_iovec_destroy(&qiov);
-    qemu_io_free(buf);
-    return 0;
-}
-
-static void write_help(void)
-{
-    printf(
-"\n"
-" writes a range of bytes from the given offset\n"
-"\n"
-" Example:\n"
-" 'write 512 1k' - writes 1 kilobyte at 512 bytes into the open file\n"
-"\n"
-" Writes into a segment of the currently open file, using a buffer\n"
-" filled with a set pattern (0xcdcdcdcd).\n"
-" -b, -- write to the VM state rather than the virtual disk\n"
-" -c, -- write compressed data with bdrv_write_compressed\n"
-" -p, -- use bdrv_pwrite to write the file\n"
-" -P, -- use different pattern to fill file\n"
-" -C, -- report statistics in a machine parsable format\n"
-" -q, -- quiet mode, do not show I/O statistics\n"
-" -z, -- write zeroes using bdrv_co_write_zeroes\n"
-"\n");
-}
-
-static int write_f(BlockDriverState *bs, int argc, char **argv);
-
-static const cmdinfo_t write_cmd = {
-    .name       = "write",
-    .altname    = "w",
-    .cfunc      = write_f,
-    .argmin     = 2,
-    .argmax     = -1,
-    .args       = "[-bcCpqz] [-P pattern ] off len",
-    .oneline    = "writes a number of bytes at a specified offset",
-    .help       = write_help,
-};
-
-static int write_f(BlockDriverState *bs, int argc, char **argv)
-{
-    struct timeval t1, t2;
-    int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0;
-    int cflag = 0;
-    int c, cnt;
-    char *buf = NULL;
-    int64_t offset;
-    int count;
-    /* Some compilers get confused and warn if this is not initialized.  */
-    int total = 0;
-    int pattern = 0xcd;
-
-    while ((c = getopt(argc, argv, "bcCpP:qz")) != EOF) {
-        switch (c) {
-        case 'b':
-            bflag = 1;
-            break;
-        case 'c':
-            cflag = 1;
-            break;
-        case 'C':
-            Cflag = 1;
-            break;
-        case 'p':
-            pflag = 1;
-            break;
-        case 'P':
-            Pflag = 1;
-            pattern = parse_pattern(optarg);
-            if (pattern < 0) {
-                return 0;
-            }
-            break;
-        case 'q':
-            qflag = 1;
-            break;
-        case 'z':
-            zflag = 1;
-            break;
-        default:
-            return command_usage(&write_cmd);
-        }
-    }
-
-    if (optind != argc - 2) {
-        return command_usage(&write_cmd);
-    }
-
-    if (bflag + pflag + zflag > 1) {
-        printf("-b, -p, or -z cannot be specified at the same time\n");
-        return 0;
-    }
-
-    if (zflag && Pflag) {
-        printf("-z and -P cannot be specified at the same time\n");
-        return 0;
-    }
-
-    offset = cvtnum(argv[optind]);
-    if (offset < 0) {
-        printf("non-numeric length argument -- %s\n", argv[optind]);
-        return 0;
-    }
-
-    optind++;
-    count = cvtnum(argv[optind]);
-    if (count < 0) {
-        printf("non-numeric length argument -- %s\n", argv[optind]);
-        return 0;
-    }
-
-    if (!pflag) {
-        if (offset & 0x1ff) {
-            printf("offset %" PRId64 " is not sector aligned\n",
-                   offset);
-            return 0;
-        }
-
-        if (count & 0x1ff) {
-            printf("count %d is not sector aligned\n",
-                   count);
-            return 0;
-        }
-    }
-
-    if (!zflag) {
-        buf = qemu_io_alloc(bs, count, pattern);
-    }
-
-    gettimeofday(&t1, NULL);
-    if (pflag) {
-        cnt = do_pwrite(bs, buf, offset, count, &total);
-    } else if (bflag) {
-        cnt = do_save_vmstate(bs, buf, offset, count, &total);
-    } else if (zflag) {
-        cnt = do_co_write_zeroes(bs, offset, count, &total);
-    } else if (cflag) {
-        cnt = do_write_compressed(bs, buf, offset, count, &total);
-    } else {
-        cnt = do_write(bs, buf, offset, count, &total);
-    }
-    gettimeofday(&t2, NULL);
-
-    if (cnt < 0) {
-        printf("write failed: %s\n", strerror(-cnt));
-        goto out;
-    }
-
-    if (qflag) {
-        goto out;
-    }
-
-    /* Finally, report back -- -C gives a parsable format */
-    t2 = tsub(t2, t1);
-    print_report("wrote", &t2, offset, count, total, cnt, Cflag);
-
-out:
-    if (!zflag) {
-        qemu_io_free(buf);
-    }
-
-    return 0;
-}
-
-static void
-writev_help(void)
-{
-    printf(
-"\n"
-" writes a range of bytes from the given offset source from multiple buffers\n"
-"\n"
-" Example:\n"
-" 'write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
-"\n"
-" Writes into a segment of the currently open file, using a buffer\n"
-" filled with a set pattern (0xcdcdcdcd).\n"
-" -P, -- use different pattern to fill file\n"
-" -C, -- report statistics in a machine parsable format\n"
-" -q, -- quiet mode, do not show I/O statistics\n"
-"\n");
-}
-
-static int writev_f(BlockDriverState *bs, int argc, char **argv);
-
-static const cmdinfo_t writev_cmd = {
-    .name       = "writev",
-    .cfunc      = writev_f,
-    .argmin     = 2,
-    .argmax     = -1,
-    .args       = "[-Cq] [-P pattern ] off len [len..]",
-    .oneline    = "writes a number of bytes at a specified offset",
-    .help       = writev_help,
-};
-
-static int writev_f(BlockDriverState *bs, int argc, char **argv)
-{
-    struct timeval t1, t2;
-    int Cflag = 0, qflag = 0;
-    int c, cnt;
-    char *buf;
-    int64_t offset;
-    /* Some compilers get confused and warn if this is not initialized.  */
-    int total = 0;
-    int nr_iov;
-    int pattern = 0xcd;
-    QEMUIOVector qiov;
-
-    while ((c = getopt(argc, argv, "CqP:")) != EOF) {
-        switch (c) {
-        case 'C':
-            Cflag = 1;
-            break;
-        case 'q':
-            qflag = 1;
-            break;
-        case 'P':
-            pattern = parse_pattern(optarg);
-            if (pattern < 0) {
-                return 0;
-            }
-            break;
-        default:
-            return command_usage(&writev_cmd);
-        }
-    }
-
-    if (optind > argc - 2) {
-        return command_usage(&writev_cmd);
-    }
-
-    offset = cvtnum(argv[optind]);
-    if (offset < 0) {
-        printf("non-numeric length argument -- %s\n", argv[optind]);
-        return 0;
-    }
-    optind++;
-
-    if (offset & 0x1ff) {
-        printf("offset %" PRId64 " is not sector aligned\n",
-               offset);
-        return 0;
-    }
-
-    nr_iov = argc - optind;
-    buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, pattern);
-    if (buf == NULL) {
-        return 0;
-    }
-
-    gettimeofday(&t1, NULL);
-    cnt = do_aio_writev(bs, &qiov, offset, &total);
-    gettimeofday(&t2, NULL);
-
-    if (cnt < 0) {
-        printf("writev failed: %s\n", strerror(-cnt));
-        goto out;
-    }
-
-    if (qflag) {
-        goto out;
-    }
-
-    /* Finally, report back -- -C gives a parsable format */
-    t2 = tsub(t2, t1);
-    print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag);
-out:
-    qemu_iovec_destroy(&qiov);
-    qemu_io_free(buf);
-    return 0;
-}
-
-static void multiwrite_help(void)
-{
-    printf(
-"\n"
-" writes a range of bytes from the given offset source from multiple buffers,\n"
-" in a batch of requests that may be merged by qemu\n"
-"\n"
-" Example:\n"
-" 'multiwrite 512 1k 1k ; 4k 1k'\n"
-"  writes 2 kB at 512 bytes and 1 kB at 4 kB into the open file\n"
-"\n"
-" Writes into a segment of the currently open file, using a buffer\n"
-" filled with a set pattern (0xcdcdcdcd). The pattern byte is increased\n"
-" by one for each request contained in the multiwrite command.\n"
-" -P, -- use different pattern to fill file\n"
-" -C, -- report statistics in a machine parsable format\n"
-" -q, -- quiet mode, do not show I/O statistics\n"
-"\n");
-}
-
-static int multiwrite_f(BlockDriverState *bs, int argc, char **argv);
-
-static const cmdinfo_t multiwrite_cmd = {
-    .name       = "multiwrite",
-    .cfunc      = multiwrite_f,
-    .argmin     = 2,
-    .argmax     = -1,
-    .args       = "[-Cq] [-P pattern ] off len [len..] [; off len [len..]..]",
-    .oneline    = "issues multiple write requests at once",
-    .help       = multiwrite_help,
-};
-
-static int multiwrite_f(BlockDriverState *bs, int argc, char **argv)
-{
-    struct timeval t1, t2;
-    int Cflag = 0, qflag = 0;
-    int c, cnt;
-    char **buf;
-    int64_t offset, first_offset = 0;
-    /* Some compilers get confused and warn if this is not initialized.  */
-    int total = 0;
-    int nr_iov;
-    int nr_reqs;
-    int pattern = 0xcd;
-    QEMUIOVector *qiovs;
-    int i;
-    BlockRequest *reqs;
-
-    while ((c = getopt(argc, argv, "CqP:")) != EOF) {
-        switch (c) {
-        case 'C':
-            Cflag = 1;
-            break;
-        case 'q':
-            qflag = 1;
-            break;
-        case 'P':
-            pattern = parse_pattern(optarg);
-            if (pattern < 0) {
-                return 0;
-            }
-            break;
-        default:
-            return command_usage(&writev_cmd);
-        }
-    }
-
-    if (optind > argc - 2) {
-        return command_usage(&writev_cmd);
-    }
-
-    nr_reqs = 1;
-    for (i = optind; i < argc; i++) {
-        if (!strcmp(argv[i], ";")) {
-            nr_reqs++;
-        }
-    }
-
-    reqs = g_malloc0(nr_reqs * sizeof(*reqs));
-    buf = g_malloc0(nr_reqs * sizeof(*buf));
-    qiovs = g_malloc(nr_reqs * sizeof(*qiovs));
-
-    for (i = 0; i < nr_reqs && optind < argc; i++) {
-        int j;
-
-        /* Read the offset of the request */
-        offset = cvtnum(argv[optind]);
-        if (offset < 0) {
-            printf("non-numeric offset argument -- %s\n", argv[optind]);
-            goto out;
-        }
-        optind++;
-
-        if (offset & 0x1ff) {
-            printf("offset %lld is not sector aligned\n",
-                   (long long)offset);
-            goto out;
-        }
-
-        if (i == 0) {
-            first_offset = offset;
-        }
-
-        /* Read lengths for qiov entries */
-        for (j = optind; j < argc; j++) {
-            if (!strcmp(argv[j], ";")) {
-                break;
-            }
-        }
-
-        nr_iov = j - optind;
-
-        /* Build request */
-        buf[i] = create_iovec(bs, &qiovs[i], &argv[optind], nr_iov, pattern);
-        if (buf[i] == NULL) {
-            goto out;
-        }
-
-        reqs[i].qiov = &qiovs[i];
-        reqs[i].sector = offset >> 9;
-        reqs[i].nb_sectors = reqs[i].qiov->size >> 9;
-
-        optind = j + 1;
-
-        pattern++;
-    }
-
-    /* If there were empty requests at the end, ignore them */
-    nr_reqs = i;
-
-    gettimeofday(&t1, NULL);
-    cnt = do_aio_multiwrite(bs, reqs, nr_reqs, &total);
-    gettimeofday(&t2, NULL);
-
-    if (cnt < 0) {
-        printf("aio_multiwrite failed: %s\n", strerror(-cnt));
-        goto out;
-    }
-
-    if (qflag) {
-        goto out;
-    }
-
-    /* Finally, report back -- -C gives a parsable format */
-    t2 = tsub(t2, t1);
-    print_report("wrote", &t2, first_offset, total, total, cnt, Cflag);
-out:
-    for (i = 0; i < nr_reqs; i++) {
-        qemu_io_free(buf[i]);
-        if (reqs[i].qiov != NULL) {
-            qemu_iovec_destroy(&qiovs[i]);
-        }
-    }
-    g_free(buf);
-    g_free(reqs);
-    g_free(qiovs);
-    return 0;
-}
-
-struct aio_ctx {
-    QEMUIOVector qiov;
-    int64_t offset;
-    char *buf;
-    int qflag;
-    int vflag;
-    int Cflag;
-    int Pflag;
-    int pattern;
-    struct timeval t1;
-};
-
-static void aio_write_done(void *opaque, int ret)
-{
-    struct aio_ctx *ctx = opaque;
-    struct timeval t2;
-
-    gettimeofday(&t2, NULL);
-
-
-    if (ret < 0) {
-        printf("aio_write failed: %s\n", strerror(-ret));
-        goto out;
-    }
-
-    if (ctx->qflag) {
-        goto out;
-    }
-
-    /* Finally, report back -- -C gives a parsable format */
-    t2 = tsub(t2, ctx->t1);
-    print_report("wrote", &t2, ctx->offset, ctx->qiov.size,
-                 ctx->qiov.size, 1, ctx->Cflag);
-out:
-    qemu_io_free(ctx->buf);
-    qemu_iovec_destroy(&ctx->qiov);
-    g_free(ctx);
-}
-
-static void aio_read_done(void *opaque, int ret)
-{
-    struct aio_ctx *ctx = opaque;
-    struct timeval t2;
-
-    gettimeofday(&t2, NULL);
-
-    if (ret < 0) {
-        printf("readv failed: %s\n", strerror(-ret));
-        goto out;
-    }
-
-    if (ctx->Pflag) {
-        void *cmp_buf = g_malloc(ctx->qiov.size);
-
-        memset(cmp_buf, ctx->pattern, ctx->qiov.size);
-        if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
-            printf("Pattern verification failed at offset %"
-                   PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
-        }
-        g_free(cmp_buf);
-    }
-
-    if (ctx->qflag) {
-        goto out;
-    }
-
-    if (ctx->vflag) {
-        dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size);
-    }
-
-    /* Finally, report back -- -C gives a parsable format */
-    t2 = tsub(t2, ctx->t1);
-    print_report("read", &t2, ctx->offset, ctx->qiov.size,
-                 ctx->qiov.size, 1, ctx->Cflag);
-out:
-    qemu_io_free(ctx->buf);
-    qemu_iovec_destroy(&ctx->qiov);
-    g_free(ctx);
-}
-
-static void aio_read_help(void)
-{
-    printf(
-"\n"
-" asynchronously reads a range of bytes from the given offset\n"
-"\n"
-" Example:\n"
-" 'aio_read -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
-"\n"
-" Reads a segment of the currently open file, optionally dumping it to the\n"
-" standard output stream (with -v option) for subsequent inspection.\n"
-" The read is performed asynchronously and the aio_flush command must be\n"
-" used to ensure all outstanding aio requests have been completed.\n"
-" -C, -- report statistics in a machine parsable format\n"
-" -P, -- use a pattern to verify read data\n"
-" -v, -- dump buffer to standard output\n"
-" -q, -- quiet mode, do not show I/O statistics\n"
-"\n");
-}
-
-static int aio_read_f(BlockDriverState *bs, int argc, char **argv);
-
-static const cmdinfo_t aio_read_cmd = {
-    .name       = "aio_read",
-    .cfunc      = aio_read_f,
-    .argmin     = 2,
-    .argmax     = -1,
-    .args       = "[-Cqv] [-P pattern ] off len [len..]",
-    .oneline    = "asynchronously reads a number of bytes",
-    .help       = aio_read_help,
-};
-
-static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
-{
-    int nr_iov, c;
-    struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
-
-    while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
-        switch (c) {
-        case 'C':
-            ctx->Cflag = 1;
-            break;
-        case 'P':
-            ctx->Pflag = 1;
-            ctx->pattern = parse_pattern(optarg);
-            if (ctx->pattern < 0) {
-                g_free(ctx);
-                return 0;
-            }
-            break;
-        case 'q':
-            ctx->qflag = 1;
-            break;
-        case 'v':
-            ctx->vflag = 1;
-            break;
-        default:
-            g_free(ctx);
-            return command_usage(&aio_read_cmd);
-        }
-    }
-
-    if (optind > argc - 2) {
-        g_free(ctx);
-        return command_usage(&aio_read_cmd);
-    }
-
-    ctx->offset = cvtnum(argv[optind]);
-    if (ctx->offset < 0) {
-        printf("non-numeric length argument -- %s\n", argv[optind]);
-        g_free(ctx);
-        return 0;
-    }
-    optind++;
-
-    if (ctx->offset & 0x1ff) {
-        printf("offset %" PRId64 " is not sector aligned\n",
-               ctx->offset);
-        g_free(ctx);
-        return 0;
-    }
-
-    nr_iov = argc - optind;
-    ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, 0xab);
-    if (ctx->buf == NULL) {
-        g_free(ctx);
-        return 0;
-    }
-
-    gettimeofday(&ctx->t1, NULL);
-    bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
-                   ctx->qiov.size >> 9, aio_read_done, ctx);
-    return 0;
-}
-
-static void aio_write_help(void)
-{
-    printf(
-"\n"
-" asynchronously writes a range of bytes from the given offset source\n"
-" from multiple buffers\n"
-"\n"
-" Example:\n"
-" 'aio_write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
-"\n"
-" Writes into a segment of the currently open file, using a buffer\n"
-" filled with a set pattern (0xcdcdcdcd).\n"
-" The write is performed asynchronously and the aio_flush command must be\n"
-" used to ensure all outstanding aio requests have been completed.\n"
-" -P, -- use different pattern to fill file\n"
-" -C, -- report statistics in a machine parsable format\n"
-" -q, -- quiet mode, do not show I/O statistics\n"
-"\n");
-}
-
-static int aio_write_f(BlockDriverState *bs, int argc, char **argv);
-
-static const cmdinfo_t aio_write_cmd = {
-    .name       = "aio_write",
-    .cfunc      = aio_write_f,
-    .argmin     = 2,
-    .argmax     = -1,
-    .args       = "[-Cq] [-P pattern ] off len [len..]",
-    .oneline    = "asynchronously writes a number of bytes",
-    .help       = aio_write_help,
-};
-
-static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
-{
-    int nr_iov, c;
-    int pattern = 0xcd;
-    struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
-
-    while ((c = getopt(argc, argv, "CqP:")) != EOF) {
-        switch (c) {
-        case 'C':
-            ctx->Cflag = 1;
-            break;
-        case 'q':
-            ctx->qflag = 1;
-            break;
-        case 'P':
-            pattern = parse_pattern(optarg);
-            if (pattern < 0) {
-                g_free(ctx);
-                return 0;
-            }
-            break;
-        default:
-            g_free(ctx);
-            return command_usage(&aio_write_cmd);
-        }
-    }
-
-    if (optind > argc - 2) {
-        g_free(ctx);
-        return command_usage(&aio_write_cmd);
-    }
-
-    ctx->offset = cvtnum(argv[optind]);
-    if (ctx->offset < 0) {
-        printf("non-numeric length argument -- %s\n", argv[optind]);
-        g_free(ctx);
-        return 0;
-    }
-    optind++;
-
-    if (ctx->offset & 0x1ff) {
-        printf("offset %" PRId64 " is not sector aligned\n",
-               ctx->offset);
-        g_free(ctx);
-        return 0;
-    }
-
-    nr_iov = argc - optind;
-    ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, pattern);
-    if (ctx->buf == NULL) {
-        g_free(ctx);
-        return 0;
-    }
-
-    gettimeofday(&ctx->t1, NULL);
-    bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
-                    ctx->qiov.size >> 9, aio_write_done, ctx);
-    return 0;
-}
-
-static int aio_flush_f(BlockDriverState *bs, int argc, char **argv)
-{
-    bdrv_drain_all();
-    return 0;
-}
-
-static const cmdinfo_t aio_flush_cmd = {
-    .name       = "aio_flush",
-    .cfunc      = aio_flush_f,
-    .oneline    = "completes all outstanding aio requests"
-};
-
-static int flush_f(BlockDriverState *bs, int argc, char **argv)
-{
-    bdrv_flush(bs);
-    return 0;
-}
-
-static const cmdinfo_t flush_cmd = {
-    .name       = "flush",
-    .altname    = "f",
-    .cfunc      = flush_f,
-    .oneline    = "flush all in-core file state to disk",
-};
-
-static int truncate_f(BlockDriverState *bs, int argc, char **argv)
-{
-    int64_t offset;
-    int ret;
-
-    offset = cvtnum(argv[1]);
-    if (offset < 0) {
-        printf("non-numeric truncate argument -- %s\n", argv[1]);
-        return 0;
-    }
-
-    ret = bdrv_truncate(bs, offset);
-    if (ret < 0) {
-        printf("truncate: %s\n", strerror(-ret));
-        return 0;
-    }
-
-    return 0;
-}
-
-static const cmdinfo_t truncate_cmd = {
-    .name       = "truncate",
-    .altname    = "t",
-    .cfunc      = truncate_f,
-    .argmin     = 1,
-    .argmax     = 1,
-    .args       = "off",
-    .oneline    = "truncates the current file at the given offset",
-};
-
-static int length_f(BlockDriverState *bs, int argc, char **argv)
-{
-    int64_t size;
-    char s1[64];
-
-    size = bdrv_getlength(bs);
-    if (size < 0) {
-        printf("getlength: %s\n", strerror(-size));
-        return 0;
-    }
-
-    cvtstr(size, s1, sizeof(s1));
-    printf("%s\n", s1);
-    return 0;
-}
-
-
-static const cmdinfo_t length_cmd = {
-    .name   = "length",
-    .altname    = "l",
-    .cfunc      = length_f,
-    .oneline    = "gets the length of the current file",
-};
-
-
-static int info_f(BlockDriverState *bs, int argc, char **argv)
-{
-    BlockDriverInfo bdi;
-    char s1[64], s2[64];
-    int ret;
-
-    if (bs->drv && bs->drv->format_name) {
-        printf("format name: %s\n", bs->drv->format_name);
-    }
-    if (bs->drv && bs->drv->protocol_name) {
-        printf("format name: %s\n", bs->drv->protocol_name);
-    }
-
-    ret = bdrv_get_info(bs, &bdi);
-    if (ret) {
-        return 0;
-    }
-
-    cvtstr(bdi.cluster_size, s1, sizeof(s1));
-    cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
-
-    printf("cluster size: %s\n", s1);
-    printf("vm state offset: %s\n", s2);
-
-    return 0;
-}
-
-
-
-static const cmdinfo_t info_cmd = {
-    .name       = "info",
-    .altname    = "i",
-    .cfunc      = info_f,
-    .oneline    = "prints information about the current file",
-};
-
-static void discard_help(void)
-{
-    printf(
-"\n"
-" discards a range of bytes from the given offset\n"
-"\n"
-" Example:\n"
-" 'discard 512 1k' - discards 1 kilobyte from 512 bytes into the file\n"
-"\n"
-" Discards a segment of the currently open file.\n"
-" -C, -- report statistics in a machine parsable format\n"
-" -q, -- quiet mode, do not show I/O statistics\n"
-"\n");
-}
-
-static int discard_f(BlockDriverState *bs, int argc, char **argv);
-
-static const cmdinfo_t discard_cmd = {
-    .name       = "discard",
-    .altname    = "d",
-    .cfunc      = discard_f,
-    .argmin     = 2,
-    .argmax     = -1,
-    .args       = "[-Cq] off len",
-    .oneline    = "discards a number of bytes at a specified offset",
-    .help       = discard_help,
-};
-
-static int discard_f(BlockDriverState *bs, int argc, char **argv)
-{
-    struct timeval t1, t2;
-    int Cflag = 0, qflag = 0;
-    int c, ret;
-    int64_t offset;
-    int count;
-
-    while ((c = getopt(argc, argv, "Cq")) != EOF) {
-        switch (c) {
-        case 'C':
-            Cflag = 1;
-            break;
-        case 'q':
-            qflag = 1;
-            break;
-        default:
-            return command_usage(&discard_cmd);
-        }
-    }
-
-    if (optind != argc - 2) {
-        return command_usage(&discard_cmd);
-    }
-
-    offset = cvtnum(argv[optind]);
-    if (offset < 0) {
-        printf("non-numeric length argument -- %s\n", argv[optind]);
-        return 0;
-    }
-
-    optind++;
-    count = cvtnum(argv[optind]);
-    if (count < 0) {
-        printf("non-numeric length argument -- %s\n", argv[optind]);
-        return 0;
-    }
-
-    gettimeofday(&t1, NULL);
-    ret = bdrv_discard(bs, offset >> BDRV_SECTOR_BITS,
-                       count >> BDRV_SECTOR_BITS);
-    gettimeofday(&t2, NULL);
-
-    if (ret < 0) {
-        printf("discard failed: %s\n", strerror(-ret));
-        goto out;
-    }
-
-    /* Finally, report back -- -C gives a parsable format */
-    if (!qflag) {
-        t2 = tsub(t2, t1);
-        print_report("discard", &t2, offset, count, count, 1, Cflag);
-    }
-
-out:
-    return 0;
-}
-
-static int alloc_f(BlockDriverState *bs, int argc, char **argv)
-{
-    int64_t offset, sector_num;
-    int nb_sectors, remaining;
-    char s1[64];
-    int num, sum_alloc;
-    int ret;
-
-    offset = cvtnum(argv[1]);
-    if (offset < 0) {
-        printf("non-numeric offset argument -- %s\n", argv[1]);
-        return 0;
-    } else if (offset & 0x1ff) {
-        printf("offset %" PRId64 " is not sector aligned\n",
-               offset);
-        return 0;
-    }
-
-    if (argc == 3) {
-        nb_sectors = cvtnum(argv[2]);
-        if (nb_sectors < 0) {
-            printf("non-numeric length argument -- %s\n", argv[2]);
-            return 0;
-        }
-    } else {
-        nb_sectors = 1;
-    }
-
-    remaining = nb_sectors;
-    sum_alloc = 0;
-    sector_num = offset >> 9;
-    while (remaining) {
-        ret = bdrv_is_allocated(bs, sector_num, remaining, &num);
-        sector_num += num;
-        remaining -= num;
-        if (ret) {
-            sum_alloc += num;
-        }
-        if (num == 0) {
-            nb_sectors -= remaining;
-            remaining = 0;
-        }
-    }
-
-    cvtstr(offset, s1, sizeof(s1));
-
-    printf("%d/%d sectors allocated at offset %s\n",
-           sum_alloc, nb_sectors, s1);
-    return 0;
-}
-
-static const cmdinfo_t alloc_cmd = {
-    .name       = "alloc",
-    .altname    = "a",
-    .argmin     = 1,
-    .argmax     = 2,
-    .cfunc      = alloc_f,
-    .args       = "off [sectors]",
-    .oneline    = "checks if a sector is present in the file",
-};
-
-
-static int map_is_allocated(BlockDriverState *bs, int64_t sector_num,
-                            int64_t nb_sectors, int64_t *pnum)
-{
-    int num, num_checked;
-    int ret, firstret;
-
-    num_checked = MIN(nb_sectors, INT_MAX);
-    ret = bdrv_is_allocated(bs, sector_num, num_checked, &num);
-    if (ret < 0) {
-        return ret;
-    }
-
-    firstret = ret;
-    *pnum = num;
-
-    while (nb_sectors > 0 && ret == firstret) {
-        sector_num += num;
-        nb_sectors -= num;
-
-        num_checked = MIN(nb_sectors, INT_MAX);
-        ret = bdrv_is_allocated(bs, sector_num, num_checked, &num);
-        if (ret == firstret) {
-            *pnum += num;
-        } else {
-            break;
-        }
-    }
-
-    return firstret;
-}
-
-static int map_f(BlockDriverState *bs, int argc, char **argv)
-{
-    int64_t offset;
-    int64_t nb_sectors;
-    char s1[64];
-    int64_t num;
-    int ret;
-    const char *retstr;
-
-    offset = 0;
-    nb_sectors = bs->total_sectors;
-
-    do {
-        ret = map_is_allocated(bs, offset, nb_sectors, &num);
-        if (ret < 0) {
-            error_report("Failed to get allocation status: %s", strerror(-ret));
-            return 0;
-        }
-
-        retstr = ret ? "    allocated" : "not allocated";
-        cvtstr(offset << 9ULL, s1, sizeof(s1));
-        printf("[% 24" PRId64 "] % 8" PRId64 "/% 8" PRId64 " sectors %s "
-               "at offset %s (%d)\n",
-               offset << 9ULL, num, nb_sectors, retstr, s1, ret);
-
-        offset += num;
-        nb_sectors -= num;
-    } while (offset < bs->total_sectors);
-
-    return 0;
-}
-
-static const cmdinfo_t map_cmd = {
-       .name           = "map",
-       .argmin         = 0,
-       .argmax         = 0,
-       .cfunc          = map_f,
-       .args           = "",
-       .oneline        = "prints the allocated areas of a file",
-};
-
-static int break_f(BlockDriverState *bs, int argc, char **argv)
-{
-    int ret;
-
-    ret = bdrv_debug_breakpoint(bs, argv[1], argv[2]);
-    if (ret < 0) {
-        printf("Could not set breakpoint: %s\n", strerror(-ret));
-    }
-
-    return 0;
-}
-
-static const cmdinfo_t break_cmd = {
-       .name           = "break",
-       .argmin         = 2,
-       .argmax         = 2,
-       .cfunc          = break_f,
-       .args           = "event tag",
-       .oneline        = "sets a breakpoint on event and tags the stopped "
-                         "request as tag",
-};
-
-static int resume_f(BlockDriverState *bs, int argc, char **argv)
-{
-    int ret;
-
-    ret = bdrv_debug_resume(bs, argv[1]);
-    if (ret < 0) {
-        printf("Could not resume request: %s\n", strerror(-ret));
-    }
-
-    return 0;
-}
-
-static const cmdinfo_t resume_cmd = {
-       .name           = "resume",
-       .argmin         = 1,
-       .argmax         = 1,
-       .cfunc          = resume_f,
-       .args           = "tag",
-       .oneline        = "resumes the request tagged as tag",
-};
-
-static int wait_break_f(BlockDriverState *bs, int argc, char **argv)
-{
-    while (!bdrv_debug_is_suspended(bs, argv[1])) {
-        qemu_aio_wait();
-    }
-
-    return 0;
-}
-
-static const cmdinfo_t wait_break_cmd = {
-       .name           = "wait_break",
-       .argmin         = 1,
-       .argmax         = 1,
-       .cfunc          = wait_break_f,
-       .args           = "tag",
-       .oneline        = "waits for the suspension of a request",
-};
-
-static int abort_f(BlockDriverState *bs, int argc, char **argv)
-{
-    abort();
-}
-
-static const cmdinfo_t abort_cmd = {
-       .name           = "abort",
-       .cfunc          = abort_f,
-       .flags          = CMD_NOFILE_OK,
-       .oneline        = "simulate a program crash using abort(3)",
-};
+extern int qemuio_misalign;
 
 static int close_f(BlockDriverState *bs, int argc, char **argv)
 {
@@ -1916,18 +137,6 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
     return openfile(argv[optind], flags, growable);
 }
 
-static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
-{
-    if (ct->flags & CMD_FLAG_GLOBAL) {
-        return 1;
-    }
-    if (!(ct->flags & CMD_NOFILE_OK) && !bs) {
-        fprintf(stderr, "no file open, try 'help open'\n");
-        return 0;
-    }
-    return 1;
-}
-
 static void usage(const char *name)
 {
     printf(
@@ -1998,7 +207,7 @@ int main(int argc, char **argv)
             readonly = 1;
             break;
         case 'm':
-            misalign = 1;
+            qemuio_misalign = 1;
             break;
         case 'g':
             growable = 1;
@@ -2039,30 +248,8 @@ int main(int argc, char **argv)
 
     /* initialize commands */
     quit_init();
-    help_init();
     add_command(&open_cmd);
     add_command(&close_cmd);
-    add_command(&read_cmd);
-    add_command(&readv_cmd);
-    add_command(&write_cmd);
-    add_command(&writev_cmd);
-    add_command(&multiwrite_cmd);
-    add_command(&aio_read_cmd);
-    add_command(&aio_write_cmd);
-    add_command(&aio_flush_cmd);
-    add_command(&flush_cmd);
-    add_command(&truncate_cmd);
-    add_command(&length_cmd);
-    add_command(&info_cmd);
-    add_command(&discard_cmd);
-    add_command(&alloc_cmd);
-    add_command(&map_cmd);
-    add_command(&break_cmd);
-    add_command(&resume_cmd);
-    add_command(&wait_break_cmd);
-    add_command(&abort_cmd);
-
-    add_check_command(init_check_command);
 
     /* open the device */
     if (!readonly) {
commit 734c3b85cb72d264ad2b38a87f30304e05de2cb1
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 14:19:30 2013 +0200

    qemu-io: Don't use global bs in command implementations
    
    Pass in the BlockDriverState to the command handlers instead of using
    the global variable. This is an important step to make the commands
    usable outside of qemu-io.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/cmd.c b/cmd.c
index 214c6f7..d501aab 100644
--- a/cmd.c
+++ b/cmd.c
@@ -57,7 +57,7 @@ check_command(
 	const cmdinfo_t	*ci)
 {
 	if (check_func)
-		return check_func(ci);
+		return check_func(qemuio_bs, ci);
 	return 1;
 }
 
@@ -103,7 +103,7 @@ command(
 		return 0;
 	}
 	optind = 0;
-	return ct->cfunc(argc, argv);
+	return ct->cfunc(qemuio_bs, argc, argv);
 }
 
 const cmdinfo_t *
@@ -452,6 +452,7 @@ static cmdinfo_t quit_cmd;
 /* ARGSUSED */
 static int
 quit_f(
+    BlockDriverState *bs,
 	int	argc,
 	char	**argv)
 {
@@ -490,6 +491,7 @@ help_all(void)
 
 static int
 help_f(
+    BlockDriverState *bs,
 	int		argc,
 	char		**argv)
 {
diff --git a/cmd.h b/cmd.h
index 4dcfe88..ccf6336 100644
--- a/cmd.h
+++ b/cmd.h
@@ -17,9 +17,13 @@
 #ifndef __COMMAND_H__
 #define __COMMAND_H__
 
+#include "qemu-common.h"
+
 #define CMD_FLAG_GLOBAL	((int)0x80000000)	/* don't iterate "args" */
 
-typedef int (*cfunc_t)(int argc, char **argv);
+extern BlockDriverState *qemuio_bs;
+
+typedef int (*cfunc_t)(BlockDriverState *bs, int argc, char **argv);
 typedef void (*helpfunc_t)(void);
 
 typedef struct cmdinfo {
@@ -41,7 +45,7 @@ extern int		ncmds;
 void help_init(void);
 void quit_init(void);
 
-typedef int (*checkfunc_t)(const cmdinfo_t *ci);
+typedef int (*checkfunc_t)(BlockDriverState *bs, const cmdinfo_t *ci);
 
 void add_command(const cmdinfo_t *ci);
 void add_user_command(char *optarg);
diff --git a/qemu-io.c b/qemu-io.c
index b4f56fc..39d7063 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -25,8 +25,8 @@
 #define CMD_NOFILE_OK   0x01
 
 char *progname;
-static BlockDriverState *bs;
 
+BlockDriverState *qemuio_bs;
 static int misalign;
 
 static int64_t cvtnum(const char *s)
@@ -63,7 +63,7 @@ static int parse_pattern(const char *arg)
  */
 
 #define MISALIGN_OFFSET     16
-static void *qemu_io_alloc(size_t len, int pattern)
+static void *qemu_io_alloc(BlockDriverState *bs, size_t len, int pattern)
 {
     void *buf;
 
@@ -136,7 +136,8 @@ static void print_report(const char *op, struct timeval *t, int64_t offset,
  * vector matching it.
  */
 static void *
-create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
+create_iovec(BlockDriverState *bs, QEMUIOVector *qiov, char **argv, int nr_iov,
+             int pattern)
 {
     size_t *sizes = g_new0(size_t, nr_iov);
     size_t count = 0;
@@ -172,7 +173,7 @@ create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
 
     qemu_iovec_init(qiov, nr_iov);
 
-    buf = p = qemu_io_alloc(count, pattern);
+    buf = p = qemu_io_alloc(bs, count, pattern);
 
     for (i = 0; i < nr_iov; i++) {
         qemu_iovec_add(qiov, p, sizes[i]);
@@ -184,7 +185,8 @@ fail:
     return buf;
 }
 
-static int do_read(char *buf, int64_t offset, int count, int *total)
+static int do_read(BlockDriverState *bs, char *buf, int64_t offset, int count,
+                   int *total)
 {
     int ret;
 
@@ -196,7 +198,8 @@ static int do_read(char *buf, int64_t offset, int count, int *total)
     return 1;
 }
 
-static int do_write(char *buf, int64_t offset, int count, int *total)
+static int do_write(BlockDriverState *bs, char *buf, int64_t offset, int count,
+                    int *total)
 {
     int ret;
 
@@ -208,7 +211,8 @@ static int do_write(char *buf, int64_t offset, int count, int *total)
     return 1;
 }
 
-static int do_pread(char *buf, int64_t offset, int count, int *total)
+static int do_pread(BlockDriverState *bs, char *buf, int64_t offset, int count,
+                    int *total)
 {
     *total = bdrv_pread(bs, offset, (uint8_t *)buf, count);
     if (*total < 0) {
@@ -217,7 +221,8 @@ static int do_pread(char *buf, int64_t offset, int count, int *total)
     return 1;
 }
 
-static int do_pwrite(char *buf, int64_t offset, int count, int *total)
+static int do_pwrite(BlockDriverState *bs, char *buf, int64_t offset, int count,
+                     int *total)
 {
     *total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count);
     if (*total < 0) {
@@ -227,6 +232,7 @@ static int do_pwrite(char *buf, int64_t offset, int count, int *total)
 }
 
 typedef struct {
+    BlockDriverState *bs;
     int64_t offset;
     int count;
     int *total;
@@ -238,7 +244,7 @@ static void coroutine_fn co_write_zeroes_entry(void *opaque)
 {
     CoWriteZeroes *data = opaque;
 
-    data->ret = bdrv_co_write_zeroes(bs, data->offset / BDRV_SECTOR_SIZE,
+    data->ret = bdrv_co_write_zeroes(data->bs, data->offset / BDRV_SECTOR_SIZE,
                                      data->count / BDRV_SECTOR_SIZE);
     data->done = true;
     if (data->ret < 0) {
@@ -249,10 +255,12 @@ static void coroutine_fn co_write_zeroes_entry(void *opaque)
     *data->total = data->count;
 }
 
-static int do_co_write_zeroes(int64_t offset, int count, int *total)
+static int do_co_write_zeroes(BlockDriverState *bs, int64_t offset, int count,
+                              int *total)
 {
     Coroutine *co;
     CoWriteZeroes data = {
+        .bs     = bs,
         .offset = offset,
         .count  = count,
         .total  = total,
@@ -271,7 +279,8 @@ static int do_co_write_zeroes(int64_t offset, int count, int *total)
     }
 }
 
-static int do_write_compressed(char *buf, int64_t offset, int count, int *total)
+static int do_write_compressed(BlockDriverState *bs, char *buf, int64_t offset,
+                               int count, int *total)
 {
     int ret;
 
@@ -283,7 +292,8 @@ static int do_write_compressed(char *buf, int64_t offset, int count, int *total)
     return 1;
 }
 
-static int do_load_vmstate(char *buf, int64_t offset, int count, int *total)
+static int do_load_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
+                           int count, int *total)
 {
     *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);
     if (*total < 0) {
@@ -292,7 +302,8 @@ static int do_load_vmstate(char *buf, int64_t offset, int count, int *total)
     return 1;
 }
 
-static int do_save_vmstate(char *buf, int64_t offset, int count, int *total)
+static int do_save_vmstate(BlockDriverState *bs, char *buf, int64_t offset,
+                           int count, int *total)
 {
     *total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count);
     if (*total < 0) {
@@ -307,7 +318,8 @@ static void aio_rw_done(void *opaque, int ret)
     *(int *)opaque = ret;
 }
 
-static int do_aio_readv(QEMUIOVector *qiov, int64_t offset, int *total)
+static int do_aio_readv(BlockDriverState *bs, QEMUIOVector *qiov,
+                        int64_t offset, int *total)
 {
     int async_ret = NOT_DONE;
 
@@ -321,7 +333,8 @@ static int do_aio_readv(QEMUIOVector *qiov, int64_t offset, int *total)
     return async_ret < 0 ? async_ret : 1;
 }
 
-static int do_aio_writev(QEMUIOVector *qiov, int64_t offset, int *total)
+static int do_aio_writev(BlockDriverState *bs, QEMUIOVector *qiov,
+                         int64_t offset, int *total)
 {
     int async_ret = NOT_DONE;
 
@@ -350,7 +363,8 @@ static void multiwrite_cb(void *opaque, int ret)
     }
 }
 
-static int do_aio_multiwrite(BlockRequest* reqs, int num_reqs, int *total)
+static int do_aio_multiwrite(BlockDriverState *bs, BlockRequest* reqs,
+                             int num_reqs, int *total)
 {
     int i, ret;
     struct multiwrite_async_ret async_ret = {
@@ -399,7 +413,7 @@ static void read_help(void)
 "\n");
 }
 
-static int read_f(int argc, char **argv);
+static int read_f(BlockDriverState *bs, int argc, char **argv);
 
 static const cmdinfo_t read_cmd = {
     .name       = "read",
@@ -412,7 +426,7 @@ static const cmdinfo_t read_cmd = {
     .help       = read_help,
 };
 
-static int read_f(int argc, char **argv)
+static int read_f(BlockDriverState *bs, int argc, char **argv)
 {
     struct timeval t1, t2;
     int Cflag = 0, pflag = 0, qflag = 0, vflag = 0;
@@ -518,15 +532,15 @@ static int read_f(int argc, char **argv)
         }
     }
 
-    buf = qemu_io_alloc(count, 0xab);
+    buf = qemu_io_alloc(bs, count, 0xab);
 
     gettimeofday(&t1, NULL);
     if (pflag) {
-        cnt = do_pread(buf, offset, count, &total);
+        cnt = do_pread(bs, buf, offset, count, &total);
     } else if (bflag) {
-        cnt = do_load_vmstate(buf, offset, count, &total);
+        cnt = do_load_vmstate(bs, buf, offset, count, &total);
     } else {
-        cnt = do_read(buf, offset, count, &total);
+        cnt = do_read(bs, buf, offset, count, &total);
     }
     gettimeofday(&t2, NULL);
 
@@ -583,7 +597,7 @@ static void readv_help(void)
 "\n");
 }
 
-static int readv_f(int argc, char **argv);
+static int readv_f(BlockDriverState *bs, int argc, char **argv);
 
 static const cmdinfo_t readv_cmd = {
     .name       = "readv",
@@ -595,7 +609,7 @@ static const cmdinfo_t readv_cmd = {
     .help       = readv_help,
 };
 
-static int readv_f(int argc, char **argv)
+static int readv_f(BlockDriverState *bs, int argc, char **argv)
 {
     struct timeval t1, t2;
     int Cflag = 0, qflag = 0, vflag = 0;
@@ -651,13 +665,13 @@ static int readv_f(int argc, char **argv)
     }
 
     nr_iov = argc - optind;
-    buf = create_iovec(&qiov, &argv[optind], nr_iov, 0xab);
+    buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, 0xab);
     if (buf == NULL) {
         return 0;
     }
 
     gettimeofday(&t1, NULL);
-    cnt = do_aio_readv(&qiov, offset, &total);
+    cnt = do_aio_readv(bs, &qiov, offset, &total);
     gettimeofday(&t2, NULL);
 
     if (cnt < 0) {
@@ -714,7 +728,7 @@ static void write_help(void)
 "\n");
 }
 
-static int write_f(int argc, char **argv);
+static int write_f(BlockDriverState *bs, int argc, char **argv);
 
 static const cmdinfo_t write_cmd = {
     .name       = "write",
@@ -727,7 +741,7 @@ static const cmdinfo_t write_cmd = {
     .help       = write_help,
 };
 
-static int write_f(int argc, char **argv)
+static int write_f(BlockDriverState *bs, int argc, char **argv)
 {
     struct timeval t1, t2;
     int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0;
@@ -814,20 +828,20 @@ static int write_f(int argc, char **argv)
     }
 
     if (!zflag) {
-        buf = qemu_io_alloc(count, pattern);
+        buf = qemu_io_alloc(bs, count, pattern);
     }
 
     gettimeofday(&t1, NULL);
     if (pflag) {
-        cnt = do_pwrite(buf, offset, count, &total);
+        cnt = do_pwrite(bs, buf, offset, count, &total);
     } else if (bflag) {
-        cnt = do_save_vmstate(buf, offset, count, &total);
+        cnt = do_save_vmstate(bs, buf, offset, count, &total);
     } else if (zflag) {
-        cnt = do_co_write_zeroes(offset, count, &total);
+        cnt = do_co_write_zeroes(bs, offset, count, &total);
     } else if (cflag) {
-        cnt = do_write_compressed(buf, offset, count, &total);
+        cnt = do_write_compressed(bs, buf, offset, count, &total);
     } else {
-        cnt = do_write(buf, offset, count, &total);
+        cnt = do_write(bs, buf, offset, count, &total);
     }
     gettimeofday(&t2, NULL);
 
@@ -870,7 +884,7 @@ writev_help(void)
 "\n");
 }
 
-static int writev_f(int argc, char **argv);
+static int writev_f(BlockDriverState *bs, int argc, char **argv);
 
 static const cmdinfo_t writev_cmd = {
     .name       = "writev",
@@ -882,7 +896,7 @@ static const cmdinfo_t writev_cmd = {
     .help       = writev_help,
 };
 
-static int writev_f(int argc, char **argv)
+static int writev_f(BlockDriverState *bs, int argc, char **argv)
 {
     struct timeval t1, t2;
     int Cflag = 0, qflag = 0;
@@ -932,13 +946,13 @@ static int writev_f(int argc, char **argv)
     }
 
     nr_iov = argc - optind;
-    buf = create_iovec(&qiov, &argv[optind], nr_iov, pattern);
+    buf = create_iovec(bs, &qiov, &argv[optind], nr_iov, pattern);
     if (buf == NULL) {
         return 0;
     }
 
     gettimeofday(&t1, NULL);
-    cnt = do_aio_writev(&qiov, offset, &total);
+    cnt = do_aio_writev(bs, &qiov, offset, &total);
     gettimeofday(&t2, NULL);
 
     if (cnt < 0) {
@@ -979,7 +993,7 @@ static void multiwrite_help(void)
 "\n");
 }
 
-static int multiwrite_f(int argc, char **argv);
+static int multiwrite_f(BlockDriverState *bs, int argc, char **argv);
 
 static const cmdinfo_t multiwrite_cmd = {
     .name       = "multiwrite",
@@ -991,7 +1005,7 @@ static const cmdinfo_t multiwrite_cmd = {
     .help       = multiwrite_help,
 };
 
-static int multiwrite_f(int argc, char **argv)
+static int multiwrite_f(BlockDriverState *bs, int argc, char **argv)
 {
     struct timeval t1, t2;
     int Cflag = 0, qflag = 0;
@@ -1072,7 +1086,7 @@ static int multiwrite_f(int argc, char **argv)
         nr_iov = j - optind;
 
         /* Build request */
-        buf[i] = create_iovec(&qiovs[i], &argv[optind], nr_iov, pattern);
+        buf[i] = create_iovec(bs, &qiovs[i], &argv[optind], nr_iov, pattern);
         if (buf[i] == NULL) {
             goto out;
         }
@@ -1090,7 +1104,7 @@ static int multiwrite_f(int argc, char **argv)
     nr_reqs = i;
 
     gettimeofday(&t1, NULL);
-    cnt = do_aio_multiwrite(reqs, nr_reqs, &total);
+    cnt = do_aio_multiwrite(bs, reqs, nr_reqs, &total);
     gettimeofday(&t2, NULL);
 
     if (cnt < 0) {
@@ -1218,7 +1232,7 @@ static void aio_read_help(void)
 "\n");
 }
 
-static int aio_read_f(int argc, char **argv);
+static int aio_read_f(BlockDriverState *bs, int argc, char **argv);
 
 static const cmdinfo_t aio_read_cmd = {
     .name       = "aio_read",
@@ -1230,7 +1244,7 @@ static const cmdinfo_t aio_read_cmd = {
     .help       = aio_read_help,
 };
 
-static int aio_read_f(int argc, char **argv)
+static int aio_read_f(BlockDriverState *bs, int argc, char **argv)
 {
     int nr_iov, c;
     struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
@@ -1281,7 +1295,7 @@ static int aio_read_f(int argc, char **argv)
     }
 
     nr_iov = argc - optind;
-    ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, 0xab);
+    ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, 0xab);
     if (ctx->buf == NULL) {
         g_free(ctx);
         return 0;
@@ -1313,7 +1327,7 @@ static void aio_write_help(void)
 "\n");
 }
 
-static int aio_write_f(int argc, char **argv);
+static int aio_write_f(BlockDriverState *bs, int argc, char **argv);
 
 static const cmdinfo_t aio_write_cmd = {
     .name       = "aio_write",
@@ -1325,7 +1339,7 @@ static const cmdinfo_t aio_write_cmd = {
     .help       = aio_write_help,
 };
 
-static int aio_write_f(int argc, char **argv)
+static int aio_write_f(BlockDriverState *bs, int argc, char **argv)
 {
     int nr_iov, c;
     int pattern = 0xcd;
@@ -1373,7 +1387,7 @@ static int aio_write_f(int argc, char **argv)
     }
 
     nr_iov = argc - optind;
-    ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern);
+    ctx->buf = create_iovec(bs, &ctx->qiov, &argv[optind], nr_iov, pattern);
     if (ctx->buf == NULL) {
         g_free(ctx);
         return 0;
@@ -1385,7 +1399,7 @@ static int aio_write_f(int argc, char **argv)
     return 0;
 }
 
-static int aio_flush_f(int argc, char **argv)
+static int aio_flush_f(BlockDriverState *bs, int argc, char **argv)
 {
     bdrv_drain_all();
     return 0;
@@ -1397,7 +1411,7 @@ static const cmdinfo_t aio_flush_cmd = {
     .oneline    = "completes all outstanding aio requests"
 };
 
-static int flush_f(int argc, char **argv)
+static int flush_f(BlockDriverState *bs, int argc, char **argv)
 {
     bdrv_flush(bs);
     return 0;
@@ -1410,7 +1424,7 @@ static const cmdinfo_t flush_cmd = {
     .oneline    = "flush all in-core file state to disk",
 };
 
-static int truncate_f(int argc, char **argv)
+static int truncate_f(BlockDriverState *bs, int argc, char **argv)
 {
     int64_t offset;
     int ret;
@@ -1440,7 +1454,7 @@ static const cmdinfo_t truncate_cmd = {
     .oneline    = "truncates the current file at the given offset",
 };
 
-static int length_f(int argc, char **argv)
+static int length_f(BlockDriverState *bs, int argc, char **argv)
 {
     int64_t size;
     char s1[64];
@@ -1465,7 +1479,7 @@ static const cmdinfo_t length_cmd = {
 };
 
 
-static int info_f(int argc, char **argv)
+static int info_f(BlockDriverState *bs, int argc, char **argv)
 {
     BlockDriverInfo bdi;
     char s1[64], s2[64];
@@ -1516,7 +1530,7 @@ static void discard_help(void)
 "\n");
 }
 
-static int discard_f(int argc, char **argv);
+static int discard_f(BlockDriverState *bs, int argc, char **argv);
 
 static const cmdinfo_t discard_cmd = {
     .name       = "discard",
@@ -1529,7 +1543,7 @@ static const cmdinfo_t discard_cmd = {
     .help       = discard_help,
 };
 
-static int discard_f(int argc, char **argv)
+static int discard_f(BlockDriverState *bs, int argc, char **argv)
 {
     struct timeval t1, t2;
     int Cflag = 0, qflag = 0;
@@ -1587,7 +1601,7 @@ out:
     return 0;
 }
 
-static int alloc_f(int argc, char **argv)
+static int alloc_f(BlockDriverState *bs, int argc, char **argv)
 {
     int64_t offset, sector_num;
     int nb_sectors, remaining;
@@ -1649,7 +1663,8 @@ static const cmdinfo_t alloc_cmd = {
 };
 
 
-static int map_is_allocated(int64_t sector_num, int64_t nb_sectors, int64_t *pnum)
+static int map_is_allocated(BlockDriverState *bs, int64_t sector_num,
+                            int64_t nb_sectors, int64_t *pnum)
 {
     int num, num_checked;
     int ret, firstret;
@@ -1679,7 +1694,7 @@ static int map_is_allocated(int64_t sector_num, int64_t nb_sectors, int64_t *pnu
     return firstret;
 }
 
-static int map_f(int argc, char **argv)
+static int map_f(BlockDriverState *bs, int argc, char **argv)
 {
     int64_t offset;
     int64_t nb_sectors;
@@ -1692,7 +1707,7 @@ static int map_f(int argc, char **argv)
     nb_sectors = bs->total_sectors;
 
     do {
-        ret = map_is_allocated(offset, nb_sectors, &num);
+        ret = map_is_allocated(bs, offset, nb_sectors, &num);
         if (ret < 0) {
             error_report("Failed to get allocation status: %s", strerror(-ret));
             return 0;
@@ -1720,7 +1735,7 @@ static const cmdinfo_t map_cmd = {
        .oneline        = "prints the allocated areas of a file",
 };
 
-static int break_f(int argc, char **argv)
+static int break_f(BlockDriverState *bs, int argc, char **argv)
 {
     int ret;
 
@@ -1742,7 +1757,7 @@ static const cmdinfo_t break_cmd = {
                          "request as tag",
 };
 
-static int resume_f(int argc, char **argv)
+static int resume_f(BlockDriverState *bs, int argc, char **argv)
 {
     int ret;
 
@@ -1763,7 +1778,7 @@ static const cmdinfo_t resume_cmd = {
        .oneline        = "resumes the request tagged as tag",
 };
 
-static int wait_break_f(int argc, char **argv)
+static int wait_break_f(BlockDriverState *bs, int argc, char **argv)
 {
     while (!bdrv_debug_is_suspended(bs, argv[1])) {
         qemu_aio_wait();
@@ -1781,7 +1796,7 @@ static const cmdinfo_t wait_break_cmd = {
        .oneline        = "waits for the suspension of a request",
 };
 
-static int abort_f(int argc, char **argv)
+static int abort_f(BlockDriverState *bs, int argc, char **argv)
 {
     abort();
 }
@@ -1793,10 +1808,10 @@ static const cmdinfo_t abort_cmd = {
        .oneline        = "simulate a program crash using abort(3)",
 };
 
-static int close_f(int argc, char **argv)
+static int close_f(BlockDriverState *bs, int argc, char **argv)
 {
     bdrv_delete(bs);
-    bs = NULL;
+    qemuio_bs = NULL;
     return 0;
 }
 
@@ -1809,23 +1824,23 @@ static const cmdinfo_t close_cmd = {
 
 static int openfile(char *name, int flags, int growable)
 {
-    if (bs) {
+    if (qemuio_bs) {
         fprintf(stderr, "file open already, try 'help close'\n");
         return 1;
     }
 
     if (growable) {
-        if (bdrv_file_open(&bs, name, NULL, flags)) {
+        if (bdrv_file_open(&qemuio_bs, name, NULL, flags)) {
             fprintf(stderr, "%s: can't open device %s\n", progname, name);
             return 1;
         }
     } else {
-        bs = bdrv_new("hda");
+        qemuio_bs = bdrv_new("hda");
 
-        if (bdrv_open(bs, name, NULL, flags, NULL) < 0) {
+        if (bdrv_open(qemuio_bs, name, NULL, flags, NULL) < 0) {
             fprintf(stderr, "%s: can't open device %s\n", progname, name);
-            bdrv_delete(bs);
-            bs = NULL;
+            bdrv_delete(qemuio_bs);
+            qemuio_bs = NULL;
             return 1;
         }
     }
@@ -1850,7 +1865,7 @@ static void open_help(void)
 "\n");
 }
 
-static int open_f(int argc, char **argv);
+static int open_f(BlockDriverState *bs, int argc, char **argv);
 
 static const cmdinfo_t open_cmd = {
     .name       = "open",
@@ -1864,7 +1879,7 @@ static const cmdinfo_t open_cmd = {
     .help       = open_help,
 };
 
-static int open_f(int argc, char **argv)
+static int open_f(BlockDriverState *bs, int argc, char **argv)
 {
     int flags = 0;
     int readonly = 0;
@@ -1901,7 +1916,7 @@ static int open_f(int argc, char **argv)
     return openfile(argv[optind], flags, growable);
 }
 
-static int init_check_command(const cmdinfo_t *ct)
+static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
 {
     if (ct->flags & CMD_FLAG_GLOBAL) {
         return 1;
@@ -2064,8 +2079,8 @@ int main(int argc, char **argv)
      */
     bdrv_drain_all();
 
-    if (bs) {
-        bdrv_delete(bs);
+    if (qemuio_bs) {
+        bdrv_delete(qemuio_bs);
     }
     return 0;
 }
commit cf49a6a00c19cabf4006d4f82bef26345043e7b5
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 14:19:29 2013 +0200

    qemu-io: Handle cvtnum() errors in 'alloc'
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/qemu-io.c b/qemu-io.c
index 8a719a8..b4f56fc 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -1596,7 +1596,10 @@ static int alloc_f(int argc, char **argv)
     int ret;
 
     offset = cvtnum(argv[1]);
-    if (offset & 0x1ff) {
+    if (offset < 0) {
+        printf("non-numeric offset argument -- %s\n", argv[1]);
+        return 0;
+    } else if (offset & 0x1ff) {
         printf("offset %" PRId64 " is not sector aligned\n",
                offset);
         return 0;
@@ -1604,6 +1607,10 @@ static int alloc_f(int argc, char **argv)
 
     if (argc == 3) {
         nb_sectors = cvtnum(argv[2]);
+        if (nb_sectors < 0) {
+            printf("non-numeric length argument -- %s\n", argv[2]);
+            return 0;
+        }
     } else {
         nb_sectors = 1;
     }
commit b6e356aa25c81d928e1c463292048d29cf25f04e
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 14:19:28 2013 +0200

    qemu-io: Make cvtnum() a wrapper around strtosz_suffix()
    
    No reason to implement the same thing multiple times. A nice side effect
    is that fractional numbers like 0.5M can be used in qemu-io now.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/cmd.c b/cmd.c
index 4e7579b..214c6f7 100644
--- a/cmd.c
+++ b/cmd.c
@@ -344,43 +344,6 @@ doneline(
 #define MEGABYTES(x)	((long long)(x) << 20)
 #define KILOBYTES(x)	((long long)(x) << 10)
 
-long long
-cvtnum(
-	char		*s)
-{
-	long long	i;
-	char		*sp;
-	int		c;
-
-	i = strtoll(s, &sp, 0);
-	if (i == 0 && sp == s)
-		return -1LL;
-	if (*sp == '\0')
-		return i;
-
-	if (sp[1] != '\0')
-		return -1LL;
-
-	c = qemu_tolower(*sp);
-	switch (c) {
-	default:
-		return i;
-	case 'k':
-		return KILOBYTES(i);
-	case 'm':
-		return MEGABYTES(i);
-	case 'g':
-		return GIGABYTES(i);
-	case 't':
-		return TERABYTES(i);
-	case 'p':
-		return PETABYTES(i);
-	case 'e':
-		return  EXABYTES(i);
-	}
-	return -1LL;
-}
-
 #define TO_EXABYTES(x)	((x) / EXABYTES(1))
 #define TO_PETABYTES(x)	((x) / PETABYTES(1))
 #define TO_TERABYTES(x)	((x) / TERABYTES(1))
diff --git a/cmd.h b/cmd.h
index 8e6f753..4dcfe88 100644
--- a/cmd.h
+++ b/cmd.h
@@ -58,7 +58,6 @@ char **breakline(char *input, int *count);
 void doneline(char *input, char **vec);
 char *fetchline(void);
 
-long long cvtnum(char *s);
 void cvtstr(double value, char *str, size_t sz);
 
 struct timeval tsub(struct timeval t1, struct timeval t2);
diff --git a/qemu-io.c b/qemu-io.c
index 4288b8c..8a719a8 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -29,6 +29,12 @@ static BlockDriverState *bs;
 
 static int misalign;
 
+static int64_t cvtnum(const char *s)
+{
+    char *end;
+    return strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
+}
+
 /*
  * Parse the pattern argument to various sub-commands.
  *
commit 5e00984aef7c1c317e27c0e8acf66526513c770f
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 14:19:27 2013 +0200

    cutils: Support 'P' and 'E' suffixes in strtosz()
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/include/qemu-common.h b/include/qemu-common.h
index cb82ef3..d95ea1e 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -191,6 +191,8 @@ int parse_uint_full(const char *s, unsigned long long *value, int base);
  * A-Z, as strtosz() will use qemu_toupper() on the given argument
  * prior to comparison.
  */
+#define STRTOSZ_DEFSUFFIX_EB	'E'
+#define STRTOSZ_DEFSUFFIX_PB	'P'
 #define STRTOSZ_DEFSUFFIX_TB	'T'
 #define STRTOSZ_DEFSUFFIX_GB	'G'
 #define STRTOSZ_DEFSUFFIX_MB	'M'
diff --git a/monitor.c b/monitor.c
index eefc7f0..9d279b8 100644
--- a/monitor.c
+++ b/monitor.c
@@ -93,10 +93,10 @@
  * 'M'          Non-negative target long (32 or 64 bit), in user mode the
  *              value is multiplied by 2^20 (think Mebibyte)
  * 'o'          octets (aka bytes)
- *              user mode accepts an optional T, t, G, g, M, m, K, k
- *              suffix, which multiplies the value by 2^40 for
- *              suffixes T and t, 2^30 for suffixes G and g, 2^20 for
- *              M and m, 2^10 for K and k
+ *              user mode accepts an optional E, e, P, p, T, t, G, g, M, m,
+ *              K, k suffix, which multiplies the value by 2^60 for suffixes E
+ *              and e, 2^50 for suffixes P and p, 2^40 for suffixes T and t,
+ *              2^30 for suffixes G and g, 2^20 for M and m, 2^10 for K and k
  * 'T'          double
  *              user mode accepts an optional ms, us, ns suffix,
  *              which divides the value by 1e3, 1e6, 1e9, respectively
diff --git a/qemu-img.c b/qemu-img.c
index 82c7977..e089c78 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -85,8 +85,9 @@ static void help(void)
            "    options are: 'none', 'writeback' (default, except for convert), 'writethrough',\n"
            "    'directsync' and 'unsafe' (default for convert)\n"
            "  'size' is the disk image size in bytes. Optional suffixes\n"
-           "    'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
-           "    and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
+           "    'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M),\n"
+           "    'T' (terabyte, 1024G), 'P' (petabyte, 1024T) and 'E' (exabyte, 1024P)  are\n"
+           "    supported. 'b' is ignored.\n"
            "  'output_filename' is the destination disk image filename\n"
            "  'output_fmt' is the destination format\n"
            "  'options' is a comma separated list of format specific options in a\n"
@@ -387,8 +388,9 @@ static int img_create(int argc, char **argv)
                 error_report("Image size must be less than 8 EiB!");
             } else {
                 error_report("Invalid image size specified! You may use k, M, "
-                      "G or T suffixes for ");
-                error_report("kilobytes, megabytes, gigabytes and terabytes.");
+                      "G, T, P or E suffixes for ");
+                error_report("kilobytes, megabytes, gigabytes, terabytes, "
+                             "petabytes and exabytes.");
             }
             return 1;
         }
diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out
index 72db13f..d2f0efe 100644
--- a/tests/qemu-iotests/049.out
+++ b/tests/qemu-iotests/049.out
@@ -108,15 +108,15 @@ qemu-img: Formatting or formatting option not supported for file format 'qcow2'
 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=-1024 encryption=off cluster_size=65536 lazy_refcounts=off 
 
 qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- 1kilobyte
-qemu-img: Invalid image size specified! You may use k, M, G or T suffixes for 
-qemu-img: kilobytes, megabytes, gigabytes and terabytes.
+qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suffixes for 
+qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
 
 qemu-img create -f qcow2 -o size=1kilobyte TEST_DIR/t.qcow2
 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off 
 
 qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- foobar
-qemu-img: Invalid image size specified! You may use k, M, G or T suffixes for 
-qemu-img: kilobytes, megabytes, gigabytes and terabytes.
+qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suffixes for 
+qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
 
 qemu-img create -f qcow2 -o size=foobar TEST_DIR/t.qcow2
 qemu-img: Parameter 'size' expects a size
diff --git a/util/cutils.c b/util/cutils.c
index a165819..8f28896 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -267,6 +267,10 @@ static int64_t suffix_mul(char suffix, int64_t unit)
         return unit * unit * unit;
     case STRTOSZ_DEFSUFFIX_TB:
         return unit * unit * unit * unit;
+    case STRTOSZ_DEFSUFFIX_PB:
+        return unit * unit * unit * unit * unit;
+    case STRTOSZ_DEFSUFFIX_EB:
+        return unit * unit * unit * unit * unit * unit;
     }
     return -1;
 }
commit a23818f4ff3d7981f49453b739f589e4205930b5
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Jun 5 14:19:26 2013 +0200

    qemu-io: Remove unused args_command
    
    The original intention seems to be something with handling multiple
    images at once, but this has never been implemented and the only
    function ever registered is implemented to make everything behave like a
    "global" command. Just do that unconditionally now.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/cmd.c b/cmd.c
index 10a8688..4e7579b 100644
--- a/cmd.c
+++ b/cmd.c
@@ -34,7 +34,6 @@
 cmdinfo_t	*cmdtab;
 int		ncmds;
 
-static argsfunc_t	args_func;
 static checkfunc_t	check_func;
 static int		ncmdline;
 static char		**cmdline;
@@ -127,22 +126,6 @@ void add_user_command(char *optarg)
     cmdline[ncmdline-1] = optarg;
 }
 
-static int
-args_command(
-	int	index)
-{
-	if (args_func)
-		return args_func(index);
-	return 0;
-}
-
-void
-add_args_command(
-	argsfunc_t	af)
-{
-	args_func = af;
-}
-
 static void prep_fetchline(void *opaque)
 {
     int *fetchable = opaque;
@@ -155,7 +138,7 @@ static char *get_prompt(void);
 
 void command_loop(void)
 {
-    int c, i, j = 0, done = 0, fetchable = 0, prompted = 0;
+    int c, i, done = 0, fetchable = 0, prompted = 0;
     char *input;
     char **v;
     const cmdinfo_t *ct;
@@ -171,14 +154,7 @@ void command_loop(void)
         if (c) {
             ct = find_command(v[0]);
             if (ct) {
-                if (ct->flags & CMD_FLAG_GLOBAL) {
-                    done = command(ct, c, v);
-                } else {
-                    j = 0;
-                    while (!done && (j = args_command(j))) {
-                        done = command(ct, c, v);
-                    }
-                }
+                done = command(ct, c, v);
             } else {
                 fprintf(stderr, _("command \"%s\" not found\n"), v[0]);
             }
diff --git a/cmd.h b/cmd.h
index b763b19..8e6f753 100644
--- a/cmd.h
+++ b/cmd.h
@@ -41,12 +41,10 @@ extern int		ncmds;
 void help_init(void);
 void quit_init(void);
 
-typedef int (*argsfunc_t)(int index);
 typedef int (*checkfunc_t)(const cmdinfo_t *ci);
 
 void add_command(const cmdinfo_t *ci);
 void add_user_command(char *optarg);
-void add_args_command(argsfunc_t af);
 void add_check_command(checkfunc_t cf);
 
 const cmdinfo_t *find_command(const char *cmd);
diff --git a/qemu-io.c b/qemu-io.c
index 5e6680b..4288b8c 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -1888,15 +1888,6 @@ static int open_f(int argc, char **argv)
     return openfile(argv[optind], flags, growable);
 }
 
-static int init_args_command(int index)
-{
-    /* only one device allowed so far */
-    if (index >= 1) {
-        return 0;
-    }
-    return ++index;
-}
-
 static int init_check_command(const cmdinfo_t *ct)
 {
     if (ct->flags & CMD_FLAG_GLOBAL) {
@@ -2043,7 +2034,6 @@ int main(int argc, char **argv)
     add_command(&wait_break_cmd);
     add_command(&abort_cmd);
 
-    add_args_command(init_args_command);
     add_check_command(init_check_command);
 
     /* open the device */
commit d1db1fa8dfcea9c62643f624f2a07d2fd375ce45
Author: Cornelia Huck <cornelia.huck at de.ibm.com>
Date:   Wed Jun 5 17:13:05 2013 +0200

    virtio-ccw: Fix unsetting of indicators.
    
    Interpretation of the ccws to register (configuration) indicators contained
    a thinko: We want to disallow reading from 0, but setting the indicator
    pointer to 0 is fine.
    
    Let's fix the handling for CCW_CMD_SET{,_CONF}_IND.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Cornelia Huck <cornelia.huck at de.ibm.com>

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 5f5e267..44f5772 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -328,10 +328,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
             ret = -EINVAL;
             break;
         }
-        indicators = ldq_phys(ccw.cda);
-        if (!indicators) {
+        if (!ccw.cda) {
             ret = -EFAULT;
         } else {
+            indicators = ldq_phys(ccw.cda);
             dev->indicators = indicators;
             sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
             ret = 0;
@@ -348,10 +348,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
             ret = -EINVAL;
             break;
         }
-        indicators = ldq_phys(ccw.cda);
-        if (!indicators) {
+        if (!ccw.cda) {
             ret = -EFAULT;
         } else {
+            indicators = ldq_phys(ccw.cda);
             dev->indicators2 = indicators;
             sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
             ret = 0;
commit 8312976e73fce9689ab831c1da565ec413680cff
Author: Cornelia Huck <cornelia.huck at de.ibm.com>
Date:   Wed Jun 5 16:54:05 2013 +0200

    s390x/css: Fix concurrent sense.
    
    Fix an off-by-one error when indicating availablity of concurrent
    sense data.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Cornelia Huck <cornelia.huck at de.ibm.com>

diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index e526a1c..f82abfe 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -777,7 +777,7 @@ int css_do_tsch(SubchDev *sch, IRB *target_irb)
             (p->chars & PMCW_CHARS_MASK_CSENSE)) {
             irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF | SCSW_FLAGS_MASK_ECTL;
             memcpy(irb.ecw, sch->sense_data, sizeof(sch->sense_data));
-            irb.esw[1] = 0x02000000 | (sizeof(sch->sense_data) << 8);
+            irb.esw[1] = 0x01000000 | (sizeof(sch->sense_data) << 8);
         }
     }
     /* Store the irb to the guest. */
commit 293c51a6ee369228633a8428ab689f14c045ff98
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Wed Jun 5 10:33:14 2013 +0200

    blockdev: reset werror/rerror on drive_del
    
    Paolo Bonzini <pbonzini at redhat.com> suggested the following test case:
    
    1. Launch a guest and wait at the GRUB boot menu:
    
      qemu-system-x86_64 -enable-kvm -m 1024 \
       -drive if=none,cache=none,file=test.img,id=foo,werror=stop,rerror=stop
       -device virtio-blk-pci,drive=foo,id=virtio0,addr=4
    
    2. Hot unplug the device:
    
      (qemu) drive_del foo
    
    3. Select the first boot menu entry
    
    Without this patch the guest pauses due to ENOMEDIUM.  The guest is
    stuck in a continuous pause loop since the I/O request is retried and
    fails immediately again when the guest is resumed.
    
    With this patch the error is reported to the guest.
    
    Note that this scenario actually happens sometimes during libvirt disk
    hot unplug, where device_del is followed by drive_del.  I/O may still be
    submitted to the drive after drive_del if the guest does not process the
    PCI hot unplug notification.
    
    Reported-by: Dafna Ron <dron at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/blockdev.c b/blockdev.c
index b9b2d10..9937311 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1180,6 +1180,10 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
      */
     if (bdrv_get_attached_dev(bs)) {
         bdrv_make_anon(bs);
+
+        /* Further I/O must not pause the guest */
+        bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT,
+                          BLOCKDEV_ON_ERROR_REPORT);
     } else {
         drive_uninit(drive_get_by_blockdev(bs));
     }
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 9cea415..4f5a3fd 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -185,6 +185,8 @@ Remove host block device.  The result is that guest generated IO is no longer
 submitted against the host device underlying the disk.  Once a drive has
 been deleted, the QEMU Block layer returns -EIO which results in IO
 errors in the guest for applications that are reading/writing to the device.
+These errors are always reported to the guest, regardless of the drive's error
+actions (drive options rerror, werror).
 ETEXI
 
     {
commit 56bbc2f967ce185fa1c5c39e1aeb5b68b26242e9
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Jun 4 09:53:19 2013 -0700

    tcg: Remove redundant tcg_target_init checks
    
    We've got a compile-time check for the condition in exec/cpu-defs.h.
    
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: liguang <lig.fnst at cn.fujitsu.com>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 3d43412..6be736b 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -2053,12 +2053,6 @@ static const TCGTargetOpDef arm_op_defs[] = {
 
 static void tcg_target_init(TCGContext *s)
 {
-#if !defined(CONFIG_USER_ONLY)
-    /* fail safe */
-    if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
-        tcg_abort();
-#endif
-
     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
     tcg_regset_set32(tcg_target_call_clobber_regs, 0,
                      (1 << TCG_REG_R0) |
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 9eec06c..9e95477 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -2283,12 +2283,6 @@ static void tcg_target_init(TCGContext *s)
     }
 #endif
 
-#if !defined(CONFIG_USER_ONLY)
-    /* fail safe */
-    if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
-        tcg_abort();
-#endif
-
     if (TCG_TARGET_REG_BITS == 64) {
         tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
         tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index 7d6f777..f229f1c 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -2324,13 +2324,6 @@ static void query_facilities(void)
 
 static void tcg_target_init(TCGContext *s)
 {
-#if !defined(CONFIG_USER_ONLY)
-    /* fail safe */
-    if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry)) {
-        tcg_abort();
-    }
-#endif
-
     query_facilities();
 
     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
commit e85ef5381a512d8f781b862e8b5f9d4cbf0ba494
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Jun 4 09:51:59 2013 -0700

    tcg: Use QEMU_BUILD_BUG_ON for CPU_TLB_ENTRY_BITS
    
    Rather than a hand-coded version of the same thing.
    
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: liguang <lig.fnst at cn.fujitsu.com>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index d8c64e9..2e5a9ba 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -99,7 +99,7 @@ typedef struct CPUTLBEntry {
                    sizeof(uintptr_t))];
 } CPUTLBEntry;
 
-extern int CPUTLBEntry_wrong_size[sizeof(CPUTLBEntry) == (1 << CPU_TLB_ENTRY_BITS) ? 1 : -1];
+QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
 
 #define CPU_COMMON_TLB \
     /* The meaning of the MMU modes is defined in the target code. */   \
commit 3ffee3cd5fb29de2115bdcbde0a02f47ce69a24c
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Tue Jun 4 14:47:26 2013 +0200

    vmxnet3: fix NICState cleanup
    
    Use qemu_del_nic() instead of qemu_del_net_client() to correctly free
    the entire NICState.
    
    Cc: qemu-stable at nongnu.org
    Reported-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index 5f483e7..4c575e5 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -1892,7 +1892,7 @@ static void vmxnet3_net_uninit(VMXNET3State *s)
     vmxnet_tx_pkt_reset(s->tx_pkt);
     vmxnet_tx_pkt_uninit(s->tx_pkt);
     vmxnet_rx_pkt_uninit(s->rx_pkt);
-    qemu_del_net_client(qemu_get_queue(s->nic));
+    qemu_del_nic(s->nic);
 }
 
 static void vmxnet3_net_init(VMXNET3State *s)
commit 8819c10b5d55d537d59a0ffd5d623f348fc36c47
Merge: a341619 9cdf79d
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Jun 4 14:58:58 2013 -0500

    Merge remote-tracking branch 'sstabellini/xen_fixes_20130603' into staging
    
    * sstabellini/xen_fixes_20130603:
      xen: use pc_init_pci instead of pc_init_pci_no_kvmclock
      xen: remove xen_vcpu_init
      xen: start PCI hole at 0xe0000000 (same as pc_init1 and qemu-xen-traditional)
      xen_machine_pv: do not create a dummy CPU in machine->init
      main_loop: do not set nonblocking if xen_enabled()
      xen: simplify xen_enabled
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit a3416197447e7846a927b6ccb4f1edb3a1982443
Merge: e47dccc 5b91704
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Jun 4 09:26:49 2013 -0500

    Merge remote-tracking branch 'kwolf/for-anthony' into staging
    
    # By Stefan Hajnoczi (6) and others
    # Via Kevin Wolf
    * kwolf/for-anthony:
      block: dump snapshot and image info to specified output
      block: move qmp and info dump related code to block/qapi.c
      block: move snapshot code in block.c to block/snapshot.c
      block: drop bs_snapshots global variable
      qemu-iotests: make create_image() common
      qemu-iotests: make compare_images() common
      qemu-iotests: make cancel_and_wait() common
      qemu-iotests: make assert_no_active_block_jobs() common
      block: add block driver read only whitelist
      qemu-iotests: fix 054 cluster size help output
    
    Message-id: 1370349940-4703-1-git-send-email-kwolf at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit e47dccc64b6ca570e4db96fd5fdb3bef251eb559
Merge: 1713924 c3c4fe3
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Jun 4 09:26:29 2013 -0500

    Merge remote-tracking branch 'mst/tags/for_anthony' into staging
    
    pci: misc cleanups
    
    This includes some pci-related cleanups,
    and fw cfg cleanups which will be useful for on-going
    pci related work.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    
    # gpg: Signature made Sun 02 Jun 2013 02:46:52 PM CDT using RSA key ID D28D5469
    # gpg: Can't check signature: public key not found
    
    # By Michael S. Tsirkin (8) and Laszlo Ersek (1)
    # Via Michael S. Tsirkin
    * mst/tags/for_anthony:
      pvpanic: use FWCfgState explicitly
      fw_cfg: fw_cfg is a singleton
      fw_cfg: add API to find FW cfg object
      fw_cfg: move typedef to qemu/typedefs.h
      refer to FWCfgState explicitly
      apic: rename apic specific bitopts
      firmware_abi: move to include/hw/nvram/
      dec.c - move to pci-bridge
      q35: set fw_name
    
    Message-id: 1370202787-3712-1-git-send-email-mst at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 5b91704469c0f801e0219f26458356872c4145ab
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Sat May 25 11:09:45 2013 +0800

    block: dump snapshot and image info to specified output
    
    bdrv_snapshot_dump() and bdrv_image_info_dump() do not dump to a buffer now,
    some internal buffers are still used for format control, which have no
    chance to be truncated. As a result, these two functions have no more issue
    of truncation, and they can be used by both qemu and qemu-img with correct
    parameter specified.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qapi.c b/block/qapi.c
index 155e77e..794dbf8 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -259,7 +259,8 @@ static char *get_human_readable_size(char *buf, int buf_size, int64_t size)
     return buf;
 }
 
-char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
+void bdrv_snapshot_dump(fprintf_function func_fprintf, void *f,
+                        QEMUSnapshotInfo *sn)
 {
     char buf1[128], date_buf[128], clock_buf[128];
     struct tm tm;
@@ -267,9 +268,9 @@ char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
     int64_t secs;
 
     if (!sn) {
-        snprintf(buf, buf_size,
-                 "%-10s%-20s%7s%20s%15s",
-                 "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
+        func_fprintf(f,
+                     "%-10s%-20s%7s%20s%15s",
+                     "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
     } else {
         ti = sn->date_sec;
         localtime_r(&ti, &tm);
@@ -282,17 +283,18 @@ char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
                  (int)((secs / 60) % 60),
                  (int)(secs % 60),
                  (int)((sn->vm_clock_nsec / 1000000) % 1000));
-        snprintf(buf, buf_size,
-                 "%-10s%-20s%7s%20s%15s",
-                 sn->id_str, sn->name,
-                 get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
-                 date_buf,
-                 clock_buf);
+        func_fprintf(f,
+                     "%-10s%-20s%7s%20s%15s",
+                     sn->id_str, sn->name,
+                     get_human_readable_size(buf1, sizeof(buf1),
+                                             sn->vm_state_size),
+                     date_buf,
+                     clock_buf);
     }
-    return buf;
 }
 
-void bdrv_image_info_dump(ImageInfo *info)
+void bdrv_image_info_dump(fprintf_function func_fprintf, void *f,
+                          ImageInfo *info)
 {
     char size_buf[128], dsize_buf[128];
     if (!info->has_actual_size) {
@@ -302,43 +304,46 @@ void bdrv_image_info_dump(ImageInfo *info)
                                 info->actual_size);
     }
     get_human_readable_size(size_buf, sizeof(size_buf), info->virtual_size);
-    printf("image: %s\n"
-           "file format: %s\n"
-           "virtual size: %s (%" PRId64 " bytes)\n"
-           "disk size: %s\n",
-           info->filename, info->format, size_buf,
-           info->virtual_size,
-           dsize_buf);
+    func_fprintf(f,
+                 "image: %s\n"
+                 "file format: %s\n"
+                 "virtual size: %s (%" PRId64 " bytes)\n"
+                 "disk size: %s\n",
+                 info->filename, info->format, size_buf,
+                 info->virtual_size,
+                 dsize_buf);
 
     if (info->has_encrypted && info->encrypted) {
-        printf("encrypted: yes\n");
+        func_fprintf(f, "encrypted: yes\n");
     }
 
     if (info->has_cluster_size) {
-        printf("cluster_size: %" PRId64 "\n", info->cluster_size);
+        func_fprintf(f, "cluster_size: %" PRId64 "\n",
+                       info->cluster_size);
     }
 
     if (info->has_dirty_flag && info->dirty_flag) {
-        printf("cleanly shut down: no\n");
+        func_fprintf(f, "cleanly shut down: no\n");
     }
 
     if (info->has_backing_filename) {
-        printf("backing file: %s", info->backing_filename);
+        func_fprintf(f, "backing file: %s", info->backing_filename);
         if (info->has_full_backing_filename) {
-            printf(" (actual path: %s)", info->full_backing_filename);
+            func_fprintf(f, " (actual path: %s)", info->full_backing_filename);
         }
-        putchar('\n');
+        func_fprintf(f, "\n");
         if (info->has_backing_filename_format) {
-            printf("backing file format: %s\n", info->backing_filename_format);
+            func_fprintf(f, "backing file format: %s\n",
+                         info->backing_filename_format);
         }
     }
 
     if (info->has_snapshots) {
         SnapshotInfoList *elem;
-        char buf[256];
 
-        printf("Snapshot list:\n");
-        printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
+        func_fprintf(f, "Snapshot list:\n");
+        bdrv_snapshot_dump(func_fprintf, f, NULL);
+        func_fprintf(f, "\n");
 
         /* Ideally bdrv_snapshot_dump() would operate on SnapshotInfoList but
          * we convert to the block layer's native QEMUSnapshotInfo for now.
@@ -354,7 +359,8 @@ void bdrv_image_info_dump(ImageInfo *info)
 
             pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id);
             pstrcpy(sn.name, sizeof(sn.name), elem->value->name);
-            printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), &sn));
+            bdrv_snapshot_dump(func_fprintf, f, &sn);
+            func_fprintf(f, "\n");
         }
     }
 }
diff --git a/include/block/qapi.h b/include/block/qapi.h
index 55d1848..e6e568d 100644
--- a/include/block/qapi.h
+++ b/include/block/qapi.h
@@ -36,6 +36,8 @@ void bdrv_collect_image_info(BlockDriverState *bs,
 BlockInfo *bdrv_query_info(BlockDriverState *s);
 BlockStats *bdrv_query_stats(const BlockDriverState *bs);
 
-char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn);
-void bdrv_image_info_dump(ImageInfo *info);
+void bdrv_snapshot_dump(fprintf_function func_fprintf, void *f,
+                        QEMUSnapshotInfo *sn);
+void bdrv_image_info_dump(fprintf_function func_fprintf, void *f,
+                          ImageInfo *info);
 #endif
diff --git a/qemu-img.c b/qemu-img.c
index 5d1e480..82c7977 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1554,16 +1554,17 @@ static void dump_snapshots(BlockDriverState *bs)
 {
     QEMUSnapshotInfo *sn_tab, *sn;
     int nb_sns, i;
-    char buf[256];
 
     nb_sns = bdrv_snapshot_list(bs, &sn_tab);
     if (nb_sns <= 0)
         return;
     printf("Snapshot list:\n");
-    printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
+    bdrv_snapshot_dump(fprintf, stdout, NULL);
+    printf("\n");
     for(i = 0; i < nb_sns; i++) {
         sn = &sn_tab[i];
-        printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
+        bdrv_snapshot_dump(fprintf, stdout, sn);
+        printf("\n");
     }
     g_free(sn_tab);
 }
@@ -1613,7 +1614,7 @@ static void dump_human_image_info_list(ImageInfoList *list)
         }
         delim = true;
 
-        bdrv_image_info_dump(elem->value);
+        bdrv_image_info_dump(fprintf, stdout, elem->value);
     }
 }
 
diff --git a/savevm.c b/savevm.c
index a886514..2ce439f 100644
--- a/savevm.c
+++ b/savevm.c
@@ -2540,7 +2540,6 @@ void do_info_snapshots(Monitor *mon, const QDict *qdict)
     int nb_sns, i, ret, available;
     int total;
     int *available_snapshots;
-    char buf[256];
 
     bs = find_vmstate_bs();
     if (!bs) {
@@ -2583,10 +2582,12 @@ void do_info_snapshots(Monitor *mon, const QDict *qdict)
     }
 
     if (total > 0) {
-        monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
+        bdrv_snapshot_dump((fprintf_function)monitor_printf, mon, NULL);
+        monitor_printf(mon, "\n");
         for (i = 0; i < total; i++) {
             sn = &sn_tab[available_snapshots[i]];
-            monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
+            bdrv_snapshot_dump((fprintf_function)monitor_printf, mon, sn);
+            monitor_printf(mon, "\n");
         }
     } else {
         monitor_printf(mon, "There is no suitable snapshot available\n");
commit f364ec65b56b69c55b674cb6560aa1fbbea9e013
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Sat May 25 11:09:44 2013 +0800

    block: move qmp and info dump related code to block/qapi.c
    
    This patch is a pure code move patch, except following modification:
    1 get_human_readable_size() is changed to static function.
    2 dump_human_image_info() is renamed to bdrv_image_info_dump().
    3 in qmp_query_block() and qmp_query_blockstats, use bdrv_next(bs)
    instead of direct traverse of global array 'bdrv_states'.
    4 collect_snapshots() and collect_image_info() are renamed, unused parameter
    *fmt in collect_image_info() is removed.
    5 code style fix.
    
    To avoid conflict and tip better, macro in header file is BLOCK_QAPI_H
    instead of QAPI_H. Now block.h and snapshot.h are at the same level in
    include path, block_int.h and qapi.h will both include them.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index 6212aae..3f616de 100644
--- a/block.c
+++ b/block.c
@@ -3100,128 +3100,6 @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
     return data.ret;
 }
 
-BlockInfo *bdrv_query_info(BlockDriverState *bs)
-{
-    BlockInfo *info = g_malloc0(sizeof(*info));
-    info->device = g_strdup(bs->device_name);
-    info->type = g_strdup("unknown");
-    info->locked = bdrv_dev_is_medium_locked(bs);
-    info->removable = bdrv_dev_has_removable_media(bs);
-
-    if (bdrv_dev_has_removable_media(bs)) {
-        info->has_tray_open = true;
-        info->tray_open = bdrv_dev_is_tray_open(bs);
-    }
-
-    if (bdrv_iostatus_is_enabled(bs)) {
-        info->has_io_status = true;
-        info->io_status = bs->iostatus;
-    }
-
-    if (bs->dirty_bitmap) {
-        info->has_dirty = true;
-        info->dirty = g_malloc0(sizeof(*info->dirty));
-        info->dirty->count = bdrv_get_dirty_count(bs) * BDRV_SECTOR_SIZE;
-        info->dirty->granularity =
-            ((int64_t) BDRV_SECTOR_SIZE << hbitmap_granularity(bs->dirty_bitmap));
-    }
-
-    if (bs->drv) {
-        info->has_inserted = true;
-        info->inserted = g_malloc0(sizeof(*info->inserted));
-        info->inserted->file = g_strdup(bs->filename);
-        info->inserted->ro = bs->read_only;
-        info->inserted->drv = g_strdup(bs->drv->format_name);
-        info->inserted->encrypted = bs->encrypted;
-        info->inserted->encryption_key_missing = bdrv_key_required(bs);
-
-        if (bs->backing_file[0]) {
-            info->inserted->has_backing_file = true;
-            info->inserted->backing_file = g_strdup(bs->backing_file);
-        }
-
-        info->inserted->backing_file_depth = bdrv_get_backing_file_depth(bs);
-
-        if (bs->io_limits_enabled) {
-            info->inserted->bps =
-                           bs->io_limits.bps[BLOCK_IO_LIMIT_TOTAL];
-            info->inserted->bps_rd =
-                           bs->io_limits.bps[BLOCK_IO_LIMIT_READ];
-            info->inserted->bps_wr =
-                           bs->io_limits.bps[BLOCK_IO_LIMIT_WRITE];
-            info->inserted->iops =
-                           bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL];
-            info->inserted->iops_rd =
-                           bs->io_limits.iops[BLOCK_IO_LIMIT_READ];
-            info->inserted->iops_wr =
-                           bs->io_limits.iops[BLOCK_IO_LIMIT_WRITE];
-        }
-    }
-    return info;
-}
-
-BlockInfoList *qmp_query_block(Error **errp)
-{
-    BlockInfoList *head = NULL, **p_next = &head;
-    BlockDriverState *bs;
-
-    QTAILQ_FOREACH(bs, &bdrv_states, list) {
-        BlockInfoList *info = g_malloc0(sizeof(*info));
-        info->value = bdrv_query_info(bs);
-
-        *p_next = info;
-        p_next = &info->next;
-    }
-
-    return head;
-}
-
-BlockStats *bdrv_query_stats(const BlockDriverState *bs)
-{
-    BlockStats *s;
-
-    s = g_malloc0(sizeof(*s));
-
-    if (bs->device_name[0]) {
-        s->has_device = true;
-        s->device = g_strdup(bs->device_name);
-    }
-
-    s->stats = g_malloc0(sizeof(*s->stats));
-    s->stats->rd_bytes = bs->nr_bytes[BDRV_ACCT_READ];
-    s->stats->wr_bytes = bs->nr_bytes[BDRV_ACCT_WRITE];
-    s->stats->rd_operations = bs->nr_ops[BDRV_ACCT_READ];
-    s->stats->wr_operations = bs->nr_ops[BDRV_ACCT_WRITE];
-    s->stats->wr_highest_offset = bs->wr_highest_sector * BDRV_SECTOR_SIZE;
-    s->stats->flush_operations = bs->nr_ops[BDRV_ACCT_FLUSH];
-    s->stats->wr_total_time_ns = bs->total_time_ns[BDRV_ACCT_WRITE];
-    s->stats->rd_total_time_ns = bs->total_time_ns[BDRV_ACCT_READ];
-    s->stats->flush_total_time_ns = bs->total_time_ns[BDRV_ACCT_FLUSH];
-
-    if (bs->file) {
-        s->has_parent = true;
-        s->parent = bdrv_query_stats(bs->file);
-    }
-
-    return s;
-}
-
-BlockStatsList *qmp_query_blockstats(Error **errp)
-{
-    BlockStatsList *head = NULL, **p_next = &head;
-    BlockDriverState *bs;
-
-    QTAILQ_FOREACH(bs, &bdrv_states, list) {
-        BlockStatsList *info = g_malloc0(sizeof(*info));
-        info->value = bdrv_query_stats(bs);
-
-        *p_next = info;
-        p_next = &info->next;
-    }
-
-    return head;
-}
-
 const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
 {
     if (bs->backing_hd && bs->backing_hd->encrypted)
@@ -3457,69 +3335,6 @@ BlockDriverState *bdrv_find_base(BlockDriverState *bs)
     return curr_bs;
 }
 
-#define NB_SUFFIXES 4
-
-char *get_human_readable_size(char *buf, int buf_size, int64_t size)
-{
-    static const char suffixes[NB_SUFFIXES] = "KMGT";
-    int64_t base;
-    int i;
-
-    if (size <= 999) {
-        snprintf(buf, buf_size, "%" PRId64, size);
-    } else {
-        base = 1024;
-        for(i = 0; i < NB_SUFFIXES; i++) {
-            if (size < (10 * base)) {
-                snprintf(buf, buf_size, "%0.1f%c",
-                         (double)size / base,
-                         suffixes[i]);
-                break;
-            } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
-                snprintf(buf, buf_size, "%" PRId64 "%c",
-                         ((size + (base >> 1)) / base),
-                         suffixes[i]);
-                break;
-            }
-            base = base * 1024;
-        }
-    }
-    return buf;
-}
-
-char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
-{
-    char buf1[128], date_buf[128], clock_buf[128];
-    struct tm tm;
-    time_t ti;
-    int64_t secs;
-
-    if (!sn) {
-        snprintf(buf, buf_size,
-                 "%-10s%-20s%7s%20s%15s",
-                 "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
-    } else {
-        ti = sn->date_sec;
-        localtime_r(&ti, &tm);
-        strftime(date_buf, sizeof(date_buf),
-                 "%Y-%m-%d %H:%M:%S", &tm);
-        secs = sn->vm_clock_nsec / 1000000000;
-        snprintf(clock_buf, sizeof(clock_buf),
-                 "%02d:%02d:%02d.%03d",
-                 (int)(secs / 3600),
-                 (int)((secs / 60) % 60),
-                 (int)(secs % 60),
-                 (int)((sn->vm_clock_nsec / 1000000) % 1000));
-        snprintf(buf, buf_size,
-                 "%-10s%-20s%7s%20s%15s",
-                 sn->id_str, sn->name,
-                 get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
-                 date_buf,
-                 clock_buf);
-    }
-    return buf;
-}
-
 /**************************************************************/
 /* async I/Os */
 
diff --git a/block/Makefile.objs b/block/Makefile.objs
index 8670999..2981654 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -4,7 +4,7 @@ block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
 block-obj-y += qed-check.o
 block-obj-y += vhdx.o
 block-obj-y += parallels.o blkdebug.o blkverify.o
-block-obj-y += snapshot.o
+block-obj-y += snapshot.o qapi.o
 block-obj-$(CONFIG_WIN32) += raw-win32.o win32-aio.o
 block-obj-$(CONFIG_POSIX) += raw-posix.o
 block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
diff --git a/block/qapi.c b/block/qapi.c
new file mode 100644
index 0000000..155e77e
--- /dev/null
+++ b/block/qapi.c
@@ -0,0 +1,360 @@
+/*
+ * Block layer qmp and info dump related functions
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "block/qapi.h"
+#include "block/block_int.h"
+#include "qmp-commands.h"
+
+void bdrv_collect_snapshots(BlockDriverState *bs , ImageInfo *info)
+{
+    int i, sn_count;
+    QEMUSnapshotInfo *sn_tab = NULL;
+    SnapshotInfoList *info_list, *cur_item = NULL;
+    sn_count = bdrv_snapshot_list(bs, &sn_tab);
+
+    for (i = 0; i < sn_count; i++) {
+        info->has_snapshots = true;
+        info_list = g_new0(SnapshotInfoList, 1);
+
+        info_list->value                = g_new0(SnapshotInfo, 1);
+        info_list->value->id            = g_strdup(sn_tab[i].id_str);
+        info_list->value->name          = g_strdup(sn_tab[i].name);
+        info_list->value->vm_state_size = sn_tab[i].vm_state_size;
+        info_list->value->date_sec      = sn_tab[i].date_sec;
+        info_list->value->date_nsec     = sn_tab[i].date_nsec;
+        info_list->value->vm_clock_sec  = sn_tab[i].vm_clock_nsec / 1000000000;
+        info_list->value->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000;
+
+        /* XXX: waiting for the qapi to support qemu-queue.h types */
+        if (!cur_item) {
+            info->snapshots = cur_item = info_list;
+        } else {
+            cur_item->next = info_list;
+            cur_item = info_list;
+        }
+
+    }
+
+    g_free(sn_tab);
+}
+
+void bdrv_collect_image_info(BlockDriverState *bs,
+                             ImageInfo *info,
+                             const char *filename)
+{
+    uint64_t total_sectors;
+    char backing_filename[1024];
+    char backing_filename2[1024];
+    BlockDriverInfo bdi;
+
+    bdrv_get_geometry(bs, &total_sectors);
+
+    info->filename        = g_strdup(filename);
+    info->format          = g_strdup(bdrv_get_format_name(bs));
+    info->virtual_size    = total_sectors * 512;
+    info->actual_size     = bdrv_get_allocated_file_size(bs);
+    info->has_actual_size = info->actual_size >= 0;
+    if (bdrv_is_encrypted(bs)) {
+        info->encrypted = true;
+        info->has_encrypted = true;
+    }
+    if (bdrv_get_info(bs, &bdi) >= 0) {
+        if (bdi.cluster_size != 0) {
+            info->cluster_size = bdi.cluster_size;
+            info->has_cluster_size = true;
+        }
+        info->dirty_flag = bdi.is_dirty;
+        info->has_dirty_flag = true;
+    }
+    bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
+    if (backing_filename[0] != '\0') {
+        info->backing_filename = g_strdup(backing_filename);
+        info->has_backing_filename = true;
+        bdrv_get_full_backing_filename(bs, backing_filename2,
+                                       sizeof(backing_filename2));
+
+        if (strcmp(backing_filename, backing_filename2) != 0) {
+            info->full_backing_filename =
+                        g_strdup(backing_filename2);
+            info->has_full_backing_filename = true;
+        }
+
+        if (bs->backing_format[0]) {
+            info->backing_filename_format = g_strdup(bs->backing_format);
+            info->has_backing_filename_format = true;
+        }
+    }
+}
+
+BlockInfo *bdrv_query_info(BlockDriverState *bs)
+{
+    BlockInfo *info = g_malloc0(sizeof(*info));
+    info->device = g_strdup(bs->device_name);
+    info->type = g_strdup("unknown");
+    info->locked = bdrv_dev_is_medium_locked(bs);
+    info->removable = bdrv_dev_has_removable_media(bs);
+
+    if (bdrv_dev_has_removable_media(bs)) {
+        info->has_tray_open = true;
+        info->tray_open = bdrv_dev_is_tray_open(bs);
+    }
+
+    if (bdrv_iostatus_is_enabled(bs)) {
+        info->has_io_status = true;
+        info->io_status = bs->iostatus;
+    }
+
+    if (bs->dirty_bitmap) {
+        info->has_dirty = true;
+        info->dirty = g_malloc0(sizeof(*info->dirty));
+        info->dirty->count = bdrv_get_dirty_count(bs) * BDRV_SECTOR_SIZE;
+        info->dirty->granularity =
+         ((int64_t) BDRV_SECTOR_SIZE << hbitmap_granularity(bs->dirty_bitmap));
+    }
+
+    if (bs->drv) {
+        info->has_inserted = true;
+        info->inserted = g_malloc0(sizeof(*info->inserted));
+        info->inserted->file = g_strdup(bs->filename);
+        info->inserted->ro = bs->read_only;
+        info->inserted->drv = g_strdup(bs->drv->format_name);
+        info->inserted->encrypted = bs->encrypted;
+        info->inserted->encryption_key_missing = bdrv_key_required(bs);
+
+        if (bs->backing_file[0]) {
+            info->inserted->has_backing_file = true;
+            info->inserted->backing_file = g_strdup(bs->backing_file);
+        }
+
+        info->inserted->backing_file_depth = bdrv_get_backing_file_depth(bs);
+
+        if (bs->io_limits_enabled) {
+            info->inserted->bps =
+                           bs->io_limits.bps[BLOCK_IO_LIMIT_TOTAL];
+            info->inserted->bps_rd =
+                           bs->io_limits.bps[BLOCK_IO_LIMIT_READ];
+            info->inserted->bps_wr =
+                           bs->io_limits.bps[BLOCK_IO_LIMIT_WRITE];
+            info->inserted->iops =
+                           bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL];
+            info->inserted->iops_rd =
+                           bs->io_limits.iops[BLOCK_IO_LIMIT_READ];
+            info->inserted->iops_wr =
+                           bs->io_limits.iops[BLOCK_IO_LIMIT_WRITE];
+        }
+    }
+    return info;
+}
+
+BlockStats *bdrv_query_stats(const BlockDriverState *bs)
+{
+    BlockStats *s;
+
+    s = g_malloc0(sizeof(*s));
+
+    if (bs->device_name[0]) {
+        s->has_device = true;
+        s->device = g_strdup(bs->device_name);
+    }
+
+    s->stats = g_malloc0(sizeof(*s->stats));
+    s->stats->rd_bytes = bs->nr_bytes[BDRV_ACCT_READ];
+    s->stats->wr_bytes = bs->nr_bytes[BDRV_ACCT_WRITE];
+    s->stats->rd_operations = bs->nr_ops[BDRV_ACCT_READ];
+    s->stats->wr_operations = bs->nr_ops[BDRV_ACCT_WRITE];
+    s->stats->wr_highest_offset = bs->wr_highest_sector * BDRV_SECTOR_SIZE;
+    s->stats->flush_operations = bs->nr_ops[BDRV_ACCT_FLUSH];
+    s->stats->wr_total_time_ns = bs->total_time_ns[BDRV_ACCT_WRITE];
+    s->stats->rd_total_time_ns = bs->total_time_ns[BDRV_ACCT_READ];
+    s->stats->flush_total_time_ns = bs->total_time_ns[BDRV_ACCT_FLUSH];
+
+    if (bs->file) {
+        s->has_parent = true;
+        s->parent = bdrv_query_stats(bs->file);
+    }
+
+    return s;
+}
+
+BlockInfoList *qmp_query_block(Error **errp)
+{
+    BlockInfoList *head = NULL, **p_next = &head;
+    BlockDriverState *bs = NULL;
+
+     while ((bs = bdrv_next(bs))) {
+        BlockInfoList *info = g_malloc0(sizeof(*info));
+        info->value = bdrv_query_info(bs);
+
+        *p_next = info;
+        p_next = &info->next;
+    }
+
+    return head;
+}
+
+BlockStatsList *qmp_query_blockstats(Error **errp)
+{
+    BlockStatsList *head = NULL, **p_next = &head;
+    BlockDriverState *bs = NULL;
+
+     while ((bs = bdrv_next(bs))) {
+        BlockStatsList *info = g_malloc0(sizeof(*info));
+        info->value = bdrv_query_stats(bs);
+
+        *p_next = info;
+        p_next = &info->next;
+    }
+
+    return head;
+}
+
+#define NB_SUFFIXES 4
+
+static char *get_human_readable_size(char *buf, int buf_size, int64_t size)
+{
+    static const char suffixes[NB_SUFFIXES] = "KMGT";
+    int64_t base;
+    int i;
+
+    if (size <= 999) {
+        snprintf(buf, buf_size, "%" PRId64, size);
+    } else {
+        base = 1024;
+        for (i = 0; i < NB_SUFFIXES; i++) {
+            if (size < (10 * base)) {
+                snprintf(buf, buf_size, "%0.1f%c",
+                         (double)size / base,
+                         suffixes[i]);
+                break;
+            } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
+                snprintf(buf, buf_size, "%" PRId64 "%c",
+                         ((size + (base >> 1)) / base),
+                         suffixes[i]);
+                break;
+            }
+            base = base * 1024;
+        }
+    }
+    return buf;
+}
+
+char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
+{
+    char buf1[128], date_buf[128], clock_buf[128];
+    struct tm tm;
+    time_t ti;
+    int64_t secs;
+
+    if (!sn) {
+        snprintf(buf, buf_size,
+                 "%-10s%-20s%7s%20s%15s",
+                 "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
+    } else {
+        ti = sn->date_sec;
+        localtime_r(&ti, &tm);
+        strftime(date_buf, sizeof(date_buf),
+                 "%Y-%m-%d %H:%M:%S", &tm);
+        secs = sn->vm_clock_nsec / 1000000000;
+        snprintf(clock_buf, sizeof(clock_buf),
+                 "%02d:%02d:%02d.%03d",
+                 (int)(secs / 3600),
+                 (int)((secs / 60) % 60),
+                 (int)(secs % 60),
+                 (int)((sn->vm_clock_nsec / 1000000) % 1000));
+        snprintf(buf, buf_size,
+                 "%-10s%-20s%7s%20s%15s",
+                 sn->id_str, sn->name,
+                 get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
+                 date_buf,
+                 clock_buf);
+    }
+    return buf;
+}
+
+void bdrv_image_info_dump(ImageInfo *info)
+{
+    char size_buf[128], dsize_buf[128];
+    if (!info->has_actual_size) {
+        snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
+    } else {
+        get_human_readable_size(dsize_buf, sizeof(dsize_buf),
+                                info->actual_size);
+    }
+    get_human_readable_size(size_buf, sizeof(size_buf), info->virtual_size);
+    printf("image: %s\n"
+           "file format: %s\n"
+           "virtual size: %s (%" PRId64 " bytes)\n"
+           "disk size: %s\n",
+           info->filename, info->format, size_buf,
+           info->virtual_size,
+           dsize_buf);
+
+    if (info->has_encrypted && info->encrypted) {
+        printf("encrypted: yes\n");
+    }
+
+    if (info->has_cluster_size) {
+        printf("cluster_size: %" PRId64 "\n", info->cluster_size);
+    }
+
+    if (info->has_dirty_flag && info->dirty_flag) {
+        printf("cleanly shut down: no\n");
+    }
+
+    if (info->has_backing_filename) {
+        printf("backing file: %s", info->backing_filename);
+        if (info->has_full_backing_filename) {
+            printf(" (actual path: %s)", info->full_backing_filename);
+        }
+        putchar('\n');
+        if (info->has_backing_filename_format) {
+            printf("backing file format: %s\n", info->backing_filename_format);
+        }
+    }
+
+    if (info->has_snapshots) {
+        SnapshotInfoList *elem;
+        char buf[256];
+
+        printf("Snapshot list:\n");
+        printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
+
+        /* Ideally bdrv_snapshot_dump() would operate on SnapshotInfoList but
+         * we convert to the block layer's native QEMUSnapshotInfo for now.
+         */
+        for (elem = info->snapshots; elem; elem = elem->next) {
+            QEMUSnapshotInfo sn = {
+                .vm_state_size = elem->value->vm_state_size,
+                .date_sec = elem->value->date_sec,
+                .date_nsec = elem->value->date_nsec,
+                .vm_clock_nsec = elem->value->vm_clock_sec * 1000000000ULL +
+                                 elem->value->vm_clock_nsec,
+            };
+
+            pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id);
+            pstrcpy(sn.name, sizeof(sn.name), elem->value->name);
+            printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), &sn));
+        }
+    }
+}
diff --git a/include/block/block.h b/include/block/block.h
index a50a75f..dc5b388 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -7,11 +7,6 @@
 #include "block/coroutine.h"
 #include "qapi/qmp/qobject.h"
 #include "qapi-types.h"
-/*
- * snapshot.h is needed since bdrv_snapshot_dump(), it can be removed when the
- * function is moved to other file.
- */
-#include "block/snapshot.h"
 
 /* block.c */
 typedef struct BlockDriver BlockDriver;
@@ -323,12 +318,8 @@ void bdrv_get_backing_filename(BlockDriverState *bs,
                                char *filename, int filename_size);
 void bdrv_get_full_backing_filename(BlockDriverState *bs,
                                     char *dest, size_t sz);
-BlockInfo *bdrv_query_info(BlockDriverState *s);
-BlockStats *bdrv_query_stats(const BlockDriverState *bs);
 int bdrv_is_snapshot(BlockDriverState *bs);
-char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn);
 
-char *get_human_readable_size(char *buf, int buf_size, int64_t size);
 int path_is_absolute(const char *path);
 void path_combine(char *dest, int dest_size,
                   const char *base_path,
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 6078dd3..ba52247 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -33,6 +33,7 @@
 #include "qapi/qmp/qerror.h"
 #include "monitor/monitor.h"
 #include "qemu/hbitmap.h"
+#include "block/snapshot.h"
 
 #define BLOCK_FLAG_ENCRYPT          1
 #define BLOCK_FLAG_COMPAT6          4
diff --git a/include/block/qapi.h b/include/block/qapi.h
new file mode 100644
index 0000000..55d1848
--- /dev/null
+++ b/include/block/qapi.h
@@ -0,0 +1,41 @@
+/*
+ * Block layer qmp and info dump related functions
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef BLOCK_QAPI_H
+#define BLOCK_QAPI_H
+
+#include "qapi-types.h"
+#include "block/block.h"
+#include "block/snapshot.h"
+
+void bdrv_collect_snapshots(BlockDriverState *bs , ImageInfo *info);
+void bdrv_collect_image_info(BlockDriverState *bs,
+                             ImageInfo *info,
+                             const char *filename);
+BlockInfo *bdrv_query_info(BlockDriverState *s);
+BlockStats *bdrv_query_stats(const BlockDriverState *bs);
+
+char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn);
+void bdrv_image_info_dump(ImageInfo *info);
+#endif
diff --git a/qemu-img.c b/qemu-img.c
index cd096a1..5d1e480 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -30,6 +30,7 @@
 #include "qemu/osdep.h"
 #include "sysemu/sysemu.h"
 #include "block/block_int.h"
+#include "block/qapi.h"
 #include <getopt.h>
 #include <stdio.h>
 #include <stdarg.h>
@@ -1584,39 +1585,6 @@ static void dump_json_image_info_list(ImageInfoList *list)
     QDECREF(str);
 }
 
-static void collect_snapshots(BlockDriverState *bs , ImageInfo *info)
-{
-    int i, sn_count;
-    QEMUSnapshotInfo *sn_tab = NULL;
-    SnapshotInfoList *info_list, *cur_item = NULL;
-    sn_count = bdrv_snapshot_list(bs, &sn_tab);
-
-    for (i = 0; i < sn_count; i++) {
-        info->has_snapshots = true;
-        info_list = g_new0(SnapshotInfoList, 1);
-
-        info_list->value                = g_new0(SnapshotInfo, 1);
-        info_list->value->id            = g_strdup(sn_tab[i].id_str);
-        info_list->value->name          = g_strdup(sn_tab[i].name);
-        info_list->value->vm_state_size = sn_tab[i].vm_state_size;
-        info_list->value->date_sec      = sn_tab[i].date_sec;
-        info_list->value->date_nsec     = sn_tab[i].date_nsec;
-        info_list->value->vm_clock_sec  = sn_tab[i].vm_clock_nsec / 1000000000;
-        info_list->value->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000;
-
-        /* XXX: waiting for the qapi to support qemu-queue.h types */
-        if (!cur_item) {
-            info->snapshots = cur_item = info_list;
-        } else {
-            cur_item->next = info_list;
-            cur_item = info_list;
-        }
-
-    }
-
-    g_free(sn_tab);
-}
-
 static void dump_json_image_info(ImageInfo *info)
 {
     Error *errp = NULL;
@@ -1634,122 +1602,6 @@ static void dump_json_image_info(ImageInfo *info)
     QDECREF(str);
 }
 
-static void collect_image_info(BlockDriverState *bs,
-                   ImageInfo *info,
-                   const char *filename,
-                   const char *fmt)
-{
-    uint64_t total_sectors;
-    char backing_filename[1024];
-    char backing_filename2[1024];
-    BlockDriverInfo bdi;
-
-    bdrv_get_geometry(bs, &total_sectors);
-
-    info->filename        = g_strdup(filename);
-    info->format          = g_strdup(bdrv_get_format_name(bs));
-    info->virtual_size    = total_sectors * 512;
-    info->actual_size     = bdrv_get_allocated_file_size(bs);
-    info->has_actual_size = info->actual_size >= 0;
-    if (bdrv_is_encrypted(bs)) {
-        info->encrypted = true;
-        info->has_encrypted = true;
-    }
-    if (bdrv_get_info(bs, &bdi) >= 0) {
-        if (bdi.cluster_size != 0) {
-            info->cluster_size = bdi.cluster_size;
-            info->has_cluster_size = true;
-        }
-        info->dirty_flag = bdi.is_dirty;
-        info->has_dirty_flag = true;
-    }
-    bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
-    if (backing_filename[0] != '\0') {
-        info->backing_filename = g_strdup(backing_filename);
-        info->has_backing_filename = true;
-        bdrv_get_full_backing_filename(bs, backing_filename2,
-                                       sizeof(backing_filename2));
-
-        if (strcmp(backing_filename, backing_filename2) != 0) {
-            info->full_backing_filename =
-                        g_strdup(backing_filename2);
-            info->has_full_backing_filename = true;
-        }
-
-        if (bs->backing_format[0]) {
-            info->backing_filename_format = g_strdup(bs->backing_format);
-            info->has_backing_filename_format = true;
-        }
-    }
-}
-
-static void dump_human_image_info(ImageInfo *info)
-{
-    char size_buf[128], dsize_buf[128];
-    if (!info->has_actual_size) {
-        snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
-    } else {
-        get_human_readable_size(dsize_buf, sizeof(dsize_buf),
-                                info->actual_size);
-    }
-    get_human_readable_size(size_buf, sizeof(size_buf), info->virtual_size);
-    printf("image: %s\n"
-           "file format: %s\n"
-           "virtual size: %s (%" PRId64 " bytes)\n"
-           "disk size: %s\n",
-           info->filename, info->format, size_buf,
-           info->virtual_size,
-           dsize_buf);
-
-    if (info->has_encrypted && info->encrypted) {
-        printf("encrypted: yes\n");
-    }
-
-    if (info->has_cluster_size) {
-        printf("cluster_size: %" PRId64 "\n", info->cluster_size);
-    }
-
-    if (info->has_dirty_flag && info->dirty_flag) {
-        printf("cleanly shut down: no\n");
-    }
-
-    if (info->has_backing_filename) {
-        printf("backing file: %s", info->backing_filename);
-        if (info->has_full_backing_filename) {
-            printf(" (actual path: %s)", info->full_backing_filename);
-        }
-        putchar('\n');
-        if (info->has_backing_filename_format) {
-            printf("backing file format: %s\n", info->backing_filename_format);
-        }
-    }
-
-    if (info->has_snapshots) {
-        SnapshotInfoList *elem;
-        char buf[256];
-
-        printf("Snapshot list:\n");
-        printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
-
-        /* Ideally bdrv_snapshot_dump() would operate on SnapshotInfoList but
-         * we convert to the block layer's native QEMUSnapshotInfo for now.
-         */
-        for (elem = info->snapshots; elem; elem = elem->next) {
-            QEMUSnapshotInfo sn = {
-                .vm_state_size = elem->value->vm_state_size,
-                .date_sec = elem->value->date_sec,
-                .date_nsec = elem->value->date_nsec,
-                .vm_clock_nsec = elem->value->vm_clock_sec * 1000000000ULL +
-                                 elem->value->vm_clock_nsec,
-            };
-
-            pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id);
-            pstrcpy(sn.name, sizeof(sn.name), elem->value->name);
-            printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), &sn));
-        }
-    }
-}
-
 static void dump_human_image_info_list(ImageInfoList *list)
 {
     ImageInfoList *elem;
@@ -1761,7 +1613,7 @@ static void dump_human_image_info_list(ImageInfoList *list)
         }
         delim = true;
 
-        dump_human_image_info(elem->value);
+        bdrv_image_info_dump(elem->value);
     }
 }
 
@@ -1811,8 +1663,8 @@ static ImageInfoList *collect_image_info_list(const char *filename,
         }
 
         info = g_new0(ImageInfo, 1);
-        collect_image_info(bs, info, filename, fmt);
-        collect_snapshots(bs, info);
+        bdrv_collect_image_info(bs, info, filename);
+        bdrv_collect_snapshots(bs, info);
 
         elem = g_new0(ImageInfoList, 1);
         elem->value = info;
diff --git a/savevm.c b/savevm.c
index 916080d..a886514 100644
--- a/savevm.c
+++ b/savevm.c
@@ -41,6 +41,7 @@
 #include "qemu/bitops.h"
 #include "qemu/iov.h"
 #include "block/snapshot.h"
+#include "block/qapi.h"
 
 #define SELF_ANNOUNCE_ROUNDS 5
 
commit de08c606f9ddafe647b6843e2b10a6d6030b0fc0
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Sat May 25 11:09:43 2013 +0800

    block: move snapshot code in block.c to block/snapshot.c
    
    All snapshot related code, except bdrv_snapshot_dump() and
    bdrv_is_snapshot(), is moved to block/snapshot.c. bdrv_snapshot_dump()
    will be moved to another file later. bdrv_is_snapshot() is not related
    with internal snapshot. It also fixes small code style errors reported
    by check script.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index e046a31..6212aae 100644
--- a/block.c
+++ b/block.c
@@ -3357,111 +3357,11 @@ bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag)
     return false;
 }
 
-/**************************************************************/
-/* handling of snapshots */
-
-int bdrv_can_snapshot(BlockDriverState *bs)
-{
-    BlockDriver *drv = bs->drv;
-    if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
-        return 0;
-    }
-
-    if (!drv->bdrv_snapshot_create) {
-        if (bs->file != NULL) {
-            return bdrv_can_snapshot(bs->file);
-        }
-        return 0;
-    }
-
-    return 1;
-}
-
 int bdrv_is_snapshot(BlockDriverState *bs)
 {
     return !!(bs->open_flags & BDRV_O_SNAPSHOT);
 }
 
-int bdrv_snapshot_create(BlockDriverState *bs,
-                         QEMUSnapshotInfo *sn_info)
-{
-    BlockDriver *drv = bs->drv;
-    if (!drv)
-        return -ENOMEDIUM;
-    if (drv->bdrv_snapshot_create)
-        return drv->bdrv_snapshot_create(bs, sn_info);
-    if (bs->file)
-        return bdrv_snapshot_create(bs->file, sn_info);
-    return -ENOTSUP;
-}
-
-int bdrv_snapshot_goto(BlockDriverState *bs,
-                       const char *snapshot_id)
-{
-    BlockDriver *drv = bs->drv;
-    int ret, open_ret;
-
-    if (!drv)
-        return -ENOMEDIUM;
-    if (drv->bdrv_snapshot_goto)
-        return drv->bdrv_snapshot_goto(bs, snapshot_id);
-
-    if (bs->file) {
-        drv->bdrv_close(bs);
-        ret = bdrv_snapshot_goto(bs->file, snapshot_id);
-        open_ret = drv->bdrv_open(bs, NULL, bs->open_flags);
-        if (open_ret < 0) {
-            bdrv_delete(bs->file);
-            bs->drv = NULL;
-            return open_ret;
-        }
-        return ret;
-    }
-
-    return -ENOTSUP;
-}
-
-int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
-{
-    BlockDriver *drv = bs->drv;
-    if (!drv)
-        return -ENOMEDIUM;
-    if (drv->bdrv_snapshot_delete)
-        return drv->bdrv_snapshot_delete(bs, snapshot_id);
-    if (bs->file)
-        return bdrv_snapshot_delete(bs->file, snapshot_id);
-    return -ENOTSUP;
-}
-
-int bdrv_snapshot_list(BlockDriverState *bs,
-                       QEMUSnapshotInfo **psn_info)
-{
-    BlockDriver *drv = bs->drv;
-    if (!drv)
-        return -ENOMEDIUM;
-    if (drv->bdrv_snapshot_list)
-        return drv->bdrv_snapshot_list(bs, psn_info);
-    if (bs->file)
-        return bdrv_snapshot_list(bs->file, psn_info);
-    return -ENOTSUP;
-}
-
-int bdrv_snapshot_load_tmp(BlockDriverState *bs,
-        const char *snapshot_name)
-{
-    BlockDriver *drv = bs->drv;
-    if (!drv) {
-        return -ENOMEDIUM;
-    }
-    if (!bs->read_only) {
-        return -EINVAL;
-    }
-    if (drv->bdrv_snapshot_load_tmp) {
-        return drv->bdrv_snapshot_load_tmp(bs, snapshot_name);
-    }
-    return -ENOTSUP;
-}
-
 /* backing_file can either be relative, or absolute, or a protocol.  If it is
  * relative, it must be relative to the chain.  So, passing in bs->filename
  * from a BDS as backing_file should not be done, as that may be relative to
diff --git a/block/Makefile.objs b/block/Makefile.objs
index 5f0358a..8670999 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -4,6 +4,7 @@ block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
 block-obj-y += qed-check.o
 block-obj-y += vhdx.o
 block-obj-y += parallels.o blkdebug.o blkverify.o
+block-obj-y += snapshot.o
 block-obj-$(CONFIG_WIN32) += raw-win32.o win32-aio.o
 block-obj-$(CONFIG_POSIX) += raw-posix.o
 block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
diff --git a/block/snapshot.c b/block/snapshot.c
new file mode 100644
index 0000000..6c6d9de
--- /dev/null
+++ b/block/snapshot.c
@@ -0,0 +1,157 @@
+/*
+ * Block layer snapshot related functions
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "block/snapshot.h"
+#include "block/block_int.h"
+
+int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
+                       const char *name)
+{
+    QEMUSnapshotInfo *sn_tab, *sn;
+    int nb_sns, i, ret;
+
+    ret = -ENOENT;
+    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
+    if (nb_sns < 0) {
+        return ret;
+    }
+    for (i = 0; i < nb_sns; i++) {
+        sn = &sn_tab[i];
+        if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
+            *sn_info = *sn;
+            ret = 0;
+            break;
+        }
+    }
+    g_free(sn_tab);
+    return ret;
+}
+
+int bdrv_can_snapshot(BlockDriverState *bs)
+{
+    BlockDriver *drv = bs->drv;
+    if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
+        return 0;
+    }
+
+    if (!drv->bdrv_snapshot_create) {
+        if (bs->file != NULL) {
+            return bdrv_can_snapshot(bs->file);
+        }
+        return 0;
+    }
+
+    return 1;
+}
+
+int bdrv_snapshot_create(BlockDriverState *bs,
+                         QEMUSnapshotInfo *sn_info)
+{
+    BlockDriver *drv = bs->drv;
+    if (!drv) {
+        return -ENOMEDIUM;
+    }
+    if (drv->bdrv_snapshot_create) {
+        return drv->bdrv_snapshot_create(bs, sn_info);
+    }
+    if (bs->file) {
+        return bdrv_snapshot_create(bs->file, sn_info);
+    }
+    return -ENOTSUP;
+}
+
+int bdrv_snapshot_goto(BlockDriverState *bs,
+                       const char *snapshot_id)
+{
+    BlockDriver *drv = bs->drv;
+    int ret, open_ret;
+
+    if (!drv) {
+        return -ENOMEDIUM;
+    }
+    if (drv->bdrv_snapshot_goto) {
+        return drv->bdrv_snapshot_goto(bs, snapshot_id);
+    }
+
+    if (bs->file) {
+        drv->bdrv_close(bs);
+        ret = bdrv_snapshot_goto(bs->file, snapshot_id);
+        open_ret = drv->bdrv_open(bs, NULL, bs->open_flags);
+        if (open_ret < 0) {
+            bdrv_delete(bs->file);
+            bs->drv = NULL;
+            return open_ret;
+        }
+        return ret;
+    }
+
+    return -ENOTSUP;
+}
+
+int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
+{
+    BlockDriver *drv = bs->drv;
+    if (!drv) {
+        return -ENOMEDIUM;
+    }
+    if (drv->bdrv_snapshot_delete) {
+        return drv->bdrv_snapshot_delete(bs, snapshot_id);
+    }
+    if (bs->file) {
+        return bdrv_snapshot_delete(bs->file, snapshot_id);
+    }
+    return -ENOTSUP;
+}
+
+int bdrv_snapshot_list(BlockDriverState *bs,
+                       QEMUSnapshotInfo **psn_info)
+{
+    BlockDriver *drv = bs->drv;
+    if (!drv) {
+        return -ENOMEDIUM;
+    }
+    if (drv->bdrv_snapshot_list) {
+        return drv->bdrv_snapshot_list(bs, psn_info);
+    }
+    if (bs->file) {
+        return bdrv_snapshot_list(bs->file, psn_info);
+    }
+    return -ENOTSUP;
+}
+
+int bdrv_snapshot_load_tmp(BlockDriverState *bs,
+        const char *snapshot_name)
+{
+    BlockDriver *drv = bs->drv;
+    if (!drv) {
+        return -ENOMEDIUM;
+    }
+    if (!bs->read_only) {
+        return -EINVAL;
+    }
+    if (drv->bdrv_snapshot_load_tmp) {
+        return drv->bdrv_snapshot_load_tmp(bs, snapshot_name);
+    }
+    return -ENOTSUP;
+}
diff --git a/include/block/block.h b/include/block/block.h
index 8965536..a50a75f 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -7,6 +7,11 @@
 #include "block/coroutine.h"
 #include "qapi/qmp/qobject.h"
 #include "qapi-types.h"
+/*
+ * snapshot.h is needed since bdrv_snapshot_dump(), it can be removed when the
+ * function is moved to other file.
+ */
+#include "block/snapshot.h"
 
 /* block.c */
 typedef struct BlockDriver BlockDriver;
@@ -27,17 +32,6 @@ typedef struct BlockFragInfo {
     uint64_t compressed_clusters;
 } BlockFragInfo;
 
-typedef struct QEMUSnapshotInfo {
-    char id_str[128]; /* unique snapshot id */
-    /* the following fields are informative. They are not needed for
-       the consistency of the snapshot */
-    char name[256]; /* user chosen name */
-    uint64_t vm_state_size; /* VM state info size */
-    uint32_t date_sec; /* UTC date of the snapshot */
-    uint32_t date_nsec;
-    uint64_t vm_clock_nsec; /* VM clock relative to boot */
-} QEMUSnapshotInfo;
-
 /* Callbacks for block device models */
 typedef struct BlockDevOps {
     /*
@@ -331,17 +325,7 @@ void bdrv_get_full_backing_filename(BlockDriverState *bs,
                                     char *dest, size_t sz);
 BlockInfo *bdrv_query_info(BlockDriverState *s);
 BlockStats *bdrv_query_stats(const BlockDriverState *bs);
-int bdrv_can_snapshot(BlockDriverState *bs);
 int bdrv_is_snapshot(BlockDriverState *bs);
-int bdrv_snapshot_create(BlockDriverState *bs,
-                         QEMUSnapshotInfo *sn_info);
-int bdrv_snapshot_goto(BlockDriverState *bs,
-                       const char *snapshot_id);
-int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
-int bdrv_snapshot_list(BlockDriverState *bs,
-                       QEMUSnapshotInfo **psn_info);
-int bdrv_snapshot_load_tmp(BlockDriverState *bs,
-                           const char *snapshot_name);
 char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn);
 
 char *get_human_readable_size(char *buf, int buf_size, int64_t size);
diff --git a/include/block/snapshot.h b/include/block/snapshot.h
new file mode 100644
index 0000000..eaf61f0
--- /dev/null
+++ b/include/block/snapshot.h
@@ -0,0 +1,53 @@
+/*
+ * Block layer snapshot related functions
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef SNAPSHOT_H
+#define SNAPSHOT_H
+
+#include "qemu-common.h"
+
+typedef struct QEMUSnapshotInfo {
+    char id_str[128]; /* unique snapshot id */
+    /* the following fields are informative. They are not needed for
+       the consistency of the snapshot */
+    char name[256]; /* user chosen name */
+    uint64_t vm_state_size; /* VM state info size */
+    uint32_t date_sec; /* UTC date of the snapshot */
+    uint32_t date_nsec;
+    uint64_t vm_clock_nsec; /* VM clock relative to boot */
+} QEMUSnapshotInfo;
+
+int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
+                       const char *name);
+int bdrv_can_snapshot(BlockDriverState *bs);
+int bdrv_snapshot_create(BlockDriverState *bs,
+                         QEMUSnapshotInfo *sn_info);
+int bdrv_snapshot_goto(BlockDriverState *bs,
+                       const char *snapshot_id);
+int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
+int bdrv_snapshot_list(BlockDriverState *bs,
+                       QEMUSnapshotInfo **psn_info);
+int bdrv_snapshot_load_tmp(BlockDriverState *bs,
+                           const char *snapshot_name);
+#endif
diff --git a/savevm.c b/savevm.c
index b11dbf6..916080d 100644
--- a/savevm.c
+++ b/savevm.c
@@ -40,6 +40,7 @@
 #include "trace.h"
 #include "qemu/bitops.h"
 #include "qemu/iov.h"
+#include "block/snapshot.h"
 
 #define SELF_ANNOUNCE_ROUNDS 5
 
@@ -2273,28 +2274,6 @@ static BlockDriverState *find_vmstate_bs(void)
     return NULL;
 }
 
-static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
-                              const char *name)
-{
-    QEMUSnapshotInfo *sn_tab, *sn;
-    int nb_sns, i, ret;
-
-    ret = -ENOENT;
-    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
-    if (nb_sns < 0)
-        return ret;
-    for(i = 0; i < nb_sns; i++) {
-        sn = &sn_tab[i];
-        if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
-            *sn_info = *sn;
-            ret = 0;
-            break;
-        }
-    }
-    g_free(sn_tab);
-    return ret;
-}
-
 /*
  * Deletes snapshots of a given name in all opened images.
  */
commit 29d782710f87f01991bfc85cd9bef7d15280a5e2
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Sat May 25 11:09:42 2013 +0800

    block: drop bs_snapshots global variable
    
    The bs_snapshots global variable points to the BlockDriverState which
    will be used to save vmstate.  This is really a savevm.c concept but was
    moved into block.c:bdrv_snapshots() when it became clear that hotplug
    could result in a dangling pointer.
    
    While auditing the block layer's global state I came upon bs_snapshots
    and realized that a variable is not necessary here.  Simply find the
    first BlockDriverState capable of internal snapshots each time this is
    needed.
    
    The behavior of bdrv_snapshots() is preserved across hotplug because new
    drives are always appended to the bdrv_states list.  This means that
    calling the new find_vmstate_bs() function is idempotent - it returns
    the same BlockDriverState unless it was hot-unplugged.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Reviewed-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index 65c0b60..e046a31 100644
--- a/block.c
+++ b/block.c
@@ -99,9 +99,6 @@ static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
 static QLIST_HEAD(, BlockDriver) bdrv_drivers =
     QLIST_HEAD_INITIALIZER(bdrv_drivers);
 
-/* The device to use for VM snapshots */
-static BlockDriverState *bs_snapshots;
-
 /* If non-zero, use only whitelisted block drivers */
 static int use_bdrv_whitelist;
 
@@ -1368,9 +1365,6 @@ void bdrv_close(BlockDriverState *bs)
     notifier_list_notify(&bs->close_notifiers, bs);
 
     if (bs->drv) {
-        if (bs == bs_snapshots) {
-            bs_snapshots = NULL;
-        }
         if (bs->backing_hd) {
             bdrv_delete(bs->backing_hd);
             bs->backing_hd = NULL;
@@ -1602,7 +1596,6 @@ void bdrv_delete(BlockDriverState *bs)
 
     bdrv_close(bs);
 
-    assert(bs != bs_snapshots);
     g_free(bs);
 }
 
@@ -1646,9 +1639,6 @@ void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
 {
     bs->dev_ops = ops;
     bs->dev_opaque = opaque;
-    if (bdrv_dev_has_removable_media(bs) && bs == bs_snapshots) {
-        bs_snapshots = NULL;
-    }
 }
 
 void bdrv_emit_qmp_error_event(const BlockDriverState *bdrv,
@@ -3392,24 +3382,6 @@ int bdrv_is_snapshot(BlockDriverState *bs)
     return !!(bs->open_flags & BDRV_O_SNAPSHOT);
 }
 
-BlockDriverState *bdrv_snapshots(void)
-{
-    BlockDriverState *bs;
-
-    if (bs_snapshots) {
-        return bs_snapshots;
-    }
-
-    bs = NULL;
-    while ((bs = bdrv_next(bs))) {
-        if (bdrv_can_snapshot(bs)) {
-            bs_snapshots = bs;
-            return bs;
-        }
-    }
-    return NULL;
-}
-
 int bdrv_snapshot_create(BlockDriverState *bs,
                          QEMUSnapshotInfo *sn_info)
 {
diff --git a/include/block/block.h b/include/block/block.h
index 5604418..8965536 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -333,7 +333,6 @@ BlockInfo *bdrv_query_info(BlockDriverState *s);
 BlockStats *bdrv_query_stats(const BlockDriverState *bs);
 int bdrv_can_snapshot(BlockDriverState *bs);
 int bdrv_is_snapshot(BlockDriverState *bs);
-BlockDriverState *bdrv_snapshots(void);
 int bdrv_snapshot_create(BlockDriverState *bs,
                          QEMUSnapshotInfo *sn_info);
 int bdrv_snapshot_goto(BlockDriverState *bs,
diff --git a/savevm.c b/savevm.c
index 4e0fab6..b11dbf6 100644
--- a/savevm.c
+++ b/savevm.c
@@ -2262,6 +2262,17 @@ out:
     return ret;
 }
 
+static BlockDriverState *find_vmstate_bs(void)
+{
+    BlockDriverState *bs = NULL;
+    while ((bs = bdrv_next(bs))) {
+        if (bdrv_can_snapshot(bs)) {
+            return bs;
+        }
+    }
+    return NULL;
+}
+
 static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
                               const char *name)
 {
@@ -2338,7 +2349,7 @@ void do_savevm(Monitor *mon, const QDict *qdict)
         }
     }
 
-    bs = bdrv_snapshots();
+    bs = find_vmstate_bs();
     if (!bs) {
         monitor_printf(mon, "No block device can accept snapshots\n");
         return;
@@ -2440,7 +2451,7 @@ int load_vmstate(const char *name)
     QEMUFile *f;
     int ret;
 
-    bs_vm_state = bdrv_snapshots();
+    bs_vm_state = find_vmstate_bs();
     if (!bs_vm_state) {
         error_report("No block device supports snapshots");
         return -ENOTSUP;
@@ -2519,7 +2530,7 @@ void do_delvm(Monitor *mon, const QDict *qdict)
     int ret;
     const char *name = qdict_get_str(qdict, "name");
 
-    bs = bdrv_snapshots();
+    bs = find_vmstate_bs();
     if (!bs) {
         monitor_printf(mon, "No block device supports snapshots\n");
         return;
@@ -2551,7 +2562,7 @@ void do_info_snapshots(Monitor *mon, const QDict *qdict)
     int *available_snapshots;
     char buf[256];
 
-    bs = bdrv_snapshots();
+    bs = find_vmstate_bs();
     if (!bs) {
         monitor_printf(mon, "No available block device supports snapshots\n");
         return;
commit 2499a096a2427f0a5c71750c9f79cf2d2d2d60f4
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Tue May 28 17:11:37 2013 +0200

    qemu-iotests: make create_image() common
    
    Both 030 and 041 use create_image().  Move it to iotests.py.
    
    Also drop ImageStreamingTestCase since the class now has no methods.
    
    Suggested-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
index 1f55095..ae56f3b 100755
--- a/tests/qemu-iotests/030
+++ b/tests/qemu-iotests/030
@@ -22,30 +22,16 @@ import time
 import os
 import iotests
 from iotests import qemu_img, qemu_io
-import struct
 
 backing_img = os.path.join(iotests.test_dir, 'backing.img')
 mid_img = os.path.join(iotests.test_dir, 'mid.img')
 test_img = os.path.join(iotests.test_dir, 'test.img')
 
-class ImageStreamingTestCase(iotests.QMPTestCase):
-    '''Abstract base class for image streaming test cases'''
-
-    def create_image(self, name, size):
-        file = open(name, 'w')
-        i = 0
-        while i < size:
-            sector = struct.pack('>l504xl', i / 512, i / 512)
-            file.write(sector)
-            i = i + 512
-        file.close()
-
-
-class TestSingleDrive(ImageStreamingTestCase):
+class TestSingleDrive(iotests.QMPTestCase):
     image_len = 1 * 1024 * 1024 # MB
 
     def setUp(self):
-        self.create_image(backing_img, TestSingleDrive.image_len)
+        iotests.create_image(backing_img, TestSingleDrive.image_len)
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img)
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
         self.vm = iotests.VM().add_drive(test_img)
@@ -145,12 +131,12 @@ class TestSingleDrive(ImageStreamingTestCase):
         self.assert_qmp(result, 'error/class', 'DeviceNotFound')
 
 
-class TestSmallerBackingFile(ImageStreamingTestCase):
+class TestSmallerBackingFile(iotests.QMPTestCase):
     backing_len = 1 * 1024 * 1024 # MB
     image_len = 2 * backing_len
 
     def setUp(self):
-        self.create_image(backing_img, self.backing_len)
+        iotests.create_image(backing_img, self.backing_len)
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img, str(self.image_len))
         self.vm = iotests.VM().add_drive(test_img)
         self.vm.launch()
@@ -176,7 +162,7 @@ class TestSmallerBackingFile(ImageStreamingTestCase):
         self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
-class TestErrors(ImageStreamingTestCase):
+class TestErrors(iotests.QMPTestCase):
     image_len = 2 * 1024 * 1024 # MB
 
     # this should match STREAM_BUFFER_SIZE/512 in block/stream.c
@@ -208,7 +194,7 @@ new_state = "1"
 class TestEIO(TestErrors):
     def setUp(self):
         self.blkdebug_file = backing_img + ".blkdebug"
-        self.create_image(backing_img, TestErrors.image_len)
+        iotests.create_image(backing_img, TestErrors.image_len)
         self.create_blkdebug_file(self.blkdebug_file, "read_aio", 5)
         qemu_img('create', '-f', iotests.imgfmt,
                  '-o', 'backing_file=blkdebug:%s:%s,backing_fmt=raw'
@@ -344,7 +330,7 @@ class TestEIO(TestErrors):
 class TestENOSPC(TestErrors):
     def setUp(self):
         self.blkdebug_file = backing_img + ".blkdebug"
-        self.create_image(backing_img, TestErrors.image_len)
+        iotests.create_image(backing_img, TestErrors.image_len)
         self.create_blkdebug_file(self.blkdebug_file, "read_aio", 28)
         qemu_img('create', '-f', iotests.imgfmt,
                  '-o', 'backing_file=blkdebug:%s:%s,backing_fmt=raw'
@@ -397,7 +383,7 @@ class TestENOSPC(TestErrors):
         self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
-class TestStreamStop(ImageStreamingTestCase):
+class TestStreamStop(iotests.QMPTestCase):
     image_len = 8 * 1024 * 1024 * 1024 # GB
 
     def setUp(self):
@@ -423,7 +409,7 @@ class TestStreamStop(ImageStreamingTestCase):
 
         self.cancel_and_wait()
 
-class TestSetSpeed(ImageStreamingTestCase):
+class TestSetSpeed(iotests.QMPTestCase):
     image_len = 80 * 1024 * 1024 # MB
 
     def setUp(self):
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
index 7702074..1e923e7 100755
--- a/tests/qemu-iotests/041
+++ b/tests/qemu-iotests/041
@@ -22,7 +22,6 @@ import time
 import os
 import iotests
 from iotests import qemu_img, qemu_io
-import struct
 
 backing_img = os.path