[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.join(iotests.test_dir, 'backing.img')
 target_backing_img = os.path.join(iotests.test_dir, 'target-backing.img')
@@ -71,20 +70,11 @@ class ImageMirroringTestCase(iotests.QMPTestCase):
 
         self.assert_no_active_block_jobs()
 
-    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(ImageMirroringTestCase):
     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, test_img)
         self.vm = iotests.VM().add_drive(test_img)
         self.vm.launch()
@@ -230,15 +220,15 @@ class TestMirrorNoBacking(ImageMirroringTestCase):
     image_len = 2 * 1024 * 1024 # MB
 
     def complete_and_wait(self, drive='drive0', wait_ready=True):
-        self.create_image(target_backing_img, TestMirrorNoBacking.image_len)
+        iotests.create_image(target_backing_img, TestMirrorNoBacking.image_len)
         return ImageMirroringTestCase.complete_and_wait(self, drive, wait_ready)
 
     def compare_images(self, img1, img2):
-        self.create_image(target_backing_img, TestMirrorNoBacking.image_len)
+        iotests.create_image(target_backing_img, TestMirrorNoBacking.image_len)
         return iotests.compare_images(img1, img2)
 
     def setUp(self):
-        self.create_image(backing_img, TestMirrorNoBacking.image_len)
+        iotests.create_image(backing_img, TestMirrorNoBacking.image_len)
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
         self.vm = iotests.VM().add_drive(test_img)
         self.vm.launch()
@@ -306,7 +296,7 @@ class TestMirrorResized(ImageMirroringTestCase):
     image_len = 2 * 1024 * 1024 # MB
 
     def setUp(self):
-        self.create_image(backing_img, TestMirrorResized.backing_len)
+        iotests.create_image(backing_img, TestMirrorResized.backing_len)
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
         qemu_img('resize', test_img, '2M')
         self.vm = iotests.VM().add_drive(test_img)
@@ -381,7 +371,7 @@ new_state = "1"
 
     def setUp(self):
         self.blkdebug_file = backing_img + ".blkdebug"
-        self.create_image(backing_img, TestReadErrors.image_len)
+        iotests.create_image(backing_img, TestReadErrors.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'
@@ -536,7 +526,7 @@ new_state = "1"
 
     def setUp(self):
         self.blkdebug_file = target_img + ".blkdebug"
-        self.create_image(backing_img, TestWriteErrors.image_len)
+        iotests.create_image(backing_img, TestWriteErrors.image_len)
         self.create_blkdebug_file(self.blkdebug_file, "write_aio", 5)
         qemu_img('create', '-f', iotests.imgfmt, '-obacking_file=%s' %(backing_img), test_img)
         self.vm = iotests.VM().add_drive(test_img)
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 733b82b..8a8f181 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -23,6 +23,7 @@ import string
 import unittest
 import sys; sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'QMP'))
 import qmp
+import struct
 
 __all__ = ['imgfmt', 'imgproto', 'test_dir' 'qemu_img', 'qemu_io',
            'VM', 'QMPTestCase', 'notrun', 'main']
@@ -56,6 +57,16 @@ def compare_images(img1, img2):
     return qemu_img('compare', '-f', imgfmt,
                     '-F', imgfmt, img1, img2) == 0
 
+def create_image(name, size):
+    '''Create a fully-allocated raw image with sector markers'''
+    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 VM(object):
     '''A QEMU VM'''
 
commit 3a3918c396c5caeab35a7f51af905172a13d996a
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Tue May 28 17:11:36 2013 +0200

    qemu-iotests: make compare_images() common
    
    The iotests.compare_images() function returns True if two image files
    have the identical data.  Previously this was implemented by converting
    images to raw and then comparing their contents using Python.  Since
    "qemu-img compare" is now available and is more efficient, switch to it.
    
    This function will be reused by the 'drive-backup' test case.
    
    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/041 b/tests/qemu-iotests/041
index c4ce75e..7702074 100755
--- a/tests/qemu-iotests/041
+++ b/tests/qemu-iotests/041
@@ -80,27 +80,6 @@ class ImageMirroringTestCase(iotests.QMPTestCase):
             i = i + 512
         file.close()
 
-    def compare_images(self, img1, img2):
-        try:
-            qemu_img('convert', '-f', iotests.imgfmt, '-O', 'raw', img1, img1 + '.raw')
-            qemu_img('convert', '-f', iotests.imgfmt, '-O', 'raw', img2, img2 + '.raw')
-            file1 = open(img1 + '.raw', 'r')
-            file2 = open(img2 + '.raw', 'r')
-            return file1.read() == file2.read()
-        finally:
-            if file1 is not None:
-                file1.close()
-            if file2 is not None:
-                file2.close()
-            try:
-                os.remove(img1 + '.raw')
-            except OSError:
-                pass
-            try:
-                os.remove(img2 + '.raw')
-            except OSError:
-                pass
-
 class TestSingleDrive(ImageMirroringTestCase):
     image_len = 1 * 1024 * 1024 # MB
 
@@ -130,7 +109,7 @@ class TestSingleDrive(ImageMirroringTestCase):
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/file', target_img)
         self.vm.shutdown()
-        self.assertTrue(self.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(test_img, target_img),
                         'target image does not match source after mirroring')
 
     def test_cancel(self):
@@ -156,7 +135,7 @@ class TestSingleDrive(ImageMirroringTestCase):
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/file', test_img)
         self.vm.shutdown()
-        self.assertTrue(self.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(test_img, target_img),
                         'target image does not match source after mirroring')
 
     def test_pause(self):
@@ -182,7 +161,7 @@ class TestSingleDrive(ImageMirroringTestCase):
 
         self.complete_and_wait()
         self.vm.shutdown()
-        self.assertTrue(self.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(test_img, target_img),
                         'target image does not match source after mirroring')
 
     def test_small_buffer(self):
@@ -197,7 +176,7 @@ class TestSingleDrive(ImageMirroringTestCase):
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/file', target_img)
         self.vm.shutdown()
-        self.assertTrue(self.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(test_img, target_img),
                         'target image does not match source after mirroring')
 
     def test_small_buffer2(self):
@@ -213,7 +192,7 @@ class TestSingleDrive(ImageMirroringTestCase):
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/file', target_img)
         self.vm.shutdown()
-        self.assertTrue(self.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(test_img, target_img),
                         'target image does not match source after mirroring')
 
     def test_large_cluster(self):
@@ -229,7 +208,7 @@ class TestSingleDrive(ImageMirroringTestCase):
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/file', target_img)
         self.vm.shutdown()
-        self.assertTrue(self.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(test_img, target_img),
                         'target image does not match source after mirroring')
 
     def test_medium_not_found(self):
@@ -256,7 +235,7 @@ class TestMirrorNoBacking(ImageMirroringTestCase):
 
     def compare_images(self, img1, img2):
         self.create_image(target_backing_img, TestMirrorNoBacking.image_len)
-        return ImageMirroringTestCase.compare_images(self, img1, img2)
+        return iotests.compare_images(img1, img2)
 
     def setUp(self):
         self.create_image(backing_img, TestMirrorNoBacking.image_len)
@@ -353,7 +332,7 @@ class TestMirrorResized(ImageMirroringTestCase):
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/file', target_img)
         self.vm.shutdown()
-        self.assertTrue(self.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(test_img, target_img),
                         'target image does not match source after mirroring')
 
     def test_complete_full(self):
@@ -367,7 +346,7 @@ class TestMirrorResized(ImageMirroringTestCase):
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/file', target_img)
         self.vm.shutdown()
-        self.assertTrue(self.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(test_img, target_img),
                         'target image does not match source after mirroring')
 
 class TestReadErrors(ImageMirroringTestCase):
@@ -487,7 +466,7 @@ new_state = "1"
 
         # Detach blkdebug to compare images successfully
         qemu_img('rebase', '-f', iotests.imgfmt, '-u', '-b', backing_img, test_img)
-        self.assertTrue(self.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(test_img, target_img),
                         'target image does not match source after mirroring')
 
     def test_stop_read(self):
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index bc9c71b..733b82b 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -51,6 +51,11 @@ def qemu_io(*args):
     args = qemu_io_args + list(args)
     return subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0]
 
+def compare_images(img1, img2):
+    '''Return True if two image files are identical'''
+    return qemu_img('compare', '-f', imgfmt,
+                    '-F', imgfmt, img1, img2) == 0
+
 class VM(object):
     '''A QEMU VM'''
 
commit 2575fe16d257a1fb5f452391b868b3c3263a9aca
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Tue May 28 17:11:35 2013 +0200

    qemu-iotests: make cancel_and_wait() common
    
    The cancel_and_wait() function has been duplicated in 030 and 041.  Move
    it into iotests.py and let it return the event so tests can perform
    additional asserts.
    
    Note that 041's cancel_and_wait(wait_ready=True) is replaced by
    wait_ready_and_cancel(), which uses the new wait_ready() and
    cancel_and_wait() underneath.
    
    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 03dd6a6..1f55095 100755
--- a/tests/qemu-iotests/030
+++ b/tests/qemu-iotests/030
@@ -31,21 +31,6 @@ test_img = os.path.join(iotests.test_dir, 'test.img')
 class ImageStreamingTestCase(iotests.QMPTestCase):
     '''Abstract base class for image streaming test cases'''
 
-    def cancel_and_wait(self, drive='drive0'):
-        '''Cancel a block job and wait for it to finish'''
-        result = self.vm.qmp('block-job-cancel', device=drive)
-        self.assert_qmp(result, 'return', {})
-
-        cancelled = False
-        while not cancelled:
-            for event in self.vm.get_qmp_events(wait=True):
-                if event['event'] == 'BLOCK_JOB_CANCELLED':
-                    self.assert_qmp(event, 'data/type', 'stream')
-                    self.assert_qmp(event, 'data/device', drive)
-                    cancelled = True
-
-        self.assert_no_active_block_jobs()
-
     def create_image(self, name, size):
         file = open(name, 'w')
         i = 0
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
index ff89427..c4ce75e 100755
--- a/tests/qemu-iotests/041
+++ b/tests/qemu-iotests/041
@@ -32,46 +32,28 @@ target_img = os.path.join(iotests.test_dir, 'target.img')
 class ImageMirroringTestCase(iotests.QMPTestCase):
     '''Abstract base class for image mirroring test cases'''
 
-    def cancel_and_wait(self, drive='drive0', wait_ready=True):
-        '''Cancel a block job and wait for it to finish'''
-        if wait_ready:
-            ready = False
-            while not ready:
-                for event in self.vm.get_qmp_events(wait=True):
-                    if event['event'] == 'BLOCK_JOB_READY':
-                        self.assert_qmp(event, 'data/type', 'mirror')
-                        self.assert_qmp(event, 'data/device', drive)
-                        ready = True
-
-        result = self.vm.qmp('block-job-cancel', device=drive,
-                             force=not wait_ready)
-        self.assert_qmp(result, 'return', {})
-
-        cancelled = False
-        while not cancelled:
+    def wait_ready(self, drive='drive0'):
+        '''Wait until a block job BLOCK_JOB_READY event'''
+        ready = False
+        while not ready:
             for event in self.vm.get_qmp_events(wait=True):
-                if event['event'] == 'BLOCK_JOB_COMPLETED' or \
-                   event['event'] == 'BLOCK_JOB_CANCELLED':
+                if event['event'] == 'BLOCK_JOB_READY':
                     self.assert_qmp(event, 'data/type', 'mirror')
                     self.assert_qmp(event, 'data/device', drive)
-                    if wait_ready:
-                        self.assertEquals(event['event'], 'BLOCK_JOB_COMPLETED')
-                        self.assert_qmp(event, 'data/offset', self.image_len)
-                        self.assert_qmp(event, 'data/len', self.image_len)
-                    cancelled = True
+                    ready = True
 
-        self.assert_no_active_block_jobs()
+    def wait_ready_and_cancel(self, drive='drive0'):
+        self.wait_ready(drive)
+        event = self.cancel_and_wait()
+        self.assertEquals(event['event'], 'BLOCK_JOB_COMPLETED')
+        self.assert_qmp(event, 'data/type', 'mirror')
+        self.assert_qmp(event, 'data/offset', self.image_len)
+        self.assert_qmp(event, 'data/len', self.image_len)
 
     def complete_and_wait(self, drive='drive0', wait_ready=True):
         '''Complete a block job and wait for it to finish'''
         if wait_ready:
-            ready = False
-            while not ready:
-                for event in self.vm.get_qmp_events(wait=True):
-                    if event['event'] == 'BLOCK_JOB_READY':
-                        self.assert_qmp(event, 'data/type', 'mirror')
-                        self.assert_qmp(event, 'data/device', drive)
-                        ready = True
+            self.wait_ready()
 
         result = self.vm.qmp('block-job-complete', device=drive)
         self.assert_qmp(result, 'return', {})
@@ -158,7 +140,7 @@ class TestSingleDrive(ImageMirroringTestCase):
                              target=target_img)
         self.assert_qmp(result, 'return', {})
 
-        self.cancel_and_wait(wait_ready=False)
+        self.cancel_and_wait(force=True)
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/file', test_img)
         self.vm.shutdown()
@@ -170,7 +152,7 @@ class TestSingleDrive(ImageMirroringTestCase):
                              target=target_img)
         self.assert_qmp(result, 'return', {})
 
-        self.cancel_and_wait()
+        self.wait_ready_and_cancel()
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/file', test_img)
         self.vm.shutdown()
@@ -312,7 +294,7 @@ class TestMirrorNoBacking(ImageMirroringTestCase):
                              mode='existing', target=target_img)
         self.assert_qmp(result, 'return', {})
 
-        self.cancel_and_wait()
+        self.wait_ready_and_cancel()
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/file', test_img)
         self.vm.shutdown()
@@ -705,7 +687,7 @@ class TestSetSpeed(ImageMirroringTestCase):
         self.assert_qmp(result, 'return[0]/device', 'drive0')
         self.assert_qmp(result, 'return[0]/speed', 8 * 1024 * 1024)
 
-        self.cancel_and_wait()
+        self.wait_ready_and_cancel()
 
         # Check setting speed in drive-mirror works
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
@@ -716,7 +698,7 @@ class TestSetSpeed(ImageMirroringTestCase):
         self.assert_qmp(result, 'return[0]/device', 'drive0')
         self.assert_qmp(result, 'return[0]/speed', 4 * 1024 * 1024)
 
-        self.cancel_and_wait()
+        self.wait_ready_and_cancel()
 
     def test_set_speed_invalid(self):
         self.assert_no_active_block_jobs()
@@ -734,7 +716,7 @@ class TestSetSpeed(ImageMirroringTestCase):
         result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
         self.assert_qmp(result, 'error/class', 'GenericError')
 
-        self.cancel_and_wait()
+        self.wait_ready_and_cancel()
 
 if __name__ == '__main__':
     iotests.main(supported_fmts=['qcow2', 'qed'])
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 0e7862c..bc9c71b 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -174,6 +174,24 @@ class QMPTestCase(unittest.TestCase):
         result = self.vm.qmp('query-block-jobs')
         self.assert_qmp(result, 'return', [])
 
+    def cancel_and_wait(self, drive='drive0', force=False):
+        '''Cancel a block job and wait for it to finish, returning the event'''
+        result = self.vm.qmp('block-job-cancel', device=drive, force=force)
+        self.assert_qmp(result, 'return', {})
+
+        cancelled = False
+        result = None
+        while not cancelled:
+            for event in self.vm.get_qmp_events(wait=True):
+                if event['event'] == 'BLOCK_JOB_COMPLETED' or \
+                   event['event'] == 'BLOCK_JOB_CANCELLED':
+                    self.assert_qmp(event, 'data/device', drive)
+                    result = event
+                    cancelled = True
+
+        self.assert_no_active_block_jobs()
+        return result
+
 def notrun(reason):
     '''Skip this test suite'''
     # Each test in qemu-iotests has a number ("seq")
commit ecc1c88efddb376687084c3387c38b3a458c5892
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Tue May 28 17:11:34 2013 +0200

    qemu-iotests: make assert_no_active_block_jobs() common
    
    Tests 030 and 041 both use query-block-jobs to check whether any block
    jobs are active.  Make this code common so that 'drive-backup' and other
    new feature tests will be able to reuse it.
    
    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 dd4ef11..03dd6a6 100755
--- a/tests/qemu-iotests/030
+++ b/tests/qemu-iotests/030
@@ -31,10 +31,6 @@ test_img = os.path.join(iotests.test_dir, 'test.img')
 class ImageStreamingTestCase(iotests.QMPTestCase):
     '''Abstract base class for image streaming test cases'''
 
-    def assert_no_active_streams(self):
-        result = self.vm.qmp('query-block-jobs')
-        self.assert_qmp(result, 'return', [])
-
     def cancel_and_wait(self, drive='drive0'):
         '''Cancel a block job and wait for it to finish'''
         result = self.vm.qmp('block-job-cancel', device=drive)
@@ -48,7 +44,7 @@ class ImageStreamingTestCase(iotests.QMPTestCase):
                     self.assert_qmp(event, 'data/device', drive)
                     cancelled = True
 
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
 
     def create_image(self, name, size):
         file = open(name, 'w')
@@ -77,7 +73,7 @@ class TestSingleDrive(ImageStreamingTestCase):
         os.remove(backing_img)
 
     def test_stream(self):
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('block-stream', device='drive0')
         self.assert_qmp(result, 'return', {})
@@ -92,7 +88,7 @@ class TestSingleDrive(ImageStreamingTestCase):
                     self.assert_qmp(event, 'data/len', self.image_len)
                     completed = True
 
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
         self.assertEqual(qemu_io('-c', 'map', backing_img),
@@ -100,7 +96,7 @@ class TestSingleDrive(ImageStreamingTestCase):
                          'image file map does not match backing file after streaming')
 
     def test_stream_pause(self):
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('block-stream', device='drive0')
         self.assert_qmp(result, 'return', {})
@@ -129,7 +125,7 @@ class TestSingleDrive(ImageStreamingTestCase):
                     self.assert_qmp(event, 'data/len', self.image_len)
                     completed = True
 
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
         self.assertEqual(qemu_io('-c', 'map', backing_img),
@@ -137,7 +133,7 @@ class TestSingleDrive(ImageStreamingTestCase):
                          'image file map does not match backing file after streaming')
 
     def test_stream_partial(self):
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('block-stream', device='drive0', base=mid_img)
         self.assert_qmp(result, 'return', {})
@@ -152,7 +148,7 @@ class TestSingleDrive(ImageStreamingTestCase):
                     self.assert_qmp(event, 'data/len', self.image_len)
                     completed = True
 
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
         self.assertEqual(qemu_io('-c', 'map', mid_img),
@@ -177,7 +173,7 @@ class TestSmallerBackingFile(ImageStreamingTestCase):
     # If this hangs, then you are missing a fix to complete streaming when the
     # end of the backing file is reached.
     def test_stream(self):
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('block-stream', device='drive0')
         self.assert_qmp(result, 'return', {})
@@ -192,7 +188,7 @@ class TestSmallerBackingFile(ImageStreamingTestCase):
                     self.assert_qmp(event, 'data/len', self.image_len)
                     completed = True
 
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
 class TestErrors(ImageStreamingTestCase):
@@ -243,7 +239,7 @@ class TestEIO(TestErrors):
         os.remove(self.blkdebug_file)
 
     def test_report(self):
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('block-stream', device='drive0')
         self.assert_qmp(result, 'return', {})
@@ -265,11 +261,11 @@ class TestEIO(TestErrors):
                     self.assert_qmp(event, 'data/len', self.image_len)
                     completed = True
 
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
     def test_ignore(self):
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('block-stream', device='drive0', on_error='ignore')
         self.assert_qmp(result, 'return', {})
@@ -293,11 +289,11 @@ class TestEIO(TestErrors):
                     self.assert_qmp(event, 'data/len', self.image_len)
                     completed = True
 
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
     def test_stop(self):
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('block-stream', device='drive0', on_error='stop')
         self.assert_qmp(result, 'return', {})
@@ -331,11 +327,11 @@ class TestEIO(TestErrors):
                     self.assert_qmp(event, 'data/len', self.image_len)
                     completed = True
 
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
     def test_enospc(self):
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('block-stream', device='drive0', on_error='enospc')
         self.assert_qmp(result, 'return', {})
@@ -357,7 +353,7 @@ class TestEIO(TestErrors):
                     self.assert_qmp(event, 'data/len', self.image_len)
                     completed = True
 
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
 class TestENOSPC(TestErrors):
@@ -379,7 +375,7 @@ class TestENOSPC(TestErrors):
         os.remove(self.blkdebug_file)
 
     def test_enospc(self):
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('block-stream', device='drive0', on_error='enospc')
         self.assert_qmp(result, 'return', {})
@@ -413,7 +409,7 @@ class TestENOSPC(TestErrors):
                     self.assert_qmp(event, 'data/len', self.image_len)
                     completed = True
 
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
 class TestStreamStop(ImageStreamingTestCase):
@@ -431,7 +427,7 @@ class TestStreamStop(ImageStreamingTestCase):
         os.remove(backing_img)
 
     def test_stream_stop(self):
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('block-stream', device='drive0')
         self.assert_qmp(result, 'return', {})
@@ -459,7 +455,7 @@ class TestSetSpeed(ImageStreamingTestCase):
     # This is a short performance test which is not run by default.
     # Invoke "IMGFMT=qed ./030 TestSetSpeed.perf_test_throughput"
     def perf_test_throughput(self):
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('block-stream', device='drive0')
         self.assert_qmp(result, 'return', {})
@@ -477,10 +473,10 @@ class TestSetSpeed(ImageStreamingTestCase):
                     self.assert_qmp(event, 'data/len', self.image_len)
                     completed = True
 
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
 
     def test_set_speed(self):
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('block-stream', device='drive0')
         self.assert_qmp(result, 'return', {})
@@ -511,12 +507,12 @@ class TestSetSpeed(ImageStreamingTestCase):
         self.cancel_and_wait()
 
     def test_set_speed_invalid(self):
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('block-stream', device='drive0', speed=-1)
         self.assert_qmp(result, 'error/class', 'GenericError')
 
-        self.assert_no_active_streams()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('block-stream', device='drive0')
         self.assert_qmp(result, 'return', {})
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
index 720eeff..ff89427 100755
--- a/tests/qemu-iotests/041
+++ b/tests/qemu-iotests/041
@@ -32,10 +32,6 @@ target_img = os.path.join(iotests.test_dir, 'target.img')
 class ImageMirroringTestCase(iotests.QMPTestCase):
     '''Abstract base class for image mirroring test cases'''
 
-    def assert_no_active_mirrors(self):
-        result = self.vm.qmp('query-block-jobs')
-        self.assert_qmp(result, 'return', [])
-
     def cancel_and_wait(self, drive='drive0', wait_ready=True):
         '''Cancel a block job and wait for it to finish'''
         if wait_ready:
@@ -64,7 +60,7 @@ class ImageMirroringTestCase(iotests.QMPTestCase):
                         self.assert_qmp(event, 'data/len', self.image_len)
                     cancelled = True
 
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
     def complete_and_wait(self, drive='drive0', wait_ready=True):
         '''Complete a block job and wait for it to finish'''
@@ -91,7 +87,7 @@ class ImageMirroringTestCase(iotests.QMPTestCase):
                     self.assert_qmp(event, 'data/len', self.image_len)
                     completed = True
 
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
     def create_image(self, name, size):
         file = open(name, 'w')
@@ -142,7 +138,7 @@ class TestSingleDrive(ImageMirroringTestCase):
             pass
 
     def test_complete(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                              target=target_img)
@@ -156,7 +152,7 @@ class TestSingleDrive(ImageMirroringTestCase):
                         'target image does not match source after mirroring')
 
     def test_cancel(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                              target=target_img)
@@ -168,7 +164,7 @@ class TestSingleDrive(ImageMirroringTestCase):
         self.vm.shutdown()
 
     def test_cancel_after_ready(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                              target=target_img)
@@ -182,7 +178,7 @@ class TestSingleDrive(ImageMirroringTestCase):
                         'target image does not match source after mirroring')
 
     def test_pause(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                              target=target_img)
@@ -208,7 +204,7 @@ class TestSingleDrive(ImageMirroringTestCase):
                         'target image does not match source after mirroring')
 
     def test_small_buffer(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         # A small buffer is rounded up automatically
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
@@ -223,7 +219,7 @@ class TestSingleDrive(ImageMirroringTestCase):
                         'target image does not match source after mirroring')
 
     def test_small_buffer2(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,size=%d'
                         % (TestSingleDrive.image_len, TestSingleDrive.image_len), target_img)
@@ -239,7 +235,7 @@ class TestSingleDrive(ImageMirroringTestCase):
                         'target image does not match source after mirroring')
 
     def test_large_cluster(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,backing_file=%s'
                         % (TestSingleDrive.image_len, backing_img), target_img)
@@ -294,7 +290,7 @@ class TestMirrorNoBacking(ImageMirroringTestCase):
         os.remove(target_img)
 
     def test_complete(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, target_img)
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
@@ -309,7 +305,7 @@ class TestMirrorNoBacking(ImageMirroringTestCase):
                         'target image does not match source after mirroring')
 
     def test_cancel(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, target_img)
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
@@ -324,7 +320,7 @@ class TestMirrorNoBacking(ImageMirroringTestCase):
                         'target image does not match source after mirroring')
 
     def test_large_cluster(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         # qemu-img create fails if the image is not there
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'size=%d'
@@ -365,7 +361,7 @@ class TestMirrorResized(ImageMirroringTestCase):
             pass
 
     def test_complete_top(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='top',
                              target=target_img)
@@ -379,7 +375,7 @@ class TestMirrorResized(ImageMirroringTestCase):
                         'target image does not match source after mirroring')
 
     def test_complete_full(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                              target=target_img)
@@ -443,7 +439,7 @@ new_state = "1"
         os.remove(self.blkdebug_file)
 
     def test_report_read(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                              target=target_img)
@@ -467,11 +463,11 @@ new_state = "1"
                     self.assert_qmp(event, 'data/len', self.image_len)
                     completed = True
 
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
     def test_ignore_read(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                              target=target_img, on_source_error='ignore')
@@ -487,7 +483,7 @@ new_state = "1"
         self.vm.shutdown()
 
     def test_large_cluster(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         # Test COW into the target image.  The first half of the
         # cluster at MIRROR_GRANULARITY has to be copied from
@@ -513,7 +509,7 @@ new_state = "1"
                         'target image does not match source after mirroring')
 
     def test_stop_read(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                              target=target_img, on_source_error='stop')
@@ -544,7 +540,7 @@ new_state = "1"
         self.assert_qmp(result, 'return[0]/io-status', 'ok')
 
         self.complete_and_wait(wait_ready=False)
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
 class TestWriteErrors(ImageMirroringTestCase):
@@ -594,7 +590,7 @@ new_state = "1"
         os.remove(self.blkdebug_file)
 
     def test_report_write(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                              mode='existing', target=self.target_img)
@@ -618,11 +614,11 @@ new_state = "1"
                     self.assert_qmp(event, 'data/len', self.image_len)
                     completed = True
 
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
     def test_ignore_write(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                              mode='existing', target=self.target_img,
@@ -639,7 +635,7 @@ new_state = "1"
         self.vm.shutdown()
 
     def test_stop_write(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                              mode='existing', target=self.target_img,
@@ -671,7 +667,7 @@ new_state = "1"
                     ready = True
 
         self.complete_and_wait(wait_ready=False)
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
 class TestSetSpeed(ImageMirroringTestCase):
@@ -690,7 +686,7 @@ class TestSetSpeed(ImageMirroringTestCase):
         os.remove(target_img)
 
     def test_set_speed(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                              target=target_img)
@@ -723,13 +719,13 @@ class TestSetSpeed(ImageMirroringTestCase):
         self.cancel_and_wait()
 
     def test_set_speed_invalid(self):
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                              target=target_img, speed=-1)
         self.assert_qmp(result, 'error/class', 'GenericError')
 
-        self.assert_no_active_mirrors()
+        self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                              target=target_img)
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 569ca3d..0e7862c 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -170,6 +170,10 @@ class QMPTestCase(unittest.TestCase):
         result = self.dictpath(d, path)
         self.assertEqual(result, value, 'values not equal "%s" and "%s"' % (str(result), str(value)))
 
+    def assert_no_active_block_jobs(self):
+        result = self.vm.qmp('query-block-jobs')
+        self.assert_qmp(result, 'return', [])
+
 def notrun(reason):
     '''Skip this test suite'''
     # Each test in qemu-iotests has a number ("seq")
commit b64ec4e4ade581d662753cdeb0d7e0e27aafbf81
Author: Fam Zheng <famz at redhat.com>
Date:   Wed May 29 19:35:40 2013 +0800

    block: add block driver read only whitelist
    
    We may want to include a driver in the whitelist for read only tasks
    such as diagnosing or exporting guest data (with libguestfs as a good
    example). This patch introduces a readonly whitelist option, and for
    backward compatibility, the old configure option --block-drv-whitelist
    is now an alias to rw whitelist.
    
    Drivers in readonly list is only permitted to open file readonly, and
    returns -ENOTSUP for RW opening.
    
    E.g. To include vmdk readonly, and others read+write:
        ./configure --target-list=x86_64-softmmu \
                    --block-drv-rw-whitelist=qcow2,raw,file,qed \
                    --block-drv-ro-whitelist=vmdk
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index 3f87489..65c0b60 100644
--- a/block.c
+++ b/block.c
@@ -328,28 +328,40 @@ BlockDriver *bdrv_find_format(const char *format_name)
     return NULL;
 }
 
-static int bdrv_is_whitelisted(BlockDriver *drv)
+static int bdrv_is_whitelisted(BlockDriver *drv, bool read_only)
 {
-    static const char *whitelist[] = {
-        CONFIG_BDRV_WHITELIST
+    static const char *whitelist_rw[] = {
+        CONFIG_BDRV_RW_WHITELIST
+    };
+    static const char *whitelist_ro[] = {
+        CONFIG_BDRV_RO_WHITELIST
     };
     const char **p;
 
-    if (!whitelist[0])
+    if (!whitelist_rw[0] && !whitelist_ro[0]) {
         return 1;               /* no whitelist, anything goes */
+    }
 
-    for (p = whitelist; *p; p++) {
+    for (p = whitelist_rw; *p; p++) {
         if (!strcmp(drv->format_name, *p)) {
             return 1;
         }
     }
+    if (read_only) {
+        for (p = whitelist_ro; *p; p++) {
+            if (!strcmp(drv->format_name, *p)) {
+                return 1;
+            }
+        }
+    }
     return 0;
 }
 
-BlockDriver *bdrv_find_whitelisted_format(const char *format_name)
+BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
+                                          bool read_only)
 {
     BlockDriver *drv = bdrv_find_format(format_name);
-    return drv && bdrv_is_whitelisted(drv) ? drv : NULL;
+    return drv && bdrv_is_whitelisted(drv, read_only) ? drv : NULL;
 }
 
 typedef struct CreateCo {
@@ -684,10 +696,6 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
 
     trace_bdrv_open_common(bs, filename ?: "", flags, drv->format_name);
 
-    if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) {
-        return -ENOTSUP;
-    }
-
     /* bdrv_open() with directly using a protocol as drv. This layer is already
      * opened, so assign it to bs (while file becomes a closed BlockDriverState)
      * and return immediately. */
@@ -698,9 +706,15 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
 
     bs->open_flags = flags;
     bs->buffer_alignment = 512;
+    open_flags = bdrv_open_flags(bs, flags);
+    bs->read_only = !(open_flags & BDRV_O_RDWR);
+
+    if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, bs->read_only)) {
+        return -ENOTSUP;
+    }
 
     assert(bs->copy_on_read == 0); /* bdrv_new() and bdrv_close() make it so */
-    if ((flags & BDRV_O_RDWR) && (flags & BDRV_O_COPY_ON_READ)) {
+    if (!bs->read_only && (flags & BDRV_O_COPY_ON_READ)) {
         bdrv_enable_copy_on_read(bs);
     }
 
@@ -714,9 +728,6 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
     bs->opaque = g_malloc0(drv->instance_size);
 
     bs->enable_write_cache = !!(flags & BDRV_O_CACHE_WB);
-    open_flags = bdrv_open_flags(bs, flags);
-
-    bs->read_only = !(open_flags & BDRV_O_RDWR);
 
     /* Open the image, either directly or using a protocol */
     if (drv->bdrv_file_open) {
@@ -801,7 +812,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename,
     /* Find the right block driver */
     drvname = qdict_get_try_str(options, "driver");
     if (drvname) {
-        drv = bdrv_find_whitelisted_format(drvname);
+        drv = bdrv_find_whitelisted_format(drvname, !(flags & BDRV_O_RDWR));
         qdict_del(options, "driver");
     } else if (filename) {
         drv = bdrv_find_protocol(filename);
diff --git a/blockdev.c b/blockdev.c
index d1ec99a..b9b2d10 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -477,7 +477,7 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
             error_printf("\n");
             return NULL;
         }
-        drv = bdrv_find_whitelisted_format(buf);
+        drv = bdrv_find_whitelisted_format(buf, ro);
         if (!drv) {
             error_report("'%s' invalid format", buf);
             return NULL;
@@ -1096,7 +1096,7 @@ void qmp_change_blockdev(const char *device, const char *filename,
     }
 
     if (format) {
-        drv = bdrv_find_whitelisted_format(format);
+        drv = bdrv_find_whitelisted_format(format, bs->read_only);
         if (!drv) {
             error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
             return;
diff --git a/configure b/configure
index 70c41b0..1654413 100755
--- a/configure
+++ b/configure
@@ -123,7 +123,8 @@ interp_prefix="/usr/gnemul/qemu-%M"
 static="no"
 cross_prefix=""
 audio_drv_list=""
-block_drv_whitelist=""
+block_drv_rw_whitelist=""
+block_drv_ro_whitelist=""
 host_cc="cc"
 libs_softmmu=""
 libs_tools=""
@@ -708,7 +709,9 @@ for opt do
   ;;
   --audio-drv-list=*) audio_drv_list="$optarg"
   ;;
-  --block-drv-whitelist=*) block_drv_whitelist=`echo "$optarg" | sed -e 's/,/ /g'`
+  --block-drv-rw-whitelist=*|--block-drv-whitelist=*) block_drv_rw_whitelist=`echo "$optarg" | sed -e 's/,/ /g'`
+  ;;
+  --block-drv-ro-whitelist=*) block_drv_ro_whitelist=`echo "$optarg" | sed -e 's/,/ /g'`
   ;;
   --enable-debug-tcg) debug_tcg="yes"
   ;;
@@ -1049,7 +1052,12 @@ echo "  --disable-cocoa          disable Cocoa (Mac OS X only)"
 echo "  --enable-cocoa           enable Cocoa (default on Mac OS X)"
 echo "  --audio-drv-list=LIST    set audio drivers list:"
 echo "                           Available drivers: $audio_possible_drivers"
-echo "  --block-drv-whitelist=L  set block driver whitelist"
+echo "  --block-drv-whitelist=L  Same as --block-drv-rw-whitelist=L"
+echo "  --block-drv-rw-whitelist=L"
+echo "                           set block driver read-write whitelist"
+echo "                           (affects only QEMU, not qemu-img)"
+echo "  --block-drv-ro-whitelist=L"
+echo "                           set block driver read-only whitelist"
 echo "                           (affects only QEMU, not qemu-img)"
 echo "  --enable-mixemu          enable mixer emulation"
 echo "  --disable-xen            disable xen backend driver support"
@@ -3481,7 +3489,8 @@ echo "curses support    $curses"
 echo "curl support      $curl"
 echo "mingw32 support   $mingw32"
 echo "Audio drivers     $audio_drv_list"
-echo "Block whitelist   $block_drv_whitelist"
+echo "Block whitelist (rw) $block_drv_rw_whitelist"
+echo "Block whitelist (ro) $block_drv_ro_whitelist"
 echo "Mixer emulation   $mixemu"
 echo "VirtFS support    $virtfs"
 echo "VNC support       $vnc"
@@ -3662,7 +3671,8 @@ fi
 if test "$audio_win_int" = "yes" ; then
   echo "CONFIG_AUDIO_WIN_INT=y" >> $config_host_mak
 fi
-echo "CONFIG_BDRV_WHITELIST=$block_drv_whitelist" >> $config_host_mak
+echo "CONFIG_BDRV_RW_WHITELIST=$block_drv_rw_whitelist" >> $config_host_mak
+echo "CONFIG_BDRV_RO_WHITELIST=$block_drv_ro_whitelist" >> $config_host_mak
 if test "$mixemu" = "yes" ; then
   echo "CONFIG_MIXEMU=y" >> $config_host_mak
 fi
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 0ac65d4..247f32f 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -780,11 +780,13 @@ static int blk_connect(struct XenDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
     int pers, index, qflags;
+    bool readonly = true;
 
     /* read-only ? */
     qflags = BDRV_O_CACHE_WB | BDRV_O_NATIVE_AIO;
     if (strcmp(blkdev->mode, "w") == 0) {
         qflags |= BDRV_O_RDWR;
+        readonly = false;
     }
 
     /* init qemu block driver */
@@ -795,8 +797,10 @@ static int blk_connect(struct XenDevice *xendev)
         xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
         blkdev->bs = bdrv_new(blkdev->dev);
         if (blkdev->bs) {
-            if (bdrv_open(blkdev->bs, blkdev->filename, NULL, qflags,
-                        bdrv_find_whitelisted_format(blkdev->fileproto)) != 0) {
+            BlockDriver *drv = bdrv_find_whitelisted_format(blkdev->fileproto,
+                                                           readonly);
+            if (bdrv_open(blkdev->bs,
+                          blkdev->filename, NULL, qflags, drv) != 0) {
                 bdrv_delete(blkdev->bs);
                 blkdev->bs = NULL;
             }
diff --git a/include/block/block.h b/include/block/block.h
index 1251c5c..5604418 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -124,7 +124,8 @@ void bdrv_init(void);
 void bdrv_init_with_whitelist(void);
 BlockDriver *bdrv_find_protocol(const char *filename);
 BlockDriver *bdrv_find_format(const char *format_name);
-BlockDriver *bdrv_find_whitelisted_format(const char *format_name);
+BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
+                                          bool readonly);
 int bdrv_create(BlockDriver *drv, const char* filename,
     QEMUOptionParameter *options);
 int bdrv_create_file(const char* filename, QEMUOptionParameter *options);
diff --git a/scripts/create_config b/scripts/create_config
index c471e8c..258513a 100755
--- a/scripts/create_config
+++ b/scripts/create_config
@@ -34,8 +34,15 @@ case $line in
     done
     echo ""
     ;;
- CONFIG_BDRV_WHITELIST=*)
-    echo "#define CONFIG_BDRV_WHITELIST \\"
+ CONFIG_BDRV_RW_WHITELIST=*)
+    echo "#define CONFIG_BDRV_RW_WHITELIST\\"
+    for drv in ${line#*=}; do
+      echo "    \"${drv}\",\\"
+    done
+    echo "    NULL"
+    ;;
+ CONFIG_BDRV_RO_WHITELIST=*)
+    echo "#define CONFIG_BDRV_RO_WHITELIST\\"
     for drv in ${line#*=}; do
       echo "    \"${drv}\",\\"
     done
commit 8ddd08c5d1415a71f21157686d43f48ff14992b6
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Tue May 28 11:19:51 2013 +0200

    qemu-iotests: fix 054 cluster size help output
    
    Commit f3f4d2c09b9cf46903ba38425ec46c44185162bd added a hint to increase
    the cluster size when a large image cannot be created.  Test 054 now has
    outdated output and fails because the golden output does not match.
    
    This patch updates the 054 golden output.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/tests/qemu-iotests/054.out b/tests/qemu-iotests/054.out
index 0b2fe30..2f357c2 100644
--- a/tests/qemu-iotests/054.out
+++ b/tests/qemu-iotests/054.out
@@ -1,7 +1,7 @@
 QA output created by 054
 
 creating too large image (1 EB)
-qemu-img: The image size is too large for file format 'qcow2'
+qemu-img: The image size is too large for file format 'qcow2' (try using a larger cluster size)
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1152921504606846976 
 
 creating too large image (1 EB) using qcow2.py
commit 171392406d8e230d62e5ebf4805f71460854b8ec
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Jun 3 15:37:23 2013 -0500

    gtk: don't use g_object_unref on GdkCursor
    
    It's not a GObject.
    
    Cc: Gerd Hoffman <kraxel at redhat.com>
    Reported-by: Michael Tokarev <mjt at tls.msk.ru>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
    ---
    v1 -> v2
     - Fix summary to agree with code (Peter)

diff --git a/ui/gtk.c b/ui/gtk.c
index 8dc9041..3bc2842 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -377,7 +377,7 @@ 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);
-    g_object_unref(cursor);
+    gdk_cursor_unref(cursor);
 }
 
 static void gd_switch(DisplayChangeListener *dcl,
commit 41686a960805ed561158c7e4809f0c9f92f1d8ec
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Jun 3 15:36:51 2013 -0500

    gtk: don't resize window when enabling scaling
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/ui/gtk.c b/ui/gtk.c
index 52c3f95..8dc9041 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -885,9 +885,11 @@ static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque)
         s->free_scale = TRUE;
     } else {
         s->free_scale = FALSE;
+        s->scale_x = 1.0;
+        s->scale_y = 1.0;
+        gd_update_windowsize(s);
     }
 
-    gd_update_windowsize(s);
     gd_update_full_redraw(s);
 }
 
commit 651eb0f41b793021f7de672de78892def5819fb9
Author: Xiao Guangrong <xiaoguangrong at linux.vnet.ibm.com>
Date:   Fri May 31 16:52:18 2013 +0800

    fix double free the memslot in kvm_set_phys_mem
    
    Luiz Capitulino reported that guest refused to boot and qemu
    complained with:
    kvm_set_phys_mem: error unregistering overlapping slot: Invalid argument
    
    It is caused by commit 235e8982ad that did double free for the memslot
    so that the second one raises the -EINVAL error
    
    Fix it by reset memory size only if it is needed
    
    Reported-by: Luiz Capitulino <lcapitulino at redhat.com>
    Signed-off-by: Xiao Guangrong <xiaoguangrong at linux.vnet.ibm.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/kvm-all.c b/kvm-all.c
index 8e7bbf8..405480e 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -206,7 +206,8 @@ static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot)
     if (s->migration_log) {
         mem.flags |= KVM_MEM_LOG_DIRTY_PAGES;
     }
-    if (mem.flags & KVM_MEM_READONLY) {
+
+    if (slot->memory_size && mem.flags & KVM_MEM_READONLY) {
         /* Set the slot size to 0 before setting the slot to the desired
          * value. This is needed based on KVM commit 75d61fbc. */
         mem.memory_size = 0;
commit 25b483381adf4144bad3cf3f433b4658da5e15bb
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon May 20 16:16:16 2013 +0100

    configure: Report unknown target names more helpfully
    
    If the user specifies a target list themselves, check each entry
    to make sure it's a target we recognise. This allows us to print
    a helpful error message, rather than falling through (where we
    would probably eventually end up hitting the uninformative
    "ERROR: Unsupported target CPU").
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1369062976-301-3-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/configure b/configure
index 9fe7053..70c41b0 100755
--- a/configure
+++ b/configure
@@ -1343,6 +1343,19 @@ if test -z "${target_list+xxx}" ; then
 else
     target_list=`echo "$target_list" | sed -e 's/,/ /g'`
 fi
+
+# Check that we recognised the target name; this allows a more
+# friendly error message than if we let it fall through.
+for target in $target_list; do
+    case " $default_target_list " in
+        *" $target "*)
+            ;;
+        *)
+            error_exit "Unknown target name '$target'"
+            ;;
+    esac
+done
+
 # see if system emulation was really requested
 case " $target_list " in
   *"-softmmu "*) softmmu=yes
commit 6e92f823b67d87aa96df01b0cb01f81ac71ec5e3
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon May 20 16:16:15 2013 +0100

    configure: Autogenerate default target list
    
    Autogenerate the default target list based on what files exist
    in default-configs; this allows us to remove one of the places
    that has to be kept up to date with a complete list of every
    target we support.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1369062976-301-2-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/configure b/configure
index d5abf98..9fe7053 100755
--- a/configure
+++ b/configure
@@ -974,78 +974,22 @@ EXTRA_CFLAGS="$CPU_CFLAGS $EXTRA_CFLAGS"
 
 default_target_list=""
 
-# these targets are portable
-if [ "$softmmu" = "yes" ] ; then
-    default_target_list="\
-i386-softmmu \
-x86_64-softmmu \
-alpha-softmmu \
-arm-softmmu \
-cris-softmmu \
-lm32-softmmu \
-m68k-softmmu \
-microblaze-softmmu \
-microblazeel-softmmu \
-mips-softmmu \
-mipsel-softmmu \
-mips64-softmmu \
-mips64el-softmmu \
-moxie-softmmu \
-or32-softmmu \
-ppc-softmmu \
-ppcemb-softmmu \
-ppc64-softmmu \
-sh4-softmmu \
-sh4eb-softmmu \
-sparc-softmmu \
-sparc64-softmmu \
-s390x-softmmu \
-xtensa-softmmu \
-xtensaeb-softmmu \
-unicore32-softmmu \
-"
-fi
-# the following are Linux specific
-if [ "$linux_user" = "yes" ] ; then
-    default_target_list="${default_target_list}\
-i386-linux-user \
-x86_64-linux-user \
-alpha-linux-user \
-arm-linux-user \
-armeb-linux-user \
-cris-linux-user \
-m68k-linux-user \
-microblaze-linux-user \
-microblazeel-linux-user \
-mips-linux-user \
-mipsel-linux-user \
-mips64-linux-user \
-mips64el-linux-user \
-mipsn32-linux-user \
-mipsn32el-linux-user \
-or32-linux-user \
-ppc-linux-user \
-ppc64-linux-user \
-ppc64abi32-linux-user \
-sh4-linux-user \
-sh4eb-linux-user \
-sparc-linux-user \
-sparc64-linux-user \
-sparc32plus-linux-user \
-unicore32-linux-user \
-s390x-linux-user \
-"
-fi
-# the following are BSD specific
-if [ "$bsd_user" = "yes" ] ; then
-    default_target_list="${default_target_list}\
-i386-bsd-user \
-x86_64-bsd-user \
-sparc-bsd-user \
-sparc64-bsd-user \
-"
+mak_wilds=""
+
+if [ "$softmmu" = "yes" ]; then
+    mak_wilds="${mak_wilds} $source_path/default-configs/*-softmmu.mak"
+fi
+if [ "$linux_user" = "yes" ]; then
+    mak_wilds="${mak_wilds} $source_path/default-configs/*-linux-user.mak"
+fi
+if [ "$bsd_user" = "yes" ]; then
+    mak_wilds="${mak_wilds} $source_path/default-configs/*-bsd-user.mak"
 fi
 
+for config in $mak_wilds; do
+    default_target_list="${default_target_list} $(basename "$config" .mak)"
+done
+
 if test x"$show_help" = x"yes" ; then
 cat << EOF
 
commit 0ded1fe5f36765b97b15a7afebb6d04ddcc4771c
Merge: 8b779b3 95669e6
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Jun 3 13:24:25 2013 -0500

    Merge remote-tracking branch 'pmaydell/arm-devs.next' into staging
    
    # By Peter Crosthwaite (20) and others
    # Via Peter Maydell
    * pmaydell/arm-devs.next: (24 commits)
      i.MX: Improve EPIT timer code.
      exynos4210.c: register rom_mem for memory migration
      hw/arm/exynos4210.c: convert chipid_and_omr to an mmio region
      i.MX: split GPT and EPIT timer implementation
      sd/sd.c: Fix "inquiry" ACMD41
      sd/sdhci:ADMA: fix interrupt
      sd/sdhci.c: Fix bdata_read DPRINT message
      sd/sdhci: Fix Buffer Write Ready interrupt
      sd/sdhci.c: Only reset data_count on new commands
      xilinx_spips: lqspi: Fix byte/misaligned access
      xilinx_spips: lqspi: Push more data to tx-fifo
      xilinx_spips: Multiple debug verbosity levels
      xilinx_spips: Debug msgs for Snoop state
      xilinx_spips: Fix striping behaviour
      xilinx_spips: Fix CTRL register RW bits
      xilinx_spips: lqspi: Dont touch config register
      xilinx_spips: Implement automatic CS
      xilinx_spips: Add automatic start support
      xilinx_spips: Trash LQ page cache on mode change
      xilinx_spips: Fix QSPI FIFO size
      ...
    
    Message-id: 1370277021-26129-1-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 95669e69848eda87861e1ec3016562101542f543
Author: Jean-Christophe DUBOIS <jcd at tribudubois.net>
Date:   Mon Jun 3 17:17:46 2013 +0100

    i.MX: Improve EPIT timer code.
    
    * Unify function and type naming
    * use dynamic cast whenever possible
    * simplify Debug printf.
    * use new style device intialization.
    
    Signed-off-by: Jean-Christophe DUBOIS <jcd at tribudubois.net>
    Reviewed-by: Peter Chubb <peter.chubb at nicta.com.au>
    Message-id: 1369839656-24466-1-git-send-email-jcd at tribudubois.net
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 451e646..7cdb006 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -5,6 +5,7 @@
  * Copyright (c) 2011 NICTA Pty Ltd
  * Originally written by Hans Jiang
  * Updated by Peter Chubb
+ * Updated by Jean-Christophe Dubois
  *
  * This code is licensed under GPL version 2 or later.  See
  * the COPYING file in the top-level directory.
@@ -18,10 +19,31 @@
 #include "hw/sysbus.h"
 #include "hw/arm/imx.h"
 
-//#define DEBUG_TIMER 1
-#ifdef DEBUG_TIMER
+#define TYPE_IMX_EPIT "imx.epit"
+
+#define DEBUG_TIMER 0
+#if DEBUG_TIMER
+
+static char const *imx_epit_reg_name(uint32_t reg)
+{
+    switch (reg) {
+    case 0:
+        return "CR";
+    case 1:
+        return "SR";
+    case 2:
+        return "LR";
+    case 3:
+        return "CMP";
+    case 4:
+        return "CNT";
+    default:
+        return "[?]";
+    }
+}
+
 #  define DPRINTF(fmt, args...) \
-      do { printf("imx_timer: " fmt , ##args); } while (0)
+          do { printf("%s: " fmt , __func__, ##args); } while (0)
 #else
 #  define DPRINTF(fmt, args...) do {} while (0)
 #endif
@@ -32,12 +54,15 @@
  */
 #define DEBUG_IMPLEMENTATION 1
 #if DEBUG_IMPLEMENTATION
-#  define IPRINTF(fmt, args...)                                         \
-    do  { fprintf(stderr, "imx_timer: " fmt, ##args); } while (0)
+#  define IPRINTF(fmt, args...) \
+          do { fprintf(stderr, "%s: " fmt, __func__, ##args); } while (0)
 #else
 #  define IPRINTF(fmt, args...) do {} while (0)
 #endif
 
+#define IMX_EPIT(obj) \
+        OBJECT_CHECK(IMXEPITState, (obj), TYPE_IMX_EPIT)
+
 /*
  * EPIT: Enhanced periodic interrupt timer
  */
@@ -63,7 +88,7 @@
  * Exact clock frequencies vary from board to board.
  * These are typical.
  */
-static const IMXClk imx_timerp_clocks[] =  {
+static const IMXClk imx_epit_clocks[] =  {
     0,        /* 00 disabled */
     IPG,      /* 01 ipg_clk, ~532MHz */
     IPG,      /* 10 ipg_clk_highfreq */
@@ -85,32 +110,33 @@ typedef struct {
 
     uint32_t freq;
     qemu_irq irq;
-} IMXTimerPState;
+} IMXEPITState;
 
 /*
  * Update interrupt status
  */
-static void imx_timerp_update(IMXTimerPState *s)
+static void imx_epit_update_int(IMXEPITState *s)
 {
-    if (s->sr && (s->cr & CR_OCIEN)) {
+    if (s->sr && (s->cr & CR_OCIEN) && (s->cr & CR_EN)) {
         qemu_irq_raise(s->irq);
     } else {
         qemu_irq_lower(s->irq);
     }
 }
 
-static void set_timerp_freq(IMXTimerPState *s)
+static void imx_epit_set_freq(IMXEPITState *s)
 {
-    unsigned clksrc;
-    unsigned prescaler;
+    uint32_t clksrc;
+    uint32_t prescaler;
     uint32_t freq;
 
     clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, 2);
     prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, 12);
 
-    freq = imx_clock_frequency(s->ccm, imx_timerp_clocks[clksrc]) / prescaler;
+    freq = imx_clock_frequency(s->ccm, imx_epit_clocks[clksrc]) / prescaler;
 
     s->freq = freq;
+
     DPRINTF("Setting ptimer frequency to %u\n", freq);
 
     if (freq) {
@@ -119,9 +145,9 @@ static void set_timerp_freq(IMXTimerPState *s)
     }
 }
 
-static void imx_timerp_reset(DeviceState *dev)
+static void imx_epit_reset(DeviceState *dev)
 {
-    IMXTimerPState *s = container_of(dev, IMXTimerPState, busdev.qdev);
+    IMXEPITState *s = IMX_EPIT(dev);
 
     /*
      * Soft reset doesn't touch some bits; hard reset clears them
@@ -135,7 +161,7 @@ static void imx_timerp_reset(DeviceState *dev)
     ptimer_stop(s->timer_cmp);
     ptimer_stop(s->timer_reload);
     /* compute new frequency */
-    set_timerp_freq(s);
+    imx_epit_set_freq(s);
     /* init both timers to TIMER_MAX */
     ptimer_set_limit(s->timer_cmp, TIMER_MAX, 1);
     ptimer_set_limit(s->timer_reload, TIMER_MAX, 1);
@@ -145,52 +171,56 @@ static void imx_timerp_reset(DeviceState *dev)
     }
 }
 
-static uint32_t imx_timerp_update_counts(IMXTimerPState *s)
+static uint32_t imx_epit_update_count(IMXEPITState *s)
 {
      s->cnt = ptimer_get_count(s->timer_reload);
 
      return s->cnt;
 }
 
-static uint64_t imx_timerp_read(void *opaque, hwaddr offset,
-                                unsigned size)
+static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
 {
-    IMXTimerPState *s = (IMXTimerPState *)opaque;
+    IMXEPITState *s = IMX_EPIT(opaque);
+    uint32_t reg_value = 0;
+    uint32_t reg = offset >> 2;
 
-    DPRINTF("p-read(offset=%x)", (unsigned int)(offset >> 2));
-    switch (offset >> 2) {
+    switch (reg) {
     case 0: /* Control Register */
-        DPRINTF("cr %x\n", s->cr);
-        return s->cr;
+        reg_value = s->cr;
+        break;
 
     case 1: /* Status Register */
-        DPRINTF("sr %x\n", s->sr);
-        return s->sr;
+        reg_value = s->sr;
+        break;
 
     case 2: /* LR - ticks*/
-        DPRINTF("lr %x\n", s->lr);
-        return s->lr;
+        reg_value = s->lr;
+        break;
 
     case 3: /* CMP */
-        DPRINTF("cmp %x\n", s->cmp);
-        return s->cmp;
+        reg_value = s->cmp;
+        break;
 
     case 4: /* CNT */
-        imx_timerp_update_counts(s);
-        DPRINTF(" cnt = %x\n", s->cnt);
-        return s->cnt;
+        imx_epit_update_count(s);
+        reg_value = s->cnt;
+        break;
+
+    default:
+        IPRINTF("Bad offset %x\n", reg);
+        break;
     }
 
-    IPRINTF("imx_timerp_read: Bad offset %x\n",
-            (int)offset >> 2);
-    return 0;
+    DPRINTF("(%s) = 0x%08x\n", imx_epit_reg_name(reg), reg_value);
+
+    return reg_value;
 }
 
-static void imx_reload_compare_timer(IMXTimerPState *s)
+static void imx_epit_reload_compare_timer(IMXEPITState *s)
 {
     if ((s->cr & CR_OCIEN) && s->cmp) {
         /* if the compare feature is on */
-        uint32_t tmp = imx_timerp_update_counts(s);
+        uint32_t tmp = imx_epit_update_count(s);
         if (tmp > s->cmp) {
             /* reinit the cmp timer if required */
             ptimer_set_count(s->timer_cmp, tmp - s->cmp);
@@ -202,21 +232,22 @@ static void imx_reload_compare_timer(IMXTimerPState *s)
     }
 }
 
-static void imx_timerp_write(void *opaque, hwaddr offset,
-                             uint64_t value, unsigned size)
+static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
+                           unsigned size)
 {
-    IMXTimerPState *s = (IMXTimerPState *)opaque;
-    DPRINTF("p-write(offset=%x, value = %x)\n", (unsigned int)offset >> 2,
-            (unsigned int)value);
+    IMXEPITState *s = IMX_EPIT(opaque);
+    uint32_t reg = offset >> 2;
+
+    DPRINTF("(%s, value = 0x%08x)\n", imx_epit_reg_name(reg), (uint32_t)value);
 
-    switch (offset >> 2) {
+    switch (reg) {
     case 0: /* CR */
         s->cr = value & 0x03ffffff;
         if (s->cr & CR_SWR) {
             /* handle the reset */
-            imx_timerp_reset(&s->busdev.qdev);
+            imx_epit_reset(DEVICE(s));
         } else {
-            set_timerp_freq(s);
+            imx_epit_set_freq(s);
         }
 
         if (s->freq && (s->cr & CR_EN)) {
@@ -228,7 +259,7 @@ static void imx_timerp_write(void *opaque, hwaddr offset,
                 }
             }
 
-            imx_reload_compare_timer(s);
+            imx_epit_reload_compare_timer(s);
 
             ptimer_run(s->timer_reload, 1);
         } else {
@@ -242,7 +273,7 @@ static void imx_timerp_write(void *opaque, hwaddr offset,
         /* writing 1 to OCIF clear the OCIF bit */
         if (value & 0x01) {
             s->sr = 0;
-            imx_timerp_update(s);
+            imx_epit_update_int(s);
         }
         break;
 
@@ -258,28 +289,29 @@ static void imx_timerp_write(void *opaque, hwaddr offset,
             ptimer_set_count(s->timer_reload, s->lr);
         }
 
-        imx_reload_compare_timer(s);
+        imx_epit_reload_compare_timer(s);
 
         break;
 
     case 3: /* CMP */
         s->cmp = value;
 
-        imx_reload_compare_timer(s);
+        imx_epit_reload_compare_timer(s);
 
         break;
 
     default:
-        IPRINTF("imx_timerp_write: Bad offset %x\n",
-                   (int)offset >> 2);
+        IPRINTF("Bad offset %x\n", reg);
+
+        break;
     }
 }
 
-static void imx_timerp_reload(void *opaque)
+static void imx_epit_timeout(void *opaque)
 {
-    IMXTimerPState *s = (IMXTimerPState *)opaque;
+    IMXEPITState *s = IMX_EPIT(opaque);
 
-    DPRINTF("imxp reload\n");
+    DPRINTF("\n");
 
     if (!(s->cr & CR_EN)) {
         return;
@@ -295,110 +327,106 @@ static void imx_timerp_reload(void *opaque)
         /* if compare register is 0 then we handle the interrupt here */
         if (s->cmp == 0) {
             s->sr = 1;
-            imx_timerp_update(s);
+            imx_epit_update_int(s);
         } else if (s->cmp <= s->lr) {
             /* We should launch the compare register */
             ptimer_set_count(s->timer_cmp, s->lr - s->cmp);
             ptimer_run(s->timer_cmp, 0);
         } else {
-            IPRINTF("imxp reload: s->lr < s->cmp\n");
+            IPRINTF("s->lr < s->cmp\n");
         }
     }
 }
 
-static void imx_timerp_cmp(void *opaque)
+static void imx_epit_cmp(void *opaque)
 {
-    IMXTimerPState *s = (IMXTimerPState *)opaque;
+    IMXEPITState *s = IMX_EPIT(opaque);
 
-    DPRINTF("imxp compare\n");
+    DPRINTF("\n");
 
     ptimer_stop(s->timer_cmp);
 
     /* compare register is not 0 */
     if (s->cmp) {
         s->sr = 1;
-        imx_timerp_update(s);
+        imx_epit_update_int(s);
     }
 }
 
-void imx_timerp_create(const hwaddr addr,
-                              qemu_irq irq,
-                              DeviceState *ccm)
+void imx_timerp_create(const hwaddr addr, qemu_irq irq, DeviceState *ccm)
 {
-    IMXTimerPState *pp;
+    IMXEPITState *pp;
     DeviceState *dev;
 
-    dev = sysbus_create_simple("imx_timerp", addr, irq);
-    pp = container_of(dev, IMXTimerPState, busdev.qdev);
+    dev = sysbus_create_simple(TYPE_IMX_EPIT, addr, irq);
+    pp = IMX_EPIT(dev);
     pp->ccm = ccm;
 }
 
-static const MemoryRegionOps imx_timerp_ops = {
-  .read = imx_timerp_read,
-  .write = imx_timerp_write,
+static const MemoryRegionOps imx_epit_ops = {
+  .read = imx_epit_read,
+  .write = imx_epit_write,
   .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static const VMStateDescription vmstate_imx_timerp = {
-    .name = "imx-timerp",
+static const VMStateDescription vmstate_imx_timer_epit = {
+    .name = TYPE_IMX_EPIT,
     .version_id = 2,
     .minimum_version_id = 2,
     .minimum_version_id_old = 2,
     .fields      = (VMStateField[]) {
-        VMSTATE_UINT32(cr, IMXTimerPState),
-        VMSTATE_UINT32(sr, IMXTimerPState),
-        VMSTATE_UINT32(lr, IMXTimerPState),
-        VMSTATE_UINT32(cmp, IMXTimerPState),
-        VMSTATE_UINT32(cnt, IMXTimerPState),
-        VMSTATE_UINT32(freq, IMXTimerPState),
-        VMSTATE_PTIMER(timer_reload, IMXTimerPState),
-        VMSTATE_PTIMER(timer_cmp, IMXTimerPState),
+        VMSTATE_UINT32(cr, IMXEPITState),
+        VMSTATE_UINT32(sr, IMXEPITState),
+        VMSTATE_UINT32(lr, IMXEPITState),
+        VMSTATE_UINT32(cmp, IMXEPITState),
+        VMSTATE_UINT32(cnt, IMXEPITState),
+        VMSTATE_UINT32(freq, IMXEPITState),
+        VMSTATE_PTIMER(timer_reload, IMXEPITState),
+        VMSTATE_PTIMER(timer_cmp, IMXEPITState),
         VMSTATE_END_OF_LIST()
     }
 };
 
-static int imx_timerp_init(SysBusDevice *dev)
+static void imx_epit_realize(DeviceState *dev, Error **errp)
 {
-    IMXTimerPState *s = FROM_SYSBUS(IMXTimerPState, dev);
+    IMXEPITState *s = IMX_EPIT(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
     QEMUBH *bh;
 
-    DPRINTF("imx_timerp_init\n");
-    sysbus_init_irq(dev, &s->irq);
-    memory_region_init_io(&s->iomem, &imx_timerp_ops,
-                          s, "imxp-timer",
+    DPRINTF("\n");
+
+    sysbus_init_irq(sbd, &s->irq);
+    memory_region_init_io(&s->iomem, &imx_epit_ops, s, TYPE_IMX_EPIT,
                           0x00001000);
-    sysbus_init_mmio(dev, &s->iomem);
+    sysbus_init_mmio(sbd, &s->iomem);
 
-    bh = qemu_bh_new(imx_timerp_reload, s);
+    bh = qemu_bh_new(imx_epit_timeout, s);
     s->timer_reload = ptimer_init(bh);
 
-    bh = qemu_bh_new(imx_timerp_cmp, s);
+    bh = qemu_bh_new(imx_epit_cmp, s);
     s->timer_cmp = ptimer_init(bh);
-
-    return 0;
 }
 
-
-static void imx_timerp_class_init(ObjectClass *klass, void *data)
+static void imx_epit_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc  = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-    k->init = imx_timerp_init;
-    dc->vmsd = &vmstate_imx_timerp;
-    dc->reset = imx_timerp_reset;
+
+    dc->realize = imx_epit_realize;
+    dc->reset = imx_epit_reset;
+    dc->vmsd = &vmstate_imx_timer_epit;
     dc->desc = "i.MX periodic timer";
 }
 
-static const TypeInfo imx_timerp_info = {
-    .name = "imx_timerp",
+static const TypeInfo imx_epit_info = {
+    .name = TYPE_IMX_EPIT,
     .parent = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(IMXTimerPState),
-    .class_init = imx_timerp_class_init,
+    .instance_size = sizeof(IMXEPITState),
+    .class_init = imx_epit_class_init,
 };
 
-static void imx_timer_register_types(void)
+static void imx_epit_register_types(void)
 {
-    type_register_static(&imx_timerp_info);
+    type_register_static(&imx_epit_info);
 }
 
-type_init(imx_timer_register_types)
+type_init(imx_epit_register_types)
commit 6539ed21b1d5c93e8add2f7b2bf9856889e6d1ac
Author: Igor Mitsyanko <i.mitsyanko at samsung.com>
Date:   Mon Jun 3 17:17:46 2013 +0100

    exynos4210.c: register rom_mem for memory migration
    
    Even if we do not register newly created RAM MemoryRegion for migration with
    vmstate_register_ram_global() function, ram_save_setup() still saves this region
    to snapshot file with empty idstr=="". Consequently this results in error during
    VM loading in ram_load().
    Register rom_mem for migration.
    
    Signed-off-by: Igor Mitsyanko <i.mitsyanko at samsung.com>
    Message-id: 1368199981-45292-3-git-send-email-i.mitsyanko at gmail.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index 502b106..8186f14 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -249,6 +249,7 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
     /* Internal ROM */
     memory_region_init_ram(&s->irom_mem, "exynos4210.irom",
                            EXYNOS4210_IROM_SIZE);
+    vmstate_register_ram_global(&s->irom_mem);
     memory_region_set_readonly(&s->irom_mem, true);
     memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR,
                                 &s->irom_mem);
commit 11a5e48249d8c34211065c25ddf222f031a0338e
Author: Igor Mitsyanko <i.mitsyanko at samsung.com>
Date:   Mon Jun 3 17:17:46 2013 +0100

    hw/arm/exynos4210.c: convert chipid_and_omr to an mmio region
    
    Exynos SoC was misusing memory_region_init_ram_ptr(): this interface can safely
    be used only for memory regions which size is a multiple of target page size.
    Change chipid_and_omr memory to an mmio region to fix this.
    
    Signed-off-by: Igor Mitsyanko <i.mitsyanko at samsung.com>
    Message-id: 1368199981-45292-2-git-send-email-i.mitsyanko at gmail.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index c8101d3..502b106 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -79,6 +79,28 @@
 static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
                                     0x09, 0x00, 0x00, 0x00 };
 
+static uint64_t exynos4210_chipid_and_omr_read(void *opaque, hwaddr offset,
+                                               unsigned size)
+{
+    assert(offset < sizeof(chipid_and_omr));
+    return chipid_and_omr[offset];
+}
+
+static void exynos4210_chipid_and_omr_write(void *opaque, hwaddr offset,
+                                            uint64_t value, unsigned size)
+{
+    return;
+}
+
+static const MemoryRegionOps exynos4210_chipid_and_omr_ops = {
+    .read = exynos4210_chipid_and_omr_read,
+    .write = exynos4210_chipid_and_omr_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .max_access_size = 1,
+    }
+};
+
 void exynos4210_write_secondary(ARMCPU *cpu,
         const struct arm_boot_info *info)
 {
@@ -219,9 +241,8 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
     /*** Memory ***/
 
     /* Chip-ID and OMR */
-    memory_region_init_ram_ptr(&s->chipid_mem, "exynos4210.chipid",
-            sizeof(chipid_and_omr), chipid_and_omr);
-    memory_region_set_readonly(&s->chipid_mem, true);
+    memory_region_init_io(&s->chipid_mem, &exynos4210_chipid_and_omr_ops,
+        NULL, "exynos4210.chipid", sizeof(chipid_and_omr));
     memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR,
                                 &s->chipid_mem);
 
commit a50c0d6f72830ca3016e63ded6ccfd4e951c172f
Author: Jean-Christophe DUBOIS <jcd at tribudubois.net>
Date:   Mon Jun 3 17:17:45 2013 +0100

    i.MX: split GPT and EPIT timer implementation
    
    There is no common code between these 2 timer implementation.
    So it is better to split them.
    
    Signed-off-by: Jean-Christophe DUBOIS <jcd at tribudubois.net>
    Message-id: 1368990197-19694-1-git-send-email-jcd at tribudubois.net
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index e4bd17f..32b5c1a 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -11,7 +11,8 @@ common-obj-$(CONFIG_XILINX) += xilinx_timer.o
 common-obj-$(CONFIG_SLAVIO) += slavio_timer.o
 common-obj-$(CONFIG_ETRAXFS) += etraxfs_timer.o
 common-obj-$(CONFIG_GRLIB) += grlib_gptimer.o
-common-obj-$(CONFIG_IMX) += imx_timer.o
+common-obj-$(CONFIG_IMX) += imx_epit.o
+common-obj-$(CONFIG_IMX) += imx_gpt.o
 common-obj-$(CONFIG_LM32) += lm32_timer.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o
 
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
new file mode 100644
index 0000000..451e646
--- /dev/null
+++ b/hw/timer/imx_epit.c
@@ -0,0 +1,404 @@
+/*
+ * IMX EPIT Timer
+ *
+ * Copyright (c) 2008 OK Labs
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally written by Hans Jiang
+ * Updated by Peter Chubb
+ *
+ * This code is licensed under GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw/hw.h"
+#include "qemu/bitops.h"
+#include "qemu/timer.h"
+#include "hw/ptimer.h"
+#include "hw/sysbus.h"
+#include "hw/arm/imx.h"
+
+//#define DEBUG_TIMER 1
+#ifdef DEBUG_TIMER
+#  define DPRINTF(fmt, args...) \
+      do { printf("imx_timer: " fmt , ##args); } while (0)
+#else
+#  define DPRINTF(fmt, args...) do {} while (0)
+#endif
+
+/*
+ * Define to 1 for messages about attempts to
+ * access unimplemented registers or similar.
+ */
+#define DEBUG_IMPLEMENTATION 1
+#if DEBUG_IMPLEMENTATION
+#  define IPRINTF(fmt, args...)                                         \
+    do  { fprintf(stderr, "imx_timer: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+/*
+ * EPIT: Enhanced periodic interrupt timer
+ */
+
+#define CR_EN       (1 << 0)
+#define CR_ENMOD    (1 << 1)
+#define CR_OCIEN    (1 << 2)
+#define CR_RLD      (1 << 3)
+#define CR_PRESCALE_SHIFT (4)
+#define CR_PRESCALE_MASK  (0xfff)
+#define CR_SWR      (1 << 16)
+#define CR_IOVW     (1 << 17)
+#define CR_DBGEN    (1 << 18)
+#define CR_WAITEN   (1 << 19)
+#define CR_DOZEN    (1 << 20)
+#define CR_STOPEN   (1 << 21)
+#define CR_CLKSRC_SHIFT (24)
+#define CR_CLKSRC_MASK  (0x3 << CR_CLKSRC_SHIFT)
+
+#define TIMER_MAX  0XFFFFFFFFUL
+
+/*
+ * Exact clock frequencies vary from board to board.
+ * These are typical.
+ */
+static const IMXClk imx_timerp_clocks[] =  {
+    0,        /* 00 disabled */
+    IPG,      /* 01 ipg_clk, ~532MHz */
+    IPG,      /* 10 ipg_clk_highfreq */
+    CLK_32k,  /* 11 ipg_clk_32k -- ~32kHz */
+};
+
+typedef struct {
+    SysBusDevice busdev;
+    ptimer_state *timer_reload;
+    ptimer_state *timer_cmp;
+    MemoryRegion iomem;
+    DeviceState *ccm;
+
+    uint32_t cr;
+    uint32_t sr;
+    uint32_t lr;
+    uint32_t cmp;
+    uint32_t cnt;
+
+    uint32_t freq;
+    qemu_irq irq;
+} IMXTimerPState;
+
+/*
+ * Update interrupt status
+ */
+static void imx_timerp_update(IMXTimerPState *s)
+{
+    if (s->sr && (s->cr & CR_OCIEN)) {
+        qemu_irq_raise(s->irq);
+    } else {
+        qemu_irq_lower(s->irq);
+    }
+}
+
+static void set_timerp_freq(IMXTimerPState *s)
+{
+    unsigned clksrc;
+    unsigned prescaler;
+    uint32_t freq;
+
+    clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, 2);
+    prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, 12);
+
+    freq = imx_clock_frequency(s->ccm, imx_timerp_clocks[clksrc]) / prescaler;
+
+    s->freq = freq;
+    DPRINTF("Setting ptimer frequency to %u\n", freq);
+
+    if (freq) {
+        ptimer_set_freq(s->timer_reload, freq);
+        ptimer_set_freq(s->timer_cmp, freq);
+    }
+}
+
+static void imx_timerp_reset(DeviceState *dev)
+{
+    IMXTimerPState *s = container_of(dev, IMXTimerPState, busdev.qdev);
+
+    /*
+     * Soft reset doesn't touch some bits; hard reset clears them
+     */
+    s->cr &= ~(CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
+    s->sr = 0;
+    s->lr = TIMER_MAX;
+    s->cmp = 0;
+    s->cnt = 0;
+    /* stop both timers */
+    ptimer_stop(s->timer_cmp);
+    ptimer_stop(s->timer_reload);
+    /* compute new frequency */
+    set_timerp_freq(s);
+    /* init both timers to TIMER_MAX */
+    ptimer_set_limit(s->timer_cmp, TIMER_MAX, 1);
+    ptimer_set_limit(s->timer_reload, TIMER_MAX, 1);
+    if (s->freq && (s->cr & CR_EN)) {
+        /* if the timer is still enabled, restart it */
+        ptimer_run(s->timer_reload, 1);
+    }
+}
+
+static uint32_t imx_timerp_update_counts(IMXTimerPState *s)
+{
+     s->cnt = ptimer_get_count(s->timer_reload);
+
+     return s->cnt;
+}
+
+static uint64_t imx_timerp_read(void *opaque, hwaddr offset,
+                                unsigned size)
+{
+    IMXTimerPState *s = (IMXTimerPState *)opaque;
+
+    DPRINTF("p-read(offset=%x)", (unsigned int)(offset >> 2));
+    switch (offset >> 2) {
+    case 0: /* Control Register */
+        DPRINTF("cr %x\n", s->cr);
+        return s->cr;
+
+    case 1: /* Status Register */
+        DPRINTF("sr %x\n", s->sr);
+        return s->sr;
+
+    case 2: /* LR - ticks*/
+        DPRINTF("lr %x\n", s->lr);
+        return s->lr;
+
+    case 3: /* CMP */
+        DPRINTF("cmp %x\n", s->cmp);
+        return s->cmp;
+
+    case 4: /* CNT */
+        imx_timerp_update_counts(s);
+        DPRINTF(" cnt = %x\n", s->cnt);
+        return s->cnt;
+    }
+
+    IPRINTF("imx_timerp_read: Bad offset %x\n",
+            (int)offset >> 2);
+    return 0;
+}
+
+static void imx_reload_compare_timer(IMXTimerPState *s)
+{
+    if ((s->cr & CR_OCIEN) && s->cmp) {
+        /* if the compare feature is on */
+        uint32_t tmp = imx_timerp_update_counts(s);
+        if (tmp > s->cmp) {
+            /* reinit the cmp timer if required */
+            ptimer_set_count(s->timer_cmp, tmp - s->cmp);
+            if ((s->cr & CR_EN)) {
+                /* Restart the cmp timer if required */
+                ptimer_run(s->timer_cmp, 0);
+            }
+        }
+    }
+}
+
+static void imx_timerp_write(void *opaque, hwaddr offset,
+                             uint64_t value, unsigned size)
+{
+    IMXTimerPState *s = (IMXTimerPState *)opaque;
+    DPRINTF("p-write(offset=%x, value = %x)\n", (unsigned int)offset >> 2,
+            (unsigned int)value);
+
+    switch (offset >> 2) {
+    case 0: /* CR */
+        s->cr = value & 0x03ffffff;
+        if (s->cr & CR_SWR) {
+            /* handle the reset */
+            imx_timerp_reset(&s->busdev.qdev);
+        } else {
+            set_timerp_freq(s);
+        }
+
+        if (s->freq && (s->cr & CR_EN)) {
+            if (s->cr & CR_ENMOD) {
+                if (s->cr & CR_RLD) {
+                    ptimer_set_limit(s->timer_reload, s->lr, 1);
+                } else {
+                    ptimer_set_limit(s->timer_reload, TIMER_MAX, 1);
+                }
+            }
+
+            imx_reload_compare_timer(s);
+
+            ptimer_run(s->timer_reload, 1);
+        } else {
+            /* stop both timers */
+            ptimer_stop(s->timer_reload);
+            ptimer_stop(s->timer_cmp);
+        }
+        break;
+
+    case 1: /* SR - ACK*/
+        /* writing 1 to OCIF clear the OCIF bit */
+        if (value & 0x01) {
+            s->sr = 0;
+            imx_timerp_update(s);
+        }
+        break;
+
+    case 2: /* LR - set ticks */
+        s->lr = value;
+
+        if (s->cr & CR_RLD) {
+            /* Also set the limit if the LRD bit is set */
+            /* If IOVW bit is set then set the timer value */
+            ptimer_set_limit(s->timer_reload, s->lr, s->cr & CR_IOVW);
+        } else if (s->cr & CR_IOVW) {
+            /* If IOVW bit is set then set the timer value */
+            ptimer_set_count(s->timer_reload, s->lr);
+        }
+
+        imx_reload_compare_timer(s);
+
+        break;
+
+    case 3: /* CMP */
+        s->cmp = value;
+
+        imx_reload_compare_timer(s);
+
+        break;
+
+    default:
+        IPRINTF("imx_timerp_write: Bad offset %x\n",
+                   (int)offset >> 2);
+    }
+}
+
+static void imx_timerp_reload(void *opaque)
+{
+    IMXTimerPState *s = (IMXTimerPState *)opaque;
+
+    DPRINTF("imxp reload\n");
+
+    if (!(s->cr & CR_EN)) {
+        return;
+    }
+
+    if (s->cr & CR_RLD) {
+        ptimer_set_limit(s->timer_reload, s->lr, 1);
+    } else {
+        ptimer_set_limit(s->timer_reload, TIMER_MAX, 1);
+    }
+
+    if (s->cr & CR_OCIEN) {
+        /* if compare register is 0 then we handle the interrupt here */
+        if (s->cmp == 0) {
+            s->sr = 1;
+            imx_timerp_update(s);
+        } else if (s->cmp <= s->lr) {
+            /* We should launch the compare register */
+            ptimer_set_count(s->timer_cmp, s->lr - s->cmp);
+            ptimer_run(s->timer_cmp, 0);
+        } else {
+            IPRINTF("imxp reload: s->lr < s->cmp\n");
+        }
+    }
+}
+
+static void imx_timerp_cmp(void *opaque)
+{
+    IMXTimerPState *s = (IMXTimerPState *)opaque;
+
+    DPRINTF("imxp compare\n");
+
+    ptimer_stop(s->timer_cmp);
+
+    /* compare register is not 0 */
+    if (s->cmp) {
+        s->sr = 1;
+        imx_timerp_update(s);
+    }
+}
+
+void imx_timerp_create(const hwaddr addr,
+                              qemu_irq irq,
+                              DeviceState *ccm)
+{
+    IMXTimerPState *pp;
+    DeviceState *dev;
+
+    dev = sysbus_create_simple("imx_timerp", addr, irq);
+    pp = container_of(dev, IMXTimerPState, busdev.qdev);
+    pp->ccm = ccm;
+}
+
+static const MemoryRegionOps imx_timerp_ops = {
+  .read = imx_timerp_read,
+  .write = imx_timerp_write,
+  .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const VMStateDescription vmstate_imx_timerp = {
+    .name = "imx-timerp",
+    .version_id = 2,
+    .minimum_version_id = 2,
+    .minimum_version_id_old = 2,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(cr, IMXTimerPState),
+        VMSTATE_UINT32(sr, IMXTimerPState),
+        VMSTATE_UINT32(lr, IMXTimerPState),
+        VMSTATE_UINT32(cmp, IMXTimerPState),
+        VMSTATE_UINT32(cnt, IMXTimerPState),
+        VMSTATE_UINT32(freq, IMXTimerPState),
+        VMSTATE_PTIMER(timer_reload, IMXTimerPState),
+        VMSTATE_PTIMER(timer_cmp, IMXTimerPState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static int imx_timerp_init(SysBusDevice *dev)
+{
+    IMXTimerPState *s = FROM_SYSBUS(IMXTimerPState, dev);
+    QEMUBH *bh;
+
+    DPRINTF("imx_timerp_init\n");
+    sysbus_init_irq(dev, &s->irq);
+    memory_region_init_io(&s->iomem, &imx_timerp_ops,
+                          s, "imxp-timer",
+                          0x00001000);
+    sysbus_init_mmio(dev, &s->iomem);
+
+    bh = qemu_bh_new(imx_timerp_reload, s);
+    s->timer_reload = ptimer_init(bh);
+
+    bh = qemu_bh_new(imx_timerp_cmp, s);
+    s->timer_cmp = ptimer_init(bh);
+
+    return 0;
+}
+
+
+static void imx_timerp_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc  = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+    k->init = imx_timerp_init;
+    dc->vmsd = &vmstate_imx_timerp;
+    dc->reset = imx_timerp_reset;
+    dc->desc = "i.MX periodic timer";
+}
+
+static const TypeInfo imx_timerp_info = {
+    .name = "imx_timerp",
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(IMXTimerPState),
+    .class_init = imx_timerp_class_init,
+};
+
+static void imx_timer_register_types(void)
+{
+    type_register_static(&imx_timerp_info);
+}
+
+type_init(imx_timer_register_types)
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
new file mode 100644
index 0000000..d8c4f0b
--- /dev/null
+++ b/hw/timer/imx_gpt.c
@@ -0,0 +1,465 @@
+/*
+ * IMX GPT Timer
+ *
+ * Copyright (c) 2008 OK Labs
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally written by Hans Jiang
+ * Updated by Peter Chubb
+ *
+ * This code is licensed under GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw/hw.h"
+#include "qemu/bitops.h"
+#include "qemu/timer.h"
+#include "hw/ptimer.h"
+#include "hw/sysbus.h"
+#include "hw/arm/imx.h"
+
+//#define DEBUG_TIMER 1
+#ifdef DEBUG_TIMER
+#  define DPRINTF(fmt, args...) \
+      do { printf("imx_timer: " fmt , ##args); } while (0)
+#else
+#  define DPRINTF(fmt, args...) do {} while (0)
+#endif
+
+/*
+ * Define to 1 for messages about attempts to
+ * access unimplemented registers or similar.
+ */
+#define DEBUG_IMPLEMENTATION 1
+#if DEBUG_IMPLEMENTATION
+#  define IPRINTF(fmt, args...)                                         \
+    do  { fprintf(stderr, "imx_timer: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+/*
+ * GPT : General purpose timer
+ *
+ * This timer counts up continuously while it is enabled, resetting itself
+ * to 0 when it reaches TIMER_MAX (in freerun mode) or when it
+ * reaches the value of ocr1 (in periodic mode).  WE simulate this using a
+ * QEMU ptimer counting down from ocr1 and reloading from ocr1 in
+ * periodic mode, or counting from ocr1 to zero, then TIMER_MAX - ocr1.
+ * waiting_rov is set when counting from TIMER_MAX.
+ *
+ * In the real hardware, there are three comparison registers that can
+ * trigger interrupts, and compare channel 1 can be used to
+ * force-reset the timer. However, this is a `bare-bones'
+ * implementation: only what Linux 3.x uses has been implemented
+ * (free-running timer from 0 to OCR1 or TIMER_MAX) .
+ */
+
+#define TIMER_MAX  0XFFFFFFFFUL
+
+/* Control register.  Not all of these bits have any effect (yet) */
+#define GPT_CR_EN     (1 << 0)  /* GPT Enable */
+#define GPT_CR_ENMOD  (1 << 1)  /* GPT Enable Mode */
+#define GPT_CR_DBGEN  (1 << 2)  /* GPT Debug mode enable */
+#define GPT_CR_WAITEN (1 << 3)  /* GPT Wait Mode Enable  */
+#define GPT_CR_DOZEN  (1 << 4)  /* GPT Doze mode enable */
+#define GPT_CR_STOPEN (1 << 5)  /* GPT Stop Mode Enable */
+#define GPT_CR_CLKSRC_SHIFT (6)
+#define GPT_CR_CLKSRC_MASK  (0x7)
+
+#define GPT_CR_FRR    (1 << 9)  /* Freerun or Restart */
+#define GPT_CR_SWR    (1 << 15) /* Software Reset */
+#define GPT_CR_IM1    (3 << 16) /* Input capture channel 1 mode (2 bits) */
+#define GPT_CR_IM2    (3 << 18) /* Input capture channel 2 mode (2 bits) */
+#define GPT_CR_OM1    (7 << 20) /* Output Compare Channel 1 Mode (3 bits) */
+#define GPT_CR_OM2    (7 << 23) /* Output Compare Channel 2 Mode (3 bits) */
+#define GPT_CR_OM3    (7 << 26) /* Output Compare Channel 3 Mode (3 bits) */
+#define GPT_CR_FO1    (1 << 29) /* Force Output Compare Channel 1 */
+#define GPT_CR_FO2    (1 << 30) /* Force Output Compare Channel 2 */
+#define GPT_CR_FO3    (1 << 31) /* Force Output Compare Channel 3 */
+
+#define GPT_SR_OF1  (1 << 0)
+#define GPT_SR_ROV  (1 << 5)
+
+#define GPT_IR_OF1IE  (1 << 0)
+#define GPT_IR_ROVIE  (1 << 5)
+
+typedef struct {
+    SysBusDevice busdev;
+    ptimer_state *timer;
+    MemoryRegion iomem;
+    DeviceState *ccm;
+
+    uint32_t cr;
+    uint32_t pr;
+    uint32_t sr;
+    uint32_t ir;
+    uint32_t ocr1;
+    uint32_t ocr2;
+    uint32_t ocr3;
+    uint32_t icr1;
+    uint32_t icr2;
+    uint32_t cnt;
+
+    uint32_t waiting_rov;
+    qemu_irq irq;
+} IMXTimerGState;
+
+static const VMStateDescription vmstate_imx_timerg = {
+    .name = "imx-timerg",
+    .version_id = 2,
+    .minimum_version_id = 2,
+    .minimum_version_id_old = 2,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(cr, IMXTimerGState),
+        VMSTATE_UINT32(pr, IMXTimerGState),
+        VMSTATE_UINT32(sr, IMXTimerGState),
+        VMSTATE_UINT32(ir, IMXTimerGState),
+        VMSTATE_UINT32(ocr1, IMXTimerGState),
+        VMSTATE_UINT32(ocr2, IMXTimerGState),
+        VMSTATE_UINT32(ocr3, IMXTimerGState),
+        VMSTATE_UINT32(icr1, IMXTimerGState),
+        VMSTATE_UINT32(icr2, IMXTimerGState),
+        VMSTATE_UINT32(cnt, IMXTimerGState),
+        VMSTATE_UINT32(waiting_rov, IMXTimerGState),
+        VMSTATE_PTIMER(timer, IMXTimerGState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const IMXClk imx_timerg_clocks[] = {
+    NOCLK,    /* 000 No clock source */
+    IPG,      /* 001 ipg_clk, 532MHz*/
+    IPG,      /* 010 ipg_clk_highfreq */
+    NOCLK,    /* 011 not defined */
+    CLK_32k,  /* 100 ipg_clk_32k */
+    NOCLK,    /* 101 not defined */
+    NOCLK,    /* 110 not defined */
+    NOCLK,    /* 111 not defined */
+};
+
+
+static void imx_timerg_set_freq(IMXTimerGState *s)
+{
+    int clksrc;
+    uint32_t freq;
+
+    clksrc = (s->cr >> GPT_CR_CLKSRC_SHIFT) & GPT_CR_CLKSRC_MASK;
+    freq = imx_clock_frequency(s->ccm, imx_timerg_clocks[clksrc]) / (1 + s->pr);
+
+    DPRINTF("Setting gtimer clksrc %d to frequency %d\n", clksrc, freq);
+
+    if (freq) {
+        ptimer_set_freq(s->timer, freq);
+    }
+}
+
+static void imx_timerg_update(IMXTimerGState *s)
+{
+    uint32_t flags = s->sr & s->ir & (GPT_SR_OF1 | GPT_SR_ROV);
+
+    DPRINTF("g-timer SR: %s %s IR=%s %s, %s\n",
+            s->sr & GPT_SR_OF1 ? "OF1" : "",
+            s->sr & GPT_SR_ROV ? "ROV" : "",
+            s->ir & GPT_SR_OF1 ? "OF1" : "",
+            s->ir & GPT_SR_ROV ? "ROV" : "",
+            s->cr & GPT_CR_EN ? "CR_EN" : "Not Enabled");
+
+    qemu_set_irq(s->irq, (s->cr & GPT_CR_EN) && flags);
+}
+
+static uint32_t imx_timerg_update_counts(IMXTimerGState *s)
+{
+    uint64_t target = s->waiting_rov ? TIMER_MAX : s->ocr1;
+    uint64_t cnt = ptimer_get_count(s->timer);
+    s->cnt = target - cnt;
+    return s->cnt;
+}
+
+static void imx_timerg_reload(IMXTimerGState *s, uint32_t timeout)
+{
+    uint64_t diff_cnt;
+
+    if (!(s->cr & GPT_CR_FRR)) {
+        IPRINTF("IMX_timerg_reload --- called in reset-mode\n");
+        return;
+    }
+
+    /*
+     * For small timeouts, qemu sometimes runs too slow.
+     * Better deliver a late interrupt than none.
+     *
+     * In Reset mode (FRR bit clear)
+     * the ptimer reloads itself from OCR1;
+     * in free-running mode we need to fake
+     * running from 0 to ocr1 to TIMER_MAX
+     */
+    if (timeout > s->cnt) {
+        diff_cnt = timeout - s->cnt;
+    } else {
+        diff_cnt = 0;
+    }
+    ptimer_set_count(s->timer, diff_cnt);
+}
+
+static uint64_t imx_timerg_read(void *opaque, hwaddr offset,
+                                unsigned size)
+{
+    IMXTimerGState *s = (IMXTimerGState *)opaque;
+
+    DPRINTF("g-read(offset=%x)", (unsigned int)(offset >> 2));
+    switch (offset >> 2) {
+    case 0: /* Control Register */
+        DPRINTF(" cr = %x\n", s->cr);
+        return s->cr;
+
+    case 1: /* prescaler */
+        DPRINTF(" pr = %x\n", s->pr);
+        return s->pr;
+
+    case 2: /* Status Register */
+        DPRINTF(" sr = %x\n", s->sr);
+        return s->sr;
+
+    case 3: /* Interrupt Register */
+        DPRINTF(" ir = %x\n", s->ir);
+        return s->ir;
+
+    case 4: /* Output Compare Register 1 */
+        DPRINTF(" ocr1 = %x\n", s->ocr1);
+        return s->ocr1;
+
+    case 5: /* Output Compare Register 2 */
+        DPRINTF(" ocr2 = %x\n", s->ocr2);
+        return s->ocr2;
+
+    case 6: /* Output Compare Register 3 */
+        DPRINTF(" ocr3 = %x\n", s->ocr3);
+        return s->ocr3;
+
+    case 7: /* input Capture Register 1 */
+        DPRINTF(" icr1 = %x\n", s->icr1);
+        return s->icr1;
+
+    case 8: /* input Capture Register 2 */
+        DPRINTF(" icr2 = %x\n", s->icr2);
+        return s->icr2;
+
+    case 9: /* cnt */
+        imx_timerg_update_counts(s);
+        DPRINTF(" cnt = %x\n", s->cnt);
+        return s->cnt;
+    }
+
+    IPRINTF("imx_timerg_read: Bad offset %x\n",
+            (int)offset >> 2);
+
+    return 0;
+}
+
+static void imx_timerg_reset(DeviceState *dev)
+{
+    IMXTimerGState *s = container_of(dev, IMXTimerGState, busdev.qdev);
+
+    /*
+     * Soft reset doesn't touch some bits; hard reset clears them
+     */
+    s->cr &= ~(GPT_CR_EN|GPT_CR_ENMOD|GPT_CR_STOPEN|GPT_CR_DOZEN|
+               GPT_CR_WAITEN|GPT_CR_DBGEN);
+    s->sr = 0;
+    s->pr = 0;
+    s->ir = 0;
+    s->cnt = 0;
+    s->ocr1 = TIMER_MAX;
+    s->ocr2 = TIMER_MAX;
+    s->ocr3 = TIMER_MAX;
+    s->icr1 = 0;
+    s->icr2 = 0;
+    ptimer_stop(s->timer);
+    ptimer_set_limit(s->timer, TIMER_MAX, 1);
+    ptimer_set_count(s->timer, TIMER_MAX);
+    imx_timerg_set_freq(s);
+}
+
+static void imx_timerg_write(void *opaque, hwaddr offset,
+                             uint64_t value, unsigned size)
+{
+    IMXTimerGState *s = (IMXTimerGState *)opaque;
+    DPRINTF("g-write(offset=%x, value = 0x%x)\n", (unsigned int)offset >> 2,
+            (unsigned int)value);
+
+    switch (offset >> 2) {
+    case 0: {
+        uint32_t oldcr = s->cr;
+        /* CR */
+        if (value & GPT_CR_SWR) { /* force reset */
+            value &= ~GPT_CR_SWR;
+            imx_timerg_reset(&s->busdev.qdev);
+            imx_timerg_update(s);
+        }
+
+        s->cr = value & ~0x7c00;
+        imx_timerg_set_freq(s);
+        if ((oldcr ^ value) & GPT_CR_EN) {
+            if (value & GPT_CR_EN) {
+                if (value & GPT_CR_ENMOD) {
+                    ptimer_set_count(s->timer, s->ocr1);
+                    s->cnt = 0;
+                }
+                ptimer_run(s->timer,
+                           (value & GPT_CR_FRR) && (s->ocr1 != TIMER_MAX));
+            } else {
+                ptimer_stop(s->timer);
+            };
+        }
+        return;
+    }
+
+    case 1: /* Prescaler */
+        s->pr = value & 0xfff;
+        imx_timerg_set_freq(s);
+        return;
+
+    case 2: /* SR */
+        /*
+         * No point in implementing the status register bits to do with
+         * external interrupt sources.
+         */
+        value &= GPT_SR_OF1 | GPT_SR_ROV;
+        s->sr &= ~value;
+        imx_timerg_update(s);
+        return;
+
+    case 3: /* IR -- interrupt register */
+        s->ir = value & 0x3f;
+        imx_timerg_update(s);
+        return;
+
+    case 4: /* OCR1 -- output compare register */
+        /* In non-freerun mode, reset count when this register is written */
+        if (!(s->cr & GPT_CR_FRR)) {
+            s->waiting_rov = 0;
+            ptimer_set_limit(s->timer, value, 1);
+        } else {
+            imx_timerg_update_counts(s);
+            if (value > s->cnt) {
+                s->waiting_rov = 0;
+                imx_timerg_reload(s, value);
+            } else {
+                s->waiting_rov = 1;
+                imx_timerg_reload(s, TIMER_MAX - s->cnt);
+            }
+        }
+        s->ocr1 = value;
+        return;
+
+    case 5: /* OCR2 -- output compare register */
+    case 6: /* OCR3 -- output compare register */
+    default:
+        IPRINTF("imx_timerg_write: Bad offset %x\n",
+                (int)offset >> 2);
+    }
+}
+
+static void imx_timerg_timeout(void *opaque)
+{
+    IMXTimerGState *s = (IMXTimerGState *)opaque;
+
+    DPRINTF("imx_timerg_timeout, waiting rov=%d\n", s->waiting_rov);
+    if (s->cr & GPT_CR_FRR) {
+        /*
+         * Free running timer from 0 -> TIMERMAX
+         * Generates interrupt at TIMER_MAX and at cnt==ocr1
+         * If ocr1 == TIMER_MAX, then no need to reload timer.
+         */
+        if (s->ocr1 == TIMER_MAX) {
+            DPRINTF("s->ocr1 == TIMER_MAX, FRR\n");
+            s->sr |= GPT_SR_OF1 | GPT_SR_ROV;
+            imx_timerg_update(s);
+            return;
+        }
+
+        if (s->waiting_rov) {
+            /*
+             * We were waiting for cnt==TIMER_MAX
+             */
+            s->sr |= GPT_SR_ROV;
+            s->waiting_rov = 0;
+            s->cnt = 0;
+            imx_timerg_reload(s, s->ocr1);
+        } else {
+            /* Must have got a cnt==ocr1 timeout. */
+            s->sr |= GPT_SR_OF1;
+            s->cnt = s->ocr1;
+            s->waiting_rov = 1;
+            imx_timerg_reload(s, TIMER_MAX);
+        }
+        imx_timerg_update(s);
+        return;
+    }
+
+    s->sr |= GPT_SR_OF1;
+    imx_timerg_update(s);
+}
+
+static const MemoryRegionOps imx_timerg_ops = {
+    .read = imx_timerg_read,
+    .write = imx_timerg_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+
+static int imx_timerg_init(SysBusDevice *dev)
+{
+    IMXTimerGState *s = FROM_SYSBUS(IMXTimerGState, dev);
+    QEMUBH *bh;
+
+    sysbus_init_irq(dev, &s->irq);
+    memory_region_init_io(&s->iomem, &imx_timerg_ops,
+                          s, "imxg-timer",
+                          0x00001000);
+    sysbus_init_mmio(dev, &s->iomem);
+
+    bh = qemu_bh_new(imx_timerg_timeout, s);
+    s->timer = ptimer_init(bh);
+
+    /* Hard reset resets extra bits in CR */
+    s->cr = 0;
+    return 0;
+}
+
+void imx_timerg_create(const hwaddr addr,
+                              qemu_irq irq,
+                              DeviceState *ccm)
+{
+    IMXTimerGState *pp;
+    DeviceState *dev;
+
+    dev = sysbus_create_simple("imx_timerg", addr, irq);
+    pp = container_of(dev, IMXTimerGState, busdev.qdev);
+    pp->ccm = ccm;
+}
+
+static void imx_timerg_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc  = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+    k->init = imx_timerg_init;
+    dc->vmsd = &vmstate_imx_timerg;
+    dc->reset = imx_timerg_reset;
+    dc->desc = "i.MX general timer";
+}
+
+static const TypeInfo imx_timerg_info = {
+    .name = "imx_timerg",
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(IMXTimerGState),
+    .class_init = imx_timerg_class_init,
+};
+
+static void imx_timer_register_types(void)
+{
+    type_register_static(&imx_timerg_info);
+}
+
+type_init(imx_timer_register_types)
diff --git a/hw/timer/imx_timer.c b/hw/timer/imx_timer.c
deleted file mode 100644
index 7693bb7..0000000
--- a/hw/timer/imx_timer.c
+++ /dev/null
@@ -1,823 +0,0 @@
-/*
- * IMX31 Timer
- *
- * Copyright (c) 2008 OK Labs
- * Copyright (c) 2011 NICTA Pty Ltd
- * Originally written by Hans Jiang
- * Updated by Peter Chubb
- *
- * This code is licensed under GPL version 2 or later.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#include "hw/hw.h"
-#include "qemu/timer.h"
-#include "hw/ptimer.h"
-#include "hw/sysbus.h"
-#include "hw/arm/imx.h"
-
-//#define DEBUG_TIMER 1
-#ifdef DEBUG_TIMER
-#  define DPRINTF(fmt, args...) \
-      do { printf("imx_timer: " fmt , ##args); } while (0)
-#else
-#  define DPRINTF(fmt, args...) do {} while (0)
-#endif
-
-/*
- * Define to 1 for messages about attempts to
- * access unimplemented registers or similar.
- */
-#define DEBUG_IMPLEMENTATION 1
-#if DEBUG_IMPLEMENTATION
-#  define IPRINTF(fmt, args...)                                         \
-    do  { fprintf(stderr, "imx_timer: " fmt, ##args); } while (0)
-#else
-#  define IPRINTF(fmt, args...) do {} while (0)
-#endif
-
-/*
- * GPT : General purpose timer
- *
- * This timer counts up continuously while it is enabled, resetting itself
- * to 0 when it reaches TIMER_MAX (in freerun mode) or when it
- * reaches the value of ocr1 (in periodic mode).  WE simulate this using a
- * QEMU ptimer counting down from ocr1 and reloading from ocr1 in
- * periodic mode, or counting from ocr1 to zero, then TIMER_MAX - ocr1.
- * waiting_rov is set when counting from TIMER_MAX.
- *
- * In the real hardware, there are three comparison registers that can
- * trigger interrupts, and compare channel 1 can be used to
- * force-reset the timer. However, this is a `bare-bones'
- * implementation: only what Linux 3.x uses has been implemented
- * (free-running timer from 0 to OCR1 or TIMER_MAX) .
- */
-
-
-#define TIMER_MAX  0XFFFFFFFFUL
-
-/* Control register.  Not all of these bits have any effect (yet) */
-#define GPT_CR_EN     (1 << 0)  /* GPT Enable */
-#define GPT_CR_ENMOD  (1 << 1)  /* GPT Enable Mode */
-#define GPT_CR_DBGEN  (1 << 2)  /* GPT Debug mode enable */
-#define GPT_CR_WAITEN (1 << 3)  /* GPT Wait Mode Enable  */
-#define GPT_CR_DOZEN  (1 << 4)  /* GPT Doze mode enable */
-#define GPT_CR_STOPEN (1 << 5)  /* GPT Stop Mode Enable */
-#define GPT_CR_CLKSRC_SHIFT (6)
-#define GPT_CR_CLKSRC_MASK  (0x7)
-
-#define GPT_CR_FRR    (1 << 9)  /* Freerun or Restart */
-#define GPT_CR_SWR    (1 << 15) /* Software Reset */
-#define GPT_CR_IM1    (3 << 16) /* Input capture channel 1 mode (2 bits) */
-#define GPT_CR_IM2    (3 << 18) /* Input capture channel 2 mode (2 bits) */
-#define GPT_CR_OM1    (7 << 20) /* Output Compare Channel 1 Mode (3 bits) */
-#define GPT_CR_OM2    (7 << 23) /* Output Compare Channel 2 Mode (3 bits) */
-#define GPT_CR_OM3    (7 << 26) /* Output Compare Channel 3 Mode (3 bits) */
-#define GPT_CR_FO1    (1 << 29) /* Force Output Compare Channel 1 */
-#define GPT_CR_FO2    (1 << 30) /* Force Output Compare Channel 2 */
-#define GPT_CR_FO3    (1 << 31) /* Force Output Compare Channel 3 */
-
-#define GPT_SR_OF1  (1 << 0)
-#define GPT_SR_ROV  (1 << 5)
-
-#define GPT_IR_OF1IE  (1 << 0)
-#define GPT_IR_ROVIE  (1 << 5)
-
-typedef struct {
-    SysBusDevice busdev;
-    ptimer_state *timer;
-    MemoryRegion iomem;
-    DeviceState *ccm;
-
-    uint32_t cr;
-    uint32_t pr;
-    uint32_t sr;
-    uint32_t ir;
-    uint32_t ocr1;
-    uint32_t ocr2;
-    uint32_t ocr3;
-    uint32_t icr1;
-    uint32_t icr2;
-    uint32_t cnt;
-
-    uint32_t waiting_rov;
-    qemu_irq irq;
-} IMXTimerGState;
-
-static const VMStateDescription vmstate_imx_timerg = {
-    .name = "imx-timerg",
-    .version_id = 2,
-    .minimum_version_id = 2,
-    .minimum_version_id_old = 2,
-    .fields      = (VMStateField[]) {
-        VMSTATE_UINT32(cr, IMXTimerGState),
-        VMSTATE_UINT32(pr, IMXTimerGState),
-        VMSTATE_UINT32(sr, IMXTimerGState),
-        VMSTATE_UINT32(ir, IMXTimerGState),
-        VMSTATE_UINT32(ocr1, IMXTimerGState),
-        VMSTATE_UINT32(ocr2, IMXTimerGState),
-        VMSTATE_UINT32(ocr3, IMXTimerGState),
-        VMSTATE_UINT32(icr1, IMXTimerGState),
-        VMSTATE_UINT32(icr2, IMXTimerGState),
-        VMSTATE_UINT32(cnt, IMXTimerGState),
-        VMSTATE_UINT32(waiting_rov, IMXTimerGState),
-        VMSTATE_PTIMER(timer, IMXTimerGState),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static const IMXClk imx_timerg_clocks[] = {
-    NOCLK,    /* 000 No clock source */
-    IPG,      /* 001 ipg_clk, 532MHz*/
-    IPG,      /* 010 ipg_clk_highfreq */
-    NOCLK,    /* 011 not defined */
-    CLK_32k,  /* 100 ipg_clk_32k */
-    NOCLK,    /* 101 not defined */
-    NOCLK,    /* 110 not defined */
-    NOCLK,    /* 111 not defined */
-};
-
-
-static void imx_timerg_set_freq(IMXTimerGState *s)
-{
-    int clksrc;
-    uint32_t freq;
-
-    clksrc = (s->cr >> GPT_CR_CLKSRC_SHIFT) & GPT_CR_CLKSRC_MASK;
-    freq = imx_clock_frequency(s->ccm, imx_timerg_clocks[clksrc]) / (1 + s->pr);
-
-    DPRINTF("Setting gtimer clksrc %d to frequency %d\n", clksrc, freq);
-    if (freq) {
-        ptimer_set_freq(s->timer, freq);
-    }
-}
-
-static void imx_timerg_update(IMXTimerGState *s)
-{
-    uint32_t flags = s->sr & s->ir & (GPT_SR_OF1 | GPT_SR_ROV);
-
-    DPRINTF("g-timer SR: %s %s IR=%s %s, %s\n",
-            s->sr & GPT_SR_OF1 ? "OF1" : "",
-            s->sr & GPT_SR_ROV ? "ROV" : "",
-            s->ir & GPT_SR_OF1 ? "OF1" : "",
-            s->ir & GPT_SR_ROV ? "ROV" : "",
-            s->cr & GPT_CR_EN ? "CR_EN" : "Not Enabled");
-
-    qemu_set_irq(s->irq, (s->cr & GPT_CR_EN) && flags);
-}
-
-static uint32_t imx_timerg_update_counts(IMXTimerGState *s)
-{
-    uint64_t target = s->waiting_rov ? TIMER_MAX : s->ocr1;
-    uint64_t cnt = ptimer_get_count(s->timer);
-    s->cnt = target - cnt;
-    return s->cnt;
-}
-
-static void imx_timerg_reload(IMXTimerGState *s, uint32_t timeout)
-{
-    uint64_t diff_cnt;
-
-    if (!(s->cr & GPT_CR_FRR)) {
-        IPRINTF("IMX_timerg_reload --- called in reset-mode\n");
-        return;
-    }
-
-    /*
-     * For small timeouts, qemu sometimes runs too slow.
-     * Better deliver a late interrupt than none.
-     *
-     * In Reset mode (FRR bit clear)
-     * the ptimer reloads itself from OCR1;
-     * in free-running mode we need to fake
-     * running from 0 to ocr1 to TIMER_MAX
-     */
-    if (timeout > s->cnt) {
-        diff_cnt = timeout - s->cnt;
-    } else {
-        diff_cnt = 0;
-    }
-    ptimer_set_count(s->timer, diff_cnt);
-}
-
-static uint64_t imx_timerg_read(void *opaque, hwaddr offset,
-                                unsigned size)
-{
-    IMXTimerGState *s = (IMXTimerGState *)opaque;
-
-    DPRINTF("g-read(offset=%x)", offset >> 2);
-    switch (offset >> 2) {
-    case 0: /* Control Register */
-        DPRINTF(" cr = %x\n", s->cr);
-        return s->cr;
-
-    case 1: /* prescaler */
-        DPRINTF(" pr = %x\n", s->pr);
-        return s->pr;
-
-    case 2: /* Status Register */
-        DPRINTF(" sr = %x\n", s->sr);
-        return s->sr;
-
-    case 3: /* Interrupt Register */
-        DPRINTF(" ir = %x\n", s->ir);
-        return s->ir;
-
-    case 4: /* Output Compare Register 1 */
-        DPRINTF(" ocr1 = %x\n", s->ocr1);
-        return s->ocr1;
-
-    case 5: /* Output Compare Register 2 */
-        DPRINTF(" ocr2 = %x\n", s->ocr2);
-        return s->ocr2;
-
-    case 6: /* Output Compare Register 3 */
-        DPRINTF(" ocr3 = %x\n", s->ocr3);
-        return s->ocr3;
-
-    case 7: /* input Capture Register 1 */
-        DPRINTF(" icr1 = %x\n", s->icr1);
-        return s->icr1;
-
-    case 8: /* input Capture Register 2 */
-        DPRINTF(" icr2 = %x\n", s->icr2);
-        return s->icr2;
-
-    case 9: /* cnt */
-        imx_timerg_update_counts(s);
-        DPRINTF(" cnt = %x\n", s->cnt);
-        return s->cnt;
-    }
-
-    IPRINTF("imx_timerg_read: Bad offset %x\n",
-            (int)offset >> 2);
-
-    return 0;
-}
-
-static void imx_timerg_reset(DeviceState *dev)
-{
-    IMXTimerGState *s = container_of(dev, IMXTimerGState, busdev.qdev);
-
-    /*
-     * Soft reset doesn't touch some bits; hard reset clears them
-     */
-    s->cr &= ~(GPT_CR_EN|GPT_CR_ENMOD|GPT_CR_STOPEN|GPT_CR_DOZEN|
-               GPT_CR_WAITEN|GPT_CR_DBGEN);
-    s->sr = 0;
-    s->pr = 0;
-    s->ir = 0;
-    s->cnt = 0;
-    s->ocr1 = TIMER_MAX;
-    s->ocr2 = TIMER_MAX;
-    s->ocr3 = TIMER_MAX;
-    s->icr1 = 0;
-    s->icr2 = 0;
-    ptimer_stop(s->timer);
-    ptimer_set_limit(s->timer, TIMER_MAX, 1);
-    ptimer_set_count(s->timer, TIMER_MAX);
-    imx_timerg_set_freq(s);
-}
-
-static void imx_timerg_write(void *opaque, hwaddr offset,
-                             uint64_t value, unsigned size)
-{
-    IMXTimerGState *s = (IMXTimerGState *)opaque;
-    DPRINTF("g-write(offset=%x, value = 0x%x)\n", (unsigned int)offset >> 2,
-            (unsigned int)value);
-
-    switch (offset >> 2) {
-    case 0: {
-        uint32_t oldcr = s->cr;
-        /* CR */
-        if (value & GPT_CR_SWR) { /* force reset */
-            value &= ~GPT_CR_SWR;
-            imx_timerg_reset(&s->busdev.qdev);
-            imx_timerg_update(s);
-        }
-
-        s->cr = value & ~0x7c00;
-        imx_timerg_set_freq(s);
-        if ((oldcr ^ value) & GPT_CR_EN) {
-            if (value & GPT_CR_EN) {
-                if (value & GPT_CR_ENMOD) {
-                    ptimer_set_count(s->timer, s->ocr1);
-                    s->cnt = 0;
-                }
-                ptimer_run(s->timer,
-                           (value & GPT_CR_FRR) && (s->ocr1 != TIMER_MAX));
-            } else {
-                ptimer_stop(s->timer);
-            };
-        }
-        return;
-    }
-
-    case 1: /* Prescaler */
-        s->pr = value & 0xfff;
-        imx_timerg_set_freq(s);
-        return;
-
-    case 2: /* SR */
-        /*
-         * No point in implementing the status register bits to do with
-         * external interrupt sources.
-         */
-        value &= GPT_SR_OF1 | GPT_SR_ROV;
-        s->sr &= ~value;
-        imx_timerg_update(s);
-        return;
-
-    case 3: /* IR -- interrupt register */
-        s->ir = value & 0x3f;
-        imx_timerg_update(s);
-        return;
-
-    case 4: /* OCR1 -- output compare register */
-        /* In non-freerun mode, reset count when this register is written */
-        if (!(s->cr & GPT_CR_FRR)) {
-            s->waiting_rov = 0;
-            ptimer_set_limit(s->timer, value, 1);
-        } else {
-            imx_timerg_update_counts(s);
-            if (value > s->cnt) {
-                s->waiting_rov = 0;
-                imx_timerg_reload(s, value);
-            } else {
-                s->waiting_rov = 1;
-                imx_timerg_reload(s, TIMER_MAX - s->cnt);
-            }
-        }
-        s->ocr1 = value;
-        return;
-
-    case 5: /* OCR2 -- output compare register */
-    case 6: /* OCR3 -- output compare register */
-    default:
-        IPRINTF("imx_timerg_write: Bad offset %x\n",
-                (int)offset >> 2);
-    }
-}
-
-static void imx_timerg_timeout(void *opaque)
-{
-    IMXTimerGState *s = (IMXTimerGState *)opaque;
-
-    DPRINTF("imx_timerg_timeout, waiting rov=%d\n", s->waiting_rov);
-    if (s->cr & GPT_CR_FRR) {
-        /*
-         * Free running timer from 0 -> TIMERMAX
-         * Generates interrupt at TIMER_MAX and at cnt==ocr1
-         * If ocr1 == TIMER_MAX, then no need to reload timer.
-         */
-        if (s->ocr1 == TIMER_MAX) {
-            DPRINTF("s->ocr1 == TIMER_MAX, FRR\n");
-            s->sr |= GPT_SR_OF1 | GPT_SR_ROV;
-            imx_timerg_update(s);
-            return;
-        }
-
-        if (s->waiting_rov) {
-            /*
-             * We were waiting for cnt==TIMER_MAX
-             */
-            s->sr |= GPT_SR_ROV;
-            s->waiting_rov = 0;
-            s->cnt = 0;
-            imx_timerg_reload(s, s->ocr1);
-        } else {
-            /* Must have got a cnt==ocr1 timeout. */
-            s->sr |= GPT_SR_OF1;
-            s->cnt = s->ocr1;
-            s->waiting_rov = 1;
-            imx_timerg_reload(s, TIMER_MAX);
-        }
-        imx_timerg_update(s);
-        return;
-    }
-
-    s->sr |= GPT_SR_OF1;
-    imx_timerg_update(s);
-}
-
-static const MemoryRegionOps imx_timerg_ops = {
-    .read = imx_timerg_read,
-    .write = imx_timerg_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-
-static int imx_timerg_init(SysBusDevice *dev)
-{
-    IMXTimerGState *s = FROM_SYSBUS(IMXTimerGState, dev);
-    QEMUBH *bh;
-
-    sysbus_init_irq(dev, &s->irq);
-    memory_region_init_io(&s->iomem, &imx_timerg_ops,
-                          s, "imxg-timer",
-                          0x00001000);
-    sysbus_init_mmio(dev, &s->iomem);
-
-    bh = qemu_bh_new(imx_timerg_timeout, s);
-    s->timer = ptimer_init(bh);
-
-    /* Hard reset resets extra bits in CR */
-    s->cr = 0;
-    return 0;
-}
-
-
-
-/*
- * EPIT: Enhanced periodic interrupt timer
- */
-
-#define CR_EN       (1 << 0)
-#define CR_ENMOD    (1 << 1)
-#define CR_OCIEN    (1 << 2)
-#define CR_RLD      (1 << 3)
-#define CR_PRESCALE_SHIFT (4)
-#define CR_PRESCALE_MASK  (0xfff)
-#define CR_SWR      (1 << 16)
-#define CR_IOVW     (1 << 17)
-#define CR_DBGEN    (1 << 18)
-#define CR_WAITEN   (1 << 19)
-#define CR_DOZEN    (1 << 20)
-#define CR_STOPEN   (1 << 21)
-#define CR_CLKSRC_SHIFT (24)
-#define CR_CLKSRC_MASK  (0x3 << CR_CLKSRC_SHIFT)
-
-
-/*
- * Exact clock frequencies vary from board to board.
- * These are typical.
- */
-static const IMXClk imx_timerp_clocks[] =  {
-    0,        /* 00 disabled */
-    IPG,      /* 01 ipg_clk, ~532MHz */
-    IPG,      /* 10 ipg_clk_highfreq */
-    CLK_32k,  /* 11 ipg_clk_32k -- ~32kHz */
-};
-
-typedef struct {
-    SysBusDevice busdev;
-    ptimer_state *timer_reload;
-    ptimer_state *timer_cmp;
-    MemoryRegion iomem;
-    DeviceState *ccm;
-
-    uint32_t cr;
-    uint32_t sr;
-    uint32_t lr;
-    uint32_t cmp;
-    uint32_t cnt;
-
-    uint32_t freq;
-    qemu_irq irq;
-} IMXTimerPState;
-
-/*
- * Update interrupt status
- */
-static void imx_timerp_update(IMXTimerPState *s)
-{
-    if (s->sr && (s->cr & CR_OCIEN)) {
-        qemu_irq_raise(s->irq);
-    } else {
-        qemu_irq_lower(s->irq);
-    }
-}
-
-static void set_timerp_freq(IMXTimerPState *s)
-{
-    int clksrc;
-    unsigned prescaler;
-    uint32_t freq;
-
-    clksrc = (s->cr & CR_CLKSRC_MASK) >> CR_CLKSRC_SHIFT;
-    prescaler = 1 + ((s->cr >> CR_PRESCALE_SHIFT) & CR_PRESCALE_MASK);
-    freq = imx_clock_frequency(s->ccm, imx_timerp_clocks[clksrc]) / prescaler;
-
-    s->freq = freq;
-    DPRINTF("Setting ptimer frequency to %u\n", freq);
-
-    if (freq) {
-        ptimer_set_freq(s->timer_reload, freq);
-        ptimer_set_freq(s->timer_cmp, freq);
-    }
-}
-
-static void imx_timerp_reset(DeviceState *dev)
-{
-    IMXTimerPState *s = container_of(dev, IMXTimerPState, busdev.qdev);
-
-    /*
-     * Soft reset doesn't touch some bits; hard reset clears them
-     */
-    s->cr &= ~(CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
-    s->sr = 0;
-    s->lr = TIMER_MAX;
-    s->cmp = 0;
-    s->cnt = 0;
-    /* stop both timers */
-    ptimer_stop(s->timer_cmp);
-    ptimer_stop(s->timer_reload);
-    /* compute new frequency */
-    set_timerp_freq(s);
-    /* init both timers to TIMER_MAX */
-    ptimer_set_limit(s->timer_cmp, TIMER_MAX, 1);
-    ptimer_set_limit(s->timer_reload, TIMER_MAX, 1);
-    if (s->freq && (s->cr & CR_EN)) {
-        /* if the timer is still enabled, restart it */
-        ptimer_run(s->timer_reload, 1);
-    }
-}
-
-static uint32_t imx_timerp_update_counts(IMXTimerPState *s)
-{
-     s->cnt = ptimer_get_count(s->timer_reload);
-
-     return s->cnt;
-}
-
-static uint64_t imx_timerp_read(void *opaque, hwaddr offset,
-                                unsigned size)
-{
-    IMXTimerPState *s = (IMXTimerPState *)opaque;
-
-    DPRINTF("p-read(offset=%x)", offset >> 2);
-    switch (offset >> 2) {
-    case 0: /* Control Register */
-        DPRINTF("cr %x\n", s->cr);
-        return s->cr;
-
-    case 1: /* Status Register */
-        DPRINTF("sr %x\n", s->sr);
-        return s->sr;
-
-    case 2: /* LR - ticks*/
-        DPRINTF("lr %x\n", s->lr);
-        return s->lr;
-
-    case 3: /* CMP */
-        DPRINTF("cmp %x\n", s->cmp);
-        return s->cmp;
-
-    case 4: /* CNT */
-        imx_timerp_update_counts(s);
-        DPRINTF(" cnt = %x\n", s->cnt);
-        return s->cnt;
-    }
-
-    IPRINTF("imx_timerp_read: Bad offset %x\n",
-            (int)offset >> 2);
-    return 0;
-}
-
-static void imx_reload_compare_timer(IMXTimerPState *s)
-{
-    if ((s->cr & CR_OCIEN) && s->cmp) {
-        /* if the compare feature is on */
-        uint32_t tmp = imx_timerp_update_counts(s);
-        if (tmp > s->cmp) {
-            /* reinit the cmp timer if required */
-            ptimer_set_count(s->timer_cmp, tmp - s->cmp);
-            if ((s->cr & CR_EN)) {
-                /* Restart the cmp timer if required */
-                ptimer_run(s->timer_cmp, 0);
-            }
-        }
-    }
-}
-
-static void imx_timerp_write(void *opaque, hwaddr offset,
-                             uint64_t value, unsigned size)
-{
-    IMXTimerPState *s = (IMXTimerPState *)opaque;
-    DPRINTF("p-write(offset=%x, value = %x)\n", (unsigned int)offset >> 2,
-            (unsigned int)value);
-
-    switch (offset >> 2) {
-    case 0: /* CR */
-        s->cr = value & 0x03ffffff;
-        if (s->cr & CR_SWR) {
-            /* handle the reset */
-            imx_timerp_reset(&s->busdev.qdev);
-        } else {
-            set_timerp_freq(s);
-        }
-
-        if (s->freq && (s->cr & CR_EN)) {
-            if (s->cr & CR_ENMOD) {
-                if (s->cr & CR_RLD) {
-                    ptimer_set_limit(s->timer_reload, s->lr, 1);
-                } else {
-                    ptimer_set_limit(s->timer_reload, TIMER_MAX, 1);
-                }
-            }
-
-            imx_reload_compare_timer(s);
-
-            ptimer_run(s->timer_reload, 1);
-        } else {
-            /* stop both timers */
-            ptimer_stop(s->timer_reload);
-            ptimer_stop(s->timer_cmp);
-        }
-        break;
-
-    case 1: /* SR - ACK*/
-        /* writing 1 to OCIF clear the OCIF bit */
-        if (value & 0x01) {
-            s->sr = 0;
-            imx_timerp_update(s);
-        }
-        break;
-
-    case 2: /* LR - set ticks */
-        s->lr = value;
-
-        if (s->cr & CR_RLD) {
-            /* Also set the limit if the LRD bit is set */
-            /* If IOVW bit is set then set the timer value */
-            ptimer_set_limit(s->timer_reload, s->lr, s->cr & CR_IOVW);
-        } else if (s->cr & CR_IOVW) {
-            /* If IOVW bit is set then set the timer value */
-            ptimer_set_count(s->timer_reload, s->lr);
-        }
-
-        imx_reload_compare_timer(s);
-
-        break;
-
-    case 3: /* CMP */
-        s->cmp = value;
-
-        imx_reload_compare_timer(s);
-
-        break;
-
-    default:
-        IPRINTF("imx_timerp_write: Bad offset %x\n",
-                   (int)offset >> 2);
-    }
-}
-
-static void imx_timerp_reload(void *opaque)
-{
-    IMXTimerPState *s = (IMXTimerPState *)opaque;
-
-    DPRINTF("imxp reload\n");
-
-    if (!(s->cr & CR_EN)) {
-        return;
-    }
-
-    if (s->cr & CR_RLD) {
-        ptimer_set_limit(s->timer_reload, s->lr, 1);
-    } else {
-        ptimer_set_limit(s->timer_reload, TIMER_MAX, 1);
-    }
-
-    if (s->cr & CR_OCIEN) {
-        /* if compare register is 0 then we handle the interrupt here */
-        if (s->cmp == 0) {
-            s->sr = 1;
-            imx_timerp_update(s);
-        } else if (s->cmp <= s->lr) {
-            /* We should launch the compare register */
-            ptimer_set_count(s->timer_cmp, s->lr - s->cmp);
-            ptimer_run(s->timer_cmp, 0);
-        } else {
-            IPRINTF("imxp reload: s->lr < s->cmp\n");
-        }
-    }
-}
-
-static void imx_timerp_cmp(void *opaque)
-{
-    IMXTimerPState *s = (IMXTimerPState *)opaque;
-
-    DPRINTF("imxp compare\n");
-
-    ptimer_stop(s->timer_cmp);
-
-    /* compare register is not 0 */
-    if (s->cmp) {
-        s->sr = 1;
-        imx_timerp_update(s);
-    }
-}
-
-void imx_timerp_create(const hwaddr addr,
-                              qemu_irq irq,
-                              DeviceState *ccm)
-{
-    IMXTimerPState *pp;
-    DeviceState *dev;
-
-    dev = sysbus_create_simple("imx_timerp", addr, irq);
-    pp = container_of(dev, IMXTimerPState, busdev.qdev);
-    pp->ccm = ccm;
-}
-
-static const MemoryRegionOps imx_timerp_ops = {
-  .read = imx_timerp_read,
-  .write = imx_timerp_write,
-  .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static const VMStateDescription vmstate_imx_timerp = {
-    .name = "imx-timerp",
-    .version_id = 2,
-    .minimum_version_id = 2,
-    .minimum_version_id_old = 2,
-    .fields      = (VMStateField[]) {
-        VMSTATE_UINT32(cr, IMXTimerPState),
-        VMSTATE_UINT32(sr, IMXTimerPState),
-        VMSTATE_UINT32(lr, IMXTimerPState),
-        VMSTATE_UINT32(cmp, IMXTimerPState),
-        VMSTATE_UINT32(cnt, IMXTimerPState),
-        VMSTATE_UINT32(freq, IMXTimerPState),
-        VMSTATE_PTIMER(timer_reload, IMXTimerPState),
-        VMSTATE_PTIMER(timer_cmp, IMXTimerPState),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static int imx_timerp_init(SysBusDevice *dev)
-{
-    IMXTimerPState *s = FROM_SYSBUS(IMXTimerPState, dev);
-    QEMUBH *bh;
-
-    DPRINTF("imx_timerp_init\n");
-    sysbus_init_irq(dev, &s->irq);
-    memory_region_init_io(&s->iomem, &imx_timerp_ops,
-                          s, "imxp-timer",
-                          0x00001000);
-    sysbus_init_mmio(dev, &s->iomem);
-
-    bh = qemu_bh_new(imx_timerp_reload, s);
-    s->timer_reload = ptimer_init(bh);
-
-    bh = qemu_bh_new(imx_timerp_cmp, s);
-    s->timer_cmp = ptimer_init(bh);
-
-    return 0;
-}
-
-
-void imx_timerg_create(const hwaddr addr,
-                              qemu_irq irq,
-                              DeviceState *ccm)
-{
-    IMXTimerGState *pp;
-    DeviceState *dev;
-
-    dev = sysbus_create_simple("imx_timerg", addr, irq);
-    pp = container_of(dev, IMXTimerGState, busdev.qdev);
-    pp->ccm = ccm;
-}
-
-static void imx_timerg_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc  = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-    k->init = imx_timerg_init;
-    dc->vmsd = &vmstate_imx_timerg;
-    dc->reset = imx_timerg_reset;
-    dc->desc = "i.MX general timer";
-}
-
-static void imx_timerp_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc  = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-    k->init = imx_timerp_init;
-    dc->vmsd = &vmstate_imx_timerp;
-    dc->reset = imx_timerp_reset;
-    dc->desc = "i.MX periodic timer";
-}
-
-static const TypeInfo imx_timerp_info = {
-    .name = "imx_timerp",
-    .parent = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(IMXTimerPState),
-    .class_init = imx_timerp_class_init,
-};
-
-static const TypeInfo imx_timerg_info = {
-    .name = "imx_timerg",
-    .parent = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(IMXTimerGState),
-    .class_init = imx_timerg_class_init,
-};
-
-static void imx_timer_register_types(void)
-{
-    type_register_static(&imx_timerp_info);
-    type_register_static(&imx_timerg_info);
-}
-
-type_init(imx_timer_register_types)
commit 37ab4a566816f518fb958ea49734d51d1ccbd227
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:45 2013 +0100

    sd/sd.c: Fix "inquiry" ACMD41
    
    QEMU models two (of the three) ACMD41 has two modes, "inquiry" and
    "first". The selection logic for which of the two is incorrect - it
    compares != 0 for the entire argument value rather than only bits 23:0
    as per the spec. Fix.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Message-id: 3ef0a7fd1b2f3ebb23b4fdeabcc14caf3fad6d71.1369622254.git.peter.crosthwaite at xilinx.com
    Reviewed-by: Igor Mitsyanko <i.mitsyanko at gmail.com>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 2e0ef3e..346d86f 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -43,6 +43,8 @@ do { fprintf(stderr, "SD: " fmt , ## __VA_ARGS__); } while (0)
 #define DPRINTF(fmt, ...) do {} while(0)
 #endif
 
+#define ACMD41_ENQUIRY_MASK 0x00ffffff
+
 typedef enum {
     sd_r0 = 0,    /* no response */
     sd_r1,        /* normal response command */
@@ -1277,9 +1279,14 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
         }
         switch (sd->state) {
         case sd_idle_state:
-            /* We accept any voltage.  10000 V is nothing.  */
-            if (req.arg)
+            /* We accept any voltage.  10000 V is nothing.
+             *
+             * We don't model init delay so just advance straight to ready state
+             * unless it's an enquiry ACMD41 (bits 23:0 == 0).
+             */
+            if (req.arg & ACMD41_ENQUIRY_MASK) {
                 sd->state = sd_ready_state;
+            }
 
             return sd_r3;
 
commit 1d32c26f28d6e25f447b8ba40440c7d228ed4006
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:45 2013 +0100

    sd/sdhci:ADMA: fix interrupt
    
    The end of transfer check was occurring and potentially returning before
    the interrupt flag was checked. This means the interrupt will be missed
    if it occurs on the last packet. Fix by checking for the interrupt
    before checking for the end of transfer.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Igor Mitsyanko <i.mitsyanko at gmail.com>
    Message-id: 9969ec154777957ec738fc4e539d68e7494d0081.1369370934.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 15345dc..e64899c 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -730,6 +730,15 @@ static void sdhci_do_adma(SDHCIState *s)
             break;
         }
 
+        if (dscr.attr & SDHC_ADMA_ATTR_INT) {
+            DPRINT_L1("ADMA interrupt: admasysaddr=0x%lx\n", s->admasysaddr);
+            if (s->norintstsen & SDHC_NISEN_DMA) {
+                s->norintsts |= SDHC_NIS_DMA;
+            }
+
+            sdhci_update_irq(s);
+        }
+
         /* ADMA transfer terminates if blkcnt == 0 or by END attribute */
         if (((s->trnmod & SDHC_TRNS_BLK_CNT_EN) &&
                     (s->blkcnt == 0)) || (dscr.attr & SDHC_ADMA_ATTR_END)) {
@@ -752,15 +761,6 @@ static void sdhci_do_adma(SDHCIState *s)
             return;
         }
 
-        if (dscr.attr & SDHC_ADMA_ATTR_INT) {
-            DPRINT_L1("ADMA interrupt: admasysaddr=0x%lx\n", s->admasysaddr);
-            if (s->norintstsen & SDHC_NISEN_DMA) {
-                s->norintsts |= SDHC_NIS_DMA;
-            }
-
-            sdhci_update_irq(s);
-            return;
-        }
     }
 
     /* we have unfinished business - reschedule to continue ADMA */
commit 677ff2ae660b3a55f936a8836513cbab185f6e4f
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:45 2013 +0100

    sd/sdhci.c: Fix bdata_read DPRINT message
    
    This message was printing out the data in decimal only, which is not
    very friendly to the debugging developer. Add hex variant in
    parenthesis to make it consistent with other similar messages in this
    module.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Igor Mitsyanko <i.mitsyanko at gmail.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: d624179649137832eaa8caa263ef9589b4395d5e.1369370934.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index ea510b5..15345dc 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -880,7 +880,8 @@ static uint32_t sdhci_read(SDHCIState *s, unsigned int offset, unsigned size)
     case  SDHC_BDATA:
         if (sdhci_buff_access_is_sequential(s, offset - SDHC_BDATA)) {
             ret = SDHCI_GET_CLASS(s)->bdata_read(s, size);
-            DPRINT_L2("read %ub: addr[0x%04x] -> %u\n", size, offset, ret);
+            DPRINT_L2("read %ub: addr[0x%04x] -> %u(0x%x)\n", size, offset,
+                      ret, ret);
             return ret;
         }
         break;
commit dcdb4cd8507d93ecad10ae54b28d9609453c0312
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:44 2013 +0100

    sd/sdhci: Fix Buffer Write Ready interrupt
    
    This interrupt is not risen after the last block is written to sd. It
    is mutually exclusive with the end of transfer conditions. Fix.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Igor Mitsyanko <i.mitsyanko at gmail.com>
    Message-id: 7ca9fd3e03ce1bec94aff08f607c15a0ec3d3371.1369370934.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 0a84540..ea510b5 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -405,15 +405,14 @@ static void sdhci_write_block_to_card(SDHCIState *s)
 
     /* Next data can be written through BUFFER DATORT register */
     s->prnsts |= SDHC_SPACE_AVAILABLE;
-    if (s->norintstsen & SDHC_NISEN_WBUFRDY) {
-        s->norintsts |= SDHC_NIS_WBUFRDY;
-    }
 
     /* Finish transfer if that was the last block of data */
     if ((s->trnmod & SDHC_TRNS_MULTI) == 0 ||
             ((s->trnmod & SDHC_TRNS_MULTI) &&
             (s->trnmod & SDHC_TRNS_BLK_CNT_EN) && (s->blkcnt == 0))) {
         SDHCI_GET_CLASS(s)->end_data_transfer(s);
+    } else if (s->norintstsen & SDHC_NISEN_WBUFRDY) {
+        s->norintsts |= SDHC_NIS_WBUFRDY;
     }
 
     /* Generate Block Gap Event if requested and if not the last block */
commit 656f416c65d8ddbfd17500676865f0ac8f960801
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:44 2013 +0100

    sd/sdhci.c: Only reset data_count on new commands
    
    The data_count variable was being reset on every transfer, including
    DMA transfer resumptions. This is incorrect, it should only be set
    on a new command.
    
    Manifests as a bug when using ADMA and there is a timer delay between
    ADMA frames where the fifo is left in a non empty state.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Igor Mitsyanko <i.mitsyanko at gmail.com>
    Message-id: 15a98609cc32315211b0963091a8efd67522e160.1369370934.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 91dc9b0..0a84540 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -260,6 +260,7 @@ static void sdhci_send_command(SDHCIState *s)
     sdhci_update_irq(s);
 
     if (s->blksize && (s->cmdreg & SDHC_CMD_DATA_PRESENT)) {
+        s->data_count = 0;
         sdhci_do_data_transfer(s);
     }
 }
@@ -773,7 +774,6 @@ static void sdhci_do_adma(SDHCIState *s)
 static void sdhci_data_transfer(SDHCIState *s)
 {
     SDHCIClass *k = SDHCI_GET_CLASS(s);
-    s->data_count = 0;
 
     if (s->trnmod & SDHC_TRNS_DMA) {
         switch (SDHC_DMA_TYPE(s->hostctl)) {
commit b0b7ae6259e96e775315357c813b74e85637bf32
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:44 2013 +0100

    xilinx_spips: lqspi: Fix byte/misaligned access
    
    The LQSPI bus attachment supports byte/halfword and misaligned
    accesses. Fixed. Refactored the LQSPI cache to be byte-wise
    instead of word wise accordingly.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: 5ec47b13563ad2d22105a1f26186d7756718394b.1369117359.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index e975a87..05a3ada 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -161,7 +161,7 @@ typedef struct {
 typedef struct {
     XilinxSPIPS parent_obj;
 
-    uint32_t lqspi_buf[LQSPI_CACHE_SIZE];
+    uint8_t lqspi_buf[LQSPI_CACHE_SIZE];
     hwaddr lqspi_cached_addr;
 } XilinxQSPIPS;
 
@@ -391,14 +391,12 @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
     }
 }
 
-static inline void rx_data_bytes(XilinxSPIPS *s, uint32_t *value, int max)
+static inline void rx_data_bytes(XilinxSPIPS *s, uint8_t *value, int max)
 {
     int i;
 
-    *value = 0;
     for (i = 0; i < max && !fifo8_is_empty(&s->rx_fifo); ++i) {
-        uint32_t next = fifo8_pop(&s->rx_fifo) & 0xFF;
-        *value |= next << 8 * (s->regs[R_CONFIG] & ENDIAN ? 3-i : i);
+        value[i] = fifo8_pop(&s->rx_fifo);
     }
 }
 
@@ -408,6 +406,7 @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
     XilinxSPIPS *s = opaque;
     uint32_t mask = ~0;
     uint32_t ret;
+    uint8_t rx_buf[4];
 
     addr >>= 2;
     switch (addr) {
@@ -437,7 +436,10 @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
         mask = 0;
         break;
     case R_RX_DATA:
-        rx_data_bytes(s, &ret, s->num_txrx_bytes);
+        memset(rx_buf, 0, sizeof(rx_buf));
+        rx_data_bytes(s, rx_buf, s->num_txrx_bytes);
+        ret = s->regs[R_CONFIG] & ENDIAN ? cpu_to_be32(*(uint32_t *)rx_buf)
+                        : cpu_to_le32(*(uint32_t *)rx_buf);
         DB_PRINT_L(0, "addr=" TARGET_FMT_plx " = %x\n", addr * 4, ret);
         xilinx_spips_update_ixr(s);
         return ret;
@@ -562,7 +564,8 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
 
     if (addr >= q->lqspi_cached_addr &&
             addr <= q->lqspi_cached_addr + LQSPI_CACHE_SIZE - 4) {
-        ret = q->lqspi_buf[(addr - q->lqspi_cached_addr) >> 2];
+        uint8_t *retp = &q->lqspi_buf[addr - q->lqspi_cached_addr];
+        ret = cpu_to_le32(*(uint32_t *)retp);
         DB_PRINT_L(1, "addr: %08x, data: %08x\n", (unsigned)addr,
                    (unsigned)ret);
         return ret;
@@ -608,13 +611,13 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
 
         DB_PRINT_L(0, "starting QSPI data read\n");
 
-        while (cache_entry < LQSPI_CACHE_SIZE / 4) {
-            for (i = 0; i < 16; ++i) {
-                tx_data_bytes(s, 0, 4);
+        while (cache_entry < LQSPI_CACHE_SIZE) {
+            for (i = 0; i < 64; ++i) {
+                tx_data_bytes(s, 0, 1);
             }
             xilinx_spips_flush_txfifo(s);
-            for (i = 0; i < 16; ++i) {
-                rx_data_bytes(s, &q->lqspi_buf[cache_entry++], 4);
+            for (i = 0; i < 64; ++i) {
+                rx_data_bytes(s, &q->lqspi_buf[cache_entry++], 1);
             }
         }
 
@@ -622,7 +625,7 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
         s->regs[R_LQSPI_STS] |= u_page_save;
         xilinx_spips_update_cs_lines(s);
 
-        q->lqspi_cached_addr = addr;
+        q->lqspi_cached_addr = flash_addr * num_effective_busses(s);
         return lqspi_read(opaque, addr, size);
     }
 }
@@ -631,7 +634,7 @@ static const MemoryRegionOps lqspi_ops = {
     .read = lqspi_read,
     .endianness = DEVICE_NATIVE_ENDIAN,
     .valid = {
-        .min_access_size = 4,
+        .min_access_size = 1,
         .max_access_size = 4
     }
 };
commit a66418f6f181ca6ee04e77896674253ff83db45e
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:44 2013 +0100

    xilinx_spips: lqspi: Push more data to tx-fifo
    
    Do 16 words per fifo flush. Increases performance and decreases
    debug verbosity. This data depth has no real hardware analogue,
    so just go with something that has reasonable performance.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: 5621ee4621941d3639b5cacfdec26bd3148f31d5.1369117359.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index 665f471..e975a87 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -608,11 +608,14 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
 
         DB_PRINT_L(0, "starting QSPI data read\n");
 
-        for (i = 0; i < LQSPI_CACHE_SIZE / 4; ++i) {
-            tx_data_bytes(s, 0, 4);
+        while (cache_entry < LQSPI_CACHE_SIZE / 4) {
+            for (i = 0; i < 16; ++i) {
+                tx_data_bytes(s, 0, 4);
+            }
             xilinx_spips_flush_txfifo(s);
-            rx_data_bytes(s, &q->lqspi_buf[cache_entry], 4);
-            cache_entry++;
+            for (i = 0; i < 16; ++i) {
+                rx_data_bytes(s, &q->lqspi_buf[cache_entry++], 4);
+            }
         }
 
         s->regs[R_LQSPI_STS] &= ~LQSPI_CFG_U_PAGE;
commit 4a5b6fa8d9bdeec71f4f92e8b7a31fc344ef512f
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:43 2013 +0100

    xilinx_spips: Multiple debug verbosity levels
    
    The debug printfs on every SPI operation is extremely verbose. Add
    a second level of debug for this.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: f63478b8e5b29cc011cdc10e29f8537bb2fc2b5e.1369117359.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index 8fbbd24..665f471 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -30,15 +30,17 @@
 #include "hw/ssi.h"
 #include "qemu/bitops.h"
 
-#ifdef XILINX_SPIPS_ERR_DEBUG
-#define DB_PRINT(...) do { \
-    fprintf(stderr,  ": %s: ", __func__); \
-    fprintf(stderr, ## __VA_ARGS__); \
-    } while (0);
-#else
-    #define DB_PRINT(...)
+#ifndef XILINX_SPIPS_ERR_DEBUG
+#define XILINX_SPIPS_ERR_DEBUG 0
 #endif
 
+#define DB_PRINT_L(level, ...) do { \
+    if (XILINX_SPIPS_ERR_DEBUG > (level)) { \
+        fprintf(stderr,  ": %s: ", __func__); \
+        fprintf(stderr, ## __VA_ARGS__); \
+    } \
+} while (0);
+
 /* config register */
 #define R_CONFIG            (0x00 / 4)
 #define IFMODE              (1 << 31)
@@ -210,10 +212,10 @@ static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
                                 (s->num_cs * s->num_busses);
 
             if (xilinx_spips_cs_is_set(s, i, field) && !found) {
-                DB_PRINT("selecting slave %d\n", i);
+                DB_PRINT_L(0, "selecting slave %d\n", i);
                 qemu_set_irq(s->cs_lines[cs_to_set], 0);
             } else {
-                DB_PRINT("deselecting slave %d\n", i);
+                DB_PRINT_L(0, "deselecting slave %d\n", i);
                 qemu_set_irq(s->cs_lines[cs_to_set], 1);
             }
         }
@@ -223,7 +225,7 @@ static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
     }
     if (!found) {
         s->snoop_state = SNOOP_CHECKING;
-        DB_PRINT("moving to snoop check state\n");
+        DB_PRINT_L(1, "moving to snoop check state\n");
     }
 }
 
@@ -306,6 +308,8 @@ static inline void stripe8(uint8_t *x, int num, bool dir)
 
 static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
 {
+    int debug_level = 0;
+
     for (;;) {
         int i;
         uint8_t tx = 0;
@@ -330,14 +334,14 @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
         }
 
         for (i = 0; i < num_effective_busses(s); ++i) {
-            DB_PRINT("tx = %02x\n", tx_rx[i]);
+            DB_PRINT_L(debug_level, "tx = %02x\n", tx_rx[i]);
             tx_rx[i] = ssi_transfer(s->spi[i], (uint32_t)tx_rx[i]);
-            DB_PRINT("rx = %02x\n", tx_rx[i]);
+            DB_PRINT_L(debug_level, "rx = %02x\n", tx_rx[i]);
         }
 
         if (fifo8_is_full(&s->rx_fifo)) {
             s->regs[R_INTR_STATUS] |= IXR_RX_FIFO_OVERFLOW;
-            DB_PRINT("rx FIFO overflow");
+            DB_PRINT_L(0, "rx FIFO overflow");
         } else if (s->snoop_state == SNOOP_STRIPING) {
             stripe8(tx_rx, num_effective_busses(s), true);
             for (i = 0; i < num_effective_busses(s); ++i) {
@@ -347,7 +351,8 @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
            fifo8_push(&s->rx_fifo, (uint8_t)tx_rx[0]);
         }
 
-        DB_PRINT("initial snoop state: %x\n", (unsigned)s->snoop_state);
+        DB_PRINT_L(debug_level, "initial snoop state: %x\n",
+                   (unsigned)s->snoop_state);
         switch (s->snoop_state) {
         case (SNOOP_CHECKING):
             switch (tx) { /* new instruction code */
@@ -372,11 +377,17 @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
             break;
         case (SNOOP_STRIPING):
         case (SNOOP_NONE):
+            /* Once we hit the boring stuff - squelch debug noise */
+            if (!debug_level) {
+                DB_PRINT_L(0, "squelching debug info ....\n");
+                debug_level = 1;
+            }
             break;
         default:
             s->snoop_state--;
         }
-        DB_PRINT("final snoop state: %x\n", (unsigned)s->snoop_state);
+        DB_PRINT_L(debug_level, "final snoop state: %x\n",
+                   (unsigned)s->snoop_state);
     }
 }
 
@@ -406,7 +417,7 @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
     case R_INTR_STATUS:
         ret = s->regs[addr] & IXR_ALL;
         s->regs[addr] = 0;
-        DB_PRINT("addr=" TARGET_FMT_plx " = %x\n", addr * 4, ret);
+        DB_PRINT_L(0, "addr=" TARGET_FMT_plx " = %x\n", addr * 4, ret);
         return ret;
     case R_INTR_MASK:
         mask = IXR_ALL;
@@ -427,11 +438,12 @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
         break;
     case R_RX_DATA:
         rx_data_bytes(s, &ret, s->num_txrx_bytes);
-        DB_PRINT("addr=" TARGET_FMT_plx " = %x\n", addr * 4, ret);
+        DB_PRINT_L(0, "addr=" TARGET_FMT_plx " = %x\n", addr * 4, ret);
         xilinx_spips_update_ixr(s);
         return ret;
     }
-    DB_PRINT("addr=" TARGET_FMT_plx " = %x\n", addr * 4, s->regs[addr] & mask);
+    DB_PRINT_L(0, "addr=" TARGET_FMT_plx " = %x\n", addr * 4,
+               s->regs[addr] & mask);
     return s->regs[addr] & mask;
 
 }
@@ -457,7 +469,7 @@ static void xilinx_spips_write(void *opaque, hwaddr addr,
     int man_start_com = 0;
     XilinxSPIPS *s = opaque;
 
-    DB_PRINT("addr=" TARGET_FMT_plx " = %x\n", addr, (unsigned)value);
+    DB_PRINT_L(0, "addr=" TARGET_FMT_plx " = %x\n", addr, (unsigned)value);
     addr >>= 2;
     switch (addr) {
     case R_CONFIG:
@@ -551,7 +563,8 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
     if (addr >= q->lqspi_cached_addr &&
             addr <= q->lqspi_cached_addr + LQSPI_CACHE_SIZE - 4) {
         ret = q->lqspi_buf[(addr - q->lqspi_cached_addr) >> 2];
-        DB_PRINT("addr: %08x, data: %08x\n", (unsigned)addr, (unsigned)ret);
+        DB_PRINT_L(1, "addr: %08x, data: %08x\n", (unsigned)addr,
+                   (unsigned)ret);
         return ret;
     } else {
         int flash_addr = (addr / num_effective_busses(s));
@@ -562,17 +575,18 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
         s->regs[R_LQSPI_STS] &= ~LQSPI_CFG_U_PAGE;
         s->regs[R_LQSPI_STS] |= slave ? LQSPI_CFG_U_PAGE : 0;
 
-        DB_PRINT("config reg status: %08x\n", s->regs[R_LQSPI_CFG]);
+        DB_PRINT_L(0, "config reg status: %08x\n", s->regs[R_LQSPI_CFG]);
 
         fifo8_reset(&s->tx_fifo);
         fifo8_reset(&s->rx_fifo);
 
         /* instruction */
-        DB_PRINT("pushing read instruction: %02x\n",
-                 (uint8_t)(s->regs[R_LQSPI_CFG] & LQSPI_CFG_INST_CODE));
+        DB_PRINT_L(0, "pushing read instruction: %02x\n",
+                   (unsigned)(uint8_t)(s->regs[R_LQSPI_CFG] &
+                                       LQSPI_CFG_INST_CODE));
         fifo8_push(&s->tx_fifo, s->regs[R_LQSPI_CFG] & LQSPI_CFG_INST_CODE);
         /* read address */
-        DB_PRINT("pushing read address %06x\n", flash_addr);
+        DB_PRINT_L(0, "pushing read address %06x\n", flash_addr);
         fifo8_push(&s->tx_fifo, (uint8_t)(flash_addr >> 16));
         fifo8_push(&s->tx_fifo, (uint8_t)(flash_addr >> 8));
         fifo8_push(&s->tx_fifo, (uint8_t)flash_addr);
@@ -585,14 +599,14 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
         /* dummy bytes */
         for (i = 0; i < (extract32(s->regs[R_LQSPI_CFG], LQSPI_CFG_DUMMY_SHIFT,
                                    LQSPI_CFG_DUMMY_WIDTH)); ++i) {
-            DB_PRINT("pushing dummy byte\n");
+            DB_PRINT_L(0, "pushing dummy byte\n");
             fifo8_push(&s->tx_fifo, 0);
         }
         xilinx_spips_update_cs_lines(s);
         xilinx_spips_flush_txfifo(s);
         fifo8_reset(&s->rx_fifo);
 
-        DB_PRINT("starting QSPI data read\n");
+        DB_PRINT_L(0, "starting QSPI data read\n");
 
         for (i = 0; i < LQSPI_CACHE_SIZE / 4; ++i) {
             tx_data_bytes(s, 0, 4);
@@ -626,7 +640,7 @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
     XilinxSPIPSClass *xsc = XILINX_SPIPS_GET_CLASS(s);
     int i;
 
-    DB_PRINT("realized spips\n");
+    DB_PRINT_L(0, "realized spips\n");
 
     s->spi = g_new(SSIBus *, s->num_busses);
     for (i = 0; i < s->num_busses; ++i) {
@@ -658,7 +672,7 @@ static void xilinx_qspips_realize(DeviceState *dev, Error **errp)
     XilinxQSPIPS *q = XILINX_QSPIPS(dev);
     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
-    DB_PRINT("realized qspips\n");
+    DB_PRINT_L(0, "realized qspips\n");
 
     s->num_busses = 2;
     s->num_cs = 2;
commit c37fc509d288ff693e42b2025451241fdd481948
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:43 2013 +0100

    xilinx_spips: Debug msgs for Snoop state
    
    This is worth keeping track of when debugging the device model.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: d3b44ecf23d671798b062eee5dc362c716ea54cd.1369117359.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index 7222e15..8fbbd24 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -223,6 +223,7 @@ static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
     }
     if (!found) {
         s->snoop_state = SNOOP_CHECKING;
+        DB_PRINT("moving to snoop check state\n");
     }
 }
 
@@ -346,6 +347,7 @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
            fifo8_push(&s->rx_fifo, (uint8_t)tx_rx[0]);
         }
 
+        DB_PRINT("initial snoop state: %x\n", (unsigned)s->snoop_state);
         switch (s->snoop_state) {
         case (SNOOP_CHECKING):
             switch (tx) { /* new instruction code */
@@ -374,6 +376,7 @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
         default:
             s->snoop_state--;
         }
+        DB_PRINT("final snoop state: %x\n", (unsigned)s->snoop_state);
     }
 }
 
commit 9151da25a71a171d19beec107a8ee2066cb65e7c
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:43 2013 +0100

    xilinx_spips: Fix striping behaviour
    
    The QSPI controller was using byte-wide stripes when striping across
    the two flashes in dual parallel mode. The real hardware however uses
    individual bit striping. QEMU misbehaves in the (corner) case where
    data is written/read in dual-parallel mode and read/written back in
    single mode.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: 718a61df1bf746ec06f6da44d12f8317af7b08ce.1369117359.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index 3e9e76c..7222e15 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -273,35 +273,77 @@ static void xilinx_spips_reset(DeviceState *d)
     xilinx_spips_update_cs_lines(s);
 }
 
+/* N way (num) in place bit striper. Lay out row wise bits (LSB to MSB)
+ * column wise (from element 0 to N-1). num is the length of x, and dir
+ * reverses the direction of the transform. Best illustrated by example:
+ * Each digit in the below array is a single bit (num == 3):
+ *
+ * {{ 76543210, }  ----- stripe (dir == false) -----> {{ FCheb630, }
+ *  { hgfedcba, }                                      { GDAfc741, }
+ *  { HGFEDCBA, }} <---- upstripe (dir == true) -----  { HEBgda52, }}
+ */
+
+static inline void stripe8(uint8_t *x, int num, bool dir)
+{
+    uint8_t r[num];
+    memset(r, 0, sizeof(uint8_t) * num);
+    int idx[2] = {0, 0};
+    int bit[2] = {0, 0};
+    int d = dir;
+
+    for (idx[0] = 0; idx[0] < num; ++idx[0]) {
+        for (bit[0] = 0; bit[0] < 8; ++bit[0]) {
+            r[idx[d]] |= x[idx[!d]] & 1 << bit[!d] ? 1 << bit[d] : 0;
+            idx[1] = (idx[1] + 1) % num;
+            if (!idx[1]) {
+                bit[1]++;
+            }
+        }
+    }
+    memcpy(x, r, sizeof(uint8_t) * num);
+}
+
 static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
 {
     for (;;) {
         int i;
-        uint8_t rx;
         uint8_t tx = 0;
+        uint8_t tx_rx[num_effective_busses(s)];
 
-        for (i = 0; i < num_effective_busses(s); ++i) {
-            if (!i || s->snoop_state == SNOOP_STRIPING) {
-                if (fifo8_is_empty(&s->tx_fifo)) {
-                    if (!(s->regs[R_LQSPI_CFG] & LQSPI_CFG_LQ_MODE)) {
-                        s->regs[R_INTR_STATUS] |= IXR_TX_FIFO_UNDERFLOW;
-                    }
-                    xilinx_spips_update_ixr(s);
-                    return;
-                } else {
-                    tx = fifo8_pop(&s->tx_fifo);
-                }
+        if (fifo8_is_empty(&s->tx_fifo)) {
+            if (!(s->regs[R_LQSPI_CFG] & LQSPI_CFG_LQ_MODE)) {
+                s->regs[R_INTR_STATUS] |= IXR_TX_FIFO_UNDERFLOW;
             }
-            rx = ssi_transfer(s->spi[i], (uint32_t)tx);
-            DB_PRINT("tx = %02x rx = %02x\n", tx, rx);
-            if (!i || s->snoop_state == SNOOP_STRIPING) {
-                if (fifo8_is_full(&s->rx_fifo)) {
-                    s->regs[R_INTR_STATUS] |= IXR_RX_FIFO_OVERFLOW;
-                    DB_PRINT("rx FIFO overflow");
-                } else {
-                    fifo8_push(&s->rx_fifo, (uint8_t)rx);
-                }
+            xilinx_spips_update_ixr(s);
+            return;
+        } else if (s->snoop_state == SNOOP_STRIPING) {
+            for (i = 0; i < num_effective_busses(s); ++i) {
+                tx_rx[i] = fifo8_pop(&s->tx_fifo);
             }
+            stripe8(tx_rx, num_effective_busses(s), false);
+        } else {
+            tx = fifo8_pop(&s->tx_fifo);
+            for (i = 0; i < num_effective_busses(s); ++i) {
+                tx_rx[i] = tx;
+            }
+        }
+
+        for (i = 0; i < num_effective_busses(s); ++i) {
+            DB_PRINT("tx = %02x\n", tx_rx[i]);
+            tx_rx[i] = ssi_transfer(s->spi[i], (uint32_t)tx_rx[i]);
+            DB_PRINT("rx = %02x\n", tx_rx[i]);
+        }
+
+        if (fifo8_is_full(&s->rx_fifo)) {
+            s->regs[R_INTR_STATUS] |= IXR_RX_FIFO_OVERFLOW;
+            DB_PRINT("rx FIFO overflow");
+        } else if (s->snoop_state == SNOOP_STRIPING) {
+            stripe8(tx_rx, num_effective_busses(s), true);
+            for (i = 0; i < num_effective_busses(s); ++i) {
+                fifo8_push(&s->rx_fifo, (uint8_t)tx_rx[i]);
+            }
+        } else {
+           fifo8_push(&s->rx_fifo, (uint8_t)tx_rx[0]);
         }
 
         switch (s->snoop_state) {
commit 2133a5f6b8f8941a6a3734c6c1990656553de76c
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:43 2013 +0100

    xilinx_spips: Fix CTRL register RW bits
    
    The CTRL register was RAZ/WI on some of the RW bits. Even though the
    function behind these bits is invalid in QEMU, they should still be
    guest accessible. Fix.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: b7aaad93163ce4af0c428635804ac7b77a567b25.1369117359.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index ea8a593..3e9e76c 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -56,6 +56,7 @@
 #define CLK_PH              (1 << 2)
 #define CLK_POL             (1 << 1)
 #define MODE_SEL            (1 << 0)
+#define R_CONFIG_RSVD       (0x7bf40000)
 
 /* interrupt mechanism */
 #define R_INTR_STATUS       (0x04 / 4)
@@ -355,7 +356,7 @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
     addr >>= 2;
     switch (addr) {
     case R_CONFIG:
-        mask = 0x0002FFFF;
+        mask = ~(R_CONFIG_RSVD | MAN_START_COM);
         break;
     case R_INTR_STATUS:
         ret = s->regs[addr] & IXR_ALL;
@@ -415,7 +416,7 @@ static void xilinx_spips_write(void *opaque, hwaddr addr,
     addr >>= 2;
     switch (addr) {
     case R_CONFIG:
-        mask = 0x0002FFFF;
+        mask = ~(R_CONFIG_RSVD | MAN_START_COM);
         if (value & MAN_START_COM) {
             man_start_com = 1;
         }
commit 15408b428f5b4db56da555fbda4f1aaf40d77f4b
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:43 2013 +0100

    xilinx_spips: lqspi: Dont touch config register
    
    The LQSPI mode is supposed to work via the automatic CS mode feature
    rather than manipulate CS lines itself. Now that auto CS is implemented
    remove LQSPIs CS mode override logic. There is still a need to
    manipulate the U_PAGE bit in LQSPI config register to implement
    dual-stack mode however.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: 000c8dd54df09523f17052638100722ef0f5a3af.1369117359.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index 631d010..ea8a593 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -511,16 +511,16 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
         int flash_addr = (addr / num_effective_busses(s));
         int slave = flash_addr >> LQSPI_ADDRESS_BITS;
         int cache_entry = 0;
+        uint32_t u_page_save = s->regs[R_LQSPI_STS] & ~LQSPI_CFG_U_PAGE;
+
+        s->regs[R_LQSPI_STS] &= ~LQSPI_CFG_U_PAGE;
+        s->regs[R_LQSPI_STS] |= slave ? LQSPI_CFG_U_PAGE : 0;
 
         DB_PRINT("config reg status: %08x\n", s->regs[R_LQSPI_CFG]);
 
         fifo8_reset(&s->tx_fifo);
         fifo8_reset(&s->rx_fifo);
 
-        s->regs[R_CONFIG] &= ~CS;
-        s->regs[R_CONFIG] |= ((~(1 << slave) << CS_SHIFT) & CS) | MANUAL_CS;
-        xilinx_spips_update_cs_lines(s);
-
         /* instruction */
         DB_PRINT("pushing read instruction: %02x\n",
                  (uint8_t)(s->regs[R_LQSPI_CFG] & LQSPI_CFG_INST_CODE));
@@ -554,9 +554,9 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
             rx_data_bytes(s, &q->lqspi_buf[cache_entry], 4);
             cache_entry++;
         }
-        xilinx_spips_update_cs_lines(s);
 
-        s->regs[R_CONFIG] |= CS;
+        s->regs[R_LQSPI_STS] &= ~LQSPI_CFG_U_PAGE;
+        s->regs[R_LQSPI_STS] |= u_page_save;
         xilinx_spips_update_cs_lines(s);
 
         q->lqspi_cached_addr = addr;
commit c4f08ffe134810307cebd66f2cbcffe5cd707915
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:42 2013 +0100

    xilinx_spips: Implement automatic CS
    
    Implement the automatic CS control feature. If the MANUAL_CS bit is
    cleared then the chip select stay de-asserted as long as the tx FIFO
    is empty.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: 1d67383adc42761af715a93f161344b9284dfc9a.1369117359.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index 0c04ec9..631d010 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -190,6 +190,12 @@ static inline int num_effective_busses(XilinxSPIPS *s)
             s->regs[R_LQSPI_CFG] & LQSPI_CFG_TWO_MEM) ? s->num_busses : 1;
 }
 
+static inline bool xilinx_spips_cs_is_set(XilinxSPIPS *s, int i, int field)
+{
+    return ~field & (1 << i) && (s->regs[R_CONFIG] & MANUAL_CS
+                    || !fifo8_is_empty(&s->tx_fifo));
+}
+
 static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
 {
     int i, j;
@@ -202,14 +208,15 @@ static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
             int cs_to_set = (j * s->num_cs + i + upage) %
                                 (s->num_cs * s->num_busses);
 
-            if (~field & (1 << i) && !found) {
+            if (xilinx_spips_cs_is_set(s, i, field) && !found) {
                 DB_PRINT("selecting slave %d\n", i);
                 qemu_set_irq(s->cs_lines[cs_to_set], 0);
             } else {
+                DB_PRINT("deselecting slave %d\n", i);
                 qemu_set_irq(s->cs_lines[cs_to_set], 1);
             }
         }
-        if (~field & (1 << i)) {
+        if (xilinx_spips_cs_is_set(s, i, field)) {
             found = true;
         }
     }
@@ -451,12 +458,13 @@ static void xilinx_spips_write(void *opaque, hwaddr addr,
     }
     s->regs[addr] = (s->regs[addr] & ~mask) | (value & mask);
 no_reg_update:
+    xilinx_spips_update_cs_lines(s);
     if ((man_start_com && s->regs[R_CONFIG] & MAN_START_EN) ||
             (fifo8_is_empty(&s->tx_fifo) && s->regs[R_CONFIG] & MAN_START_EN)) {
         xilinx_spips_flush_txfifo(s);
     }
-    xilinx_spips_update_ixr(s);
     xilinx_spips_update_cs_lines(s);
+    xilinx_spips_update_ixr(s);
 }
 
 static const MemoryRegionOps spips_ops = {
@@ -510,7 +518,7 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
         fifo8_reset(&s->rx_fifo);
 
         s->regs[R_CONFIG] &= ~CS;
-        s->regs[R_CONFIG] |= (~(1 << slave) << CS_SHIFT) & CS;
+        s->regs[R_CONFIG] |= ((~(1 << slave) << CS_SHIFT) & CS) | MANUAL_CS;
         xilinx_spips_update_cs_lines(s);
 
         /* instruction */
@@ -534,6 +542,7 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
             DB_PRINT("pushing dummy byte\n");
             fifo8_push(&s->tx_fifo, 0);
         }
+        xilinx_spips_update_cs_lines(s);
         xilinx_spips_flush_txfifo(s);
         fifo8_reset(&s->rx_fifo);
 
@@ -545,6 +554,7 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
             rx_data_bytes(s, &q->lqspi_buf[cache_entry], 4);
             cache_entry++;
         }
+        xilinx_spips_update_cs_lines(s);
 
         s->regs[R_CONFIG] |= CS;
         xilinx_spips_update_cs_lines(s);
commit e100f3be0cccc58692b3988ec2e35cd8b906ca05
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:42 2013 +0100

    xilinx_spips: Add automatic start support
    
    SPI has a mode where it automatically starts based on tx fifo
    occupancy. Implemented.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: f4e9accb5de87b526fff6ed937f63278db76533b.1369117359.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index cf4c43e..0c04ec9 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -451,7 +451,8 @@ static void xilinx_spips_write(void *opaque, hwaddr addr,
     }
     s->regs[addr] = (s->regs[addr] & ~mask) | (value & mask);
 no_reg_update:
-    if (man_start_com) {
+    if ((man_start_com && s->regs[R_CONFIG] & MAN_START_EN) ||
+            (fifo8_is_empty(&s->tx_fifo) && s->regs[R_CONFIG] & MAN_START_EN)) {
         xilinx_spips_flush_txfifo(s);
     }
     xilinx_spips_update_ixr(s);
commit b5cd9143e78da8ea9e17fa523aacbedd267aae54
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:42 2013 +0100

    xilinx_spips: Trash LQ page cache on mode change
    
    Invalidate the LQSPI cached page when transitioning into LQSPI mode.
    Otherwise there is a possibility that the controller will return stale
    data to the guest when transitioning back to LQ_MODE after a page
    program.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: 677490a6ee1953fe5d366e599d665de645ac84db.1369117359.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index 86f33ef..cf4c43e 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -165,6 +165,8 @@ typedef struct {
 typedef struct XilinxSPIPSClass {
     SysBusDeviceClass parent_class;
 
+    const MemoryRegionOps *reg_ops;
+
     uint32_t rx_fifo_size;
     uint32_t tx_fifo_size;
 } XilinxSPIPSClass;
@@ -462,6 +464,25 @@ static const MemoryRegionOps spips_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
+static void xilinx_qspips_write(void *opaque, hwaddr addr,
+                                uint64_t value, unsigned size)
+{
+    XilinxQSPIPS *q = XILINX_QSPIPS(opaque);
+
+    xilinx_spips_write(opaque, addr, value, size);
+    addr >>= 2;
+
+    if (addr == R_LQSPI_CFG) {
+        q->lqspi_cached_addr = ~0ULL;
+    }
+}
+
+static const MemoryRegionOps qspips_ops = {
+    .read = xilinx_spips_read,
+    .write = xilinx_qspips_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 #define LQSPI_CACHE_SIZE 1024
 
 static uint64_t
@@ -565,7 +586,7 @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
         sysbus_init_irq(sbd, &s->cs_lines[i]);
     }
 
-    memory_region_init_io(&s->iomem, &spips_ops, s, "spi", R_MAX*4);
+    memory_region_init_io(&s->iomem, xsc->reg_ops, s, "spi", R_MAX*4);
     sysbus_init_mmio(sbd, &s->iomem);
 
     s->irqline = -1;
@@ -629,6 +650,7 @@ static void xilinx_qspips_class_init(ObjectClass *klass, void * data)
     XilinxSPIPSClass *xsc = XILINX_SPIPS_CLASS(klass);
 
     dc->realize = xilinx_qspips_realize;
+    xsc->reg_ops = &qspips_ops;
     xsc->rx_fifo_size = RXFF_A_Q;
     xsc->tx_fifo_size = TXFF_A_Q;
 }
@@ -643,6 +665,7 @@ static void xilinx_spips_class_init(ObjectClass *klass, void *data)
     dc->props = xilinx_spips_properties;
     dc->vmsd = &vmstate_xilinx_spips;
 
+    xsc->reg_ops = &spips_ops;
     xsc->rx_fifo_size = RXFF_A;
     xsc->tx_fifo_size = TXFF_A;
 }
commit 10e60b35d04359fba1d759925018204527a1b9f5
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:42 2013 +0100

    xilinx_spips: Fix QSPI FIFO size
    
    QSPI has a bigger FIFO than the regular SPI controller. Differentiate
    between the two with correct FIFO sizes for each.
    
    This is the first piece of class data for SPIPS, so this patch sees
    the creation of the XilinxSPIPSClass definition and assoicated QOM
    constructs.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: acee25dd5e203215cbc15ca5d3cb5d5b2efebe7b.1369117359.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index 29636ce..86f33ef 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -106,6 +106,9 @@
 #define RXFF_A          32
 #define TXFF_A          32
 
+#define RXFF_A_Q          (64 * 4)
+#define TXFF_A_Q          (64 * 4)
+
 /* 16MB per linear region */
 #define LQSPI_ADDRESS_BITS 24
 /* Bite off 4k chunks at a time */
@@ -159,12 +162,23 @@ typedef struct {
     hwaddr lqspi_cached_addr;
 } XilinxQSPIPS;
 
+typedef struct XilinxSPIPSClass {
+    SysBusDeviceClass parent_class;
+
+    uint32_t rx_fifo_size;
+    uint32_t tx_fifo_size;
+} XilinxSPIPSClass;
 
 #define TYPE_XILINX_SPIPS "xlnx.ps7-spi"
 #define TYPE_XILINX_QSPIPS "xlnx.ps7-qspi"
 
 #define XILINX_SPIPS(obj) \
      OBJECT_CHECK(XilinxSPIPS, (obj), TYPE_XILINX_SPIPS)
+#define XILINX_SPIPS_CLASS(klass) \
+     OBJECT_CLASS_CHECK(XilinxSPIPSClass, (klass), TYPE_XILINX_SPIPS)
+#define XILINX_SPIPS_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(XilinxSPIPSClass, (obj), TYPE_XILINX_SPIPS)
+
 #define XILINX_QSPIPS(obj) \
      OBJECT_CHECK(XilinxQSPIPS, (obj), TYPE_XILINX_QSPIPS)
 
@@ -531,6 +545,7 @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
 {
     XilinxSPIPS *s = XILINX_SPIPS(dev);
     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    XilinxSPIPSClass *xsc = XILINX_SPIPS_GET_CLASS(s);
     int i;
 
     DB_PRINT("realized spips\n");
@@ -555,8 +570,8 @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
 
     s->irqline = -1;
 
-    fifo8_create(&s->rx_fifo, RXFF_A);
-    fifo8_create(&s->tx_fifo, TXFF_A);
+    fifo8_create(&s->rx_fifo, xsc->rx_fifo_size);
+    fifo8_create(&s->tx_fifo, xsc->tx_fifo_size);
 }
 
 static void xilinx_qspips_realize(DeviceState *dev, Error **errp)
@@ -611,18 +626,25 @@ static Property xilinx_spips_properties[] = {
 static void xilinx_qspips_class_init(ObjectClass *klass, void * data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    XilinxSPIPSClass *xsc = XILINX_SPIPS_CLASS(klass);
 
     dc->realize = xilinx_qspips_realize;
+    xsc->rx_fifo_size = RXFF_A_Q;
+    xsc->tx_fifo_size = TXFF_A_Q;
 }
 
 static void xilinx_spips_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    XilinxSPIPSClass *xsc = XILINX_SPIPS_CLASS(klass);
 
     dc->realize = xilinx_spips_realize;
     dc->reset = xilinx_spips_reset;
     dc->props = xilinx_spips_properties;
     dc->vmsd = &vmstate_xilinx_spips;
+
+    xsc->rx_fifo_size = RXFF_A;
+    xsc->tx_fifo_size = TXFF_A;
 }
 
 static const TypeInfo xilinx_spips_info = {
@@ -630,6 +652,7 @@ static const TypeInfo xilinx_spips_info = {
     .parent = TYPE_SYS_BUS_DEVICE,
     .instance_size  = sizeof(XilinxSPIPS),
     .class_init = xilinx_spips_class_init,
+    .class_size = sizeof(XilinxSPIPSClass),
 };
 
 static const TypeInfo xilinx_qspips_info = {
commit abef5fa6438d654de59dfa083166f41a4067f6b7
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:41 2013 +0100

    xilinx_spips: Add verbose LQSPI debug output
    
    You really need this is you want to track a guest banging on LQSPI.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: 26e508da4af11058d37daa777064c9e5c2a69abb.1369117359.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index a8691d5..29636ce 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -456,10 +456,13 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
     int i;
     XilinxQSPIPS *q = opaque;
     XilinxSPIPS *s = opaque;
+    uint32_t ret;
 
     if (addr >= q->lqspi_cached_addr &&
             addr <= q->lqspi_cached_addr + LQSPI_CACHE_SIZE - 4) {
-        return q->lqspi_buf[(addr - q->lqspi_cached_addr) >> 2];
+        ret = q->lqspi_buf[(addr - q->lqspi_cached_addr) >> 2];
+        DB_PRINT("addr: %08x, data: %08x\n", (unsigned)addr, (unsigned)ret);
+        return ret;
     } else {
         int flash_addr = (addr / num_effective_busses(s));
         int slave = flash_addr >> LQSPI_ADDRESS_BITS;
commit 3ea728d0c87011845666caedc582eaa9629797db
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:41 2013 +0100

    xilinx_spips: Inhibit interrupts in LQSPI mode
    
    The real hardware does not produce interrupts in LQSPI mode. Inhibit
    generation of interrupts when the LQ_MODE bit is set.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: dff794a06872009ea7e5733ce6adcff94d18bbd0.1369117359.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index 261d948..a8691d5 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -204,6 +204,9 @@ static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
 
 static void xilinx_spips_update_ixr(XilinxSPIPS *s)
 {
+    if (s->regs[R_LQSPI_CFG] & LQSPI_CFG_LQ_MODE) {
+        return;
+    }
     /* These are set/cleared as they occur */
     s->regs[R_INTR_STATUS] &= (IXR_TX_FIFO_UNDERFLOW | IXR_RX_FIFO_OVERFLOW |
                                 IXR_TX_FIFO_MODE_FAIL);
@@ -256,7 +259,9 @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
         for (i = 0; i < num_effective_busses(s); ++i) {
             if (!i || s->snoop_state == SNOOP_STRIPING) {
                 if (fifo8_is_empty(&s->tx_fifo)) {
-                    s->regs[R_INTR_STATUS] |= IXR_TX_FIFO_UNDERFLOW;
+                    if (!(s->regs[R_LQSPI_CFG] & LQSPI_CFG_LQ_MODE)) {
+                        s->regs[R_INTR_STATUS] |= IXR_TX_FIFO_UNDERFLOW;
+                    }
                     xilinx_spips_update_ixr(s);
                     return;
                 } else {
commit 87920b44a1e04a45bf74ee0a88a2dfa51c65acdb
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:41 2013 +0100

    xilinx_spips: Make interrupts clear on read
    
    By default these interrupts are clear on read.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: 999ff0091ed3cc3969a431bf55c00ef934cecc8e.1369117359.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index 734adf0..261d948 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -330,6 +330,10 @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
         mask = 0x0002FFFF;
         break;
     case R_INTR_STATUS:
+        ret = s->regs[addr] & IXR_ALL;
+        s->regs[addr] = 0;
+        DB_PRINT("addr=" TARGET_FMT_plx " = %x\n", addr * 4, ret);
+        return ret;
     case R_INTR_MASK:
         mask = IXR_ALL;
         break;
commit 6b91f0155b9338b7fa53d1d64f4e40c43a5d3bba
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Jun 3 17:17:41 2013 +0100

    xilinx_spips: seperate SPI and QSPI as two classes
    
    Make SPI and QSPI different classes. QSPIPS is setup as a child of SPIPS.
    Only QSPI has the LQSPI functionality, so move all that to the child class.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: 2cdd0cadb5ba77ca02fde5cae627852dc9a64c71.1369117359.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 41505c3..4602a6f 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -66,7 +66,7 @@ static inline void zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq,
     int num_busses =  is_qspi ? NUM_QSPI_BUSSES : 1;
     int num_ss = is_qspi ? NUM_QSPI_FLASHES : NUM_SPI_FLASHES;
 
-    dev = qdev_create(NULL, "xilinx,spips");
+    dev = qdev_create(NULL, is_qspi ? "xlnx.ps7-qspi" : "xlnx.ps7-spi");
     qdev_prop_set_uint8(dev, "num-txrx-bytes", is_qspi ? 4 : 1);
     qdev_prop_set_uint8(dev, "num-ss-bits", num_ss);
     qdev_prop_set_uint8(dev, "num-busses", num_busses);
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index b2397f4..734adf0 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -129,7 +129,8 @@ typedef enum {
 } FlashCMD;
 
 typedef struct {
-    SysBusDevice busdev;
+    SysBusDevice parent_obj;
+
     MemoryRegion iomem;
     MemoryRegion mmlqspi;
 
@@ -149,15 +150,23 @@ typedef struct {
     uint8_t num_txrx_bytes;
 
     uint32_t regs[R_MAX];
+} XilinxSPIPS;
+
+typedef struct {
+    XilinxSPIPS parent_obj;
 
     uint32_t lqspi_buf[LQSPI_CACHE_SIZE];
     hwaddr lqspi_cached_addr;
-} XilinxSPIPS;
+} XilinxQSPIPS;
+
 
-#define TYPE_XILINX_SPIPS "xilinx,spips"
+#define TYPE_XILINX_SPIPS "xlnx.ps7-spi"
+#define TYPE_XILINX_QSPIPS "xlnx.ps7-qspi"
 
 #define XILINX_SPIPS(obj) \
      OBJECT_CHECK(XilinxSPIPS, (obj), TYPE_XILINX_SPIPS)
+#define XILINX_QSPIPS(obj) \
+     OBJECT_CHECK(XilinxQSPIPS, (obj), TYPE_XILINX_QSPIPS)
 
 static inline int num_effective_busses(XilinxSPIPS *s)
 {
@@ -436,11 +445,12 @@ static uint64_t
 lqspi_read(void *opaque, hwaddr addr, unsigned int size)
 {
     int i;
+    XilinxQSPIPS *q = opaque;
     XilinxSPIPS *s = opaque;
 
-    if (addr >= s->lqspi_cached_addr &&
-            addr <= s->lqspi_cached_addr + LQSPI_CACHE_SIZE - 4) {
-        return s->lqspi_buf[(addr - s->lqspi_cached_addr) >> 2];
+    if (addr >= q->lqspi_cached_addr &&
+            addr <= q->lqspi_cached_addr + LQSPI_CACHE_SIZE - 4) {
+        return q->lqspi_buf[(addr - q->lqspi_cached_addr) >> 2];
     } else {
         int flash_addr = (addr / num_effective_busses(s));
         int slave = flash_addr >> LQSPI_ADDRESS_BITS;
@@ -484,14 +494,14 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
         for (i = 0; i < LQSPI_CACHE_SIZE / 4; ++i) {
             tx_data_bytes(s, 0, 4);
             xilinx_spips_flush_txfifo(s);
-            rx_data_bytes(s, &s->lqspi_buf[cache_entry], 4);
+            rx_data_bytes(s, &q->lqspi_buf[cache_entry], 4);
             cache_entry++;
         }
 
         s->regs[R_CONFIG] |= CS;
         xilinx_spips_update_cs_lines(s);
 
-        s->lqspi_cached_addr = addr;
+        q->lqspi_cached_addr = addr;
         return lqspi_read(opaque, addr, size);
     }
 }
@@ -511,7 +521,7 @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
     int i;
 
-    DB_PRINT("inited device model\n");
+    DB_PRINT("realized spips\n");
 
     s->spi = g_new(SSIBus *, s->num_busses);
     for (i = 0; i < s->num_busses; ++i) {
@@ -531,17 +541,32 @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
     memory_region_init_io(&s->iomem, &spips_ops, s, "spi", R_MAX*4);
     sysbus_init_mmio(sbd, &s->iomem);
 
-    memory_region_init_io(&s->mmlqspi, &lqspi_ops, s, "lqspi",
-                          (1 << LQSPI_ADDRESS_BITS) * 2);
-    sysbus_init_mmio(sbd, &s->mmlqspi);
-
     s->irqline = -1;
-    s->lqspi_cached_addr = ~0ULL;
 
     fifo8_create(&s->rx_fifo, RXFF_A);
     fifo8_create(&s->tx_fifo, TXFF_A);
 }
 
+static void xilinx_qspips_realize(DeviceState *dev, Error **errp)
+{
+    XilinxSPIPS *s = XILINX_SPIPS(dev);
+    XilinxQSPIPS *q = XILINX_QSPIPS(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+    DB_PRINT("realized qspips\n");
+
+    s->num_busses = 2;
+    s->num_cs = 2;
+    s->num_txrx_bytes = 4;
+
+    xilinx_spips_realize(dev, errp);
+    memory_region_init_io(&s->mmlqspi, &lqspi_ops, s, "lqspi",
+                          (1 << LQSPI_ADDRESS_BITS) * 2);
+    sysbus_init_mmio(sbd, &s->mmlqspi);
+
+    q->lqspi_cached_addr = ~0ULL;
+}
+
 static int xilinx_spips_post_load(void *opaque, int version_id)
 {
     xilinx_spips_update_ixr((XilinxSPIPS *)opaque);
@@ -570,6 +595,14 @@ static Property xilinx_spips_properties[] = {
     DEFINE_PROP_UINT8("num-txrx-bytes", XilinxSPIPS, num_txrx_bytes, 1),
     DEFINE_PROP_END_OF_LIST(),
 };
+
+static void xilinx_qspips_class_init(ObjectClass *klass, void * data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = xilinx_qspips_realize;
+}
+
 static void xilinx_spips_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -587,9 +620,17 @@ static const TypeInfo xilinx_spips_info = {
     .class_init = xilinx_spips_class_init,
 };
 
+static const TypeInfo xilinx_qspips_info = {
+    .name  = TYPE_XILINX_QSPIPS,
+    .parent = TYPE_XILINX_SPIPS,
+    .instance_size  = sizeof(XilinxQSPIPS),
+    .class_init = xilinx_qspips_class_init,
+};
+
 static void xilinx_spips_register_types(void)
 {
     type_register_static(&xilinx_spips_info);
+    type_register_static(&xilinx_qspips_info);
 }
 
 type_init(xilinx_spips_register_types)
commit 9cdf79d068f52f7de347cb45cfd8903519410e4d
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date:   Mon May 27 16:46:01 2013 +0000

    xen: use pc_init_pci instead of pc_init_pci_no_kvmclock
    
    Call kvmclock_create only if kvmclock_enabled.
    Use pc_init_pci on Xen rather than pc_init_pci_no_kvmclock.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 742544e..2653502 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -98,7 +98,7 @@ static void pc_init1(MemoryRegion *system_memory,
     pc_cpus_init(cpu_model, icc_bridge);
     pc_acpi_init("acpi-dsdt.aml");
 
-    if (kvmclock_enabled) {
+    if (kvm_enabled() && kvmclock_enabled) {
         kvmclock_create();
     }
 
@@ -323,7 +323,7 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
     if (xen_hvm_init() != 0) {
         hw_error("xen hardware virtual machine initialisation failed");
     }
-    pc_init_pci_no_kvmclock(args);
+    pc_init_pci(args);
 }
 #endif
 
commit 95222d0945ac8e7fea2adf2fc927634ff3ea1389
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date:   Thu May 30 16:52:44 2013 +0000

    xen: remove xen_vcpu_init
    
    No need for xen_vcpu_init anymore:
    
    - the RTC emulator doesn't have any periodic timers continuously running
    even in absence of guest interactions anymore;
    
    - qemu_dummy_start_vcpu takes care of disabling TCG for us, so we don't
    need to do it manually here.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 06416ce..742544e 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -324,7 +324,6 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
         hw_error("xen hardware virtual machine initialisation failed");
     }
     pc_init_pci_no_kvmclock(args);
-    xen_vcpu_init();
 }
 #endif
 
diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h
index b42b0fd..6d42dd1 100644
--- a/include/hw/xen/xen.h
+++ b/include/hw/xen/xen.h
@@ -38,7 +38,6 @@ qemu_irq *xen_interrupt_controller_init(void);
 
 int xen_init(void);
 int xen_hvm_init(void);
-void xen_vcpu_init(void);
 void xenstore_store_pv_console_info(int i, struct CharDriverState *chr);
 
 #if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY)
diff --git a/xen-all.c b/xen-all.c
index 5ca0c26..bc105f1 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -574,29 +574,6 @@ void qmp_xen_set_global_dirty_log(bool enable, Error **errp)
     }
 }
 
-/* VCPU Operations, MMIO, IO ring ... */
-
-static void xen_reset_vcpu(void *opaque)
-{
-    CPUState *cpu = opaque;
-
-    cpu->halted = 1;
-}
-
-void xen_vcpu_init(void)
-{
-    if (first_cpu != NULL) {
-        CPUState *cpu = ENV_GET_CPU(first_cpu);
-
-        qemu_register_reset(xen_reset_vcpu, cpu);
-        xen_reset_vcpu(cpu);
-    }
-    /* if rtc_clock is left to default (host_clock), disable it */
-    if (rtc_clock == host_clock) {
-        qemu_clock_enable(rtc_clock, false);
-    }
-}
-
 /* get the ioreq packets from share mem */
 static ioreq_t *cpu_get_ioreq_from_shared_memory(XenIOState *state, int vcpu)
 {
commit 9f24a8030a70ea4954b5b8c48f606012f086f65f
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date:   Mon Jun 3 15:37:45 2013 +0000

    xen: start PCI hole at 0xe0000000 (same as pc_init1 and qemu-xen-traditional)
    
    We are currently setting the PCI hole to start at HVM_BELOW_4G_RAM_END,
    that is 0xf0000000.
    Start the PCI hole at 0xe0000000 instead, that is the same value used by
    pc_init1 and qemu-xen-traditional.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
    CC: qemu-stable at nongnu.org

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 43ab480..06416ce 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -102,9 +102,9 @@ static void pc_init1(MemoryRegion *system_memory,
         kvmclock_create();
     }
 
-    if (ram_size >= 0xe0000000 ) {
-        above_4g_mem_size = ram_size - 0xe0000000;
-        below_4g_mem_size = 0xe0000000;
+    if (ram_size >= QEMU_BELOW_4G_RAM_END ) {
+        above_4g_mem_size = ram_size - QEMU_BELOW_4G_RAM_END;
+        below_4g_mem_size = QEMU_BELOW_4G_RAM_END;
     } else {
         above_4g_mem_size = 0;
         below_4g_mem_size = ram_size;
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 663426c..626442b 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -77,6 +77,9 @@ extern int fd_bootchk;
 void pc_register_ferr_irq(qemu_irq irq);
 void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
 
+#define QEMU_BELOW_4G_RAM_END       0xe0000000
+#define QEMU_BELOW_4G_MMIO_LENGTH   ((1ULL << 32) - QEMU_BELOW_4G_RAM_END)
+
 void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge);
 void pc_hot_add_cpu(const int64_t id, Error **errp);
 void pc_acpi_init(const char *default_dsdt);
diff --git a/xen-all.c b/xen-all.c
index 539a154..5ca0c26 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -161,18 +161,18 @@ static void xen_ram_init(ram_addr_t ram_size)
     ram_addr_t block_len;
 
     block_len = ram_size;
-    if (ram_size >= HVM_BELOW_4G_RAM_END) {
+    if (ram_size >= QEMU_BELOW_4G_RAM_END) {
         /* Xen does not allocate the memory continuously, and keep a hole at
-         * HVM_BELOW_4G_MMIO_START of HVM_BELOW_4G_MMIO_LENGTH
+         * QEMU_BELOW_4G_RAM_END of QEMU_BELOW_4G_MMIO_LENGTH
          */
-        block_len += HVM_BELOW_4G_MMIO_LENGTH;
+        block_len += QEMU_BELOW_4G_MMIO_LENGTH;
     }
     memory_region_init_ram(&ram_memory, "xen.ram", block_len);
     vmstate_register_ram_global(&ram_memory);
 
-    if (ram_size >= HVM_BELOW_4G_RAM_END) {
-        above_4g_mem_size = ram_size - HVM_BELOW_4G_RAM_END;
-        below_4g_mem_size = HVM_BELOW_4G_RAM_END;
+    if (ram_size >= QEMU_BELOW_4G_RAM_END) {
+        above_4g_mem_size = ram_size - QEMU_BELOW_4G_RAM_END;
+        below_4g_mem_size = QEMU_BELOW_4G_RAM_END;
     } else {
         below_4g_mem_size = ram_size;
     }
commit 58ee9b0ae05d81c74d6869a25ce4263fc22ed809
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date:   Mon Jun 3 15:38:31 2013 +0000

    xen_machine_pv: do not create a dummy CPU in machine->init
    
    This fixes a regression introduced by:
    
    commit 62fc403f11523169eb4264de31279745f48e3ecc
    Author: Igor Mammedov <imammedo at redhat.com>
    Date:   Mon Apr 29 18:54:13 2013 +0200
    
        target-i386: Attach ICC bus to CPU on its creation
    
        X86CPU should have parent bus so it could provide bus for child APIC.
    
    The commit makes it mandatory to pass a valid ICC bus to cpu_x86_create,
    but cpu_x86_init just passes NULL to it.
    xen_machine_pv uses cpu_x86_init, therefore it has been broken.
    
    This patch fixes the problem by removing the dummy CPU creation
    altogether from xen_init_pv, relying on the fact that QEMU can now cope
    with a machine without an emulated CPU.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    CC: imammedo at redhat.com
    CC: qemu-stable at nongnu.org

diff --git a/hw/i386/xen_machine_pv.c b/hw/i386/xen_machine_pv.c
index f829a52..9f2e291 100644
--- a/hw/i386/xen_machine_pv.c
+++ b/hw/i386/xen_machine_pv.c
@@ -23,7 +23,6 @@
  */
 
 #include "hw/hw.h"
-#include "hw/i386/pc.h"
 #include "hw/boards.h"
 #include "hw/xen/xen_backend.h"
 #include "xen_domainbuild.h"
@@ -31,27 +30,12 @@
 
 static void xen_init_pv(QEMUMachineInitArgs *args)
 {
-    const char *cpu_model = args->cpu_model;
     const char *kernel_filename = args->kernel_filename;
     const char *kernel_cmdline = args->kernel_cmdline;
     const char *initrd_filename = args->initrd_filename;
-    X86CPU *cpu;
-    CPUState *cs;
     DriveInfo *dinfo;
     int i;
 
-    /* Initialize a dummy CPU */
-    if (cpu_model == NULL) {
-#ifdef TARGET_X86_64
-        cpu_model = "qemu64";
-#else
-        cpu_model = "qemu32";
-#endif
-    }
-    cpu = cpu_x86_init(cpu_model);
-    cs = CPU(cpu);
-    cs->halted = 1;
-
     /* Initialize backend core & drivers */
     if (xen_be_init() != 0) {
         fprintf(stderr, "%s: xen backend core setup failed\n", __FUNCTION__);
commit a7d4207d378069a5bb3175a131e8fdedd39ef97d
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date:   Mon Jun 3 15:38:43 2013 +0000

    main_loop: do not set nonblocking if xen_enabled()
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
    CC: qemu-stable at nongnu.org

diff --git a/vl.c b/vl.c
index 510d2c2..47ab45d 100644
--- a/vl.c
+++ b/vl.c
@@ -2022,7 +2022,7 @@ static void main_loop(void)
     int64_t ti;
 #endif
     do {
-        nonblocking = !kvm_enabled() && last_io > 0;
+        nonblocking = !kvm_enabled() && !xen_enabled() && last_io > 0;
 #ifdef CONFIG_PROFILER
         ti = profile_getclock();
 #endif
commit 49fa9881b2358e390e9e9466ddde74e995927efa
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date:   Mon Jun 3 15:38:48 2013 +0000

    xen: simplify xen_enabled
    
    No need for preprocessor conditionals in xen_enabled: xen_allowed is
    always defined.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
    CC: qemu-stable at nongnu.org

diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h
index 7451c5a..b42b0fd 100644
--- a/include/hw/xen/xen.h
+++ b/include/hw/xen/xen.h
@@ -25,11 +25,7 @@ extern bool xen_allowed;
 
 static inline bool xen_enabled(void)
 {
-#if defined(CONFIG_XEN_BACKEND) && defined(CONFIG_XEN)
     return xen_allowed;
-#else
-    return 0;
-#endif
 }
 
 int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
commit 5866e078770cba631a33e6d3062afa7a4068adf8
Author: Peter Chubb <peter.chubb at nicta.com.au>
Date:   Thu May 30 18:50:50 2013 +0000

    Fix rfe instruction
    
    The rfe instruction has been broken since patch
    5a839c0d54fac9db0516904db873a4fe01f50f4b because of a typo.
    
    Signed-off-by: Peter Chubb <peter.chubb at nicta.com.au>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 71135bd..b462f4b 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6752,7 +6752,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
             tcg_gen_qemu_ld32u(tmp, addr, 0);
             tcg_gen_addi_i32(addr, addr, 4);
             tmp2 = tcg_temp_new_i32();
-            tcg_gen_qemu_ld32u(tmp, addr, 0);
+            tcg_gen_qemu_ld32u(tmp2, addr, 0);
             if (insn & (1 << 21)) {
                 /* Base writeback.  */
                 switch (i) {
commit 8b779b368b3b45d5ed3160173499eeafee4d567c
Author: Ákos Kovács <akoskovacs at gmx.com>
Date:   Mon May 6 19:14:52 2013 +0200

    po/hu.po: Hungarian translation for the GTK+ interface
    
    Cc: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Ákos Kovács <akoskovacs at gmx.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Message-id: 1367860492-3357-1-git-send-email-akoskovacs at gmx.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/po/hu.po b/po/hu.po
new file mode 100644
index 0000000..debba96
--- /dev/null
+++ b/po/hu.po
@@ -0,0 +1,63 @@
+# Hungarian translation for QEMU.
+# This file is put in the public domain.
+# Ákos Kovács <akoskovacs at gmx.com>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: QEMU 1.4.50\n"
+"Report-Msgid-Bugs-To: qemu-devel at nongnu.org\n"
+"POT-Creation-Date: 2013-05-06 20:42+0200\n"
+"PO-Revision-Date: 2013-05-06 20:42+0200\n"
+"Last-Translator: Ákos Kovács <akoskovacs at gmx.com>\n"
+"Language-Team: Hungarian <hu at li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../ui/gtk.c:213
+msgid " - Press Ctrl+Alt+G to release grab"
+msgstr " - Nyomj Ctrl+Alt+G-t a bemeneti eszközök elengedéséhez"
+
+#: ../ui/gtk.c:217
+msgid " [Paused]"
+msgstr " [Megállítva]"
+
+#: ../ui/gtk.c:1250
+msgid "_Machine"
+msgstr "_Gép"
+
+#: ../ui/gtk.c:1252
+msgid "_Pause"
+msgstr "_Megállítás"
+
+#: ../ui/gtk.c:1258
+msgid "_Reset"
+msgstr "Új_raindítás"
+
+#: ../ui/gtk.c:1261
+msgid "Power _Down"
+msgstr "_Leállítás"
+
+#: ../ui/gtk.c:1276
+msgid "_View"
+msgstr "_Nézet"
+
+#: ../ui/gtk.c:1306
+msgid "Zoom To _Fit"
+msgstr "Ablakmérethez _igazítás"
+
+#: ../ui/gtk.c:1312
+msgid "Grab On _Hover"
+msgstr "Automatikus _elfogás"
+
+#: ../ui/gtk.c:1315
+msgid "_Grab Input"
+msgstr "_Bemeneti eszközök megragadása"
+
+#: ../ui/gtk.c:1341
+msgid "Show _Tabs"
+msgstr "_Fülek megjelenítése"
+
+#~ msgid "_File"
+#~ msgstr "_File"
commit 40459a0312569817f622926efd0780ef2299aaa1
Merge: 7087d3d 37352df
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Jun 3 08:37:54 2013 -0500

    Merge remote-tracking branch 'kraxel/usb.83' into staging
    
    # By Gerd Hoffmann (5) and others
    # Via Gerd Hoffmann
    * kraxel/usb.83:
      xhci: add live migration support
      xhci: add xhci_init_epctx
      xhci: add xhci_alloc_epctx
      xhci: add XHCISlot->addressed
      pci: add VMSTATE_MSIX
      host-libusb: Correct test for USB packet state
      Fix usage of USB_DEV_FLAG_IS_HOST flag.
    
    Message-id: 1370253951-12323-1-git-send-email-kraxel at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 7087d3df18b8e8d27a2115dfc5d56614073e55de
Merge: f10acc8 a4cc73d
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Jun 3 08:37:44 2013 -0500

    Merge remote-tracking branch 'mjt/trivial-patches' into staging
    
    # By Ed Maste (3) and others
    # Via Michael Tokarev
    * mjt/trivial-patches:
      do not check pointers after dereferencing them
      m25p80: Add Micron n25q032a
      qemu: fix out of tree cross compile
      slirp: cleanup leftovers from misc.h
      migration: Remove duplicate bandwidth_limit set
      docs: Fix typo and update file in migration
      configure: try pkg-config ncurses first
      rtc: remove rtc_set_date
      linux-user: Fix typo in comment
      configure: remove confusing file manipulation
      debugcon: fix compiler warning when open DEBUG_DEBUGCON
      debugcon: make debug message more readable
      debugcon: fix always print "addr=0x0, val=0x0" bug when use DEBUG_DEBUGCON
      Remove unnecessary break statements
      don't run pkg-config for features explicitly disabled
    
    Message-id: 51A9CCFB.1000109 at msgid.tls.msk.ru
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 37352df30fbc38d1de464db8927536d5e36cf52a
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Mar 21 10:55:35 2013 +0100

    xhci: add live migration support
    
    With all preparing pieces in place we can finally drop in
    the vmstate structs and the postload function.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 9b90067..91633ed 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -3386,9 +3386,171 @@ static int usb_xhci_initfn(struct PCIDevice *dev)
     return 0;
 }
 
+static int usb_xhci_post_load(void *opaque, int version_id)
+{
+    XHCIState *xhci = opaque;
+    XHCISlot *slot;
+    XHCIEPContext *epctx;
+    dma_addr_t dcbaap, pctx;
+    uint32_t slot_ctx[4];
+    uint32_t ep_ctx[5];
+    int slotid, epid, state, intr;
+
+    dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high);
+
+    for (slotid = 1; slotid <= xhci->numslots; slotid++) {
+        slot = &xhci->slots[slotid-1];
+        if (!slot->addressed) {
+            continue;
+        }
+        slot->ctx =
+            xhci_mask64(ldq_le_pci_dma(&xhci->pci_dev, dcbaap + 8*slotid));
+        xhci_dma_read_u32s(xhci, slot->ctx, slot_ctx, sizeof(slot_ctx));
+        slot->uport = xhci_lookup_uport(xhci, slot_ctx);
+        assert(slot->uport && slot->uport->dev);
+
+        for (epid = 1; epid <= 32; epid++) {
+            pctx = slot->ctx + 32 * epid;
+            xhci_dma_read_u32s(xhci, pctx, ep_ctx, sizeof(ep_ctx));
+            state = ep_ctx[0] & EP_STATE_MASK;
+            if (state == EP_DISABLED) {
+                continue;
+            }
+            epctx = xhci_alloc_epctx(xhci, slotid, epid);
+            slot->eps[epid-1] = epctx;
+            xhci_init_epctx(epctx, pctx, ep_ctx);
+            epctx->state = state;
+            if (state == EP_RUNNING) {
+                /* kick endpoint after vmload is finished */
+                qemu_mod_timer(epctx->kick_timer, qemu_get_clock_ns(vm_clock));
+            }
+        }
+    }
+
+    for (intr = 0; intr < xhci->numintrs; intr++) {
+        if (xhci->intr[intr].msix_used) {
+            msix_vector_use(&xhci->pci_dev, intr);
+        } else {
+            msix_vector_unuse(&xhci->pci_dev, intr);
+        }
+    }
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_xhci_ring = {
+    .name = "xhci-ring",
+    .version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT64(dequeue, XHCIRing),
+        VMSTATE_BOOL(ccs, XHCIRing),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_xhci_port = {
+    .name = "xhci-port",
+    .version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(portsc, XHCIPort),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_xhci_slot = {
+    .name = "xhci-slot",
+    .version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_BOOL(enabled,   XHCISlot),
+        VMSTATE_BOOL(addressed, XHCISlot),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_xhci_event = {
+    .name = "xhci-event",
+    .version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(type,   XHCIEvent),
+        VMSTATE_UINT32(ccode,  XHCIEvent),
+        VMSTATE_UINT64(ptr,    XHCIEvent),
+        VMSTATE_UINT32(length, XHCIEvent),
+        VMSTATE_UINT32(flags,  XHCIEvent),
+        VMSTATE_UINT8(slotid,  XHCIEvent),
+        VMSTATE_UINT8(epid,    XHCIEvent),
+    }
+};
+
+static bool xhci_er_full(void *opaque, int version_id)
+{
+    struct XHCIInterrupter *intr = opaque;
+    return intr->er_full;
+}
+
+static const VMStateDescription vmstate_xhci_intr = {
+    .name = "xhci-intr",
+    .version_id = 1,
+    .fields = (VMStateField[]) {
+        /* registers */
+        VMSTATE_UINT32(iman,          XHCIInterrupter),
+        VMSTATE_UINT32(imod,          XHCIInterrupter),
+        VMSTATE_UINT32(erstsz,        XHCIInterrupter),
+        VMSTATE_UINT32(erstba_low,    XHCIInterrupter),
+        VMSTATE_UINT32(erstba_high,   XHCIInterrupter),
+        VMSTATE_UINT32(erdp_low,      XHCIInterrupter),
+        VMSTATE_UINT32(erdp_high,     XHCIInterrupter),
+
+        /* state */
+        VMSTATE_BOOL(msix_used,       XHCIInterrupter),
+        VMSTATE_BOOL(er_pcs,          XHCIInterrupter),
+        VMSTATE_UINT64(er_start,      XHCIInterrupter),
+        VMSTATE_UINT32(er_size,       XHCIInterrupter),
+        VMSTATE_UINT32(er_ep_idx,     XHCIInterrupter),
+
+        /* event queue (used if ring is full) */
+        VMSTATE_BOOL(er_full,         XHCIInterrupter),
+        VMSTATE_UINT32_TEST(ev_buffer_put, XHCIInterrupter, xhci_er_full),
+        VMSTATE_UINT32_TEST(ev_buffer_get, XHCIInterrupter, xhci_er_full),
+        VMSTATE_STRUCT_ARRAY_TEST(ev_buffer, XHCIInterrupter, EV_QUEUE,
+                                  xhci_er_full, 1,
+                                  vmstate_xhci_event, XHCIEvent),
+
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_xhci = {
     .name = "xhci",
-    .unmigratable = 1,
+    .version_id = 1,
+    .post_load = usb_xhci_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_PCIE_DEVICE(pci_dev, XHCIState),
+        VMSTATE_MSIX(pci_dev, XHCIState),
+
+        VMSTATE_STRUCT_VARRAY_UINT32(ports, XHCIState, numports, 1,
+                                     vmstate_xhci_port, XHCIPort),
+        VMSTATE_STRUCT_VARRAY_UINT32(slots, XHCIState, numslots, 1,
+                                     vmstate_xhci_slot, XHCISlot),
+        VMSTATE_STRUCT_VARRAY_UINT32(intr, XHCIState, numintrs, 1,
+                                     vmstate_xhci_intr, XHCIInterrupter),
+
+        /* Operational Registers */
+        VMSTATE_UINT32(usbcmd,        XHCIState),
+        VMSTATE_UINT32(usbsts,        XHCIState),
+        VMSTATE_UINT32(dnctrl,        XHCIState),
+        VMSTATE_UINT32(crcr_low,      XHCIState),
+        VMSTATE_UINT32(crcr_high,     XHCIState),
+        VMSTATE_UINT32(dcbaap_low,    XHCIState),
+        VMSTATE_UINT32(dcbaap_high,   XHCIState),
+        VMSTATE_UINT32(config,        XHCIState),
+
+        /* Runtime Registers & state */
+        VMSTATE_INT64(mfindex_start,  XHCIState),
+        VMSTATE_TIMER(mfwrap_timer,   XHCIState),
+        VMSTATE_STRUCT(cmd_ring, XHCIState, 1, vmstate_xhci_ring, XHCIRing),
+
+        VMSTATE_END_OF_LIST()
+    }
 };
 
 static Property xhci_properties[] = {
commit 003e15a180373048f0c1f4df0bfe303746eb2676
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Wed Apr 24 10:11:22 2013 +0200

    xhci: add xhci_init_epctx
    
    Factor out endpoint context initialization to a separate function.
    xhci live migration will need that too, in post_load.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 5084e52..9b90067 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1218,26 +1218,11 @@ static XHCIEPContext *xhci_alloc_epctx(XHCIState *xhci,
     return epctx;
 }
 
-static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,
-                               unsigned int epid, dma_addr_t pctx,
-                               uint32_t *ctx)
+static void xhci_init_epctx(XHCIEPContext *epctx,
+                            dma_addr_t pctx, uint32_t *ctx)
 {
-    XHCISlot *slot;
-    XHCIEPContext *epctx;
     dma_addr_t dequeue;
 
-    trace_usb_xhci_ep_enable(slotid, epid);
-    assert(slotid >= 1 && slotid <= xhci->numslots);
-    assert(epid >= 1 && epid <= 31);
-
-    slot = &xhci->slots[slotid-1];
-    if (slot->eps[epid-1]) {
-        xhci_disable_ep(xhci, slotid, epid);
-    }
-
-    epctx = xhci_alloc_epctx(xhci, slotid, epid);
-    slot->eps[epid-1] = epctx;
-
     dequeue = xhci_addr64(ctx[2] & ~0xf, ctx[3]);
 
     epctx->type = (ctx[1] >> EP_TYPE_SHIFT) & EP_TYPE_MASK;
@@ -1252,11 +1237,33 @@ static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,
     if (epctx->max_pstreams) {
         xhci_alloc_streams(epctx, dequeue);
     } else {
-        xhci_ring_init(xhci, &epctx->ring, dequeue);
+        xhci_ring_init(epctx->xhci, &epctx->ring, dequeue);
         epctx->ring.ccs = ctx[2] & 1;
     }
 
     epctx->interval = 1 << (ctx[0] >> 16) & 0xff;
+}
+
+static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,
+                               unsigned int epid, dma_addr_t pctx,
+                               uint32_t *ctx)
+{
+    XHCISlot *slot;
+    XHCIEPContext *epctx;
+
+    trace_usb_xhci_ep_enable(slotid, epid);
+    assert(slotid >= 1 && slotid <= xhci->numslots);
+    assert(epid >= 1 && epid <= 31);
+
+    slot = &xhci->slots[slotid-1];
+    if (slot->eps[epid-1]) {
+        xhci_disable_ep(xhci, slotid, epid);
+    }
+
+    epctx = xhci_alloc_epctx(xhci, slotid, epid);
+    slot->eps[epid-1] = epctx;
+    xhci_init_epctx(epctx, pctx, ctx);
+
     epctx->mfindex_last = 0;
 
     epctx->state = EP_RUNNING;
commit 492b21f63fa655e0271abef4784cc337dd1d3fe7
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Wed Apr 24 09:33:35 2013 +0200

    xhci: add xhci_alloc_epctx
    
    Factor out endpoint context allocation to a separate function.
    xhci live migration will need that too, in post_load.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index ac683ce..5084e52 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1198,6 +1198,26 @@ static void xhci_ep_kick_timer(void *opaque)
     xhci_kick_ep(epctx->xhci, epctx->slotid, epctx->epid, 0);
 }
 
+static XHCIEPContext *xhci_alloc_epctx(XHCIState *xhci,
+                                       unsigned int slotid,
+                                       unsigned int epid)
+{
+    XHCIEPContext *epctx;
+    int i;
+
+    epctx = g_new0(XHCIEPContext, 1);
+    epctx->xhci = xhci;
+    epctx->slotid = slotid;
+    epctx->epid = epid;
+
+    for (i = 0; i < ARRAY_SIZE(epctx->transfers); i++) {
+        usb_packet_init(&epctx->transfers[i].packet);
+    }
+    epctx->kick_timer = qemu_new_timer_ns(vm_clock, xhci_ep_kick_timer, epctx);
+
+    return epctx;
+}
+
 static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,
                                unsigned int epid, dma_addr_t pctx,
                                uint32_t *ctx)
@@ -1205,7 +1225,6 @@ static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,
     XHCISlot *slot;
     XHCIEPContext *epctx;
     dma_addr_t dequeue;
-    int i;
 
     trace_usb_xhci_ep_enable(slotid, epid);
     assert(slotid >= 1 && slotid <= xhci->numslots);
@@ -1216,12 +1235,7 @@ static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,
         xhci_disable_ep(xhci, slotid, epid);
     }
 
-    epctx = g_malloc(sizeof(XHCIEPContext));
-    memset(epctx, 0, sizeof(XHCIEPContext));
-    epctx->xhci = xhci;
-    epctx->slotid = slotid;
-    epctx->epid = epid;
-
+    epctx = xhci_alloc_epctx(xhci, slotid, epid);
     slot->eps[epid-1] = epctx;
 
     dequeue = xhci_addr64(ctx[2] & ~0xf, ctx[3]);
@@ -1241,13 +1255,9 @@ static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,
         xhci_ring_init(xhci, &epctx->ring, dequeue);
         epctx->ring.ccs = ctx[2] & 1;
     }
-    for (i = 0; i < ARRAY_SIZE(epctx->transfers); i++) {
-        usb_packet_init(&epctx->transfers[i].packet);
-    }
 
     epctx->interval = 1 << (ctx[0] >> 16) & 0xff;
     epctx->mfindex_last = 0;
-    epctx->kick_timer = qemu_new_timer_ns(vm_clock, xhci_ep_kick_timer, epctx);
 
     epctx->state = EP_RUNNING;
     ctx[0] &= ~EP_STATE_MASK;
commit 4034e6938a4cba090a8fac02499c8a9567201665
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Apr 5 12:37:32 2013 +0200

    xhci: add XHCISlot->addressed
    
    Preparing for live-migration support, post_load will need that.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 8813bdf..ac683ce 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -405,6 +405,7 @@ struct XHCIEPContext {
 
 typedef struct XHCISlot {
     bool enabled;
+    bool addressed;
     dma_addr_t ctx;
     USBPort *uport;
     XHCIEPContext * eps[31];
@@ -2041,6 +2042,7 @@ static TRBCCode xhci_disable_slot(XHCIState *xhci, unsigned int slotid)
     }
 
     xhci->slots[slotid-1].enabled = 0;
+    xhci->slots[slotid-1].addressed = 0;
     return CC_SUCCESS;
 }
 
@@ -2167,6 +2169,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
     xhci_dma_write_u32s(xhci, octx, slot_ctx, sizeof(slot_ctx));
     xhci_dma_write_u32s(xhci, octx+32, ep0_ctx, sizeof(ep0_ctx));
 
+    xhci->slots[slotid-1].addressed = 1;
     return res;
 }
 
commit 340b50c759d6b4ef33e514c40afcc799c0d7df7a
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Tue May 7 15:16:58 2013 +0200

    pci: add VMSTATE_MSIX
    
    Using a trick cut+pasted from vmstate_scsi_device
    to wind up msix_save and msix_load.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
    Acked-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pci/msix.c b/hw/pci/msix.c
index e231a0d..6da75ec 100644
--- a/hw/pci/msix.c
+++ b/hw/pci/msix.c
@@ -569,3 +569,36 @@ void msix_unset_vector_notifiers(PCIDevice *dev)
     dev->msix_vector_release_notifier = NULL;
     dev->msix_vector_poll_notifier = NULL;
 }
+
+static void put_msix_state(QEMUFile *f, void *pv, size_t size)
+{
+    msix_save(pv, f);
+}
+
+static int get_msix_state(QEMUFile *f, void *pv, size_t size)
+{
+    msix_load(pv, f);
+    return 0;
+}
+
+static VMStateInfo vmstate_info_msix = {
+    .name = "msix state",
+    .get  = get_msix_state,
+    .put  = put_msix_state,
+};
+
+const VMStateDescription vmstate_msix = {
+    .name = "msix",
+    .fields = (VMStateField[]) {
+        {
+            .name         = "msix",
+            .version_id   = 0,
+            .field_exists = NULL,
+            .size         = 0,   /* ouch */
+            .info         = &vmstate_info_msix,
+            .flags        = VMS_SINGLE,
+            .offset       = 0,
+        },
+        VMSTATE_END_OF_LIST()
+    }
+};
diff --git a/include/hw/pci/msix.h b/include/hw/pci/msix.h
index e648410..954d82b 100644
--- a/include/hw/pci/msix.h
+++ b/include/hw/pci/msix.h
@@ -43,4 +43,15 @@ int msix_set_vector_notifiers(PCIDevice *dev,
                               MSIVectorReleaseNotifier release_notifier,
                               MSIVectorPollNotifier poll_notifier);
 void msix_unset_vector_notifiers(PCIDevice *dev);
+
+extern const VMStateDescription vmstate_msix;
+
+#define VMSTATE_MSIX(_field, _state) {                               \
+    .name       = (stringify(_field)),                               \
+    .size       = sizeof(PCIDevice),                                 \
+    .vmsd       = &vmstate_msix,                                     \
+    .flags      = VMS_STRUCT,                                        \
+    .offset     = vmstate_offset_value(_state, _field, PCIDevice),   \
+}
+
 #endif
commit 45ec267160307ce2ca7494d942589ba222b29479
Author: Ed Maste <emaste at freebsd.org>
Date:   Tue May 7 10:06:12 2013 -0400

    host-libusb: Correct test for USB packet state
    
    USB_RET_ASYNC is -6, so inflight was always false.
    
    Signed-off-by: Ed Maste <emaste at freebsd.org>
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index f3de459..3a582c5 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -385,7 +385,7 @@ out:
 static void usb_host_req_abort(USBHostRequest *r)
 {
     USBHostDevice  *s = r->host;
-    bool inflight = (r->p && r->p->state == USB_RET_ASYNC);
+    bool inflight = (r->p && r->p->state == USB_PACKET_ASYNC);
 
     if (inflight) {
         r->p->status = USB_RET_NODEV;
commit 756335292f2b46775992c314cc70b54480a46d26
Author: Michael Marineau <mike at marineau.org>
Date:   Sun May 12 19:19:37 2013 -0400

    Fix usage of USB_DEV_FLAG_IS_HOST flag.
    
    USB_DEV_FLAG_IS_HOST is the bit number, not value. Booting with a
    "Fitbit Base Station" USB dongle was triggering this assert.
    
    Signed-off-by: Michael Marineau <mike at marineau.org>
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/core.c b/hw/usb/core.c
index 15a150a..05948ca 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -410,7 +410,7 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p)
             assert(p->ep->type != USB_ENDPOINT_XFER_ISOC);
             /* using async for interrupt packets breaks migration */
             assert(p->ep->type != USB_ENDPOINT_XFER_INT ||
-                   (dev->flags & USB_DEV_FLAG_IS_HOST));
+                   (dev->flags & (1 << USB_DEV_FLAG_IS_HOST)));
             usb_packet_set_state(p, USB_PACKET_ASYNC);
             QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
         } else if (p->status == USB_RET_ADD_TO_QUEUE) {
commit f10acc8b38d65a66ffa0588a036489d7fa6a593e
Author: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
Date:   Sun Jun 2 17:23:00 2013 +0100

    tcx: Fix 24-bit display mode
    
    Commit d08151bf (conversion of tcx to the memory API) broke the 24-bit mode of
    the tcx display adapter by accidentally passing in the final address of the
    dirty region to memory_region_reset_dirty() instead of its size.
    
    Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/display/tcx.c b/hw/display/tcx.c
index fc27f45..995641c 100644
--- a/hw/display/tcx.c
+++ b/hw/display/tcx.c
@@ -193,15 +193,16 @@ static inline void reset_dirty(TCXState *ts, ram_addr_t page_min,
                               ram_addr_t cpage)
 {
     memory_region_reset_dirty(&ts->vram_mem,
-                              page_min, page_max + TARGET_PAGE_SIZE,
+                              page_min,
+                              (page_max - page_min) + TARGET_PAGE_SIZE,
                               DIRTY_MEMORY_VGA);
     memory_region_reset_dirty(&ts->vram_mem,
                               page24 + page_min * 4,
-                              page24 + page_max * 4 + TARGET_PAGE_SIZE,
+                              (page_max - page_min) * 4 + TARGET_PAGE_SIZE,
                               DIRTY_MEMORY_VGA);
     memory_region_reset_dirty(&ts->vram_mem,
                               cpage + page_min * 4,
-                              cpage + page_max * 4 + TARGET_PAGE_SIZE,
+                              (page_max - page_min) * 4 + TARGET_PAGE_SIZE,
                               DIRTY_MEMORY_VGA);
 }
 
@@ -285,7 +286,8 @@ static void tcx_update_display(void *opaque)
     /* reset modified pages */
     if (page_max >= page_min) {
         memory_region_reset_dirty(&ts->vram_mem,
-                                  page_min, page_max + TARGET_PAGE_SIZE,
+                                  page_min,
+                                  (page_max - page_min) + TARGET_PAGE_SIZE,
                                   DIRTY_MEMORY_VGA);
     }
 }
commit c3c4fe35be9f6c37388ba7615c6c33e8f4034438
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Thu May 30 15:59:06 2013 +0300

    pvpanic: use FWCfgState explicitly
    
    Use the type-safe FWCfgState structure instead
    of the unsafe void *.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 159340f..910e44f 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -90,7 +90,7 @@ static int pvpanic_isa_initfn(ISADevice *dev)
 {
     PVPanicState *s = ISA_PVPANIC_DEVICE(dev);
     static bool port_configured;
-    void *fw_cfg;
+    FWCfgState *fw_cfg;
 
     memory_region_init_io(&s->io, &pvpanic_ops, s, "pvpanic", 1);
     isa_register_ioport(dev, &s->io, s->ioport);
commit cac122103abac633d7b39aac87273bf6d5a37588
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Thu May 30 16:21:24 2013 +0300

    fw_cfg: fw_cfg is a singleton
    
    Make sure we only have a single instance ever:
    because if it isn't we can't find it so it's
    useless anyway.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index df3f089..3c255ce 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -496,10 +496,9 @@ FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
 
     s = DO_UPCAST(FWCfgState, busdev.qdev, dev);
 
-    if (!object_resolve_path(FW_CFG_PATH, NULL)) {
-        object_property_add_child(qdev_get_machine(), FW_CFG_NAME, OBJECT(s),
-                                  NULL);
-    }
+    assert(!object_resolve_path(FW_CFG_PATH, NULL));
+
+    object_property_add_child(qdev_get_machine(), FW_CFG_NAME, OBJECT(s), NULL);
 
     qdev_init_nofail(dev);
 
commit 600c60b76d0682f6c39d19bfff79da9321e8cf86
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Thu May 30 16:07:58 2013 +0300

    fw_cfg: add API to find FW cfg object
    
    Remove some code duplication by adding a
    function to look up the fw cfg file.
    This way, we don't need to duplicate same strings everywhere.
    Use by both fw cfg and pvpanic device.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 31e1b1d..159340f 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -96,7 +96,7 @@ static int pvpanic_isa_initfn(ISADevice *dev)
     isa_register_ioport(dev, &s->io, s->ioport);
 
     if (!port_configured) {
-        fw_cfg = object_resolve_path("/machine/fw_cfg", NULL);
+        fw_cfg = fw_cfg_find();
         if (fw_cfg) {
             fw_cfg_add_file(fw_cfg, "etc/pvpanic-port",
                             g_memdup(&s->ioport, sizeof(s->ioport)),
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 479113b..df3f089 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -32,6 +32,9 @@
 
 #define FW_CFG_SIZE 2
 #define FW_CFG_DATA_SIZE 1
+#define TYPE_FW_CFG "fw_cfg"
+#define FW_CFG_NAME "fw_cfg"
+#define FW_CFG_PATH "/machine/" FW_CFG_NAME
 
 typedef struct FWCfgEntry {
     uint32_t len;
@@ -493,8 +496,8 @@ FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
 
     s = DO_UPCAST(FWCfgState, busdev.qdev, dev);
 
-    if (!object_resolve_path("/machine/fw_cfg", NULL)) {
-        object_property_add_child(qdev_get_machine(), "fw_cfg", OBJECT(s),
+    if (!object_resolve_path(FW_CFG_PATH, NULL)) {
+        object_property_add_child(qdev_get_machine(), FW_CFG_NAME, OBJECT(s),
                                   NULL);
     }
 
@@ -553,6 +556,12 @@ static Property fw_cfg_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
+FWCfgState *fw_cfg_find(void)
+{
+    return OBJECT_CHECK(FWCfgState, object_resolve_path(FW_CFG_PATH, NULL),
+                        TYPE_FW_CFG);
+}
+
 static void fw_cfg_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -566,7 +575,7 @@ static void fw_cfg_class_init(ObjectClass *klass, void *data)
 }
 
 static const TypeInfo fw_cfg_info = {
-    .name          = "fw_cfg",
+    .name          = TYPE_FW_CFG,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(FWCfgState),
     .class_init    = fw_cfg_class_init,
diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
index f37714e..f60dd67 100644
--- a/include/hw/nvram/fw_cfg.h
+++ b/include/hw/nvram/fw_cfg.h
@@ -73,6 +73,8 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data,
 FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
                         hwaddr crl_addr, hwaddr data_addr);
 
+FWCfgState *fw_cfg_find(void);
+
 #endif /* NO_QEMU_PROTOS */
 
 #endif
commit 45936c8b79012da4c8986c20af4afcc9cd14bb8e
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Mon May 13 16:27:06 2013 +0300

    fw_cfg: move typedef to qemu/typedefs.h
    
    Less header dependencies this way.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index fa3bf24..b4c8a74 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -8,7 +8,6 @@
 #include "hw/block/fdc.h"
 #include "net/net.h"
 #include "hw/i386/ioapic.h"
-#include "hw/nvram/fw_cfg.h"
 
 /* PC-style peripherals (also used by other machines).  */
 
diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
index 3e4a334..f37714e 100644
--- a/include/hw/nvram/fw_cfg.h
+++ b/include/hw/nvram/fw_cfg.h
@@ -6,6 +6,7 @@
 #include <stddef.h>
 
 #include "exec/hwaddr.h"
+#include "qemu/typedefs.h"
 #endif
 
 #define FW_CFG_SIGNATURE        0x00
@@ -60,7 +61,6 @@ typedef struct FWCfgFiles {
 
 typedef void (*FWCfgCallback)(void *opaque, uint8_t *data);
 
-typedef struct FWCfgState FWCfgState;
 void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len);
 void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value);
 void fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value);
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 93aae81..afe4ec7 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -61,5 +61,6 @@ typedef struct EventNotifier EventNotifier;
 typedef struct VirtIODevice VirtIODevice;
 typedef struct QEMUSGList QEMUSGList;
 typedef struct SHPCDevice SHPCDevice;
+typedef struct FWCfgState FWCfgState;
 
 #endif /* QEMU_TYPEDEFS_H */
commit a88b362c6ffbb7a802bf0ed5ef0e2447164dc989
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Tue Apr 16 02:24:08 2013 +0200

    refer to FWCfgState explicitly
    
    Currently some places use pointer-to-void even though they mean
    pointer-to-FWCfgState. Clean them up.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index c4af1cc..e6525ac 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -447,7 +447,7 @@ static int piix4_pm_initfn(PCIDevice *dev)
 
 i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
                        qemu_irq sci_irq, qemu_irq smi_irq,
-                       int kvm_enabled, void *fw_cfg)
+                       int kvm_enabled, FWCfgState *fw_cfg)
 {
     PCIDevice *dev;
     PIIX4PMState *s;
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 7507914..a711145 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -733,7 +733,7 @@ int rom_load_all(void)
     return 0;
 }
 
-void rom_set_fw(void *f)
+void rom_set_fw(FWCfgState *f)
 {
     fw_cfg = f;
 }
diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c
index d696507..09211e0 100644
--- a/hw/i386/multiboot.c
+++ b/hw/i386/multiboot.c
@@ -124,7 +124,7 @@ static void mb_add_mod(MultibootState *s,
     s->mb_mods_count++;
 }
 
-int load_multiboot(void *fw_cfg,
+int load_multiboot(FWCfgState *fw_cfg,
                    FILE *f,
                    const char *kernel_filename,
                    const char *initrd_filename,
diff --git a/hw/i386/multiboot.h b/hw/i386/multiboot.h
index 98fb1b7..60de309 100644
--- a/hw/i386/multiboot.h
+++ b/hw/i386/multiboot.h
@@ -1,7 +1,9 @@
 #ifndef QEMU_MULTIBOOT_H
 #define QEMU_MULTIBOOT_H
 
-int load_multiboot(void *fw_cfg,
+#include "hw/nvram/fw_cfg.h"
+
+int load_multiboot(FWCfgState *fw_cfg,
                    FILE *f,
                    const char *kernel_filename,
                    const char *initrd_filename,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 197d218..4844a6b 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -595,9 +595,9 @@ static unsigned int pc_apic_id_limit(unsigned int max_cpus)
     return x86_cpu_apic_id_from_index(max_cpus - 1) + 1;
 }
 
-static void *bochs_bios_init(void)
+static FWCfgState *bochs_bios_init(void)
 {
-    void *fw_cfg;
+    FWCfgState *fw_cfg;
     uint8_t *smbios_table;
     size_t smbios_len;
     uint64_t *numa_fw_cfg;
@@ -674,7 +674,7 @@ static long get_file_size(FILE *f)
     return size;
 }
 
-static void load_linux(void *fw_cfg,
+static void load_linux(FWCfgState *fw_cfg,
                        const char *kernel_filename,
                        const char *initrd_filename,
                        const char *kernel_cmdline,
@@ -1012,19 +1012,19 @@ void pc_acpi_init(const char *default_dsdt)
     }
 }
 
-void *pc_memory_init(MemoryRegion *system_memory,
-                    const char *kernel_filename,
-                    const char *kernel_cmdline,
-                    const char *initrd_filename,
-                    ram_addr_t below_4g_mem_size,
-                    ram_addr_t above_4g_mem_size,
-                    MemoryRegion *rom_memory,
-                    MemoryRegion **ram_memory)
+FWCfgState *pc_memory_init(MemoryRegion *system_memory,
+                           const char *kernel_filename,
+                           const char *kernel_cmdline,
+                           const char *initrd_filename,
+                           ram_addr_t below_4g_mem_size,
+                           ram_addr_t above_4g_mem_size,
+                           MemoryRegion *rom_memory,
+                           MemoryRegion **ram_memory)
 {
     int linux_boot, i;
     MemoryRegion *ram, *option_rom_mr;
     MemoryRegion *ram_below_4g, *ram_above_4g;
-    void *fw_cfg;
+    FWCfgState *fw_cfg;
 
     linux_boot = (kernel_filename != NULL);
 
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 530b6ab..d547548 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -89,7 +89,7 @@ static void pc_init1(MemoryRegion *system_memory,
     MemoryRegion *pci_memory;
     MemoryRegion *rom_memory;
     DeviceState *icc_bridge;
-    void *fw_cfg = NULL;
+    FWCfgState *fw_cfg = NULL;
 
     icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE);
     object_property_add_child(qdev_get_machine(), "icc-bridge",
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 6e62d17..0e86ca7 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -831,7 +831,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
     qemu_irq *cpu_halt;
     unsigned long kernel_size;
     DriveInfo *fd[MAX_FD];
-    void *fw_cfg;
+    FWCfgState *fw_cfg;
     unsigned int num_vsimms;
 
     /* init CPUs */
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 13672de..2c2a111 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -818,7 +818,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     qemu_irq *ivec_irqs, *pbm_irqs;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     DriveInfo *fd[MAX_FD];
-    void *fw_cfg;
+    FWCfgState *fw_cfg;
 
     /* init CPUs */
     cpu = cpu_devinit(cpu_model, hwdef);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 663426c..fa3bf24 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -8,6 +8,7 @@
 #include "hw/block/fdc.h"
 #include "net/net.h"
 #include "hw/i386/ioapic.h"
+#include "hw/nvram/fw_cfg.h"
 
 /* PC-style peripherals (also used by other machines).  */
 
@@ -80,14 +81,14 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
 void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge);
 void pc_hot_add_cpu(const int64_t id, Error **errp);
 void pc_acpi_init(const char *default_dsdt);
-void *pc_memory_init(MemoryRegion *system_memory,
-                    const char *kernel_filename,
-                    const char *kernel_cmdline,
-                    const char *initrd_filename,
-                    ram_addr_t below_4g_mem_size,
-                    ram_addr_t above_4g_mem_size,
-                    MemoryRegion *rom_memory,
-                    MemoryRegion **ram_memory);
+FWCfgState *pc_memory_init(MemoryRegion *system_memory,
+                           const char *kernel_filename,
+                           const char *kernel_cmdline,
+                           const char *initrd_filename,
+                           ram_addr_t below_4g_mem_size,
+                           ram_addr_t above_4g_mem_size,
+                           MemoryRegion *rom_memory,
+                           MemoryRegion **ram_memory);
 qemu_irq *pc_allocate_cpu_irq(void);
 DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus);
 void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
@@ -111,7 +112,7 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
 
 i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
                        qemu_irq sci_irq, qemu_irq smi_irq,
-                       int kvm_enabled, void *fw_cfg);
+                       int kvm_enabled, FWCfgState *fw_cfg);
 void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
 
 /* hpet.c */
diff --git a/include/hw/loader.h b/include/hw/loader.h
index 0958f06..15d4cc9 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -1,6 +1,7 @@
 #ifndef LOADER_H
 #define LOADER_H
 #include "qapi/qmp/qdict.h"
+#include "hw/nvram/fw_cfg.h"
 
 /* loader.c */
 int get_image_size(const char *filename);
@@ -30,7 +31,7 @@ int rom_add_blob(const char *name, const void *blob, size_t len,
 int rom_add_elf_program(const char *name, void *data, size_t datasize,
                         size_t romsize, hwaddr addr);
 int rom_load_all(void);
-void rom_set_fw(void *f);
+void rom_set_fw(FWCfgState *f);
 int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
 void *rom_ptr(hwaddr addr);
 void do_info_roms(Monitor *mon, const QDict *qdict);
commit edf9735e40841298874ee308fdecca2ac2aa5bdf
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Mon May 13 14:11:02 2013 +0300

    apic: rename apic specific bitopts
    
    apic has its own version of bitops, with the
    difference that it works on u32 and not long.
    Add apic_ prefix to avoid namespace clashes.
    
    We should look into reusing standard bitops long-term,
    but that's not entirely trivial.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index 756dff0..46cb097 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -40,18 +40,18 @@ static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
                                       uint8_t dest, uint8_t dest_mode);
 
 /* Find first bit starting from msb */
-static int fls_bit(uint32_t value)
+static int apic_fls_bit(uint32_t value)
 {
     return 31 - clz32(value);
 }
 
 /* Find first bit starting from lsb */
-static int ffs_bit(uint32_t value)
+static int apic_ffs_bit(uint32_t value)
 {
     return ctz32(value);
 }
 
-static inline void set_bit(uint32_t *tab, int index)
+static inline void apic_set_bit(uint32_t *tab, int index)
 {
     int i, mask;
     i = index >> 5;
@@ -59,7 +59,7 @@ static inline void set_bit(uint32_t *tab, int index)
     tab[i] |= mask;
 }
 
-static inline void reset_bit(uint32_t *tab, int index)
+static inline void apic_reset_bit(uint32_t *tab, int index)
 {
     int i, mask;
     i = index >> 5;
@@ -67,7 +67,7 @@ static inline void reset_bit(uint32_t *tab, int index)
     tab[i] &= ~mask;
 }
 
-static inline int get_bit(uint32_t *tab, int index)
+static inline int apic_get_bit(uint32_t *tab, int index)
 {
     int i, mask;
     i = index >> 5;
@@ -81,7 +81,7 @@ static int get_highest_priority_int(uint32_t *tab)
     int i;
     for (i = 7; i >= 0; i--) {
         if (tab[i] != 0) {
-            return i * 32 + fls_bit(tab[i]);
+            return i * 32 + apic_fls_bit(tab[i]);
         }
     }
     return -1;
@@ -184,7 +184,7 @@ void apic_deliver_pic_intr(DeviceState *d, int level)
         case APIC_DM_FIXED:
             if (!(lvt & APIC_LVT_LEVEL_TRIGGER))
                 break;
-            reset_bit(s->irr, lvt & 0xff);
+            apic_reset_bit(s->irr, lvt & 0xff);
             /* fall through */
         case APIC_DM_EXTINT:
             cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_HARD);
@@ -230,7 +230,7 @@ static void apic_bus_deliver(const uint32_t *deliver_bitmask,
                 d = -1;
                 for(i = 0; i < MAX_APIC_WORDS; i++) {
                     if (deliver_bitmask[i]) {
-                        d = i * 32 + ffs_bit(deliver_bitmask[i]);
+                        d = i * 32 + apic_ffs_bit(deliver_bitmask[i]);
                         break;
                     }
                 }
@@ -386,13 +386,13 @@ void apic_poll_irq(DeviceState *d)
 
 static void apic_set_irq(APICCommonState *s, int vector_num, int trigger_mode)
 {
-    apic_report_irq_delivered(!get_bit(s->irr, vector_num));
+    apic_report_irq_delivered(!apic_get_bit(s->irr, vector_num));
 
-    set_bit(s->irr, vector_num);
+    apic_set_bit(s->irr, vector_num);
     if (trigger_mode)
-        set_bit(s->tmr, vector_num);
+        apic_set_bit(s->tmr, vector_num);
     else
-        reset_bit(s->tmr, vector_num);
+        apic_reset_bit(s->tmr, vector_num);
     if (s->vapic_paddr) {
         apic_sync_vapic(s, SYNC_ISR_IRR_TO_VAPIC);
         /*
@@ -412,8 +412,8 @@ static void apic_eoi(APICCommonState *s)
     isrv = get_highest_priority_int(s->isr);
     if (isrv < 0)
         return;
-    reset_bit(s->isr, isrv);
-    if (!(s->spurious_vec & APIC_SV_DIRECTED_IO) && get_bit(s->tmr, isrv)) {
+    apic_reset_bit(s->isr, isrv);
+    if (!(s->spurious_vec & APIC_SV_DIRECTED_IO) && apic_get_bit(s->tmr, isrv)) {
         ioapic_eoi_broadcast(isrv);
     }
     apic_sync_vapic(s, SYNC_FROM_VAPIC | SYNC_TO_VAPIC);
@@ -452,7 +452,7 @@ static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
             int idx = apic_find_dest(dest);
             memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
             if (idx >= 0)
-                set_bit(deliver_bitmask, idx);
+                apic_set_bit(deliver_bitmask, idx);
         }
     } else {
         /* XXX: cluster mode */
@@ -462,11 +462,11 @@ static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
             if (apic_iter) {
                 if (apic_iter->dest_mode == 0xf) {
                     if (dest & apic_iter->log_dest)
-                        set_bit(deliver_bitmask, i);
+                        apic_set_bit(deliver_bitmask, i);
                 } else if (apic_iter->dest_mode == 0x0) {
                     if ((dest & 0xf0) == (apic_iter->log_dest & 0xf0) &&
                         (dest & apic_iter->log_dest & 0x0f)) {
-                        set_bit(deliver_bitmask, i);
+                        apic_set_bit(deliver_bitmask, i);
                     }
                 }
             } else {
@@ -509,14 +509,14 @@ static void apic_deliver(DeviceState *d, uint8_t dest, uint8_t dest_mode,
         break;
     case 1:
         memset(deliver_bitmask, 0x00, sizeof(deliver_bitmask));
-        set_bit(deliver_bitmask, s->idx);
+        apic_set_bit(deliver_bitmask, s->idx);
         break;
     case 2:
         memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
         break;
     case 3:
         memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
-        reset_bit(deliver_bitmask, s->idx);
+        apic_reset_bit(deliver_bitmask, s->idx);
         break;
     }
 
@@ -573,8 +573,8 @@ int apic_get_interrupt(DeviceState *d)
         apic_sync_vapic(s, SYNC_TO_VAPIC);
         return s->spurious_vec & 0xff;
     }
-    reset_bit(s->irr, intno);
-    set_bit(s->isr, intno);
+    apic_reset_bit(s->irr, intno);
+    apic_set_bit(s->isr, intno);
     apic_sync_vapic(s, SYNC_TO_VAPIC);
 
     /* re-inject if there is still a pending PIC interrupt */
commit ec0503b4f0a37b55fedc164185369bf5f0030f7b
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Thu May 30 12:13:06 2013 +0300

    firmware_abi: move to include/hw/nvram/
    
    firmware_abi.h with structs for OpenBIOS landed in hw/sparc/ by mistake
    - move it to hw/nvram/ alongside fw_cfg.h.  In addition to sparc it's
    included from ppc mac_nvram.c and will need to include it from prep.c in
    the future.
    
    Acked-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/nvram/mac_nvram.c b/hw/nvram/mac_nvram.c
index 5223330..d76a06c 100644
--- a/hw/nvram/mac_nvram.c
+++ b/hw/nvram/mac_nvram.c
@@ -23,7 +23,7 @@
  * THE SOFTWARE.
  */
 #include "hw/hw.h"
-#include "hw/sparc/firmware_abi.h"
+#include "hw/nvram/openbios_firmware_abi.h"
 #include "sysemu/sysemu.h"
 #include "hw/ppc/mac.h"
 
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 8840881..6e62d17 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -30,7 +30,7 @@
 #include "sysemu/sysemu.h"
 #include "net/net.h"
 #include "hw/boards.h"
-#include "hw/sparc/firmware_abi.h"
+#include "hw/nvram/openbios_firmware_abi.h"
 #include "hw/scsi/esp.h"
 #include "hw/i386/pc.h"
 #include "hw/isa/isa.h"
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 5c2bbd4..13672de 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -32,7 +32,7 @@
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
 #include "hw/boards.h"
-#include "hw/sparc/firmware_abi.h"
+#include "hw/nvram/openbios_firmware_abi.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/sysbus.h"
 #include "hw/ide.h"
diff --git a/include/hw/nvram/openbios_firmware_abi.h b/include/hw/nvram/openbios_firmware_abi.h
new file mode 100644
index 0000000..5e6e5d4
--- /dev/null
+++ b/include/hw/nvram/openbios_firmware_abi.h
@@ -0,0 +1,73 @@
+#ifndef FIRMWARE_ABI_H
+#define FIRMWARE_ABI_H
+
+/* OpenBIOS NVRAM partition */
+struct OpenBIOS_nvpart_v1 {
+    uint8_t signature;
+    uint8_t checksum;
+    uint16_t len; // BE, length divided by 16
+    char name[12];
+};
+
+#define OPENBIOS_PART_SYSTEM 0x70
+#define OPENBIOS_PART_FREE 0x7f
+
+static inline void
+OpenBIOS_finish_partition(struct OpenBIOS_nvpart_v1 *header, uint32_t size)
+{
+    unsigned int i, sum;
+    uint8_t *tmpptr;
+
+    // Length divided by 16
+    header->len = cpu_to_be16(size >> 4);
+
+    // Checksum
+    tmpptr = (uint8_t *)header;
+    sum = *tmpptr;
+    for (i = 0; i < 14; i++) {
+        sum += tmpptr[2 + i];
+        sum = (sum + ((sum & 0xff00) >> 8)) & 0xff;
+    }
+    header->checksum = sum & 0xff;
+}
+
+static inline uint32_t
+OpenBIOS_set_var(uint8_t *nvram, uint32_t addr, const char *str)
+{
+    uint32_t len;
+
+    len = strlen(str) + 1;
+    memcpy(&nvram[addr], str, len);
+
+    return addr + len;
+}
+
+/* Sun IDPROM structure at the end of NVRAM */
+/* from http://www.squirrel.com/squirrel/sun-nvram-hostid.faq.html */
+struct Sun_nvram {
+    uint8_t type;       /* always 01 */
+    uint8_t machine_id; /* first byte of host id (machine type) */
+    uint8_t macaddr[6]; /* 6 byte ethernet address (first 3 bytes 08, 00, 20) */
+    uint8_t date[4];    /* date of manufacture */
+    uint8_t hostid[3];  /* remaining 3 bytes of host id (serial number) */
+    uint8_t checksum;   /* bitwise xor of previous bytes */
+};
+
+static inline void
+Sun_init_header(struct Sun_nvram *header, const uint8_t *macaddr, int machine_id)
+{
+    uint8_t tmp, *tmpptr;
+    unsigned int i;
+
+    header->type = 1;
+    header->machine_id = machine_id & 0xff;
+    memcpy(&header->macaddr, macaddr, 6);
+    /* Calculate checksum */
+    tmp = 0;
+    tmpptr = (uint8_t *)header;
+    for (i = 0; i < 15; i++)
+        tmp ^= tmpptr[i];
+
+    header->checksum = tmp;
+}
+#endif /* FIRMWARE_ABI_H */
diff --git a/include/hw/sparc/firmware_abi.h b/include/hw/sparc/firmware_abi.h
deleted file mode 100644
index 5e6e5d4..0000000
--- a/include/hw/sparc/firmware_abi.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef FIRMWARE_ABI_H
-#define FIRMWARE_ABI_H
-
-/* OpenBIOS NVRAM partition */
-struct OpenBIOS_nvpart_v1 {
-    uint8_t signature;
-    uint8_t checksum;
-    uint16_t len; // BE, length divided by 16
-    char name[12];
-};
-
-#define OPENBIOS_PART_SYSTEM 0x70
-#define OPENBIOS_PART_FREE 0x7f
-
-static inline void
-OpenBIOS_finish_partition(struct OpenBIOS_nvpart_v1 *header, uint32_t size)
-{
-    unsigned int i, sum;
-    uint8_t *tmpptr;
-
-    // Length divided by 16
-    header->len = cpu_to_be16(size >> 4);
-
-    // Checksum
-    tmpptr = (uint8_t *)header;
-    sum = *tmpptr;
-    for (i = 0; i < 14; i++) {
-        sum += tmpptr[2 + i];
-        sum = (sum + ((sum & 0xff00) >> 8)) & 0xff;
-    }
-    header->checksum = sum & 0xff;
-}
-
-static inline uint32_t
-OpenBIOS_set_var(uint8_t *nvram, uint32_t addr, const char *str)
-{
-    uint32_t len;
-
-    len = strlen(str) + 1;
-    memcpy(&nvram[addr], str, len);
-
-    return addr + len;
-}
-
-/* Sun IDPROM structure at the end of NVRAM */
-/* from http://www.squirrel.com/squirrel/sun-nvram-hostid.faq.html */
-struct Sun_nvram {
-    uint8_t type;       /* always 01 */
-    uint8_t machine_id; /* first byte of host id (machine type) */
-    uint8_t macaddr[6]; /* 6 byte ethernet address (first 3 bytes 08, 00, 20) */
-    uint8_t date[4];    /* date of manufacture */
-    uint8_t hostid[3];  /* remaining 3 bytes of host id (serial number) */
-    uint8_t checksum;   /* bitwise xor of previous bytes */
-};
-
-static inline void
-Sun_init_header(struct Sun_nvram *header, const uint8_t *macaddr, int machine_id)
-{
-    uint8_t tmp, *tmpptr;
-    unsigned int i;
-
-    header->type = 1;
-    header->machine_id = machine_id & 0xff;
-    memcpy(&header->macaddr, macaddr, 6);
-    /* Calculate checksum */
-    tmp = 0;
-    tmpptr = (uint8_t *)header;
-    for (i = 0; i < 15; i++)
-        tmp ^= tmpptr[i];
-
-    header->checksum = tmp;
-}
-#endif /* FIRMWARE_ABI_H */
commit cbef02f819b05112cb626a955d8c86e30afe6a9f
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Thu May 30 12:09:20 2013 +0300

    dec.c - move to pci-bridge
    
    Looks like dec.c is in pci-host by mistake.
    Moving it over to pci-bridge.
    
    Acked-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pci-bridge/Makefile.objs b/hw/pci-bridge/Makefile.objs
index 5dd92d2..968b369 100644
--- a/hw/pci-bridge/Makefile.objs
+++ b/hw/pci-bridge/Makefile.objs
@@ -1,3 +1,5 @@
 common-obj-y += pci_bridge_dev.o
 common-obj-y += ioh3420.o xio3130_upstream.o xio3130_downstream.o
 common-obj-y += i82801b11.o
+# NewWorld PowerMac
+common-obj-$(CONFIG_DEC_PCI) += dec.o
diff --git a/hw/pci-bridge/dec.c b/hw/pci-bridge/dec.c
new file mode 100644
index 0000000..cff458b
--- /dev/null
+++ b/hw/pci-bridge/dec.c
@@ -0,0 +1,156 @@
+/*
+ * QEMU DEC 21154 PCI bridge
+ *
+ * Copyright (c) 2006-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * 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 "dec.h"
+#include "hw/sysbus.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_host.h"
+#include "hw/pci/pci_bridge.h"
+#include "hw/pci/pci_bus.h"
+
+/* debug DEC */
+//#define DEBUG_DEC
+
+#ifdef DEBUG_DEC
+#define DEC_DPRINTF(fmt, ...)                               \
+    do { printf("DEC: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DEC_DPRINTF(fmt, ...)
+#endif
+
+#define DEC_21154(obj) OBJECT_CHECK(DECState, (obj), TYPE_DEC_21154)
+
+typedef struct DECState {
+    PCIHostState parent_obj;
+} DECState;
+
+static int dec_map_irq(PCIDevice *pci_dev, int irq_num)
+{
+    return irq_num;
+}
+
+static int dec_pci_bridge_initfn(PCIDevice *pci_dev)
+{
+    return pci_bridge_initfn(pci_dev, TYPE_PCI_BUS);
+}
+
+static void dec_21154_pci_bridge_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = dec_pci_bridge_initfn;
+    k->exit = pci_bridge_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_DEC;
+    k->device_id = PCI_DEVICE_ID_DEC_21154;
+    k->config_write = pci_bridge_write_config;
+    k->is_bridge = 1;
+    dc->desc = "DEC 21154 PCI-PCI bridge";
+    dc->reset = pci_bridge_reset;
+    dc->vmsd = &vmstate_pci_device;
+}
+
+static const TypeInfo dec_21154_pci_bridge_info = {
+    .name          = "dec-21154-p2p-bridge",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIBridge),
+    .class_init    = dec_21154_pci_bridge_class_init,
+};
+
+PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
+{
+    PCIDevice *dev;
+    PCIBridge *br;
+
+    dev = pci_create_multifunction(parent_bus, devfn, false,
+                                   "dec-21154-p2p-bridge");
+    br = DO_UPCAST(PCIBridge, dev, dev);
+    pci_bridge_map_irq(br, "DEC 21154 PCI-PCI bridge", dec_map_irq);
+    qdev_init_nofail(&dev->qdev);
+    return pci_bridge_get_sec_bus(br);
+}
+
+static int pci_dec_21154_device_init(SysBusDevice *dev)
+{
+    PCIHostState *phb;
+
+    phb = PCI_HOST_BRIDGE(dev);
+
+    memory_region_init_io(&phb->conf_mem, &pci_host_conf_le_ops,
+                          dev, "pci-conf-idx", 0x1000);
+    memory_region_init_io(&phb->data_mem, &pci_host_data_le_ops,
+                          dev, "pci-data-idx", 0x1000);
+    sysbus_init_mmio(dev, &phb->conf_mem);
+    sysbus_init_mmio(dev, &phb->data_mem);
+    return 0;
+}
+
+static int dec_21154_pci_host_init(PCIDevice *d)
+{
+    /* PCI2PCI bridge same values as PearPC - check this */
+    return 0;
+}
+
+static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = dec_21154_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_DEC;
+    k->device_id = PCI_DEVICE_ID_DEC_21154;
+    k->revision = 0x02;
+    k->class_id = PCI_CLASS_BRIDGE_PCI;
+    k->is_bridge = 1;
+}
+
+static const TypeInfo dec_21154_pci_host_info = {
+    .name          = "dec-21154",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
+    .class_init    = dec_21154_pci_host_class_init,
+};
+
+static void pci_dec_21154_device_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = pci_dec_21154_device_init;
+}
+
+static const TypeInfo pci_dec_21154_device_info = {
+    .name          = TYPE_DEC_21154,
+    .parent        = TYPE_PCI_HOST_BRIDGE,
+    .instance_size = sizeof(DECState),
+    .class_init    = pci_dec_21154_device_class_init,
+};
+
+static void dec_register_types(void)
+{
+    type_register_static(&pci_dec_21154_device_info);
+    type_register_static(&dec_21154_pci_host_info);
+    type_register_static(&dec_21154_pci_bridge_info);
+}
+
+type_init(dec_register_types)
diff --git a/hw/pci-bridge/dec.h b/hw/pci-bridge/dec.h
new file mode 100644
index 0000000..17dc0c2
--- /dev/null
+++ b/hw/pci-bridge/dec.h
@@ -0,0 +1,10 @@
+#ifndef DEC_PCI_H
+#define DEC_PCI_H
+
+#include "qemu-common.h"
+
+#define TYPE_DEC_21154 "dec-21154-sysbus"
+
+PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn);
+
+#endif
diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs
index 909e702..bb65f9c 100644
--- a/hw/pci-host/Makefile.objs
+++ b/hw/pci-host/Makefile.objs
@@ -5,7 +5,6 @@ common-obj-$(CONFIG_PREP_PCI) += prep.o
 common-obj-$(CONFIG_GRACKLE_PCI) += grackle.o
 # NewWorld PowerMac
 common-obj-$(CONFIG_UNIN_PCI) += uninorth.o
-common-obj-$(CONFIG_DEC_PCI) += dec.o
 # PowerPC E500 boards
 common-obj-$(CONFIG_PPCE500_PCI) += ppce500.o
 
diff --git a/hw/pci-host/dec.c b/hw/pci-host/dec.c
deleted file mode 100644
index cff458b..0000000
--- a/hw/pci-host/dec.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * QEMU DEC 21154 PCI bridge
- *
- * Copyright (c) 2006-2007 Fabrice Bellard
- * Copyright (c) 2007 Jocelyn Mayer
- *
- * 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 "dec.h"
-#include "hw/sysbus.h"
-#include "hw/pci/pci.h"
-#include "hw/pci/pci_host.h"
-#include "hw/pci/pci_bridge.h"
-#include "hw/pci/pci_bus.h"
-
-/* debug DEC */
-//#define DEBUG_DEC
-
-#ifdef DEBUG_DEC
-#define DEC_DPRINTF(fmt, ...)                               \
-    do { printf("DEC: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DEC_DPRINTF(fmt, ...)
-#endif
-
-#define DEC_21154(obj) OBJECT_CHECK(DECState, (obj), TYPE_DEC_21154)
-
-typedef struct DECState {
-    PCIHostState parent_obj;
-} DECState;
-
-static int dec_map_irq(PCIDevice *pci_dev, int irq_num)
-{
-    return irq_num;
-}
-
-static int dec_pci_bridge_initfn(PCIDevice *pci_dev)
-{
-    return pci_bridge_initfn(pci_dev, TYPE_PCI_BUS);
-}
-
-static void dec_21154_pci_bridge_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = dec_pci_bridge_initfn;
-    k->exit = pci_bridge_exitfn;
-    k->vendor_id = PCI_VENDOR_ID_DEC;
-    k->device_id = PCI_DEVICE_ID_DEC_21154;
-    k->config_write = pci_bridge_write_config;
-    k->is_bridge = 1;
-    dc->desc = "DEC 21154 PCI-PCI bridge";
-    dc->reset = pci_bridge_reset;
-    dc->vmsd = &vmstate_pci_device;
-}
-
-static const TypeInfo dec_21154_pci_bridge_info = {
-    .name          = "dec-21154-p2p-bridge",
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(PCIBridge),
-    .class_init    = dec_21154_pci_bridge_class_init,
-};
-
-PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
-{
-    PCIDevice *dev;
-    PCIBridge *br;
-
-    dev = pci_create_multifunction(parent_bus, devfn, false,
-                                   "dec-21154-p2p-bridge");
-    br = DO_UPCAST(PCIBridge, dev, dev);
-    pci_bridge_map_irq(br, "DEC 21154 PCI-PCI bridge", dec_map_irq);
-    qdev_init_nofail(&dev->qdev);
-    return pci_bridge_get_sec_bus(br);
-}
-
-static int pci_dec_21154_device_init(SysBusDevice *dev)
-{
-    PCIHostState *phb;
-
-    phb = PCI_HOST_BRIDGE(dev);
-
-    memory_region_init_io(&phb->conf_mem, &pci_host_conf_le_ops,
-                          dev, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&phb->data_mem, &pci_host_data_le_ops,
-                          dev, "pci-data-idx", 0x1000);
-    sysbus_init_mmio(dev, &phb->conf_mem);
-    sysbus_init_mmio(dev, &phb->data_mem);
-    return 0;
-}
-
-static int dec_21154_pci_host_init(PCIDevice *d)
-{
-    /* PCI2PCI bridge same values as PearPC - check this */
-    return 0;
-}
-
-static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data)
-{
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = dec_21154_pci_host_init;
-    k->vendor_id = PCI_VENDOR_ID_DEC;
-    k->device_id = PCI_DEVICE_ID_DEC_21154;
-    k->revision = 0x02;
-    k->class_id = PCI_CLASS_BRIDGE_PCI;
-    k->is_bridge = 1;
-}
-
-static const TypeInfo dec_21154_pci_host_info = {
-    .name          = "dec-21154",
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(PCIDevice),
-    .class_init    = dec_21154_pci_host_class_init,
-};
-
-static void pci_dec_21154_device_class_init(ObjectClass *klass, void *data)
-{
-    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
-
-    sdc->init = pci_dec_21154_device_init;
-}
-
-static const TypeInfo pci_dec_21154_device_info = {
-    .name          = TYPE_DEC_21154,
-    .parent        = TYPE_PCI_HOST_BRIDGE,
-    .instance_size = sizeof(DECState),
-    .class_init    = pci_dec_21154_device_class_init,
-};
-
-static void dec_register_types(void)
-{
-    type_register_static(&pci_dec_21154_device_info);
-    type_register_static(&dec_21154_pci_host_info);
-    type_register_static(&dec_21154_pci_bridge_info);
-}
-
-type_init(dec_register_types)
diff --git a/hw/pci-host/dec.h b/hw/pci-host/dec.h
deleted file mode 100644
index 17dc0c2..0000000
--- a/hw/pci-host/dec.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef DEC_PCI_H
-#define DEC_PCI_H
-
-#include "qemu-common.h"
-
-#define TYPE_DEC_21154 "dec-21154-sysbus"
-
-PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn);
-
-#endif
commit a4cc73d629d43c8a4d171d043ff229a959df3ca6
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 31 14:00:27 2013 +0200

    do not check pointers after dereferencing them
    
    Two instances, both spotted by Coverity.  In one, two blocks were
    swapped.  In the other, the check is not needed anymore.
    
    Cc: qemu-stable at nongnu.org
    Cc: qemu-trivial at nongnu.org
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/monitor.c b/monitor.c
index 6ce2a4e..eefc7f0 100644
--- a/monitor.c
+++ b/monitor.c
@@ -280,7 +280,7 @@ void monitor_flush(Monitor *mon)
     buf = qstring_get_str(mon->outbuf);
     len = qstring_get_length(mon->outbuf);
 
-    if (mon && len && !mon->mux_out) {
+    if (len && !mon->mux_out) {
         rc = qemu_chr_fe_write(mon->chr, (const uint8_t *) buf, len);
         if (rc == len) {
             /* all flushed */
diff --git a/savevm.c b/savevm.c
index 31dcce9..4e0fab6 100644
--- a/savevm.c
+++ b/savevm.c
@@ -322,13 +322,13 @@ QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
     FILE *stdio_file;
     QEMUFileStdio *s;
 
-    stdio_file = popen(command, mode);
-    if (stdio_file == NULL) {
+    if (mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
+        fprintf(stderr, "qemu_popen: Argument validity check failed\n");
         return NULL;
     }
 
-    if (mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
-        fprintf(stderr, "qemu_popen: Argument validity check failed\n");
+    stdio_file = popen(command, mode);
+    if (stdio_file == NULL) {
         return NULL;
     }
 
commit cd2e64ce306910f6a627d899e6779eda33f8511c
Author: Ed Maste <emaste at freebsd.org>
Date:   Wed May 29 09:58:29 2013 -0400

    m25p80: Add Micron n25q032a
    
    Based on the datasheet at
    http://www.micron.com/~/media/Documents/Products/Data%20Sheet/NOR%20Flash/Serial%20NOR/N25Q/n25q_32mb_1_8v_65nm.pdf
    
    Signed-off-by: Ed Maste <emaste at freebsd.org>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 759c84d..a927a6b 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -123,6 +123,7 @@ static const FlashPartInfo known_devices[] = {
     { INFO("mx25l25655e", 0xc22619,      0,  64 << 10, 512, 0) },
 
     /* Micron */
+    { INFO("n25q032a",    0x20bb16,      0,  64 << 10,  64, ER_4K) },
     { INFO("n25q128a11",  0x20bb18,      0,  64 << 10, 256, 0) },
     { INFO("n25q128a13",  0x20ba18,      0,  64 << 10, 256, 0) },
     { INFO("n25q256a",    0x20ba19,      0,  64 << 10, 512, ER_4K) },
commit a585140dd546ffb606ec506b362ab9decf1ab14e
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Wed May 29 23:30:43 2013 +1000

    qemu: fix out of tree cross compile
    
    The symlink to "asm" platform linux headers is made in the build tree by
    the configure script but gcc is not told to look for them there.
    
    The patch fixes this.
    
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/configure b/configure
index 08ceb43..d5abf98 100755
--- a/configure
+++ b/configure
@@ -546,7 +546,7 @@ Haiku)
   if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
     audio_possible_drivers="$audio_possible_drivers fmod"
   fi
-  QEMU_INCLUDES="-I\$(SRC_PATH)/linux-headers $QEMU_INCLUDES"
+  QEMU_INCLUDES="-I\$(SRC_PATH)/linux-headers -I$(pwd)/linux-headers $QEMU_INCLUDES"
 ;;
 esac
 
commit a9c34e4485ef0a8a61e88f1c9f9bb87f00ba2c72
Author: Michael Tokarev <mjt at tls.msk.ru>
Date:   Tue May 28 00:46:10 2013 +0400

    slirp: cleanup leftovers from misc.h
    
    There are quite a few leftover declarations in slirp/misc.h.
    Remove them.
    
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/slirp/misc.h b/slirp/misc.h
index cc36aeb..ba8beb1 100644
--- a/slirp/misc.h
+++ b/slirp/misc.h
@@ -20,8 +20,6 @@ struct ex_list {
 char *strdup(const char *);
 #endif
 
-void do_wait(int);
-
 #define EMU_NONE 0x0
 
 /* TCP emulations */
@@ -51,21 +49,9 @@ struct emu_t {
     struct emu_t *next;
 };
 
-extern int x_port, x_server, x_display;
-
-int show_x(char *, struct socket *);
-void redir_x(uint32_t, int, int, int);
 void slirp_insque(void *, void *);
 void slirp_remque(void *);
 int add_exec(struct ex_list **, int, char *, struct in_addr, int);
-int slirp_openpty(int *, int *);
 int fork_exec(struct socket *so, const char *ex, int do_pty);
-void snooze_hup(int);
-void snooze(void);
-void relay(int);
-void add_emu(char *);
-void fd_nonblock(int);
-void fd_block(int);
-int rsh_exec(struct socket *, struct socket *, char *, char *, char *);
 
 #endif
commit 12cd30e9c026e03db908785276057c5a3d912596
Author: Lei Li <lilei at linux.vnet.ibm.com>
Date:   Mon May 27 18:33:02 2013 +0800

    migration: Remove duplicate bandwidth_limit set
    
    bandwidth_limit is double set in migrate_init(), remove one.
    
    Signed-off-by: Lei Li <lilei at linux.vnet.ibm.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/migration.c b/migration.c
index bfbc345..058f9e6 100644
--- a/migration.c
+++ b/migration.c
@@ -349,7 +349,6 @@ static MigrationState *migrate_init(const MigrationParams *params)
            sizeof(enabled_capabilities));
 
     memset(s, 0, sizeof(*s));
-    s->bandwidth_limit = bandwidth_limit;
     s->params = *params;
     memcpy(s->enabled_capabilities, enabled_capabilities,
            sizeof(enabled_capabilities));
commit 7465dfeca065882c93424b23b14b2c9f31b16aa5
Author: Lei Li <lilei at linux.vnet.ibm.com>
Date:   Mon May 27 18:33:01 2013 +0800

    docs: Fix typo and update file in migration
    
    This patch fix some typo and update the file that already
    moved.
    
    Signed-off-by: Lei Li <lilei at linux.vnet.ibm.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/docs/migration.txt b/docs/migration.txt
index 0719a55..0e0a1d4 100644
--- a/docs/migration.txt
+++ b/docs/migration.txt
@@ -41,7 +41,7 @@ All these four migration protocols use the same infrastructure to
 save/restore state devices.  This infrastructure is shared with the
 savevm/loadvm functionality.
 
-=== State Live Migration ==
+=== State Live Migration ===
 
 This is used for RAM and block devices.  It is not yet ported to vmstate.
 <Fill more information here>
@@ -83,7 +83,7 @@ pointer that is passed to all functions.
 The important functions for us are put_buffer()/get_buffer() that
 allow to write/read a buffer into the QEMUFile.
 
-=== How to save the state of one device ==
+=== How to save the state of one device ===
 
 The state of a device is saved using intermediate buffers.  There are
 some helper functions to assist this saving.
@@ -97,7 +97,7 @@ associated with a series of fields saved.  The save_state always saves
 the state as the newer version.  But load_state sometimes is able to
 load state from an older version.
 
- === Legacy way ===
+=== Legacy way ===
 
 This way is going to disappear as soon as all current users are ported to VMSTATE.
 
@@ -133,7 +133,7 @@ to interpret that definition to be able to load/save the state.  As
 the state is declared only once, it can't go out of sync in the
 save/load functions.
 
-An example (from hw/pckbd.c)
+An example (from hw/input/pckbd.c)
 
 static const VMStateDescription vmstate_kbd = {
     .name = "pckbd",
@@ -158,9 +158,9 @@ We registered this with:
 Note: talk about how vmstate <-> qdev interact, and what the instance ids mean.
 
 You can search for VMSTATE_* macros for lots of types used in QEMU in
-hw/hw.h.
+include/hw/hw.h.
 
-=== More about versions ==
+=== More about versions ===
 
 You can see that there are several version fields:
 
@@ -227,7 +227,7 @@ using a specific functionality, ....
 
 It is impossible to create a way to make migration from any version to
 any other version to work.  But we can do better than only allowing
-migration from older versions no newer ones.  For that fields that are
+migration from older versions to newer ones.  For that fields that are
 only needed sometimes, we add the idea of subsections.  A subsection
 is "like" a device vmstate, but with a particularity, it has a Boolean
 function that tells if that values are needed to be sent or not.  If
@@ -247,7 +247,8 @@ static bool ide_drive_pio_state_needed(void *opaque)
 {
     IDEState *s = opaque;
 
-    return (s->status & DRQ_STAT) != 0;
+    return ((s->status & DRQ_STAT) != 0)
+        || (s->bus->error_status & BM_STATUS_PIO_RETRY);
 }
 
 const VMStateDescription vmstate_ide_drive_pio_state = {
commit cfeda5f4b8710b6ba14131df8e287021b729b784
Author: Ed Maste <emaste at freebsd.org>
Date:   Fri May 24 16:07:00 2013 -0400

    configure: try pkg-config ncurses first
    
    When probing for ncurses, try pkg-config first rather than after
    explicit -lncurses and -lcurses.  This fixes static linking in the case
    that ncurses has additional dependencies, such as -ltinfo (as on FreeBSD).
    
    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 e17281e..08ceb43 100755
--- a/configure
+++ b/configure
@@ -2157,7 +2157,7 @@ if test "$curses" != "no" ; then
   if test "$mingw32" = "yes" ; then
     curses_list="-lpdcurses"
   else
-    curses_list="-lncurses:-lcurses:$($pkg_config --libs ncurses 2>/dev/null)"
+    curses_list="$($pkg_config --libs ncurses 2>/dev/null):-lncurses:-lcurses"
   fi
   curses_found=no
   cat > $TMPC << EOF
commit d720e9831cab9934079d36a5fe3ebcdded4cb3a7
Author: Hu Tao <hutao at cn.fujitsu.com>
Date:   Wed May 22 13:33:12 2013 +0800

    rtc: remove rtc_set_date
    
    Since it's not defined and used anywhere.
    
    Cc: qemu-trivial at nongnu.org
    Signed-off-by: Hu Tao <hutao at cn.fujitsu.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/include/hw/timer/mc146818rtc.h b/include/hw/timer/mc146818rtc.h
index 753dda6..eaf6497 100644
--- a/include/hw/timer/mc146818rtc.h
+++ b/include/hw/timer/mc146818rtc.h
@@ -9,6 +9,5 @@
 ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq);
 void rtc_set_memory(ISADevice *dev, int addr, int val);
 int rtc_get_memory(ISADevice *dev, int addr);
-void rtc_set_date(ISADevice *dev, const struct tm *tm);
 
 #endif /* !MC146818RTC_H */
commit d2d6b8576ccf0de429fb96ea6ab9669d8e916085
Author: Lei Li <lilei at linux.vnet.ibm.com>
Date:   Mon May 20 17:20:50 2013 +0800

    linux-user: Fix typo in comment
    
    Signed-off-by: Lei Li <lilei at linux.vnet.ibm.com>
    Reviewed-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 1b3c0ed..0099d64 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8236,7 +8236,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_madvise
     case TARGET_NR_madvise:
         /* A straight passthrough may not be safe because qemu sometimes
-           turns private flie-backed mappings into anonymous mappings.
+           turns private file-backed mappings into anonymous mappings.
            This will break MADV_DONTNEED.
            This is a hint, so ignoring and returning success is ok.  */
         ret = get_errno(0);
commit cbc8d595ef21635b630dd1cad54eb730ae6620a1
Author: Ed Maste <emaste at freebsd.org>
Date:   Wed May 22 09:21:39 2013 -0400

    configure: remove confusing file manipulation
    
    The configure script had some code to manipulate config-host.ld~ (i.e.,
    a common backup filename), comparing it with the newly-generated file.
    I believe the sense of the comparison was backwards.
    
    Since it seemed to serve little purpose anyway, remove it to avoid any
    confusion.
    
    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 269382a..e17281e 100755
--- a/configure
+++ b/configure
@@ -4104,17 +4104,8 @@ 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}
 
-if test -f ${config_host_ld}~ ; then
-  if cmp -s $config_host_ld ${config_host_ld}~ ; then
-    mv ${config_host_ld}~ $config_host_ld
-  else
-    rm ${config_host_ld}~
-  fi
-fi
-
 # use included Linux headers
 if test "$linux" = "yes" ; then
   mkdir -p linux-headers
commit 668fca91d48a7d55a0e3911447b078679f2ce986
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Fri May 24 10:47:33 2013 +0800

    debugcon: fix compiler warning when open DEBUG_DEBUGCON
    
    compiler warnings:
      CC    hw/char/debugcon.o
    hw/char/debugcon.c: In function ‘debugcon_ioport_write’:
    hw/char/debugcon.c:58: warning: format ‘%02x’ expects type ‘unsigned int’, but argument 3 has type ‘uint64_t’
    hw/char/debugcon.c: In function ‘debugcon_ioport_read’:
    hw/char/debugcon.c:70: warning: format ‘%04x’ expects type ‘unsigned int’, but argument 2 has type ‘hwaddr’
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c
index 52fa0ab..3b0637d 100644
--- a/hw/char/debugcon.c
+++ b/hw/char/debugcon.c
@@ -55,7 +55,7 @@ static void debugcon_ioport_write(void *opaque, hwaddr addr, uint64_t val,
     unsigned char ch = val;
 
 #ifdef DEBUG_DEBUGCON
-    printf(" [debugcon: write addr=0x%04" HWADDR_PRIx " val=0x%02x]\n", addr, val);
+    printf(" [debugcon: write addr=0x%04" HWADDR_PRIx " val=0x%02" PRIx64 "]\n", addr, val);
 #endif
 
     qemu_chr_fe_write(s->chr, &ch, 1);
@@ -67,7 +67,7 @@ static uint64_t debugcon_ioport_read(void *opaque, hwaddr addr, unsigned width)
     DebugconState *s = opaque;
 
 #ifdef DEBUG_DEBUGCON
-    printf("debugcon: read addr=0x%04x\n", addr);
+    printf("debugcon: read addr=0x%04" HWADDR_PRIx "\n", addr);
 #endif
 
     return s->readback;
commit e6ee28469fc41af5cc7d5b470ec9a1a078177fa7
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Fri May 24 10:47:32 2013 +0800

    debugcon: make debug message more readable
    
    before change:
    Bdebugcon: write addr=0x0000 val=0x6f
    odebugcon: write addr=0x0000 val=0x6f
    odebugcon: write addr=0x0000 val=0x74
    tdebugcon: write addr=0x0000 val=0x69
    idebugcon: write addr=0x0000 val=0x6e
    ndebugcon: write addr=0x0000 val=0x67
    gdebugcon: write addr=0x0000 val=0x20
     debugcon: write addr=0x0000 val=0x66
    
    after change:
    B [debugcon: write addr=0x0000 val=0x6f]
    o [debugcon: write addr=0x0000 val=0x6f]
    o [debugcon: write addr=0x0000 val=0x74]
    t [debugcon: write addr=0x0000 val=0x69]
    i [debugcon: write addr=0x0000 val=0x6e]
    n [debugcon: write addr=0x0000 val=0x67]
    g [debugcon: write addr=0x0000 val=0x20]
      [debugcon: write addr=0x0000 val=0x66]
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c
index 7e41c90..52fa0ab 100644
--- a/hw/char/debugcon.c
+++ b/hw/char/debugcon.c
@@ -55,7 +55,7 @@ static void debugcon_ioport_write(void *opaque, hwaddr addr, uint64_t val,
     unsigned char ch = val;
 
 #ifdef DEBUG_DEBUGCON
-    printf("debugcon: write addr=0x%04" HWADDR_PRIx " val=0x%02x\n", addr, val);
+    printf(" [debugcon: write addr=0x%04" HWADDR_PRIx " val=0x%02x]\n", addr, val);
 #endif
 
     qemu_chr_fe_write(s->chr, &ch, 1);
commit 8c1f72da6b11051c48a642f7de7048956383e217
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Fri May 24 10:47:31 2013 +0800

    debugcon: fix always print "addr=0x0, val=0x0" bug when use DEBUG_DEBUGCON
    
    when use DEBUG_DEBUGCON, screen spits:
    debugcon: write addr=0x0000 val=0x00
    Rdebugcon: write addr=0x0000 val=0x00
    udebugcon: write addr=0x0000 val=0x00
    ndebugcon: write addr=0x0000 val=0x00
    ndebugcon: write addr=0x0000 val=0x00
    idebugcon: write addr=0x0000 val=0x00
    ndebugcon: write addr=0x0000 val=0x00
    gdebugcon: write addr=0x0000 val=0x00
     debugcon: write addr=0x0000 val=0x00
    odebugcon: write addr=0x0000 val=0x00
    pdebugcon: write addr=0x0000 val=0x00
    tdebugcon: write addr=0x0000 val=0x00
    idebugcon: write addr=0x0000 val=0x00
    odebugcon: write addr=0x0000 val=0x00
    ndebugcon: write addr=0x0000 val=0x00
     debugcon: write addr=0x0000 val=0x00
    rdebugcon: write addr=0x0000 val=0x00
    odebugcon: write addr=0x0000 val=0x00
    mdebugcon: write addr=0x0000 val=0x00
     debugcon: write addr=0x0000 val=0x00
    adebugcon: write addr=0x0000 val=0x00
    tdebugcon: write addr=0x0000 val=0x00
     debugcon: write addr=0x0000 val=0x00
    
    Oh, that's wrong, val is not always be 0.
    this bug caused by lack of length modifier
    for specifier 'x'.
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c
index 02c9577..7e41c90 100644
--- a/hw/char/debugcon.c
+++ b/hw/char/debugcon.c
@@ -55,7 +55,7 @@ static void debugcon_ioport_write(void *opaque, hwaddr addr, uint64_t val,
     unsigned char ch = val;
 
 #ifdef DEBUG_DEBUGCON
-    printf("debugcon: write addr=0x%04x val=0x%02x\n", addr, val);
+    printf("debugcon: write addr=0x%04" HWADDR_PRIx " val=0x%02x\n", addr, val);
 #endif
 
     qemu_chr_fe_write(s->chr, &ch, 1);
commit 6681fca3fc5f44eff68a0c0b2e62694f8579ce28
Author: Stefan Weil <sw at weilnetz.de>
Date:   Fri May 24 12:19:25 2013 +0200

    Remove unnecessary break statements
    
    Fix these warnings from cppcheck:
    
    hw/display/cirrus_vga.c:2603:
    hw/sd/sd.c:348:
    hw/timer/exynos4210_mct.c:1033:
    target-arm/translate.c:9886:
    target-s390x/mem_helper.c:518:
    target-unicore32/translate.c:1936:
     style: Consecutive return, break, continue, goto or throw statements are unnecessary.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
index 64bfe2b..a5dbc39 100644
--- a/hw/display/cirrus_vga.c
+++ b/hw/display/cirrus_vga.c
@@ -2600,7 +2600,6 @@ static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val,
 #endif
 	cirrus_vga_write_sr(c, val);
         break;
-	break;
     case 0x3c6:
 	cirrus_write_hidden_dac(c, val);
 	break;
diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c
index 87ce75b..38dcc1a 100644
--- a/hw/timer/exynos4210_mct.c
+++ b/hw/timer/exynos4210_mct.c
@@ -1030,7 +1030,6 @@ static uint64_t exynos4210_mct_read(void *opaque, hwaddr offset,
     case G_INT_ENB:
         value = s->g_timer.reg.int_enb;
         break;
-        break;
     case G_WSTAT:
         value = s->g_timer.reg.wstat;
         break;
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 71135bd..b3f26d6 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -9916,7 +9916,6 @@ static inline void gen_intermediate_code_internal(CPUARMState *env,
                        invalidate this TB.  */
                     dc->pc += 2;
                     goto done_generating;
-                    break;
                 }
             }
         }
diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
index 02bc432..1422ae9 100644
--- a/target-s390x/mem_helper.c
+++ b/target-s390x/mem_helper.c
@@ -515,7 +515,6 @@ uint32_t HELPER(ex)(CPUS390XState *env, uint32_t cc, uint64_t v1,
             break;
         default:
             goto abort;
-            break;
         }
     } else if ((insn & 0xff00) == 0x0a00) {
         /* supervisor call */
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index 151e35e..3dc7856 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -1933,7 +1933,6 @@ static inline void gen_intermediate_code_internal(CPUUniCore32State *env,
                        invalidate this TB.  */
                     dc->pc += 2; /* FIXME */
                     goto done_generating;
-                    break;
                 }
             }
         }
commit a3605bf696a30e793d375b6c4ff1fd88ec546010
Author: Michael Tokarev <mjt at tls.msk.ru>
Date:   Sat May 25 13:17:21 2013 +0400

    don't run pkg-config for features explicitly disabled
    
    We test pkg-config for curses and curl even if those are explicitly
    disabled.  Move these tests inside `if "$feature" != "no"' sections.
    
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/configure b/configure
index 918dc36..269382a 100755
--- a/configure
+++ b/configure
@@ -2153,13 +2153,12 @@ fi
 
 ##########################################
 # curses probe
-if test "$mingw32" = "yes" ; then
+if test "$curses" != "no" ; then
+  if test "$mingw32" = "yes" ; then
     curses_list="-lpdcurses"
-else
+  else
     curses_list="-lncurses:-lcurses:$($pkg_config --libs ncurses 2>/dev/null)"
-fi
-
-if test "$curses" != "no" ; then
+  fi
   curses_found=no
   cat > $TMPC << EOF
 #include <curses.h>
@@ -2191,14 +2190,12 @@ fi
 
 ##########################################
 # curl probe
-
-if $pkg_config libcurl --modversion >/dev/null 2>&1; then
-  curlconfig="$pkg_config libcurl"
-else
-  curlconfig=curl-config
-fi
-
 if test "$curl" != "no" ; then
+  if $pkg_config libcurl --modversion >/dev/null 2>&1; then
+    curlconfig="$pkg_config libcurl"
+  else
+    curlconfig=curl-config
+  fi
   cat > $TMPC << EOF
 #include <curl/curl.h>
 int main(void) { curl_easy_init(); curl_multi_setopt(0, 0, 0); return 0; }
commit dec3fc9657e0682637de4d5a29d947284d01985c
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed May 29 12:30:51 2013 -0700

    target-i386: Fix aflag logic for CODE64 and the 0x67 prefix
    
    The code reorganization in commit 4a6fd938 broke handling of PREFIX_ADR.
    While fixing this, tidy and comment the code so that it's more obvious
    what's going on in setting both aflag and dflag.
    
    The TARGET_X86_64 ifdef can be eliminated because CODE64 expands to the
    constant zero when TARGET_X86_64 is undefined.
    
    Cc: Paolo Bonzini <pbonzini at redhat.com>
    Reported-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 1369855851-21400-1-git-send-email-rth at twiddle.net
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/target-i386/translate.c b/target-i386/translate.c
index 0aeccdb..14b0298 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -4677,8 +4677,6 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
     }
     s->pc = pc_start;
     prefixes = 0;
-    aflag = s->code32;
-    dflag = s->code32;
     s->override = -1;
     rex_w = -1;
     rex_r = 0;
@@ -4801,23 +4799,25 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
     }
 
     /* Post-process prefixes.  */
-    if (prefixes & PREFIX_DATA) {
-        dflag ^= 1;
-    }
-    if (prefixes & PREFIX_ADR) {
-        aflag ^= 1;
-    }
-#ifdef TARGET_X86_64
     if (CODE64(s)) {
-        if (rex_w == 1) {
-            /* 0x66 is ignored if rex.w is set */
-            dflag = 2;
+        /* In 64-bit mode, the default data size is 32-bit.  Select 64-bit
+           data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
+           over 0x66 if both are present.  */
+        dflag = (rex_w > 0 ? 2 : prefixes & PREFIX_DATA ? 0 : 1);
+        /* In 64-bit mode, 0x67 selects 32-bit addressing.  */
+        aflag = (prefixes & PREFIX_ADR ? 1 : 2);
+    } else {
+        /* In 16/32-bit mode, 0x66 selects the opposite data size.  */
+        dflag = s->code32;
+        if (prefixes & PREFIX_DATA) {
+            dflag ^= 1;
         }
-        if (!(prefixes & PREFIX_ADR)) {
-            aflag = 2;
+        /* In 16/32-bit mode, 0x67 selects the opposite addressing.  */
+        aflag = s->code32;
+        if (prefixes & PREFIX_ADR) {
+            aflag ^= 1;
         }
     }
-#endif
 
     s->prefix = prefixes;
     s->aflag = aflag;
commit 39c93c67c5995bd8db7a3fa3b95dcd4e6bc881a7
Author: Christian Borntraeger <borntraeger at de.ibm.com>
Date:   Thu May 23 13:51:41 2013 +0200

    s390/ipl: Fix spurious errors in virtio
    
    With the ccw ipl code sometimes an error message like
    "virtio: trying to map MMIO memory" or
    "Guest moved used index from %u to %u" appeared. Turns out
    that the ccw bios did not zero out the vring, which might
    cause stale values in avail->idx and friends, especially
    on reboot.
    
    Lets zero out the relevant fields. To activate the patch we
    need to rebuild s390-ccw.img as well.
    
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>
    Message-id: 1369309901-418-1-git-send-email-borntraeger at de.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
index 5b9e1dc..f438af1 100644
--- a/pc-bios/s390-ccw/virtio.c
+++ b/pc-bios/s390-ccw/virtio.c
@@ -114,8 +114,13 @@ static void vring_init(struct vring *vr, unsigned int num, void *p,
     vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + align-1)
                 & ~(align - 1));
 
+    /* Zero out all relevant field */
+    vr->avail->flags = 0;
+    vr->avail->idx = 0;
+
     /* We're running with interrupts off anyways, so don't bother */
     vr->used->flags = VRING_USED_F_NO_NOTIFY;
+    vr->used->idx = 0;
 
     debug_print_addr("init vr", vr);
 }
commit 0a1f348c429a6af0ba6448e5b3ae08dbc8e28696
Merge: 6c8df7a f2e3978
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri May 31 11:33:02 2013 -0500

    Merge remote-tracking branch 'mdroth/qga-pull-2013-05-30' into staging
    
    # By Laszlo Ersek
    # Via Michael Roth
    * mdroth/qga-pull-2013-05-30:
      Makefile: create ".../var/run" when installing the POSIX guest agent
      qga: save state directory in ga_install_service()
      qga: remove undefined behavior in ga_install_service()
      qga: create state directory on win32
      configure: don't save any fixed local_statedir for win32
      qga: determine default state dir and pidfile dynamically
      osdep: add qemu_get_local_state_pathname()
    
    Message-id: 1369940341-9043-1-git-send-email-mdroth at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 6c8df7a33ade90c8c96b01655520c7e9b69b46c0
Merge: cdf79b6 bff6347
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri May 31 11:32:32 2013 -0500

    Merge remote-tracking branch 'luiz/queue/qmp' into staging
    
    # By Luiz Capitulino (1) and others
    # Via Luiz Capitulino
    * luiz/queue/qmp:
      target-i386: Fix mask of pte index in memory mapping
      target-i386: fix abort on bad PML4E/PDPTE/PDE/PTE addresses
      qapi: pad GenericList value fields to 64 bits
    
    Message-id: 1370009905-4255-1-git-send-email-lcapitulino at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit cdf79b6454abe13aec89d4be7cf59b3e841a7faf
Merge: fd21faa fd8aaa7
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri May 31 11:32:25 2013 -0500

    Merge remote-tracking branch 'bonzini/iommu-for-anthony' into staging
    
    # By Paolo Bonzini
    # Via Paolo Bonzini
    * bonzini/iommu-for-anthony: (22 commits)
      memory: add return value to address_space_rw/read/write
      memory: propagate errors on I/O dispatch
      exec: just use io_mem_read/io_mem_write for 8-byte I/O accesses
      memory: correctly handle endian-swapped 64-bit accesses
      memory: split accesses even when the old MMIO callbacks are used
      memory: add big endian support to access_with_adjusted_size
      memory: accept mismatching sizes in memory_region_access_valid
      memory: add address_space_access_valid
      exec: implement .valid.accepts for subpages
      memory: export memory_region_access_valid to exec.c
      exec: introduce memory_access_size
      exec: introduce memory_access_is_direct
      exec: expect mr->ops to be initialized for ROM
      memory: assign MemoryRegionOps to all regions
      memory: move unassigned_mem_ops to memory.c
      memory: add address_space_translate
      memory: dispatch unassigned accesses based on .valid.accepts
      exec: do not use error_mem_read
      exec: make io_mem_unassigned private
      cputlb: simplify tlb_set_page
      ...
    
    Message-id: 1369947836-2638-1-git-send-email-pbonzini at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit bff63471ced94e3a6de76b1a7375a875178d6cdc
Author: Qiao Nuohan <qiaonuohan at cn.fujitsu.com>
Date:   Thu May 30 17:07:54 2013 +0200

    target-i386: Fix mask of pte index in memory mapping
    
    Function walk_pte() needs pte index to calculate virtual address.
    However, pte index of PAE paging or IA-32e paging is 9 bit, so the mask
    should be 0x1ff.
    
    Signed-off-by: Qiao Nuohan <qiaonuohan at cn.fujitsu.com>
    Reviewed-by: Jesse Larrew <jlarrew at linux.vnet.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/target-i386/arch_memory_mapping.c b/target-i386/arch_memory_mapping.c
index 24884bd..5096fbd 100644
--- a/target-i386/arch_memory_mapping.c
+++ b/target-i386/arch_memory_mapping.c
@@ -38,7 +38,7 @@ static void walk_pte(MemoryMappingList *list, hwaddr pte_start_addr,
             continue;
         }
 
-        start_vaddr = start_line_addr | ((i & 0x1fff) << 12);
+        start_vaddr = start_line_addr | ((i & 0x1ff) << 12);
         memory_mapping_list_add_merge_sorted(list, start_paddr,
                                              start_vaddr, 1 << 12);
     }
commit fbc2ed9518efcdcdcbf0adb9539c17a65addd20a
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Tue May 28 14:19:22 2013 -0400

    target-i386: fix abort on bad PML4E/PDPTE/PDE/PTE addresses
    
    The code used to walk IA-32e page-tables, and possibly PAE page-tables,
    uses the bit mask ~0xfff to get the next PML4E/PDPTE/PDE/PTE address.
    
    However, as we use a uint64_t to store the resulting address, that mask
    gets expanded to 0xfffffffffffff000 which not only ends up selecting
    reserved bits but also selects the XD bit (execute-disable) which
    happens to be enabled by Windows 8, causing qemu_get_ram_ptr() to abort.
    
    This commit fixes that problem by replacing ~0xfff by a correct mask
    that only selects the address bit range (ie. bits 51:12).
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>

diff --git a/target-i386/arch_memory_mapping.c b/target-i386/arch_memory_mapping.c
index 844893f..24884bd 100644
--- a/target-i386/arch_memory_mapping.c
+++ b/target-i386/arch_memory_mapping.c
@@ -75,6 +75,8 @@ static void walk_pte2(MemoryMappingList *list,
 }
 
 /* PAE Paging or IA-32e Paging */
+#define PLM4_ADDR_MASK 0xffffffffff000 /* selects bits 51:12 */
+
 static void walk_pde(MemoryMappingList *list, hwaddr pde_start_addr,
                      int32_t a20_mask, target_ulong start_line_addr)
 {
@@ -105,7 +107,7 @@ static void walk_pde(MemoryMappingList *list, hwaddr pde_start_addr,
             continue;
         }
 
-        pte_start_addr = (pde & ~0xfff) & a20_mask;
+        pte_start_addr = (pde & PLM4_ADDR_MASK) & a20_mask;
         walk_pte(list, pte_start_addr, a20_mask, line_addr);
     }
 }
@@ -208,7 +210,7 @@ static void walk_pdpe(MemoryMappingList *list,
             continue;
         }
 
-        pde_start_addr = (pdpe & ~0xfff) & a20_mask;
+        pde_start_addr = (pdpe & PLM4_ADDR_MASK) & a20_mask;
         walk_pde(list, pde_start_addr, a20_mask, line_addr);
     }
 }
@@ -231,7 +233,7 @@ static void walk_pml4e(MemoryMappingList *list,
         }
 
         line_addr = ((i & 0x1ffULL) << 39) | (0xffffULL << 48);
-        pdpe_start_addr = (pml4e & ~0xfff) & a20_mask;
+        pdpe_start_addr = (pml4e & PLM4_ADDR_MASK) & a20_mask;
         walk_pdpe(list, pdpe_start_addr, a20_mask, line_addr);
     }
 }
@@ -249,7 +251,7 @@ int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env)
         if (env->hflags & HF_LMA_MASK) {
             hwaddr pml4e_addr;
 
-            pml4e_addr = (env->cr[3] & ~0xfff) & env->a20_mask;
+            pml4e_addr = (env->cr[3] & PLM4_ADDR_MASK) & env->a20_mask;
             walk_pml4e(list, pml4e_addr, env->a20_mask);
         } else
 #endif
commit fd21faadb12669e24eaf0a277de61c24fcde4cac
Author: Paul Moore <pmoore at redhat.com>
Date:   Wed May 29 16:30:01 2013 -0400

    seccomp: add the asynchronous I/O syscalls to the whitelist
    
    In order to enable the asynchronous I/O functionality when using the
    seccomp sandbox we need to add the associated syscalls to the
    whitelist.
    
    Signed-off-by: Paul Moore <pmoore at redhat.com>
    Reviewed-by: Corey Bryant <coreyb at linux.vnet.ibm.com>
    Message-id: 20130529203001.20939.83322.stgit at localhost
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/qemu-seccomp.c b/qemu-seccomp.c
index 031da1d..ca123bf 100644
--- a/qemu-seccomp.c
+++ b/qemu-seccomp.c
@@ -87,6 +87,7 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = {
     { SCMP_SYS(stat), 245 },
     { SCMP_SYS(uname), 245 },
     { SCMP_SYS(eventfd2), 245 },
+    { SCMP_SYS(io_getevents), 245 },
     { SCMP_SYS(dup), 245 },
     { SCMP_SYS(dup2), 245 },
     { SCMP_SYS(dup3), 245 },
@@ -229,7 +230,9 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = {
     { SCMP_SYS(sendmmsg), 241 },
     { SCMP_SYS(recvmmsg), 241 },
     { SCMP_SYS(prlimit64), 241 },
-    { SCMP_SYS(waitid), 241 }
+    { SCMP_SYS(waitid), 241 },
+    { SCMP_SYS(io_setup), 241 },
+    { SCMP_SYS(io_destroy), 241 }
 };
 
 int seccomp_start(void)
commit 87f25c12bfeaaa0c41fb857713bbc7e8a9b757dc
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu May 30 13:20:40 2013 +0200

    gdbstub: do not restart crashed guest
    
    If a guest has crashed with an internal error or similar, detaching
    gdb (or any other debugger action) should not restart it.
    
    Cc: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Message-id: 1369912840-18577-1-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 e80e1d3..90e54cb 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -371,7 +371,9 @@ static inline void gdb_continue(GDBState *s)
 #ifdef CONFIG_USER_ONLY
     s->running_state = 1;
 #else
-    vm_start();
+    if (runstate_check(RUN_STATE_DEBUG)) {
+        vm_start();
+    }
 #endif
 }
 
commit bbfa18fca4e44ff9c23d36b50d8a998af9c9e9fc
Author: Amos Kong <akong at redhat.com>
Date:   Wed May 29 15:56:42 2013 +0800

    qdev: fix get_fw_dev_path to support to add nothing to fw_dev_path
    
    Recent virtio refactoring in QEMU made virtio-bus become the parent bus
    of scsi-bus, and virtio-bus doesn't have get_fw_dev_path implementation,
    typename will be added to fw_dev_path by default, the new fw_dev_path
    could not be identified by seabios. It causes that bootindex parameter
    of scsi device doesn't work.
    
    This patch implements get_fw_dev_path() in BusClass, it will be called
    if bus doesn't implement the method, tyename will be added to
    fw_dev_path. If the implemented method returns NULL, nothing will be
    added to fw_dev_path.
    
    It also implements virtio_bus_get_fw_dev_path() to return NULL. Then
    QEMU will still pass original style of fw_dev_path to seabios.
    
    Signed-off-by: Amos Kong <akong at redhat.com>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Message-id: 1369814202-10346-1-git-send-email-akong at redhat.com
    --
    v2: only add nothing to fw_dev_path when get_fw_dev_path() is
        implemented and returns NULL. then it will not effect other devices
        don't have get_fw_dev_path() implementation.
    v3: implement default get_fw_dev_path() in BusClass
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 6985ad8..9190a7e 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -515,7 +515,7 @@ static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
             l += snprintf(p + l, size - l, "%s", d);
             g_free(d);
         } else {
-            l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
+            return l;
         }
     }
     l += snprintf(p + l , size - l, "/");
@@ -867,9 +867,17 @@ static void qbus_initfn(Object *obj)
     QTAILQ_INIT(&bus->children);
 }
 
+static char *default_bus_get_fw_dev_path(DeviceState *dev)
+{
+    return g_strdup(object_get_typename(OBJECT(dev)));
+}
+
 static void bus_class_init(ObjectClass *class, void *data)
 {
+    BusClass *bc = BUS_CLASS(class);
+
     class->unparent = bus_unparent;
+    bc->get_fw_dev_path = default_bus_get_fw_dev_path;
 }
 
 static void qbus_finalize(Object *obj)
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index ea2e11a..6849a01 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -161,10 +161,16 @@ static char *virtio_bus_get_dev_path(DeviceState *dev)
     return qdev_get_dev_path(proxy);
 }
 
+static char *virtio_bus_get_fw_dev_path(DeviceState *dev)
+{
+    return NULL;
+}
+
 static void virtio_bus_class_init(ObjectClass *klass, void *data)
 {
     BusClass *bus_class = BUS_CLASS(klass);
     bus_class->get_dev_path = virtio_bus_get_dev_path;
+    bus_class->get_fw_dev_path = virtio_bus_get_fw_dev_path;
 }
 
 static const TypeInfo virtio_bus_info = {
commit f2e3978b5a72870b061d29948075dccc0a72db8e
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Sat May 18 07:13:14 2013 +0200

    Makefile: create ".../var/run" when installing the POSIX guest agent
    
    Otherwise the default local state directory of POSIX qga won't exist after
    installation with a non-standard ${prefix} or DESTDIR.
    
    For now qga is the only user of ".../var" (= $qemu_localstatedir) too, so
    don't create that directory either unless we're installing the agent.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/Makefile b/Makefile
index 9695c9d..a96736b 100644
--- a/Makefile
+++ b/Makefile
@@ -318,13 +318,21 @@ endif
 install-datadir:
 	$(INSTALL_DIR) "$(DESTDIR)$(qemu_datadir)"
 
+install-localstatedir:
+ifdef CONFIG_POSIX
+ifneq (,$(findstring qemu-ga,$(TOOLS)))
+	$(INSTALL_DIR) "$(DESTDIR)$(qemu_localstatedir)"/run
+endif
+endif
+
 install-confdir:
 	$(INSTALL_DIR) "$(DESTDIR)$(qemu_confdir)"
 
 install-sysconfig: install-datadir install-confdir
 	$(INSTALL_DATA) $(SRC_PATH)/sysconfigs/target/target-x86_64.conf "$(DESTDIR)$(qemu_confdir)"
 
-install: all $(if $(BUILD_DOCS),install-doc) install-sysconfig install-datadir
+install: all $(if $(BUILD_DOCS),install-doc) install-sysconfig \
+install-datadir install-localstatedir
 	$(INSTALL_DIR) "$(DESTDIR)$(bindir)"
 ifneq ($(TOOLS),)
 	$(INSTALL_PROG) $(STRIP_OPT) $(TOOLS) "$(DESTDIR)$(bindir)"
commit a839ee77c786a8200c76ca92f697eebf6bcc9aa3
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Sat May 18 06:31:53 2013 +0200

    qga: save state directory in ga_install_service()
    
    If the user selects a non-default state directory at service installation
    time, we should remember it in the registered service.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/qga/main.c b/qga/main.c
index 5f2d141..0e04e73 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -1022,7 +1022,16 @@ int main(int argc, char **argv)
         case 's':
             service = optarg;
             if (strcmp(service, "install") == 0) {
-                return ga_install_service(path, log_filepath);
+                const char *fixed_state_dir;
+
+                /* If the user passed the "-t" option, we save that state dir
+                 * in the service. Otherwise we let the service fetch the state
+                 * dir from the environment when it starts.
+                 */
+                fixed_state_dir = (state_dir == dfl_pathnames.state_dir) ?
+                                  NULL :
+                                  state_dir;
+                return ga_install_service(path, log_filepath, fixed_state_dir);
             } else if (strcmp(service, "uninstall") == 0) {
                 return ga_uninstall_service();
             } else {
diff --git a/qga/service-win32.c b/qga/service-win32.c
index 8a5de8a..02926ab 100644
--- a/qga/service-win32.c
+++ b/qga/service-win32.c
@@ -35,7 +35,8 @@ static int printf_win_error(const char *text)
     return n;
 }
 
-int ga_install_service(const char *path, const char *logfile)
+int ga_install_service(const char *path, const char *logfile,
+                       const char *state_dir)
 {
     SC_HANDLE manager;
     SC_HANDLE service;
@@ -56,6 +57,9 @@ int ga_install_service(const char *path, const char *logfile)
     if (logfile) {
         g_string_append_printf(cmdline, " -l %s -v", logfile);
     }
+    if (state_dir) {
+        g_string_append_printf(cmdline, " -t %s", state_dir);
+    }
 
     g_debug("service's cmdline: %s", cmdline->str);
 
diff --git a/qga/service-win32.h b/qga/service-win32.h
index 99dfc53..3b9e870 100644
--- a/qga/service-win32.h
+++ b/qga/service-win32.h
@@ -24,7 +24,8 @@ typedef struct GAService {
     SERVICE_STATUS_HANDLE status_handle;
 } GAService;
 
-int ga_install_service(const char *path, const char *logfile);
+int ga_install_service(const char *path, const char *logfile,
+                       const char *state_dir);
 int ga_uninstall_service(void);
 
 #endif
commit a880845f3d92e508e43fcc38f0631b91c203e5d5
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Sat May 18 06:31:52 2013 +0200

    qga: remove undefined behavior in ga_install_service()
    
    We shouldn't snprintf() from a buffer to the same buffer.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/qga/service-win32.c b/qga/service-win32.c
index 843398a..8a5de8a 100644
--- a/qga/service-win32.c
+++ b/qga/service-win32.c
@@ -39,34 +39,36 @@ int ga_install_service(const char *path, const char *logfile)
 {
     SC_HANDLE manager;
     SC_HANDLE service;
-    TCHAR cmdline[MAX_PATH];
+    TCHAR module_fname[MAX_PATH];
+    GString *cmdline;
 
-    if (GetModuleFileName(NULL, cmdline, MAX_PATH) == 0) {
+    if (GetModuleFileName(NULL, module_fname, MAX_PATH) == 0) {
         printf_win_error("No full path to service's executable");
         return EXIT_FAILURE;
     }
 
-    _snprintf(cmdline, MAX_PATH - strlen(cmdline), "%s -d", cmdline);
+    cmdline = g_string_new(module_fname);
+    g_string_append(cmdline, " -d");
 
     if (path) {
-        _snprintf(cmdline, MAX_PATH - strlen(cmdline), "%s -p %s", cmdline, path);
+        g_string_append_printf(cmdline, " -p %s", path);
     }
     if (logfile) {
-        _snprintf(cmdline, MAX_PATH - strlen(cmdline), "%s -l %s -v",
-            cmdline, logfile);
+        g_string_append_printf(cmdline, " -l %s -v", logfile);
     }
 
-    g_debug("service's cmdline: %s", cmdline);
+    g_debug("service's cmdline: %s", cmdline->str);
 
     manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
     if (manager == NULL) {
         printf_win_error("No handle to service control manager");
+        g_string_free(cmdline, TRUE);
         return EXIT_FAILURE;
     }
 
     service = CreateService(manager, QGA_SERVICE_NAME, QGA_SERVICE_DISPLAY_NAME,
         SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START,
-        SERVICE_ERROR_NORMAL, cmdline, NULL, NULL, NULL, NULL, NULL);
+        SERVICE_ERROR_NORMAL, cmdline->str, NULL, NULL, NULL, NULL, NULL);
 
     if (service) {
         SERVICE_DESCRIPTION desc = { (char *)QGA_SERVICE_DESCRIPTION };
@@ -80,6 +82,7 @@ int ga_install_service(const char *path, const char *logfile)
     CloseServiceHandle(service);
     CloseServiceHandle(manager);
 
+    g_string_free(cmdline, TRUE);
     return (service == NULL);
 }
 
commit bf12c1fa8c78e3c667f2fe2ecc656f4f3cfb914e
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Sat May 18 06:31:51 2013 +0200

    qga: create state directory on win32
    
    On Win32 the local state directory is application specific and users might
    expect qemu-ga to create it automatically.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/qga/main.c b/qga/main.c
index f5f033d..5f2d141 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -1041,6 +1041,20 @@ int main(int argc, char **argv)
         }
     }
 
+#ifdef _WIN32
+    /* On win32 the state directory is application specific (be it the default
+     * or a user override). We got past the command line parsing; let's create
+     * the directory (with any intermediate directories). If we run into an
+     * error later on, we won't try to clean up the directory, it is considered
+     * persistent.
+     */
+    if (g_mkdir_with_parents(state_dir, S_IRWXU) == -1) {
+        g_critical("unable to create (an ancestor of) the state directory"
+                   " '%s': %s", state_dir, strerror(errno));
+        return EXIT_FAILURE;
+    }
+#endif
+
     s = g_malloc0(sizeof(GAState));
     s->log_level = log_level;
     s->log_file = stderr;
commit 5a699bbbf300902141d2458682d05cd310d7a07f
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Sat May 18 06:31:50 2013 +0200

    configure: don't save any fixed local_statedir for win32
    
    ... because now we can get the dynamic value with
    qemu_get_local_state_pathname().
    
    The only user of the fixed value was the guest agent, which we've moved to
    qemu_get_local_state_pathname() in the previous patch.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/configure b/configure
index eb74510..918dc36 100755
--- a/configure
+++ b/configure
@@ -587,7 +587,7 @@ EOF
   qemu_docdir="\${prefix}"
   bindir="\${prefix}"
   sysconfdir="\${prefix}"
-  local_statedir="\${prefix}"
+  local_statedir=
   confsuffix=""
   libs_qga="-lws2_32 -lwinmm -lpowrprof $libs_qga"
 fi
@@ -1082,7 +1082,7 @@ echo "  --docdir=PATH            install documentation in PATH$confsuffix"
 echo "  --bindir=PATH            install binaries in PATH"
 echo "  --libdir=PATH            install libraries in PATH"
 echo "  --sysconfdir=PATH        install config in PATH$confsuffix"
-echo "  --localstatedir=PATH     install local state in PATH"
+echo "  --localstatedir=PATH     install local state in PATH (set at runtime on win32)"
 echo "  --with-confsuffix=SUFFIX suffix for QEMU data inside datadir and sysconfdir [$confsuffix]"
 echo "  --enable-debug-tcg       enable TCG debugging"
 echo "  --disable-debug-tcg      disable TCG debugging (default)"
@@ -3487,10 +3487,12 @@ echo "library directory `eval echo $libdir`"
 echo "libexec directory `eval echo $libexecdir`"
 echo "include directory `eval echo $includedir`"
 echo "config directory  `eval echo $sysconfdir`"
-echo "local state directory   `eval echo $local_statedir`"
 if test "$mingw32" = "no" ; then
+echo "local state directory   `eval echo $local_statedir`"
 echo "Manual directory  `eval echo $mandir`"
 echo "ELF interp prefix $interp_prefix"
+else
+echo "local state directory   queried at runtime"
 fi
 echo "Source path       $source_path"
 echo "C compiler        $cc"
@@ -3611,7 +3613,9 @@ echo "sysconfdir=$sysconfdir" >> $config_host_mak
 echo "qemu_confdir=$qemu_confdir" >> $config_host_mak
 echo "qemu_datadir=$qemu_datadir" >> $config_host_mak
 echo "qemu_docdir=$qemu_docdir" >> $config_host_mak
-echo "qemu_localstatedir=$local_statedir" >> $config_host_mak
+if test "$mingw32" = "no" ; then
+  echo "qemu_localstatedir=$local_statedir" >> $config_host_mak
+fi
 echo "qemu_helperdir=$libexecdir" >> $config_host_mak
 echo "extra_cflags=$EXTRA_CFLAGS" >> $config_host_mak
 echo "extra_ldflags=$EXTRA_LDFLAGS" >> $config_host_mak
commit c394ecb7bf55b7234f852b9c8518aefb5d0943fa
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Sat May 18 06:31:49 2013 +0200

    qga: determine default state dir and pidfile dynamically
    
    No effective change on POSIX, but on Win32 the defaults come from the
    environment / session.
    
    Since commit 39097daf ("qemu-ga: use key-value store to avoid recycling fd
    handles after restart") we've relied on the state directory for the fd
    handles' key-value store. Even though we don't support the guest-file-*
    commands on win32 yet, the key-value store is written, and it's the first
    use of the state directory on win32. We should have a sensible default for
    its location.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/qga/main.c b/qga/main.c
index 44a2836..f5f033d 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -45,16 +45,21 @@
 
 #ifndef _WIN32
 #define QGA_VIRTIO_PATH_DEFAULT "/dev/virtio-ports/org.qemu.guest_agent.0"
+#define QGA_STATE_RELATIVE_DIR  "run"
 #else
 #define QGA_VIRTIO_PATH_DEFAULT "\\\\.\\Global\\org.qemu.guest_agent.0"
+#define QGA_STATE_RELATIVE_DIR  "qemu-ga"
 #endif
-#define QGA_STATEDIR_DEFAULT CONFIG_QEMU_LOCALSTATEDIR "/run"
-#define QGA_PIDFILE_DEFAULT QGA_STATEDIR_DEFAULT "/qemu-ga.pid"
 #ifdef CONFIG_FSFREEZE
 #define QGA_FSFREEZE_HOOK_DEFAULT CONFIG_QEMU_CONFDIR "/fsfreeze-hook"
 #endif
 #define QGA_SENTINEL_BYTE 0xFF
 
+static struct {
+    const char *state_dir;
+    const char *pidfile;
+} dfl_pathnames;
+
 typedef struct GAPersistentState {
 #define QGA_PSTATE_DEFAULT_FD_COUNTER 1000
     int64_t fd_counter;
@@ -106,6 +111,17 @@ DWORD WINAPI service_ctrl_handler(DWORD ctrl, DWORD type, LPVOID data,
 VOID WINAPI service_main(DWORD argc, TCHAR *argv[]);
 #endif
 
+static void
+init_dfl_pathnames(void)
+{
+    g_assert(dfl_pathnames.state_dir == NULL);
+    g_assert(dfl_pathnames.pidfile == NULL);
+    dfl_pathnames.state_dir = qemu_get_local_state_pathname(
+      QGA_STATE_RELATIVE_DIR);
+    dfl_pathnames.pidfile   = qemu_get_local_state_pathname(
+      QGA_STATE_RELATIVE_DIR G_DIR_SEPARATOR_S "qemu-ga.pid");
+}
+
 static void quit_handler(int sig)
 {
     /* if we're frozen, don't exit unless we're absolutely forced to,
@@ -198,11 +214,11 @@ static void usage(const char *cmd)
 "  -h, --help        display this help and exit\n"
 "\n"
 "Report bugs to <mdroth at linux.vnet.ibm.com>\n"
-    , cmd, QEMU_VERSION, QGA_VIRTIO_PATH_DEFAULT, QGA_PIDFILE_DEFAULT,
+    , cmd, QEMU_VERSION, QGA_VIRTIO_PATH_DEFAULT, dfl_pathnames.pidfile,
 #ifdef CONFIG_FSFREEZE
     QGA_FSFREEZE_HOOK_DEFAULT,
 #endif
-    QGA_STATEDIR_DEFAULT);
+    dfl_pathnames.state_dir);
 }
 
 static const char *ga_log_level_str(GLogLevelFlags level)
@@ -908,11 +924,11 @@ int main(int argc, char **argv)
     const char *sopt = "hVvdm:p:l:f:F::b:s:t:";
     const char *method = NULL, *path = NULL;
     const char *log_filepath = NULL;
-    const char *pid_filepath = QGA_PIDFILE_DEFAULT;
+    const char *pid_filepath;
 #ifdef CONFIG_FSFREEZE
     const char *fsfreeze_hook = NULL;
 #endif
-    const char *state_dir = QGA_STATEDIR_DEFAULT;
+    const char *state_dir;
 #ifdef _WIN32
     const char *service = NULL;
 #endif
@@ -942,6 +958,10 @@ int main(int argc, char **argv)
 
     module_call_init(MODULE_INIT_QAPI);
 
+    init_dfl_pathnames();
+    pid_filepath = dfl_pathnames.pidfile;
+    state_dir = dfl_pathnames.state_dir;
+
     while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
         switch (ch) {
         case 'm':
commit e2ea3515a9d2d747f91dadf361afcbeb57a71500
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Sat May 18 06:31:48 2013 +0200

    osdep: add qemu_get_local_state_pathname()
    
    This function returns ${prefix}/var/RELATIVE_PATHNAME on POSIX-y systems,
    and <CSIDL_COMMON_APPDATA>/RELATIVE_PATHNAME on Win32.
    
    http://msdn.microsoft.com/en-us/library/bb762494.aspx
    
      [...] This folder is used for application data that is not user
      specific. For example, an application can store a spell-check
      dictionary, a database of clip art, or a log file in the
      CSIDL_COMMON_APPDATA folder. [...]
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 57d7b1f..26136f1 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -204,4 +204,15 @@ const char *qemu_get_version(void);
 void fips_set_state(bool requested);
 bool fips_get_state(void);
 
+/* Return a dynamically allocated pathname denoting a file or directory that is
+ * appropriate for storing local state.
+ *
+ * @relative_pathname need not start with a directory separator; one will be
+ * added automatically.
+ *
+ * The caller is responsible for releasing the value returned with g_free()
+ * after use.
+ */
+char *qemu_get_local_state_pathname(const char *relative_pathname);
+
 #endif
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 631a1de..3dc8b1b 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -47,6 +47,8 @@ extern int daemon(int, int);
 #  define QEMU_VMALLOC_ALIGN getpagesize()
 #endif
 
+#include <glib/gprintf.h>
+
 #include "config-host.h"
 #include "sysemu/sysemu.h"
 #include "trace.h"
@@ -232,3 +234,10 @@ int qemu_utimens(const char *path, const struct timespec *times)
 
     return utimes(path, &tv[0]);
 }
+
+char *
+qemu_get_local_state_pathname(const char *relative_pathname)
+{
+    return g_strdup_printf("%s/%s", CONFIG_QEMU_LOCALSTATEDIR,
+                           relative_pathname);
+}
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index df2ecbd..961fbf5 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -26,12 +26,17 @@
  * THE SOFTWARE.
  */
 #include <windows.h>
+#include <glib.h>
+#include <stdlib.h>
 #include "config-host.h"
 #include "sysemu/sysemu.h"
 #include "qemu/main-loop.h"
 #include "trace.h"
 #include "qemu/sockets.h"
 
+/* this must come after including "trace.h" */
+#include <shlobj.h>
+
 void *qemu_oom_check(void *ptr)
 {
     if (ptr == NULL) {
@@ -160,3 +165,20 @@ int qemu_get_thread_id(void)
 {
     return GetCurrentThreadId();
 }
+
+char *
+qemu_get_local_state_pathname(const char *relative_pathname)
+{
+    HRESULT result;
+    char base_path[MAX_PATH+1] = "";
+
+    result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL,
+                             /* SHGFP_TYPE_CURRENT */ 0, base_path);
+    if (result != S_OK) {
+        /* misconfigured environment */
+        g_critical("CSIDL_COMMON_APPDATA unavailable: %ld", (long)result);
+        abort();
+    }
+    return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", base_path,
+                           relative_pathname);
+}
commit 68c0e134a090666246b467deaf9046e573b089f2
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Thu May 30 11:35:23 2013 +0300

    q35: set fw_name
    
    PCI host bridges need to set fw_name to be discoverable
    by bios for boot device selection.
    
    In particular, seabios expects root device to be called
    "/pci/@i0cf8", so let's set it up like that for Q35.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Tested-by: Amos Kong <akong at redhat.com>

diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 8467f86..24df6b5 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -76,6 +76,7 @@ static void q35_host_class_init(ObjectClass *klass, void *data)
 
     k->init = q35_host_init;
     dc->props = mch_props;
+    dc->fw_name = "pci";
 }
 
 static void q35_host_initfn(Object *obj)
commit a678e26cbe89f7a27cbce794c2c2784571ee9d21
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Sun May 26 22:20:58 2013 -0500

    qapi: pad GenericList value fields to 64 bits
    
    With the introduction of native list types, we now have types such as
    int64List where the 'value' field is not a pointer, but the actual
    64-bit value.
    
    On 32-bit architectures, this can lead to situations where 'next' field
    offset in GenericList does not correspond to the 'next' field in the
    types that we cast to GenericList when using the visit_next_list()
    interface, causing issues when we attempt to traverse linked list
    structures of these types.
    
    To fix this, pad the 'value' field of GenericList and other
    schema-defined/native *List types out to 64-bits.
    
    This is less memory-efficient for 32-bit architectures, but allows us to
    continue to rely on list-handling interfaces that target GenericList to
    simply visitor implementations.
    
    In the future we can improve efficiency by defaulting to using native C
    array backends to handle list of non-pointer types, which would be more
    memory efficient in itself and allow us to roll back this change.
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 1fef18c..28c21d8 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -18,7 +18,10 @@
 
 typedef struct GenericList
 {
-    void *value;
+    union {
+        void *value;
+        uint64_t padding;
+    };
     struct GenericList *next;
 } GenericList;
 
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index fd42d71..ddcfed9 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -22,7 +22,10 @@ def generate_fwd_struct(name, members, builtin_type=False):
 
 typedef struct %(name)sList
 {
-    %(type)s value;
+    union {
+        %(type)s value;
+        uint64_t padding;
+    };
     struct %(name)sList *next;
 } %(name)sList;
 ''',
@@ -35,7 +38,10 @@ typedef struct %(name)s %(name)s;
 
 typedef struct %(name)sList
 {
-    %(name)s *value;
+    union {
+        %(name)s *value;
+        uint64_t padding;
+    };
     struct %(name)sList *next;
 } %(name)sList;
 ''',
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index 0942a41..b2fa9a7 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -295,7 +295,10 @@ static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
 
 typedef struct TestStructList
 {
-    TestStruct *value;
+    union {
+        TestStruct *value;
+        uint64_t padding;
+    };
     struct TestStructList *next;
 } TestStructList;
 
commit fd8aaa767ab5d804c2aa156a616b8ca8837916b0
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue May 21 09:56:55 2013 +0200

    memory: add return value to address_space_rw/read/write
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index 520d4c4..5b8b40d 100644
--- a/exec.c
+++ b/exec.c
@@ -1902,7 +1902,7 @@ static inline int memory_access_size(int l, hwaddr addr)
     return 1;
 }
 
-void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
+bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
                       int len, bool is_write)
 {
     hwaddr l;
@@ -1910,6 +1910,7 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
     uint64_t val;
     hwaddr addr1;
     MemoryRegionSection *section;
+    bool error = false;
 
     while (len > 0) {
         l = len;
@@ -1923,15 +1924,15 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
                 if (l == 4) {
                     /* 32 bit write access */
                     val = ldl_p(buf);
-                    io_mem_write(section->mr, addr1, val, 4);
+                    error |= io_mem_write(section->mr, addr1, val, 4);
                 } else if (l == 2) {
                     /* 16 bit write access */
                     val = lduw_p(buf);
-                    io_mem_write(section->mr, addr1, val, 2);
+                    error |= io_mem_write(section->mr, addr1, val, 2);
                 } else {
                     /* 8 bit write access */
                     val = ldub_p(buf);
-                    io_mem_write(section->mr, addr1, val, 1);
+                    error |= io_mem_write(section->mr, addr1, val, 1);
                 }
             } else {
                 addr1 += memory_region_get_ram_addr(section->mr);
@@ -1946,15 +1947,15 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
                 l = memory_access_size(l, addr1);
                 if (l == 4) {
                     /* 32 bit read access */
-                    io_mem_read(section->mr, addr1, &val, 4);
+                    error |= io_mem_read(section->mr, addr1, &val, 4);
                     stl_p(buf, val);
                 } else if (l == 2) {
                     /* 16 bit read access */
-                    io_mem_read(section->mr, addr1, &val, 2);
+                    error |= io_mem_read(section->mr, addr1, &val, 2);
                     stw_p(buf, val);
                 } else {
                     /* 8 bit read access */
-                    io_mem_read(section->mr, addr1, &val, 1);
+                    error |= io_mem_read(section->mr, addr1, &val, 1);
                     stb_p(buf, val);
                 }
             } else {
@@ -1967,31 +1968,26 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
         buf += l;
         addr += l;
     }
+
+    return error;
 }
 
-void address_space_write(AddressSpace *as, hwaddr addr,
+bool address_space_write(AddressSpace *as, hwaddr addr,
                          const uint8_t *buf, int len)
 {
-    address_space_rw(as, addr, (uint8_t *)buf, len, true);
+    return address_space_rw(as, addr, (uint8_t *)buf, len, true);
 }
 
-/**
- * address_space_read: read from an address space.
- *
- * @as: #AddressSpace to be accessed
- * @addr: address within that address space
- * @buf: buffer with the data transferred
- */
-void address_space_read(AddressSpace *as, hwaddr addr, uint8_t *buf, int len)
+bool address_space_read(AddressSpace *as, hwaddr addr, uint8_t *buf, int len)
 {
-    address_space_rw(as, addr, buf, len, false);
+    return address_space_rw(as, addr, buf, len, false);
 }
 
 
 void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
                             int len, int is_write)
 {
-    return address_space_rw(&address_space_memory, addr, buf, len, is_write);
+    address_space_rw(&address_space_memory, addr, buf, len, is_write);
 }
 
 /* used for ROM loading : can write in RAM and ROM */
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 81e0e41..d53a6a1 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -825,32 +825,38 @@ void address_space_destroy(AddressSpace *as);
 /**
  * address_space_rw: read from or write to an address space.
  *
+ * Return true if the operation hit any unassigned memory.
+ *
  * @as: #AddressSpace to be accessed
  * @addr: address within that address space
  * @buf: buffer with the data transferred
  * @is_write: indicates the transfer direction
  */
-void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
+bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
                       int len, bool is_write);
 
 /**
  * address_space_write: write to address space.
  *
+ * Return true if the operation hit any unassigned memory.
+ *
  * @as: #AddressSpace to be accessed
  * @addr: address within that address space
  * @buf: buffer with the data transferred
  */
-void address_space_write(AddressSpace *as, hwaddr addr,
+bool address_space_write(AddressSpace *as, hwaddr addr,
                          const uint8_t *buf, int len);
 
 /**
  * address_space_read: read from an address space.
  *
+ * Return true if the operation hit any unassigned memory.
+ *
  * @as: #AddressSpace to be accessed
  * @addr: address within that address space
  * @buf: buffer with the data transferred
  */
-void address_space_read(AddressSpace *as, hwaddr addr, uint8_t *buf, int len);
+bool address_space_read(AddressSpace *as, hwaddr addr, uint8_t *buf, int len);
 
 /* address_space_translate: translate an address range into an address space
  * into a MemoryRegionSection and an address range into that section
commit 791af8c861f4537ad29c34df14fb81701e04596f
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 16:10:39 2013 +0200

    memory: propagate errors on I/O dispatch
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index 878f021..520d4c4 100644
--- a/exec.c
+++ b/exec.c
@@ -1526,6 +1526,8 @@ static uint64_t subpage_read(void *opaque, hwaddr addr,
 {
     subpage_t *mmio = opaque;
     unsigned int idx = SUBPAGE_IDX(addr);
+    uint64_t val;
+
     MemoryRegionSection *section;
 #if defined(DEBUG_SUBPAGE)
     printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__,
@@ -1536,7 +1538,8 @@ static uint64_t subpage_read(void *opaque, hwaddr addr,
     addr += mmio->base;
     addr -= section->offset_within_address_space;
     addr += section->offset_within_region;
-    return io_mem_read(section->mr, addr, len);
+    io_mem_read(section->mr, addr, &val, len);
+    return val;
 }
 
 static void subpage_write(void *opaque, hwaddr addr,
@@ -1904,7 +1907,7 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
 {
     hwaddr l;
     uint8_t *ptr;
-    uint32_t val;
+    uint64_t val;
     hwaddr addr1;
     MemoryRegionSection *section;
 
@@ -1943,15 +1946,15 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
                 l = memory_access_size(l, addr1);
                 if (l == 4) {
                     /* 32 bit read access */
-                    val = io_mem_read(section->mr, addr1, 4);
+                    io_mem_read(section->mr, addr1, &val, 4);
                     stl_p(buf, val);
                 } else if (l == 2) {
                     /* 16 bit read access */
-                    val = io_mem_read(section->mr, addr1, 2);
+                    io_mem_read(section->mr, addr1, &val, 2);
                     stw_p(buf, val);
                 } else {
                     /* 8 bit read access */
-                    val = io_mem_read(section->mr, addr1, 1);
+                    io_mem_read(section->mr, addr1, &val, 1);
                     stb_p(buf, val);
                 }
             } else {
@@ -2195,7 +2198,7 @@ static inline uint32_t ldl_phys_internal(hwaddr addr,
                                          enum device_endian endian)
 {
     uint8_t *ptr;
-    uint32_t val;
+    uint64_t val;
     MemoryRegionSection *section;
     hwaddr l = 4;
     hwaddr addr1;
@@ -2204,7 +2207,7 @@ static inline uint32_t ldl_phys_internal(hwaddr addr,
                                       false);
     if (l < 4 || !memory_access_is_direct(section->mr, false)) {
         /* I/O case */
-        val = io_mem_read(section->mr, addr1, 4);
+        io_mem_read(section->mr, addr1, &val, 4);
 #if defined(TARGET_WORDS_BIGENDIAN)
         if (endian == DEVICE_LITTLE_ENDIAN) {
             val = bswap32(val);
@@ -2263,7 +2266,7 @@ static inline uint64_t ldq_phys_internal(hwaddr addr,
                                       false);
     if (l < 8 || !memory_access_is_direct(section->mr, false)) {
         /* I/O case */
-        val = io_mem_read(section->mr, addr1, 8);
+        io_mem_read(section->mr, addr1, &val, 8);
 #if defined(TARGET_WORDS_BIGENDIAN)
         if (endian == DEVICE_LITTLE_ENDIAN) {
             val = bswap64(val);
@@ -2330,7 +2333,7 @@ static inline uint32_t lduw_phys_internal(hwaddr addr,
                                       false);
     if (l < 2 || !memory_access_is_direct(section->mr, false)) {
         /* I/O case */
-        val = io_mem_read(section->mr, addr1, 2);
+        io_mem_read(section->mr, addr1, &val, 2);
 #if defined(TARGET_WORDS_BIGENDIAN)
         if (endian == DEVICE_LITTLE_ENDIAN) {
             val = bswap16(val);
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 6362074..17fde25 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -367,9 +367,9 @@ bool is_tcg_gen_code(uintptr_t pc_ptr);
 #if !defined(CONFIG_USER_ONLY)
 
 struct MemoryRegion *iotlb_to_region(hwaddr index);
-uint64_t io_mem_read(struct MemoryRegion *mr, hwaddr addr,
-                     unsigned size);
-void io_mem_write(struct MemoryRegion *mr, hwaddr addr,
+bool io_mem_read(struct MemoryRegion *mr, hwaddr addr,
+                 uint64_t *pvalue, unsigned size);
+bool io_mem_write(struct MemoryRegion *mr, hwaddr addr,
                   uint64_t value, unsigned size);
 
 void tlb_fill(CPUArchState *env1, target_ulong addr, int is_write, int mmu_idx,
diff --git a/include/exec/softmmu_template.h b/include/exec/softmmu_template.h
index 292ca02..8584902 100644
--- a/include/exec/softmmu_template.h
+++ b/include/exec/softmmu_template.h
@@ -63,6 +63,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
                                               target_ulong addr,
                                               uintptr_t retaddr)
 {
+    uint64_t val;
     MemoryRegion *mr = iotlb_to_region(physaddr);
 
     physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
@@ -72,7 +73,8 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
     }
 
     env->mem_io_vaddr = addr;
-    return io_mem_read(mr, physaddr, 1 << SHIFT);
+    io_mem_read(mr, physaddr, &val, 1 << SHIFT);
+    return val;
 }
 
 /* handle all cases except unaligned access which span two pages */
diff --git a/memory.c b/memory.c
index f84fc53..5cb8f4a 100644
--- a/memory.c
+++ b/memory.c
@@ -928,10 +928,6 @@ static uint64_t memory_region_dispatch_read1(MemoryRegion *mr,
 {
     uint64_t data = 0;
 
-    if (!memory_region_access_valid(mr, addr, size, false)) {
-        return unassigned_mem_read(mr, addr, size);
-    }
-
     if (mr->ops->read) {
         access_with_adjusted_size(addr, &data, size,
                                   mr->ops->impl.min_access_size,
@@ -966,25 +962,29 @@ static void adjust_endianness(MemoryRegion *mr, uint64_t *data, unsigned size)
     }
 }
 
-static uint64_t memory_region_dispatch_read(MemoryRegion *mr,
-                                            hwaddr addr,
-                                            unsigned size)
+static bool memory_region_dispatch_read(MemoryRegion *mr,
+                                        hwaddr addr,
+                                        uint64_t *pval,
+                                        unsigned size)
 {
-    uint64_t ret;
+    if (!memory_region_access_valid(mr, addr, size, false)) {
+        *pval = unassigned_mem_read(mr, addr, size);
+        return true;
+    }
 
-    ret = memory_region_dispatch_read1(mr, addr, size);
-    adjust_endianness(mr, &ret, size);
-    return ret;
+    *pval = memory_region_dispatch_read1(mr, addr, size);
+    adjust_endianness(mr, pval, size);
+    return false;
 }
 
-static void memory_region_dispatch_write(MemoryRegion *mr,
+static bool memory_region_dispatch_write(MemoryRegion *mr,
                                          hwaddr addr,
                                          uint64_t data,
                                          unsigned size)
 {
     if (!memory_region_access_valid(mr, addr, size, true)) {
         unassigned_mem_write(mr, addr, data, size);
-        return;
+        return true;
     }
 
     adjust_endianness(mr, &data, size);
@@ -998,6 +998,7 @@ static void memory_region_dispatch_write(MemoryRegion *mr,
         access_with_adjusted_size(addr, &data, size, 1, 4,
                                   memory_region_oldmmio_write_accessor, mr);
     }
+    return false;
 }
 
 void memory_region_init_io(MemoryRegion *mr,
@@ -1650,15 +1651,15 @@ void address_space_destroy(AddressSpace *as)
     g_free(as->ioeventfds);
 }
 
-uint64_t io_mem_read(MemoryRegion *mr, hwaddr addr, unsigned size)
+bool io_mem_read(MemoryRegion *mr, hwaddr addr, uint64_t *pval, unsigned size)
 {
-    return memory_region_dispatch_read(mr, addr, size);
+    return memory_region_dispatch_read(mr, addr, pval, size);
 }
 
-void io_mem_write(MemoryRegion *mr, hwaddr addr,
+bool io_mem_write(MemoryRegion *mr, hwaddr addr,
                   uint64_t val, unsigned size)
 {
-    memory_region_dispatch_write(mr, addr, val, size);
+    return memory_region_dispatch_write(mr, addr, val, size);
 }
 
 typedef struct MemoryRegionList MemoryRegionList;
commit a649b9168cb9169b41532b168b94294e2be32e50
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 12:40:43 2013 +0200

    exec: just use io_mem_read/io_mem_write for 8-byte I/O accesses
    
    The memory API is able to split it in two 4-byte accesses.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index 453946e..878f021 100644
--- a/exec.c
+++ b/exec.c
@@ -2263,13 +2263,7 @@ static inline uint64_t ldq_phys_internal(hwaddr addr,
                                       false);
     if (l < 8 || !memory_access_is_direct(section->mr, false)) {
         /* I/O case */
-#ifdef TARGET_WORDS_BIGENDIAN
-        val = io_mem_read(section->mr, addr1, 4) << 32;
-        val |= io_mem_read(section->mr, addr1 + 4, 4);
-#else
-        val = io_mem_read(section->mr, addr1, 4);
-        val |= io_mem_read(section->mr, addr1 + 4, 4) << 32;
-#endif
+        val = io_mem_read(section->mr, addr1, 8);
 #if defined(TARGET_WORDS_BIGENDIAN)
         if (endian == DEVICE_LITTLE_ENDIAN) {
             val = bswap64(val);
diff --git a/include/exec/softmmu_template.h b/include/exec/softmmu_template.h
index ca91fd0..292ca02 100644
--- a/include/exec/softmmu_template.h
+++ b/include/exec/softmmu_template.h
@@ -63,7 +63,6 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
                                               target_ulong addr,
                                               uintptr_t retaddr)
 {
-    DATA_TYPE res;
     MemoryRegion *mr = iotlb_to_region(physaddr);
 
     physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
@@ -73,18 +72,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
     }
 
     env->mem_io_vaddr = addr;
-#if SHIFT <= 2
-    res = io_mem_read(mr, physaddr, 1 << SHIFT);
-#else
-#ifdef TARGET_WORDS_BIGENDIAN
-    res = io_mem_read(mr, physaddr, 4) << 32;
-    res |= io_mem_read(mr, physaddr + 4, 4);
-#else
-    res = io_mem_read(mr, physaddr, 4);
-    res |= io_mem_read(mr, physaddr + 4, 4) << 32;
-#endif
-#endif /* SHIFT > 2 */
-    return res;
+    return io_mem_read(mr, physaddr, 1 << SHIFT);
 }
 
 /* handle all cases except unaligned access which span two pages */
@@ -221,17 +209,7 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
 
     env->mem_io_vaddr = addr;
     env->mem_io_pc = retaddr;
-#if SHIFT <= 2
     io_mem_write(mr, physaddr, val, 1 << SHIFT);
-#else
-#ifdef TARGET_WORDS_BIGENDIAN
-    io_mem_write(mr, physaddr, (val >> 32), 4);
-    io_mem_write(mr, physaddr + 4, (uint32_t)val, 4);
-#else
-    io_mem_write(mr, physaddr, (uint32_t)val, 4);
-    io_mem_write(mr, physaddr + 4, val >> 32, 4);
-#endif
-#endif /* SHIFT > 2 */
 }
 
 void glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
commit 968a5627c80ff2b9fd1ed40f9400897088bd661a
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 17:58:37 2013 +0200

    memory: correctly handle endian-swapped 64-bit accesses
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index 1c4c466..453946e 100644
--- a/exec.c
+++ b/exec.c
@@ -2263,9 +2263,6 @@ static inline uint64_t ldq_phys_internal(hwaddr addr,
                                       false);
     if (l < 8 || !memory_access_is_direct(section->mr, false)) {
         /* I/O case */
-
-        /* XXX This is broken when device endian != cpu endian.
-               Fix and add "endian" variable check */
 #ifdef TARGET_WORDS_BIGENDIAN
         val = io_mem_read(section->mr, addr1, 4) << 32;
         val |= io_mem_read(section->mr, addr1 + 4, 4);
@@ -2273,6 +2270,15 @@ static inline uint64_t ldq_phys_internal(hwaddr addr,
         val = io_mem_read(section->mr, addr1, 4);
         val |= io_mem_read(section->mr, addr1 + 4, 4) << 32;
 #endif
+#if defined(TARGET_WORDS_BIGENDIAN)
+        if (endian == DEVICE_LITTLE_ENDIAN) {
+            val = bswap64(val);
+        }
+#else
+        if (endian == DEVICE_BIG_ENDIAN) {
+            val = bswap64(val);
+        }
+#endif
     } else {
         /* RAM case */
         ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section->mr)
diff --git a/memory.c b/memory.c
index ca27102..f84fc53 100644
--- a/memory.c
+++ b/memory.c
@@ -957,6 +957,9 @@ static void adjust_endianness(MemoryRegion *mr, uint64_t *data, unsigned size)
         case 4:
             *data = bswap32(*data);
             break;
+        case 8:
+            *data = bswap64(*data);
+            break;
         default:
             abort();
         }
commit ce5d2f331ec42b43f92aa4c57fdaaf4c34ccb377
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 17:45:48 2013 +0200

    memory: split accesses even when the old MMIO callbacks are used
    
    This is useful for 64-bit memory accesses.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/memory.c b/memory.c
index 679bd8d..ca27102 100644
--- a/memory.c
+++ b/memory.c
@@ -302,6 +302,20 @@ static void flatview_simplify(FlatView *view)
     }
 }
 
+static void memory_region_oldmmio_read_accessor(void *opaque,
+                                                hwaddr addr,
+                                                uint64_t *value,
+                                                unsigned size,
+                                                unsigned shift,
+                                                uint64_t mask)
+{
+    MemoryRegion *mr = opaque;
+    uint64_t tmp;
+
+    tmp = mr->ops->old_mmio.read[ctz32(size)](mr->opaque, addr);
+    *value |= (tmp & mask) << shift;
+}
+
 static void memory_region_read_accessor(void *opaque,
                                         hwaddr addr,
                                         uint64_t *value,
@@ -319,6 +333,20 @@ static void memory_region_read_accessor(void *opaque,
     *value |= (tmp & mask) << shift;
 }
 
+static void memory_region_oldmmio_write_accessor(void *opaque,
+                                                 hwaddr addr,
+                                                 uint64_t *value,
+                                                 unsigned size,
+                                                 unsigned shift,
+                                                 uint64_t mask)
+{
+    MemoryRegion *mr = opaque;
+    uint64_t tmp;
+
+    tmp = (*value >> shift) & mask;
+    mr->ops->old_mmio.write[ctz32(size)](mr->opaque, addr, tmp);
+}
+
 static void memory_region_write_accessor(void *opaque,
                                          hwaddr addr,
                                          uint64_t *value,
@@ -359,6 +387,8 @@ static void access_with_adjusted_size(hwaddr addr,
     if (!access_size_max) {
         access_size_max = 4;
     }
+
+    /* FIXME: support unaligned access? */
     access_size = MAX(MIN(size, access_size_max), access_size_min);
     access_mask = -1ULL >> (64 - access_size * 8);
     for (i = 0; i < size; i += access_size) {
@@ -902,16 +932,16 @@ static uint64_t memory_region_dispatch_read1(MemoryRegion *mr,
         return unassigned_mem_read(mr, addr, size);
     }
 
-    if (!mr->ops->read) {
-        return mr->ops->old_mmio.read[ctz32(size)](mr->opaque, addr);
+    if (mr->ops->read) {
+        access_with_adjusted_size(addr, &data, size,
+                                  mr->ops->impl.min_access_size,
+                                  mr->ops->impl.max_access_size,
+                                  memory_region_read_accessor, mr);
+    } else {
+        access_with_adjusted_size(addr, &data, size, 1, 4,
+                                  memory_region_oldmmio_read_accessor, mr);
     }
 
-    /* FIXME: support unaligned access */
-    access_with_adjusted_size(addr, &data, size,
-                              mr->ops->impl.min_access_size,
-                              mr->ops->impl.max_access_size,
-                              memory_region_read_accessor, mr);
-
     return data;
 }
 
@@ -956,16 +986,15 @@ static void memory_region_dispatch_write(MemoryRegion *mr,
 
     adjust_endianness(mr, &data, size);
 
-    if (!mr->ops->write) {
-        mr->ops->old_mmio.write[ctz32(size)](mr->opaque, addr, data);
-        return;
+    if (mr->ops->write) {
+        access_with_adjusted_size(addr, &data, size,
+                                  mr->ops->impl.min_access_size,
+                                  mr->ops->impl.max_access_size,
+                                  memory_region_write_accessor, mr);
+    } else {
+        access_with_adjusted_size(addr, &data, size, 1, 4,
+                                  memory_region_oldmmio_write_accessor, mr);
     }
-
-    /* FIXME: support unaligned access */
-    access_with_adjusted_size(addr, &data, size,
-                              mr->ops->impl.min_access_size,
-                              mr->ops->impl.max_access_size,
-                              memory_region_write_accessor, mr);
 }
 
 void memory_region_init_io(MemoryRegion *mr,
commit 08521e28c7e6e8cc1f53424a0f845f58d2ed9546
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 12:54:01 2013 +0200

    memory: add big endian support to access_with_adjusted_size
    
    This will be used to split 8-byte access down to two four-byte accesses.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/memory.c b/memory.c
index c72f56d..679bd8d 100644
--- a/memory.c
+++ b/memory.c
@@ -362,8 +362,12 @@ static void access_with_adjusted_size(hwaddr addr,
     access_size = MAX(MIN(size, access_size_max), access_size_min);
     access_mask = -1ULL >> (64 - access_size * 8);
     for (i = 0; i < size; i += access_size) {
-        /* FIXME: big-endian support */
+#ifdef TARGET_WORDS_BIGENDIAN
+        access(opaque, addr + i, value, access_size,
+               (size - access_size - i) * 8, access_mask);
+#else
         access(opaque, addr + i, value, access_size, i * 8, access_mask);
+#endif
     }
 }
 
commit a014ed07bd5a93950fe12c88ed5faf188a22ee01
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 17:48:52 2013 +0200

    memory: accept mismatching sizes in memory_region_access_valid
    
    The memory API is able to use smaller/wider accesses than requested,
    match that in memory_region_access_valid.  Of course, the accepts
    callback is still free to reject those accesses.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/memory.c b/memory.c
index 9e1c1a3..c72f56d 100644
--- a/memory.c
+++ b/memory.c
@@ -856,24 +856,35 @@ bool memory_region_access_valid(MemoryRegion *mr,
                                 unsigned size,
                                 bool is_write)
 {
-    if (mr->ops->valid.accepts
-        && !mr->ops->valid.accepts(mr->opaque, addr, size, is_write)) {
-        return false;
-    }
+    int access_size_min, access_size_max;
+    int access_size, i;
 
     if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
         return false;
     }
 
-    /* Treat zero as compatibility all valid */
-    if (!mr->ops->valid.max_access_size) {
+    if (!mr->ops->valid.accepts) {
         return true;
     }
 
-    if (size > mr->ops->valid.max_access_size
-        || size < mr->ops->valid.min_access_size) {
-        return false;
+    access_size_min = mr->ops->valid.min_access_size;
+    if (!mr->ops->valid.min_access_size) {
+        access_size_min = 1;
+    }
+
+    access_size_max = mr->ops->valid.max_access_size;
+    if (!mr->ops->valid.max_access_size) {
+        access_size_max = 4;
+    }
+
+    access_size = MAX(MIN(size, access_size_max), access_size_min);
+    for (i = 0; i < size; i += access_size) {
+        if (!mr->ops->valid.accepts(mr->opaque, addr + i, access_size,
+                                    is_write)) {
+            return false;
+        }
     }
+
     return true;
 }
 
commit 51644ab70ba125cb9545702d64890743d75b444b
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Apr 11 15:40:59 2013 +0200

    memory: add address_space_access_valid
    
    The old-style IOMMU lets you check whether an access is valid in a
    given DMAContext.  There is no equivalent for AddressSpace in the
    memory API, implement it with a lookup of the dispatch tree.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/dma-helpers.c b/dma-helpers.c
index 272632f..2e298b6 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -298,6 +298,11 @@ bool iommu_dma_memory_valid(DMAContext *dma, dma_addr_t addr, dma_addr_t len,
             plen = len;
         }
 
+        if (!address_space_access_valid(dma->as, paddr, len,
+                                        dir == DMA_DIRECTION_FROM_DEVICE)) {
+            return false;
+        }
+
         len -= plen;
         addr += plen;
     }
diff --git a/exec.c b/exec.c
index ab4b4d2..1c4c466 100644
--- a/exec.c
+++ b/exec.c
@@ -2067,6 +2067,27 @@ static void cpu_notify_map_clients(void)
     }
 }
 
+bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write)
+{
+    MemoryRegionSection *section;
+    hwaddr l, xlat;
+
+    while (len > 0) {
+        l = len;
+        section = address_space_translate(as, addr, &xlat, &l, is_write);
+        if (!memory_access_is_direct(section->mr, is_write)) {
+            l = memory_access_size(l, addr);
+            if (!memory_region_access_valid(section->mr, xlat, l, is_write)) {
+                return false;
+            }
+        }
+
+        len -= l;
+        addr += l;
+    }
+    return true;
+}
+
 /* Map a physical memory region into a host virtual address.
  * May map a subset of the requested range, given by and returned in *plen.
  * May return NULL if resources needed to perform the mapping are exhausted.
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 688d3f0..81e0e41 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -866,6 +866,21 @@ MemoryRegionSection *address_space_translate(AddressSpace *as, hwaddr addr,
                                              hwaddr *xlat, hwaddr *len,
                                              bool is_write);
 
+/* address_space_access_valid: check for validity of accessing an address
+ * space range
+ *
+ * Check whether memory is assigned to the given address space range.
+ *
+ * For now, addr and len should be aligned to a page size.  This limitation
+ * will be lifted in the future.
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @len: length of the area to be checked
+ * @is_write: indicates the transfer direction
+ */
+bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write);
+
 /* address_space_map: map a physical memory region into a host virtual address
  *
  * May map a subset of the requested range, given by and returned in @plen.
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index a52c93a..02e0dcd 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -113,7 +113,8 @@ static inline bool dma_memory_valid(DMAContext *dma,
                                     DMADirection dir)
 {
     if (!dma_has_iommu(dma)) {
-        return true;
+        return address_space_access_valid(dma->as, addr, len,
+                                          dir == DMA_DIRECTION_FROM_DEVICE);
     } else {
         return iommu_dma_memory_valid(dma, addr, len, dir);
     }
commit c353e4cc08a2fce7c505dd0d04512ef3947adff8
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 14:02:39 2013 +0200

    exec: implement .valid.accepts for subpages
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index d640d07..ab4b4d2 100644
--- a/exec.c
+++ b/exec.c
@@ -1558,9 +1558,29 @@ static void subpage_write(void *opaque, hwaddr addr,
     io_mem_write(section->mr, addr, value, len);
 }
 
+static bool subpage_accepts(void *opaque, hwaddr addr,
+                            unsigned size, bool is_write)
+{
+    subpage_t *mmio = opaque;
+    unsigned int idx = SUBPAGE_IDX(addr);
+    MemoryRegionSection *section;
+#if defined(DEBUG_SUBPAGE)
+    printf("%s: subpage %p %c len %d addr " TARGET_FMT_plx
+           " idx %d\n", __func__, mmio,
+           is_write ? 'w' : 'r', len, addr, idx);
+#endif
+
+    section = &phys_sections[mmio->sub_section[idx]];
+    addr += mmio->base;
+    addr -= section->offset_within_address_space;
+    addr += section->offset_within_region;
+    return memory_region_access_valid(section->mr, addr, size, is_write);
+}
+
 static const MemoryRegionOps subpage_ops = {
     .read = subpage_read,
     .write = subpage_write,
+    .valid.accepts = subpage_accepts,
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
commit d2702032b4746515cff0bf29891a6b6decfc3d86
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 11:55:06 2013 +0200

    memory: export memory_region_access_valid to exec.c
    
    We'll use it to implement address_space_access_valid.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
index c18b36c..799c02a 100644
--- a/include/exec/memory-internal.h
+++ b/include/exec/memory-internal.h
@@ -45,6 +45,9 @@ void address_space_destroy_dispatch(AddressSpace *as);
 
 extern const MemoryRegionOps unassigned_mem_ops;
 
+bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
+                                unsigned size, bool is_write);
+
 ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
                                    MemoryRegion *mr);
 ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
diff --git a/memory.c b/memory.c
index f2135d1..9e1c1a3 100644
--- a/memory.c
+++ b/memory.c
@@ -851,10 +851,10 @@ const MemoryRegionOps unassigned_mem_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static bool memory_region_access_valid(MemoryRegion *mr,
-                                       hwaddr addr,
-                                       unsigned size,
-                                       bool is_write)
+bool memory_region_access_valid(MemoryRegion *mr,
+                                hwaddr addr,
+                                unsigned size,
+                                bool is_write)
 {
     if (mr->ops->valid.accepts
         && !mr->ops->valid.accepts(mr->opaque, addr, size, is_write)) {
commit 82f2563fc81532e24380085d23a9d32c17b74169
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 11:59:43 2013 +0200

    exec: introduce memory_access_size
    
    This will be used by address_space_access_valid too.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index 881f6ec..d640d07 100644
--- a/exec.c
+++ b/exec.c
@@ -1868,6 +1868,17 @@ static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
     return false;
 }
 
+static inline int memory_access_size(int l, hwaddr addr)
+{
+    if (l >= 4 && ((addr & 3) == 0)) {
+        return 4;
+    }
+    if (l >= 2 && ((addr & 1) == 0)) {
+        return 2;
+    }
+    return 1;
+}
+
 void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
                       int len, bool is_write)
 {
@@ -1883,23 +1894,21 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
 
         if (is_write) {
             if (!memory_access_is_direct(section->mr, is_write)) {
+                l = memory_access_size(l, addr1);
                 /* XXX: could force cpu_single_env to NULL to avoid
                    potential bugs */
-                if (l >= 4 && ((addr1 & 3) == 0)) {
+                if (l == 4) {
                     /* 32 bit write access */
                     val = ldl_p(buf);
                     io_mem_write(section->mr, addr1, val, 4);
-                    l = 4;
-                } else if (l >= 2 && ((addr1 & 1) == 0)) {
+                } else if (l == 2) {
                     /* 16 bit write access */
                     val = lduw_p(buf);
                     io_mem_write(section->mr, addr1, val, 2);
-                    l = 2;
                 } else {
                     /* 8 bit write access */
                     val = ldub_p(buf);
                     io_mem_write(section->mr, addr1, val, 1);
-                    l = 1;
                 }
             } else {
                 addr1 += memory_region_get_ram_addr(section->mr);
@@ -1911,21 +1920,19 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
         } else {
             if (!memory_access_is_direct(section->mr, is_write)) {
                 /* I/O case */
-                if (l >= 4 && ((addr1 & 3) == 0)) {
+                l = memory_access_size(l, addr1);
+                if (l == 4) {
                     /* 32 bit read access */
                     val = io_mem_read(section->mr, addr1, 4);
                     stl_p(buf, val);
-                    l = 4;
-                } else if (l >= 2 && ((addr1 & 1) == 0)) {
+                } else if (l == 2) {
                     /* 16 bit read access */
                     val = io_mem_read(section->mr, addr1, 2);
                     stw_p(buf, val);
-                    l = 2;
                 } else {
                     /* 8 bit read access */
                     val = io_mem_read(section->mr, addr1, 1);
                     stb_p(buf, val);
-                    l = 1;
                 }
             } else {
                 /* RAM case */
commit 2bbfa05d20067de0d032d832ae22c1041f4c89c2
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 12:29:54 2013 +0200

    exec: introduce memory_access_is_direct
    
    After the previous patches, this is a common test for all read/write
    functions.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index f6cebd6..881f6ec 100644
--- a/exec.c
+++ b/exec.c
@@ -1856,6 +1856,18 @@ static void invalidate_and_set_dirty(hwaddr addr,
     xen_modified_memory(addr, length);
 }
 
+static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
+{
+    if (memory_region_is_ram(mr)) {
+        return !(is_write && mr->readonly);
+    }
+    if (memory_region_is_romd(mr)) {
+        return !is_write;
+    }
+
+    return false;
+}
+
 void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
                       int len, bool is_write)
 {
@@ -1870,7 +1882,7 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
         section = address_space_translate(as, addr, &addr1, &l, is_write);
 
         if (is_write) {
-            if (!memory_region_is_ram(section->mr)) {
+            if (!memory_access_is_direct(section->mr, is_write)) {
                 /* XXX: could force cpu_single_env to NULL to avoid
                    potential bugs */
                 if (l >= 4 && ((addr1 & 3) == 0)) {
@@ -1889,7 +1901,7 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
                     io_mem_write(section->mr, addr1, val, 1);
                     l = 1;
                 }
-            } else if (!section->readonly) {
+            } else {
                 addr1 += memory_region_get_ram_addr(section->mr);
                 /* RAM case */
                 ptr = qemu_get_ram_ptr(addr1);
@@ -1897,8 +1909,7 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
                 invalidate_and_set_dirty(addr1, l);
             }
         } else {
-            if (!(memory_region_is_ram(section->mr) ||
-                  memory_region_is_romd(section->mr))) {
+            if (!memory_access_is_direct(section->mr, is_write)) {
                 /* I/O case */
                 if (l >= 4 && ((addr1 & 3) == 0)) {
                     /* 32 bit read access */
@@ -2053,7 +2064,7 @@ void *address_space_map(AddressSpace *as,
         l = len;
         section = address_space_translate(as, addr, &xlat, &l, is_write);
 
-        if (!(memory_region_is_ram(section->mr) && !section->readonly)) {
+        if (!memory_access_is_direct(section->mr, is_write)) {
             if (todo || bounce.buffer) {
                 break;
             }
@@ -2143,9 +2154,7 @@ static inline uint32_t ldl_phys_internal(hwaddr addr,
 
     section = address_space_translate(&address_space_memory, addr, &addr1, &l,
                                       false);
-    if (l < 4 ||
-        !(memory_region_is_ram(section->mr) ||
-          memory_region_is_romd(section->mr))) {
+    if (l < 4 || !memory_access_is_direct(section->mr, false)) {
         /* I/O case */
         val = io_mem_read(section->mr, addr1, 4);
 #if defined(TARGET_WORDS_BIGENDIAN)
@@ -2204,9 +2213,7 @@ static inline uint64_t ldq_phys_internal(hwaddr addr,
 
     section = address_space_translate(&address_space_memory, addr, &addr1, &l,
                                       false);
-    if (l < 8 ||
-        !(memory_region_is_ram(section->mr) ||
-          memory_region_is_romd(section->mr))) {
+    if (l < 8 || !memory_access_is_direct(section->mr, false)) {
         /* I/O case */
 
         /* XXX This is broken when device endian != cpu endian.
@@ -2273,9 +2280,7 @@ static inline uint32_t lduw_phys_internal(hwaddr addr,
 
     section = address_space_translate(&address_space_memory, addr, &addr1, &l,
                                       false);
-    if (l < 2 ||
-        !(memory_region_is_ram(section->mr) ||
-          memory_region_is_romd(section->mr))) {
+    if (l < 2 || !memory_access_is_direct(section->mr, false)) {
         /* I/O case */
         val = io_mem_read(section->mr, addr1, 2);
 #if defined(TARGET_WORDS_BIGENDIAN)
@@ -2334,7 +2339,7 @@ void stl_phys_notdirty(hwaddr addr, uint32_t val)
 
     section = address_space_translate(&address_space_memory, addr, &addr1, &l,
                                       true);
-    if (l < 4 || !memory_region_is_ram(section->mr) || section->readonly) {
+    if (l < 4 || !memory_access_is_direct(section->mr, true)) {
         io_mem_write(section->mr, addr1, val, 4);
     } else {
         addr1 += memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK;
@@ -2364,7 +2369,7 @@ static inline void stl_phys_internal(hwaddr addr, uint32_t val,
 
     section = address_space_translate(&address_space_memory, addr, &addr1, &l,
                                       true);
-    if (l < 4 || !memory_region_is_ram(section->mr) || section->readonly) {
+    if (l < 4 || !memory_access_is_direct(section->mr, true)) {
 #if defined(TARGET_WORDS_BIGENDIAN)
         if (endian == DEVICE_LITTLE_ENDIAN) {
             val = bswap32(val);
@@ -2427,7 +2432,7 @@ static inline void stw_phys_internal(hwaddr addr, uint32_t val,
 
     section = address_space_translate(&address_space_memory, addr, &addr1, &l,
                                       true);
-    if (l < 2 || !memory_region_is_ram(section->mr) || section->readonly) {
+    if (l < 2 || !memory_access_is_direct(section->mr, true)) {
 #if defined(TARGET_WORDS_BIGENDIAN)
         if (endian == DEVICE_LITTLE_ENDIAN) {
             val = bswap16(val);
commit d17d45e95f497e67aa48ff9e49a4ad62bb1e17df
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 13:21:01 2013 +0200

    exec: expect mr->ops to be initialized for ROM
    
    There is no need to use the special phys_section_rom section.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index 03003b2..f6cebd6 100644
--- a/exec.c
+++ b/exec.c
@@ -2335,9 +2335,6 @@ void stl_phys_notdirty(hwaddr addr, uint32_t val)
     section = address_space_translate(&address_space_memory, addr, &addr1, &l,
                                       true);
     if (l < 4 || !memory_region_is_ram(section->mr) || section->readonly) {
-        if (memory_region_is_ram(section->mr)) {
-            section = &phys_sections[phys_section_rom];
-        }
         io_mem_write(section->mr, addr1, val, 4);
     } else {
         addr1 += memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK;
@@ -2368,9 +2365,6 @@ static inline void stl_phys_internal(hwaddr addr, uint32_t val,
     section = address_space_translate(&address_space_memory, addr, &addr1, &l,
                                       true);
     if (l < 4 || !memory_region_is_ram(section->mr) || section->readonly) {
-        if (memory_region_is_ram(section->mr)) {
-            section = &phys_sections[phys_section_rom];
-        }
 #if defined(TARGET_WORDS_BIGENDIAN)
         if (endian == DEVICE_LITTLE_ENDIAN) {
             val = bswap32(val);
@@ -2434,9 +2428,6 @@ static inline void stw_phys_internal(hwaddr addr, uint32_t val,
     section = address_space_translate(&address_space_memory, addr, &addr1, &l,
                                       true);
     if (l < 2 || !memory_region_is_ram(section->mr) || section->readonly) {
-        if (memory_region_is_ram(section->mr)) {
-            section = &phys_sections[phys_section_rom];
-        }
 #if defined(TARGET_WORDS_BIGENDIAN)
         if (endian == DEVICE_LITTLE_ENDIAN) {
             val = bswap16(val);
commit 2cdfcf272d1a38e22879aecae83e95be51369b2d
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 13:55:52 2013 +0200

    memory: assign MemoryRegionOps to all regions
    
    This allows to remove the checks on section->readonly.  Simply,
    write accesses to ROM will not be considered "direct" and will
    go through mr->ops without any special intervention.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/memory.c b/memory.c
index 2e4f547..f2135d1 100644
--- a/memory.c
+++ b/memory.c
@@ -788,7 +788,8 @@ void memory_region_init(MemoryRegion *mr,
                         const char *name,
                         uint64_t size)
 {
-    mr->ops = NULL;
+    mr->ops = &unassigned_mem_ops;
+    mr->opaque = NULL;
     mr->parent = NULL;
     mr->size = int128_make64(size);
     if (size == UINT64_MAX) {
commit d197063fcf969e1269dc53c9c9e9a073f87aa3b4
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 13:23:38 2013 +0200

    memory: move unassigned_mem_ops to memory.c
    
    reservation_ops is already doing the same thing.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index 3ebc46a..03003b2 100644
--- a/exec.c
+++ b/exec.c
@@ -50,7 +50,6 @@
 
 #include "exec/memory-internal.h"
 
-//#define DEBUG_UNASSIGNED
 //#define DEBUG_SUBPAGE
 
 #if !defined(CONFIG_USER_ONLY)
@@ -1402,17 +1401,6 @@ ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
     return ram_addr;
 }
 
-static bool unassigned_mem_accepts(void *opaque, hwaddr addr,
-                                   unsigned size, bool is_write)
-{
-    return false;
-}
-
-const MemoryRegionOps unassigned_mem_ops = {
-    .valid.accepts = unassigned_mem_accepts,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
 static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
                                uint64_t val, unsigned size)
 {
diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
index 8d15f90..c18b36c 100644
--- a/include/exec/memory-internal.h
+++ b/include/exec/memory-internal.h
@@ -43,6 +43,8 @@ struct AddressSpaceDispatch {
 void address_space_init_dispatch(AddressSpace *as);
 void address_space_destroy_dispatch(AddressSpace *as);
 
+extern const MemoryRegionOps unassigned_mem_ops;
+
 ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
                                    MemoryRegion *mr);
 ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
diff --git a/memory.c b/memory.c
index 15da877..2e4f547 100644
--- a/memory.c
+++ b/memory.c
@@ -22,6 +22,8 @@
 
 #include "exec/memory-internal.h"
 
+//#define DEBUG_UNASSIGNED
+
 static unsigned memory_region_transaction_depth;
 static bool memory_region_update_pending;
 static bool global_dirty_log = false;
@@ -837,6 +839,17 @@ static void unassigned_mem_write(void *opaque, hwaddr addr,
 #endif
 }
 
+static bool unassigned_mem_accepts(void *opaque, hwaddr addr,
+                                   unsigned size, bool is_write)
+{
+    return false;
+}
+
+const MemoryRegionOps unassigned_mem_ops = {
+    .valid.accepts = unassigned_mem_accepts,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
 static bool memory_region_access_valid(MemoryRegion *mr,
                                        hwaddr addr,
                                        unsigned size,
@@ -1001,40 +1014,11 @@ void memory_region_init_rom_device(MemoryRegion *mr,
     mr->ram_addr = qemu_ram_alloc(size, mr);
 }
 
-static uint64_t invalid_read(void *opaque, hwaddr addr,
-                             unsigned size)
-{
-    MemoryRegion *mr = opaque;
-
-    if (!mr->warning_printed) {
-        fprintf(stderr, "Invalid read from memory region %s\n", mr->name);
-        mr->warning_printed = true;
-    }
-    return -1U;
-}
-
-static void invalid_write(void *opaque, hwaddr addr, uint64_t data,
-                          unsigned size)
-{
-    MemoryRegion *mr = opaque;
-
-    if (!mr->warning_printed) {
-        fprintf(stderr, "Invalid write to memory region %s\n", mr->name);
-        mr->warning_printed = true;
-    }
-}
-
-static const MemoryRegionOps reservation_ops = {
-    .read = invalid_read,
-    .write = invalid_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
 void memory_region_init_reservation(MemoryRegion *mr,
                                     const char *name,
                                     uint64_t size)
 {
-    memory_region_init_io(mr, &reservation_ops, mr, name, size);
+    memory_region_init_io(mr, &unassigned_mem_ops, mr, name, size);
 }
 
 void memory_region_destroy(MemoryRegion *mr)
commit 149f54b53b7666a3facd45e86eece60ce7d3b114
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 12:59:37 2013 +0200

    memory: add address_space_translate
    
    Using phys_page_find to translate an AddressSpace to a MemoryRegionSection
    is unwieldy.  It requires to pass the page index rather than the address,
    and later memory_region_section_addr has to be called.  Replace
    memory_region_section_addr with a function that does all of it: call
    phys_page_find, compute the offset within the region, and check how
    big the current mapping is.  This way, a large flat region can be written
    with a single lookup rather than a page at a time.
    
    address_space_translate will also provide a single point where IOMMU
    forwarding is implemented.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/cputlb.c b/cputlb.c
index b56bc01..86666c8 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -248,13 +248,18 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
     target_ulong code_address;
     uintptr_t addend;
     CPUTLBEntry *te;
-    hwaddr iotlb;
+    hwaddr iotlb, xlat, sz;
 
     assert(size >= TARGET_PAGE_SIZE);
     if (size != TARGET_PAGE_SIZE) {
         tlb_add_large_page(env, vaddr, size);
     }
-    section = phys_page_find(address_space_memory.dispatch, paddr >> TARGET_PAGE_BITS);
+
+    sz = size;
+    section = address_space_translate(&address_space_memory, paddr, &xlat, &sz,
+                                      false);
+    assert(sz >= TARGET_PAGE_SIZE);
+
 #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",
@@ -268,13 +273,12 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
         addend = 0;
     } else {
         /* TLB_MMIO for rom/romd handled below */
-        addend = (uintptr_t)memory_region_get_ram_ptr(section->mr)
-        + memory_region_section_addr(section, paddr);
+        addend = (uintptr_t)memory_region_get_ram_ptr(section->mr) + xlat;
     }
 
     code_address = address;
-    iotlb = memory_region_section_get_iotlb(env, section, vaddr, paddr, prot,
-                                            &address);
+    iotlb = memory_region_section_get_iotlb(env, section, vaddr, paddr, xlat,
+                                            prot, &address);
 
     index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
     env->iotlb[mmu_idx][index] = iotlb - vaddr;
@@ -297,9 +301,7 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
             /* Write access calls the I/O callback.  */
             te->addr_write = address | TLB_MMIO;
         } else if (memory_region_is_ram(section->mr)
-                   && !cpu_physical_memory_is_dirty(
-                           section->mr->ram_addr
-                           + memory_region_section_addr(section, paddr))) {
+                   && !cpu_physical_memory_is_dirty(section->mr->ram_addr + xlat)) {
             te->addr_write = address | TLB_NOTDIRTY;
         } else {
             te->addr_write = address;
diff --git a/exec.c b/exec.c
index c5100d6..3ebc46a 100644
--- a/exec.c
+++ b/exec.c
@@ -182,7 +182,7 @@ static void phys_page_set(AddressSpaceDispatch *d,
     phys_page_set_level(&d->phys_map, &index, &nb, leaf, P_L2_LEVELS - 1);
 }
 
-MemoryRegionSection *phys_page_find(AddressSpaceDispatch *d, hwaddr index)
+static MemoryRegionSection *phys_page_find(AddressSpaceDispatch *d, hwaddr index)
 {
     PhysPageEntry lp = d->phys_map;
     PhysPageEntry *p;
@@ -203,6 +203,25 @@ bool memory_region_is_unassigned(MemoryRegion *mr)
     return mr != &io_mem_rom && mr != &io_mem_notdirty && !mr->rom_device
         && mr != &io_mem_watch;
 }
+
+MemoryRegionSection *address_space_translate(AddressSpace *as, hwaddr addr,
+                                             hwaddr *xlat, hwaddr *plen,
+                                             bool is_write)
+{
+    MemoryRegionSection *section;
+    Int128 diff;
+
+    section = phys_page_find(as->dispatch, addr >> TARGET_PAGE_BITS);
+    /* Compute offset within MemoryRegionSection */
+    addr -= section->offset_within_address_space;
+
+    /* Compute offset within MemoryRegion */
+    *xlat = addr + section->offset_within_region;
+
+    diff = int128_sub(section->mr->size, int128_make64(addr));
+    *plen = MIN(int128_get64(diff), *plen);
+    return section;
+}
 #endif
 
 void cpu_exec_init_all(void)
@@ -615,11 +634,11 @@ static int cpu_physical_memory_set_dirty_tracking(int enable)
 }
 
 hwaddr memory_region_section_get_iotlb(CPUArchState *env,
-                                                   MemoryRegionSection *section,
-                                                   target_ulong vaddr,
-                                                   hwaddr paddr,
-                                                   int prot,
-                                                   target_ulong *address)
+                                       MemoryRegionSection *section,
+                                       target_ulong vaddr,
+                                       hwaddr paddr, hwaddr xlat,
+                                       int prot,
+                                       target_ulong *address)
 {
     hwaddr iotlb;
     CPUWatchpoint *wp;
@@ -627,7 +646,7 @@ hwaddr memory_region_section_get_iotlb(CPUArchState *env,
     if (memory_region_is_ram(section->mr)) {
         /* Normal RAM.  */
         iotlb = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
-            + memory_region_section_addr(section, paddr);
+            + xlat;
         if (!section->readonly) {
             iotlb |= phys_section_notdirty;
         } else {
@@ -635,7 +654,7 @@ hwaddr memory_region_section_get_iotlb(CPUArchState *env,
         }
     } else {
         iotlb = section - phys_sections;
-        iotlb += memory_region_section_addr(section, paddr);
+        iotlb += xlat;
     }
 
     /* Make accesses to pages with watchpoints go via the
@@ -1852,24 +1871,18 @@ static void invalidate_and_set_dirty(hwaddr addr,
 void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
                       int len, bool is_write)
 {
-    AddressSpaceDispatch *d = as->dispatch;
-    int l;
+    hwaddr l;
     uint8_t *ptr;
     uint32_t val;
-    hwaddr page;
+    hwaddr addr1;
     MemoryRegionSection *section;
 
     while (len > 0) {
-        page = addr & TARGET_PAGE_MASK;
-        l = (page + TARGET_PAGE_SIZE) - addr;
-        if (l > len)
-            l = len;
-        section = phys_page_find(d, page >> TARGET_PAGE_BITS);
+        l = len;
+        section = address_space_translate(as, addr, &addr1, &l, is_write);
 
         if (is_write) {
             if (!memory_region_is_ram(section->mr)) {
-                hwaddr addr1;
-                addr1 = memory_region_section_addr(section, addr);
                 /* XXX: could force cpu_single_env to NULL to avoid
                    potential bugs */
                 if (l >= 4 && ((addr1 & 3) == 0)) {
@@ -1889,9 +1902,7 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
                     l = 1;
                 }
             } else if (!section->readonly) {
-                ram_addr_t addr1;
-                addr1 = memory_region_get_ram_addr(section->mr)
-                    + memory_region_section_addr(section, addr);
+                addr1 += memory_region_get_ram_addr(section->mr);
                 /* RAM case */
                 ptr = qemu_get_ram_ptr(addr1);
                 memcpy(ptr, buf, l);
@@ -1900,9 +1911,7 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
         } else {
             if (!(memory_region_is_ram(section->mr) ||
                   memory_region_is_romd(section->mr))) {
-                hwaddr addr1;
                 /* I/O case */
-                addr1 = memory_region_section_addr(section, addr);
                 if (l >= 4 && ((addr1 & 3) == 0)) {
                     /* 32 bit read access */
                     val = io_mem_read(section->mr, addr1, 4);
@@ -1921,9 +1930,7 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
                 }
             } else {
                 /* RAM case */
-                ptr = qemu_get_ram_ptr(section->mr->ram_addr
-                                       + memory_region_section_addr(section,
-                                                                    addr));
+                ptr = qemu_get_ram_ptr(section->mr->ram_addr + addr1);
                 memcpy(buf, ptr, l);
             }
         }
@@ -1962,26 +1969,21 @@ void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
 void cpu_physical_memory_write_rom(hwaddr addr,
                                    const uint8_t *buf, int len)
 {
-    AddressSpaceDispatch *d = address_space_memory.dispatch;
-    int l;
+    hwaddr l;
     uint8_t *ptr;
-    hwaddr page;
+    hwaddr addr1;
     MemoryRegionSection *section;
 
     while (len > 0) {
-        page = addr & TARGET_PAGE_MASK;
-        l = (page + TARGET_PAGE_SIZE) - addr;
-        if (l > len)
-            l = len;
-        section = phys_page_find(d, page >> TARGET_PAGE_BITS);
+        l = len;
+        section = address_space_translate(&address_space_memory,
+                                          addr, &addr1, &l, true);
 
         if (!(memory_region_is_ram(section->mr) ||
               memory_region_is_romd(section->mr))) {
             /* do nothing */
         } else {
-            unsigned long addr1;
-            addr1 = memory_region_get_ram_addr(section->mr)
-                + memory_region_section_addr(section, addr);
+            addr1 += memory_region_get_ram_addr(section->mr);
             /* ROM/RAM case */
             ptr = qemu_get_ram_ptr(addr1);
             memcpy(ptr, buf, l);
@@ -2051,22 +2053,17 @@ void *address_space_map(AddressSpace *as,
                         hwaddr *plen,
                         bool is_write)
 {
-    AddressSpaceDispatch *d = as->dispatch;
     hwaddr len = *plen;
     hwaddr todo = 0;
-    int l;
-    hwaddr page;
+    hwaddr l, xlat;
     MemoryRegionSection *section;
     ram_addr_t raddr = RAM_ADDR_MAX;
     ram_addr_t rlen;
     void *ret;
 
     while (len > 0) {
-        page = addr & TARGET_PAGE_MASK;
-        l = (page + TARGET_PAGE_SIZE) - addr;
-        if (l > len)
-            l = len;
-        section = phys_page_find(d, page >> TARGET_PAGE_BITS);
+        l = len;
+        section = address_space_translate(as, addr, &xlat, &l, is_write);
 
         if (!(memory_region_is_ram(section->mr) && !section->readonly)) {
             if (todo || bounce.buffer) {
@@ -2083,8 +2080,11 @@ void *address_space_map(AddressSpace *as,
             return bounce.buffer;
         }
         if (!todo) {
-            raddr = memory_region_get_ram_addr(section->mr)
-                + memory_region_section_addr(section, addr);
+            raddr = memory_region_get_ram_addr(section->mr) + xlat;
+        } else {
+            if (memory_region_get_ram_addr(section->mr) + xlat != raddr + todo) {
+                break;
+            }
         }
 
         len -= l;
@@ -2150,14 +2150,16 @@ static inline uint32_t ldl_phys_internal(hwaddr addr,
     uint8_t *ptr;
     uint32_t val;
     MemoryRegionSection *section;
+    hwaddr l = 4;
+    hwaddr addr1;
 
-    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
-
-    if (!(memory_region_is_ram(section->mr) ||
+    section = address_space_translate(&address_space_memory, addr, &addr1, &l,
+                                      false);
+    if (l < 4 ||
+        !(memory_region_is_ram(section->mr) ||
           memory_region_is_romd(section->mr))) {
         /* I/O case */
-        addr = memory_region_section_addr(section, addr);
-        val = io_mem_read(section->mr, addr, 4);
+        val = io_mem_read(section->mr, addr1, 4);
 #if defined(TARGET_WORDS_BIGENDIAN)
         if (endian == DEVICE_LITTLE_ENDIAN) {
             val = bswap32(val);
@@ -2171,7 +2173,7 @@ static inline uint32_t ldl_phys_internal(hwaddr addr,
         /* RAM case */
         ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section->mr)
                                 & TARGET_PAGE_MASK)
-                               + memory_region_section_addr(section, addr));
+                               + addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             val = ldl_le_p(ptr);
@@ -2209,28 +2211,30 @@ static inline uint64_t ldq_phys_internal(hwaddr addr,
     uint8_t *ptr;
     uint64_t val;
     MemoryRegionSection *section;
+    hwaddr l = 8;
+    hwaddr addr1;
 
-    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
-
-    if (!(memory_region_is_ram(section->mr) ||
+    section = address_space_translate(&address_space_memory, addr, &addr1, &l,
+                                      false);
+    if (l < 8 ||
+        !(memory_region_is_ram(section->mr) ||
           memory_region_is_romd(section->mr))) {
         /* I/O case */
-        addr = memory_region_section_addr(section, addr);
 
         /* XXX This is broken when device endian != cpu endian.
                Fix and add "endian" variable check */
 #ifdef TARGET_WORDS_BIGENDIAN
-        val = io_mem_read(section->mr, addr, 4) << 32;
-        val |= io_mem_read(section->mr, addr + 4, 4);
+        val = io_mem_read(section->mr, addr1, 4) << 32;
+        val |= io_mem_read(section->mr, addr1 + 4, 4);
 #else
-        val = io_mem_read(section->mr, addr, 4);
-        val |= io_mem_read(section->mr, addr + 4, 4) << 32;
+        val = io_mem_read(section->mr, addr1, 4);
+        val |= io_mem_read(section->mr, addr1 + 4, 4) << 32;
 #endif
     } else {
         /* RAM case */
         ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section->mr)
                                 & TARGET_PAGE_MASK)
-                               + memory_region_section_addr(section, addr));
+                               + addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             val = ldq_le_p(ptr);
@@ -2276,14 +2280,16 @@ static inline uint32_t lduw_phys_internal(hwaddr addr,
     uint8_t *ptr;
     uint64_t val;
     MemoryRegionSection *section;
+    hwaddr l = 2;
+    hwaddr addr1;
 
-    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
-
-    if (!(memory_region_is_ram(section->mr) ||
+    section = address_space_translate(&address_space_memory, addr, &addr1, &l,
+                                      false);
+    if (l < 2 ||
+        !(memory_region_is_ram(section->mr) ||
           memory_region_is_romd(section->mr))) {
         /* I/O case */
-        addr = memory_region_section_addr(section, addr);
-        val = io_mem_read(section->mr, addr, 2);
+        val = io_mem_read(section->mr, addr1, 2);
 #if defined(TARGET_WORDS_BIGENDIAN)
         if (endian == DEVICE_LITTLE_ENDIAN) {
             val = bswap16(val);
@@ -2297,7 +2303,7 @@ static inline uint32_t lduw_phys_internal(hwaddr addr,
         /* RAM case */
         ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section->mr)
                                 & TARGET_PAGE_MASK)
-                               + memory_region_section_addr(section, addr));
+                               + addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             val = lduw_le_p(ptr);
@@ -2335,19 +2341,18 @@ void stl_phys_notdirty(hwaddr addr, uint32_t val)
 {
     uint8_t *ptr;
     MemoryRegionSection *section;
+    hwaddr l = 4;
+    hwaddr addr1;
 
-    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
-
-    if (!memory_region_is_ram(section->mr) || section->readonly) {
-        addr = memory_region_section_addr(section, addr);
+    section = address_space_translate(&address_space_memory, addr, &addr1, &l,
+                                      true);
+    if (l < 4 || !memory_region_is_ram(section->mr) || section->readonly) {
         if (memory_region_is_ram(section->mr)) {
             section = &phys_sections[phys_section_rom];
         }
-        io_mem_write(section->mr, addr, val, 4);
+        io_mem_write(section->mr, addr1, val, 4);
     } else {
-        unsigned long addr1 = (memory_region_get_ram_addr(section->mr)
-                               & TARGET_PAGE_MASK)
-            + memory_region_section_addr(section, addr);
+        addr1 += memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK;
         ptr = qemu_get_ram_ptr(addr1);
         stl_p(ptr, val);
 
@@ -2369,11 +2374,12 @@ static inline void stl_phys_internal(hwaddr addr, uint32_t val,
 {
     uint8_t *ptr;
     MemoryRegionSection *section;
+    hwaddr l = 4;
+    hwaddr addr1;
 
-    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
-
-    if (!memory_region_is_ram(section->mr) || section->readonly) {
-        addr = memory_region_section_addr(section, addr);
+    section = address_space_translate(&address_space_memory, addr, &addr1, &l,
+                                      true);
+    if (l < 4 || !memory_region_is_ram(section->mr) || section->readonly) {
         if (memory_region_is_ram(section->mr)) {
             section = &phys_sections[phys_section_rom];
         }
@@ -2386,12 +2392,10 @@ static inline void stl_phys_internal(hwaddr addr, uint32_t val,
             val = bswap32(val);
         }
 #endif
-        io_mem_write(section->mr, addr, val, 4);
+        io_mem_write(section->mr, addr1, val, 4);
     } else {
-        unsigned long addr1;
-        addr1 = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
-            + memory_region_section_addr(section, addr);
         /* RAM case */
+        addr1 += memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK;
         ptr = qemu_get_ram_ptr(addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
@@ -2436,11 +2440,12 @@ static inline void stw_phys_internal(hwaddr addr, uint32_t val,
 {
     uint8_t *ptr;
     MemoryRegionSection *section;
+    hwaddr l = 2;
+    hwaddr addr1;
 
-    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
-
-    if (!memory_region_is_ram(section->mr) || section->readonly) {
-        addr = memory_region_section_addr(section, addr);
+    section = address_space_translate(&address_space_memory, addr, &addr1, &l,
+                                      true);
+    if (l < 2 || !memory_region_is_ram(section->mr) || section->readonly) {
         if (memory_region_is_ram(section->mr)) {
             section = &phys_sections[phys_section_rom];
         }
@@ -2453,12 +2458,10 @@ static inline void stw_phys_internal(hwaddr addr, uint32_t val,
             val = bswap16(val);
         }
 #endif
-        io_mem_write(section->mr, addr, val, 2);
+        io_mem_write(section->mr, addr1, val, 2);
     } else {
-        unsigned long addr1;
-        addr1 = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
-            + memory_region_section_addr(section, addr);
         /* RAM case */
+        addr1 += memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK;
         ptr = qemu_get_ram_ptr(addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
@@ -2561,9 +2564,10 @@ bool virtio_is_big_endian(void)
 bool cpu_physical_memory_is_io(hwaddr phys_addr)
 {
     MemoryRegionSection *section;
+    hwaddr l = 1;
 
-    section = phys_page_find(address_space_memory.dispatch,
-                             phys_addr >> TARGET_PAGE_BITS);
+    section = address_space_translate(&address_space_memory,
+                                      phys_addr, &phys_addr, &l, false);
 
     return !(memory_region_is_ram(section->mr) ||
              memory_region_is_romd(section->mr));
diff --git a/include/exec/cputlb.h b/include/exec/cputlb.h
index 733c885..e821660 100644
--- a/include/exec/cputlb.h
+++ b/include/exec/cputlb.h
@@ -26,8 +26,6 @@ void tlb_unprotect_code_phys(CPUArchState *env, ram_addr_t ram_addr,
                              target_ulong vaddr);
 void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start,
                            uintptr_t length);
-MemoryRegionSection *phys_page_find(struct AddressSpaceDispatch *d,
-                                    hwaddr index);
 void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length);
 void tlb_set_dirty(CPUArchState *env, target_ulong vaddr);
 extern int tlb_flush_count;
@@ -35,11 +33,11 @@ extern int tlb_flush_count;
 /* exec.c */
 void tb_flush_jmp_cache(CPUArchState *env, target_ulong addr);
 hwaddr memory_region_section_get_iotlb(CPUArchState *env,
-                                                   MemoryRegionSection *section,
-                                                   target_ulong vaddr,
-                                                   hwaddr paddr,
-                                                   int prot,
-                                                   target_ulong *address);
+                                       MemoryRegionSection *section,
+                                       target_ulong vaddr,
+                                       hwaddr paddr, hwaddr xlat,
+                                       int prot,
+                                       target_ulong *address);
 bool memory_region_is_unassigned(MemoryRegion *mr);
 
 #endif
diff --git a/include/exec/memory.h b/include/exec/memory.h
index fdf55fe..688d3f0 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -752,23 +752,6 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr,
                                        hwaddr addr, uint64_t size);
 
 /**
- * memory_region_section_addr: get offset within MemoryRegionSection
- *
- * Returns offset within MemoryRegionSection
- *
- * @section: the memory region section being queried
- * @addr: address in address space
- */
-static inline hwaddr
-memory_region_section_addr(MemoryRegionSection *section,
-                           hwaddr addr)
-{
-    addr -= section->offset_within_address_space;
-    addr += section->offset_within_region;
-    return addr;
-}
-
-/**
  * address_space_sync_dirty_bitmap: synchronize the dirty log for all memory
  *
  * Synchronizes the dirty page log for an entire address space.
@@ -869,6 +852,20 @@ void address_space_write(AddressSpace *as, hwaddr addr,
  */
 void address_space_read(AddressSpace *as, hwaddr addr, uint8_t *buf, int len);
 
+/* address_space_translate: translate an address range into an address space
+ * into a MemoryRegionSection and an address range into that section
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @xlat: pointer to address within the returned memory region section's
+ * #MemoryRegion.
+ * @len: pointer to length
+ * @is_write: indicates the transfer direction
+ */
+MemoryRegionSection *address_space_translate(AddressSpace *as, hwaddr addr,
+                                             hwaddr *xlat, hwaddr *len,
+                                             bool is_write);
+
 /* address_space_map: map a physical memory region into a host virtual address
  *
  * May map a subset of the requested range, given by and returned in @plen.
diff --git a/translate-all.c b/translate-all.c
index 211be31..40b8f3d 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -1354,15 +1354,15 @@ void tb_invalidate_phys_addr(hwaddr addr)
 {
     ram_addr_t ram_addr;
     MemoryRegionSection *section;
+    hwaddr l = 1;
 
-    section = phys_page_find(address_space_memory.dispatch,
-                             addr >> TARGET_PAGE_BITS);
+    section = address_space_translate(&address_space_memory, addr, &addr, &l, false);
     if (!(memory_region_is_ram(section->mr)
           || memory_region_is_romd(section->mr))) {
         return;
     }
     ram_addr = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
-        + memory_region_section_addr(section, addr);
+        + addr;
     tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
 }
 #endif /* TARGET_HAS_ICE && !defined(CONFIG_USER_ONLY) */
commit b018ddf633f77195e9ae859c6d940a334e68879f
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 14:48:38 2013 +0200

    memory: dispatch unassigned accesses based on .valid.accepts
    
    This provides the basics for detecting accesses to unassigned memory
    as soon as they happen, and also for a simple implementation of
    address_space_access_valid.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index 785eeeb..c5100d6 100644
--- a/exec.c
+++ b/exec.c
@@ -1383,32 +1383,14 @@ ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
     return ram_addr;
 }
 
-static uint64_t unassigned_mem_read(void *opaque, hwaddr addr,
-                                    unsigned size)
+static bool unassigned_mem_accepts(void *opaque, hwaddr addr,
+                                   unsigned size, bool is_write)
 {
-#ifdef DEBUG_UNASSIGNED
-    printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
-#endif
-#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
-    cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, size);
-#endif
-    return 0;
-}
-
-static void unassigned_mem_write(void *opaque, hwaddr addr,
-                                 uint64_t val, unsigned size)
-{
-#ifdef DEBUG_UNASSIGNED
-    printf("Unassigned mem write " TARGET_FMT_plx " = 0x%"PRIx64"\n", addr, val);
-#endif
-#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
-    cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, size);
-#endif
+    return false;
 }
 
-static const MemoryRegionOps unassigned_mem_ops = {
-    .read = unassigned_mem_read,
-    .write = unassigned_mem_write,
+const MemoryRegionOps unassigned_mem_ops = {
+    .valid.accepts = unassigned_mem_accepts,
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
@@ -1442,9 +1424,15 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
         tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr);
 }
 
+static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
+                                 unsigned size, bool is_write)
+{
+    return is_write;
+}
+
 static const MemoryRegionOps notdirty_mem_ops = {
-    .read = unassigned_mem_read,
     .write = notdirty_mem_write,
+    .valid.accepts = notdirty_mem_accepts,
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
diff --git a/memory.c b/memory.c
index 99f046d..15da877 100644
--- a/memory.c
+++ b/memory.c
@@ -814,6 +814,29 @@ void memory_region_init(MemoryRegion *mr,
     mr->flush_coalesced_mmio = false;
 }
 
+static uint64_t unassigned_mem_read(void *opaque, hwaddr addr,
+                                    unsigned size)
+{
+#ifdef DEBUG_UNASSIGNED
+    printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
+#endif
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+    cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, size);
+#endif
+    return 0;
+}
+
+static void unassigned_mem_write(void *opaque, hwaddr addr,
+                                 uint64_t val, unsigned size)
+{
+#ifdef DEBUG_UNASSIGNED
+    printf("Unassigned mem write " TARGET_FMT_plx " = 0x%"PRIx64"\n", addr, val);
+#endif
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+    cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, size);
+#endif
+}
+
 static bool memory_region_access_valid(MemoryRegion *mr,
                                        hwaddr addr,
                                        unsigned size,
@@ -847,7 +870,7 @@ static uint64_t memory_region_dispatch_read1(MemoryRegion *mr,
     uint64_t data = 0;
 
     if (!memory_region_access_valid(mr, addr, size, false)) {
-        return -1U; /* FIXME: better signalling */
+        return unassigned_mem_read(mr, addr, size);
     }
 
     if (!mr->ops->read) {
@@ -898,7 +921,8 @@ static void memory_region_dispatch_write(MemoryRegion *mr,
                                          unsigned size)
 {
     if (!memory_region_access_valid(mr, addr, size, true)) {
-        return; /* FIXME: better signalling */
+        unassigned_mem_write(mr, addr, data, size);
+        return;
     }
 
     adjust_endianness(mr, &data, size);
commit bf8d5166395612b4e856fad57606eb0cff97ae2e
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 14:39:13 2013 +0200

    exec: do not use error_mem_read
    
    We will soon reach this case when doing (unaligned) accesses that
    span partly past the end of memory.  We do not want to crash in
    that case.
    
    unassigned_mem_ops and rom_mem_ops are now the same.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index 7e22980..785eeeb 100644
--- a/exec.c
+++ b/exec.c
@@ -1412,18 +1412,6 @@ static const MemoryRegionOps unassigned_mem_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static uint64_t error_mem_read(void *opaque, hwaddr addr,
-                               unsigned size)
-{
-    abort();
-}
-
-static const MemoryRegionOps rom_mem_ops = {
-    .read = error_mem_read,
-    .write = unassigned_mem_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
 static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
                                uint64_t val, unsigned size)
 {
@@ -1455,7 +1443,7 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
 }
 
 static const MemoryRegionOps notdirty_mem_ops = {
-    .read = error_mem_read,
+    .read = unassigned_mem_read,
     .write = notdirty_mem_write,
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
@@ -1676,7 +1664,7 @@ MemoryRegion *iotlb_to_region(hwaddr index)
 
 static void io_mem_init(void)
 {
-    memory_region_init_io(&io_mem_rom, &rom_mem_ops, NULL, "rom", UINT64_MAX);
+    memory_region_init_io(&io_mem_rom, &unassigned_mem_ops, NULL, "rom", UINT64_MAX);
     memory_region_init_io(&io_mem_unassigned, &unassigned_mem_ops, NULL,
                           "unassigned", UINT64_MAX);
     memory_region_init_io(&io_mem_notdirty, &notdirty_mem_ops, NULL,
commit 0844e007624acb6dbf45bfb232286ce9502b424e
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 14:37:28 2013 +0200

    exec: make io_mem_unassigned private
    
    There is no reason to avoid a recompile before accessing unassigned
    memory.  In the end it will be treated as MMIO anyway.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index 7728ea3..7e22980 100644
--- a/exec.c
+++ b/exec.c
@@ -66,8 +66,8 @@ AddressSpace address_space_io;
 AddressSpace address_space_memory;
 DMAContext dma_context_memory;
 
-MemoryRegion io_mem_rom, io_mem_unassigned, io_mem_notdirty;
-static MemoryRegion io_mem_subpage_ram;
+MemoryRegion io_mem_rom, io_mem_notdirty;
+static MemoryRegion io_mem_unassigned, io_mem_subpage_ram;
 
 #endif
 
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 1686b8f..e061e21 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -111,7 +111,6 @@ void cpu_physical_memory_write_rom(hwaddr addr,
                                    const uint8_t *buf, int len);
 
 extern struct MemoryRegion io_mem_rom;
-extern struct MemoryRegion io_mem_unassigned;
 extern struct MemoryRegion io_mem_notdirty;
 
 #endif
diff --git a/include/exec/softmmu_template.h b/include/exec/softmmu_template.h
index 4501dac..ca91fd0 100644
--- a/include/exec/softmmu_template.h
+++ b/include/exec/softmmu_template.h
@@ -68,10 +68,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
 
     physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
     env->mem_io_pc = retaddr;
-    if (mr != &io_mem_rom
-        && mr != &io_mem_unassigned
-        && mr != &io_mem_notdirty
-            && !can_do_io(env)) {
+    if (mr != &io_mem_rom && mr != &io_mem_notdirty && !can_do_io(env)) {
         cpu_io_recompile(env, retaddr);
     }
 
@@ -218,10 +215,7 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
     MemoryRegion *mr = iotlb_to_region(physaddr);
 
     physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
-    if (mr != &io_mem_rom
-        && mr != &io_mem_unassigned
-        && mr != &io_mem_notdirty
-            && !can_do_io(env)) {
+    if (mr != &io_mem_rom && mr != &io_mem_notdirty && !can_do_io(env)) {
         cpu_io_recompile(env, retaddr);
     }
 
commit 8f3e03cb73dce9eac207cfe0f37d87d6490421a0
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 16:45:30 2013 +0200

    cputlb: simplify tlb_set_page
    
    The same "if" condition is repeated twice.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/cputlb.c b/cputlb.c
index aba7e44..b56bc01 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -262,17 +262,14 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
 #endif
 
     address = vaddr;
-    if (!(memory_region_is_ram(section->mr) ||
-          memory_region_is_romd(section->mr))) {
-        /* IO memory case (romd handled later) */
+    if (!memory_region_is_ram(section->mr) && !memory_region_is_romd(section->mr)) {
+        /* IO memory case */
         address |= TLB_MMIO;
-    }
-    if (memory_region_is_ram(section->mr) ||
-        memory_region_is_romd(section->mr)) {
+        addend = 0;
+    } else {
+        /* TLB_MMIO for rom/romd handled below */
         addend = (uintptr_t)memory_region_get_ram_ptr(section->mr)
         + memory_region_section_addr(section, paddr);
-    } else {
-        addend = 0;
     }
 
     code_address = address;
commit ae4e43e80f3e1e65d096ebbc643eed9d763e1441
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 17:14:05 2013 +0200

    exec: drop useless #if
    
    This code is only compiled for softmmu targets.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index b720be5..7728ea3 100644
--- a/exec.c
+++ b/exec.c
@@ -1430,10 +1430,8 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
     int dirty_flags;
     dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
     if (!(dirty_flags & CODE_DIRTY_FLAG)) {
-#if !defined(CONFIG_USER_ONLY)
         tb_invalidate_phys_page_fast(ram_addr, size);
         dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
-#endif
     }
     switch (size) {
     case 1:
commit 2a8e7499093cd33a607ebd7c1cd591169aa68a3e
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 24 14:34:08 2013 +0200

    exec: eliminate io_mem_ram
    
    It is never used, the IOTLB always goes through io_mem_notdirty.
    
    In fact in softmmu_template.h, if it were, QEMU would crash just
    below the tests, as soon as io_mem_read/write dispatches to
    error_mem_read/write.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index 3a9ddcb..b720be5 100644
--- a/exec.c
+++ b/exec.c
@@ -66,7 +66,7 @@ AddressSpace address_space_io;
 AddressSpace address_space_memory;
 DMAContext dma_context_memory;
 
-MemoryRegion io_mem_ram, io_mem_rom, io_mem_unassigned, io_mem_notdirty;
+MemoryRegion io_mem_rom, io_mem_unassigned, io_mem_notdirty;
 static MemoryRegion io_mem_subpage_ram;
 
 #endif
@@ -200,8 +200,7 @@ MemoryRegionSection *phys_page_find(AddressSpaceDispatch *d, hwaddr index)
 
 bool memory_region_is_unassigned(MemoryRegion *mr)
 {
-    return mr != &io_mem_ram && mr != &io_mem_rom
-        && mr != &io_mem_notdirty && !mr->rom_device
+    return mr != &io_mem_rom && mr != &io_mem_notdirty && !mr->rom_device
         && mr != &io_mem_watch;
 }
 #endif
@@ -1419,18 +1418,6 @@ static uint64_t error_mem_read(void *opaque, hwaddr addr,
     abort();
 }
 
-static void error_mem_write(void *opaque, hwaddr addr,
-                            uint64_t value, unsigned size)
-{
-    abort();
-}
-
-static const MemoryRegionOps error_mem_ops = {
-    .read = error_mem_read,
-    .write = error_mem_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
 static const MemoryRegionOps rom_mem_ops = {
     .read = error_mem_read,
     .write = unassigned_mem_write,
@@ -1691,7 +1678,6 @@ MemoryRegion *iotlb_to_region(hwaddr index)
 
 static void io_mem_init(void)
 {
-    memory_region_init_io(&io_mem_ram, &error_mem_ops, NULL, "ram", UINT64_MAX);
     memory_region_init_io(&io_mem_rom, &rom_mem_ops, NULL, "rom", UINT64_MAX);
     memory_region_init_io(&io_mem_unassigned, &unassigned_mem_ops, NULL,
                           "unassigned", UINT64_MAX);
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index af5258d..1686b8f 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -110,7 +110,6 @@ void stq_phys(hwaddr addr, uint64_t val);
 void cpu_physical_memory_write_rom(hwaddr addr,
                                    const uint8_t *buf, int len);
 
-extern struct MemoryRegion io_mem_ram;
 extern struct MemoryRegion io_mem_rom;
 extern struct MemoryRegion io_mem_unassigned;
 extern struct MemoryRegion io_mem_notdirty;
diff --git a/include/exec/softmmu_template.h b/include/exec/softmmu_template.h
index b219191..4501dac 100644
--- a/include/exec/softmmu_template.h
+++ b/include/exec/softmmu_template.h
@@ -68,7 +68,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
 
     physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
     env->mem_io_pc = retaddr;
-    if (mr != &io_mem_ram && mr != &io_mem_rom
+    if (mr != &io_mem_rom
         && mr != &io_mem_unassigned
         && mr != &io_mem_notdirty
             && !can_do_io(env)) {
@@ -218,7 +218,7 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
     MemoryRegion *mr = iotlb_to_region(physaddr);
 
     physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
-    if (mr != &io_mem_ram && mr != &io_mem_rom
+    if (mr != &io_mem_rom
         && mr != &io_mem_unassigned
         && mr != &io_mem_notdirty
             && !can_do_io(env)) {
commit 87d23f78aa79b72da022afda358bbc8a8509ca70
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Tue May 28 13:20:23 2013 +0300

    virtio-pci: drop unused wmb macro
    
    The implementation is wrong for kvm, and it's unused anyway.
    Drop it.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Message-id: 20130528102023.GA30055 at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 70d2c6b..444b71a 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -89,12 +89,6 @@
 /* Flags track per-device state like workarounds for quirks in older guests. */
 #define VIRTIO_PCI_FLAG_BUS_MASTER_BUG  (1 << 0)
 
-/* QEMU doesn't strictly need write barriers since everything runs in
- * lock-step.  We'll leave the calls to wmb() in though to make it obvious for
- * KVM or if kqemu gets SMP support.
- */
-#define wmb() do { } while (0)
-
 /* HACK for virtio to determine if it's running a big endian guest */
 bool virtio_is_big_endian(void);
 
commit 04129606170ec9011d4952b4f22c368679bedbf9
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Mon May 27 15:28:51 2013 +0200

    tests: set MALLOC_PERTURB_ to expose memory bugs
    
    glibc wipes malloc(3) memory when the MALLOC_PERTURB_ environment
    variable is set.  The value of the environment variable determines the
    bit pattern used to wipe memory.  For more information, see
    http://udrepper.livejournal.com/11429.html.
    
    Set MALLOC_PERTURB_ for gtester and qemu-iotests.  Note we pick a random
    value from 1 to 255 to expose more bugs.  If you need to reproduce a
    crash use 'show environment' in gdb to extract the MALLOC_PERTURB_
    value from a core dump.
    
    Both make check and qemu-iotests pass with MALLOC_PERTURB_ enabled.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Message-id: 1369661331-28041-1-git-send-email-stefanha at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/tests/Makefile b/tests/Makefile
index a307d5a..c107489 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -171,6 +171,7 @@ GCOV_OPTIONS = -n $(if $(V),-f,)
 $(patsubst %, check-qtest-%, $(QTEST_TARGETS)): check-qtest-%: $(check-qtest-y)
 	$(if $(CONFIG_GCOV), at rm -f *.gcda */*.gcda */*/*.gcda */*/*/*.gcda,)
 	$(call quiet-command,QTEST_QEMU_BINARY=$*-softmmu/qemu-system-$* \
+		MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$((RANDOM % 255 + 1))} \
 		gtester $(GTESTER_OPTIONS) -m=$(SPEED) $(check-qtest-$*-y),"GTESTER $@")
 	$(if $(CONFIG_GCOV), at for f in $(gcov-files-$*-y); do \
 	  echo Gcov report for $$f:;\
@@ -180,7 +181,9 @@ $(patsubst %, check-qtest-%, $(QTEST_TARGETS)): check-qtest-%: $(check-qtest-y)
 .PHONY: $(patsubst %, check-%, $(check-unit-y))
 $(patsubst %, check-%, $(check-unit-y)): check-%: %
 	$(if $(CONFIG_GCOV), at rm -f *.gcda */*.gcda */*/*.gcda */*/*/*.gcda,)
-	$(call quiet-command,gtester $(GTESTER_OPTIONS) -m=$(SPEED) $*,"GTESTER $*")
+	$(call quiet-command, \
+		MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$((RANDOM % 255 + 1))} \
+		gtester $(GTESTER_OPTIONS) -m=$(SPEED) $*,"GTESTER $*")
 	$(if $(CONFIG_GCOV), at for f in $(gcov-files-$(subst tests/,,$*)-y); do \
 	  echo Gcov report for $$f:;\
 	  $(GCOV) $(GCOV_OPTIONS) $$f -o `dirname $$f`; \
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index 432732c..74628ae 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -214,7 +214,8 @@ do
 	start=`_wallclock`
 	$timestamp && echo -n "	["`date "+%T"`"]"
 	[ ! -x $seq ] && chmod u+x $seq # ensure we can run it
-	./$seq >$tmp.out 2>&1
+	MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \
+		./$seq >$tmp.out 2>&1
 	sts=$?
 	$timestamp && _timestamp
 	stop=`_wallclock`
commit dafb82e0fc89b631d25f8def649fbfd14fec3db2
Author: Jordan Justen <jordan.l.justen at intel.com>
Date:   Wed May 29 01:27:27 2013 -0700

    pc_sysfw: allow flash (-pflash) memory to be used with KVM
    
    When pc-sysfw.rom_only == 0, flash memory will be
    usable with kvm. In order to enable flash memory mode,
    a pflash device must be created. (For example, by
    using the -pflash command line parameter.)
    
    Usage of a flash memory device with kvm requires
    KVM_CAP_READONLY_MEM, and kvm will abort if
    a flash device is used with an older kvm which does
    not support this capability.
    
    If a flash device is not used, then qemu/kvm will
    operate in the original rom-mode.
    
    Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 1369816047-16384-5-git-send-email-jordan.l.justen at intel.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/block/pc_sysfw.c b/hw/block/pc_sysfw.c
index ea1a355..412d1b0 100644
--- a/hw/block/pc_sysfw.c
+++ b/hw/block/pc_sysfw.c
@@ -220,28 +220,40 @@ void pc_system_firmware_init(MemoryRegion *rom_memory)
 
     qdev_init_nofail(DEVICE(sysfw_dev));
 
-    if (sysfw_dev->rom_only) {
-        old_pc_system_rom_init(rom_memory, sysfw_dev->isapc_ram_fw);
-        return;
-    }
-
     pflash_drv = drive_get(IF_PFLASH, 0, 0);
 
-    /* Currently KVM cannot execute from device memory.
-       Use old rom based firmware initialization for KVM. */
-    /*
-     * This is a Bad Idea, because it makes enabling/disabling KVM
-     * guest-visible.  Let's fix it for real in QEMU 1.6.
-     */
-    if (kvm_enabled()) {
-        if (pflash_drv != NULL) {
-            fprintf(stderr, "qemu: pflash cannot be used with kvm enabled\n");
-            exit(1);
-        } else {
-            sysfw_dev->rom_only = 1;
-            old_pc_system_rom_init(rom_memory, sysfw_dev->isapc_ram_fw);
-            return;
+    if (pc_sysfw_flash_vs_rom_bug_compatible) {
+        /*
+         * This is a Bad Idea, because it makes enabling/disabling KVM
+         * guest-visible.  Do it only in bug-compatibility mode.
+         */
+        if (kvm_enabled()) {
+            if (pflash_drv != NULL) {
+                fprintf(stderr, "qemu: pflash cannot be used with kvm enabled\n");
+                exit(1);
+            } else {
+                /* In old pc_sysfw_flash_vs_rom_bug_compatible mode, we assume
+                 * that KVM cannot execute from device memory. In this case, we
+                 * use old rom based firmware initialization for KVM. But, since
+                 * this is different from non-kvm mode, this behavior is
+                 * undesirable */
+                sysfw_dev->rom_only = 1;
+            }
         }
+    } else if (pflash_drv == NULL) {
+        /* When a pflash drive is not found, use rom-mode */
+        sysfw_dev->rom_only = 1;
+    } else if (kvm_enabled() && !kvm_readonly_mem_enabled()) {
+        /* Older KVM cannot execute from device memory. So, flash memory
+         * cannot be used unless the readonly memory kvm capability is present. */
+        fprintf(stderr, "qemu: pflash with kvm requires KVM readonly memory support\n");
+        exit(1);
+    }
+
+    /* If rom-mode is active, use the old pc system rom initialization. */
+    if (sysfw_dev->rom_only) {
+        old_pc_system_rom_init(rom_memory, sysfw_dev->isapc_ram_fw);
+        return;
     }
 
     /* If a pflash drive is not found, then create one using
commit 235e8982ad393e5611cb892df54881c872eea9e1
Author: Jordan Justen <jordan.l.justen at intel.com>
Date:   Wed May 29 01:27:26 2013 -0700

    kvm: support using KVM_MEM_READONLY flag for regions
    
    For readonly memory regions and rom devices in romd_mode,
    we make use of the KVM_MEM_READONLY. A slot that uses
    KVM_MEM_READONLY can be read from and code can execute from the
    region, but writes will exit to qemu.
    
    For rom devices with !romd_mode, we force the slot to be
    removed so reads or writes to the region will exit to qemu.
    (Note that a memory region in this state is not executable
    within kvm.)
    
    v7:
     * Update for readable => romd_mode rename (5f9a5ea1)
    
    Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
    Reviewed-by: Xiao Guangrong <xiaoguangrong at linux.vnet.ibm.com> (v4)
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com> (v5)
    Message-id: 1369816047-16384-4-git-send-email-jordan.l.justen at intel.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/kvm-all.c b/kvm-all.c
index 327ae12..8e7bbf8 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -201,12 +201,18 @@ static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot)
 
     mem.slot = slot->slot;
     mem.guest_phys_addr = slot->start_addr;
-    mem.memory_size = slot->memory_size;
     mem.userspace_addr = (unsigned long)slot->ram;
     mem.flags = slot->flags;
     if (s->migration_log) {
         mem.flags |= KVM_MEM_LOG_DIRTY_PAGES;
     }
+    if (mem.flags & KVM_MEM_READONLY) {
+        /* Set the slot size to 0 before setting the slot to the desired
+         * value. This is needed based on KVM commit 75d61fbc. */
+        mem.memory_size = 0;
+        kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
+    }
+    mem.memory_size = slot->memory_size;
     return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
 }
 
@@ -268,9 +274,14 @@ err:
  * dirty pages logging control
  */
 
-static int kvm_mem_flags(KVMState *s, bool log_dirty)
+static int kvm_mem_flags(KVMState *s, bool log_dirty, bool readonly)
 {
-    return log_dirty ? KVM_MEM_LOG_DIRTY_PAGES : 0;
+    int flags = 0;
+    flags = log_dirty ? KVM_MEM_LOG_DIRTY_PAGES : 0;
+    if (readonly && kvm_readonly_mem_allowed) {
+        flags |= KVM_MEM_READONLY;
+    }
+    return flags;
 }
 
 static int kvm_slot_dirty_pages_log_change(KVMSlot *mem, bool log_dirty)
@@ -281,7 +292,7 @@ static int kvm_slot_dirty_pages_log_change(KVMSlot *mem, bool log_dirty)
 
     old_flags = mem->flags;
 
-    flags = (mem->flags & ~mask) | kvm_mem_flags(s, log_dirty);
+    flags = (mem->flags & ~mask) | kvm_mem_flags(s, log_dirty, false);
     mem->flags = flags;
 
     /* If nothing changed effectively, no need to issue ioctl */
@@ -619,6 +630,8 @@ static void kvm_set_phys_mem(MemoryRegionSection *section, bool add)
     int err;
     MemoryRegion *mr = section->mr;
     bool log_dirty = memory_region_is_logging(mr);
+    bool writeable = !mr->readonly && !mr->rom_device;
+    bool readonly_flag = mr->readonly || memory_region_is_romd(mr);
     hwaddr start_addr = section->offset_within_address_space;
     ram_addr_t size = section->size;
     void *ram = NULL;
@@ -638,7 +651,13 @@ static void kvm_set_phys_mem(MemoryRegionSection *section, bool add)
     }
 
     if (!memory_region_is_ram(mr)) {
-        return;
+        if (writeable || !kvm_readonly_mem_allowed) {
+            return;
+        } else if (!mr->romd_mode) {
+            /* If the memory device is not in romd_mode, then we actually want
+             * to remove the kvm memory slot so all accesses will trap. */
+            add = false;
+        }
     }
 
     ram = memory_region_get_ram_ptr(mr) + section->offset_within_region + delta;
@@ -687,7 +706,7 @@ static void kvm_set_phys_mem(MemoryRegionSection *section, bool add)
             mem->memory_size = old.memory_size;
             mem->start_addr = old.start_addr;
             mem->ram = old.ram;
-            mem->flags = kvm_mem_flags(s, log_dirty);
+            mem->flags = kvm_mem_flags(s, log_dirty, readonly_flag);
 
             err = kvm_set_user_memory_region(s, mem);
             if (err) {
@@ -708,7 +727,7 @@ static void kvm_set_phys_mem(MemoryRegionSection *section, bool add)
             mem->memory_size = start_addr - old.start_addr;
             mem->start_addr = old.start_addr;
             mem->ram = old.ram;
-            mem->flags =  kvm_mem_flags(s, log_dirty);
+            mem->flags =  kvm_mem_flags(s, log_dirty, readonly_flag);
 
             err = kvm_set_user_memory_region(s, mem);
             if (err) {
@@ -732,7 +751,7 @@ static void kvm_set_phys_mem(MemoryRegionSection *section, bool add)
             size_delta = mem->start_addr - old.start_addr;
             mem->memory_size = old.memory_size - size_delta;
             mem->ram = old.ram + size_delta;
-            mem->flags = kvm_mem_flags(s, log_dirty);
+            mem->flags = kvm_mem_flags(s, log_dirty, readonly_flag);
 
             err = kvm_set_user_memory_region(s, mem);
             if (err) {
@@ -754,7 +773,7 @@ static void kvm_set_phys_mem(MemoryRegionSection *section, bool add)
     mem->memory_size = size;
     mem->start_addr = start_addr;
     mem->ram = ram;
-    mem->flags = kvm_mem_flags(s, log_dirty);
+    mem->flags = kvm_mem_flags(s, log_dirty, readonly_flag);
 
     err = kvm_set_user_memory_region(s, mem);
     if (err) {
commit df9c8b758a04825e23f82427001028342b92d0cf
Author: Jordan Justen <jordan.l.justen at intel.com>
Date:   Wed May 29 01:27:25 2013 -0700

    kvm: add kvm_readonly_mem_enabled
    
    Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 1369816047-16384-3-git-send-email-jordan.l.justen at intel.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 08284ef..8b19322 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -45,6 +45,7 @@ extern bool kvm_async_interrupts_allowed;
 extern bool kvm_irqfds_allowed;
 extern bool kvm_msi_via_irqfd_allowed;
 extern bool kvm_gsi_routing_allowed;
+extern bool kvm_readonly_mem_allowed;
 
 #if defined CONFIG_KVM || !defined NEED_CPU_H
 #define kvm_enabled()           (kvm_allowed)
@@ -97,6 +98,14 @@ extern bool kvm_gsi_routing_allowed;
  */
 #define kvm_gsi_routing_enabled() (kvm_gsi_routing_allowed)
 
+/**
+ * kvm_readonly_mem_enabled:
+ *
+ * Returns: true if KVM readonly memory is enabled (ie the kernel
+ * supports it and we're running in a configuration that permits it).
+ */
+#define kvm_readonly_mem_enabled() (kvm_readonly_mem_allowed)
+
 #else
 #define kvm_enabled()           (0)
 #define kvm_irqchip_in_kernel() (false)
@@ -104,6 +113,7 @@ extern bool kvm_gsi_routing_allowed;
 #define kvm_irqfds_enabled() (false)
 #define kvm_msi_via_irqfd_enabled() (false)
 #define kvm_gsi_routing_allowed() (false)
+#define kvm_readonly_mem_enabled() (false)
 #endif
 
 struct kvm_run;
diff --git a/kvm-all.c b/kvm-all.c
index 8222729..327ae12 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -111,6 +111,7 @@ bool kvm_irqfds_allowed;
 bool kvm_msi_via_irqfd_allowed;
 bool kvm_gsi_routing_allowed;
 bool kvm_allowed;
+bool kvm_readonly_mem_allowed;
 
 static const KVMCapabilityInfo kvm_required_capabilites[] = {
     KVM_CAP_INFO(USER_MEMORY),
@@ -1425,6 +1426,11 @@ int kvm_init(void)
         s->irq_set_ioctl = KVM_IRQ_LINE_STATUS;
     }
 
+#ifdef KVM_CAP_READONLY_MEM
+    kvm_readonly_mem_allowed =
+        (kvm_check_extension(s, KVM_CAP_READONLY_MEM) > 0);
+#endif
+
     ret = kvm_arch_init(s);
     if (ret < 0) {
         goto err;
diff --git a/kvm-stub.c b/kvm-stub.c
index b2c8f9b..22eaff0 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -26,6 +26,7 @@ bool kvm_irqfds_allowed;
 bool kvm_msi_via_irqfd_allowed;
 bool kvm_gsi_routing_allowed;
 bool kvm_allowed;
+bool kvm_readonly_mem_allowed;
 
 int kvm_init_vcpu(CPUState *cpu)
 {
commit dade922f357c709c02eed2e1b1891453896756dd
Author: Jordan Justen <jordan.l.justen at intel.com>
Date:   Wed May 29 01:27:24 2013 -0700

    isapc: Fix non-KVM qemu boot (read/write memory for isapc BIOS)
    
    The isapc machine with seabios currently requires the BIOS region
    to be read/write memory rather than read-only memory.
    
    KVM currently cannot support the BIOS as a ROM region, but qemu
    in non-KVM mode can. Based on this, isapc machine currently only
    works with KVM.
    
    To work-around this isapc issue, this change avoids marking the
    BIOS as readonly for isapc.
    
    This change also will allow KVM to start supporting ROM mode
    via KVM_CAP_READONLY_MEM.
    
    Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 1369816047-16384-2-git-send-email-jordan.l.justen at intel.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/block/pc_sysfw.c b/hw/block/pc_sysfw.c
index 4f17668..ea1a355 100644
--- a/hw/block/pc_sysfw.c
+++ b/hw/block/pc_sysfw.c
@@ -39,6 +39,7 @@
 typedef struct PcSysFwDevice {
     SysBusDevice busdev;
     uint8_t rom_only;
+    uint8_t isapc_ram_fw;
 } PcSysFwDevice;
 
 static void pc_isa_bios_init(MemoryRegion *rom_memory,
@@ -139,7 +140,7 @@ static void pc_system_flash_init(MemoryRegion *rom_memory,
     pc_isa_bios_init(rom_memory, flash_mem, size);
 }
 
-static void old_pc_system_rom_init(MemoryRegion *rom_memory)
+static void old_pc_system_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
 {
     char *filename;
     MemoryRegion *bios, *isa_bios;
@@ -163,7 +164,9 @@ static void old_pc_system_rom_init(MemoryRegion *rom_memory)
     bios = g_malloc(sizeof(*bios));
     memory_region_init_ram(bios, "pc.bios", bios_size);
     vmstate_register_ram_global(bios);
-    memory_region_set_readonly(bios, true);
+    if (!isapc_ram_fw) {
+        memory_region_set_readonly(bios, true);
+    }
     ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
     if (ret != 0) {
     bios_error:
@@ -186,7 +189,9 @@ static void old_pc_system_rom_init(MemoryRegion *rom_memory)
                                         0x100000 - isa_bios_size,
                                         isa_bios,
                                         1);
-    memory_region_set_readonly(isa_bios, true);
+    if (!isapc_ram_fw) {
+        memory_region_set_readonly(isa_bios, true);
+    }
 
     /* map all the bios at the top of memory */
     memory_region_add_subregion(rom_memory,
@@ -216,7 +221,7 @@ void pc_system_firmware_init(MemoryRegion *rom_memory)
     qdev_init_nofail(DEVICE(sysfw_dev));
 
     if (sysfw_dev->rom_only) {
-        old_pc_system_rom_init(rom_memory);
+        old_pc_system_rom_init(rom_memory, sysfw_dev->isapc_ram_fw);
         return;
     }
 
@@ -234,7 +239,7 @@ void pc_system_firmware_init(MemoryRegion *rom_memory)
             exit(1);
         } else {
             sysfw_dev->rom_only = 1;
-            old_pc_system_rom_init(rom_memory);
+            old_pc_system_rom_init(rom_memory, sysfw_dev->isapc_ram_fw);
             return;
         }
     }
@@ -255,6 +260,7 @@ void pc_system_firmware_init(MemoryRegion *rom_memory)
 }
 
 static Property pcsysfw_properties[] = {
+    DEFINE_PROP_UINT8("isapc_ram_fw", PcSysFwDevice, isapc_ram_fw, 0),
     DEFINE_PROP_UINT8("rom_only", PcSysFwDevice, rom_only, 0),
     DEFINE_PROP_END_OF_LIST(),
 };
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 43ab480..530b6ab 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -713,6 +713,11 @@ static QEMUMachine isapc_machine = {
             .property = "rom_only",
             .value    = stringify(1),
         },
+        {
+            .driver   = "pc-sysfw",
+            .property = "isapc_ram_fw",
+            .value    = stringify(1),
+        },
         { /* end of list */ }
     },
     DEFAULT_MACHINE_OPTIONS,
commit 338ea905e948613607c98346e127fc9472c57f0d
Merge: 1afd566 db431f6
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Wed May 29 08:13:20 2013 -0500

    Merge remote-tracking branch 'aneesh/for-upstream' into staging
    
    # By Aneesh Kumar K.V (3) and Gabriel de Perthuis (1)
    # Via Aneesh Kumar K.V
    * aneesh/for-upstream:
      hw/9pfs: Be robust against paths without FS_IOC_GETVERSION
      hw/9pfs: Use O_NOFOLLOW when opening files on server
      hw/9pfs: use O_NOFOLLOW for mapped readlink operation
      hw/9pfs: Fix segfault with 9p2000.u
    
    Message-id: 87zjvevx4s.fsf at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 1afd566ce921493a13b3878662b5320aab7645d0
Merge: 46a352a 2ba9de6
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Wed May 29 08:13:09 2013 -0500

    Merge remote-tracking branch 'afaerber-or/cocoa-for-upstream' into staging
    
    # By Peter Maydell
    # Via Andreas Färber
    * afaerber-or/cocoa-for-upstream:
      cocoa: Avoid deprecated NSOpenPanel beginSheetForDirectory
      cocoa: Avoid deprecated NSOpenPanel filename method
      cocoa: Avoid deprecated CPS* functions
      cocoa: Fix leaks of NSScreen and NSConcreteMapTable

commit 46a352a7d7a47b3733ae76c0a0906d6934f81fc0
Merge: c199707 60d9538
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Wed May 29 08:12:53 2013 -0500

    Merge remote-tracking branch 'kraxel/chardev.6' into staging
    
    # By Gerd Hoffmann
    # Via Gerd Hoffmann
    * kraxel/chardev.6:
      chardev: fix "info chardev" output
      Revert "chardev: Get filename for new qapi backend"
    
    Message-id: 1369722844-24345-1-git-send-email-kraxel at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit c199707ad0dcbb4a72e7435551c7f23b9606a063
Merge: 6a4e177 6683d7b
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Wed May 29 08:12:25 2013 -0500

    Merge remote-tracking branch 'kraxel/seabios-1.7.2.2' into staging
    
    # By Gerd Hoffmann
    # Via Gerd Hoffmann
    * kraxel/seabios-1.7.2.2:
      update seabios to release 1.7.2.2
      Revert "roms: switch oldnoconfig to olddefconfig"
    
    Message-id: 1369736932-16627-1-git-send-email-kraxel at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 2ba9de6ed0455f5c55e4fb1841e1597204535430
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Apr 22 10:29:49 2013 +0000

    cocoa: Avoid deprecated NSOpenPanel beginSheetForDirectory
    
    In MacOSX 10.6 and above the NSOpenPanel beginSheetForDirectory
    method is deprecated. Use the preferred replacements instead.
    We retain the original code for use on earlier MacOSX versions
    because the replacement methods don't exist before 10.6.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/ui/cocoa.m b/ui/cocoa.m
index bb59511..be49179 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -35,6 +35,9 @@
 #ifndef MAC_OS_X_VERSION_10_5
 #define MAC_OS_X_VERSION_10_5 1050
 #endif
+#ifndef MAC_OS_X_VERSION_10_6
+#define MAC_OS_X_VERSION_10_6 1060
+#endif
 
 
 //#define DEBUG
@@ -771,9 +774,20 @@ QemuCocoaView *cocoaView;
         NSOpenPanel *op = [[NSOpenPanel alloc] init];
         [op setPrompt:@"Boot image"];
         [op setMessage:@"Select the disk image you want to boot.\n\nHit the \"Cancel\" button to quit"];
-        [op beginSheetForDirectory:nil file:nil types:[NSArray arrayWithObjects:@"img",@"iso",@"dmg",@"qcow",@"cow",@"cloop",@"vmdk",nil]
+        NSArray *filetypes = [NSArray arrayWithObjects:@"img", @"iso", @"dmg",
+                                 @"qcow", @"cow", @"cloop", @"vmdk", nil];
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
+        [op setAllowedFileTypes:filetypes];
+        [op beginSheetModalForWindow:normalWindow
+            completionHandler:^(NSInteger returnCode)
+            { [self openPanelDidEnd:op
+                  returnCode:returnCode contextInfo:NULL ]; } ];
+#else
+        // Compatibility code for pre-10.6, using deprecated method
+        [op beginSheetForDirectory:nil file:nil types:filetypes
               modalForWindow:normalWindow modalDelegate:self
               didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL];
+#endif
     } else {
         // or launch QEMU, with the global args
         [self startEmulationWithArgc:gArgc argv:(char **)gArgv];
commit 8bb3f1e3742ca8d26af7156e14068435437918a1
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Apr 22 10:29:48 2013 +0000

    cocoa: Avoid deprecated NSOpenPanel filename method
    
    Avoid the NSOpenPanel filename method (deprecated in MacOSX 10.6)
    in favour of using the URL method and extracting the path from the
    resulting NSUrl object.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/ui/cocoa.m b/ui/cocoa.m
index ec09728..bb59511 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -810,7 +810,7 @@ QemuCocoaView *cocoaView;
         exit(0);
     } else if(returnCode == NSOKButton) {
         const char *bin = "qemu";
-        char *img = (char*)[ [ sheet filename ] cStringUsingEncoding:NSASCIIStringEncoding];
+        char *img = (char*)[ [ [ sheet URL ] path ] cStringUsingEncoding:NSASCIIStringEncoding];
 
         char **argv = (char**)malloc( sizeof(char*)*3 );
 
commit 42a5dfe75f455fe7f3619ce44b7eb025ba631ee8
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Apr 22 10:29:47 2013 +0000

    cocoa: Avoid deprecated CPS* functions
    
    The functions CPSGetCurrentProcess and CPSEnableForegroundOperation
    are deprecated in newer versions of MacOSX and cause warning messages
    to be logged to the system log. Instead, use the new preferred method
    of promoting our console process up to a graphical app with menubar
    and Dock icon, which is TransformProcessType. (This function came
    in with MacOSX 10.3, so there's no need to retain the old method as
    we don't support anything earlier than 10.3 anyway.)
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 5d7a1e0..ec09728 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -851,22 +851,10 @@ QemuCocoaView *cocoaView;
 
 
 
-// Dock Connection
-typedef struct CPSProcessSerNum
-{
-        UInt32                lo;
-        UInt32                hi;
-} CPSProcessSerNum;
-
-OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
-OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
-OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
-
 int main (int argc, const char * argv[]) {
 
     gArgc = argc;
     gArgv = (char **)argv;
-    CPSProcessSerNum PSN;
     int i;
 
     /* In case we don't need to display a window, let's not do that */
@@ -890,12 +878,13 @@ int main (int argc, const char * argv[]) {
     }
 
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-    [NSApplication sharedApplication];
 
-    if (!CPSGetCurrentProcess(&PSN))
-        if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
-            if (!CPSSetFrontProcess(&PSN))
-                [NSApplication sharedApplication];
+    // Pull this console process up to being a fully-fledged graphical
+    // app with a menubar and Dock icon
+    ProcessSerialNumber psn = { 0, kCurrentProcess };
+    TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+
+    [NSApplication sharedApplication];
 
     // Add menus
     NSMenu      *menu;
commit 6e657e64cdc478461c1e6a5e81c6d23115664326
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Apr 22 10:29:46 2013 +0000

    cocoa: Fix leaks of NSScreen and NSConcreteMapTable
    
    On MacOSX 10.8 QEMU provokes system log messages:
    11/03/2013 17:03:29.998 qemu-system-arm[42586]: objc[42586]: Object
    0x7ffbf9c2f3b0 of class NSScreen autoreleased with no pool in place - just
    leaking - break on objc_autoreleaseNoPool() to debug
    
    11/03/2013 17:03:29.999 qemu-system-arm[42586]: objc[42586]: Object
    0x7ffbf9c3a010 of class NSConcreteMapTable autoreleased with no pool in
    place - just leaking - break on objc_autoreleaseNoPool() to debug
    
    This is because we call back into Cocoa from threads other than
    the UI thread (specifically from the CPU thread). Since we created
    these threads via the POSIX API rather than NSThread, they don't have
    automatically created autorelease pools. Guard all the functions where
    QEMU can call back into the Cocoa UI code with autorelease pools
    so that we don't leak any Cocoa objects.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 1971d9c..5d7a1e0 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -960,6 +960,8 @@ int main (int argc, const char * argv[]) {
 static void cocoa_update(DisplayChangeListener *dcl,
                          int x, int y, int w, int h)
 {
+    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
     COCOA_DEBUG("qemu_cocoa: cocoa_update\n");
 
     NSRect rect;
@@ -973,18 +975,24 @@ static void cocoa_update(DisplayChangeListener *dcl,
             h * [cocoaView cdy]);
     }
     [cocoaView setNeedsDisplayInRect:rect];
+
+    [pool release];
 }
 
 static void cocoa_switch(DisplayChangeListener *dcl,
                          DisplaySurface *surface)
 {
-    COCOA_DEBUG("qemu_cocoa: cocoa_resize\n");
+    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
+    COCOA_DEBUG("qemu_cocoa: cocoa_switch\n");
     [cocoaView switchSurface:surface];
+    [pool release];
 }
 
 static void cocoa_refresh(DisplayChangeListener *dcl)
 {
+    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
     COCOA_DEBUG("qemu_cocoa: cocoa_refresh\n");
 
     if (kbd_mouse_is_absolute()) {
@@ -1007,6 +1015,7 @@ static void cocoa_refresh(DisplayChangeListener *dcl)
         }
     } while(event != nil);
     graphic_hw_update(NULL);
+    [pool release];
 }
 
 static void cocoa_cleanup(void)
commit 6683d7bc2759e9da8b5c4907a9de85d500933ffb
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Tue May 28 12:17:50 2013 +0200

    update seabios to release 1.7.2.2
    
    git shortlog from 1.7.2.1
    
    Asias He (2):
          virtio-scsi: Pack struct virtio_scsi_{req_cmd,resp_cmd}
          virtio-scsi: Set _DRIVER_OK flag before scsi target scanning
    
    Kevin O'Connor (1):
          Cache boot-fail-wait to avoid romfile access after POST.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin
index ec9eeb1..c2a19b8 100644
Binary files a/pc-bios/bios.bin and b/pc-bios/bios.bin differ
diff --git a/roms/seabios b/roms/seabios
index 88cb66e..d4f7d90 160000
--- a/roms/seabios
+++ b/roms/seabios
@@ -1 +1 @@
-Subproject commit 88cb66ea542906ffff8a80ef397b9e3adbb33116
+Subproject commit d4f7d90f47462b4e8836899adc5060fbde5253e9
commit 19cd090e17b293b49eec59346df94a668f5d2438
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Tue May 28 12:09:41 2013 +0200

    Revert "roms: switch oldnoconfig to olddefconfig"
    
    This reverts commit a5519b42cfd6c00e9f8b31c5aad7682e7a9f1181.
    
    Breaks "make bios" in roms/ as the kconfig version in seabios doesn't
    support olddefconfig.  Must have been be totally untested.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/roms/configure-seabios.sh b/roms/configure-seabios.sh
index 4bb6c2b..98f59a2 100755
--- a/roms/configure-seabios.sh
+++ b/roms/configure-seabios.sh
@@ -2,4 +2,4 @@
 config="$1"
 make -C seabios clean distclean
 cp "$config" seabios/.config
-make -C seabios olddefconfig
+make -C seabios oldnoconfig
commit db431f6adc881a0758512cd765b3108209013512
Author: Gabriel de Perthuis <g2p.code at gmail.com>
Date:   Fri May 10 19:53:28 2013 +0200

    hw/9pfs: Be robust against paths without FS_IOC_GETVERSION
    
    9P optionally uses the FS_IOC_GETVERSION ioctl to get information about
    a file's version (sometimes called generation number).
    
    The code checks for supported filesystems at mount time, but some paths
    may come from other mounted filesystems.
    
    Change it to treat unsupported paths the same as unsupported
    filesystems, returning 0 in both cases.
    
    Note: ENOTTY is the error code for an unsupported ioctl.
    
    This fix allows booting a linux kernel with the same / filesystem as the
    host; otherwise the boot fails when mounting devtmpfs.
    
    Signed-off-by: Gabriel de Perthuis <g2p.code at gmail.com>
    Reviewed-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
index 2efebf3..194c130 100644
--- a/hw/9pfs/cofile.c
+++ b/hw/9pfs/cofile.c
@@ -38,6 +38,10 @@ int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode,
             });
         v9fs_path_unlock(s);
     }
+    /* The ioctl may not be supported depending on the path */
+    if (err == -ENOTTY) {
+        err = 0;
+    }
     return err;
 }
 
commit 0ceb092e35f9d8793d64d86194ec9463718dffa3
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Mon May 20 19:43:15 2013 +0530

    hw/9pfs: Use O_NOFOLLOW when opening files on server
    
    9p server should never follow a symlink. So use O_NOFOLLOW with all open
    syscall
    
    Tested-by: "M. Mohan Kumar" <mohan at in.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index 87aa75d..fc93e9e 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -59,6 +59,33 @@ static const char *local_mapped_attr_path(FsContext *ctx,
     return buffer;
 }
 
+static FILE *local_fopen(const char *path, const char *mode)
+{
+    int fd, o_mode = 0;
+    FILE *fp;
+    int flags = O_NOFOLLOW;
+    /*
+     * only supports two modes
+     */
+    if (mode[0] == 'r') {
+        flags |= O_RDONLY;
+    } else if (mode[0] == 'w') {
+        flags |= O_WRONLY | O_TRUNC | O_CREAT;
+        o_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+    } else {
+        return NULL;
+    }
+    fd = open(path, flags, o_mode);
+    if (fd == -1) {
+        return NULL;
+    }
+    fp = fdopen(fd, mode);
+    if (!fp) {
+        close(fd);
+    }
+    return fp;
+}
+
 #define ATTR_MAX 100
 static void local_mapped_file_attr(FsContext *ctx, const char *path,
                                    struct stat *stbuf)
@@ -68,7 +95,7 @@ static void local_mapped_file_attr(FsContext *ctx, const char *path,
     char attr_path[PATH_MAX];
 
     local_mapped_attr_path(ctx, path, attr_path);
-    fp = fopen(attr_path, "r");
+    fp = local_fopen(attr_path, "r");
     if (!fp) {
         return;
     }
@@ -152,7 +179,7 @@ static int local_set_mapped_file_attr(FsContext *ctx,
     char attr_path[PATH_MAX];
     int uid = -1, gid = -1, mode = -1, rdev = -1;
 
-    fp = fopen(local_mapped_attr_path(ctx, path, attr_path), "r");
+    fp = local_fopen(local_mapped_attr_path(ctx, path, attr_path), "r");
     if (!fp) {
         goto create_map_file;
     }
@@ -179,7 +206,7 @@ create_map_file:
     }
 
 update_map_file:
-    fp = fopen(attr_path, "w");
+    fp = local_fopen(attr_path, "w");
     if (!fp) {
         ret = -1;
         goto err_out;
@@ -316,7 +343,7 @@ static int local_open(FsContext *ctx, V9fsPath *fs_path,
     char buffer[PATH_MAX];
     char *path = fs_path->data;
 
-    fs->fd = open(rpath(ctx, path, buffer), flags);
+    fs->fd = open(rpath(ctx, path, buffer), flags | O_NOFOLLOW);
     return fs->fd;
 }
 
@@ -601,6 +628,11 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
     V9fsString fullname;
     char buffer[PATH_MAX];
 
+    /*
+     * Mark all the open to not follow symlinks
+     */
+    flags |= O_NOFOLLOW;
+
     v9fs_string_init(&fullname);
     v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
     path = fullname.data;
@@ -676,8 +708,9 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
     if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
         int fd;
         ssize_t oldpath_size, write_size;
-        fd = open(rpath(fs_ctx, newpath, buffer), O_CREAT|O_EXCL|O_RDWR,
-                SM_LOCAL_MODE_BITS);
+        fd = open(rpath(fs_ctx, newpath, buffer),
+                  O_CREAT|O_EXCL|O_RDWR|O_NOFOLLOW,
+                  SM_LOCAL_MODE_BITS);
         if (fd == -1) {
             err = fd;
             goto out;
@@ -705,7 +738,8 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
     } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
         int fd;
         ssize_t oldpath_size, write_size;
-        fd = open(rpath(fs_ctx, newpath, buffer), O_CREAT|O_EXCL|O_RDWR,
+        fd = open(rpath(fs_ctx, newpath, buffer),
+                  O_CREAT|O_EXCL|O_RDWR|O_NOFOLLOW,
                   SM_LOCAL_MODE_BITS);
         if (fd == -1) {
             err = fd;
commit aed858ce10ef09c7bdf03f73e75e772f567c74cd
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Mon May 20 17:28:29 2013 +0530

    hw/9pfs: use O_NOFOLLOW for mapped readlink operation
    
    With mapped security models like mapped-xattr and mapped-file, we save the
    symlink target as file contents. Now if we ever expose a normal directory
    with mapped security model and find real symlinks in export path, never
    follow them and return proper error.
    
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index 6ece6f7..87aa75d 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -284,7 +284,7 @@ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
     if ((fs_ctx->export_flags & V9FS_SM_MAPPED) ||
         (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE)) {
         int fd;
-        fd = open(rpath(fs_ctx, path, buffer), O_RDONLY);
+        fd = open(rpath(fs_ctx, path, buffer), O_RDONLY | O_NOFOLLOW);
         if (fd == -1) {
             return -1;
         }
commit c7e587b73ebac05943df78f5f37d80d32ff47d3d
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Mon May 20 11:29:52 2013 +0530

    hw/9pfs: Fix segfault with 9p2000.u
    
    When guest tries to chmod a block or char device file over 9pfs,
    the qemu process segfaults. With 9p2000.u protocol we use wstat to
    change mode bits and client don't send extension information for
    chmod. We need to check for size field to check whether extension
    info is present or not.
    
    Reported-by: Michael Tokarev <mjt at tls.msk.ru>
    Acked-by: Michael Tokarev <mjt at tls.msk.ru>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 296f66f..8cbb8ae 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -658,7 +658,7 @@ static mode_t v9mode_to_mode(uint32_t mode, V9fsString *extension)
         ret |= S_IFIFO;
     }
     if (mode & P9_STAT_MODE_DEVICE) {
-        if (extension && extension->data[0] == 'c') {
+        if (extension->size && extension->data[0] == 'c') {
             ret |= S_IFCHR;
         } else {
             ret |= S_IFBLK;
commit 60d95386abf1f5f37ded6a812d12ac458df2491b
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Mon May 27 12:41:24 2013 +0200

    chardev: fix "info chardev" output
    
    Fill unset CharDriverState->filename with the backend name, so
    'info chardev' will return at least the chardev type.  Don't
    touch it in case the chardev init function filled it already,
    like the socket+pty chardevs do for example.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/qemu-char.c b/qemu-char.c
index f825294..d04b429 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3801,6 +3801,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
         chr->label = g_strdup(id);
         chr->avail_connections =
             (backend->kind == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1;
+        if (!chr->filename) {
+            chr->filename = g_strdup(ChardevBackendKind_lookup[backend->kind]);
+        }
         QTAILQ_INSERT_TAIL(&chardevs, chr, next);
         return ret;
     } else {
commit 3022e6b472d0f6d56efbe890e0f1c94841b170d4
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Mon May 27 12:38:58 2013 +0200

    Revert "chardev: Get filename for new qapi backend"
    
    Does not handle chardevs created via chardev-add monitor command.
    
    This reverts commit 2b220025993e76d4116781ca91a4fabc5ad9c722.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/qemu-char.c b/qemu-char.c
index 4f8382e..f825294 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3276,7 +3276,6 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
         ChardevReturn *ret = NULL;
         const char *id = qemu_opts_id(opts);
         const char *bid = NULL;
-        char *filename = g_strdup(qemu_opt_get(opts, "backend"));
 
         if (qemu_opt_get_bool(opts, "mux", 0)) {
             bid = g_strdup_printf("%s-base", id);
@@ -3309,7 +3308,6 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
         }
 
         chr = qemu_chr_find(id);
-        chr->filename = filename;
 
     qapi_out:
         qapi_free_ChardevBackend(backend);
commit 6a4e17711442849bf2cc731ccddef5a2a2d92d29
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Apr 14 18:10:28 2013 +0000

    Remove Sun4c, Sun4d and a few CPUs
    
    Sun4c and Sun4d architectures and related CPUs are not fully implemented
    (especially Sun4c MMU) and there has been no interest for them.
    
    Likewise, a few CPUs (Cypress, Ross etc) are only half implemented.
    
    Remove the machines and CPUs, they can be re-added if needed later.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 718d97a..3e68d2e 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -7,7 +7,7 @@ common-obj-$(CONFIG_ETRAXFS) += etraxfs_pic.o
 common-obj-$(CONFIG_IMX) += imx_avic.o
 common-obj-$(CONFIG_LM32) += lm32_pic.o
 common-obj-$(CONFIG_REALVIEW) += realview_gic.o
-common-obj-$(CONFIG_SLAVIO) += sbi.o slavio_intctl.o sun4c_intctl.o
+common-obj-$(CONFIG_SLAVIO) += slavio_intctl.o
 common-obj-$(CONFIG_IOAPIC) += ioapic_common.o
 common-obj-$(CONFIG_ARM_GIC) += arm_gic_common.o
 
diff --git a/hw/intc/sbi.c b/hw/intc/sbi.c
deleted file mode 100644
index 8795749..0000000
--- a/hw/intc/sbi.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * QEMU Sparc SBI interrupt controller emulation
- *
- * Based on slavio_intctl, copyright (c) 2003-2005 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 "hw/sysbus.h"
-
-//#define DEBUG_IRQ
-
-#ifdef DEBUG_IRQ
-#define DPRINTF(fmt, ...)                                       \
-    do { printf("IRQ: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...)
-#endif
-
-#define MAX_CPUS 16
-
-#define SBI_NREGS 16
-
-typedef struct SBIState {
-    SysBusDevice busdev;
-    MemoryRegion iomem;
-    uint32_t regs[SBI_NREGS];
-    uint32_t intreg_pending[MAX_CPUS];
-    qemu_irq cpu_irqs[MAX_CPUS];
-    uint32_t pil_out[MAX_CPUS];
-} SBIState;
-
-#define SBI_SIZE (SBI_NREGS * 4)
-
-static void sbi_set_irq(void *opaque, int irq, int level)
-{
-}
-
-static uint64_t sbi_mem_read(void *opaque, hwaddr addr,
-                             unsigned size)
-{
-    SBIState *s = opaque;
-    uint32_t saddr, ret;
-
-    saddr = addr >> 2;
-    switch (saddr) {
-    default:
-        ret = s->regs[saddr];
-        break;
-    }
-    DPRINTF("read system reg 0x" TARGET_FMT_plx " = %x\n", addr, ret);
-
-    return ret;
-}
-
-static void sbi_mem_write(void *opaque, hwaddr addr,
-                          uint64_t val, unsigned dize)
-{
-    SBIState *s = opaque;
-    uint32_t saddr;
-
-    saddr = addr >> 2;
-    DPRINTF("write system reg 0x" TARGET_FMT_plx " = %x\n", addr, (int)val);
-    switch (saddr) {
-    default:
-        s->regs[saddr] = val;
-        break;
-    }
-}
-
-static const MemoryRegionOps sbi_mem_ops = {
-    .read = sbi_mem_read,
-    .write = sbi_mem_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-    .valid = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
-};
-
-static const VMStateDescription vmstate_sbi = {
-    .name ="sbi",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .minimum_version_id_old = 1,
-    .fields      = (VMStateField []) {
-        VMSTATE_UINT32_ARRAY(intreg_pending, SBIState, MAX_CPUS),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static void sbi_reset(DeviceState *d)
-{
-    SBIState *s = container_of(d, SBIState, busdev.qdev);
-    unsigned int i;
-
-    for (i = 0; i < MAX_CPUS; i++) {
-        s->intreg_pending[i] = 0;
-    }
-}
-
-static int sbi_init1(SysBusDevice *dev)
-{
-    SBIState *s = FROM_SYSBUS(SBIState, dev);
-    unsigned int i;
-
-    qdev_init_gpio_in(&dev->qdev, sbi_set_irq, 32 + MAX_CPUS);
-    for (i = 0; i < MAX_CPUS; i++) {
-        sysbus_init_irq(dev, &s->cpu_irqs[i]);
-    }
-
-    memory_region_init_io(&s->iomem, &sbi_mem_ops, s, "sbi", SBI_SIZE);
-    sysbus_init_mmio(dev, &s->iomem);
-
-    return 0;
-}
-
-static void sbi_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
-    k->init = sbi_init1;
-    dc->reset = sbi_reset;
-    dc->vmsd = &vmstate_sbi;
-}
-
-static const TypeInfo sbi_info = {
-    .name          = "sbi",
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(SBIState),
-    .class_init    = sbi_class_init,
-};
-
-static void sbi_register_types(void)
-{
-    type_register_static(&sbi_info);
-}
-
-type_init(sbi_register_types)
diff --git a/hw/intc/sun4c_intctl.c b/hw/intc/sun4c_intctl.c
deleted file mode 100644
index 1096375..0000000
--- a/hw/intc/sun4c_intctl.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * QEMU Sparc Sun4c interrupt controller emulation
- *
- * Based on slavio_intctl, copyright (c) 2003-2005 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 "hw/hw.h"
-#include "hw/sparc/sun4m.h"
-#include "monitor/monitor.h"
-#include "hw/sysbus.h"
-
-//#define DEBUG_IRQ_COUNT
-//#define DEBUG_IRQ
-
-#ifdef DEBUG_IRQ
-#define DPRINTF(fmt, ...)                                       \
-    do { printf("IRQ: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...)
-#endif
-
-/*
- * Registers of interrupt controller in sun4c.
- *
- */
-
-#define MAX_PILS 16
-
-typedef struct Sun4c_INTCTLState {
-    SysBusDevice busdev;
-    MemoryRegion iomem;
-#ifdef DEBUG_IRQ_COUNT
-    uint64_t irq_count;
-#endif
-    qemu_irq cpu_irqs[MAX_PILS];
-    const uint32_t *intbit_to_level;
-    uint32_t pil_out;
-    uint8_t reg;
-    uint8_t pending;
-} Sun4c_INTCTLState;
-
-#define INTCTL_SIZE 1
-
-static void sun4c_check_interrupts(void *opaque);
-
-static uint64_t sun4c_intctl_mem_read(void *opaque, hwaddr addr,
-                                      unsigned size)
-{
-    Sun4c_INTCTLState *s = opaque;
-    uint32_t ret;
-
-    ret = s->reg;
-    DPRINTF("read reg 0x" TARGET_FMT_plx " = %x\n", addr, ret);
-
-    return ret;
-}
-
-static void sun4c_intctl_mem_write(void *opaque, hwaddr addr,
-                                   uint64_t val, unsigned size)
-{
-    Sun4c_INTCTLState *s = opaque;
-
-    DPRINTF("write reg 0x" TARGET_FMT_plx " = %x\n", addr, (unsigned)val);
-    val &= 0xbf;
-    s->reg = val;
-    sun4c_check_interrupts(s);
-}
-
-static const MemoryRegionOps sun4c_intctl_mem_ops = {
-    .read = sun4c_intctl_mem_read,
-    .write = sun4c_intctl_mem_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-    .valid = {
-        .min_access_size = 1,
-        .max_access_size = 1,
-    },
-};
-
-static const uint32_t intbit_to_level[] = { 0, 1, 4, 6, 8, 10, 0, 14, };
-
-static void sun4c_check_interrupts(void *opaque)
-{
-    Sun4c_INTCTLState *s = opaque;
-    uint32_t pil_pending;
-    unsigned int i;
-
-    pil_pending = 0;
-    if (s->pending && !(s->reg & 0x80000000)) {
-        for (i = 0; i < 8; i++) {
-            if (s->pending & (1 << i))
-                pil_pending |= 1 << intbit_to_level[i];
-        }
-    }
-
-    for (i = 0; i < MAX_PILS; i++) {
-        if (pil_pending & (1 << i)) {
-            if (!(s->pil_out & (1 << i)))
-                qemu_irq_raise(s->cpu_irqs[i]);
-        } else {
-            if (s->pil_out & (1 << i))
-                qemu_irq_lower(s->cpu_irqs[i]);
-        }
-    }
-    s->pil_out = pil_pending;
-}
-
-/*
- * "irq" here is the bit number in the system interrupt register
- */
-static void sun4c_set_irq(void *opaque, int irq, int level)
-{
-    Sun4c_INTCTLState *s = opaque;
-    uint32_t mask = 1 << irq;
-    uint32_t pil = intbit_to_level[irq];
-
-    DPRINTF("Set irq %d -> pil %d level %d\n", irq, pil,
-            level);
-    if (pil > 0) {
-        if (level) {
-#ifdef DEBUG_IRQ_COUNT
-            s->irq_count++;
-#endif
-            s->pending |= mask;
-        } else {
-            s->pending &= ~mask;
-        }
-        sun4c_check_interrupts(s);
-    }
-}
-
-static const VMStateDescription vmstate_sun4c_intctl = {
-    .name ="sun4c_intctl",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .minimum_version_id_old = 1,
-    .fields      = (VMStateField []) {
-        VMSTATE_UINT8(reg, Sun4c_INTCTLState),
-        VMSTATE_UINT8(pending, Sun4c_INTCTLState),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static void sun4c_intctl_reset(DeviceState *d)
-{
-    Sun4c_INTCTLState *s = container_of(d, Sun4c_INTCTLState, busdev.qdev);
-
-    s->reg = 1;
-    s->pending = 0;
-}
-
-static int sun4c_intctl_init1(SysBusDevice *dev)
-{
-    Sun4c_INTCTLState *s = FROM_SYSBUS(Sun4c_INTCTLState, dev);
-    unsigned int i;
-
-    memory_region_init_io(&s->iomem, &sun4c_intctl_mem_ops, s,
-                          "intctl", INTCTL_SIZE);
-    sysbus_init_mmio(dev, &s->iomem);
-    qdev_init_gpio_in(&dev->qdev, sun4c_set_irq, 8);
-
-    for (i = 0; i < MAX_PILS; i++) {
-        sysbus_init_irq(dev, &s->cpu_irqs[i]);
-    }
-
-    return 0;
-}
-
-static void sun4c_intctl_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
-    k->init = sun4c_intctl_init1;
-    dc->reset = sun4c_intctl_reset;
-    dc->vmsd = &vmstate_sun4c_intctl;
-}
-
-static const TypeInfo sun4c_intctl_info = {
-    .name          = "sun4c_intctl",
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(Sun4c_INTCTLState),
-    .class_init    = sun4c_intctl_class_init,
-};
-
-static void sun4c_intctl_register_types(void)
-{
-    type_register_static(&sun4c_intctl_info);
-}
-
-type_init(sun4c_intctl_register_types)
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 635115f..8840881 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -55,18 +55,6 @@
  * SPARCstation 20/xx, SPARCserver 20
  * SPARCstation 4
  *
- * Sun4d architecture was used in the following machines:
- *
- * SPARCcenter 2000
- * SPARCserver 1000
- *
- * Sun4c architecture was used in the following machines:
- * SPARCstation 1/1+, SPARCserver 1/1+
- * SPARCstation SLC
- * SPARCstation IPC
- * SPARCstation ELC
- * SPARCstation IPX
- *
  * See for example: http://www.sunhelp.org/faq/sunref1.html
  */
 
@@ -104,36 +92,6 @@ struct sun4m_hwdef {
     uint8_t nvram_machine_id;
 };
 
-#define MAX_IOUNITS 5
-
-struct sun4d_hwdef {
-    hwaddr iounit_bases[MAX_IOUNITS], slavio_base;
-    hwaddr counter_base, nvram_base, ms_kb_base;
-    hwaddr serial_base;
-    hwaddr espdma_base, esp_base;
-    hwaddr ledma_base, le_base;
-    hwaddr tcx_base;
-    hwaddr sbi_base;
-    uint64_t max_mem;
-    const char * const default_cpu_model;
-    uint32_t iounit_version;
-    uint16_t machine_id;
-    uint8_t nvram_machine_id;
-};
-
-struct sun4c_hwdef {
-    hwaddr iommu_base, slavio_base;
-    hwaddr intctl_base, counter_base, nvram_base, ms_kb_base;
-    hwaddr serial_base, fd_base;
-    hwaddr idreg_base, dma_base, esp_base, le_base;
-    hwaddr tcx_base, aux1_base;
-    uint64_t max_mem;
-    const char * const default_cpu_model;
-    uint32_t iommu_version;
-    uint16_t machine_id;
-    uint8_t nvram_machine_id;
-};
-
 int DMA_get_channel_mode (int nchan)
 {
     return 0;
@@ -1052,7 +1010,6 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
 }
 
 enum {
-    ss2_id = 0,
     ss5_id = 32,
     vger_id,
     lx_id,
@@ -1062,8 +1019,6 @@ enum {
     ss10_id = 64,
     ss20_id,
     ss600mp_id,
-    ss1000_id = 96,
-    ss2000_id,
 };
 
 static const struct sun4m_hwdef sun4m_hwdefs[] = {
@@ -1504,417 +1459,6 @@ static QEMUMachine sbook_machine = {
     DEFAULT_MACHINE_OPTIONS,
 };
 
-static const struct sun4d_hwdef sun4d_hwdefs[] = {
-    /* SS-1000 */
-    {
-        .iounit_bases   = {
-            0xfe0200000ULL,
-            0xfe1200000ULL,
-            0xfe2200000ULL,
-            0xfe3200000ULL,
-            -1,
-        },
-        .tcx_base     = 0x820000000ULL,
-        .slavio_base  = 0xf00000000ULL,
-        .ms_kb_base   = 0xf00240000ULL,
-        .serial_base  = 0xf00200000ULL,
-        .nvram_base   = 0xf00280000ULL,
-        .counter_base = 0xf00300000ULL,
-        .espdma_base  = 0x800081000ULL,
-        .esp_base     = 0x800080000ULL,
-        .ledma_base   = 0x800040000ULL,
-        .le_base      = 0x800060000ULL,
-        .sbi_base     = 0xf02800000ULL,
-        .nvram_machine_id = 0x80,
-        .machine_id = ss1000_id,
-        .iounit_version = 0x03000000,
-        .max_mem = 0xf00000000ULL,
-        .default_cpu_model = "TI SuperSparc II",
-    },
-    /* SS-2000 */
-    {
-        .iounit_bases   = {
-            0xfe0200000ULL,
-            0xfe1200000ULL,
-            0xfe2200000ULL,
-            0xfe3200000ULL,
-            0xfe4200000ULL,
-        },
-        .tcx_base     = 0x820000000ULL,
-        .slavio_base  = 0xf00000000ULL,
-        .ms_kb_base   = 0xf00240000ULL,
-        .serial_base  = 0xf00200000ULL,
-        .nvram_base   = 0xf00280000ULL,
-        .counter_base = 0xf00300000ULL,
-        .espdma_base  = 0x800081000ULL,
-        .esp_base     = 0x800080000ULL,
-        .ledma_base   = 0x800040000ULL,
-        .le_base      = 0x800060000ULL,
-        .sbi_base     = 0xf02800000ULL,
-        .nvram_machine_id = 0x80,
-        .machine_id = ss2000_id,
-        .iounit_version = 0x03000000,
-        .max_mem = 0xf00000000ULL,
-        .default_cpu_model = "TI SuperSparc II",
-    },
-};
-
-static DeviceState *sbi_init(hwaddr addr, qemu_irq **parent_irq)
-{
-    DeviceState *dev;
-    SysBusDevice *s;
-    unsigned int i;
-
-    dev = qdev_create(NULL, "sbi");
-    qdev_init_nofail(dev);
-
-    s = SYS_BUS_DEVICE(dev);
-
-    for (i = 0; i < MAX_CPUS; i++) {
-        sysbus_connect_irq(s, i, *parent_irq[i]);
-    }
-
-    sysbus_mmio_map(s, 0, addr);
-
-    return dev;
-}
-
-static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
-                          const char *boot_device,
-                          const char *kernel_filename,
-                          const char *kernel_cmdline,
-                          const char *initrd_filename, const char *cpu_model)
-{
-    unsigned int i;
-    void *iounits[MAX_IOUNITS], *espdma, *ledma, *nvram;
-    qemu_irq *cpu_irqs[MAX_CPUS], sbi_irq[32], sbi_cpu_irq[MAX_CPUS],
-        espdma_irq, ledma_irq;
-    qemu_irq esp_reset, dma_enable;
-    unsigned long kernel_size;
-    void *fw_cfg;
-    DeviceState *dev;
-
-    /* init CPUs */
-    if (!cpu_model)
-        cpu_model = hwdef->default_cpu_model;
-
-    for(i = 0; i < smp_cpus; i++) {
-        cpu_devinit(cpu_model, i, hwdef->slavio_base, &cpu_irqs[i]);
-    }
-
-    for (i = smp_cpus; i < MAX_CPUS; i++)
-        cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
-
-    /* set up devices */
-    ram_init(0, RAM_size, hwdef->max_mem);
-
-    prom_init(hwdef->slavio_base, bios_name);
-
-    dev = sbi_init(hwdef->sbi_base, cpu_irqs);
-
-    for (i = 0; i < 32; i++) {
-        sbi_irq[i] = qdev_get_gpio_in(dev, i);
-    }
-    for (i = 0; i < MAX_CPUS; i++) {
-        sbi_cpu_irq[i] = qdev_get_gpio_in(dev, 32 + i);
-    }
-
-    for (i = 0; i < MAX_IOUNITS; i++)
-        if (hwdef->iounit_bases[i] != (hwaddr)-1)
-            iounits[i] = iommu_init(hwdef->iounit_bases[i],
-                                    hwdef->iounit_version,
-                                    sbi_irq[0]);
-
-    espdma = sparc32_dma_init(hwdef->espdma_base, sbi_irq[3],
-                              iounits[0], &espdma_irq, 0);
-
-    /* should be lebuffer instead */
-    ledma = sparc32_dma_init(hwdef->ledma_base, sbi_irq[4],
-                             iounits[0], &ledma_irq, 0);
-
-    if (graphic_depth != 8 && graphic_depth != 24) {
-        fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
-        exit (1);
-    }
-    tcx_init(hwdef->tcx_base, 0x00100000, graphic_width, graphic_height,
-             graphic_depth);
-
-    lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq);
-
-    nvram = m48t59_init(sbi_irq[0], hwdef->nvram_base, 0, 0x2000, 8);
-
-    slavio_timer_init_all(hwdef->counter_base, sbi_irq[10], sbi_cpu_irq, smp_cpus);
-
-    slavio_serial_ms_kbd_init(hwdef->ms_kb_base, sbi_irq[12],
-                              display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
-    /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device
-       Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */
-    escc_init(hwdef->serial_base, sbi_irq[12], sbi_irq[12],
-              serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);
-
-    if (drive_get_max_bus(IF_SCSI) > 0) {
-        fprintf(stderr, "qemu: too many SCSI bus\n");
-        exit(1);
-    }
-
-    esp_init(hwdef->esp_base, 2,
-             espdma_memory_read, espdma_memory_write,
-             espdma, espdma_irq, &esp_reset, &dma_enable);
-
-    qdev_connect_gpio_out(espdma, 0, esp_reset);
-    qdev_connect_gpio_out(espdma, 1, dma_enable);
-
-    kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
-                                    RAM_size);
-
-    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
-               boot_device, RAM_size, kernel_size, graphic_width,
-               graphic_height, graphic_depth, hwdef->nvram_machine_id,
-               "Sun4d");
-
-    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
-    fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
-    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
-    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
-    fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_DEPTH, graphic_depth);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
-    if (kernel_cmdline) {
-        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
-        pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
-        fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
-    } else {
-        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
-    }
-    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, 0); // not used
-    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_device[0]);
-    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
-}
-
-/* SPARCserver 1000 hardware initialisation */
-static void ss1000_init(QEMUMachineInitArgs *args)
-{
-    ram_addr_t RAM_size = args->ram_size;
-    const char *cpu_model = args->cpu_model;
-    const char *kernel_filename = args->kernel_filename;
-    const char *kernel_cmdline = args->kernel_cmdline;
-    const char *initrd_filename = args->initrd_filename;
-    const char *boot_device = args->boot_device;
-    sun4d_hw_init(&sun4d_hwdefs[0], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
-}
-
-/* SPARCcenter 2000 hardware initialisation */
-static void ss2000_init(QEMUMachineInitArgs *args)
-{
-    ram_addr_t RAM_size = args->ram_size;
-    const char *cpu_model = args->cpu_model;
-    const char *kernel_filename = args->kernel_filename;
-    const char *kernel_cmdline = args->kernel_cmdline;
-    const char *initrd_filename = args->initrd_filename;
-    const char *boot_device = args->boot_device;
-    sun4d_hw_init(&sun4d_hwdefs[1], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
-}
-
-static QEMUMachine ss1000_machine = {
-    .name = "SS-1000",
-    .desc = "Sun4d platform, SPARCserver 1000",
-    .init = ss1000_init,
-    .block_default_type = IF_SCSI,
-    .max_cpus = 8,
-    DEFAULT_MACHINE_OPTIONS,
-};
-
-static QEMUMachine ss2000_machine = {
-    .name = "SS-2000",
-    .desc = "Sun4d platform, SPARCcenter 2000",
-    .init = ss2000_init,
-    .block_default_type = IF_SCSI,
-    .max_cpus = 20,
-    DEFAULT_MACHINE_OPTIONS,
-};
-
-static const struct sun4c_hwdef sun4c_hwdefs[] = {
-    /* SS-2 */
-    {
-        .iommu_base   = 0xf8000000,
-        .tcx_base     = 0xfe000000,
-        .slavio_base  = 0xf6000000,
-        .intctl_base  = 0xf5000000,
-        .counter_base = 0xf3000000,
-        .ms_kb_base   = 0xf0000000,
-        .serial_base  = 0xf1000000,
-        .nvram_base   = 0xf2000000,
-        .fd_base      = 0xf7200000,
-        .dma_base     = 0xf8400000,
-        .esp_base     = 0xf8800000,
-        .le_base      = 0xf8c00000,
-        .aux1_base    = 0xf7400003,
-        .nvram_machine_id = 0x55,
-        .machine_id = ss2_id,
-        .max_mem = 0x10000000,
-        .default_cpu_model = "Cypress CY7C601",
-    },
-};
-
-static DeviceState *sun4c_intctl_init(hwaddr addr,
-                                      qemu_irq *parent_irq)
-{
-    DeviceState *dev;
-    SysBusDevice *s;
-    unsigned int i;
-
-    dev = qdev_create(NULL, "sun4c_intctl");
-    qdev_init_nofail(dev);
-
-    s = SYS_BUS_DEVICE(dev);
-
-    for (i = 0; i < MAX_PILS; i++) {
-        sysbus_connect_irq(s, i, parent_irq[i]);
-    }
-    sysbus_mmio_map(s, 0, addr);
-
-    return dev;
-}
-
-static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
-                          const char *boot_device,
-                          const char *kernel_filename,
-                          const char *kernel_cmdline,
-                          const char *initrd_filename, const char *cpu_model)
-{
-    void *iommu, *espdma, *ledma, *nvram;
-    qemu_irq *cpu_irqs, slavio_irq[8], espdma_irq, ledma_irq;
-    qemu_irq esp_reset, dma_enable;
-    qemu_irq fdc_tc;
-    unsigned long kernel_size;
-    DriveInfo *fd[MAX_FD];
-    void *fw_cfg;
-    DeviceState *dev;
-    unsigned int i;
-
-    /* init CPU */
-    if (!cpu_model)
-        cpu_model = hwdef->default_cpu_model;
-
-    cpu_devinit(cpu_model, 0, hwdef->slavio_base, &cpu_irqs);
-
-    /* set up devices */
-    ram_init(0, RAM_size, hwdef->max_mem);
-
-    prom_init(hwdef->slavio_base, bios_name);
-
-    dev = sun4c_intctl_init(hwdef->intctl_base, cpu_irqs);
-
-    for (i = 0; i < 8; i++) {
-        slavio_irq[i] = qdev_get_gpio_in(dev, i);
-    }
-
-    iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version,
-                       slavio_irq[1]);
-
-    espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[2],
-                              iommu, &espdma_irq, 0);
-
-    ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
-                             slavio_irq[3], iommu, &ledma_irq, 1);
-
-    if (graphic_depth != 8 && graphic_depth != 24) {
-        fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
-        exit (1);
-    }
-    tcx_init(hwdef->tcx_base, 0x00100000, graphic_width, graphic_height,
-             graphic_depth);
-
-    lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq);
-
-    nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, 0x800, 2);
-
-    slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[1],
-                              display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
-    /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device
-       Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */
-    escc_init(hwdef->serial_base, slavio_irq[1],
-              slavio_irq[1], serial_hds[0], serial_hds[1],
-              ESCC_CLOCK, 1);
-
-    if (hwdef->fd_base != (hwaddr)-1) {
-        /* there is zero or one floppy drive */
-        memset(fd, 0, sizeof(fd));
-        fd[0] = drive_get(IF_FLOPPY, 0, 0);
-        sun4m_fdctrl_init(slavio_irq[1], hwdef->fd_base, fd,
-                          &fdc_tc);
-    } else {
-        fdc_tc = *qemu_allocate_irqs(dummy_fdc_tc, NULL, 1);
-    }
-
-    slavio_misc_init(0, hwdef->aux1_base, 0, slavio_irq[1], fdc_tc);
-
-    if (drive_get_max_bus(IF_SCSI) > 0) {
-        fprintf(stderr, "qemu: too many SCSI bus\n");
-        exit(1);
-    }
-
-    esp_init(hwdef->esp_base, 2,
-             espdma_memory_read, espdma_memory_write,
-             espdma, espdma_irq, &esp_reset, &dma_enable);
-
-    qdev_connect_gpio_out(espdma, 0, esp_reset);
-    qdev_connect_gpio_out(espdma, 1, dma_enable);
-
-    kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
-                                    RAM_size);
-
-    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
-               boot_device, RAM_size, kernel_size, graphic_width,
-               graphic_height, graphic_depth, hwdef->nvram_machine_id,
-               "Sun4c");
-
-    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
-    fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
-    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
-    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
-    fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_DEPTH, graphic_depth);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
-    if (kernel_cmdline) {
-        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
-        pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
-        fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
-    } else {
-        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
-    }
-    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, 0); // not used
-    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_device[0]);
-    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
-}
-
-/* SPARCstation 2 hardware initialisation */
-static void ss2_init(QEMUMachineInitArgs *args)
-{
-    ram_addr_t RAM_size = args->ram_size;
-    const char *cpu_model = args->cpu_model;
-    const char *kernel_filename = args->kernel_filename;
-    const char *kernel_cmdline = args->kernel_cmdline;
-    const char *initrd_filename = args->initrd_filename;
-    const char *boot_device = args->boot_device;
-    sun4c_hw_init(&sun4c_hwdefs[0], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
-}
-
-static QEMUMachine ss2_machine = {
-    .name = "SS-2",
-    .desc = "Sun4c platform, SPARCstation 2",
-    .init = ss2_init,
-    .block_default_type = IF_SCSI,
-    DEFAULT_MACHINE_OPTIONS,
-};
-
 static void sun4m_register_types(void)
 {
     type_register_static(&idreg_info);
@@ -1923,7 +1467,7 @@ static void sun4m_register_types(void)
     type_register_static(&ram_info);
 }
 
-static void ss2_machine_init(void)
+static void sun4m_machine_init(void)
 {
     qemu_register_machine(&ss5_machine);
     qemu_register_machine(&ss10_machine);
@@ -1934,10 +1478,7 @@ static void ss2_machine_init(void)
     qemu_register_machine(&ss4_machine);
     qemu_register_machine(&scls_machine);
     qemu_register_machine(&sbook_machine);
-    qemu_register_machine(&ss1000_machine);
-    qemu_register_machine(&ss2000_machine);
-    qemu_register_machine(&ss2_machine);
 }
 
 type_init(sun4m_register_types)
-machine_init(ss2_machine_init);
+machine_init(sun4m_machine_init);
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 5fc0eae..8022890 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -1958,15 +1958,11 @@ SPARCbook
 The emulation is somewhat complete. SMP up to 16 CPUs is supported,
 but Linux limits the number of usable CPUs to 4.
 
-It's also possible to simulate a SPARCstation 2 (sun4c architecture),
-SPARCserver 1000, or SPARCcenter 2000 (sun4d architecture), but these
-emulators are not usable yet.
-
-QEMU emulates the following sun4m/sun4c/sun4d peripherals:
+QEMU emulates the following sun4m peripherals:
 
 @itemize @minus
 @item
-IOMMU or IO-UNITs
+IOMMU
 @item
 TCX Frame buffer
 @item
@@ -2019,7 +2015,7 @@ qemu-system-sparc -prom-env 'auto-boot?=false' \
  -prom-env 'boot-device=sd(0,2,0):d' -prom-env 'boot-args=linux single'
 @end example
 
- at item -M [SS-4|SS-5|SS-10|SS-20|SS-600MP|LX|Voyager|SPARCClassic] [|SPARCbook|SS-2|SS-1000|SS-2000]
+ at item -M [SS-4|SS-5|SS-10|SS-20|SS-600MP|LX|Voyager|SPARCClassic] [|SPARCbook]
 
 Set the emulated machine type. Default is SS-5.
 
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index ab1adfd..290b580 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -292,19 +292,6 @@ static const sparc_def_t sparc_defs[] = {
     },
 #else
     {
-        .name = "Fujitsu MB86900",
-        .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
-        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
-        .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 7,
-        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
-    },
-    {
         .name = "Fujitsu MB86904",
         .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
         .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
@@ -331,48 +318,6 @@ static const sparc_def_t sparc_defs[] = {
         .features = CPU_DEFAULT_FEATURES,
     },
     {
-        .name = "LSI L64811",
-        .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
-        .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
-        .mmu_version = 0x10 << 24,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
-        CPU_FEATURE_FSMULD,
-    },
-    {
-        .name = "Cypress CY7C601",
-        .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
-        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
-        .mmu_version = 0x10 << 24,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
-        CPU_FEATURE_FSMULD,
-    },
-    {
-        .name = "Cypress CY7C611",
-        .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
-        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
-        .mmu_version = 0x10 << 24,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
-        CPU_FEATURE_FSMULD,
-    },
-    {
         .name = "TI MicroSparc I",
         .iu_version = 0x41000000,
         .fpu_version = 4 << 17,
@@ -495,73 +440,6 @@ static const sparc_def_t sparc_defs[] = {
         .features = CPU_DEFAULT_FEATURES,
     },
     {
-        .name = "Ross RT625",
-        .iu_version = 0x1e000000,
-        .fpu_version = 1 << 17,
-        .mmu_version = 0x1e000000,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "Ross RT620",
-        .iu_version = 0x1f000000,
-        .fpu_version = 1 << 17,
-        .mmu_version = 0x1f000000,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "BIT B5010",
-        .iu_version = 0x20000000,
-        .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
-        .mmu_version = 0x20000000,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
-        CPU_FEATURE_FSMULD,
-    },
-    {
-        .name = "Matsushita MN10501",
-        .iu_version = 0x50000000,
-        .fpu_version = 0 << 17,
-        .mmu_version = 0x50000000,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
-        CPU_FEATURE_FSMULD,
-    },
-    {
-        .name = "Weitek W8601",
-        .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
-        .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
-        .mmu_version = 0x10 << 24,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
         .name = "LEON2",
         .iu_version = 0xf2000000,
         .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
commit 4f6ab397b60615d2da77bff4f32666be9ac2e949
Author: Brad Smith <brad at comstyle.com>
Date:   Fri May 24 19:01:07 2013 -0400

    Remove OSS support for OpenBSD
    
    Remove the OSS support for OpenBSD. The OSS API has not been usable
    for quite some time.
    
    Signed-off-by: Brad Smith <brad at comstyle.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index 00be9c9..007c641 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -25,11 +25,7 @@
 #include <sys/mman.h>
 #include <sys/types.h>
 #include <sys/ioctl.h>
-#ifdef __OpenBSD__
-#include <soundcard.h>
-#else
 #include <sys/soundcard.h>
-#endif
 #include "qemu-common.h"
 #include "qemu/main-loop.h"
 #include "qemu/host-utils.h"
diff --git a/configure b/configure
index 5ae7e4a..eb74510 100755
--- a/configure
+++ b/configure
@@ -468,9 +468,8 @@ NetBSD)
 OpenBSD)
   bsd="yes"
   make="${MAKE-gmake}"
-  audio_drv_list="oss"
-  audio_possible_drivers="oss sdl esd"
-  oss_lib="-lossaudio"
+  audio_drv_list="sdl"
+  audio_possible_drivers="sdl esd"
 ;;
 Darwin)
   bsd="yes"
commit 5b35b4e91d4d023d44dc28437ae414a21e9b8117
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu May 23 13:00:03 2013 +0100

    target-arm: Remove gen_{ld,st}* definitions
    
    All the uses of the gen_{ld,st}* functions are gone now, so remove
    the functions themselves.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 0ca68fe..71135bd 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -841,52 +841,6 @@ static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
     }
 }
 
-static inline TCGv_i32 gen_ld8s(TCGv_i32 addr, int index)
-{
-    TCGv_i32 tmp = tcg_temp_new_i32();
-    tcg_gen_qemu_ld8s(tmp, addr, index);
-    return tmp;
-}
-static inline TCGv_i32 gen_ld8u(TCGv_i32 addr, int index)
-{
-    TCGv_i32 tmp = tcg_temp_new_i32();
-    tcg_gen_qemu_ld8u(tmp, addr, index);
-    return tmp;
-}
-static inline TCGv_i32 gen_ld16s(TCGv_i32 addr, int index)
-{
-    TCGv_i32 tmp = tcg_temp_new_i32();
-    tcg_gen_qemu_ld16s(tmp, addr, index);
-    return tmp;
-}
-static inline TCGv_i32 gen_ld16u(TCGv_i32 addr, int index)
-{
-    TCGv_i32 tmp = tcg_temp_new_i32();
-    tcg_gen_qemu_ld16u(tmp, addr, index);
-    return tmp;
-}
-static inline TCGv_i32 gen_ld32(TCGv_i32 addr, int index)
-{
-    TCGv_i32 tmp = tcg_temp_new_i32();
-    tcg_gen_qemu_ld32u(tmp, addr, index);
-    return tmp;
-}
-static inline void gen_st8(TCGv_i32 val, TCGv_i32 addr, int index)
-{
-    tcg_gen_qemu_st8(val, addr, index);
-    tcg_temp_free_i32(val);
-}
-static inline void gen_st16(TCGv_i32 val, TCGv_i32 addr, int index)
-{
-    tcg_gen_qemu_st16(val, addr, index);
-    tcg_temp_free_i32(val);
-}
-static inline void gen_st32(TCGv_i32 val, TCGv_i32 addr, int index)
-{
-    tcg_gen_qemu_st32(val, addr, index);
-    tcg_temp_free_i32(val);
-}
-
 static inline void gen_set_pc_im(uint32_t val)
 {
     tcg_gen_movi_i32(cpu_R[15], val);
commit e2592fad1720d848699f32e67882b611bbed2cb5
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu May 23 13:00:02 2013 +0100

    target-arm: Remove gen_{ld,st}* from thumb2 decoder
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 953c5fb..0ca68fe 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -8134,18 +8134,22 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                 }
                 if (insn & (1 << 20)) {
                     /* ldrd */
-                    tmp = gen_ld32(addr, IS_USER(s));
+                    tmp = tcg_temp_new_i32();
+                    tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
                     store_reg(s, rs, tmp);
                     tcg_gen_addi_i32(addr, addr, 4);
-                    tmp = gen_ld32(addr, IS_USER(s));
+                    tmp = tcg_temp_new_i32();
+                    tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
                     store_reg(s, rd, tmp);
                 } else {
                     /* strd */
                     tmp = load_reg(s, rs);
-                    gen_st32(tmp, addr, IS_USER(s));
+                    tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+                    tcg_temp_free_i32(tmp);
                     tcg_gen_addi_i32(addr, addr, 4);
                     tmp = load_reg(s, rd);
-                    gen_st32(tmp, addr, IS_USER(s));
+                    tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+                    tcg_temp_free_i32(tmp);
                 }
                 if (insn & (1 << 21)) {
                     /* Base writeback.  */
@@ -8181,10 +8185,12 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                     /* tbh */
                     tcg_gen_add_i32(addr, addr, tmp);
                     tcg_temp_free_i32(tmp);
-                    tmp = gen_ld16u(addr, IS_USER(s));
+                    tmp = tcg_temp_new_i32();
+                    tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
                 } else { /* tbb */
                     tcg_temp_free_i32(tmp);
-                    tmp = gen_ld8u(addr, IS_USER(s));
+                    tmp = tcg_temp_new_i32();
+                    tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
                 }
                 tcg_temp_free_i32(addr);
                 tcg_gen_shli_i32(tmp, tmp, 1);
@@ -8219,9 +8225,11 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                     if ((insn & (1 << 24)) == 0)
                         tcg_gen_addi_i32(addr, addr, -8);
                     /* Load PC into tmp and CPSR into tmp2.  */
-                    tmp = gen_ld32(addr, 0);
+                    tmp = tcg_temp_new_i32();
+                    tcg_gen_qemu_ld32u(tmp, addr, 0);
                     tcg_gen_addi_i32(addr, addr, 4);
-                    tmp2 = gen_ld32(addr, 0);
+                    tmp2 = tcg_temp_new_i32();
+                    tcg_gen_qemu_ld32u(tmp2, addr, 0);
                     if (insn & (1 << 21)) {
                         /* Base writeback.  */
                         if (insn & (1 << 24)) {
@@ -8259,7 +8267,8 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                         continue;
                     if (insn & (1 << 20)) {
                         /* Load.  */
-                        tmp = gen_ld32(addr, IS_USER(s));
+                        tmp = tcg_temp_new_i32();
+                        tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
                         if (i == 15) {
                             gen_bx(s, tmp);
                         } else if (i == rn) {
@@ -8271,7 +8280,8 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                     } else {
                         /* Store.  */
                         tmp = load_reg(s, i);
-                        gen_st32(tmp, addr, IS_USER(s));
+                        tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+                        tcg_temp_free_i32(tmp);
                     }
                     tcg_gen_addi_i32(addr, addr, 4);
                 }
commit c40c85560b6a9bf272dcc7de1beb8910f240bae8
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu May 23 13:00:01 2013 +0100

    target-arm: Remove gen_{ld,st}* from Thumb insns
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-arm/translate.c b/target-arm/translate.c
index e5a2e4c..953c5fb 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -9217,7 +9217,8 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
             val &= ~(uint32_t)2;
             addr = tcg_temp_new_i32();
             tcg_gen_movi_i32(addr, val);
-            tmp = gen_ld32(addr, IS_USER(s));
+            tmp = tcg_temp_new_i32();
+            tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
             tcg_temp_free_i32(addr);
             store_reg(s, rd, tmp);
             break;
@@ -9412,37 +9413,43 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
         tcg_gen_add_i32(addr, addr, tmp);
         tcg_temp_free_i32(tmp);
 
-        if (op < 3) /* store */
+        if (op < 3) { /* store */
             tmp = load_reg(s, rd);
+        } else {
+            tmp = tcg_temp_new_i32();
+        }
 
         switch (op) {
         case 0: /* str */
-            gen_st32(tmp, addr, IS_USER(s));
+            tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
             break;
         case 1: /* strh */
-            gen_st16(tmp, addr, IS_USER(s));
+            tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
             break;
         case 2: /* strb */
-            gen_st8(tmp, addr, IS_USER(s));
+            tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
             break;
         case 3: /* ldrsb */
-            tmp = gen_ld8s(addr, IS_USER(s));
+            tcg_gen_qemu_ld8s(tmp, addr, IS_USER(s));
             break;
         case 4: /* ldr */
-            tmp = gen_ld32(addr, IS_USER(s));
+            tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
             break;
         case 5: /* ldrh */
-            tmp = gen_ld16u(addr, IS_USER(s));
+            tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
             break;
         case 6: /* ldrb */
-            tmp = gen_ld8u(addr, IS_USER(s));
+            tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
             break;
         case 7: /* ldrsh */
-            tmp = gen_ld16s(addr, IS_USER(s));
+            tcg_gen_qemu_ld16s(tmp, addr, IS_USER(s));
             break;
         }
-        if (op >= 3) /* load */
+        if (op >= 3) { /* load */
             store_reg(s, rd, tmp);
+        } else {
+            tcg_temp_free_i32(tmp);
+        }
         tcg_temp_free_i32(addr);
         break;
 
@@ -9456,12 +9463,14 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
 
         if (insn & (1 << 11)) {
             /* load */
-            tmp = gen_ld32(addr, IS_USER(s));
+            tmp = tcg_temp_new_i32();
+            tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
             store_reg(s, rd, tmp);
         } else {
             /* store */
             tmp = load_reg(s, rd);
-            gen_st32(tmp, addr, IS_USER(s));
+            tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+            tcg_temp_free_i32(tmp);
         }
         tcg_temp_free_i32(addr);
         break;
@@ -9476,12 +9485,14 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
 
         if (insn & (1 << 11)) {
             /* load */
-            tmp = gen_ld8u(addr, IS_USER(s));
+            tmp = tcg_temp_new_i32();
+            tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
             store_reg(s, rd, tmp);
         } else {
             /* store */
             tmp = load_reg(s, rd);
-            gen_st8(tmp, addr, IS_USER(s));
+            tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
+            tcg_temp_free_i32(tmp);
         }
         tcg_temp_free_i32(addr);
         break;
@@ -9496,12 +9507,14 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
 
         if (insn & (1 << 11)) {
             /* load */
-            tmp = gen_ld16u(addr, IS_USER(s));
+            tmp = tcg_temp_new_i32();
+            tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
             store_reg(s, rd, tmp);
         } else {
             /* store */
             tmp = load_reg(s, rd);
-            gen_st16(tmp, addr, IS_USER(s));
+            tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
+            tcg_temp_free_i32(tmp);
         }
         tcg_temp_free_i32(addr);
         break;
@@ -9515,12 +9528,14 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
 
         if (insn & (1 << 11)) {
             /* load */
-            tmp = gen_ld32(addr, IS_USER(s));
+            tmp = tcg_temp_new_i32();
+            tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
             store_reg(s, rd, tmp);
         } else {
             /* store */
             tmp = load_reg(s, rd);
-            gen_st32(tmp, addr, IS_USER(s));
+            tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+            tcg_temp_free_i32(tmp);
         }
         tcg_temp_free_i32(addr);
         break;
@@ -9586,12 +9601,14 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
                 if (insn & (1 << i)) {
                     if (insn & (1 << 11)) {
                         /* pop */
-                        tmp = gen_ld32(addr, IS_USER(s));
+                        tmp = tcg_temp_new_i32();
+                        tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
                         store_reg(s, i, tmp);
                     } else {
                         /* push */
                         tmp = load_reg(s, i);
-                        gen_st32(tmp, addr, IS_USER(s));
+                        tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+                        tcg_temp_free_i32(tmp);
                     }
                     /* advance to the next address.  */
                     tcg_gen_addi_i32(addr, addr, 4);
@@ -9601,13 +9618,15 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
             if (insn & (1 << 8)) {
                 if (insn & (1 << 11)) {
                     /* pop pc */
-                    tmp = gen_ld32(addr, IS_USER(s));
+                    tmp = tcg_temp_new_i32();
+                    tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
                     /* don't set the pc until the rest of the instruction
                        has completed */
                 } else {
                     /* push lr */
                     tmp = load_reg(s, 14);
-                    gen_st32(tmp, addr, IS_USER(s));
+                    tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+                    tcg_temp_free_i32(tmp);
                 }
                 tcg_gen_addi_i32(addr, addr, 4);
             }
@@ -9730,7 +9749,8 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
             if (insn & (1 << i)) {
                 if (insn & (1 << 11)) {
                     /* load */
-                    tmp = gen_ld32(addr, IS_USER(s));
+                    tmp = tcg_temp_new_i32();
+                    tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
                     if (i == rn) {
                         loaded_var = tmp;
                     } else {
@@ -9739,7 +9759,8 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
                 } else {
                     /* store */
                     tmp = load_reg(s, i);
-                    gen_st32(tmp, addr, IS_USER(s));
+                    tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+                    tcg_temp_free_i32(tmp);
                 }
                 /* advance to the next address */
                 tcg_gen_addi_i32(addr, addr, 4);
commit 5a839c0d54fac9db0516904db873a4fe01f50f4b
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu May 23 13:00:00 2013 +0100

    target-arm: Remove gen_{ld,st}* from basic ARM insns
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 3899d0a..e5a2e4c 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6646,10 +6646,12 @@ static void gen_srs(DisasContext *s,
     }
     tcg_gen_addi_i32(addr, addr, offset);
     tmp = load_reg(s, 14);
-    gen_st32(tmp, addr, 0);
+    tcg_gen_qemu_st32(tmp, addr, 0);
+    tcg_temp_free_i32(tmp);
     tmp = load_cpu_field(spsr);
     tcg_gen_addi_i32(addr, addr, 4);
-    gen_st32(tmp, addr, 0);
+    tcg_gen_qemu_st32(tmp, addr, 0);
+    tcg_temp_free_i32(tmp);
     if (writeback) {
         switch (amode) {
         case 0:
@@ -6792,9 +6794,11 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
             if (offset)
                 tcg_gen_addi_i32(addr, addr, offset);
             /* Load PC into tmp and CPSR into tmp2.  */
-            tmp = gen_ld32(addr, 0);
+            tmp = tcg_temp_new_i32();
+            tcg_gen_qemu_ld32u(tmp, addr, 0);
             tcg_gen_addi_i32(addr, addr, 4);
-            tmp2 = gen_ld32(addr, 0);
+            tmp2 = tcg_temp_new_i32();
+            tcg_gen_qemu_ld32u(tmp, addr, 0);
             if (insn & (1 << 21)) {
                 /* Base writeback.  */
                 switch (i) {
@@ -7368,13 +7372,15 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
                            so it is good enough.  */
                         addr = load_reg(s, rn);
                         tmp = load_reg(s, rm);
+                        tmp2 = tcg_temp_new_i32();
                         if (insn & (1 << 22)) {
-                            tmp2 = gen_ld8u(addr, IS_USER(s));
-                            gen_st8(tmp, addr, IS_USER(s));
+                            tcg_gen_qemu_ld8u(tmp2, addr, IS_USER(s));
+                            tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
                         } else {
-                            tmp2 = gen_ld32(addr, IS_USER(s));
-                            gen_st32(tmp, addr, IS_USER(s));
+                            tcg_gen_qemu_ld32u(tmp2, addr, IS_USER(s));
+                            tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
                         }
+                        tcg_temp_free_i32(tmp);
                         tcg_temp_free_i32(addr);
                         store_reg(s, rd, tmp2);
                     }
@@ -7391,16 +7397,17 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
                 address_offset = 0;
                 if (insn & (1 << 20)) {
                     /* load */
+                    tmp = tcg_temp_new_i32();
                     switch(sh) {
                     case 1:
-                        tmp = gen_ld16u(addr, IS_USER(s));
+                        tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
                         break;
                     case 2:
-                        tmp = gen_ld8s(addr, IS_USER(s));
+                        tcg_gen_qemu_ld8s(tmp, addr, IS_USER(s));
                         break;
                     default:
                     case 3:
-                        tmp = gen_ld16s(addr, IS_USER(s));
+                        tcg_gen_qemu_ld16s(tmp, addr, IS_USER(s));
                         break;
                     }
                     load = 1;
@@ -7410,17 +7417,21 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
                     if (sh & 1) {
                         /* store */
                         tmp = load_reg(s, rd);
-                        gen_st32(tmp, addr, IS_USER(s));
+                        tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+                        tcg_temp_free_i32(tmp);
                         tcg_gen_addi_i32(addr, addr, 4);
                         tmp = load_reg(s, rd + 1);
-                        gen_st32(tmp, addr, IS_USER(s));
+                        tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+                        tcg_temp_free_i32(tmp);
                         load = 0;
                     } else {
                         /* load */
-                        tmp = gen_ld32(addr, IS_USER(s));
+                        tmp = tcg_temp_new_i32();
+                        tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
                         store_reg(s, rd, tmp);
                         tcg_gen_addi_i32(addr, addr, 4);
-                        tmp = gen_ld32(addr, IS_USER(s));
+                        tmp = tcg_temp_new_i32();
+                        tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
                         rd++;
                         load = 1;
                     }
@@ -7428,7 +7439,8 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
                 } else {
                     /* store */
                     tmp = load_reg(s, rd);
-                    gen_st16(tmp, addr, IS_USER(s));
+                    tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
+                    tcg_temp_free_i32(tmp);
                     load = 0;
                 }
                 /* Perform base writeback before the loaded value to
@@ -7758,18 +7770,21 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
                 gen_add_data_offset(s, insn, tmp2);
             if (insn & (1 << 20)) {
                 /* load */
+                tmp = tcg_temp_new_i32();
                 if (insn & (1 << 22)) {
-                    tmp = gen_ld8u(tmp2, i);
+                    tcg_gen_qemu_ld8u(tmp, tmp2, i);
                 } else {
-                    tmp = gen_ld32(tmp2, i);
+                    tcg_gen_qemu_ld32u(tmp, tmp2, i);
                 }
             } else {
                 /* store */
                 tmp = load_reg(s, rd);
-                if (insn & (1 << 22))
-                    gen_st8(tmp, tmp2, i);
-                else
-                    gen_st32(tmp, tmp2, i);
+                if (insn & (1 << 22)) {
+                    tcg_gen_qemu_st8(tmp, tmp2, i);
+                } else {
+                    tcg_gen_qemu_st32(tmp, tmp2, i);
+                }
+                tcg_temp_free_i32(tmp);
             }
             if (!(insn & (1 << 24))) {
                 gen_add_data_offset(s, insn, tmp2);
@@ -7833,7 +7848,8 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
                     if (insn & (1 << i)) {
                         if (insn & (1 << 20)) {
                             /* load */
-                            tmp = gen_ld32(addr, IS_USER(s));
+                            tmp = tcg_temp_new_i32();
+                            tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
                             if (user) {
                                 tmp2 = tcg_const_i32(i);
                                 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
@@ -7860,7 +7876,8 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
                             } else {
                                 tmp = load_reg(s, i);
                             }
-                            gen_st32(tmp, addr, IS_USER(s));
+                            tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+                            tcg_temp_free_i32(tmp);
                         }
                         j++;
                         /* no need to add after the last transfer */
@@ -9026,13 +9043,25 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
         }
         if (insn & (1 << 20)) {
             /* Load.  */
+            tmp = tcg_temp_new_i32();
             switch (op) {
-            case 0: tmp = gen_ld8u(addr, user); break;
-            case 4: tmp = gen_ld8s(addr, user); break;
-            case 1: tmp = gen_ld16u(addr, user); break;
-            case 5: tmp = gen_ld16s(addr, user); break;
-            case 2: tmp = gen_ld32(addr, user); break;
+            case 0:
+                tcg_gen_qemu_ld8u(tmp, addr, user);
+                break;
+            case 4:
+                tcg_gen_qemu_ld8s(tmp, addr, user);
+                break;
+            case 1:
+                tcg_gen_qemu_ld16u(tmp, addr, user);
+                break;
+            case 5:
+                tcg_gen_qemu_ld16s(tmp, addr, user);
+                break;
+            case 2:
+                tcg_gen_qemu_ld32u(tmp, addr, user);
+                break;
             default:
+                tcg_temp_free_i32(tmp);
                 tcg_temp_free_i32(addr);
                 goto illegal_op;
             }
@@ -9045,13 +9074,21 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
             /* Store.  */
             tmp = load_reg(s, rs);
             switch (op) {
-            case 0: gen_st8(tmp, addr, user); break;
-            case 1: gen_st16(tmp, addr, user); break;
-            case 2: gen_st32(tmp, addr, user); break;
+            case 0:
+                tcg_gen_qemu_st8(tmp, addr, user);
+                break;
+            case 1:
+                tcg_gen_qemu_st16(tmp, addr, user);
+                break;
+            case 2:
+                tcg_gen_qemu_st32(tmp, addr, user);
+                break;
             default:
+                tcg_temp_free_i32(tmp);
                 tcg_temp_free_i32(addr);
                 goto illegal_op;
             }
+            tcg_temp_free_i32(tmp);
         }
         if (postinc)
             tcg_gen_addi_i32(addr, addr, imm);
commit 94ee24e7fbb0d6d6fd63627c2e89d2513cb7b893
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu May 23 12:59:59 2013 +0100

    target-arm: Remove use of gen_{ld,st}* from ldrex/strex
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 057b180..3899d0a 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6493,18 +6493,18 @@ static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
                                TCGv_i32 addr, int size)
 {
-    TCGv_i32 tmp;
+    TCGv_i32 tmp = tcg_temp_new_i32();
 
     switch (size) {
     case 0:
-        tmp = gen_ld8u(addr, IS_USER(s));
+        tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
         break;
     case 1:
-        tmp = gen_ld16u(addr, IS_USER(s));
+        tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
         break;
     case 2:
     case 3:
-        tmp = gen_ld32(addr, IS_USER(s));
+        tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
         break;
     default:
         abort();
@@ -6514,7 +6514,8 @@ static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
     if (size == 3) {
         TCGv_i32 tmp2 = tcg_temp_new_i32();
         tcg_gen_addi_i32(tmp2, addr, 4);
-        tmp = gen_ld32(tmp2, IS_USER(s));
+        tmp = tcg_temp_new_i32();
+        tcg_gen_qemu_ld32u(tmp, tmp2, IS_USER(s));
         tcg_temp_free_i32(tmp2);
         tcg_gen_mov_i32(cpu_exclusive_high, tmp);
         store_reg(s, rt2, tmp);
@@ -6553,16 +6554,17 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
     fail_label = gen_new_label();
     done_label = gen_new_label();
     tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
+    tmp = tcg_temp_new_i32();
     switch (size) {
     case 0:
-        tmp = gen_ld8u(addr, IS_USER(s));
+        tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
         break;
     case 1:
-        tmp = gen_ld16u(addr, IS_USER(s));
+        tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
         break;
     case 2:
     case 3:
-        tmp = gen_ld32(addr, IS_USER(s));
+        tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
         break;
     default:
         abort();
@@ -6572,7 +6574,8 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
     if (size == 3) {
         TCGv_i32 tmp2 = tcg_temp_new_i32();
         tcg_gen_addi_i32(tmp2, addr, 4);
-        tmp = gen_ld32(tmp2, IS_USER(s));
+        tmp = tcg_temp_new_i32();
+        tcg_gen_qemu_ld32u(tmp, tmp2, IS_USER(s));
         tcg_temp_free_i32(tmp2);
         tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
         tcg_temp_free_i32(tmp);
@@ -6580,22 +6583,24 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
     tmp = load_reg(s, rt);
     switch (size) {
     case 0:
-        gen_st8(tmp, addr, IS_USER(s));
+        tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
         break;
     case 1:
-        gen_st16(tmp, addr, IS_USER(s));
+        tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
         break;
     case 2:
     case 3:
-        gen_st32(tmp, addr, IS_USER(s));
+        tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
         break;
     default:
         abort();
     }
+    tcg_temp_free_i32(tmp);
     if (size == 3) {
         tcg_gen_addi_i32(addr, addr, 4);
         tmp = load_reg(s, rt2);
-        gen_st32(tmp, addr, IS_USER(s));
+        tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+        tcg_temp_free_i32(tmp);
     }
     tcg_gen_movi_i32(cpu_R[rd], 0);
     tcg_gen_br(done_label);
commit 58ab8e96469955f8b575bfe1f6b1e992f8f36c0f
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu May 23 12:59:58 2013 +0100

    target-arm: Remove uses of gen_{ld,st}* from Neon code
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 7ce9a1c..057b180 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -2572,18 +2572,18 @@ static void gen_neon_dup_high16(TCGv_i32 var)
 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
 {
     /* Load a single Neon element and replicate into a 32 bit TCG reg */
-    TCGv_i32 tmp;
+    TCGv_i32 tmp = tcg_temp_new_i32();
     switch (size) {
     case 0:
-        tmp = gen_ld8u(addr, IS_USER(s));
+        tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
         gen_neon_dup_u8(tmp, 0);
         break;
     case 1:
-        tmp = gen_ld16u(addr, IS_USER(s));
+        tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
         gen_neon_dup_low16(tmp);
         break;
     case 2:
-        tmp = gen_ld32(addr, IS_USER(s));
+        tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
         break;
     default: /* Avoid compiler warnings.  */
         abort();
@@ -3872,18 +3872,22 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                 for (pass = 0; pass < 2; pass++) {
                     if (size == 2) {
                         if (load) {
-                            tmp = gen_ld32(addr, IS_USER(s));
+                            tmp = tcg_temp_new_i32();
+                            tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
                             neon_store_reg(rd, pass, tmp);
                         } else {
                             tmp = neon_load_reg(rd, pass);
-                            gen_st32(tmp, addr, IS_USER(s));
+                            tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
+                            tcg_temp_free_i32(tmp);
                         }
                         tcg_gen_addi_i32(addr, addr, stride);
                     } else if (size == 1) {
                         if (load) {
-                            tmp = gen_ld16u(addr, IS_USER(s));
+                            tmp = tcg_temp_new_i32();
+                            tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
                             tcg_gen_addi_i32(addr, addr, stride);
-                            tmp2 = gen_ld16u(addr, IS_USER(s));
+                            tmp2 = tcg_temp_new_i32();
+                            tcg_gen_qemu_ld16u(tmp2, addr, IS_USER(s));
                             tcg_gen_addi_i32(addr, addr, stride);
                             tcg_gen_shli_i32(tmp2, tmp2, 16);
                             tcg_gen_or_i32(tmp, tmp, tmp2);
@@ -3893,16 +3897,19 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                             tmp = neon_load_reg(rd, pass);
                             tmp2 = tcg_temp_new_i32();
                             tcg_gen_shri_i32(tmp2, tmp, 16);
-                            gen_st16(tmp, addr, IS_USER(s));
+                            tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
+                            tcg_temp_free_i32(tmp);
                             tcg_gen_addi_i32(addr, addr, stride);
-                            gen_st16(tmp2, addr, IS_USER(s));
+                            tcg_gen_qemu_st16(tmp2, addr, IS_USER(s));
+                            tcg_temp_free_i32(tmp2);
                             tcg_gen_addi_i32(addr, addr, stride);
                         }
                     } else /* size == 0 */ {
                         if (load) {
                             TCGV_UNUSED_I32(tmp2);
                             for (n = 0; n < 4; n++) {
-                                tmp = gen_ld8u(addr, IS_USER(s));
+                                tmp = tcg_temp_new_i32();
+                                tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
                                 tcg_gen_addi_i32(addr, addr, stride);
                                 if (n == 0) {
                                     tmp2 = tmp;
@@ -3922,7 +3929,8 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                                 } else {
                                     tcg_gen_shri_i32(tmp, tmp2, n * 8);
                                 }
-                                gen_st8(tmp, addr, IS_USER(s));
+                                tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
+                                tcg_temp_free_i32(tmp);
                                 tcg_gen_addi_i32(addr, addr, stride);
                             }
                             tcg_temp_free_i32(tmp2);
@@ -4042,15 +4050,16 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
             load_reg_var(s, addr, rn);
             for (reg = 0; reg < nregs; reg++) {
                 if (load) {
+                    tmp = tcg_temp_new_i32();
                     switch (size) {
                     case 0:
-                        tmp = gen_ld8u(addr, IS_USER(s));
+                        tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
                         break;
                     case 1:
-                        tmp = gen_ld16u(addr, IS_USER(s));
+                        tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
                         break;
                     case 2:
-                        tmp = gen_ld32(addr, IS_USER(s));
+                        tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
                         break;
                     default: /* Avoid compiler warnings.  */
                         abort();
@@ -4068,15 +4077,16 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                         tcg_gen_shri_i32(tmp, tmp, shift);
                     switch (size) {
                     case 0:
-                        gen_st8(tmp, addr, IS_USER(s));
+                        tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
                         break;
                     case 1:
-                        gen_st16(tmp, addr, IS_USER(s));
+                        tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
                         break;
                     case 2:
-                        gen_st32(tmp, addr, IS_USER(s));
+                        tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
                         break;
                     }
+                    tcg_temp_free_i32(tmp);
                 }
                 rd += stride;
                 tcg_gen_addi_i32(addr, addr, 1 << size);
commit 29531141a7658cfb9f6e5f72a685c3859a5fff8b
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu May 23 12:59:57 2013 +0100

    target-arm: Remove uses of gen_{ld,st}* from iWMMXt code
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 8e46527..7ce9a1c 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -1473,13 +1473,15 @@ static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
                         tcg_gen_qemu_ld64(cpu_M0, addr, IS_USER(s));
                         i = 0;
                     } else {				/* WLDRW wRd */
-                        tmp = gen_ld32(addr, IS_USER(s));
+                        tmp = tcg_temp_new_i32();
+                        tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
                     }
                 } else {
+                    tmp = tcg_temp_new_i32();
                     if (insn & (1 << 22)) {		/* WLDRH */
-                        tmp = gen_ld16u(addr, IS_USER(s));
+                        tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
                     } else {				/* WLDRB */
-                        tmp = gen_ld8u(addr, IS_USER(s));
+                        tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
                     }
                 }
                 if (i) {
@@ -1491,28 +1493,28 @@ static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
         } else {
             if ((insn >> 28) == 0xf) {			/* WSTRW wCx */
                 tmp = iwmmxt_load_creg(wrd);
-                gen_st32(tmp, addr, IS_USER(s));
+                tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
             } else {
                 gen_op_iwmmxt_movq_M0_wRn(wrd);
                 tmp = tcg_temp_new_i32();
                 if (insn & (1 << 8)) {
                     if (insn & (1 << 22)) {		/* WSTRD */
-                        tcg_temp_free_i32(tmp);
                         tcg_gen_qemu_st64(cpu_M0, addr, IS_USER(s));
                     } else {				/* WSTRW wRd */
                         tcg_gen_trunc_i64_i32(tmp, cpu_M0);
-                        gen_st32(tmp, addr, IS_USER(s));
+                        tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
                     }
                 } else {
                     if (insn & (1 << 22)) {		/* WSTRH */
                         tcg_gen_trunc_i64_i32(tmp, cpu_M0);
-                        gen_st16(tmp, addr, IS_USER(s));
+                        tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
                     } else {				/* WSTRB */
                         tcg_gen_trunc_i64_i32(tmp, cpu_M0);
-                        gen_st8(tmp, addr, IS_USER(s));
+                        tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
                     }
                 }
             }
+            tcg_temp_free_i32(tmp);
         }
         tcg_temp_free_i32(addr);
         return 0;
commit 8ed1237d6401e0bd9461417b58b07e545bbc4b7e
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu May 23 12:59:56 2013 +0100

    target-arm: Remove gen_ld64() and gen_st64()
    
    gen_ld64() and gen_st64() are used only in one place, so just
    expand them out.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 75972cf..8e46527 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -871,12 +871,6 @@ static inline TCGv_i32 gen_ld32(TCGv_i32 addr, int index)
     tcg_gen_qemu_ld32u(tmp, addr, index);
     return tmp;
 }
-static inline TCGv_i64 gen_ld64(TCGv_i32 addr, int index)
-{
-    TCGv_i64 tmp = tcg_temp_new_i64();
-    tcg_gen_qemu_ld64(tmp, addr, index);
-    return tmp;
-}
 static inline void gen_st8(TCGv_i32 val, TCGv_i32 addr, int index)
 {
     tcg_gen_qemu_st8(val, addr, index);
@@ -892,11 +886,6 @@ static inline void gen_st32(TCGv_i32 val, TCGv_i32 addr, int index)
     tcg_gen_qemu_st32(val, addr, index);
     tcg_temp_free_i32(val);
 }
-static inline void gen_st64(TCGv_i64 val, TCGv_i32 addr, int index)
-{
-    tcg_gen_qemu_st64(val, addr, index);
-    tcg_temp_free_i64(val);
-}
 
 static inline void gen_set_pc_im(uint32_t val)
 {
@@ -3867,15 +3856,15 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                 tcg_gen_addi_i32(addr, addr, 1 << size);
             }
             if (size == 3) {
+                tmp64 = tcg_temp_new_i64();
                 if (load) {
-                    tmp64 = gen_ld64(addr, IS_USER(s));
+                    tcg_gen_qemu_ld64(tmp64, addr, IS_USER(s));
                     neon_store_reg64(tmp64, rd);
-                    tcg_temp_free_i64(tmp64);
                 } else {
-                    tmp64 = tcg_temp_new_i64();
                     neon_load_reg64(tmp64, rd);
-                    gen_st64(tmp64, addr, IS_USER(s));
+                    tcg_gen_qemu_st64(tmp64, addr, IS_USER(s));
                 }
+                tcg_temp_free_i64(tmp64);
                 tcg_gen_addi_i32(addr, addr, stride);
             } else {
                 for (pass = 0; pass < 2; pass++) {
commit 39d5492a186d156d4acc306ae258d7e04f8a6c29
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu May 23 12:59:55 2013 +0100

    target-arm: Don't use TCGv when we mean TCGv_i32
    
    TCGv changes size depending on the compile time value of
    TARGET_LONG_BITS.  This is useful for generating code for MIPS style
    "instructions are the same but the register width changes" CPUs, and
    also for the generic bits of QEMU which operate on "width of a
    virtual address" values, but mostly in the ARM target code we were
    using it purely as a shorthand for "any 32 bit value".
    
    This needs to change in preparation for AArch64 support, since an
    AArch64-capable v8 core will have 64 bit virtual addresses but still
    use 32 bit values for the 32 bit instruction set.
    
    This patch mechanically converts all the occurrences of TCGv,
    tcg_temp_new(), tcg_temp_free(), tcg_temp_local_new() and
    TCGV_UNUSED() to their explicitly 32 bit counterparts.  This is
    correct for everything except the arguments to tcg_gen_qemu_{ld,st}*,
    which really do need to be TCGv and so will require a 32-to-64
    conversion when building the 32 bit code for AArch64.  Those changes
    will be in a separate patch for easier review.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-arm/translate.c b/target-arm/translate.c
index a1b7b8c..75972cf 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -95,7 +95,7 @@ static TCGv_i32 cpu_exclusive_info;
 #endif
 
 /* FIXME:  These should be removed.  */
-static TCGv cpu_F0s, cpu_F1s;
+static TCGv_i32 cpu_F0s, cpu_F1s;
 static TCGv_i64 cpu_F0d, cpu_F1d;
 
 #include "exec/gen-icount.h"
@@ -138,16 +138,16 @@ void arm_translate_init(void)
 #include "helper.h"
 }
 
-static inline TCGv load_cpu_offset(int offset)
+static inline TCGv_i32 load_cpu_offset(int offset)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_ld_i32(tmp, cpu_env, offset);
     return tmp;
 }
 
 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
 
-static inline void store_cpu_offset(TCGv var, int offset)
+static inline void store_cpu_offset(TCGv_i32 var, int offset)
 {
     tcg_gen_st_i32(var, cpu_env, offset);
     tcg_temp_free_i32(var);
@@ -157,7 +157,7 @@ static inline void store_cpu_offset(TCGv var, int offset)
     store_cpu_offset(var, offsetof(CPUARMState, name))
 
 /* Set a variable to the value of a CPU register.  */
-static void load_reg_var(DisasContext *s, TCGv var, int reg)
+static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
 {
     if (reg == 15) {
         uint32_t addr;
@@ -173,16 +173,16 @@ static void load_reg_var(DisasContext *s, TCGv var, int reg)
 }
 
 /* Create a new temporary and set it to the value of a CPU register.  */
-static inline TCGv load_reg(DisasContext *s, int reg)
+static inline TCGv_i32 load_reg(DisasContext *s, int reg)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     load_reg_var(s, tmp, reg);
     return tmp;
 }
 
 /* Set a CPU register.  The source must be a temporary and will be
    marked as dead.  */
-static void store_reg(DisasContext *s, int reg, TCGv var)
+static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
 {
     if (reg == 15) {
         tcg_gen_andi_i32(var, var, ~1);
@@ -202,9 +202,9 @@ static void store_reg(DisasContext *s, int reg, TCGv var)
 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
 
 
-static inline void gen_set_cpsr(TCGv var, uint32_t mask)
+static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
 {
-    TCGv tmp_mask = tcg_const_i32(mask);
+    TCGv_i32 tmp_mask = tcg_const_i32(mask);
     gen_helper_cpsr_write(cpu_env, var, tmp_mask);
     tcg_temp_free_i32(tmp_mask);
 }
@@ -213,16 +213,16 @@ static inline void gen_set_cpsr(TCGv var, uint32_t mask)
 
 static void gen_exception(int excp)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_movi_i32(tmp, excp);
     gen_helper_exception(cpu_env, tmp);
     tcg_temp_free_i32(tmp);
 }
 
-static void gen_smul_dual(TCGv a, TCGv b)
+static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
 {
-    TCGv tmp1 = tcg_temp_new_i32();
-    TCGv tmp2 = tcg_temp_new_i32();
+    TCGv_i32 tmp1 = tcg_temp_new_i32();
+    TCGv_i32 tmp2 = tcg_temp_new_i32();
     tcg_gen_ext16s_i32(tmp1, a);
     tcg_gen_ext16s_i32(tmp2, b);
     tcg_gen_mul_i32(tmp1, tmp1, tmp2);
@@ -235,9 +235,9 @@ static void gen_smul_dual(TCGv a, TCGv b)
 }
 
 /* Byteswap each halfword.  */
-static void gen_rev16(TCGv var)
+static void gen_rev16(TCGv_i32 var)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_shri_i32(tmp, var, 8);
     tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
     tcg_gen_shli_i32(var, var, 8);
@@ -247,7 +247,7 @@ static void gen_rev16(TCGv var)
 }
 
 /* Byteswap low halfword and sign extend.  */
-static void gen_revsh(TCGv var)
+static void gen_revsh(TCGv_i32 var)
 {
     tcg_gen_ext16u_i32(var, var);
     tcg_gen_bswap16_i32(var, var);
@@ -255,7 +255,7 @@ static void gen_revsh(TCGv var)
 }
 
 /* Unsigned bitfield extract.  */
-static void gen_ubfx(TCGv var, int shift, uint32_t mask)
+static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
 {
     if (shift)
         tcg_gen_shri_i32(var, var, shift);
@@ -263,7 +263,7 @@ static void gen_ubfx(TCGv var, int shift, uint32_t mask)
 }
 
 /* Signed bitfield extract.  */
-static void gen_sbfx(TCGv var, int shift, int width)
+static void gen_sbfx(TCGv_i32 var, int shift, int width)
 {
     uint32_t signbit;
 
@@ -278,7 +278,7 @@ static void gen_sbfx(TCGv var, int shift, int width)
 }
 
 /* Return (b << 32) + a. Mark inputs as dead */
-static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv b)
+static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
 {
     TCGv_i64 tmp64 = tcg_temp_new_i64();
 
@@ -292,7 +292,7 @@ static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv b)
 }
 
 /* Return (b << 32) - a. Mark inputs as dead. */
-static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv b)
+static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
 {
     TCGv_i64 tmp64 = tcg_temp_new_i64();
 
@@ -306,10 +306,10 @@ static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv b)
 }
 
 /* 32x32->64 multiply.  Marks inputs as dead.  */
-static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
+static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
 {
-    TCGv lo = tcg_temp_new_i32();
-    TCGv hi = tcg_temp_new_i32();
+    TCGv_i32 lo = tcg_temp_new_i32();
+    TCGv_i32 hi = tcg_temp_new_i32();
     TCGv_i64 ret;
 
     tcg_gen_mulu2_i32(lo, hi, a, b);
@@ -318,16 +318,16 @@ static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
 
     ret = tcg_temp_new_i64();
     tcg_gen_concat_i32_i64(ret, lo, hi);
-    tcg_temp_free(lo);
-    tcg_temp_free(hi);
+    tcg_temp_free_i32(lo);
+    tcg_temp_free_i32(hi);
 
     return ret;
 }
 
-static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
+static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
 {
-    TCGv lo = tcg_temp_new_i32();
-    TCGv hi = tcg_temp_new_i32();
+    TCGv_i32 lo = tcg_temp_new_i32();
+    TCGv_i32 hi = tcg_temp_new_i32();
     TCGv_i64 ret;
 
     tcg_gen_muls2_i32(lo, hi, a, b);
@@ -336,16 +336,16 @@ static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
 
     ret = tcg_temp_new_i64();
     tcg_gen_concat_i32_i64(ret, lo, hi);
-    tcg_temp_free(lo);
-    tcg_temp_free(hi);
+    tcg_temp_free_i32(lo);
+    tcg_temp_free_i32(hi);
 
     return ret;
 }
 
 /* Swap low and high halfwords.  */
-static void gen_swap_half(TCGv var)
+static void gen_swap_half(TCGv_i32 var)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_shri_i32(tmp, var, 16);
     tcg_gen_shli_i32(var, var, 16);
     tcg_gen_or_i32(var, var, tmp);
@@ -359,9 +359,9 @@ static void gen_swap_half(TCGv var)
     t0 = (t0 + t1) ^ tmp;
  */
 
-static void gen_add16(TCGv t0, TCGv t1)
+static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_xor_i32(tmp, t0, t1);
     tcg_gen_andi_i32(tmp, tmp, 0x8000);
     tcg_gen_andi_i32(t0, t0, ~0x8000);
@@ -373,34 +373,34 @@ static void gen_add16(TCGv t0, TCGv t1)
 }
 
 /* Set CF to the top bit of var.  */
-static void gen_set_CF_bit31(TCGv var)
+static void gen_set_CF_bit31(TCGv_i32 var)
 {
     tcg_gen_shri_i32(cpu_CF, var, 31);
 }
 
 /* Set N and Z flags from var.  */
-static inline void gen_logic_CC(TCGv var)
+static inline void gen_logic_CC(TCGv_i32 var)
 {
     tcg_gen_mov_i32(cpu_NF, var);
     tcg_gen_mov_i32(cpu_ZF, var);
 }
 
 /* T0 += T1 + CF.  */
-static void gen_adc(TCGv t0, TCGv t1)
+static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
 {
     tcg_gen_add_i32(t0, t0, t1);
     tcg_gen_add_i32(t0, t0, cpu_CF);
 }
 
 /* dest = T0 + T1 + CF. */
-static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
+static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 {
     tcg_gen_add_i32(dest, t0, t1);
     tcg_gen_add_i32(dest, dest, cpu_CF);
 }
 
 /* dest = T0 - T1 + CF - 1.  */
-static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
+static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 {
     tcg_gen_sub_i32(dest, t0, t1);
     tcg_gen_add_i32(dest, dest, cpu_CF);
@@ -408,9 +408,9 @@ static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
 }
 
 /* dest = T0 + T1. Compute C, N, V and Z flags */
-static void gen_add_CC(TCGv dest, TCGv t0, TCGv t1)
+static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_movi_i32(tmp, 0);
     tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
     tcg_gen_mov_i32(cpu_ZF, cpu_NF);
@@ -422,9 +422,9 @@ static void gen_add_CC(TCGv dest, TCGv t0, TCGv t1)
 }
 
 /* dest = T0 + T1 + CF.  Compute C, N, V and Z flags */
-static void gen_adc_CC(TCGv dest, TCGv t0, TCGv t1)
+static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     if (TCG_TARGET_HAS_add2_i32) {
         tcg_gen_movi_i32(tmp, 0);
         tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
@@ -450,9 +450,9 @@ static void gen_adc_CC(TCGv dest, TCGv t0, TCGv t1)
 }
 
 /* dest = T0 - T1. Compute C, N, V and Z flags */
-static void gen_sub_CC(TCGv dest, TCGv t0, TCGv t1)
+static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 {
-    TCGv tmp;
+    TCGv_i32 tmp;
     tcg_gen_sub_i32(cpu_NF, t0, t1);
     tcg_gen_mov_i32(cpu_ZF, cpu_NF);
     tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
@@ -465,18 +465,18 @@ static void gen_sub_CC(TCGv dest, TCGv t0, TCGv t1)
 }
 
 /* dest = T0 + ~T1 + CF.  Compute C, N, V and Z flags */
-static void gen_sbc_CC(TCGv dest, TCGv t0, TCGv t1)
+static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_not_i32(tmp, t1);
     gen_adc_CC(dest, t0, tmp);
-    tcg_temp_free(tmp);
+    tcg_temp_free_i32(tmp);
 }
 
 #define GEN_SHIFT(name)                                               \
-static void gen_##name(TCGv dest, TCGv t0, TCGv t1)                   \
+static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)       \
 {                                                                     \
-    TCGv tmp1, tmp2, tmp3;                                            \
+    TCGv_i32 tmp1, tmp2, tmp3;                                        \
     tmp1 = tcg_temp_new_i32();                                        \
     tcg_gen_andi_i32(tmp1, t1, 0xff);                                 \
     tmp2 = tcg_const_i32(0);                                          \
@@ -492,9 +492,9 @@ GEN_SHIFT(shl)
 GEN_SHIFT(shr)
 #undef GEN_SHIFT
 
-static void gen_sar(TCGv dest, TCGv t0, TCGv t1)
+static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 {
-    TCGv tmp1, tmp2;
+    TCGv_i32 tmp1, tmp2;
     tmp1 = tcg_temp_new_i32();
     tcg_gen_andi_i32(tmp1, t1, 0xff);
     tmp2 = tcg_const_i32(0x1f);
@@ -504,17 +504,17 @@ static void gen_sar(TCGv dest, TCGv t0, TCGv t1)
     tcg_temp_free_i32(tmp1);
 }
 
-static void tcg_gen_abs_i32(TCGv dest, TCGv src)
+static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
 {
-    TCGv c0 = tcg_const_i32(0);
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 c0 = tcg_const_i32(0);
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_neg_i32(tmp, src);
     tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
     tcg_temp_free_i32(c0);
     tcg_temp_free_i32(tmp);
 }
 
-static void shifter_out_im(TCGv var, int shift)
+static void shifter_out_im(TCGv_i32 var, int shift)
 {
     if (shift == 0) {
         tcg_gen_andi_i32(cpu_CF, var, 1);
@@ -527,7 +527,8 @@ static void shifter_out_im(TCGv var, int shift)
 }
 
 /* Shift by immediate.  Includes special handling for shift == 0.  */
-static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
+static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
+                                    int shift, int flags)
 {
     switch (shiftop) {
     case 0: /* LSL */
@@ -564,7 +565,7 @@ static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
                 shifter_out_im(var, shift - 1);
             tcg_gen_rotri_i32(var, var, shift); break;
         } else {
-            TCGv tmp = tcg_temp_new_i32();
+            TCGv_i32 tmp = tcg_temp_new_i32();
             tcg_gen_shli_i32(tmp, cpu_CF, 31);
             if (flags)
                 shifter_out_im(var, 0);
@@ -575,8 +576,8 @@ static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
     }
 };
 
-static inline void gen_arm_shift_reg(TCGv var, int shiftop,
-                                     TCGv shift, int flags)
+static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
+                                     TCGv_i32 shift, int flags)
 {
     if (flags) {
         switch (shiftop) {
@@ -612,7 +613,7 @@ static inline void gen_arm_shift_reg(TCGv var, int shiftop,
     case 4: gen_pas_helper(glue(pfx,add8)); break; \
     case 7: gen_pas_helper(glue(pfx,sub8)); break; \
     }
-static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
+static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
 {
     TCGv_ptr tmp;
 
@@ -659,7 +660,7 @@ static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
     case 5: gen_pas_helper(glue(pfx,sub16)); break; \
     case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
     }
-static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
+static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
 {
     TCGv_ptr tmp;
 
@@ -698,7 +699,7 @@ static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
 
 static void gen_test_cc(int cc, int label)
 {
-    TCGv tmp;
+    TCGv_i32 tmp;
     int inv;
 
     switch (cc) {
@@ -792,7 +793,7 @@ static const uint8_t table_logic_cc[16] = {
 /* Set PC and Thumb state from an immediate address.  */
 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
 {
-    TCGv tmp;
+    TCGv_i32 tmp;
 
     s->is_jmp = DISAS_UPDATE;
     if (s->thumb != (addr & 1)) {
@@ -805,7 +806,7 @@ static inline void gen_bx_im(DisasContext *s, uint32_t addr)
 }
 
 /* Set PC and Thumb state from var.  var is marked as dead.  */
-static inline void gen_bx(DisasContext *s, TCGv var)
+static inline void gen_bx(DisasContext *s, TCGv_i32 var)
 {
     s->is_jmp = DISAS_UPDATE;
     tcg_gen_andi_i32(cpu_R[15], var, ~1);
@@ -817,7 +818,7 @@ static inline void gen_bx(DisasContext *s, TCGv var)
    to r15 in ARM architecture v7 and above. The source must be a temporary
    and will be marked as dead. */
 static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
-                                int reg, TCGv var)
+                                int reg, TCGv_i32 var)
 {
     if (reg == 15 && ENABLE_ARCH_7) {
         gen_bx(s, var);
@@ -831,7 +832,7 @@ static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
  * the results of a LDR/LDM/POP into r15, and corresponds to the cases
  * in the ARM ARM which use the LoadWritePC() pseudocode function. */
 static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
-                                int reg, TCGv var)
+                                       int reg, TCGv_i32 var)
 {
     if (reg == 15 && ENABLE_ARCH_5) {
         gen_bx(s, var);
@@ -840,58 +841,58 @@ static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
     }
 }
 
-static inline TCGv gen_ld8s(TCGv addr, int index)
+static inline TCGv_i32 gen_ld8s(TCGv_i32 addr, int index)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_qemu_ld8s(tmp, addr, index);
     return tmp;
 }
-static inline TCGv gen_ld8u(TCGv addr, int index)
+static inline TCGv_i32 gen_ld8u(TCGv_i32 addr, int index)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_qemu_ld8u(tmp, addr, index);
     return tmp;
 }
-static inline TCGv gen_ld16s(TCGv addr, int index)
+static inline TCGv_i32 gen_ld16s(TCGv_i32 addr, int index)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_qemu_ld16s(tmp, addr, index);
     return tmp;
 }
-static inline TCGv gen_ld16u(TCGv addr, int index)
+static inline TCGv_i32 gen_ld16u(TCGv_i32 addr, int index)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_qemu_ld16u(tmp, addr, index);
     return tmp;
 }
-static inline TCGv gen_ld32(TCGv addr, int index)
+static inline TCGv_i32 gen_ld32(TCGv_i32 addr, int index)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_qemu_ld32u(tmp, addr, index);
     return tmp;
 }
-static inline TCGv_i64 gen_ld64(TCGv addr, int index)
+static inline TCGv_i64 gen_ld64(TCGv_i32 addr, int index)
 {
     TCGv_i64 tmp = tcg_temp_new_i64();
     tcg_gen_qemu_ld64(tmp, addr, index);
     return tmp;
 }
-static inline void gen_st8(TCGv val, TCGv addr, int index)
+static inline void gen_st8(TCGv_i32 val, TCGv_i32 addr, int index)
 {
     tcg_gen_qemu_st8(val, addr, index);
     tcg_temp_free_i32(val);
 }
-static inline void gen_st16(TCGv val, TCGv addr, int index)
+static inline void gen_st16(TCGv_i32 val, TCGv_i32 addr, int index)
 {
     tcg_gen_qemu_st16(val, addr, index);
     tcg_temp_free_i32(val);
 }
-static inline void gen_st32(TCGv val, TCGv addr, int index)
+static inline void gen_st32(TCGv_i32 val, TCGv_i32 addr, int index)
 {
     tcg_gen_qemu_st32(val, addr, index);
     tcg_temp_free_i32(val);
 }
-static inline void gen_st64(TCGv_i64 val, TCGv addr, int index)
+static inline void gen_st64(TCGv_i64 val, TCGv_i32 addr, int index)
 {
     tcg_gen_qemu_st64(val, addr, index);
     tcg_temp_free_i64(val);
@@ -910,10 +911,10 @@ static inline void gen_lookup_tb(DisasContext *s)
 }
 
 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
-                                       TCGv var)
+                                       TCGv_i32 var)
 {
     int val, rm, shift, shiftop;
-    TCGv offset;
+    TCGv_i32 offset;
 
     if (!(insn & (1 << 25))) {
         /* immediate */
@@ -938,10 +939,10 @@ static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
 }
 
 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
-                                        int extra, TCGv var)
+                                        int extra, TCGv_i32 var)
 {
     int val, rm;
-    TCGv offset;
+    TCGv_i32 offset;
 
     if (insn & (1 << 22)) {
         /* immediate */
@@ -1104,7 +1105,7 @@ VFP_GEN_FTOI(tosiz)
 #define VFP_GEN_FIX(name) \
 static inline void gen_vfp_##name(int dp, int shift, int neon) \
 { \
-    TCGv tmp_shift = tcg_const_i32(shift); \
+    TCGv_i32 tmp_shift = tcg_const_i32(shift); \
     TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
     if (dp) { \
         gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
@@ -1124,7 +1125,7 @@ VFP_GEN_FIX(uhto)
 VFP_GEN_FIX(ulto)
 #undef VFP_GEN_FIX
 
-static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv addr)
+static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
 {
     if (dp)
         tcg_gen_qemu_ld64(cpu_F0d, addr, IS_USER(s));
@@ -1132,7 +1133,7 @@ static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv addr)
         tcg_gen_qemu_ld32u(cpu_F0s, addr, IS_USER(s));
 }
 
-static inline void gen_vfp_st(DisasContext *s, int dp, TCGv addr)
+static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
 {
     if (dp)
         tcg_gen_qemu_st64(cpu_F0d, addr, IS_USER(s));
@@ -1164,14 +1165,14 @@ neon_reg_offset (int reg, int n)
     return vfp_reg_offset(0, sreg);
 }
 
-static TCGv neon_load_reg(int reg, int pass)
+static TCGv_i32 neon_load_reg(int reg, int pass)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
     return tmp;
 }
 
-static void neon_store_reg(int reg, int pass, TCGv var)
+static void neon_store_reg(int reg, int pass, TCGv_i32 var)
 {
     tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
     tcg_temp_free_i32(var);
@@ -1228,14 +1229,14 @@ static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
     tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
 }
 
-static inline TCGv iwmmxt_load_creg(int reg)
+static inline TCGv_i32 iwmmxt_load_creg(int reg)
 {
-    TCGv var = tcg_temp_new_i32();
+    TCGv_i32 var = tcg_temp_new_i32();
     tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
     return var;
 }
 
-static inline void iwmmxt_store_creg(int reg, TCGv var)
+static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
 {
     tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
     tcg_temp_free_i32(var);
@@ -1353,7 +1354,7 @@ IWMMXT_OP_ENV(packsq)
 
 static void gen_op_iwmmxt_set_mup(void)
 {
-    TCGv tmp;
+    TCGv_i32 tmp;
     tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
     tcg_gen_ori_i32(tmp, tmp, 2);
     store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
@@ -1361,7 +1362,7 @@ static void gen_op_iwmmxt_set_mup(void)
 
 static void gen_op_iwmmxt_set_cup(void)
 {
-    TCGv tmp;
+    TCGv_i32 tmp;
     tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
     tcg_gen_ori_i32(tmp, tmp, 1);
     store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
@@ -1369,7 +1370,7 @@ static void gen_op_iwmmxt_set_cup(void)
 
 static void gen_op_iwmmxt_setpsr_nz(void)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
     store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
 }
@@ -1381,11 +1382,12 @@ static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
     tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
 }
 
-static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest)
+static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
+                                     TCGv_i32 dest)
 {
     int rd;
     uint32_t offset;
-    TCGv tmp;
+    TCGv_i32 tmp;
 
     rd = (insn >> 16) & 0xf;
     tmp = load_reg(s, rd);
@@ -1415,10 +1417,10 @@ static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest)
     return 0;
 }
 
-static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv dest)
+static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
 {
     int rd = (insn >> 0) & 0xf;
-    TCGv tmp;
+    TCGv_i32 tmp;
 
     if (insn & (1 << 8)) {
         if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
@@ -1443,8 +1445,8 @@ static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
 {
     int rd, wrd;
     int rdhi, rdlo, rd0, rd1, i;
-    TCGv addr;
-    TCGv tmp, tmp2, tmp3;
+    TCGv_i32 addr;
+    TCGv_i32 tmp, tmp2, tmp3;
 
     if ((insn & 0x0e000e00) == 0x0c000000) {
         if ((insn & 0x0fe00ff0) == 0x0c400000) {
@@ -1796,12 +1798,12 @@ static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
             tmp3 = tcg_const_i32((insn & 1) << 5);
             break;
         default:
-            TCGV_UNUSED(tmp2);
-            TCGV_UNUSED(tmp3);
+            TCGV_UNUSED_I32(tmp2);
+            TCGV_UNUSED_I32(tmp3);
         }
         gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
-        tcg_temp_free(tmp3);
-        tcg_temp_free(tmp2);
+        tcg_temp_free_i32(tmp3);
+        tcg_temp_free_i32(tmp2);
         tcg_temp_free_i32(tmp);
         gen_op_iwmmxt_movq_wRn_M0(wrd);
         gen_op_iwmmxt_set_mup();
@@ -2260,7 +2262,7 @@ static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
         tmp = tcg_const_i32((insn >> 20) & 3);
         iwmmxt_load_reg(cpu_V1, rd1);
         gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
-        tcg_temp_free(tmp);
+        tcg_temp_free_i32(tmp);
         gen_op_iwmmxt_movq_wRn_M0(wrd);
         gen_op_iwmmxt_set_mup();
         break;
@@ -2316,7 +2318,7 @@ static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
         gen_op_iwmmxt_movq_M0_wRn(rd0);
         tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
         gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
-        tcg_temp_free(tmp);
+        tcg_temp_free_i32(tmp);
         gen_op_iwmmxt_movq_wRn_M0(wrd);
         gen_op_iwmmxt_set_mup();
         gen_op_iwmmxt_set_cup();
@@ -2446,7 +2448,7 @@ static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
 static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
 {
     int acc, rd0, rd1, rdhi, rdlo;
-    TCGv tmp, tmp2;
+    TCGv_i32 tmp, tmp2;
 
     if ((insn & 0x0ff00f10) == 0x0e200010) {
         /* Multiply with Internal Accumulate Format */
@@ -2532,22 +2534,22 @@ static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
 
 /* Move between integer and VFP cores.  */
-static TCGv gen_vfp_mrs(void)
+static TCGv_i32 gen_vfp_mrs(void)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_mov_i32(tmp, cpu_F0s);
     return tmp;
 }
 
-static void gen_vfp_msr(TCGv tmp)
+static void gen_vfp_msr(TCGv_i32 tmp)
 {
     tcg_gen_mov_i32(cpu_F0s, tmp);
     tcg_temp_free_i32(tmp);
 }
 
-static void gen_neon_dup_u8(TCGv var, int shift)
+static void gen_neon_dup_u8(TCGv_i32 var, int shift)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     if (shift)
         tcg_gen_shri_i32(var, var, shift);
     tcg_gen_ext8u_i32(var, var);
@@ -2558,28 +2560,28 @@ static void gen_neon_dup_u8(TCGv var, int shift)
     tcg_temp_free_i32(tmp);
 }
 
-static void gen_neon_dup_low16(TCGv var)
+static void gen_neon_dup_low16(TCGv_i32 var)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_ext16u_i32(var, var);
     tcg_gen_shli_i32(tmp, var, 16);
     tcg_gen_or_i32(var, var, tmp);
     tcg_temp_free_i32(tmp);
 }
 
-static void gen_neon_dup_high16(TCGv var)
+static void gen_neon_dup_high16(TCGv_i32 var)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_andi_i32(var, var, 0xffff0000);
     tcg_gen_shri_i32(tmp, var, 16);
     tcg_gen_or_i32(var, var, tmp);
     tcg_temp_free_i32(tmp);
 }
 
-static TCGv gen_load_and_replicate(DisasContext *s, TCGv addr, int size)
+static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
 {
     /* Load a single Neon element and replicate into a 32 bit TCG reg */
-    TCGv tmp;
+    TCGv_i32 tmp;
     switch (size) {
     case 0:
         tmp = gen_ld8u(addr, IS_USER(s));
@@ -2604,9 +2606,9 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
 {
     uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
     int dp, veclen;
-    TCGv addr;
-    TCGv tmp;
-    TCGv tmp2;
+    TCGv_i32 addr;
+    TCGv_i32 tmp;
+    TCGv_i32 tmp2;
 
     if (!arm_feature(env, ARM_FEATURE_VFP))
         return 1;
@@ -3428,7 +3430,7 @@ static inline void gen_jmp (DisasContext *s, uint32_t dest)
     }
 }
 
-static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
+static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
 {
     if (x)
         tcg_gen_sari_i32(t0, t0, 16);
@@ -3475,9 +3477,9 @@ static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr)
 }
 
 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
-static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0)
+static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
 {
-    TCGv tmp;
+    TCGv_i32 tmp;
     if (spsr) {
         /* ??? This is also undefined in system mode.  */
         if (IS_USER(s))
@@ -3499,16 +3501,16 @@ static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0)
 /* Returns nonzero if access to the PSR is not permitted.  */
 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
 {
-    TCGv tmp;
+    TCGv_i32 tmp;
     tmp = tcg_temp_new_i32();
     tcg_gen_movi_i32(tmp, val);
     return gen_set_psr(s, mask, spsr, tmp);
 }
 
 /* Generate an old-style exception return. Marks pc as dead. */
-static void gen_exception_return(DisasContext *s, TCGv pc)
+static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
 {
-    TCGv tmp;
+    TCGv_i32 tmp;
     store_reg(s, 15, pc);
     tmp = load_cpu_field(spsr);
     gen_set_cpsr(tmp, 0xffffffff);
@@ -3517,7 +3519,7 @@ static void gen_exception_return(DisasContext *s, TCGv pc)
 }
 
 /* Generate a v6 exception return.  Marks both values as dead.  */
-static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
+static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
 {
     gen_set_cpsr(cpsr, 0xffffffff);
     tcg_temp_free_i32(cpsr);
@@ -3530,7 +3532,7 @@ gen_set_condexec (DisasContext *s)
 {
     if (s->condexec_mask) {
         uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
-        TCGv tmp = tcg_temp_new_i32();
+        TCGv_i32 tmp = tcg_temp_new_i32();
         tcg_gen_movi_i32(tmp, val);
         store_cpu_field(tmp, condexec_bits);
     }
@@ -3561,7 +3563,7 @@ static void gen_nop_hint(DisasContext *s, int val)
 
 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
 
-static inline void gen_neon_add(int size, TCGv t0, TCGv t1)
+static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
 {
     switch (size) {
     case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
@@ -3571,7 +3573,7 @@ static inline void gen_neon_add(int size, TCGv t0, TCGv t1)
     }
 }
 
-static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
+static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
 {
     switch (size) {
     case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
@@ -3633,22 +3635,22 @@ static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
     default: return 1; \
     }} while (0)
 
-static TCGv neon_load_scratch(int scratch)
+static TCGv_i32 neon_load_scratch(int scratch)
 {
-    TCGv tmp = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
     tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
     return tmp;
 }
 
-static void neon_store_scratch(int scratch, TCGv var)
+static void neon_store_scratch(int scratch, TCGv_i32 var)
 {
     tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
     tcg_temp_free_i32(var);
 }
 
-static inline TCGv neon_get_scalar(int size, int reg)
+static inline TCGv_i32 neon_get_scalar(int size, int reg)
 {
-    TCGv tmp;
+    TCGv_i32 tmp;
     if (size == 1) {
         tmp = neon_load_reg(reg & 7, reg >> 4);
         if (reg & 8) {
@@ -3664,7 +3666,7 @@ static inline TCGv neon_get_scalar(int size, int reg)
 
 static int gen_neon_unzip(int rd, int rm, int size, int q)
 {
-    TCGv tmp, tmp2;
+    TCGv_i32 tmp, tmp2;
     if (!q && size == 2) {
         return 1;
     }
@@ -3703,7 +3705,7 @@ static int gen_neon_unzip(int rd, int rm, int size, int q)
 
 static int gen_neon_zip(int rd, int rm, int size, int q)
 {
-    TCGv tmp, tmp2;
+    TCGv_i32 tmp, tmp2;
     if (!q && size == 2) {
         return 1;
     }
@@ -3740,9 +3742,9 @@ static int gen_neon_zip(int rd, int rm, int size, int q)
     return 0;
 }
 
-static void gen_neon_trn_u8(TCGv t0, TCGv t1)
+static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
 {
-    TCGv rd, tmp;
+    TCGv_i32 rd, tmp;
 
     rd = tcg_temp_new_i32();
     tmp = tcg_temp_new_i32();
@@ -3762,9 +3764,9 @@ static void gen_neon_trn_u8(TCGv t0, TCGv t1)
     tcg_temp_free_i32(rd);
 }
 
-static void gen_neon_trn_u16(TCGv t0, TCGv t1)
+static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
 {
-    TCGv rd, tmp;
+    TCGv_i32 rd, tmp;
 
     rd = tcg_temp_new_i32();
     tmp = tcg_temp_new_i32();
@@ -3816,9 +3818,9 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
     int load;
     int shift;
     int n;
-    TCGv addr;
-    TCGv tmp;
-    TCGv tmp2;
+    TCGv_i32 addr;
+    TCGv_i32 tmp;
+    TCGv_i32 tmp2;
     TCGv_i64 tmp64;
 
     if (!s->vfp_enabled)
@@ -3907,7 +3909,7 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                         }
                     } else /* size == 0 */ {
                         if (load) {
-                            TCGV_UNUSED(tmp2);
+                            TCGV_UNUSED_I32(tmp2);
                             for (n = 0; n < 4; n++) {
                                 tmp = gen_ld8u(addr, IS_USER(s));
                                 tcg_gen_addi_i32(addr, addr, stride);
@@ -4093,13 +4095,13 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
         }
     }
     if (rm != 15) {
-        TCGv base;
+        TCGv_i32 base;
 
         base = load_reg(s, rn);
         if (rm == 13) {
             tcg_gen_addi_i32(base, base, stride);
         } else {
-            TCGv index;
+            TCGv_i32 index;
             index = load_reg(s, rm);
             tcg_gen_add_i32(base, base, index);
             tcg_temp_free_i32(index);
@@ -4110,14 +4112,14 @@ static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
 }
 
 /* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
-static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
+static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
 {
     tcg_gen_and_i32(t, t, c);
     tcg_gen_andc_i32(f, f, c);
     tcg_gen_or_i32(dest, t, f);
 }
 
-static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
+static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
 {
     switch (size) {
     case 0: gen_helper_neon_narrow_u8(dest, src); break;
@@ -4127,7 +4129,7 @@ static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
     }
 }
 
-static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
+static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
 {
     switch (size) {
     case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
@@ -4137,7 +4139,7 @@ static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
     }
 }
 
-static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
+static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
 {
     switch (size) {
     case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
@@ -4147,7 +4149,7 @@ static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
     }
 }
 
-static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src)
+static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
 {
     switch (size) {
     case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
@@ -4157,7 +4159,7 @@ static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src)
     }
 }
 
-static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
+static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
                                          int q, int u)
 {
     if (q) {
@@ -4191,7 +4193,7 @@ static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
     }
 }
 
-static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
+static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
 {
     if (u) {
         switch (size) {
@@ -4252,7 +4254,8 @@ static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
     }
 }
 
-static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
+static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
+                                 int size, int u)
 {
     TCGv_i64 tmp;
 
@@ -4282,7 +4285,8 @@ static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
     }
 }
 
-static void gen_neon_narrow_op(int op, int u, int size, TCGv dest, TCGv_i64 src)
+static void gen_neon_narrow_op(int op, int u, int size,
+                               TCGv_i32 dest, TCGv_i64 src)
 {
     if (op) {
         if (u) {
@@ -4493,7 +4497,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
     int pairwise;
     int u;
     uint32_t imm, mask;
-    TCGv tmp, tmp2, tmp3, tmp4, tmp5;
+    TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
     TCGv_i64 tmp64;
 
     if (!s->vfp_enabled)
@@ -5450,11 +5454,11 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
                     tmp = neon_load_reg(rn, 1);
                     neon_store_scratch(2, tmp);
                 }
-                TCGV_UNUSED(tmp3);
+                TCGV_UNUSED_I32(tmp3);
                 for (pass = 0; pass < 2; pass++) {
                     if (src1_wide) {
                         neon_load_reg64(cpu_V0, rn + pass);
-                        TCGV_UNUSED(tmp);
+                        TCGV_UNUSED_I32(tmp);
                     } else {
                         if (pass == 1 && rd == rn) {
                             tmp = neon_load_scratch(2);
@@ -5467,7 +5471,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
                     }
                     if (src2_wide) {
                         neon_load_reg64(cpu_V1, rm + pass);
-                        TCGV_UNUSED(tmp2);
+                        TCGV_UNUSED_I32(tmp2);
                     } else {
                         if (pass == 1 && rd == rm) {
                             tmp2 = neon_load_scratch(2);
@@ -5881,7 +5885,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
                     if (rm & 1) {
                         return 1;
                     }
-                    TCGV_UNUSED(tmp2);
+                    TCGV_UNUSED_I32(tmp2);
                     for (pass = 0; pass < 2; pass++) {
                         neon_load_reg64(cpu_V0, rm + pass);
                         tmp = tcg_temp_new_i32();
@@ -5963,7 +5967,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
                         if (neon_2rm_is_float_op(op)) {
                             tcg_gen_ld_f32(cpu_F0s, cpu_env,
                                            neon_reg_offset(rm, pass));
-                            TCGV_UNUSED(tmp);
+                            TCGV_UNUSED_I32(tmp);
                         } else {
                             tmp = neon_load_reg(rm, pass);
                         }
@@ -6036,7 +6040,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
                             case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
                             default: abort();
                             }
-                            tcg_temp_free(tmp2);
+                            tcg_temp_free_i32(tmp2);
                             if (op == NEON_2RM_VCLE0) {
                                 tcg_gen_not_i32(tmp, tmp);
                             }
@@ -6049,7 +6053,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
                             case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
                             default: abort();
                             }
-                            tcg_temp_free(tmp2);
+                            tcg_temp_free_i32(tmp2);
                             if (op == NEON_2RM_VCLT0) {
                                 tcg_gen_not_i32(tmp, tmp);
                             }
@@ -6062,7 +6066,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
                             case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
                             default: abort();
                             }
-                            tcg_temp_free(tmp2);
+                            tcg_temp_free_i32(tmp2);
                             break;
                         case NEON_2RM_VABS:
                             switch(size) {
@@ -6075,14 +6079,14 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
                         case NEON_2RM_VNEG:
                             tmp2 = tcg_const_i32(0);
                             gen_neon_rsb(size, tmp, tmp2);
-                            tcg_temp_free(tmp2);
+                            tcg_temp_free_i32(tmp2);
                             break;
                         case NEON_2RM_VCGT0_F:
                         {
                             TCGv_ptr fpstatus = get_fpstatus_ptr(1);
                             tmp2 = tcg_const_i32(0);
                             gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
-                            tcg_temp_free(tmp2);
+                            tcg_temp_free_i32(tmp2);
                             tcg_temp_free_ptr(fpstatus);
                             break;
                         }
@@ -6091,7 +6095,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
                             TCGv_ptr fpstatus = get_fpstatus_ptr(1);
                             tmp2 = tcg_const_i32(0);
                             gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
-                            tcg_temp_free(tmp2);
+                            tcg_temp_free_i32(tmp2);
                             tcg_temp_free_ptr(fpstatus);
                             break;
                         }
@@ -6100,7 +6104,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
                             TCGv_ptr fpstatus = get_fpstatus_ptr(1);
                             tmp2 = tcg_const_i32(0);
                             gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
-                            tcg_temp_free(tmp2);
+                            tcg_temp_free_i32(tmp2);
                             tcg_temp_free_ptr(fpstatus);
                             break;
                         }
@@ -6109,7 +6113,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
                             TCGv_ptr fpstatus = get_fpstatus_ptr(1);
                             tmp2 = tcg_const_i32(0);
                             gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
-                            tcg_temp_free(tmp2);
+                            tcg_temp_free_i32(tmp2);
                             tcg_temp_free_ptr(fpstatus);
                             break;
                         }
@@ -6118,7 +6122,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
                             TCGv_ptr fpstatus = get_fpstatus_ptr(1);
                             tmp2 = tcg_const_i32(0);
                             gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
-                            tcg_temp_free(tmp2);
+                            tcg_temp_free_i32(tmp2);
                             tcg_temp_free_ptr(fpstatus);
                             break;
                         }
@@ -6346,7 +6350,7 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                 tcg_temp_free_i64(tmp64);
                 store_reg(s, rt2, tmp);
             } else {
-                TCGv tmp;
+                TCGv_i32 tmp;
                 if (ri->type & ARM_CP_CONST) {
                     tmp = tcg_const_i32(ri->resetvalue);
                 } else if (ri->readfn) {
@@ -6377,7 +6381,7 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
             }
 
             if (is64) {
-                TCGv tmplo, tmphi;
+                TCGv_i32 tmplo, tmphi;
                 TCGv_i64 tmp64 = tcg_temp_new_i64();
                 tmplo = load_reg(s, rt);
                 tmphi = load_reg(s, rt2);
@@ -6395,7 +6399,7 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                 tcg_temp_free_i64(tmp64);
             } else {
                 if (ri->writefn) {
-                    TCGv tmp;
+                    TCGv_i32 tmp;
                     TCGv_ptr tmpptr;
                     gen_set_pc_im(s->pc);
                     tmp = load_reg(s, rt);
@@ -6404,7 +6408,7 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                     tcg_temp_free_ptr(tmpptr);
                     tcg_temp_free_i32(tmp);
                 } else {
-                    TCGv tmp = load_reg(s, rt);
+                    TCGv_i32 tmp = load_reg(s, rt);
                     store_cpu_offset(tmp, ri->fieldoffset);
                 }
             }
@@ -6426,7 +6430,7 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
 /* Store a 64-bit value to a register pair.  Clobbers val.  */
 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
 {
-    TCGv tmp;
+    TCGv_i32 tmp;
     tmp = tcg_temp_new_i32();
     tcg_gen_trunc_i64_i32(tmp, val);
     store_reg(s, rlow, tmp);
@@ -6440,7 +6444,7 @@ static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
 {
     TCGv_i64 tmp;
-    TCGv tmp2;
+    TCGv_i32 tmp2;
 
     /* Load value and extend to 64 bits.  */
     tmp = tcg_temp_new_i64();
@@ -6455,8 +6459,8 @@ static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
 {
     TCGv_i64 tmp;
-    TCGv tmpl;
-    TCGv tmph;
+    TCGv_i32 tmpl;
+    TCGv_i32 tmph;
 
     /* Load 64-bit value rd:rn.  */
     tmpl = load_reg(s, rlow);
@@ -6470,7 +6474,7 @@ static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
 }
 
 /* Set N and Z flags from hi|lo.  */
-static void gen_logicq_cc(TCGv lo, TCGv hi)
+static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
 {
     tcg_gen_mov_i32(cpu_NF, hi);
     tcg_gen_or_i32(cpu_ZF, lo, hi);
@@ -6486,9 +6490,9 @@ static void gen_logicq_cc(TCGv lo, TCGv hi)
    this sequence is effectively atomic.  In user emulation mode we
    throw an exception and handle the atomic operation elsewhere.  */
 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
-                               TCGv addr, int size)
+                               TCGv_i32 addr, int size)
 {
-    TCGv tmp;
+    TCGv_i32 tmp;
 
     switch (size) {
     case 0:
@@ -6507,7 +6511,7 @@ static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
     tcg_gen_mov_i32(cpu_exclusive_val, tmp);
     store_reg(s, rt, tmp);
     if (size == 3) {
-        TCGv tmp2 = tcg_temp_new_i32();
+        TCGv_i32 tmp2 = tcg_temp_new_i32();
         tcg_gen_addi_i32(tmp2, addr, 4);
         tmp = gen_ld32(tmp2, IS_USER(s));
         tcg_temp_free_i32(tmp2);
@@ -6524,7 +6528,7 @@ static void gen_clrex(DisasContext *s)
 
 #ifdef CONFIG_USER_ONLY
 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
-                                TCGv addr, int size)
+                                TCGv_i32 addr, int size)
 {
     tcg_gen_mov_i32(cpu_exclusive_test, addr);
     tcg_gen_movi_i32(cpu_exclusive_info,
@@ -6533,9 +6537,9 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
 }
 #else
 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
-                                TCGv addr, int size)
+                                TCGv_i32 addr, int size)
 {
-    TCGv tmp;
+    TCGv_i32 tmp;
     int done_label;
     int fail_label;
 
@@ -6565,7 +6569,7 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
     tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
     tcg_temp_free_i32(tmp);
     if (size == 3) {
-        TCGv tmp2 = tcg_temp_new_i32();
+        TCGv_i32 tmp2 = tcg_temp_new_i32();
         tcg_gen_addi_i32(tmp2, addr, 4);
         tmp = gen_ld32(tmp2, IS_USER(s));
         tcg_temp_free_i32(tmp2);
@@ -6668,10 +6672,10 @@ static void gen_srs(DisasContext *s,
 static void disas_arm_insn(CPUARMState * env, DisasContext *s)
 {
     unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
-    TCGv tmp;
-    TCGv tmp2;
-    TCGv tmp3;
-    TCGv addr;
+    TCGv_i32 tmp;
+    TCGv_i32 tmp2;
+    TCGv_i32 tmp3;
+    TCGv_i32 addr;
     TCGv_i64 tmp64;
 
     insn = arm_ldl_code(env, s->pc, s->bswap_code);
@@ -7084,7 +7088,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
             rn = (insn >> 16) & 0xf;
             tmp = load_reg(s, rn);
         } else {
-            TCGV_UNUSED(tmp);
+            TCGV_UNUSED_I32(tmp);
         }
         rd = (insn >> 12) & 0xf;
         switch(op1) {
@@ -7285,11 +7289,11 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
                             tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
                         }
                         if (insn & (1 << 21)) { /* mult accumulate */
-                            TCGv al = load_reg(s, rn);
-                            TCGv ah = load_reg(s, rd);
+                            TCGv_i32 al = load_reg(s, rn);
+                            TCGv_i32 ah = load_reg(s, rd);
                             tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
-                            tcg_temp_free(al);
-                            tcg_temp_free(ah);
+                            tcg_temp_free_i32(al);
+                            tcg_temp_free_i32(ah);
                         }
                         if (insn & (1 << 20)) {
                             gen_logicq_cc(tmp, tmp2);
@@ -7348,7 +7352,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
                                 abort();
                             }
                         }
-                        tcg_temp_free(addr);
+                        tcg_temp_free_i32(addr);
                     } else {
                         /* SWP instruction */
                         rm = (insn) & 0xf;
@@ -7778,7 +7782,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
         case 0x09:
             {
                 int j, n, user, loaded_base;
-                TCGv loaded_var;
+                TCGv_i32 loaded_var;
                 /* load/store multiple words */
                 /* XXX: store correct base if write back */
                 user = 0;
@@ -7794,7 +7798,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
 
                 /* compute total size */
                 loaded_base = 0;
-                TCGV_UNUSED(loaded_var);
+                TCGV_UNUSED_I32(loaded_var);
                 n = 0;
                 for(i=0;i<16;i++) {
                     if (insn & (1 << i))
@@ -7944,7 +7948,8 @@ thumb2_logic_op(int op)
    Returns zero if the opcode is valid.  */
 
 static int
-gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
+gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
+                   TCGv_i32 t0, TCGv_i32 t1)
 {
     int logic_cc;
 
@@ -8018,10 +8023,10 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
 {
     uint32_t insn, imm, shift, offset;
     uint32_t rd, rn, rm, rs;
-    TCGv tmp;
-    TCGv tmp2;
-    TCGv tmp3;
-    TCGv addr;
+    TCGv_i32 tmp;
+    TCGv_i32 tmp2;
+    TCGv_i32 tmp3;
+    TCGv_i32 addr;
     TCGv_i64 tmp64;
     int op;
     int shiftop;
@@ -8130,7 +8135,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                 }
             } else if ((insn & (1 << 23)) == 0) {
                 /* Load/store exclusive word.  */
-                addr = tcg_temp_local_new();
+                addr = tcg_temp_local_new_i32();
                 load_reg_var(s, addr, rn);
                 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
                 if (insn & (1 << 20)) {
@@ -8138,7 +8143,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                 } else {
                     gen_store_exclusive(s, rd, rs, 15, addr, 2);
                 }
-                tcg_temp_free(addr);
+                tcg_temp_free_i32(addr);
             } else if ((insn & (1 << 6)) == 0) {
                 /* Table Branch.  */
                 if (rn == 15) {
@@ -8169,14 +8174,14 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                 if (op == 2) {
                     goto illegal_op;
                 }
-                addr = tcg_temp_local_new();
+                addr = tcg_temp_local_new_i32();
                 load_reg_var(s, addr, rn);
                 if (insn & (1 << 20)) {
                     gen_load_exclusive(s, rs, rd, addr, op);
                 } else {
                     gen_store_exclusive(s, rm, rs, rd, addr, op);
                 }
-                tcg_temp_free(addr);
+                tcg_temp_free_i32(addr);
             }
         } else {
             /* Load/store multiple, RFE, SRS.  */
@@ -8213,7 +8218,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                 }
             } else {
                 int i, loaded_base = 0;
-                TCGv loaded_var;
+                TCGv_i32 loaded_var;
                 /* Load/store multiple.  */
                 addr = load_reg(s, rn);
                 offset = 0;
@@ -8225,7 +8230,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                     tcg_gen_addi_i32(addr, addr, -offset);
                 }
 
-                TCGV_UNUSED(loaded_var);
+                TCGV_UNUSED_I32(loaded_var);
                 for (i = 0; i < 16; i++) {
                     if ((insn & (1 << i)) == 0)
                         continue;
@@ -9064,9 +9069,9 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
     uint32_t val, insn, op, rm, rn, rd, shift, cond;
     int32_t offset;
     int i;
-    TCGv tmp;
-    TCGv tmp2;
-    TCGv addr;
+    TCGv_i32 tmp;
+    TCGv_i32 tmp2;
+    TCGv_i32 addr;
 
     if (s->condexec_mask) {
         cond = s->condexec_cond;
@@ -9234,7 +9239,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
         } else if (op != 0xf) { /* mvn doesn't read its first operand */
             tmp = load_reg(s, rd);
         } else {
-            TCGV_UNUSED(tmp);
+            TCGV_UNUSED_I32(tmp);
         }
 
         tmp2 = load_reg(s, rm);
@@ -9549,7 +9554,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
                     tcg_gen_addi_i32(addr, addr, 4);
                 }
             }
-            TCGV_UNUSED(tmp);
+            TCGV_UNUSED_I32(tmp);
             if (insn & (1 << 8)) {
                 if (insn & (1 << 11)) {
                     /* pop pc */
@@ -9674,8 +9679,8 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
     case 12:
     {
         /* load/store multiple */
-        TCGv loaded_var;
-        TCGV_UNUSED(loaded_var);
+        TCGv_i32 loaded_var;
+        TCGV_UNUSED_I32(loaded_var);
         rn = (insn >> 8) & 0x7;
         addr = load_reg(s, rn);
         for (i = 0; i < 8; i++) {
@@ -9851,7 +9856,7 @@ static inline void gen_intermediate_code_internal(CPUARMState *env,
        complications trying to do it at the end of the block.  */
     if (dc->condexec_mask || dc->condexec_cond)
       {
-        TCGv tmp = tcg_temp_new_i32();
+        TCGv_i32 tmp = tcg_temp_new_i32();
         tcg_gen_movi_i32(tmp, 0);
         store_cpu_field(tmp, condexec_bits);
       }
commit fd469df97ab4277411ecdd4032a2f045a3a87b2a
Merge: 4a542df fd29893
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri May 24 13:47:42 2013 -0500

    Merge remote-tracking branch 'bonzini/iommu-for-anthony' into staging
    
    # By Paolo Bonzini (11) and others
    # Via Paolo Bonzini
    * bonzini/iommu-for-anthony:
      memory: clean up phys_page_find
      memory: populate FlatView for new address spaces
      memory: limit sections in the radix tree to the actual address space size
      s390x: reduce TARGET_PHYS_ADDR_SPACE_BITS to 62
      memory: fix address space initialization/destruction
      memory: make memory_global_sync_dirty_bitmap take an AddressSpace
      memory: do not duplicate memory_region_destructor_none
      memory: Rename readable flag to romd_mode
      memory: Replace open-coded memory_region_is_romd
      memory: allow memory_region_find() to run on non-root memory regions
      memory: assert that PhysPageEntry's ptr does not overflow
      exec: eliminate stq_phys_notdirty
      exec: make qemu_get_ram_ptr private
      exec: eliminate qemu_put_ram_ptr
      exec: remove obsolete comment
    
    Message-id: 1369414987-8839-1-git-send-email-pbonzini at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 4a542df0910dff2caf17d6bb76bbf3704197db42
Merge: 4c5dad0 00b7ade
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri May 24 13:47:33 2013 -0500

    Merge remote-tracking branch 'stefanha/net' into staging
    
    # By Alasdair McLeay (1) and Stefan Hajnoczi (1)
    # Via Stefan Hajnoczi
    * stefanha/net:
      rtl8139: flush queued packets when RxBufPtr is written
      net: support for bridged networking on Mac OS X
    
    Message-id: 1369406295-20411-1-git-send-email-stefanha at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 4c5dad040bce8f8c9924dc72cfac9380e4ffdc26
Merge: 64afc2b 02ffb50
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri May 24 13:47:25 2013 -0500

    Merge remote-tracking branch 'stefanha/block' into staging
    
    # By Wenchao Xia (5) and others
    # Via Stefan Hajnoczi
    * stefanha/block:
      coroutine: stop using AioContext in CoQueue
      coroutine: protect global pool with a mutex
      qemu-iotests: Try creating huge qcow2 image
      qcow2.py: Subcommand for changing header fields
      qemu-io: Fix 'map' output
      blockdev: Rename BlockdevAction -> TransactionAction
      block: make all steps in qmp_transaction() as callback
      block: package rollback code in qmp_transaction()
      block: package committing code in qmp_transaction()
      block: move input parsing code in qmp_transaction()
      block: package preparation code in qmp_transaction()
    
    Message-id: 1369405947-14818-1-git-send-email-stefanha at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit fd2989341e758813351c2fc1446cc8fbcae06ad9
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon May 20 12:21:07 2013 +0200

    memory: clean up phys_page_find
    
    Remove the goto.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index 3fdca46..3a9ddcb 100644
--- a/exec.c
+++ b/exec.c
@@ -187,19 +187,15 @@ MemoryRegionSection *phys_page_find(AddressSpaceDispatch *d, hwaddr index)
     PhysPageEntry lp = d->phys_map;
     PhysPageEntry *p;
     int i;
-    uint16_t s_index = phys_section_unassigned;
 
     for (i = P_L2_LEVELS - 1; i >= 0 && !lp.is_leaf; i--) {
         if (lp.ptr == PHYS_MAP_NODE_NIL) {
-            goto not_found;
+            return &phys_sections[phys_section_unassigned];
         }
         p = phys_map_nodes[lp.ptr];
         lp = p[(index >> (i * L2_BITS)) & (L2_SIZE - 1)];
     }
-
-    s_index = lp.ptr;
-not_found:
-    return &phys_sections[s_index];
+    return &phys_sections[lp.ptr];
 }
 
 bool memory_region_is_unassigned(MemoryRegion *mr)
commit f43793c7caab49c68b41c3b8524fc35b4c206856
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Apr 16 15:39:51 2013 +0200

    memory: populate FlatView for new address spaces
    
    Even a new address space might have a non-empty FlatView.  In order
    to initialize it properly, address_space_init should (a) call
    memory_region_transaction_commit after the address space is inserted
    into the list; (b) force memory_region_transaction_commit to do something.
    
    This bug was latent so far because all address spaces started empty, including
    the PCI address space where the bus master region is initially disabled.
    However, the target address space of an IOMMU is usually rooted at
    get_system_memory(), which might not be empty at the time the IOMMU is created.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/memory.c b/memory.c
index 9478f98..99f046d 100644
--- a/memory.c
+++ b/memory.c
@@ -1576,8 +1576,9 @@ void address_space_init(AddressSpace *as, MemoryRegion *root)
     as->ioeventfds = NULL;
     QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
     as->name = NULL;
-    memory_region_transaction_commit();
     address_space_init_dispatch(as);
+    memory_region_update_pending |= root->enabled;
+    memory_region_transaction_commit();
 }
 
 void address_space_destroy(AddressSpace *as)
commit 86a8623692b1b559a419a92eb8b6897c221bca74
Author: Avi Kivity <avi.kivity at gmail.com>
Date:   Tue Oct 30 13:47:45 2012 +0200

    memory: limit sections in the radix tree to the actual address space size
    
    The radix tree is statically sized to fit TARGET_PHYS_ADDR_SPACE_BITS.
    If a larger memory region is registered, it will overflow.
    
    Fix by limiting any section in the radix tree to the supported size.
    
    This problem was not observed earlier since artificial regions (containers
    and aliases) are eliminated by the memory core, leaving only device regions
    which have reasonable sizes.  An IOMMU however cannot be eliminated by the
    memory core, and may have an artificial size.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Avi Kivity <avi.kivity at gmail.com>
    [ Fail the build if TARGET_PHYS_ADDR_SPACE_BITS is too large - Paolo ]
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index 8562fca..3fdca46 100644
--- a/exec.c
+++ b/exec.c
@@ -775,10 +775,21 @@ static void register_multipage(AddressSpaceDispatch *d, MemoryRegionSection *sec
                   section_index);
 }
 
+QEMU_BUILD_BUG_ON(TARGET_PHYS_ADDR_SPACE_BITS > MAX_PHYS_ADDR_SPACE_BITS)
+
+static MemoryRegionSection limit(MemoryRegionSection section)
+{
+    section.size = MIN(section.offset_within_address_space + section.size,
+                       MAX_PHYS_ADDR + 1)
+                   - section.offset_within_address_space;
+
+    return section;
+}
+
 static void mem_add(MemoryListener *listener, MemoryRegionSection *section)
 {
     AddressSpaceDispatch *d = container_of(listener, AddressSpaceDispatch, listener);
-    MemoryRegionSection now = *section, remain = *section;
+    MemoryRegionSection now = limit(*section), remain = limit(*section);
 
     if ((now.offset_within_address_space & ~TARGET_PAGE_MASK)
         || (now.size < TARGET_PAGE_SIZE)) {
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 91be2a3..fdf55fe 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -26,6 +26,9 @@
 #include "exec/ioport.h"
 #include "qemu/int128.h"
 
+#define MAX_PHYS_ADDR_SPACE_BITS 62
+#define MAX_PHYS_ADDR            (((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 1)
+
 typedef struct MemoryRegionOps MemoryRegionOps;
 typedef struct MemoryRegionPortio MemoryRegionPortio;
 typedef struct MemoryRegionMmio MemoryRegionMmio;
commit 311f83ca08c011b048c063c2fd3038a8957970bc
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon May 13 15:54:44 2013 +0200

    s390x: reduce TARGET_PHYS_ADDR_SPACE_BITS to 62
    
    With the next patch, the memory API will complain if the
    TARGET_PHYS_ADDR_SPACE_BITS gets dangerously close to an
    overflow.  s390x can handle up to 64 bit of physical address
    space from its page tables, but we never use that much.  Just
    decrease the value.
    
    Cc: Alexander Graf <agraf at suse.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 0ce82cf..6304c4d 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -34,7 +34,10 @@
 #include "exec/cpu-defs.h"
 #define TARGET_PAGE_BITS 12
 
-#define TARGET_PHYS_ADDR_SPACE_BITS 64
+/* Actually 64-bits, limited by the memory API to 62 bits.  We
+ * never use that much.
+ */
+#define TARGET_PHYS_ADDR_SPACE_BITS 62
 #define TARGET_VIRT_ADDR_SPACE_BITS 64
 
 #include "exec/cpu-all.h"
commit 4c19eb721a5929f2277d33a98bb59963c58c2e3b
Author: Avi Kivity <avi.kivity at gmail.com>
Date:   Tue Oct 30 13:47:44 2012 +0200

    memory: fix address space initialization/destruction
    
    A couple of fields were left uninitialized.  This was not observed earlier
    because all address spaces were statically allocated.  Also free allocation
    for those fields.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Avi Kivity <avi.kivity at gmail.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/memory.c b/memory.c
index 11bbeb7..9478f98 100644
--- a/memory.c
+++ b/memory.c
@@ -1572,6 +1572,8 @@ void address_space_init(AddressSpace *as, MemoryRegion *root)
     as->root = root;
     as->current_map = g_new(FlatView, 1);
     flatview_init(as->current_map);
+    as->ioeventfd_nb = 0;
+    as->ioeventfds = NULL;
     QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
     as->name = NULL;
     memory_region_transaction_commit();
@@ -1588,6 +1590,7 @@ void address_space_destroy(AddressSpace *as)
     address_space_destroy_dispatch(as);
     flatview_destroy(as->current_map);
     g_free(as->current_map);
+    g_free(as->ioeventfds);
 }
 
 uint64_t io_mem_read(MemoryRegion *mr, hwaddr addr, unsigned size)
commit 1d671369c3f8eb2b5dfd0e1709688faba9b85f95
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Apr 24 10:46:55 2013 +0200

    memory: make memory_global_sync_dirty_bitmap take an AddressSpace
    
    Since this is a MemoryListener operation, it only makes sense
    on an AddressSpace granularity.
    
    Suggested-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/arch_init.c b/arch_init.c
index 49c5dc2..5d32ecf 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -386,7 +386,7 @@ static void migration_bitmap_sync(void)
     }
 
     trace_migration_bitmap_sync_start();
-    memory_global_sync_dirty_bitmap(get_system_memory());
+    address_space_sync_dirty_bitmap(&address_space_memory);
 
     QTAILQ_FOREACH(block, &ram_list.blocks, next) {
         for (addr = 0; addr < block->length; addr += TARGET_PAGE_SIZE) {
diff --git a/include/exec/memory.h b/include/exec/memory.h
index e1208e4..91be2a3 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -766,13 +766,12 @@ memory_region_section_addr(MemoryRegionSection *section,
 }
 
 /**
- * memory_global_sync_dirty_bitmap: synchronize the dirty log for all memory
+ * address_space_sync_dirty_bitmap: synchronize the dirty log for all memory
  *
  * Synchronizes the dirty page log for an entire address space.
- * @address_space: a top-level (i.e. parentless) region that contains the
- *       memory being synchronized
+ * @as: the address space that contains the memory being synchronized
  */
-void memory_global_sync_dirty_bitmap(MemoryRegion *address_space);
+void address_space_sync_dirty_bitmap(AddressSpace *as);
 
 /**
  * memory_region_transaction_begin: Start a transaction.
diff --git a/memory.c b/memory.c
index 5431463..11bbeb7 100644
--- a/memory.c
+++ b/memory.c
@@ -1485,9 +1485,8 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr,
     return ret;
 }
 
-void memory_global_sync_dirty_bitmap(MemoryRegion *address_space)
+void address_space_sync_dirty_bitmap(AddressSpace *as)
 {
-    AddressSpace *as = memory_region_to_address_space(address_space);
     FlatRange *fr;
 
     FOR_EACH_FLAT_RANGE(fr, as->current_map) {
commit 5553e3a5c95f4a842489384a2fafb27d7555a4ef
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 3 17:18:36 2013 +0200

    memory: do not duplicate memory_region_destructor_none
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/memory.c b/memory.c
index 013464b..5431463 100644
--- a/memory.c
+++ b/memory.c
@@ -768,10 +768,6 @@ static void memory_region_destructor_ram_from_ptr(MemoryRegion *mr)
     qemu_ram_free_from_ptr(mr->ram_addr);
 }
 
-static void memory_region_destructor_iomem(MemoryRegion *mr)
-{
-}
-
 static void memory_region_destructor_rom_device(MemoryRegion *mr)
 {
     qemu_ram_free(mr->ram_addr & TARGET_PAGE_MASK);
@@ -929,7 +925,6 @@ void memory_region_init_io(MemoryRegion *mr,
     mr->ops = ops;
     mr->opaque = opaque;
     mr->terminates = true;
-    mr->destructor = memory_region_destructor_iomem;
     mr->ram_addr = ~(ram_addr_t)0;
 }
 
commit 5f9a5ea1c0a8391033e7d33abd335dd804a1001a
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Tue May 7 19:04:25 2013 +0200

    memory: Rename readable flag to romd_mode
    
    "Readable" is a very unfortunate name for this flag because even a
    rom_device region will always be readable from the guest POV. What
    differs is the mapping, just like the comments had to explain already.
    Also, readable could currently be understood as being a generic region
    flag, but it only applies to rom_device regions.
    
    So rename the flag and the function to modify it after the original term
    "ROMD" which could also be interpreted as "ROM direct", i.e. ROM mode
    with direct access. In any case, the scope of the flag is clearer now.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 3ff20e0..63d7c99 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -105,7 +105,7 @@ static void pflash_timer (void *opaque)
     DPRINTF("%s: command %02x done\n", __func__, pfl->cmd);
     /* Reset flash */
     pfl->status ^= 0x80;
-    memory_region_rom_device_set_readable(&pfl->mem, true);
+    memory_region_rom_device_set_romd(&pfl->mem, true);
     pfl->wcycle = 0;
     pfl->cmd = 0;
 }
@@ -281,7 +281,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
 
     if (!pfl->wcycle) {
         /* Set the device in I/O access mode */
-        memory_region_rom_device_set_readable(&pfl->mem, false);
+        memory_region_rom_device_set_romd(&pfl->mem, false);
     }
 
     switch (pfl->wcycle) {
@@ -458,7 +458,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
                   "\n", __func__, offset, pfl->wcycle, pfl->cmd, value);
 
  reset_flash:
-    memory_region_rom_device_set_readable(&pfl->mem, true);
+    memory_region_rom_device_set_romd(&pfl->mem, true);
 
     pfl->wcycle = 0;
     pfl->cmd = 0;
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 9a7fa70..5f25246 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -111,7 +111,7 @@ static void pflash_setup_mappings(pflash_t *pfl)
 
 static void pflash_register_memory(pflash_t *pfl, int rom_mode)
 {
-    memory_region_rom_device_set_readable(&pfl->orig_mem, rom_mode);
+    memory_region_rom_device_set_romd(&pfl->orig_mem, rom_mode);
     pfl->rom_mode = rom_mode;
 }
 
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 329ffb1..e1208e4 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -126,7 +126,7 @@ struct MemoryRegion {
     ram_addr_t ram_addr;
     bool subpage;
     bool terminates;
-    bool readable;
+    bool romd_mode;
     bool ram;
     bool readonly; /* For RAM regions */
     bool enabled;
@@ -355,16 +355,16 @@ uint64_t memory_region_size(MemoryRegion *mr);
 bool memory_region_is_ram(MemoryRegion *mr);
 
 /**
- * memory_region_is_romd: check whether a memory region is ROMD
+ * memory_region_is_romd: check whether a memory region is in ROMD mode
  *
- * Returns %true is a memory region is ROMD and currently set to allow
+ * Returns %true if a memory region is a ROM device and currently set to allow
  * direct reads.
  *
  * @mr: the memory region being queried
  */
 static inline bool memory_region_is_romd(MemoryRegion *mr)
 {
-    return mr->rom_device && mr->readable;
+    return mr->rom_device && mr->romd_mode;
 }
 
 /**
@@ -502,18 +502,18 @@ void memory_region_reset_dirty(MemoryRegion *mr, hwaddr addr,
 void memory_region_set_readonly(MemoryRegion *mr, bool readonly);
 
 /**
- * memory_region_rom_device_set_readable: enable/disable ROM readability
+ * memory_region_rom_device_set_romd: enable/disable ROMD mode
  *
  * Allows a ROM device (initialized with memory_region_init_rom_device() to
- * to be marked as readable (default) or not readable.  When it is readable,
- * the device is mapped to guest memory.  When not readable, reads are
- * forwarded to the #MemoryRegion.read function.
+ * set to ROMD mode (default) or MMIO mode.  When it is in ROMD mode, the
+ * device is mapped to guest memory and satisfies read access directly.
+ * When in MMIO mode, reads are forwarded to the #MemoryRegion.read function.
+ * Writes are always handled by the #MemoryRegion.write function.
  *
  * @mr: the memory region to be updated
- * @readable: whether reads are satisified directly (%true) or via callbacks
- *            (%false)
+ * @romd_mode: %true to put the region into ROMD mode
  */
-void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable);
+void memory_region_rom_device_set_romd(MemoryRegion *mr, bool romd_mode);
 
 /**
  * memory_region_set_coalescing: Enable memory coalescing for the region.
diff --git a/memory.c b/memory.c
index 34bfb13..013464b 100644
--- a/memory.c
+++ b/memory.c
@@ -213,7 +213,7 @@ struct FlatRange {
     hwaddr offset_in_region;
     AddrRange addr;
     uint8_t dirty_log_mask;
-    bool readable;
+    bool romd_mode;
     bool readonly;
 };
 
@@ -236,7 +236,7 @@ static bool flatrange_equal(FlatRange *a, FlatRange *b)
     return a->mr == b->mr
         && addrrange_equal(a->addr, b->addr)
         && a->offset_in_region == b->offset_in_region
-        && a->readable == b->readable
+        && a->romd_mode == b->romd_mode
         && a->readonly == b->readonly;
 }
 
@@ -276,7 +276,7 @@ static bool can_merge(FlatRange *r1, FlatRange *r2)
                                 r1->addr.size),
                      int128_make64(r2->offset_in_region))
         && r1->dirty_log_mask == r2->dirty_log_mask
-        && r1->readable == r2->readable
+        && r1->romd_mode == r2->romd_mode
         && r1->readonly == r2->readonly;
 }
 
@@ -532,7 +532,7 @@ static void render_memory_region(FlatView *view,
             fr.offset_in_region = offset_in_region;
             fr.addr = addrrange_make(base, now);
             fr.dirty_log_mask = mr->dirty_log_mask;
-            fr.readable = mr->readable;
+            fr.romd_mode = mr->romd_mode;
             fr.readonly = readonly;
             flatview_insert(view, i, &fr);
             ++i;
@@ -552,7 +552,7 @@ static void render_memory_region(FlatView *view,
         fr.offset_in_region = offset_in_region;
         fr.addr = addrrange_make(base, remain);
         fr.dirty_log_mask = mr->dirty_log_mask;
-        fr.readable = mr->readable;
+        fr.romd_mode = mr->romd_mode;
         fr.readonly = readonly;
         flatview_insert(view, i, &fr);
     }
@@ -801,7 +801,7 @@ void memory_region_init(MemoryRegion *mr,
     mr->enabled = true;
     mr->terminates = false;
     mr->ram = false;
-    mr->readable = true;
+    mr->romd_mode = true;
     mr->readonly = false;
     mr->rom_device = false;
     mr->destructor = memory_region_destructor_none;
@@ -1121,11 +1121,11 @@ void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
     }
 }
 
-void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable)
+void memory_region_rom_device_set_romd(MemoryRegion *mr, bool romd_mode)
 {
-    if (mr->readable != readable) {
+    if (mr->romd_mode != romd_mode) {
         memory_region_transaction_begin();
-        mr->readable = readable;
+        mr->romd_mode = romd_mode;
         memory_region_update_pending |= mr->enabled;
         memory_region_transaction_commit();
     }
@@ -1659,9 +1659,9 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f,
                    base + mr->addr
                    + (hwaddr)int128_get64(mr->size) - 1,
                    mr->priority,
-                   mr->readable ? 'R' : '-',
-                   !mr->readonly && !(mr->rom_device && mr->readable) ? 'W'
-                                                                      : '-',
+                   mr->romd_mode ? 'R' : '-',
+                   !mr->readonly && !(mr->rom_device && mr->romd_mode) ? 'W'
+                                                                       : '-',
                    mr->name,
                    mr->alias->name,
                    mr->alias_offset,
@@ -1674,9 +1674,9 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f,
                    base + mr->addr
                    + (hwaddr)int128_get64(mr->size) - 1,
                    mr->priority,
-                   mr->readable ? 'R' : '-',
-                   !mr->readonly && !(mr->rom_device && mr->readable) ? 'W'
-                                                                      : '-',
+                   mr->romd_mode ? 'R' : '-',
+                   !mr->readonly && !(mr->rom_device && mr->romd_mode) ? 'W'
+                                                                       : '-',
                    mr->name);
     }
 
commit 4b81126e3399bfbcc47a4d696902c93401169f72
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Mon May 6 18:07:05 2013 +0200

    memory: Replace open-coded memory_region_is_romd
    
    Improves readability.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>

diff --git a/translate-all.c b/translate-all.c
index da93608..0d84b0d 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -1359,7 +1359,7 @@ void tb_invalidate_phys_addr(hwaddr addr)
     section = phys_page_find(address_space_memory.dispatch,
                              addr >> TARGET_PAGE_BITS);
     if (!(memory_region_is_ram(section->mr)
-          || (section->mr->rom_device && section->mr->readable))) {
+          || memory_region_is_romd(section->mr))) {
         return;
     }
     ram_addr = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
commit 73034e9e087aa51b85cf86b6c81ef92f7e1e9d09
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue May 7 15:48:28 2013 +0200

    memory: allow memory_region_find() to run on non-root memory regions
    
    memory_region_find() is similar to registering a MemoryListener and
    checking for the MemoryRegionSections that come from a particular
    region.  There is no reason for this to be limited to a root memory
    region.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 9e88320..329ffb1 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -718,24 +718,34 @@ void memory_region_set_alias_offset(MemoryRegion *mr,
                                     hwaddr offset);
 
 /**
- * memory_region_find: locate a MemoryRegion in an address space
+ * memory_region_find: translate an address/size relative to a
+ * MemoryRegion into a #MemoryRegionSection.
  *
- * Locates the first #MemoryRegion within an address space given by
- * @address_space that overlaps the range given by @addr and @size.
+ * Locates the first #MemoryRegion within @mr that overlaps the range
+ * given by @addr and @size.
  *
  * Returns a #MemoryRegionSection that describes a contiguous overlap.
  * It will have the following characteristics:
- *    . at offset_within_address_space >= @addr
- *    . at offset_within_address_space + . at size <= @addr + @size
  *    . at size = 0 iff no overlap was found
  *    . at mr is non-%NULL iff an overlap was found
  *
- * @address_space: a top-level (i.e. parentless) region that contains
- *       the region to be found
- * @addr: start of the area within @address_space to be searched
+ * Remember that in the return value the @offset_within_region is
+ * relative to the returned region (in the . at mr field), not to the
+ * @mr argument.
+ *
+ * Similarly, the . at offset_within_address_space is relative to the
+ * address space that contains both regions, the passed and the
+ * returned one.  However, in the special case where the @mr argument
+ * has no parent (and thus is the root of the address space), the
+ * following will hold:
+ *    . at offset_within_address_space >= @addr
+ *    . at offset_within_address_space + . at size <= @addr + @size
+ *
+ * @mr: a MemoryRegion within which @addr is a relative address
+ * @addr: start of the area within @as to be searched
  * @size: size of the area to be searched
  */
-MemoryRegionSection memory_region_find(MemoryRegion *address_space,
+MemoryRegionSection memory_region_find(MemoryRegion *mr,
                                        hwaddr addr, uint64_t size);
 
 /**
diff --git a/memory.c b/memory.c
index 75ca281..34bfb13 100644
--- a/memory.c
+++ b/memory.c
@@ -1451,15 +1451,24 @@ static FlatRange *address_space_lookup(AddressSpace *as, AddrRange addr)
                    sizeof(FlatRange), cmp_flatrange_addr);
 }
 
-MemoryRegionSection memory_region_find(MemoryRegion *address_space,
+MemoryRegionSection memory_region_find(MemoryRegion *mr,
                                        hwaddr addr, uint64_t size)
 {
-    AddressSpace *as = memory_region_to_address_space(address_space);
-    AddrRange range = addrrange_make(int128_make64(addr),
-                                     int128_make64(size));
-    FlatRange *fr = address_space_lookup(as, range);
     MemoryRegionSection ret = { .mr = NULL, .size = 0 };
+    MemoryRegion *root;
+    AddressSpace *as;
+    AddrRange range;
+    FlatRange *fr;
+
+    addr += mr->addr;
+    for (root = mr; root->parent; ) {
+        root = root->parent;
+        addr += root->addr;
+    }
 
+    as = memory_region_to_address_space(root);
+    range = addrrange_make(int128_make64(addr), int128_make64(size));
+    fr = address_space_lookup(as, range);
     if (!fr) {
         return ret;
     }
@@ -1470,6 +1479,7 @@ MemoryRegionSection memory_region_find(MemoryRegion *address_space,
     }
 
     ret.mr = fr->mr;
+    ret.address_space = as;
     range = addrrange_intersection(range, fr->addr);
     ret.offset_within_region = fr->offset_in_region;
     ret.offset_within_region += int128_get64(int128_sub(range.start,
commit 68f3f65b09a1ce8c82fac17911ffc3bb6031ebe4
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue May 7 11:30:23 2013 +0200

    memory: assert that PhysPageEntry's ptr does not overflow
    
    While sized to 15 bits in PhysPageEntry, the ptr field is ORed into the
    iotlb entries together with a page-aligned pointer.  The ptr field must
    not overflow into this page-aligned value, assert that it is smaller than
    the page size.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index 1355661..8562fca 100644
--- a/exec.c
+++ b/exec.c
@@ -713,6 +713,12 @@ static void destroy_all_mappings(AddressSpaceDispatch *d)
 
 static uint16_t phys_section_add(MemoryRegionSection *section)
 {
+    /* The physical section number is ORed with a page-aligned
+     * pointer to produce the iotlb entries.  Thus it should
+     * never overflow into the page-aligned value.
+     */
+    assert(phys_sections_nb < TARGET_PAGE_SIZE);
+
     if (phys_sections_nb == phys_sections_nb_alloc) {
         phys_sections_nb_alloc = MAX(phys_sections_nb_alloc * 2, 16);
         phys_sections = g_renew(MemoryRegionSection, phys_sections,
commit 8b0d6711a276bdb9edcd9299b194c7c0d6b56a88
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon May 20 12:40:58 2013 +0200

    exec: eliminate stq_phys_notdirty
    
    It is not used anywhere.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index fa5f9c3..1355661 100644
--- a/exec.c
+++ b/exec.c
@@ -2390,33 +2390,6 @@ void stl_phys_notdirty(hwaddr addr, uint32_t val)
     }
 }
 
-void stq_phys_notdirty(hwaddr addr, uint64_t val)
-{
-    uint8_t *ptr;
-    MemoryRegionSection *section;
-
-    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
-
-    if (!memory_region_is_ram(section->mr) || section->readonly) {
-        addr = memory_region_section_addr(section, addr);
-        if (memory_region_is_ram(section->mr)) {
-            section = &phys_sections[phys_section_rom];
-        }
-#ifdef TARGET_WORDS_BIGENDIAN
-        io_mem_write(section->mr, addr, val >> 32, 4);
-        io_mem_write(section->mr, addr + 4, (uint32_t)val, 4);
-#else
-        io_mem_write(section->mr, addr, (uint32_t)val, 4);
-        io_mem_write(section->mr, addr + 4, val >> 32, 4);
-#endif
-    } else {
-        ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section->mr)
-                                & TARGET_PAGE_MASK)
-                               + memory_region_section_addr(section, addr));
-        stq_p(ptr, val);
-    }
-}
-
 /* warning: addr must be aligned */
 static inline void stl_phys_internal(hwaddr addr, uint32_t val,
                                      enum device_endian endian)
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index af851aa..af5258d 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -102,7 +102,6 @@ uint32_t lduw_phys(hwaddr addr);
 uint32_t ldl_phys(hwaddr addr);
 uint64_t ldq_phys(hwaddr addr);
 void stl_phys_notdirty(hwaddr addr, uint32_t val);
-void stq_phys_notdirty(hwaddr addr, uint64_t val);
 void stw_phys(hwaddr addr, uint32_t val);
 void stl_phys(hwaddr addr, uint32_t val);
 void stq_phys(hwaddr addr, uint64_t val);
diff --git a/include/exec/poison.h b/include/exec/poison.h
index 7d7b23b..2341a75 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -42,7 +42,6 @@
 #pragma GCC poison ldl_phys
 #pragma GCC poison ldq_phys
 #pragma GCC poison stl_phys_notdirty
-#pragma GCC poison stq_phys_notdirty
 #pragma GCC poison stw_phys
 #pragma GCC poison stl_phys
 #pragma GCC poison stq_phys
commit ee983cb3cc8f856b408a272269f434cc9a82ceff
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue May 14 11:47:56 2013 +0200

    exec: make qemu_get_ram_ptr private
    
    It is a private interface between exec.c and memory.c.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index cafc3c2..af851aa 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -49,8 +49,6 @@ typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value);
 typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr);
 
 void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
-/* This should only be used for ram local to a device.  */
-void *qemu_get_ram_ptr(ram_addr_t addr);
 /* This should not be used by devices.  */
 int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
 ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr);
diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
index 1b156fd..8d15f90 100644
--- a/include/exec/memory-internal.h
+++ b/include/exec/memory-internal.h
@@ -46,6 +46,7 @@ void address_space_destroy_dispatch(AddressSpace *as);
 ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
                                    MemoryRegion *mr);
 ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
+void *qemu_get_ram_ptr(ram_addr_t addr);
 void qemu_ram_free(ram_addr_t addr);
 void qemu_ram_free_from_ptr(ram_addr_t addr);
 
commit 4f39178b3ab54538759df92a38655063f5d59301
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue May 14 11:44:02 2013 +0200

    exec: eliminate qemu_put_ram_ptr
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index 197625c..fa5f9c3 100644
--- a/exec.c
+++ b/exec.c
@@ -1334,11 +1334,6 @@ static void *qemu_ram_ptr_length(ram_addr_t addr, ram_addr_t *size)
     }
 }
 
-void qemu_put_ram_ptr(void *addr)
-{
-    trace_qemu_put_ram_ptr(addr);
-}
-
 int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
 {
     RAMBlock *block;
@@ -1928,7 +1923,6 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
                 ptr = qemu_get_ram_ptr(addr1);
                 memcpy(ptr, buf, l);
                 invalidate_and_set_dirty(addr1, l);
-                qemu_put_ram_ptr(ptr);
             }
         } else {
             if (!(memory_region_is_ram(section->mr) ||
@@ -1958,7 +1952,6 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
                                        + memory_region_section_addr(section,
                                                                     addr));
                 memcpy(buf, ptr, l);
-                qemu_put_ram_ptr(ptr);
             }
         }
         len -= l;
@@ -2020,7 +2013,6 @@ void cpu_physical_memory_write_rom(hwaddr addr,
             ptr = qemu_get_ram_ptr(addr1);
             memcpy(ptr, buf, l);
             invalidate_and_set_dirty(addr1, l);
-            qemu_put_ram_ptr(ptr);
         }
         len -= l;
         buf += l;
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index d5257ed..bb3879b 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1959,8 +1959,6 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
         pci_patch_ids(pdev, ptr, size);
     }
 
-    qemu_put_ram_ptr(ptr);
-
     pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
 
     return 0;
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 4934a81..fe6550c 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -711,7 +711,6 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd)
 
         ptr = memory_region_get_ram_ptr(&s->dev.rom);
         memcpy(biosver, ptr + 0x41, 31);
-        qemu_put_ram_ptr(ptr);
         memcpy(info.image_component[1].name, "BIOS", 4);
         memcpy(info.image_component[1].version, biosver,
                strlen((const char *)biosver));
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 2e5f11f..cafc3c2 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -51,7 +51,6 @@ typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr);
 void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
 /* This should only be used for ram local to a device.  */
 void *qemu_get_ram_ptr(ram_addr_t addr);
-void qemu_put_ram_ptr(void *addr);
 /* This should not be used by devices.  */
 int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
 ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr);
diff --git a/trace-events b/trace-events
index 9c73931..b123b0f 100644
--- a/trace-events
+++ b/trace-events
@@ -813,9 +813,6 @@ xen_map_cache_return(void* ptr) "%p"
 xen_map_block(uint64_t phys_addr, uint64_t size) "%#"PRIx64", size %#"PRIx64
 xen_unmap_block(void* addr, unsigned long size) "%p, size %#lx"
 
-# exec.c
-qemu_put_ram_ptr(void* addr) "%p"
-
 # hw/xen_platform.c
 xen_platform_log(char *s) "xen platform: %s"
 
commit bbcfd2913cdb8623d1c57fa26bf481f34bf7989a
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Apr 11 15:33:16 2013 +0200

    exec: remove obsolete comment
    
    See how we call memory_region_section_addr two lines below to
    convert a physical address to a base address in the region.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index aec65c5..197625c 100644
--- a/exec.c
+++ b/exec.c
@@ -639,12 +639,6 @@ hwaddr memory_region_section_get_iotlb(CPUArchState *env,
             iotlb |= phys_section_rom;
         }
     } else {
-        /* IO handlers are currently passed a physical address.
-           It would be nice to pass an offset from the base address
-           of that region.  This would avoid having to special case RAM,
-           and avoid full address decoding in every device.
-           We can't use the high bits of pd for this because
-           IO_MEM_ROMD uses these as a ram address.  */
         iotlb = section - phys_sections;
         iotlb += memory_region_section_addr(section, paddr);
     }
commit 00b7ade807b5ce6779ddd86ce29c5521ec5c529a
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Wed May 22 14:50:18 2013 +0200

    rtl8139: flush queued packets when RxBufPtr is written
    
    Net queues support efficient "receive disable".  For example, tap's file
    descriptor will not be polled while its peer has receive disabled.  This
    saves CPU cycles for needlessly copying and then dropping packets which
    the peer cannot receive.
    
    rtl8139 is missing the qemu_flush_queued_packets() call that wakes the
    queue up when receive becomes possible again.
    
    As a result, the Windows 7 guest driver reaches a state where the
    rtl8139 cannot receive packets.  The driver has actually refilled the
    receive buffer but we never resume reception.
    
    The bug can be reproduced by running a large FTP 'get' inside a Windows
    7 guest:
    
      $ qemu -netdev tap,id=tap0,...
             -device rtl8139,netdev=tap0
    
    The Linux guest driver does not trigger the bug, probably due to a
    different buffer management strategy.
    
    Reported-by: Oliver Francke <oliver.francke at filoo.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 9369507..7993f9f 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -2575,6 +2575,9 @@ static void rtl8139_RxBufPtr_write(RTL8139State *s, uint32_t val)
     /* this value is off by 16 */
     s->RxBufPtr = MOD2(val + 0x10, s->RxBufferSize);
 
+    /* more buffer space may be available so try to receive */
+    qemu_flush_queued_packets(qemu_get_queue(s->nic));
+
     DPRINTF(" CAPR write: rx buffer length %d head 0x%04x read 0x%04x\n",
         s->RxBufferSize, s->RxBufAddr, s->RxBufPtr);
 }
commit d73fe37e7bab4ef06b94c48b2a8d8952c03619d4
Author: Alasdair McLeay <alasdair.mcleay at me.com>
Date:   Thu May 9 19:44:30 2013 +0100

    net: support for bridged networking on Mac OS X
    
    tun tap can be implemented on Mac OS X using
    http://tuntaposx.sourceforge.net
    
    It behaves in the same way as FreeBSD/OpenBSD implementations, but Qemu
    needs a patch to use the OpenBS/FreeBSD code.
    
    As per the patch listed in this forum thread:
    http://forum.gns3.net/post17679.html#p17679
    
    And also as used in the MacPorts installation:
    https://trac.macports.org/browser/trunk/dports/emulators/qemu/files/patch-net-tap-interface.diff
    
    Signed-off-by: Alasdair McLeay <alasdair.mcleay at me.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/net/tap-bsd.c b/net/tap-bsd.c
index bcdb268..f61d580 100644
--- a/net/tap-bsd.c
+++ b/net/tap-bsd.c
@@ -44,7 +44,8 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
     struct stat s;
 #endif
 
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
+    defined(__OpenBSD__) || defined(__APPLE__)
     /* if no ifname is given, always start the search from tap0/tun0. */
     int i;
     char dname[100];
commit 02ffb504485f0920cfc75a0982a602f824a9a4f4
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Fri May 17 15:51:26 2013 +0200

    coroutine: stop using AioContext in CoQueue
    
    qemu_co_queue_next(&queue) arranges that the next queued coroutine is
    run at a later point in time.  This deferred restart is useful because
    the caller may not want to transfer control yet.
    
    This behavior was implemented using QEMUBH in the past, which meant that
    CoQueue (and hence CoMutex and CoRwlock) had a dependency on the
    AioContext event loop.  This hidden dependency causes trouble when we
    move to a world with multiple event loops - now qemu_co_queue_next()
    needs to know which event loop to schedule the QEMUBH in.
    
    After pondering how to stash AioContext I realized the best solution is
    to not use AioContext at all.  This patch implements the deferred
    restart behavior purely in terms of coroutines and no longer uses
    QEMUBH.
    
    Here is how it works:
    
    Each Coroutine has a wakeup queue that starts out empty.  When
    qemu_co_queue_next() is called, the next coroutine is added to our
    wakeup queue.  The wakeup queue is processed when we yield or terminate.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/include/block/coroutine_int.h b/include/block/coroutine_int.h
index 17eb71e..f133d65 100644
--- a/include/block/coroutine_int.h
+++ b/include/block/coroutine_int.h
@@ -38,6 +38,9 @@ struct Coroutine {
     void *entry_arg;
     Coroutine *caller;
     QSLIST_ENTRY(Coroutine) pool_next;
+
+    /* Coroutines that should be woken up when we yield or terminate */
+    QTAILQ_HEAD(, Coroutine) co_queue_wakeup;
     QTAILQ_ENTRY(Coroutine) co_queue_next;
 };
 
@@ -45,5 +48,6 @@ Coroutine *qemu_coroutine_new(void);
 void qemu_coroutine_delete(Coroutine *co);
 CoroutineAction qemu_coroutine_switch(Coroutine *from, Coroutine *to,
                                       CoroutineAction action);
+void coroutine_fn qemu_co_queue_run_restart(Coroutine *co);
 
 #endif
diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c
index 86efe1f..d9fea49 100644
--- a/qemu-coroutine-lock.c
+++ b/qemu-coroutine-lock.c
@@ -26,39 +26,11 @@
 #include "block/coroutine.h"
 #include "block/coroutine_int.h"
 #include "qemu/queue.h"
-#include "block/aio.h"
 #include "trace.h"
 
-/* Coroutines are awoken from a BH to allow the current coroutine to complete
- * its flow of execution.  The BH may run after the CoQueue has been destroyed,
- * so keep BH data in a separate heap-allocated struct.
- */
-typedef struct {
-    QEMUBH *bh;
-    QTAILQ_HEAD(, Coroutine) entries;
-} CoQueueNextData;
-
-static void qemu_co_queue_next_bh(void *opaque)
-{
-    CoQueueNextData *data = opaque;
-    Coroutine *next;
-
-    trace_qemu_co_queue_next_bh();
-    while ((next = QTAILQ_FIRST(&data->entries))) {
-        QTAILQ_REMOVE(&data->entries, next, co_queue_next);
-        qemu_coroutine_enter(next, NULL);
-    }
-
-    qemu_bh_delete(data->bh);
-    g_slice_free(CoQueueNextData, data);
-}
-
 void qemu_co_queue_init(CoQueue *queue)
 {
     QTAILQ_INIT(&queue->entries);
-
-    /* This will be exposed to callers once there are multiple AioContexts */
-    queue->ctx = qemu_get_aio_context();
 }
 
 void coroutine_fn qemu_co_queue_wait(CoQueue *queue)
@@ -77,23 +49,37 @@ void coroutine_fn qemu_co_queue_wait_insert_head(CoQueue *queue)
     assert(qemu_in_coroutine());
 }
 
+/**
+ * qemu_co_queue_run_restart:
+ *
+ * Enter each coroutine that was previously marked for restart by
+ * qemu_co_queue_next() or qemu_co_queue_restart_all().  This function is
+ * invoked by the core coroutine code when the current coroutine yields or
+ * terminates.
+ */
+void qemu_co_queue_run_restart(Coroutine *co)
+{
+    Coroutine *next;
+
+    trace_qemu_co_queue_run_restart(co);
+    while ((next = QTAILQ_FIRST(&co->co_queue_wakeup))) {
+        QTAILQ_REMOVE(&co->co_queue_wakeup, next, co_queue_next);
+        qemu_coroutine_enter(next, NULL);
+    }
+}
+
 static bool qemu_co_queue_do_restart(CoQueue *queue, bool single)
 {
+    Coroutine *self = qemu_coroutine_self();
     Coroutine *next;
-    CoQueueNextData *data;
 
     if (QTAILQ_EMPTY(&queue->entries)) {
         return false;
     }
 
-    data = g_slice_new(CoQueueNextData);
-    data->bh = aio_bh_new(queue->ctx, qemu_co_queue_next_bh, data);
-    QTAILQ_INIT(&data->entries);
-    qemu_bh_schedule(data->bh);
-
     while ((next = QTAILQ_FIRST(&queue->entries)) != NULL) {
         QTAILQ_REMOVE(&queue->entries, next, co_queue_next);
-        QTAILQ_INSERT_TAIL(&data->entries, next, co_queue_next);
+        QTAILQ_INSERT_TAIL(&self->co_queue_wakeup, next, co_queue_next);
         trace_qemu_co_queue_next(next);
         if (single) {
             break;
diff --git a/qemu-coroutine.c b/qemu-coroutine.c
index 60ac79e..423430d 100644
--- a/qemu-coroutine.c
+++ b/qemu-coroutine.c
@@ -45,6 +45,7 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
     }
 
     co->entry = entry;
+    QTAILQ_INIT(&co->co_queue_wakeup);
     return co;
 }
 
@@ -87,6 +88,8 @@ static void coroutine_swap(Coroutine *from, Coroutine *to)
 
     ret = qemu_coroutine_switch(from, to, COROUTINE_YIELD);
 
+    qemu_co_queue_run_restart(to);
+
     switch (ret) {
     case COROUTINE_YIELD:
         return;
diff --git a/trace-events b/trace-events
index 9c73931..f51408a 100644
--- a/trace-events
+++ b/trace-events
@@ -825,7 +825,7 @@ qemu_coroutine_yield(void *from, void *to) "from %p to %p"
 qemu_coroutine_terminate(void *co) "self %p"
 
 # qemu-coroutine-lock.c
-qemu_co_queue_next_bh(void) ""
+qemu_co_queue_run_restart(void *co) "co %p"
 qemu_co_queue_next(void *nxt) "next %p"
 qemu_co_mutex_lock_entry(void *mutex, void *self) "mutex %p self %p"
 qemu_co_mutex_lock_return(void *mutex, void *self) "mutex %p self %p"
commit b84c4586234b26ccc875595713f6f4491e5b3385
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Fri May 17 15:51:25 2013 +0200

    coroutine: protect global pool with a mutex
    
    The coroutine freelist is a global pool of unused coroutines.  It avoids
    the setup/teardown overhead associated with the coroutine lifecycle.
    Since the pool is global, we need to synchronize access so that
    coroutines can be used outside the BQL.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/qemu-coroutine.c b/qemu-coroutine.c
index 25a14c6..60ac79e 100644
--- a/qemu-coroutine.c
+++ b/qemu-coroutine.c
@@ -14,6 +14,7 @@
 
 #include "trace.h"
 #include "qemu-common.h"
+#include "qemu/thread.h"
 #include "block/coroutine.h"
 #include "block/coroutine_int.h"
 
@@ -23,6 +24,7 @@ enum {
 };
 
 /** Free list to speed up creation */
+static QemuMutex pool_lock;
 static QSLIST_HEAD(, Coroutine) pool = QSLIST_HEAD_INITIALIZER(pool);
 static unsigned int pool_size;
 
@@ -30,11 +32,15 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
 {
     Coroutine *co;
 
+    qemu_mutex_lock(&pool_lock);
     co = QSLIST_FIRST(&pool);
     if (co) {
         QSLIST_REMOVE_HEAD(&pool, pool_next);
         pool_size--;
-    } else {
+    }
+    qemu_mutex_unlock(&pool_lock);
+
+    if (!co) {
         co = qemu_coroutine_new();
     }
 
@@ -44,17 +50,25 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
 
 static void coroutine_delete(Coroutine *co)
 {
+    qemu_mutex_lock(&pool_lock);
     if (pool_size < POOL_MAX_SIZE) {
         QSLIST_INSERT_HEAD(&pool, co, pool_next);
         co->caller = NULL;
         pool_size++;
+        qemu_mutex_unlock(&pool_lock);
         return;
     }
+    qemu_mutex_unlock(&pool_lock);
 
     qemu_coroutine_delete(co);
 }
 
-static void __attribute__((destructor)) coroutine_cleanup(void)
+static void __attribute__((constructor)) coroutine_pool_init(void)
+{
+    qemu_mutex_init(&pool_lock);
+}
+
+static void __attribute__((destructor)) coroutine_pool_cleanup(void)
 {
     Coroutine *co;
     Coroutine *tmp;
@@ -63,6 +77,8 @@ static void __attribute__((destructor)) coroutine_cleanup(void)
         QSLIST_REMOVE_HEAD(&pool, pool_next);
         qemu_coroutine_delete(co);
     }
+
+    qemu_mutex_destroy(&pool_lock);
 }
 
 static void coroutine_swap(Coroutine *from, Coroutine *to)
commit bd91ecbf5b43b52321c4d938e16a612b9c68bf06
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Mon May 13 14:11:13 2013 +0200

    qemu-iotests: Try creating huge qcow2 image
    
    It's supposed to fail gracefully instead of segfaulting.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/tests/qemu-iotests/054 b/tests/qemu-iotests/054
new file mode 100755
index 0000000..b360429
--- /dev/null
+++ b/tests/qemu-iotests/054
@@ -0,0 +1,58 @@
+#!/bin/bash
+#
+# Test huge qcow2 images
+#
+# Copyright (C) 2013 Red Hat, Inc.
+#
+# 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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/>.
+#
+
+# creator
+owner=kwolf at redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+
+_cleanup()
+{
+	_cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+echo
+echo "creating too large image (1 EB)"
+_make_test_img $((1024*1024))T
+
+echo
+echo "creating too large image (1 EB) using qcow2.py"
+_make_test_img 4G
+./qcow2.py $TEST_IMG set-header size $((1024 ** 6))
+_check_test_img
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/054.out b/tests/qemu-iotests/054.out
new file mode 100644
index 0000000..0b2fe30
--- /dev/null
+++ b/tests/qemu-iotests/054.out
@@ -0,0 +1,10 @@
+QA output created by 054
+
+creating too large image (1 EB)
+qemu-img: The image size is too large for file format 'qcow2'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1152921504606846976 
+
+creating too large image (1 EB) using qcow2.py
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4294967296 
+qemu-img: Could not open 'TEST_DIR/t.qcow2': File too large
+*** done
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 31eb62b..e9ba358 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -167,7 +167,7 @@ _cleanup_test_img()
 
 _check_test_img()
 {
-    $QEMU_IMG check "$@" -f $IMGFMT $TEST_IMG 2>&1 | \
+    $QEMU_IMG check "$@" -f $IMGFMT $TEST_IMG 2>&1 | _filter_testdir | \
         sed -e '/allocated.*fragmented.*compressed clusters/d' \
             -e 's/qemu-img: This image format does not support checks/No errors were found on the image./' \
             -e '/Image end offset: [0-9]\+/d'
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index bf944d9..387b050 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -60,3 +60,4 @@
 #051 rw auto
 052 rw auto backing
 053 rw auto
+054 rw auto
commit c93331c9146719958a4b102435fcd0566da45ea2
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Mon May 13 14:00:15 2013 +0200

    qcow2.py: Subcommand for changing header fields
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/tests/qemu-iotests/qcow2.py b/tests/qemu-iotests/qcow2.py
index fecf5b9..44a2b45 100755
--- a/tests/qemu-iotests/qcow2.py
+++ b/tests/qemu-iotests/qcow2.py
@@ -149,6 +149,22 @@ def cmd_dump_header(fd):
     h.dump()
     h.dump_extensions()
 
+def cmd_set_header(fd, name, value):
+    try:
+        value = int(value, 0)
+    except:
+        print "'%s' is not a valid number" % value
+        sys.exit(1)
+
+    fields = (field[2] for field in QcowHeader.fields)
+    if not name in fields:
+        print "'%s' is not a known header field" % name
+        sys.exit(1)
+
+    h = QcowHeader(fd)
+    h.__dict__[name] = value
+    h.update(fd)
+
 def cmd_add_header_ext(fd, magic, data):
     try:
         magic = int(magic, 0)
@@ -205,6 +221,7 @@ def cmd_set_feature_bit(fd, group, bit):
 
 cmds = [
     [ 'dump-header',    cmd_dump_header,    0, 'Dump image header and header extensions' ],
+    [ 'set-header',     cmd_set_header,     2, 'Set a field in the header'],
     [ 'add-header-ext', cmd_add_header_ext, 2, 'Add a header extension' ],
     [ 'del-header-ext', cmd_del_header_ext, 1, 'Delete a header extension' ],
     [ 'set-feature-bit', cmd_set_feature_bit, 2, 'Set a feature bit'],
commit a00e81e98f71c91a35b96bcd8ae431a86f42378d
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Mon May 13 15:31:34 2013 +0200

    qemu-io: Fix 'map' output
    
    The output of the 'map' command in qemu-io used to directly resemble
    bdrv_is_allocated() and could contain many lines for small chunks that
    all have the same allocation status. After this patch, they will be
    coalesced into a single output line for a large chunk.
    
    As a side effect, the command gains some error handling.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/qemu-io.c b/qemu-io.c
index 475a8bd..5e6680b 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -1635,12 +1635,43 @@ static const cmdinfo_t alloc_cmd = {
     .oneline    = "checks if a sector is present in the file",
 };
 
+
+static int map_is_allocated(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(int argc, char **argv)
 {
     int64_t offset;
     int64_t nb_sectors;
     char s1[64];
-    int num, num_checked;
+    int64_t num;
     int ret;
     const char *retstr;
 
@@ -1648,12 +1679,17 @@ static int map_f(int argc, char **argv)
     nb_sectors = bs->total_sectors;
 
     do {
-        num_checked = MIN(nb_sectors, INT_MAX);
-        ret = bdrv_is_allocated(bs, offset, num_checked, &num);
+        ret = map_is_allocated(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 "] % 8d/% 8d sectors %s at offset %s (%d)\n",
-               offset << 9ULL, num, num_checked, retstr, s1, ret);
+        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;
commit c8a83e8500329d82f1282c4905be11a39078007f
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Mon May 13 10:43:43 2013 +0200

    blockdev: Rename BlockdevAction -> TransactionAction
    
    There's no reason to restrict transactions to operations related to
    block devices, so rename the type now before schema introspection stops
    us from doing so.
    
    Also change the schema documentation of 'transaction' to not refer to
    block devices or snapshots any more.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/blockdev.c b/blockdev.c
index 617501c..d1ec99a 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -750,8 +750,8 @@ void do_commit(Monitor *mon, const QDict *qdict)
 
 static void blockdev_do_action(int kind, void *data, Error **errp)
 {
-    BlockdevAction action;
-    BlockdevActionList list;
+    TransactionAction action;
+    TransactionActionList list;
 
     action.kind = kind;
     action.data = data;
@@ -773,8 +773,8 @@ void qmp_blockdev_snapshot_sync(const char *device, const char *snapshot_file,
         .has_mode = has_mode,
         .mode = mode,
     };
-    blockdev_do_action(BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC, &snapshot,
-                       errp);
+    blockdev_do_action(TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC,
+                       &snapshot, errp);
 }
 
 
@@ -803,7 +803,7 @@ typedef struct BdrvActionOps {
  * Later it will be used in free().
  */
 struct BlkTransactionStates {
-    BlockdevAction *action;
+    TransactionAction *action;
     const BdrvActionOps *ops;
     QSIMPLEQ_ENTRY(BlkTransactionStates) entry;
 };
@@ -828,10 +828,10 @@ static void external_snapshot_prepare(BlkTransactionStates *common,
     enum NewImageMode mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
     ExternalSnapshotStates *states =
                              DO_UPCAST(ExternalSnapshotStates, common, common);
-    BlockdevAction *action = common->action;
+    TransactionAction *action = common->action;
 
     /* get parameters */
-    g_assert(action->kind == BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC);
+    g_assert(action->kind == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC);
 
     device = action->blockdev_snapshot_sync->device;
     new_image_file = action->blockdev_snapshot_sync->snapshot_file;
@@ -927,7 +927,7 @@ static void external_snapshot_abort(BlkTransactionStates *common)
 }
 
 static const BdrvActionOps actions[] = {
-    [BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC] = {
+    [TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC] = {
         .instance_size = sizeof(ExternalSnapshotStates),
         .prepare  = external_snapshot_prepare,
         .commit   = external_snapshot_commit,
@@ -940,9 +940,9 @@ static const BdrvActionOps actions[] = {
  *  then we do not pivot any of the devices in the group, and abandon the
  *  snapshots
  */
-void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
+void qmp_transaction(TransactionActionList *dev_list, Error **errp)
 {
-    BlockdevActionList *dev_entry = dev_list;
+    TransactionActionList *dev_entry = dev_list;
     BlkTransactionStates *states, *next;
     Error *local_err = NULL;
 
@@ -954,7 +954,7 @@ void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
 
     /* We don't do anything in this loop that commits us to the snapshot */
     while (NULL != dev_entry) {
-        BlockdevAction *dev_info = NULL;
+        TransactionAction *dev_info = NULL;
         const BdrvActionOps *ops;
 
         dev_info = dev_entry->value;
diff --git a/qapi-schema.json b/qapi-schema.json
index 664b31f..ef1f657 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1609,12 +1609,12 @@
             '*mode': 'NewImageMode' } }
 
 ##
-# @BlockdevAction
+# @TransactionAction
 #
 # A discriminated record of operations that can be performed with
 # @transaction.
 ##
-{ 'union': 'BlockdevAction',
+{ 'union': 'TransactionAction',
   'data': {
        'blockdev-snapshot-sync': 'BlockdevSnapshot'
    } }
@@ -1622,25 +1622,24 @@
 ##
 # @transaction
 #
-# Atomically operate on a group of one or more block devices.  If
-# any operation fails, then the entire set of actions will be
-# abandoned and the appropriate error returned.  The only operation
-# supported is currently blockdev-snapshot-sync.
+# Executes a number of transactionable QMP commands atomically. If any
+# operation fails, then the entire set of actions will be abandoned and the
+# appropriate error returned.
 #
 #  List of:
-#  @BlockdevAction: information needed for the device snapshot
+#  @TransactionAction: information needed for the respective operation
 #
 # Returns: nothing on success
-#          If @device is not a valid block device, DeviceNotFound
+#          Errors depend on the operations of the transaction
 #
-# Note: The transaction aborts on the first failure.  Therefore, there will
-# be only one device or snapshot file returned in an error condition, and
+# Note: The transaction aborts on the first failure.  Therefore, there will be
+# information on only one failed operation returned in an error condition, and
 # subsequent actions will not have been attempted.
 #
 # Since 1.1
 ##
 { 'command': 'transaction',
-  'data': { 'actions': [ 'BlockdevAction' ] } }
+  'data': { 'actions': [ 'TransactionAction' ] } }
 
 ##
 # @blockdev-snapshot-sync
commit ba0c86a34e29b31ef360feda74c94200a5403fdd
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Wed May 8 18:25:16 2013 +0800

    block: make all steps in qmp_transaction() as callback
    
    Make it easier to add other operations to qmp_transaction() by using
    callbacks, with external snapshots serving as an example implementation
    of the callbacks.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/blockdev.c b/blockdev.c
index 2131e13..617501c 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -779,14 +779,43 @@ void qmp_blockdev_snapshot_sync(const char *device, const char *snapshot_file,
 
 
 /* New and old BlockDriverState structs for group snapshots */
-typedef struct BlkTransactionStates {
+
+typedef struct BlkTransactionStates BlkTransactionStates;
+
+/* Only prepare() may fail. In a single transaction, only one of commit() or
+   abort() will be called, clean() will always be called if it present. */
+typedef struct BdrvActionOps {
+    /* Size of state struct, in bytes. */
+    size_t instance_size;
+    /* Prepare the work, must NOT be NULL. */
+    void (*prepare)(BlkTransactionStates *common, Error **errp);
+    /* Commit the changes, must NOT be NULL. */
+    void (*commit)(BlkTransactionStates *common);
+    /* Abort the changes on fail, can be NULL. */
+    void (*abort)(BlkTransactionStates *common);
+    /* Clean up resource in the end, can be NULL. */
+    void (*clean)(BlkTransactionStates *common);
+} BdrvActionOps;
+
+/*
+ * This structure must be arranged as first member in child type, assuming
+ * that compiler will also arrange it to the same address with parent instance.
+ * Later it will be used in free().
+ */
+struct BlkTransactionStates {
+    BlockdevAction *action;
+    const BdrvActionOps *ops;
+    QSIMPLEQ_ENTRY(BlkTransactionStates) entry;
+};
+
+/* external snapshot private data */
+typedef struct ExternalSnapshotStates {
+    BlkTransactionStates common;
     BlockDriverState *old_bs;
     BlockDriverState *new_bs;
-    QSIMPLEQ_ENTRY(BlkTransactionStates) entry;
-} BlkTransactionStates;
+} ExternalSnapshotStates;
 
-static void external_snapshot_prepare(BlockdevAction *action,
-                                      BlkTransactionStates *states,
+static void external_snapshot_prepare(BlkTransactionStates *common,
                                       Error **errp)
 {
     BlockDriver *proto_drv;
@@ -797,6 +826,9 @@ static void external_snapshot_prepare(BlockdevAction *action,
     const char *new_image_file;
     const char *format = "qcow2";
     enum NewImageMode mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
+    ExternalSnapshotStates *states =
+                             DO_UPCAST(ExternalSnapshotStates, common, common);
+    BlockdevAction *action = common->action;
 
     /* get parameters */
     g_assert(action->kind == BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC);
@@ -871,8 +903,11 @@ static void external_snapshot_prepare(BlockdevAction *action,
     }
 }
 
-static void external_snapshot_commit(BlkTransactionStates *states)
+static void external_snapshot_commit(BlkTransactionStates *common)
 {
+    ExternalSnapshotStates *states =
+                             DO_UPCAST(ExternalSnapshotStates, common, common);
+
     /* This removes our old bs from the bdrv_states, and adds the new bs */
     bdrv_append(states->new_bs, states->old_bs);
     /* We don't need (or want) to use the transactional
@@ -882,13 +917,24 @@ static void external_snapshot_commit(BlkTransactionStates *states)
                 NULL);
 }
 
-static void external_snapshot_abort(BlkTransactionStates *states)
+static void external_snapshot_abort(BlkTransactionStates *common)
 {
+    ExternalSnapshotStates *states =
+                             DO_UPCAST(ExternalSnapshotStates, common, common);
     if (states->new_bs) {
         bdrv_delete(states->new_bs);
     }
 }
 
+static const BdrvActionOps actions[] = {
+    [BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC] = {
+        .instance_size = sizeof(ExternalSnapshotStates),
+        .prepare  = external_snapshot_prepare,
+        .commit   = external_snapshot_commit,
+        .abort = external_snapshot_abort,
+    },
+};
+
 /*
  * 'Atomic' group snapshots.  The snapshots are taken as a set, and if any fail
  *  then we do not pivot any of the devices in the group, and abandon the
@@ -909,32 +955,28 @@ void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
     /* We don't do anything in this loop that commits us to the snapshot */
     while (NULL != dev_entry) {
         BlockdevAction *dev_info = NULL;
+        const BdrvActionOps *ops;
 
         dev_info = dev_entry->value;
         dev_entry = dev_entry->next;
 
-        states = g_malloc0(sizeof(BlkTransactionStates));
+        assert(dev_info->kind < ARRAY_SIZE(actions));
+
+        ops = &actions[dev_info->kind];
+        states = g_malloc0(ops->instance_size);
+        states->ops = ops;
+        states->action = dev_info;
         QSIMPLEQ_INSERT_TAIL(&snap_bdrv_states, states, entry);
 
-        switch (dev_info->kind) {
-        case BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC:
-            external_snapshot_prepare(dev_info, states, errp);
-            if (error_is_set(&local_err)) {
-                error_propagate(errp, local_err);
-                goto delete_and_fail;
-            }
-            break;
-        default:
-            abort();
+        states->ops->prepare(states, &local_err);
+        if (error_is_set(&local_err)) {
+            error_propagate(errp, local_err);
+            goto delete_and_fail;
         }
-
     }
 
-
-    /* Now we are going to do the actual pivot.  Everything up to this point
-     * is reversible, but we are committed at this point */
     QSIMPLEQ_FOREACH(states, &snap_bdrv_states, entry) {
-        external_snapshot_commit(states);
+        states->ops->commit(states);
     }
 
     /* success */
@@ -946,10 +988,15 @@ delete_and_fail:
     * the original bs for all images
     */
     QSIMPLEQ_FOREACH(states, &snap_bdrv_states, entry) {
-        external_snapshot_abort(states);
+        if (states->ops->abort) {
+            states->ops->abort(states);
+        }
     }
 exit:
     QSIMPLEQ_FOREACH_SAFE(states, &snap_bdrv_states, entry, next) {
+        if (states->ops->clean) {
+            states->ops->clean(states);
+        }
         g_free(states);
     }
 }
commit 96b86bf72de0c6eda2799201517ef32910beb340
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Wed May 8 18:25:15 2013 +0800

    block: package rollback code in qmp_transaction()
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/blockdev.c b/blockdev.c
index 76f0532..2131e13 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -882,6 +882,13 @@ static void external_snapshot_commit(BlkTransactionStates *states)
                 NULL);
 }
 
+static void external_snapshot_abort(BlkTransactionStates *states)
+{
+    if (states->new_bs) {
+        bdrv_delete(states->new_bs);
+    }
+}
+
 /*
  * 'Atomic' group snapshots.  The snapshots are taken as a set, and if any fail
  *  then we do not pivot any of the devices in the group, and abandon the
@@ -939,9 +946,7 @@ delete_and_fail:
     * the original bs for all images
     */
     QSIMPLEQ_FOREACH(states, &snap_bdrv_states, entry) {
-        if (states->new_bs) {
-             bdrv_delete(states->new_bs);
-        }
+        external_snapshot_abort(states);
     }
 exit:
     QSIMPLEQ_FOREACH_SAFE(states, &snap_bdrv_states, entry, next) {
commit 3b0047e86a1c215d830b1ae1da0778db4636b83a
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Wed May 8 18:25:14 2013 +0800

    block: package committing code in qmp_transaction()
    
    The code is simply moved into a separate function.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/blockdev.c b/blockdev.c
index 0115f46..76f0532 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -871,6 +871,17 @@ static void external_snapshot_prepare(BlockdevAction *action,
     }
 }
 
+static void external_snapshot_commit(BlkTransactionStates *states)
+{
+    /* This removes our old bs from the bdrv_states, and adds the new bs */
+    bdrv_append(states->new_bs, states->old_bs);
+    /* We don't need (or want) to use the transactional
+     * bdrv_reopen_multiple() across all the entries at once, because we
+     * don't want to abort all of them if one of them fails the reopen */
+    bdrv_reopen(states->new_bs, states->new_bs->open_flags & ~BDRV_O_RDWR,
+                NULL);
+}
+
 /*
  * 'Atomic' group snapshots.  The snapshots are taken as a set, and if any fail
  *  then we do not pivot any of the devices in the group, and abandon the
@@ -916,13 +927,7 @@ void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
     /* Now we are going to do the actual pivot.  Everything up to this point
      * is reversible, but we are committed at this point */
     QSIMPLEQ_FOREACH(states, &snap_bdrv_states, entry) {
-        /* This removes our old bs from the bdrv_states, and adds the new bs */
-        bdrv_append(states->new_bs, states->old_bs);
-        /* We don't need (or want) to use the transactional
-         * bdrv_reopen_multiple() across all the entries at once, because we
-         * don't want to abort all of them if one of them fails the reopen */
-        bdrv_reopen(states->new_bs, states->new_bs->open_flags & ~BDRV_O_RDWR,
-                    NULL);
+        external_snapshot_commit(states);
     }
 
     /* success */
commit e2a31e8798e8246bed8ab396a71cd06bf95edde6
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Wed May 8 18:25:13 2013 +0800

    block: move input parsing code in qmp_transaction()
    
    The code is moved into preparation function, and changed
    a bit to tip more clearly what it is doing.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/blockdev.c b/blockdev.c
index 1cb9640..0115f46 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -785,10 +785,7 @@ typedef struct BlkTransactionStates {
     QSIMPLEQ_ENTRY(BlkTransactionStates) entry;
 } BlkTransactionStates;
 
-static void external_snapshot_prepare(const char *device,
-                                      const char *format,
-                                      const char *new_image_file,
-                                      enum NewImageMode mode,
+static void external_snapshot_prepare(BlockdevAction *action,
                                       BlkTransactionStates *states,
                                       Error **errp)
 {
@@ -796,7 +793,24 @@ static void external_snapshot_prepare(const char *device,
     BlockDriver *drv;
     int flags, ret;
     Error *local_err = NULL;
+    const char *device;
+    const char *new_image_file;
+    const char *format = "qcow2";
+    enum NewImageMode mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
 
+    /* get parameters */
+    g_assert(action->kind == BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC);
+
+    device = action->blockdev_snapshot_sync->device;
+    new_image_file = action->blockdev_snapshot_sync->snapshot_file;
+    if (action->blockdev_snapshot_sync->has_format) {
+        format = action->blockdev_snapshot_sync->format;
+    }
+    if (action->blockdev_snapshot_sync->has_mode) {
+        mode = action->blockdev_snapshot_sync->mode;
+    }
+
+    /* start processing */
     drv = bdrv_find_format(format);
     if (!drv) {
         error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
@@ -877,10 +891,6 @@ void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
     /* We don't do anything in this loop that commits us to the snapshot */
     while (NULL != dev_entry) {
         BlockdevAction *dev_info = NULL;
-        enum NewImageMode mode;
-        const char *new_image_file;
-        const char *device;
-        const char *format = "qcow2";
 
         dev_info = dev_entry->value;
         dev_entry = dev_entry->next;
@@ -890,17 +900,7 @@ void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
 
         switch (dev_info->kind) {
         case BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC:
-            device = dev_info->blockdev_snapshot_sync->device;
-            if (!dev_info->blockdev_snapshot_sync->has_mode) {
-                dev_info->blockdev_snapshot_sync->mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
-            }
-            new_image_file = dev_info->blockdev_snapshot_sync->snapshot_file;
-            if (dev_info->blockdev_snapshot_sync->has_format) {
-                format = dev_info->blockdev_snapshot_sync->format;
-            }
-            mode = dev_info->blockdev_snapshot_sync->mode;
-            external_snapshot_prepare(device, format, new_image_file,
-                                      mode, states, &local_err);
+            external_snapshot_prepare(dev_info, states, errp);
             if (error_is_set(&local_err)) {
                 error_propagate(errp, local_err);
                 goto delete_and_fail;
commit 9b9877ee9f1c27588a286f591852c0b7c0548b6a
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Wed May 8 18:25:12 2013 +0800

    block: package preparation code in qmp_transaction()
    
    The code before really committing is moved into a function. Most
    code is simply moved from qmp_transaction(), except that on fail it
    just returns now. Other code such as input parsing is not touched,
    to make it easier in review.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/blockdev.c b/blockdev.c
index 7c9d8dd..1cb9640 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -785,6 +785,78 @@ typedef struct BlkTransactionStates {
     QSIMPLEQ_ENTRY(BlkTransactionStates) entry;
 } BlkTransactionStates;
 
+static void external_snapshot_prepare(const char *device,
+                                      const char *format,
+                                      const char *new_image_file,
+                                      enum NewImageMode mode,
+                                      BlkTransactionStates *states,
+                                      Error **errp)
+{
+    BlockDriver *proto_drv;
+    BlockDriver *drv;
+    int flags, ret;
+    Error *local_err = NULL;
+
+    drv = bdrv_find_format(format);
+    if (!drv) {
+        error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
+        return;
+    }
+
+    states->old_bs = bdrv_find(device);
+    if (!states->old_bs) {
+        error_set(errp, QERR_DEVICE_NOT_FOUND, device);
+        return;
+    }
+
+    if (!bdrv_is_inserted(states->old_bs)) {
+        error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
+        return;
+    }
+
+    if (bdrv_in_use(states->old_bs)) {
+        error_set(errp, QERR_DEVICE_IN_USE, device);
+        return;
+    }
+
+    if (!bdrv_is_read_only(states->old_bs)) {
+        if (bdrv_flush(states->old_bs)) {
+            error_set(errp, QERR_IO_ERROR);
+            return;
+        }
+    }
+
+    flags = states->old_bs->open_flags;
+
+    proto_drv = bdrv_find_protocol(new_image_file);
+    if (!proto_drv) {
+        error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
+        return;
+    }
+
+    /* create new image w/backing file */
+    if (mode != NEW_IMAGE_MODE_EXISTING) {
+        bdrv_img_create(new_image_file, format,
+                        states->old_bs->filename,
+                        states->old_bs->drv->format_name,
+                        NULL, -1, flags, &local_err, false);
+        if (error_is_set(&local_err)) {
+            error_propagate(errp, local_err);
+            return;
+        }
+    }
+
+    /* We will manually add the backing_hd field to the bs later */
+    states->new_bs = bdrv_new("");
+    /* TODO Inherit bs->options or only take explicit options with an
+     * extended QMP command? */
+    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);
+    }
+}
+
 /*
  * 'Atomic' group snapshots.  The snapshots are taken as a set, and if any fail
  *  then we do not pivot any of the devices in the group, and abandon the
@@ -792,7 +864,6 @@ typedef struct BlkTransactionStates {
  */
 void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
 {
-    int ret = 0;
     BlockdevActionList *dev_entry = dev_list;
     BlkTransactionStates *states, *next;
     Error *local_err = NULL;
@@ -806,9 +877,6 @@ void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
     /* We don't do anything in this loop that commits us to the snapshot */
     while (NULL != dev_entry) {
         BlockdevAction *dev_info = NULL;
-        BlockDriver *proto_drv;
-        BlockDriver *drv;
-        int flags;
         enum NewImageMode mode;
         const char *new_image_file;
         const char *device;
@@ -831,70 +899,17 @@ void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
                 format = dev_info->blockdev_snapshot_sync->format;
             }
             mode = dev_info->blockdev_snapshot_sync->mode;
-            break;
-        default:
-            abort();
-        }
-
-        drv = bdrv_find_format(format);
-        if (!drv) {
-            error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
-            goto delete_and_fail;
-        }
-
-        states->old_bs = bdrv_find(device);
-        if (!states->old_bs) {
-            error_set(errp, QERR_DEVICE_NOT_FOUND, device);
-            goto delete_and_fail;
-        }
-
-        if (!bdrv_is_inserted(states->old_bs)) {
-            error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
-            goto delete_and_fail;
-        }
-
-        if (bdrv_in_use(states->old_bs)) {
-            error_set(errp, QERR_DEVICE_IN_USE, device);
-            goto delete_and_fail;
-        }
-
-        if (!bdrv_is_read_only(states->old_bs)) {
-            if (bdrv_flush(states->old_bs)) {
-                error_set(errp, QERR_IO_ERROR);
-                goto delete_and_fail;
-            }
-        }
-
-        flags = states->old_bs->open_flags;
-
-        proto_drv = bdrv_find_protocol(new_image_file);
-        if (!proto_drv) {
-            error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
-            goto delete_and_fail;
-        }
-
-        /* create new image w/backing file */
-        if (mode != NEW_IMAGE_MODE_EXISTING) {
-            bdrv_img_create(new_image_file, format,
-                            states->old_bs->filename,
-                            states->old_bs->drv->format_name,
-                            NULL, -1, flags, &local_err, false);
+            external_snapshot_prepare(device, format, new_image_file,
+                                      mode, states, &local_err);
             if (error_is_set(&local_err)) {
                 error_propagate(errp, local_err);
                 goto delete_and_fail;
             }
+            break;
+        default:
+            abort();
         }
 
-        /* We will manually add the backing_hd field to the bs later */
-        states->new_bs = bdrv_new("");
-        /* TODO Inherit bs->options or only take explicit options with an
-         * extended QMP command? */
-        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);
-            goto delete_and_fail;
-        }
     }
 
 
commit 64afc2b4d48fb21e085517c38a59a3f61a11283c
Merge: 95de21a 70e098a
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Thu May 23 14:16:34 2013 -0500

    Merge remote-tracking branch 'luiz/queue/qmp' into staging
    
    # By Michael Roth (10) and others
    # Via Luiz Capitulino
    * luiz/queue/qmp:
      monitor: allow to disable the default monitor
      ui/input.c: replace magic numbers with macros
      qapi: add native list coverage for QMP input visitor tests
      qapi: add native list coverage for QMP output visitor tests
      qapi: add native list coverage for visitor serialization tests
      qapi: fix visitor serialization tests for numbers/doubles
      qapi: add QMP input test for large integers
      json-parser: fix handling of large whole number values
      qapi: enable generation of native list code
      qapi: qapi-visit.py, native list support
      qapi: qapi-visit.py, fix list handling for union types
      qapi: qapi-types.py, native list support
    
    Message-id: 1369333232-24145-1-git-send-email-lcapitulino at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 70e098af88f79340d420992af526254866a42ddd
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Thu May 16 12:02:55 2013 -0400

    monitor: allow to disable the default monitor
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/qemu-options.hx b/qemu-options.hx
index fb3961d..bf94862 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2528,6 +2528,7 @@ Redirect the monitor to host device @var{dev} (same devices as the
 serial port).
 The default device is @code{vc} in graphical mode and @code{stdio} in
 non graphical mode.
+Use @code{-monitor none} to disable the default monitor.
 ETEXI
 DEF("qmp", HAS_ARG, QEMU_OPTION_qmp, \
     "-qmp dev        like -monitor but opens in 'control' mode\n",
diff --git a/vl.c b/vl.c
index 59dc0b4..510d2c2 100644
--- a/vl.c
+++ b/vl.c
@@ -3366,8 +3366,10 @@ int main(int argc, char **argv, char **envp)
                     break;
                 }
             case QEMU_OPTION_monitor:
-                monitor_parse(optarg, "readline");
                 default_monitor = 0;
+                if (strncmp(optarg, "none", 4)) {
+                    monitor_parse(optarg, "readline");
+                }
                 break;
             case QEMU_OPTION_qmp:
                 monitor_parse(optarg, "control");
commit b2d1674b75563326515cf2178cc1d0a002797a12
Author: Amos Kong <akong at redhat.com>
Date:   Thu May 16 13:19:47 2013 +0800

    ui/input.c: replace magic numbers with macros
    
    It's clearer to use defined macros than magic numbers.
    
    Signed-off-by: Amos Kong <akong at redhat.com>
    Reviewed-by: Lei Li <lilei at linux.vnet.ibm.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/ui/input.c b/ui/input.c
index 8ca1a03..92c44ca 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -28,6 +28,7 @@
 #include "qapi/error.h"
 #include "qmp-commands.h"
 #include "qapi-types.h"
+#include "ui/keymaps.h"
 
 struct QEMUPutMouseEntry {
     QEMUPutMouseEvent *qemu_put_mouse_event;
@@ -260,10 +261,10 @@ static void free_keycodes(void)
 static void release_keys(void *opaque)
 {
     while (keycodes_size > 0) {
-        if (keycodes[--keycodes_size] & 0x80) {
-            kbd_put_keycode(0xe0);
+        if (keycodes[--keycodes_size] & SCANCODE_GREY) {
+            kbd_put_keycode(SCANCODE_EMUL0);
         }
-        kbd_put_keycode(keycodes[keycodes_size] | 0x80);
+        kbd_put_keycode(keycodes[keycodes_size] | SCANCODE_UP);
     }
 
     free_keycodes();
@@ -297,10 +298,10 @@ void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time,
             return;
         }
 
-        if (keycode & 0x80) {
-            kbd_put_keycode(0xe0);
+        if (keycode & SCANCODE_GREY) {
+            kbd_put_keycode(SCANCODE_EMUL0);
         }
-        kbd_put_keycode(keycode & 0x7f);
+        kbd_put_keycode(keycode & SCANCODE_KEYCODEMASK);
 
         keycodes = g_realloc(keycodes, sizeof(int) * (keycodes_size + 1));
         keycodes[keycodes_size++] = keycode;
commit 199e0f17f23a68c8d619e9e623d970324ed5efc1
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Fri May 10 17:46:10 2013 -0500

    qapi: add native list coverage for QMP input visitor tests
    
    This exercises schema-generated visitors for native list types and does
    some sanity checking on validity of deserialized data.
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Amos Kong <akong at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index b308cf9..2741eef 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -61,6 +61,31 @@ Visitor *visitor_input_test_init(TestInputVisitorData *data,
     return v;
 }
 
+/* similar to visitor_input_test_init(), but does not expect a string
+ * literal/format json_string argument and so can be used for
+ * programatically generated strings (and we can't pass in programatically
+ * generated strings via %s format parameters since qobject_from_jsonv()
+ * will wrap those in double-quotes and treat the entire object as a
+ * string)
+ */
+static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data,
+                                            const char *json_string)
+{
+    Visitor *v;
+
+    data->obj = qobject_from_json(json_string);
+
+    g_assert(data->obj != NULL);
+
+    data->qiv = qmp_input_visitor_new(data->obj);
+    g_assert(data->qiv != NULL);
+
+    v = qmp_input_get_visitor(data->qiv);
+    g_assert(v != NULL);
+
+    return v;
+}
+
 static void test_visitor_in_int(TestInputVisitorData *data,
                                 const void *unused)
 {
@@ -277,6 +302,287 @@ static void test_visitor_in_union(TestInputVisitorData *data,
     qapi_free_UserDefUnion(tmp);
 }
 
+static void test_native_list_integer_helper(TestInputVisitorData *data,
+                                            const void *unused,
+                                            UserDefNativeListUnionKind kind)
+{
+    UserDefNativeListUnion *cvalue = NULL;
+    Error *err = NULL;
+    Visitor *v;
+    GString *gstr_list = g_string_new("");
+    GString *gstr_union = g_string_new("");
+    int i;
+
+    for (i = 0; i < 32; i++) {
+        g_string_append_printf(gstr_list, "%d", i);
+        if (i != 31) {
+            g_string_append(gstr_list, ", ");
+        }
+    }
+    g_string_append_printf(gstr_union,  "{ 'type': '%s', 'data': [ %s ] }",
+                           UserDefNativeListUnionKind_lookup[kind],
+                           gstr_list->str);
+    v = visitor_input_test_init_raw(data,  gstr_union->str);
+
+    visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
+    g_assert(err == NULL);
+    g_assert(cvalue != NULL);
+    g_assert_cmpint(cvalue->kind, ==, kind);
+
+    switch (kind) {
+    case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
+        intList *elem = NULL;
+        for (i = 0, elem = cvalue->integer; elem; elem = elem->next, i++) {
+            g_assert_cmpint(elem->value, ==, i);
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
+        int8List *elem = NULL;
+        for (i = 0, elem = cvalue->s8; elem; elem = elem->next, i++) {
+            g_assert_cmpint(elem->value, ==, i);
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
+        int16List *elem = NULL;
+        for (i = 0, elem = cvalue->s16; elem; elem = elem->next, i++) {
+            g_assert_cmpint(elem->value, ==, i);
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
+        int32List *elem = NULL;
+        for (i = 0, elem = cvalue->s32; elem; elem = elem->next, i++) {
+            g_assert_cmpint(elem->value, ==, i);
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
+        int64List *elem = NULL;
+        for (i = 0, elem = cvalue->s64; elem; elem = elem->next, i++) {
+            g_assert_cmpint(elem->value, ==, i);
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
+        uint8List *elem = NULL;
+        for (i = 0, elem = cvalue->u8; elem; elem = elem->next, i++) {
+            g_assert_cmpint(elem->value, ==, i);
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
+        uint16List *elem = NULL;
+        for (i = 0, elem = cvalue->u16; elem; elem = elem->next, i++) {
+            g_assert_cmpint(elem->value, ==, i);
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
+        uint32List *elem = NULL;
+        for (i = 0, elem = cvalue->u32; elem; elem = elem->next, i++) {
+            g_assert_cmpint(elem->value, ==, i);
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
+        uint64List *elem = NULL;
+        for (i = 0, elem = cvalue->u64; elem; elem = elem->next, i++) {
+            g_assert_cmpint(elem->value, ==, i);
+        }
+        break;
+    }
+    default:
+        g_assert(false);
+    }
+
+    g_string_free(gstr_union, true);
+    g_string_free(gstr_list, true);
+    qapi_free_UserDefNativeListUnion(cvalue);
+}
+
+static void test_visitor_in_native_list_int(TestInputVisitorData *data,
+                                            const void *unused)
+{
+    test_native_list_integer_helper(data, unused,
+                                    USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER);
+}
+
+static void test_visitor_in_native_list_int8(TestInputVisitorData *data,
+                                             const void *unused)
+{
+    test_native_list_integer_helper(data, unused,
+                                    USER_DEF_NATIVE_LIST_UNION_KIND_S8);
+}
+
+static void test_visitor_in_native_list_int16(TestInputVisitorData *data,
+                                              const void *unused)
+{
+    test_native_list_integer_helper(data, unused,
+                                    USER_DEF_NATIVE_LIST_UNION_KIND_S16);
+}
+
+static void test_visitor_in_native_list_int32(TestInputVisitorData *data,
+                                              const void *unused)
+{
+    test_native_list_integer_helper(data, unused,
+                                    USER_DEF_NATIVE_LIST_UNION_KIND_S32);
+}
+
+static void test_visitor_in_native_list_int64(TestInputVisitorData *data,
+                                              const void *unused)
+{
+    test_native_list_integer_helper(data, unused,
+                                    USER_DEF_NATIVE_LIST_UNION_KIND_S64);
+}
+
+static void test_visitor_in_native_list_uint8(TestInputVisitorData *data,
+                                             const void *unused)
+{
+    test_native_list_integer_helper(data, unused,
+                                    USER_DEF_NATIVE_LIST_UNION_KIND_U8);
+}
+
+static void test_visitor_in_native_list_uint16(TestInputVisitorData *data,
+                                               const void *unused)
+{
+    test_native_list_integer_helper(data, unused,
+                                    USER_DEF_NATIVE_LIST_UNION_KIND_U16);
+}
+
+static void test_visitor_in_native_list_uint32(TestInputVisitorData *data,
+                                               const void *unused)
+{
+    test_native_list_integer_helper(data, unused,
+                                    USER_DEF_NATIVE_LIST_UNION_KIND_U32);
+}
+
+static void test_visitor_in_native_list_uint64(TestInputVisitorData *data,
+                                               const void *unused)
+{
+    test_native_list_integer_helper(data, unused,
+                                    USER_DEF_NATIVE_LIST_UNION_KIND_U64);
+}
+
+static void test_visitor_in_native_list_bool(TestInputVisitorData *data,
+                                            const void *unused)
+{
+    UserDefNativeListUnion *cvalue = NULL;
+    boolList *elem = NULL;
+    Error *err = NULL;
+    Visitor *v;
+    GString *gstr_list = g_string_new("");
+    GString *gstr_union = g_string_new("");
+    int i;
+
+    for (i = 0; i < 32; i++) {
+        g_string_append_printf(gstr_list, "%s",
+                               (i % 3 == 0) ? "true" : "false");
+        if (i != 31) {
+            g_string_append(gstr_list, ", ");
+        }
+    }
+    g_string_append_printf(gstr_union,  "{ 'type': 'boolean', 'data': [ %s ] }",
+                           gstr_list->str);
+    v = visitor_input_test_init_raw(data,  gstr_union->str);
+
+    visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
+    g_assert(err == NULL);
+    g_assert(cvalue != NULL);
+    g_assert_cmpint(cvalue->kind, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
+
+    for (i = 0, elem = cvalue->boolean; elem; elem = elem->next, i++) {
+        g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0);
+    }
+
+    g_string_free(gstr_union, true);
+    g_string_free(gstr_list, true);
+    qapi_free_UserDefNativeListUnion(cvalue);
+}
+
+static void test_visitor_in_native_list_string(TestInputVisitorData *data,
+                                               const void *unused)
+{
+    UserDefNativeListUnion *cvalue = NULL;
+    strList *elem = NULL;
+    Error *err = NULL;
+    Visitor *v;
+    GString *gstr_list = g_string_new("");
+    GString *gstr_union = g_string_new("");
+    int i;
+
+    for (i = 0; i < 32; i++) {
+        g_string_append_printf(gstr_list, "'%d'", i);
+        if (i != 31) {
+            g_string_append(gstr_list, ", ");
+        }
+    }
+    g_string_append_printf(gstr_union,  "{ 'type': 'string', 'data': [ %s ] }",
+                           gstr_list->str);
+    v = visitor_input_test_init_raw(data,  gstr_union->str);
+
+    visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
+    g_assert(err == NULL);
+    g_assert(cvalue != NULL);
+    g_assert_cmpint(cvalue->kind, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
+
+    for (i = 0, elem = cvalue->string; elem; elem = elem->next, i++) {
+        gchar str[8];
+        sprintf(str, "%d", i);
+        g_assert_cmpstr(elem->value, ==, str);
+    }
+
+    g_string_free(gstr_union, true);
+    g_string_free(gstr_list, true);
+    qapi_free_UserDefNativeListUnion(cvalue);
+}
+
+#define DOUBLE_STR_MAX 16
+
+static void test_visitor_in_native_list_number(TestInputVisitorData *data,
+                                               const void *unused)
+{
+    UserDefNativeListUnion *cvalue = NULL;
+    numberList *elem = NULL;
+    Error *err = NULL;
+    Visitor *v;
+    GString *gstr_list = g_string_new("");
+    GString *gstr_union = g_string_new("");
+    int i;
+
+    for (i = 0; i < 32; i++) {
+        g_string_append_printf(gstr_list, "%f", (double)i / 3);
+        if (i != 31) {
+            g_string_append(gstr_list, ", ");
+        }
+    }
+    g_string_append_printf(gstr_union,  "{ 'type': 'number', 'data': [ %s ] }",
+                           gstr_list->str);
+    v = visitor_input_test_init_raw(data,  gstr_union->str);
+
+    visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
+    g_assert(err == NULL);
+    g_assert(cvalue != NULL);
+    g_assert_cmpint(cvalue->kind, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
+
+    for (i = 0, elem = cvalue->number; elem; elem = elem->next, i++) {
+        GString *double_expected = g_string_new("");
+        GString *double_actual = g_string_new("");
+
+        g_string_printf(double_expected, "%.6f", (double)i / 3);
+        g_string_printf(double_actual, "%.6f", elem->value);
+        g_assert_cmpstr(double_expected->str, ==, double_actual->str);
+
+        g_string_free(double_expected, true);
+        g_string_free(double_actual, true);
+    }
+
+    g_string_free(gstr_union, true);
+    g_string_free(gstr_list, true);
+    qapi_free_UserDefNativeListUnion(cvalue);
+}
+
 static void input_visitor_test_add(const char *testpath,
                                    TestInputVisitorData *data,
                                    void (*test_func)(TestInputVisitorData *data, const void *user_data))
@@ -330,6 +636,38 @@ int main(int argc, char **argv)
                             &in_visitor_data, test_visitor_in_union);
     input_visitor_test_add("/visitor/input/errors",
                             &in_visitor_data, test_visitor_in_errors);
+    input_visitor_test_add("/visitor/input/native_list/int",
+                            &in_visitor_data,
+                            test_visitor_in_native_list_int);
+    input_visitor_test_add("/visitor/input/native_list/int8",
+                            &in_visitor_data,
+                            test_visitor_in_native_list_int8);
+    input_visitor_test_add("/visitor/input/native_list/int16",
+                            &in_visitor_data,
+                            test_visitor_in_native_list_int16);
+    input_visitor_test_add("/visitor/input/native_list/int32",
+                            &in_visitor_data,
+                            test_visitor_in_native_list_int32);
+    input_visitor_test_add("/visitor/input/native_list/int64",
+                            &in_visitor_data,
+                            test_visitor_in_native_list_int64);
+    input_visitor_test_add("/visitor/input/native_list/uint8",
+                            &in_visitor_data,
+                            test_visitor_in_native_list_uint8);
+    input_visitor_test_add("/visitor/input/native_list/uint16",
+                            &in_visitor_data,
+                            test_visitor_in_native_list_uint16);
+    input_visitor_test_add("/visitor/input/native_list/uint32",
+                            &in_visitor_data,
+                            test_visitor_in_native_list_uint32);
+    input_visitor_test_add("/visitor/input/native_list/uint64",
+                            &in_visitor_data, test_visitor_in_native_list_uint64);
+    input_visitor_test_add("/visitor/input/native_list/bool",
+                            &in_visitor_data, test_visitor_in_native_list_bool);
+    input_visitor_test_add("/visitor/input/native_list/str",
+                            &in_visitor_data, test_visitor_in_native_list_string);
+    input_visitor_test_add("/visitor/input/native_list/number",
+                            &in_visitor_data, test_visitor_in_native_list_number);
 
     g_test_run();
 
commit 83c84667f57637fe5a7a6fc9905d6a9e9589d3e5
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Fri May 10 17:46:09 2013 -0500

    qapi: add native list coverage for QMP output visitor tests
    
    This exercises schema-generated visitors for native list types and does
    some sanity checking on validity of serialized data.
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Amos Kong <akong at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/qapi-schema-test.json b/qapi-schema-test.json
index 9eae350..4434fa3 100644
--- a/qapi-schema-test.json
+++ b/qapi-schema-test.json
@@ -32,6 +32,21 @@
 { 'union': 'UserDefUnion',
   'data': { 'a' : 'UserDefA', 'b' : 'UserDefB' } }
 
+# for testing native lists
+{ 'union': 'UserDefNativeListUnion',
+  'data': { 'integer': ['int'],
+            's8': ['int8'],
+            's16': ['int16'],
+            's32': ['int32'],
+            's64': ['int64'],
+            'u8': ['uint8'],
+            'u16': ['uint16'],
+            'u32': ['uint32'],
+            'u64': ['uint64'],
+            'number': ['number'],
+            'boolean': ['bool'],
+            'string': ['str'] } }
+
 # testing commands
 { 'command': 'user_def_cmd', 'data': {} }
 { 'command': 'user_def_cmd1', 'data': {'ud1a': 'UserDefOne'} }
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index 71367e6..0942a41 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -431,6 +431,314 @@ static void test_visitor_out_union(TestOutputVisitorData *data,
     QDECREF(qdict);
 }
 
+static void init_native_list(UserDefNativeListUnion *cvalue)
+{
+    int i;
+    switch (cvalue->kind) {
+    case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
+        intList **list = &cvalue->integer;
+        for (i = 0; i < 32; i++) {
+            *list = g_new0(intList, 1);
+            (*list)->value = i;
+            (*list)->next = NULL;
+            list = &(*list)->next;
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
+        int8List **list = &cvalue->s8;
+        for (i = 0; i < 32; i++) {
+            *list = g_new0(int8List, 1);
+            (*list)->value = i;
+            (*list)->next = NULL;
+            list = &(*list)->next;
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
+        int16List **list = &cvalue->s16;
+        for (i = 0; i < 32; i++) {
+            *list = g_new0(int16List, 1);
+            (*list)->value = i;
+            (*list)->next = NULL;
+            list = &(*list)->next;
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
+        int32List **list = &cvalue->s32;
+        for (i = 0; i < 32; i++) {
+            *list = g_new0(int32List, 1);
+            (*list)->value = i;
+            (*list)->next = NULL;
+            list = &(*list)->next;
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
+        int64List **list = &cvalue->s64;
+        for (i = 0; i < 32; i++) {
+            *list = g_new0(int64List, 1);
+            (*list)->value = i;
+            (*list)->next = NULL;
+            list = &(*list)->next;
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
+        uint8List **list = &cvalue->u8;
+        for (i = 0; i < 32; i++) {
+            *list = g_new0(uint8List, 1);
+            (*list)->value = i;
+            (*list)->next = NULL;
+            list = &(*list)->next;
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
+        uint16List **list = &cvalue->u16;
+        for (i = 0; i < 32; i++) {
+            *list = g_new0(uint16List, 1);
+            (*list)->value = i;
+            (*list)->next = NULL;
+            list = &(*list)->next;
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
+        uint32List **list = &cvalue->u32;
+        for (i = 0; i < 32; i++) {
+            *list = g_new0(uint32List, 1);
+            (*list)->value = i;
+            (*list)->next = NULL;
+            list = &(*list)->next;
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
+        uint64List **list = &cvalue->u64;
+        for (i = 0; i < 32; i++) {
+            *list = g_new0(uint64List, 1);
+            (*list)->value = i;
+            (*list)->next = NULL;
+            list = &(*list)->next;
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN: {
+        boolList **list = &cvalue->boolean;
+        for (i = 0; i < 32; i++) {
+            *list = g_new0(boolList, 1);
+            (*list)->value = (i % 3 == 0);
+            (*list)->next = NULL;
+            list = &(*list)->next;
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_STRING: {
+        strList **list = &cvalue->string;
+        for (i = 0; i < 32; i++) {
+            *list = g_new0(strList, 1);
+            (*list)->value = g_strdup_printf("%d", i);
+            (*list)->next = NULL;
+            list = &(*list)->next;
+        }
+        break;
+    }
+    case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER: {
+        numberList **list = &cvalue->number;
+        for (i = 0; i < 32; i++) {
+            *list = g_new0(numberList, 1);
+            (*list)->value = (double)i / 3;
+            (*list)->next = NULL;
+            list = &(*list)->next;
+        }
+        break;
+    }
+    default:
+        g_assert(false);
+    }
+}
+
+static void check_native_list(QObject *qobj,
+                              UserDefNativeListUnionKind kind)
+{
+    QDict *qdict;
+    QList *qlist;
+    int i;
+
+    g_assert(qobj);
+    g_assert(qobject_type(qobj) == QTYPE_QDICT);
+    qdict = qobject_to_qdict(qobj);
+    g_assert(qdict);
+    g_assert(qdict_haskey(qdict, "data"));
+    qlist = qlist_copy(qobject_to_qlist(qdict_get(qdict, "data")));
+
+    switch (kind) {
+    case USER_DEF_NATIVE_LIST_UNION_KIND_S8:
+    case USER_DEF_NATIVE_LIST_UNION_KIND_S16:
+    case USER_DEF_NATIVE_LIST_UNION_KIND_S32:
+    case USER_DEF_NATIVE_LIST_UNION_KIND_S64:
+    case USER_DEF_NATIVE_LIST_UNION_KIND_U8:
+    case USER_DEF_NATIVE_LIST_UNION_KIND_U16:
+    case USER_DEF_NATIVE_LIST_UNION_KIND_U32:
+    case USER_DEF_NATIVE_LIST_UNION_KIND_U64:
+        /* all integer elements in JSON arrays get stored into QInts when
+         * we convert to QObjects, so we can check them all in the same
+         * fashion, so simply fall through here
+         */
+    case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER:
+        for (i = 0; i < 32; i++) {
+            QObject *tmp;
+            QInt *qvalue;
+            tmp = qlist_peek(qlist);
+            g_assert(tmp);
+            qvalue = qobject_to_qint(tmp);
+            g_assert_cmpint(qint_get_int(qvalue), ==, i);
+            qobject_decref(qlist_pop(qlist));
+        }
+        break;
+    case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN:
+        for (i = 0; i < 32; i++) {
+            QObject *tmp;
+            QBool *qvalue;
+            tmp = qlist_peek(qlist);
+            g_assert(tmp);
+            qvalue = qobject_to_qbool(tmp);
+            g_assert_cmpint(qbool_get_int(qvalue), ==, (i % 3 == 0) ? 1 : 0);
+            qobject_decref(qlist_pop(qlist));
+        }
+        break;
+    case USER_DEF_NATIVE_LIST_UNION_KIND_STRING:
+        for (i = 0; i < 32; i++) {
+            QObject *tmp;
+            QString *qvalue;
+            gchar str[8];
+            tmp = qlist_peek(qlist);
+            g_assert(tmp);
+            qvalue = qobject_to_qstring(tmp);
+            sprintf(str, "%d", i);
+            g_assert_cmpstr(qstring_get_str(qvalue), ==, str);
+            qobject_decref(qlist_pop(qlist));
+        }
+        break;
+    case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER:
+        for (i = 0; i < 32; i++) {
+            QObject *tmp;
+            QFloat *qvalue;
+            GString *double_expected = g_string_new("");
+            GString *double_actual = g_string_new("");
+
+            tmp = qlist_peek(qlist);
+            g_assert(tmp);
+            qvalue = qobject_to_qfloat(tmp);
+            g_string_printf(double_expected, "%.6f", (double)i / 3);
+            g_string_printf(double_actual, "%.6f", qfloat_get_double(qvalue));
+            g_assert_cmpstr(double_actual->str, ==, double_expected->str);
+
+            qobject_decref(qlist_pop(qlist));
+            g_string_free(double_expected, true);
+            g_string_free(double_actual, true);
+        }
+        break;
+    default:
+        g_assert(false);
+    }
+    QDECREF(qlist);
+}
+
+static void test_native_list(TestOutputVisitorData *data,
+                             const void *unused,
+                             UserDefNativeListUnionKind kind)
+{
+    UserDefNativeListUnion *cvalue = g_new0(UserDefNativeListUnion, 1);
+    Error *err = NULL;
+    QObject *obj;
+
+    cvalue->kind = kind;
+    init_native_list(cvalue);
+
+    visit_type_UserDefNativeListUnion(data->ov, &cvalue, NULL, &err);
+    g_assert(err == NULL);
+
+    obj = qmp_output_get_qobject(data->qov);
+    check_native_list(obj, cvalue->kind);
+    qapi_free_UserDefNativeListUnion(cvalue);
+    qobject_decref(obj);
+}
+
+static void test_visitor_out_native_list_int(TestOutputVisitorData *data,
+                                             const void *unused)
+{
+    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER);
+}
+
+static void test_visitor_out_native_list_int8(TestOutputVisitorData *data,
+                                              const void *unused)
+{
+    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S8);
+}
+
+static void test_visitor_out_native_list_int16(TestOutputVisitorData *data,
+                                               const void *unused)
+{
+    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S16);
+}
+
+static void test_visitor_out_native_list_int32(TestOutputVisitorData *data,
+                                               const void *unused)
+{
+    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S32);
+}
+
+static void test_visitor_out_native_list_int64(TestOutputVisitorData *data,
+                                               const void *unused)
+{
+    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S64);
+}
+
+static void test_visitor_out_native_list_uint8(TestOutputVisitorData *data,
+                                               const void *unused)
+{
+    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U8);
+}
+
+static void test_visitor_out_native_list_uint16(TestOutputVisitorData *data,
+                                                const void *unused)
+{
+    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U16);
+}
+
+static void test_visitor_out_native_list_uint32(TestOutputVisitorData *data,
+                                                const void *unused)
+{
+    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U32);
+}
+
+static void test_visitor_out_native_list_uint64(TestOutputVisitorData *data,
+                                                const void *unused)
+{
+    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U64);
+}
+
+static void test_visitor_out_native_list_bool(TestOutputVisitorData *data,
+                                              const void *unused)
+{
+    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
+}
+
+static void test_visitor_out_native_list_str(TestOutputVisitorData *data,
+                                              const void *unused)
+{
+    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
+}
+
+static void test_visitor_out_native_list_number(TestOutputVisitorData *data,
+                                                const void *unused)
+{
+    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
+}
+
 static void output_visitor_test_add(const char *testpath,
                                     TestOutputVisitorData *data,
                                     void (*test_func)(TestOutputVisitorData *data, const void *user_data))
@@ -471,6 +779,30 @@ int main(int argc, char **argv)
                             &out_visitor_data, test_visitor_out_list_qapi_free);
     output_visitor_test_add("/visitor/output/union",
                             &out_visitor_data, test_visitor_out_union);
+    output_visitor_test_add("/visitor/output/native_list/int",
+                            &out_visitor_data, test_visitor_out_native_list_int);
+    output_visitor_test_add("/visitor/output/native_list/int8",
+                            &out_visitor_data, test_visitor_out_native_list_int8);
+    output_visitor_test_add("/visitor/output/native_list/int16",
+                            &out_visitor_data, test_visitor_out_native_list_int16);
+    output_visitor_test_add("/visitor/output/native_list/int32",
+                            &out_visitor_data, test_visitor_out_native_list_int32);
+    output_visitor_test_add("/visitor/output/native_list/int64",
+                            &out_visitor_data, test_visitor_out_native_list_int64);
+    output_visitor_test_add("/visitor/output/native_list/uint8",
+                            &out_visitor_data, test_visitor_out_native_list_uint8);
+    output_visitor_test_add("/visitor/output/native_list/uint16",
+                            &out_visitor_data, test_visitor_out_native_list_uint16);
+    output_visitor_test_add("/visitor/output/native_list/uint32",
+                            &out_visitor_data, test_visitor_out_native_list_uint32);
+    output_visitor_test_add("/visitor/output/native_list/uint64",
+                            &out_visitor_data, test_visitor_out_native_list_uint64);
+    output_visitor_test_add("/visitor/output/native_list/bool",
+                            &out_visitor_data, test_visitor_out_native_list_bool);
+    output_visitor_test_add("/visitor/output/native_list/string",
+                            &out_visitor_data, test_visitor_out_native_list_str);
+    output_visitor_test_add("/visitor/output/native_list/number",
+                            &out_visitor_data, test_visitor_out_native_list_number);
 
     g_test_run();
 
commit 8addacddfece619f1795fcf6cb9a3c49f800e7b9
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Fri May 10 17:46:08 2013 -0500

    qapi: add native list coverage for visitor serialization tests
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Amos Kong <akong at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c
index fed6810..ee7916b 100644
--- a/tests/test-visitor-serialization.c
+++ b/tests/test-visitor-serialization.c
@@ -23,6 +23,25 @@
 #include "qapi/qmp-output-visitor.h"
 #include "qapi/string-input-visitor.h"
 #include "qapi/string-output-visitor.h"
+#include "qapi-types.h"
+#include "qapi-visit.h"
+#include "qapi/dealloc-visitor.h"
+
+enum PrimitiveTypeKind {
+    PTYPE_STRING = 0,
+    PTYPE_BOOLEAN,
+    PTYPE_NUMBER,
+    PTYPE_INTEGER,
+    PTYPE_U8,
+    PTYPE_U16,
+    PTYPE_U32,
+    PTYPE_U64,
+    PTYPE_S8,
+    PTYPE_S16,
+    PTYPE_S32,
+    PTYPE_S64,
+    PTYPE_EOL,
+};
 
 typedef struct PrimitiveType {
     union {
@@ -40,26 +59,42 @@ typedef struct PrimitiveType {
         int64_t s64;
         intmax_t max;
     } value;
-    enum {
-        PTYPE_STRING = 0,
-        PTYPE_BOOLEAN,
-        PTYPE_NUMBER,
-        PTYPE_INTEGER,
-        PTYPE_U8,
-        PTYPE_U16,
-        PTYPE_U32,
-        PTYPE_U64,
-        PTYPE_S8,
-        PTYPE_S16,
-        PTYPE_S32,
-        PTYPE_S64,
-        PTYPE_EOL,
-    } type;
+    enum PrimitiveTypeKind type;
     const char *description;
 } PrimitiveType;
 
+typedef struct PrimitiveList {
+    union {
+        strList *strings;
+        boolList *booleans;
+        numberList *numbers;
+        intList *integers;
+        int8List *s8_integers;
+        int16List *s16_integers;
+        int32List *s32_integers;
+        int64List *s64_integers;
+        uint8List *u8_integers;
+        uint16List *u16_integers;
+        uint32List *u32_integers;
+        uint64List *u64_integers;
+    } value;
+    enum PrimitiveTypeKind type;
+    const char *description;
+} PrimitiveList;
+
 /* test helpers */
 
+typedef void (*VisitorFunc)(Visitor *v, void **native, Error **errp);
+
+static void dealloc_helper(void *native_in, VisitorFunc visit, Error **errp)
+{
+    QapiDeallocVisitor *qdv = qapi_dealloc_visitor_new();
+
+    visit(qapi_dealloc_get_visitor(qdv), &native_in, errp);
+
+    qapi_dealloc_visitor_cleanup(qdv);
+}
+
 static void visit_primitive_type(Visitor *v, void **native, Error **errp)
 {
     PrimitiveType *pt = *native;
@@ -105,6 +140,51 @@ static void visit_primitive_type(Visitor *v, void **native, Error **errp)
     }
 }
 
+static void visit_primitive_list(Visitor *v, void **native, Error **errp)
+{
+    PrimitiveList *pl = *native;
+    switch (pl->type) {
+    case PTYPE_STRING:
+        visit_type_strList(v, &pl->value.strings, NULL, errp);
+        break;
+    case PTYPE_BOOLEAN:
+        visit_type_boolList(v, &pl->value.booleans, NULL, errp);
+        break;
+    case PTYPE_NUMBER:
+        visit_type_numberList(v, &pl->value.numbers, NULL, errp);
+        break;
+    case PTYPE_INTEGER:
+        visit_type_intList(v, &pl->value.integers, NULL, errp);
+        break;
+    case PTYPE_S8:
+        visit_type_int8List(v, &pl->value.s8_integers, NULL, errp);
+        break;
+    case PTYPE_S16:
+        visit_type_int16List(v, &pl->value.s16_integers, NULL, errp);
+        break;
+    case PTYPE_S32:
+        visit_type_int32List(v, &pl->value.s32_integers, NULL, errp);
+        break;
+    case PTYPE_S64:
+        visit_type_int64List(v, &pl->value.s64_integers, NULL, errp);
+        break;
+    case PTYPE_U8:
+        visit_type_uint8List(v, &pl->value.u8_integers, NULL, errp);
+        break;
+    case PTYPE_U16:
+        visit_type_uint16List(v, &pl->value.u16_integers, NULL, errp);
+        break;
+    case PTYPE_U32:
+        visit_type_uint32List(v, &pl->value.u32_integers, NULL, errp);
+        break;
+    case PTYPE_U64:
+        visit_type_uint64List(v, &pl->value.u64_integers, NULL, errp);
+        break;
+    default:
+        g_assert(false);
+    }
+}
+
 typedef struct TestStruct
 {
     int64_t integer;
@@ -206,12 +286,11 @@ static void visit_nested_struct_list(Visitor *v, void **native, Error **errp)
 
 /* test cases */
 
-typedef void (*VisitorFunc)(Visitor *v, void **native, Error **errp);
-
 typedef enum VisitorCapabilities {
     VCAP_PRIMITIVES = 1,
     VCAP_STRUCTURES = 2,
     VCAP_LISTS = 4,
+    VCAP_PRIMITIVE_LISTS = 8,
 } VisitorCapabilities;
 
 typedef struct SerializeOps {
@@ -270,6 +349,328 @@ static void test_primitives(gconstpointer opaque)
     g_free(pt_copy);
 }
 
+static void test_primitive_lists(gconstpointer opaque)
+{
+    TestArgs *args = (TestArgs *) opaque;
+    const SerializeOps *ops = args->ops;
+    PrimitiveType *pt = args->test_data;
+    PrimitiveList pl = { .value = { 0 } };
+    PrimitiveList pl_copy = { .value = { 0 } };
+    PrimitiveList *pl_copy_ptr = &pl_copy;
+    Error *err = NULL;
+    void *serialize_data;
+    void *cur_head = NULL;
+    int i;
+
+    pl.type = pl_copy.type = pt->type;
+
+    /* build up our list of primitive types */
+    for (i = 0; i < 32; i++) {
+        switch (pl.type) {
+        case PTYPE_STRING: {
+            strList *tmp = g_new0(strList, 1);
+            tmp->value = g_strdup(pt->value.string);
+            if (pl.value.strings == NULL) {
+                pl.value.strings = tmp;
+            } else {
+                tmp->next = pl.value.strings;
+                pl.value.strings = tmp;
+            }
+            break;
+        }
+        case PTYPE_INTEGER: {
+            intList *tmp = g_new0(intList, 1);
+            tmp->value = pt->value.integer;
+            if (pl.value.integers == NULL) {
+                pl.value.integers = tmp;
+            } else {
+                tmp->next = pl.value.integers;
+                pl.value.integers = tmp;
+            }
+            break;
+        }
+        case PTYPE_S8: {
+            int8List *tmp = g_new0(int8List, 1);
+            tmp->value = pt->value.s8;
+            if (pl.value.s8_integers == NULL) {
+                pl.value.s8_integers = tmp;
+            } else {
+                tmp->next = pl.value.s8_integers;
+                pl.value.s8_integers = tmp;
+            }
+            break;
+        }
+        case PTYPE_S16: {
+            int16List *tmp = g_new0(int16List, 1);
+            tmp->value = pt->value.s16;
+            if (pl.value.s16_integers == NULL) {
+                pl.value.s16_integers = tmp;
+            } else {
+                tmp->next = pl.value.s16_integers;
+                pl.value.s16_integers = tmp;
+            }
+            break;
+        }
+        case PTYPE_S32: {
+            int32List *tmp = g_new0(int32List, 1);
+            tmp->value = pt->value.s32;
+            if (pl.value.s32_integers == NULL) {
+                pl.value.s32_integers = tmp;
+            } else {
+                tmp->next = pl.value.s32_integers;
+                pl.value.s32_integers = tmp;
+            }
+            break;
+        }
+        case PTYPE_S64: {
+            int64List *tmp = g_new0(int64List, 1);
+            tmp->value = pt->value.s64;
+            if (pl.value.s64_integers == NULL) {
+                pl.value.s64_integers = tmp;
+            } else {
+                tmp->next = pl.value.s64_integers;
+                pl.value.s64_integers = tmp;
+            }
+            break;
+        }
+        case PTYPE_U8: {
+            uint8List *tmp = g_new0(uint8List, 1);
+            tmp->value = pt->value.u8;
+            if (pl.value.u8_integers == NULL) {
+                pl.value.u8_integers = tmp;
+            } else {
+                tmp->next = pl.value.u8_integers;
+                pl.value.u8_integers = tmp;
+            }
+            break;
+        }
+        case PTYPE_U16: {
+            uint16List *tmp = g_new0(uint16List, 1);
+            tmp->value = pt->value.u16;
+            if (pl.value.u16_integers == NULL) {
+                pl.value.u16_integers = tmp;
+            } else {
+                tmp->next = pl.value.u16_integers;
+                pl.value.u16_integers = tmp;
+            }
+            break;
+        }
+        case PTYPE_U32: {
+            uint32List *tmp = g_new0(uint32List, 1);
+            tmp->value = pt->value.u32;
+            if (pl.value.u32_integers == NULL) {
+                pl.value.u32_integers = tmp;
+            } else {
+                tmp->next = pl.value.u32_integers;
+                pl.value.u32_integers = tmp;
+            }
+            break;
+        }
+        case PTYPE_U64: {
+            uint64List *tmp = g_new0(uint64List, 1);
+            tmp->value = pt->value.u64;
+            if (pl.value.u64_integers == NULL) {
+                pl.value.u64_integers = tmp;
+            } else {
+                tmp->next = pl.value.u64_integers;
+                pl.value.u64_integers = tmp;
+            }
+            break;
+        }
+        case PTYPE_NUMBER: {
+            numberList *tmp = g_new0(numberList, 1);
+            tmp->value = pt->value.number;
+            if (pl.value.numbers == NULL) {
+                pl.value.numbers = tmp;
+            } else {
+                tmp->next = pl.value.numbers;
+                pl.value.numbers = tmp;
+            }
+            break;
+        }
+        case PTYPE_BOOLEAN: {
+            boolList *tmp = g_new0(boolList, 1);
+            tmp->value = pt->value.boolean;
+            if (pl.value.booleans == NULL) {
+                pl.value.booleans = tmp;
+            } else {
+                tmp->next = pl.value.booleans;
+                pl.value.booleans = tmp;
+            }
+            break;
+        }
+        default:
+            g_assert(0);
+        }
+    }
+
+    ops->serialize((void **)&pl, &serialize_data, visit_primitive_list, &err);
+    ops->deserialize((void **)&pl_copy_ptr, serialize_data, visit_primitive_list, &err);
+
+    g_assert(err == NULL);
+    i = 0;
+
+    /* compare our deserialized list of primitives to the original */
+    do {
+        switch (pl_copy.type) {
+        case PTYPE_STRING: {
+            strList *ptr;
+            if (cur_head) {
+                ptr = cur_head;
+                cur_head = ptr->next;
+            } else {
+                cur_head = ptr = pl_copy.value.strings;
+            }
+            g_assert_cmpstr(pt->value.string, ==, ptr->value);
+            break;
+        }
+        case PTYPE_INTEGER: {
+            intList *ptr;
+            if (cur_head) {
+                ptr = cur_head;
+                cur_head = ptr->next;
+            } else {
+                cur_head = ptr = pl_copy.value.integers;
+            }
+            g_assert_cmpint(pt->value.integer, ==, ptr->value);
+            break;
+        }
+        case PTYPE_S8: {
+            int8List *ptr;
+            if (cur_head) {
+                ptr = cur_head;
+                cur_head = ptr->next;
+            } else {
+                cur_head = ptr = pl_copy.value.s8_integers;
+            }
+            g_assert_cmpint(pt->value.s8, ==, ptr->value);
+            break;
+        }
+        case PTYPE_S16: {
+            int16List *ptr;
+            if (cur_head) {
+                ptr = cur_head;
+                cur_head = ptr->next;
+            } else {
+                cur_head = ptr = pl_copy.value.s16_integers;
+            }
+            g_assert_cmpint(pt->value.s16, ==, ptr->value);
+            break;
+        }
+        case PTYPE_S32: {
+            int32List *ptr;
+            if (cur_head) {
+                ptr = cur_head;
+                cur_head = ptr->next;
+            } else {
+                cur_head = ptr = pl_copy.value.s32_integers;
+            }
+            g_assert_cmpint(pt->value.s32, ==, ptr->value);
+            break;
+        }
+        case PTYPE_S64: {
+            int64List *ptr;
+            if (cur_head) {
+                ptr = cur_head;
+                cur_head = ptr->next;
+            } else {
+                cur_head = ptr = pl_copy.value.s64_integers;
+            }
+            g_assert_cmpint(pt->value.s64, ==, ptr->value);
+            break;
+        }
+        case PTYPE_U8: {
+            uint8List *ptr;
+            if (cur_head) {
+                ptr = cur_head;
+                cur_head = ptr->next;
+            } else {
+                cur_head = ptr = pl_copy.value.u8_integers;
+            }
+            g_assert_cmpint(pt->value.u8, ==, ptr->value);
+            break;
+        }
+        case PTYPE_U16: {
+            uint16List *ptr;
+            if (cur_head) {
+                ptr = cur_head;
+                cur_head = ptr->next;
+            } else {
+                cur_head = ptr = pl_copy.value.u16_integers;
+            }
+            g_assert_cmpint(pt->value.u16, ==, ptr->value);
+            break;
+        }
+        case PTYPE_U32: {
+            uint32List *ptr;
+            if (cur_head) {
+                ptr = cur_head;
+                cur_head = ptr->next;
+            } else {
+                cur_head = ptr = pl_copy.value.u32_integers;
+            }
+            g_assert_cmpint(pt->value.u32, ==, ptr->value);
+            break;
+        }
+        case PTYPE_U64: {
+            uint64List *ptr;
+            if (cur_head) {
+                ptr = cur_head;
+                cur_head = ptr->next;
+            } else {
+                cur_head = ptr = pl_copy.value.u64_integers;
+            }
+            g_assert_cmpint(pt->value.u64, ==, ptr->value);
+            break;
+        }
+        case PTYPE_NUMBER: {
+            numberList *ptr;
+            GString *double_expected = g_string_new("");
+            GString *double_actual = g_string_new("");
+            if (cur_head) {
+                ptr = cur_head;
+                cur_head = ptr->next;
+            } else {
+                cur_head = ptr = pl_copy.value.numbers;
+            }
+            /* we serialize with %f for our reference visitors, so rather than
+             * fuzzy floating math to test "equality", just compare the
+             * formatted values
+             */
+            g_string_printf(double_expected, "%.6f", pt->value.number);
+            g_string_printf(double_actual, "%.6f", ptr->value);
+            g_assert_cmpstr(double_actual->str, ==, double_expected->str);
+            g_string_free(double_expected, true);
+            g_string_free(double_actual, true);
+            break;
+        }
+        case PTYPE_BOOLEAN: {
+            boolList *ptr;
+            if (cur_head) {
+                ptr = cur_head;
+                cur_head = ptr->next;
+            } else {
+                cur_head = ptr = pl_copy.value.booleans;
+            }
+            g_assert_cmpint(!!pt->value.boolean, ==, !!ptr->value);
+            break;
+        }
+        default:
+            g_assert(0);
+        }
+        i++;
+    } while (cur_head);
+
+    g_assert_cmpint(i, ==, 33);
+
+    ops->cleanup(serialize_data);
+    dealloc_helper(&pl, visit_primitive_list, &err);
+    g_assert(!err);
+    dealloc_helper(&pl_copy, visit_primitive_list, &err);
+    g_assert(!err);
+    g_free(args);
+}
+
 static void test_struct(gconstpointer opaque)
 {
     TestArgs *args = (TestArgs *) opaque;
@@ -719,7 +1120,8 @@ static const SerializeOps visitors[] = {
         .serialize = qmp_serialize,
         .deserialize = qmp_deserialize,
         .cleanup = qmp_cleanup,
-        .caps = VCAP_PRIMITIVES | VCAP_STRUCTURES | VCAP_LISTS
+        .caps = VCAP_PRIMITIVES | VCAP_STRUCTURES | VCAP_LISTS |
+                VCAP_PRIMITIVE_LISTS
     },
     {
         .type = "String",
@@ -773,6 +1175,19 @@ static void add_visitor_type(const SerializeOps *ops)
         args->test_data = NULL;
         g_test_add_data_func(testname, args, test_nested_struct_list);
     }
+
+    if (ops->caps & VCAP_PRIMITIVE_LISTS) {
+        i = 0;
+        while (pt_values[i].type != PTYPE_EOL) {
+            sprintf(testname, "%s/primitive_list/%s", testname_prefix,
+                    pt_values[i].description);
+            args = g_malloc0(sizeof(*args));
+            args->ops = ops;
+            args->test_data = &pt_values[i];
+            g_test_add_data_func(testname, args, test_primitive_lists);
+            i++;
+        }
+    }
 }
 
 int main(int argc, char **argv)
commit 089f26bb735fb414b79f5fa3753910d5339d2a1d
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Fri May 10 17:46:07 2013 -0500

    qapi: fix visitor serialization tests for numbers/doubles
    
    We never actually stored the stringified double values into the strings
    before we did the comparisons. This left number/double values completely
    uncovered in test-visitor-serialization tests.
    
    Fixing this exposed a bug in our handling of large whole number values
    in QEMU's JSON parser which is now fixed.
    
    Simplify the code while we're at it by dropping the
    calc_float_string_storage() craziness in favor of GStrings.
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Amos Kong <akong at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c
index 8c8adac..fed6810 100644
--- a/tests/test-visitor-serialization.c
+++ b/tests/test-visitor-serialization.c
@@ -229,17 +229,6 @@ typedef struct TestArgs {
     void *test_data;
 } TestArgs;
 
-#define FLOAT_STRING_PRECISION 6 /* corresponding to n in %.nf formatting */
-static gsize calc_float_string_storage(double value)
-{
-    int whole_value = value;
-    gsize i = 0;
-    do {
-        i++;
-    } while (whole_value /= 10);
-    return i + 2 + FLOAT_STRING_PRECISION;
-}
-
 static void test_primitives(gconstpointer opaque)
 {
     TestArgs *args = (TestArgs *) opaque;
@@ -248,7 +237,6 @@ static void test_primitives(gconstpointer opaque)
     PrimitiveType *pt_copy = g_malloc0(sizeof(*pt_copy));
     Error *err = NULL;
     void *serialize_data;
-    char *double1, *double2;
 
     pt_copy->type = pt->type;
     ops->serialize(pt, &serialize_data, visit_primitive_type, &err);
@@ -260,14 +248,17 @@ static void test_primitives(gconstpointer opaque)
         g_assert_cmpstr(pt->value.string, ==, pt_copy->value.string);
         g_free((char *)pt_copy->value.string);
     } else if (pt->type == PTYPE_NUMBER) {
+        GString *double_expected = g_string_new("");
+        GString *double_actual = g_string_new("");
         /* we serialize with %f for our reference visitors, so rather than fuzzy
          * floating math to test "equality", just compare the formatted values
          */
-        double1 = g_malloc0(calc_float_string_storage(pt->value.number));
-        double2 = g_malloc0(calc_float_string_storage(pt_copy->value.number));
-        g_assert_cmpstr(double1, ==, double2);
-        g_free(double1);
-        g_free(double2);
+        g_string_printf(double_expected, "%.6f", pt->value.number);
+        g_string_printf(double_actual, "%.6f", pt_copy->value.number);
+        g_assert_cmpstr(double_actual->str, ==, double_expected->str);
+
+        g_string_free(double_expected, true);
+        g_string_free(double_actual, true);
     } else if (pt->type == PTYPE_BOOLEAN) {
         g_assert_cmpint(!!pt->value.max, ==, !!pt->value.max);
     } else {
commit e92cfa0d90c618ff1f131c60ef1b27aa6fe69a0a
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Fri May 10 17:46:06 2013 -0500

    qapi: add QMP input test for large integers
    
    Large integers previously got capped to LLONG_MAX/LLONG_MIN so we could
    store them as int64_t. This could lead to silent errors occuring.
    
    Now, we use a double to handle these cases.
    
    Add a test to confirm that QMPInputVisitor handles this as expected if
    we're expected an integer value: errors for out of range integer values
    that got promoted to doubles in this fashion.
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Amos Kong <akong at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index 955a4c0..b308cf9 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -75,6 +75,24 @@ static void test_visitor_in_int(TestInputVisitorData *data,
     g_assert_cmpint(res, ==, value);
 }
 
+static void test_visitor_in_int_overflow(TestInputVisitorData *data,
+                                         const void *unused)
+{
+    int64_t res = 0;
+    Error *errp = NULL;
+    Visitor *v;
+
+    /* this will overflow a Qint/int64, so should be deserialized into
+     * a QFloat/double field instead, leading to an error if we pass it
+     * to visit_type_int. confirm this.
+     */
+    v = visitor_input_test_init(data, "%f", DBL_MAX);
+
+    visit_type_int(v, &res, NULL, &errp);
+    g_assert(error_is_set(&errp));
+    error_free(errp);
+}
+
 static void test_visitor_in_bool(TestInputVisitorData *data,
                                  const void *unused)
 {
@@ -292,6 +310,8 @@ int main(int argc, char **argv)
 
     input_visitor_test_add("/visitor/input/int",
                            &in_visitor_data, test_visitor_in_int);
+    input_visitor_test_add("/visitor/input/int_overflow",
+                           &in_visitor_data, test_visitor_in_int_overflow);
     input_visitor_test_add("/visitor/input/bool",
                            &in_visitor_data, test_visitor_in_bool);
     input_visitor_test_add("/visitor/input/number",
commit 3d5b3ec6d460a92245215aaf7b349b0b9e5ffa25
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Fri May 10 17:46:05 2013 -0500

    json-parser: fix handling of large whole number values
    
    Currently our JSON parser assumes that numbers lacking a fractional
    value are integers and attempts to store them as QInt/int64 values. This
    breaks in the case where the number overflows/underflows int64 values (which
    is still valid JSON)
    
    Fix this by detecting such cases and using a QFloat to store the value
    instead.
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Amos Kong <akong at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/qobject/json-parser.c b/qobject/json-parser.c
index 05279c1..e7947b3 100644
--- a/qobject/json-parser.c
+++ b/qobject/json-parser.c
@@ -640,9 +640,29 @@ static QObject *parse_literal(JSONParserContext *ctxt)
     case JSON_STRING:
         obj = QOBJECT(qstring_from_escaped_str(ctxt, token));
         break;
-    case JSON_INTEGER:
-        obj = QOBJECT(qint_from_int(strtoll(token_get_value(token), NULL, 10)));
-        break;
+    case JSON_INTEGER: {
+        /* A possibility exists that this is a whole-valued float where the
+         * fractional part was left out due to being 0 (.0). It's not a big
+         * deal to treat these as ints in the parser, so long as users of the
+         * resulting QObject know to expect a QInt in place of a QFloat in
+         * cases like these.
+         *
+         * However, in some cases these values will overflow/underflow a
+         * QInt/int64 container, thus we should assume these are to be handled
+         * as QFloats/doubles rather than silently changing their values.
+         *
+         * strtoll() indicates these instances by setting errno to ERANGE
+         */
+        int64_t value;
+
+        errno = 0; /* strtoll doesn't set errno on success */
+        value = strtoll(token_get_value(token), NULL, 10);
+        if (errno != ERANGE) {
+            obj = QOBJECT(qint_from_int(value));
+            break;
+        }
+        /* fall through to JSON_FLOAT */
+    }
     case JSON_FLOAT:
         /* FIXME dependent on locale */
         obj = QOBJECT(qfloat_from_double(strtod(token_get_value(token), NULL)));
commit 0b400e792718f59275d5d54c21de9a589b35a81f
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Fri May 10 17:46:03 2013 -0500

    qapi: enable generation of native list code
    
    Also, fix a dependency issue with libqemuutil: qemu-sockets.c needs
    qapi-types.c/qapi-visit.c
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Amos Kong <akong at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/Makefile b/Makefile
index 7dc0204..9695c9d 100644
--- a/Makefile
+++ b/Makefile
@@ -178,7 +178,7 @@ Makefile: $(version-obj-y) $(version-lobj-y)
 # Build libraries
 
 libqemustub.a: $(stub-obj-y)
-libqemuutil.a: $(util-obj-y)
+libqemuutil.a: $(util-obj-y) qapi-types.o qapi-visit.o
 
 ######################################################################
 
@@ -215,10 +215,10 @@ $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
 
 qapi-types.c qapi-types.h :\
 $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
-	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o "." < $<, "  GEN   $@")
+	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o "." -b < $<, "  GEN   $@")
 qapi-visit.c qapi-visit.h :\
 $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
-	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o "."  < $<, "  GEN   $@")
+	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o "." -b < $<, "  GEN   $@")
 qmp-commands.h qmp-marshal.c :\
 $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
 	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -m -o "." < $<, "  GEN   $@")
commit 7c946bc418db6b2a11f89b3465424fef48f714eb
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Fri May 10 17:46:02 2013 -0500

    qapi: qapi-visit.py, native list support
    
    Teach visitor generators about native types so they can generate the
    appropriate visitor routines.
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Amos Kong <akong at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 4c4de4b..6cac05a 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -202,12 +202,14 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **
 
     return ret
 
-def generate_declaration(name, members, genlist=True):
-    ret = mcgen('''
+def generate_declaration(name, members, genlist=True, builtin_type=False):
+    ret = ""
+    if not builtin_type:
+        ret += mcgen('''
 
 void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp);
 ''',
-                name=name)
+                    name=name)
 
     if genlist:
         ret += mcgen('''
@@ -235,8 +237,9 @@ void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **e
                 name=name)
 
 try:
-    opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:",
-                                   ["source", "header", "prefix=", "output-dir="])
+    opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:o:",
+                                   ["source", "header", "builtins", "prefix=",
+                                    "output-dir="])
 except getopt.GetoptError, err:
     print str(err)
     sys.exit(1)
@@ -248,6 +251,7 @@ h_file = 'qapi-visit.h'
 
 do_c = False
 do_h = False
+do_builtins = False
 
 for o, a in opts:
     if o in ("-p", "--prefix"):
@@ -258,6 +262,8 @@ for o, a in opts:
         do_c = True
     elif o in ("-h", "--header"):
         do_h = True
+    elif o in ("-b", "--builtins"):
+        do_builtins = True
 
 if not do_c and not do_h:
     do_c = True
@@ -324,11 +330,29 @@ fdecl.write(mcgen('''
 
 #include "qapi/visitor.h"
 #include "%(prefix)sqapi-types.h"
+
 ''',
                   prefix=prefix, guard=guardname(h_file)))
 
 exprs = parse_schema(sys.stdin)
 
+# to avoid header dependency hell, we always generate declarations
+# for built-in types in our header files and simply guard them
+fdecl.write(guardstart("QAPI_VISIT_BUILTIN_VISITOR_DECL"))
+for typename in builtin_types:
+    fdecl.write(generate_declaration(typename, None, genlist=True,
+                                     builtin_type=True))
+fdecl.write(guardend("QAPI_VISIT_BUILTIN_VISITOR_DECL"))
+
+# ...this doesn't work for cases where we link in multiple objects that
+# have the functions defined, so we use -b option to provide control
+# over these cases
+if do_builtins:
+    fdef.write(guardstart("QAPI_VISIT_BUILTIN_VISITOR_DEF"))
+    for typename in builtin_types:
+        fdef.write(generate_visit_list(typename, None))
+    fdef.write(guardend("QAPI_VISIT_BUILTIN_VISITOR_DEF"))
+
 for expr in exprs:
     if expr.has_key('type'):
         ret = generate_visit_struct(expr['type'], expr['data'])
commit c664aef551714e91b7d83a28617b6e767db30d11
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Fri May 10 17:46:01 2013 -0500

    qapi: qapi-visit.py, fix list handling for union types
    
    Currently we assume non-list types when generating visitor routines for
    union types. This is broken, since values like ['Type'] need to mapped
    to 'TypeList'.
    
    We already have a type_name() function to handle this that we use for
    generating struct visitors, so use that here as well.
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Amos Kong <akong at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index a276540..4c4de4b 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -174,7 +174,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **
 ''',
                 abbrev = de_camel_case(name).upper(),
                 enum = c_fun(de_camel_case(key),False).upper(),
-                c_type=members[key],
+                c_type=type_name(members[key]),
                 c_name=c_fun(key))
 
     ret += mcgen('''
commit c0afa9c5f717d0ebf10c70c305974ebbffe4c71f
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Fri May 10 17:46:00 2013 -0500

    qapi: qapi-types.py, native list support
    
    Teach type generators about native types so they can generate the
    appropriate linked list types.
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Amos Kong <akong at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 9e19920..fd42d71 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -16,8 +16,21 @@ import os
 import getopt
 import errno
 
-def generate_fwd_struct(name, members):
+def generate_fwd_struct(name, members, builtin_type=False):
+    if builtin_type:
+        return mcgen('''
+
+typedef struct %(name)sList
+{
+    %(type)s value;
+    struct %(name)sList *next;
+} %(name)sList;
+''',
+                     type=c_type(name),
+                     name=name)
+
     return mcgen('''
+
 typedef struct %(name)s %(name)s;
 
 typedef struct %(name)sList
@@ -164,6 +177,7 @@ void qapi_free_%(type)s(%(c_type)s obj);
 
 def generate_type_cleanup(name):
     ret = mcgen('''
+
 void qapi_free_%(type)s(%(c_type)s obj)
 {
     QapiDeallocVisitor *md;
@@ -184,8 +198,9 @@ void qapi_free_%(type)s(%(c_type)s obj)
 
 
 try:
-    opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:",
-                                   ["source", "header", "prefix=", "output-dir="])
+    opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:o:",
+                                   ["source", "header", "builtins",
+                                    "prefix=", "output-dir="])
 except getopt.GetoptError, err:
     print str(err)
     sys.exit(1)
@@ -197,6 +212,7 @@ h_file = 'qapi-types.h'
 
 do_c = False
 do_h = False
+do_builtins = False
 
 for o, a in opts:
     if o in ("-p", "--prefix"):
@@ -207,6 +223,8 @@ for o, a in opts:
         do_c = True
     elif o in ("-h", "--header"):
         do_h = True
+    elif o in ("-b", "--builtins"):
+        do_builtins = True
 
 if not do_c and not do_h:
     do_c = True
@@ -282,6 +300,11 @@ fdecl.write(mcgen('''
 exprs = parse_schema(sys.stdin)
 exprs = filter(lambda expr: not expr.has_key('gen'), exprs)
 
+fdecl.write(guardstart("QAPI_TYPES_BUILTIN_STRUCT_DECL"))
+for typename in builtin_types:
+    fdecl.write(generate_fwd_struct(typename, None, builtin_type=True))
+fdecl.write(guardend("QAPI_TYPES_BUILTIN_STRUCT_DECL"))
+
 for expr in exprs:
     ret = "\n"
     if expr.has_key('type'):
@@ -298,6 +321,22 @@ for expr in exprs:
         continue
     fdecl.write(ret)
 
+# to avoid header dependency hell, we always generate declarations
+# for built-in types in our header files and simply guard them
+fdecl.write(guardstart("QAPI_TYPES_BUILTIN_CLEANUP_DECL"))
+for typename in builtin_types:
+    fdecl.write(generate_type_cleanup_decl(typename + "List"))
+fdecl.write(guardend("QAPI_TYPES_BUILTIN_CLEANUP_DECL"))
+
+# ...this doesn't work for cases where we link in multiple objects that
+# have the functions defined, so we use -b option to provide control
+# over these cases
+if do_builtins:
+    fdef.write(guardstart("QAPI_TYPES_BUILTIN_CLEANUP_DEF"))
+    for typename in builtin_types:
+        fdef.write(generate_type_cleanup(typename + "List"))
+    fdef.write(guardend("QAPI_TYPES_BUILTIN_CLEANUP_DEF"))
+
 for expr in exprs:
     ret = "\n"
     if expr.has_key('type'):
diff --git a/scripts/qapi.py b/scripts/qapi.py
index afc5f32..02ad668 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -11,6 +11,12 @@
 
 from ordereddict import OrderedDict
 
+builtin_types = [
+    'str', 'int', 'number', 'bool',
+    'int8', 'int16', 'int32', 'int64',
+    'uint8', 'uint16', 'uint32', 'uint64'
+]
+
 def tokenize(data):
     while len(data):
         ch = data[0]
@@ -242,3 +248,20 @@ def guardname(filename):
     for substr in [".", " ", "-"]:
         guard = guard.replace(substr, "_")
     return guard.upper() + '_H'
+
+def guardstart(name):
+    return mcgen('''
+
+#ifndef %(name)s
+#define %(name)s
+
+''',
+                 name=guardname(name))
+
+def guardend(name):
+    return mcgen('''
+
+#endif /* %(name)s */
+
+''',
+                 name=guardname(name))
commit 95de21a430f7bc4166a153b1f69b1425c8a99c7b
Merge: 3459f01 d2ad502
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Wed May 22 08:22:36 2013 -0500

    Merge remote-tracking branch 'mjt/trivial-patches' into staging
    
    # By Christophe Lyon (1) and others
    # Via Michael Tokarev
    * mjt/trivial-patches:
      target-moxie: replace target_phys_addr_t with hwaddr
      Rename hexdump to avoid FreeBSD libutil conflict
      remove some double-includes
      translate: remove redundantly included qemu/timer.h
      Remove twice include of qemu-common.h
      fix /proc/self/maps output
    
    Message-id: 51977B44.1000302 at msgid.tls.msk.ru
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 3459f01b2d9612070ec23221a4ccb60a41b775ae
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Mon May 13 14:20:02 2013 -0600

    pci-assign: Add MSI affinity support
    
    To support guest MSI affinity changes update the MSI message any time
    the guest writes to the address or data fields.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>
    Acked-by: Michael S. Tsirkin <mst at redhat.com>
    Message-id: 20130513201840.5430.86331.stgit at bling.home
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
index c1e08ec..ff85590 100644
--- a/hw/i386/kvm/pci-assign.c
+++ b/hw/i386/kvm/pci-assign.c
@@ -1026,6 +1026,21 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev)
     }
 }
 
+static void assigned_dev_update_msi_msg(PCIDevice *pci_dev)
+{
+    AssignedDevice *assigned_dev = DO_UPCAST(AssignedDevice, dev, pci_dev);
+    uint8_t ctrl_byte = pci_get_byte(pci_dev->config + pci_dev->msi_cap +
+                                     PCI_MSI_FLAGS);
+
+    if (assigned_dev->assigned_irq_type != ASSIGNED_IRQ_MSI ||
+        !(ctrl_byte & PCI_MSI_FLAGS_ENABLE)) {
+        return;
+    }
+
+    kvm_irqchip_update_msi_route(kvm_state, assigned_dev->msi_virq[0],
+                                 msi_get_message(pci_dev, 0));
+}
+
 static bool assigned_dev_msix_masked(MSIXTableEntry *entry)
 {
     return (entry->ctrl & cpu_to_le32(0x1)) != 0;
@@ -1201,6 +1216,9 @@ static void assigned_dev_pci_write_config(PCIDevice *pci_dev, uint32_t address,
         if (range_covers_byte(address, len,
                               pci_dev->msi_cap + PCI_MSI_FLAGS)) {
             assigned_dev_update_msi(pci_dev);
+        } else if (ranges_overlap(address, len, /* 32bit MSI only */
+                                  pci_dev->msi_cap + PCI_MSI_ADDRESS_LO, 6)) {
+            assigned_dev_update_msi_msg(pci_dev);
         }
     }
     if (assigned_dev->cap.available & ASSIGNED_DEVICE_CAP_MSIX) {
commit 644c98587d4ccc09e7592e1688e4e7fa363c5a75
Author: Dmitry Fleytman <dfleytma at redhat.com>
Date:   Mon May 20 11:18:14 2013 +0300

    virtio-net: dynamic network offloads configuration
    
    Virtio-net driver currently negotiates network offloads
    on startup via features mechanism and have no ability to
    disable and re-enable offloads later.
    This patch introduced a new control command that allows
    to configure device network offloads state dynamically.
    The patch also introduces a new feature flag
    VIRTIO_NET_F_CTRL_GUEST_OFFLOADS.
    
    Signed-off-by: Dmitry Fleytman <dfleytma at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Message-id: 20130520081814.GA8162 at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index bed0822..1ea9556 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -359,6 +359,34 @@ static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
     return features;
 }
 
+static void virtio_net_apply_guest_offloads(VirtIONet *n)
+{
+    tap_set_offload(qemu_get_subqueue(n->nic, 0)->peer,
+            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_CSUM)),
+            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO4)),
+            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO6)),
+            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_ECN)),
+            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_UFO)));
+}
+
+static uint64_t virtio_net_guest_offloads_by_features(uint32_t features)
+{
+    static const uint64_t guest_offloads_mask =
+        (1ULL << VIRTIO_NET_F_GUEST_CSUM) |
+        (1ULL << VIRTIO_NET_F_GUEST_TSO4) |
+        (1ULL << VIRTIO_NET_F_GUEST_TSO6) |
+        (1ULL << VIRTIO_NET_F_GUEST_ECN)  |
+        (1ULL << VIRTIO_NET_F_GUEST_UFO);
+
+    return guest_offloads_mask & features;
+}
+
+static inline uint64_t virtio_net_supported_guest_offloads(VirtIONet *n)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(n);
+    return virtio_net_guest_offloads_by_features(vdev->guest_features);
+}
+
 static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
 {
     VirtIONet *n = VIRTIO_NET(vdev);
@@ -369,12 +397,9 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
     virtio_net_set_mrg_rx_bufs(n, !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF)));
 
     if (n->has_vnet_hdr) {
-        tap_set_offload(qemu_get_subqueue(n->nic, 0)->peer,
-                        (features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
-                        (features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
-                        (features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
-                        (features >> VIRTIO_NET_F_GUEST_ECN)  & 1,
-                        (features >> VIRTIO_NET_F_GUEST_UFO)  & 1);
+        n->curr_guest_offloads =
+            virtio_net_guest_offloads_by_features(features);
+        virtio_net_apply_guest_offloads(n);
     }
 
     for (i = 0;  i < n->max_queues; i++) {
@@ -420,6 +445,43 @@ static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd,
     return VIRTIO_NET_OK;
 }
 
+static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,
+                                     struct iovec *iov, unsigned int iov_cnt)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(n);
+    uint64_t offloads;
+    size_t s;
+
+    if (!((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features)) {
+        return VIRTIO_NET_ERR;
+    }
+
+    s = iov_to_buf(iov, iov_cnt, 0, &offloads, sizeof(offloads));
+    if (s != sizeof(offloads)) {
+        return VIRTIO_NET_ERR;
+    }
+
+    if (cmd == VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET) {
+        uint64_t supported_offloads;
+
+        if (!n->has_vnet_hdr) {
+            return VIRTIO_NET_ERR;
+        }
+
+        supported_offloads = virtio_net_supported_guest_offloads(n);
+        if (offloads & ~supported_offloads) {
+            return VIRTIO_NET_ERR;
+        }
+
+        n->curr_guest_offloads = offloads;
+        virtio_net_apply_guest_offloads(n);
+
+        return VIRTIO_NET_OK;
+    } else {
+        return VIRTIO_NET_ERR;
+    }
+}
+
 static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd,
                                  struct iovec *iov, unsigned int iov_cnt)
 {
@@ -590,6 +652,8 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
             status = virtio_net_handle_vlan_table(n, ctrl.cmd, iov, iov_cnt);
         } else if (ctrl.class == VIRTIO_NET_CTRL_MQ) {
             status = virtio_net_handle_mq(n, ctrl.cmd, iov, iov_cnt);
+        } else if (ctrl.class == VIRTIO_NET_CTRL_GUEST_OFFLOADS) {
+            status = virtio_net_handle_offloads(n, ctrl.cmd, iov, iov_cnt);
         }
 
         s = iov_from_buf(elem.in_sg, elem.in_num, 0, &status, sizeof(status));
@@ -1110,6 +1174,10 @@ static void virtio_net_save(QEMUFile *f, void *opaque)
             qemu_put_be32(f, n->vqs[i].tx_waiting);
         }
     }
+
+    if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
+        qemu_put_be64(f, n->curr_guest_offloads);
+    }
 }
 
 static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
@@ -1167,15 +1235,6 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
             error_report("virtio-net: saved image requires vnet_hdr=on");
             return -1;
         }
-
-        if (n->has_vnet_hdr) {
-            tap_set_offload(qemu_get_queue(n->nic)->peer,
-                    (vdev->guest_features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
-                    (vdev->guest_features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
-                    (vdev->guest_features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
-                    (vdev->guest_features >> VIRTIO_NET_F_GUEST_ECN)  & 1,
-                    (vdev->guest_features >> VIRTIO_NET_F_GUEST_UFO)  & 1);
-        }
     }
 
     if (version_id >= 9) {
@@ -1209,6 +1268,16 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
         }
     }
 
+    if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
+        n->curr_guest_offloads = qemu_get_be64(f);
+    } else {
+        n->curr_guest_offloads = virtio_net_supported_guest_offloads(n);
+    }
+
+    if (peer_has_vnet_hdr(n)) {
+        virtio_net_apply_guest_offloads(n);
+    }
+
     virtio_net_set_queues(n);
 
     /* Find the first multicast entry in the saved MAC filter */
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 2bd7090..93d8357 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -217,6 +217,10 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
             .property = "vectors",\
             /* DEV_NVECTORS_UNSPECIFIED as a uint32_t string */\
             .value    = stringify(0xFFFFFFFF),\
+        },{ \
+            .driver   = "virtio-net-pci", \
+            .property = "ctrl_guest_offloads", \
+            .value    = "off", \
         },{\
             .driver   = "e1000",\
             .property = "romfile",\
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index beeead7..b315ac9 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -31,6 +31,8 @@
 /* The feature bitmap for virtio net */
 #define VIRTIO_NET_F_CSUM       0       /* Host handles pkts w/ partial csum */
 #define VIRTIO_NET_F_GUEST_CSUM 1       /* Guest handles pkts w/ partial csum */
+#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Control channel offload
+                                         * configuration support */
 #define VIRTIO_NET_F_MAC        5       /* Host has given MAC address. */
 #define VIRTIO_NET_F_GSO        6       /* Host handles pkts w/ any GSO type */
 #define VIRTIO_NET_F_GUEST_TSO4 7       /* Guest can handle TSOv4 in. */
@@ -190,6 +192,7 @@ typedef struct VirtIONet {
     size_t config_size;
     char *netclient_name;
     char *netclient_type;
+    uint64_t curr_guest_offloads;
 } VirtIONet;
 
 #define VIRTIO_NET_CTRL_MAC    1
@@ -229,6 +232,15 @@ struct virtio_net_ctrl_mq {
  #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN        1
  #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX        0x8000
 
+/*
+ * Control network offloads
+ *
+ * Dynamic offloads are available with the
+ * VIRTIO_NET_F_CTRL_GUEST_OFFLOADS feature bit.
+ */
+#define VIRTIO_NET_CTRL_GUEST_OFFLOADS   5
+ #define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET        0
+
 #define DEFINE_VIRTIO_NET_FEATURES(_state, _field) \
         DEFINE_VIRTIO_COMMON_FEATURES(_state, _field), \
         DEFINE_PROP_BIT("csum", _state, _field, VIRTIO_NET_F_CSUM, true), \
@@ -249,6 +261,7 @@ struct virtio_net_ctrl_mq {
         DEFINE_PROP_BIT("ctrl_vlan", _state, _field, VIRTIO_NET_F_CTRL_VLAN, true), \
         DEFINE_PROP_BIT("ctrl_rx_extra", _state, _field, VIRTIO_NET_F_CTRL_RX_EXTRA, true), \
         DEFINE_PROP_BIT("ctrl_mac_addr", _state, _field, VIRTIO_NET_F_CTRL_MAC_ADDR, true), \
+        DEFINE_PROP_BIT("ctrl_guest_offloads", _state, _field, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, true), \
         DEFINE_PROP_BIT("mq", _state, _field, VIRTIO_NET_F_MQ, false)
 
 #define DEFINE_VIRTIO_NET_PROPERTIES(_state, _field)                           \
commit 2b220025993e76d4116781ca91a4fabc5ad9c722
Author: Lei Li <lilei at linux.vnet.ibm.com>
Date:   Tue May 21 18:27:59 2013 +0800

    chardev: Get filename for new qapi backend
    
    This patch sets the filename when the new qapi backend
    init from opts.
    
    The previous patch and discussions as link below:
    
    http://patchwork.ozlabs.org/patch/243896/
    
    If anyone who have better idea to fix this please let
    me know your suggestions.
    
    Signed-off-by: Lei Li <lilei at linux.vnet.ibm.com>
    Message-id: 1369132079-11377-3-git-send-email-lilei at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/qemu-char.c b/qemu-char.c
index f825294..4f8382e 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3276,6 +3276,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
         ChardevReturn *ret = NULL;
         const char *id = qemu_opts_id(opts);
         const char *bid = NULL;
+        char *filename = g_strdup(qemu_opt_get(opts, "backend"));
 
         if (qemu_opt_get_bool(opts, "mux", 0)) {
             bid = g_strdup_printf("%s-base", id);
@@ -3308,6 +3309,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
         }
 
         chr = qemu_chr_find(id);
+        chr->filename = filename;
 
     qapi_out:
         qapi_free_ChardevBackend(backend);
commit 6a85e60cb994bd95d1537aafbff65816f3de4637
Author: Lei Li <lilei at linux.vnet.ibm.com>
Date:   Tue May 21 18:27:58 2013 +0800

    chardev: Make the name of memory device consistent
    
    Now we have memory char device, but the backend name of it
    is a little confusion. We actually register it by 'memory', but
    the description in qemu-option, the name of open functions
    and the new api backend called it 'ringbuf'. It should keep
    consistent. This patch named it all to 'memory'.
    
    Signed-off-by: Lei Li <lilei at linux.vnet.ibm.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Message-id: 1369132079-11377-2-git-send-email-lilei at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/qapi-schema.json b/qapi-schema.json
index 9302e7d..664b31f 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3286,7 +3286,7 @@
                                  '*rows'   : 'int' } }
 
 ##
-# @ChardevRingbuf:
+# @ChardevMemory:
 #
 # Configuration info for memory chardevs
 #
@@ -3294,7 +3294,7 @@
 #
 # Since: 1.5
 ##
-{ 'type': 'ChardevRingbuf', 'data': { '*size'  : 'int' } }
+{ 'type': 'ChardevMemory', 'data': { '*size'  : 'int' } }
 
 ##
 # @ChardevBackend:
@@ -3321,7 +3321,7 @@
                                        'spicevmc' : 'ChardevSpiceChannel',
                                        'spiceport' : 'ChardevSpicePort',
                                        'vc'     : 'ChardevVC',
-                                       'memory' : 'ChardevRingbuf' } }
+                                       'memory' : 'ChardevMemory' } }
 
 ##
 # @ChardevReturn:
diff --git a/qemu-char.c b/qemu-char.c
index 5d20d3c..f825294 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2875,8 +2875,8 @@ static void ringbuf_chr_close(struct CharDriverState *chr)
     chr->opaque = NULL;
 }
 
-static CharDriverState *qemu_chr_open_ringbuf(ChardevRingbuf *opts,
-                                              Error **errp)
+static CharDriverState *qemu_chr_open_memory(ChardevMemory *opts,
+                                             Error **errp)
 {
     CharDriverState *chr;
     RingBufCharDriver *d;
@@ -2888,7 +2888,7 @@ static CharDriverState *qemu_chr_open_ringbuf(ChardevRingbuf *opts,
 
     /* The size must be power of 2 */
     if (d->size & (d->size - 1)) {
-        error_setg(errp, "size of ringbuf chardev must be power of two");
+        error_setg(errp, "size of memory chardev must be power of two");
         goto fail;
     }
 
@@ -3190,12 +3190,12 @@ static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend,
     backend->pipe->device = g_strdup(device);
 }
 
-static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend,
-                                   Error **errp)
+static void qemu_chr_parse_memory(QemuOpts *opts, ChardevBackend *backend,
+                                  Error **errp)
 {
     int val;
 
-    backend->memory = g_new0(ChardevRingbuf, 1);
+    backend->memory = g_new0(ChardevMemory, 1);
 
     val = qemu_opt_get_number(opts, "size", 0);
     if (val != 0) {
@@ -3787,7 +3787,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
         chr = vc_init(backend->vc);
         break;
     case CHARDEV_BACKEND_KIND_MEMORY:
-        chr = qemu_chr_open_ringbuf(backend->memory, errp);
+        chr = qemu_chr_open_memory(backend->memory, errp);
         break;
     default:
         error_setg(errp, "unknown chardev backend (%d)", backend->kind);
@@ -3832,7 +3832,7 @@ static void register_types(void)
     register_char_driver("socket", qemu_chr_open_socket);
     register_char_driver("udp", qemu_chr_open_udp);
     register_char_driver_qapi("memory", CHARDEV_BACKEND_KIND_MEMORY,
-                              qemu_chr_parse_ringbuf);
+                              qemu_chr_parse_memory);
     register_char_driver_qapi("file", CHARDEV_BACKEND_KIND_FILE,
                               qemu_chr_parse_file_out);
     register_char_driver_qapi("stdio", CHARDEV_BACKEND_KIND_STDIO,
diff --git a/qemu-options.hx b/qemu-options.hx
index fb62b75..fb3961d 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1779,7 +1779,7 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
     "-chardev msmouse,id=id[,mux=on|off]\n"
     "-chardev vc,id=id[[,width=width][,height=height]][[,cols=cols][,rows=rows]]\n"
     "         [,mux=on|off]\n"
-    "-chardev ringbuf,id=id[,size=size]\n"
+    "-chardev memory,id=id[,size=size]\n"
     "-chardev file,id=id,path=path[,mux=on|off]\n"
     "-chardev pipe,id=id,path=path[,mux=on|off]\n"
 #ifdef _WIN32
@@ -1817,7 +1817,7 @@ Backend is one of:
 @option{udp},
 @option{msmouse},
 @option{vc},
- at option{ringbuf},
+ at option{memory},
 @option{file},
 @option{pipe},
 @option{console},
@@ -1926,7 +1926,7 @@ the console, in pixels.
 @option{cols} and @option{rows} specify that the console be sized to fit a text
 console with the given dimensions.
 
- at item -chardev ringbuf ,id=@var{id} [,size=@var{size}]
+ at item -chardev memory ,id=@var{id} [,size=@var{size}]
 
 Create a ring buffer with fixed size @option{size}.
 @var{size} must be a power of two, and defaults to @code{64K}).
commit 17bf9735dd5a46d829cfb175703c6a2c254a9aa2
Author: Brad Smith <brad at comstyle.com>
Date:   Tue May 21 12:14:24 2013 -0400

    ui/gtk.c: Fix *BSD build of Gtk+ UI
    
    Fix the build of the Gtk+ UI on *BSD systems.
    
    Signed-off-by: Brad Smith <brad at comstyle.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Message-id: 20130521161324.GA29977 at rox.home.comstyle.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/include/qemu-common.h b/include/qemu-common.h
index b9057d1..cb82ef3 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -45,6 +45,7 @@
 #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
commit 95916abcf428fb03644468c7fbce64356c6483c0
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Wed May 22 11:19:16 2013 +1000

    qom/object: Don't poll cast cache for NULL objects
    
    object_dynamic_cast_assert used to be tolerant of NULL objects and not
    assert. It's clear from the implementation that this is the expected
    behavior.
    
    The preceding check of the cast cache dereferences obj however causing
    a segfault. Fix by conditionalizing the cast cache logic on obj being
    non-null.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Anthony Liguori <aliguori at us.ibm.com>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: 8e2bef6a55753869c50bfa32226f7fcf0439ca62.1369183592.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/qom/object.c b/qom/object.c
index ec88231..803b94b 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -442,7 +442,7 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename,
     int i;
     Object *inst;
 
-    for (i = 0; i < OBJECT_CLASS_CAST_CACHE; i++) {
+    for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) {
         if (obj->class->cast_cache[i] == typename) {
             goto out;
         }
@@ -458,7 +458,7 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename,
 
     assert(obj == inst);
 
-    if (obj == inst) {
+    if (obj && obj == inst) {
         for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
             obj->class->cast_cache[i - 1] = obj->class->cast_cache[i];
         }
commit 3d1bba20913356ff4f8ff2c38519f10c5f4b77e6
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Wed May 22 13:01:43 2013 +1000

    glib: Fix some misuses of gsize/size_t types
    
    This unbreaks cross compile builds:
    
    configure --target-list="i386-softmmu" --cpu=i386
    
    When building on a 64bit machine.
    
    Reported-by: David Holsgrove <david.holsgrove at xilinx.com>
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: 926326e96fd8685d74e9d5bf430fe4ad97a55289.1369191585.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 1a7e49c..479113b 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -54,7 +54,7 @@ struct FWCfgState {
 #define JPG_FILE 0
 #define BMP_FILE 1
 
-static char *read_splashfile(char *filename, size_t *file_sizep,
+static char *read_splashfile(char *filename, gsize *file_sizep,
                              int *file_typep)
 {
     GError *err = NULL;
@@ -112,7 +112,7 @@ static void fw_cfg_bootsplash(FWCfgState *s)
     const char *boot_splash_filename = NULL;
     char *p;
     char *filename, *file_data;
-    size_t file_size;
+    gsize file_size;
     int file_type;
     const char *temp;
 
diff --git a/qemu-char.c b/qemu-char.c
index cff2896..5d20d3c 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2920,7 +2920,7 @@ void qmp_ringbuf_write(const char *device, const char *data,
     CharDriverState *chr;
     const uint8_t *write_data;
     int ret;
-    size_t write_count;
+    gsize write_count;
 
     chr = qemu_chr_find(device);
     if (!chr) {
commit 1239b472bb0dba8060f1af29d40dafbc1b2860d4
Author: Kwok Cheung Yeung <kcy at codesourcery.com>
Date:   Fri May 17 14:51:21 2013 -0700

    linux-user: Save the correct resume address for MIPS signal handling
    
    The current ISA mode needs to be saved in bit 0 of the resume address.
    If the current instruction happens to be in a branch delay slot, then
    the address of the preceding jump instruction should be stored instead.
    exception_resume_pc already does both of these tasks, so it is
    made available and reused.
    
    MIPS_HFLAG_BMASK in hflags is cleared, otherwise QEMU may treat the
    first instruction of the signal handler as a delay slot instruction.
    
    Signed-off-by: Kwok Cheung Yeung <kcy at codesourcery.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/linux-user/signal.c b/linux-user/signal.c
index dc34ae7..5da8452 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -2528,7 +2528,8 @@ setup_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
     int err = 0;
     int i;
 
-    err |= __put_user(regs->active_tc.PC, &sc->sc_pc);
+    err |= __put_user(exception_resume_pc(regs), &sc->sc_pc);
+    regs->hflags &= ~MIPS_HFLAG_BMASK;
 
     __put_user(0, &sc->sc_regs[0]);
     for (i = 1; i < 32; ++i) {
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index cedf03d..6e761e0 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -668,6 +668,7 @@ void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra);
 hwaddr cpu_mips_translate_address (CPUMIPSState *env, target_ulong address,
 		                               int rw);
 #endif
+target_ulong exception_resume_pc (CPUMIPSState *env);
 
 static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 3a54acf..36929dd 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -366,8 +366,7 @@ static const char * const excp_names[EXCP_LAST + 1] = {
     [EXCP_CACHE] = "cache error",
 };
 
-#if !defined(CONFIG_USER_ONLY)
-static target_ulong exception_resume_pc (CPUMIPSState *env)
+target_ulong exception_resume_pc (CPUMIPSState *env)
 {
     target_ulong bad_pc;
     target_ulong isa_mode;
@@ -383,6 +382,7 @@ static target_ulong exception_resume_pc (CPUMIPSState *env)
     return bad_pc;
 }
 
+#if !defined(CONFIG_USER_ONLY)
 static void set_hflags_for_handler (CPUMIPSState *env)
 {
     /* Exception handlers are entered in 32-bit mode.  */
commit ea3164aafccdfdd8a9543787cdfa25fac30a5def
Author: Kwok Cheung Yeung <kcy at codesourcery.com>
Date:   Fri May 17 14:51:20 2013 -0700

    linux-user: Fix MIPS ISA transitions during signal handling
    
    Processors supporting the MIPS16 or microMIPS ISAs set bit 0 in target
    addresses to indicate that the target is written using a compressed ISA.
    
    During signal handling, when jumping to or returning from a signal
    handler, bit 0 of the destination PC is inspected and MIPS_HFLAG_M16 in
    hflags cleared or set accordingly.  Bit 0 of the PC is then cleared.
    
    Signed-off-by: Kwok Cheung Yeung <kcy at codesourcery.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 1055507..dc34ae7 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -2620,6 +2620,15 @@ get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
     return (sp - frame_size) & ~7;
 }
 
+static void mips_set_hflags_isa_mode_from_pc(CPUMIPSState *env)
+{
+    if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
+        env->hflags &= ~MIPS_HFLAG_M16;
+        env->hflags |= (env->active_tc.PC & 1) << MIPS_HFLAG_M16_SHIFT;
+        env->active_tc.PC &= ~(target_ulong) 1;
+    }
+}
+
 # if defined(TARGET_ABI_MIPSO32)
 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
 static void setup_frame(int sig, struct target_sigaction * ka,
@@ -2662,6 +2671,7 @@ static void setup_frame(int sig, struct target_sigaction * ka,
     * since it returns to userland using eret
     * we cannot do this here, and we must set PC directly */
     regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
+    mips_set_hflags_isa_mode_from_pc(regs);
     unlock_user_struct(frame, frame_addr, 1);
     return;
 
@@ -2709,6 +2719,7 @@ long do_sigreturn(CPUMIPSState *regs)
 #endif
 
     regs->active_tc.PC = regs->CP0_EPC;
+    mips_set_hflags_isa_mode_from_pc(regs);
     /* I am not sure this is right, but it seems to work
     * maybe a problem with nested signals ? */
     regs->CP0_EPC = 0;
@@ -2771,6 +2782,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
     * since it returns to userland using eret
     * we cannot do this here, and we must set PC directly */
     env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
+    mips_set_hflags_isa_mode_from_pc(env);
     unlock_user_struct(frame, frame_addr, 1);
     return;
 
@@ -2804,6 +2816,7 @@ long do_rt_sigreturn(CPUMIPSState *env)
         goto badframe;
 
     env->active_tc.PC = env->CP0_EPC;
+    mips_set_hflags_isa_mode_from_pc(env);
     /* I am not sure this is right, but it seems to work
     * maybe a problem with nested signals ? */
     env->CP0_EPC = 0;
commit d8992825aedbb83b7a0e98284e0527bc82a6f7df
Author: Petar Jovanovic <petar.jovanovic at imgtec.com>
Date:   Mon May 13 03:35:37 2013 +0200

    target-mips: clean-up in BIT_INSV
    
    This is a small follow-up change to "fix incorrect behaviour for INSV".
    
    It includes two minor modifications:
    
    - sizefilter is constant so it can be moved inside of the block,
    - several lines of the code are replaced with a call to deposit64.
    
    No functional change.
    
    Signed-off-by: Petar Jovanovic <petar.jovanovic at imgtec.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index 918a898..4116de9 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -2902,13 +2902,13 @@ target_ulong helper_bitrev(target_ulong rt)
     return (target_ulong)rd;
 }
 
-#define BIT_INSV(name, posfilter, sizefilter, ret_type)         \
+#define BIT_INSV(name, posfilter, ret_type)                     \
 target_ulong helper_##name(CPUMIPSState *env, target_ulong rs,  \
                            target_ulong rt)                     \
 {                                                               \
     uint32_t pos, size, msb, lsb;                               \
-    target_ulong filter;                                        \
-    target_ulong temp, temprs, temprt;                          \
+    uint32_t const sizefilter = 0x3F;                           \
+    target_ulong temp;                                          \
     target_ulong dspc;                                          \
                                                                 \
     dspc = env->active_tc.DSPControl;                           \
@@ -2923,18 +2923,14 @@ target_ulong helper_##name(CPUMIPSState *env, target_ulong rs,  \
         return rt;                                              \
     }                                                           \
                                                                 \
-    filter = ((int64_t)0x01 << size) - 1;                       \
-    filter = filter << pos;                                     \
-    temprs = (rs << pos) & filter;                              \
-    temprt = rt & ~filter;                                      \
-    temp = temprs | temprt;                                     \
+    temp = deposit64(rt, pos, size, rs);                        \
                                                                 \
     return (target_long)(ret_type)temp;                         \
 }
 
-BIT_INSV(insv, 0x1F, 0x3F, int32_t);
+BIT_INSV(insv, 0x1F, int32_t);
 #ifdef TARGET_MIPS64
-BIT_INSV(dinsv, 0x7F, 0x3F, target_long);
+BIT_INSV(dinsv, 0x7F, target_long);
 #endif
 
 #undef BIT_INSV
commit 9ce0e9275434bacdeba42dd32e0e8269293fe2cf
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon May 20 10:55:18 2013 -0500

    Open up 1.6 development
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/VERSION b/VERSION
index bc80560..88eb60e 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.5.0
+1.5.50
commit 371386fb60961e0afc02f03c817dff79633e323e
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon May 20 07:22:02 2013 -0500

    Update version for 1.5.0 release.
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/VERSION b/VERSION
index 80fd6ef..bc80560 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.4.93
+1.5.0
commit da4c1a7a850176cde4840eaec0a19c305843ad21
Author: Hervé Poussineau <hpoussin at reactos.org>
Date:   Mon May 20 12:33:08 2013 +0200

    osdep: fix qemu_anon_ram_free trace (+ fix compilation on 32 bit hosts)
    
    Commit e7a09b92b70786f9e8c5fbf787e0248c6ebbe707 added a trace at each
    memory freeing, but unfortunately inverted size and pointer when printing
    them. Fix trace.
    
    This also led to a compilation error on 32 bit hosts:
    In file included from include/trace.h:4:0,
                     from trace/generated-events.c:3:
    ./trace/generated-tracers.h: In function ‘trace_qemu_anon_ram_free’:
    ./trace/generated-tracers.h:64:9: error: format ‘%zu’ expects argument of type
    ‘size_t’, but argument 3 has type ‘void *’ [-Werror=format]
    ./trace/generated-tracers.h:64:9: error: format ‘%p’ expects argument of type
    ‘void *’, but argument 4 has type ‘size_t’ [-Werror=format]
    
    Signed-off-by: Hervé Poussineau <hpoussin at reactos.org>
    Signed-off-by: Hervé Poussineau <hpoussin at reactos.org>
    Message-id: 1369045989-14016-1-git-send-email-hpoussin at reactos.org
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/trace-events b/trace-events
index c03b9cb..9c73931 100644
--- a/trace-events
+++ b/trace-events
@@ -34,7 +34,7 @@ g_free(void *ptr) "ptr %p"
 qemu_memalign(size_t alignment, size_t size, void *ptr) "alignment %zu size %zu ptr %p"
 qemu_anon_ram_alloc(size_t size, void *ptr) "size %zu ptr %p"
 qemu_vfree(void *ptr) "ptr %p"
-qemu_anon_ram_free(void *ptr, size_t size) "size %zu ptr %p"
+qemu_anon_ram_free(void *ptr, size_t size) "ptr %p size %zu"
 
 # hw/virtio.c
 virtqueue_fill(void *vq, const void *elem, unsigned int len, unsigned int idx) "vq %p elem %p len %u idx %u"
commit 3568ac2a6e6df89cea52a56f70b95af9e1251bbd
Author: Ed Maste <emaste at freebsd.org>
Date:   Thu May 16 11:32:28 2013 -0400

    Rename hexdump to avoid FreeBSD libutil conflict
    
    On FreeBSD libutil is used for openpty(), but it also provides a hexdump()
    which conflicts with QEMU's.
    
    Signed-off-by: Ed Maste <emaste at freebsd.org>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 1368718348-15199-1-git-send-email-emaste at freebsd.org
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
index 8b33138..60f5299 100644
--- a/hw/dma/pl330.c
+++ b/hw/dma/pl330.c
@@ -1157,7 +1157,7 @@ static int pl330_exec_cycle(PL330Chan *channel)
         if (PL330_ERR_DEBUG > 1) {
             DB_PRINT("PL330 read from memory @%08x (size = %08x):\n",
                       q->addr, len);
-            hexdump((char *)buf, stderr, "", len);
+            qemu_hexdump((char *)buf, stderr, "", len);
         }
         fifo_res = pl330_fifo_push(&s->fifo, buf, len, q->tag);
         if (fifo_res == PL330_FIFO_OK) {
@@ -1189,7 +1189,7 @@ static int pl330_exec_cycle(PL330Chan *channel)
             if (PL330_ERR_DEBUG > 1) {
                 DB_PRINT("PL330 read from memory @%08x (size = %08x):\n",
                          q->addr, len);
-                hexdump((char *)buf, stderr, "", len);
+                qemu_hexdump((char *)buf, stderr, "", len);
             }
             if (q->inc) {
                 q->addr += len;
diff --git a/include/qemu-common.h b/include/qemu-common.h
index 7f18b8e..b9057d1 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -443,7 +443,7 @@ int mod_utf8_codepoint(const char *s, size_t n, char **end);
  * Hexdump a buffer to a file. An optional string prefix is added to every line
  */
 
-void hexdump(const char *buf, FILE *fp, const char *prefix, size_t size);
+void qemu_hexdump(const char *buf, FILE *fp, const char *prefix, size_t size);
 
 /* vector definitions */
 #ifdef __ALTIVEC__
diff --git a/util/hexdump.c b/util/hexdump.c
index 0d0efc8..969b340 100644
--- a/util/hexdump.c
+++ b/util/hexdump.c
@@ -15,7 +15,7 @@
 
 #include "qemu-common.h"
 
-void hexdump(const char *buf, FILE *fp, const char *prefix, size_t size)
+void qemu_hexdump(const char *buf, FILE *fp, const char *prefix, size_t size)
 {
     unsigned int b;
 
diff --git a/util/iov.c b/util/iov.c
index 78bbbe1..cc6e837 100644
--- a/util/iov.c
+++ b/util/iov.c
@@ -225,7 +225,7 @@ void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt,
     size = size > limit ? limit : size;
     buf = g_malloc(size);
     iov_to_buf(iov, iov_cnt, 0, buf, size);
-    hexdump(buf, fp, prefix, size);
+    qemu_hexdump(buf, fp, prefix, size);
     g_free(buf);
 }
 
commit fd2a2e1c552cb47ca196552457e175c889b58478
Author: Hu Tao <hutao at cn.fujitsu.com>
Date:   Mon May 20 12:46:20 2013 +0200

    vl: new runstate transition: RUN_STATE_GUEST_PANICKED -> RUN_STATE_FINISH_MIGRATE
    
    This fixes a problem that after guest panic happens, virsh dump without
    --memory-only fails:
    
    ERROR: invalid runstate transition: 'guest-panicked' -> 'finish-migrate'
    
    Reported-by: Christian Borntraeger <borntraeger at de.ibm.com>
    Signed-off-by: Hu Tao <hutao at cn.fujitsu.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 1369046780-17498-1-git-send-email-pbonzini at redhat.com
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Hu Tao <hutao at cn.fujitsu.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/vl.c b/vl.c
index be0a93c..59dc0b4 100644
--- a/vl.c
+++ b/vl.c
@@ -609,6 +609,7 @@ static const RunStateTransition runstate_transitions_def[] = {
     { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
 
     { RUN_STATE_GUEST_PANICKED, RUN_STATE_PAUSED },
+    { RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
 
     { RUN_STATE_MAX, RUN_STATE_MAX },
 };
commit 08d0ab3fe6bc9dfb80967a0b7d3109bc9ec7585b
Author: Lei Li <lilei at linux.vnet.ibm.com>
Date:   Mon May 20 14:51:03 2013 +0800

    chardev: Make consistent with udp device for new qapi backend
    
    When register and open a chardev udp, the backend name should be udp
    not dgram, and we do not have backend dgram in the chardev list. This
    patch makes the new qapi udp backend consistent with the original
    udp device.
    
    Signed-off-by: Lei Li <lilei at linux.vnet.ibm.com>
    Message-id: 1369032665-18159-2-git-send-email-lilei at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/qapi-schema.json b/qapi-schema.json
index 199744a..9302e7d 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3210,7 +3210,7 @@
                                      '*telnet'  : 'bool' } }
 
 ##
-# @ChardevDgram:
+# @ChardevUdp:
 #
 # Configuration info for datagram socket chardevs.
 #
@@ -3219,8 +3219,8 @@
 #
 # Since: 1.5
 ##
-{ 'type': 'ChardevDgram', 'data': { 'remote' : 'SocketAddress',
-                                    '*local' : 'SocketAddress' } }
+{ 'type': 'ChardevUdp', 'data': { 'remote' : 'SocketAddress',
+                                  '*local' : 'SocketAddress' } }
 
 ##
 # @ChardevMux:
@@ -3310,7 +3310,7 @@
                                        'parallel': 'ChardevHostdev',
                                        'pipe'   : 'ChardevHostdev',
                                        'socket' : 'ChardevSocket',
-                                       'dgram'  : 'ChardevDgram',
+                                       'udp'    : 'ChardevUdp',
                                        'pty'    : 'ChardevDummy',
                                        'null'   : 'ChardevDummy',
                                        'mux'    : 'ChardevMux',
diff --git a/qemu-char.c b/qemu-char.c
index 30a2ddf..cff2896 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3698,12 +3698,12 @@ static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock,
                                    is_telnet, is_waitconnect, errp);
 }
 
-static CharDriverState *qmp_chardev_open_dgram(ChardevDgram *dgram,
-                                               Error **errp)
+static CharDriverState *qmp_chardev_open_udp(ChardevUdp *udp,
+                                             Error **errp)
 {
     int fd;
 
-    fd = socket_dgram(dgram->remote, dgram->local, errp);
+    fd = socket_dgram(udp->remote, udp->local, errp);
     if (error_is_set(errp)) {
         return NULL;
     }
@@ -3739,8 +3739,8 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
     case CHARDEV_BACKEND_KIND_SOCKET:
         chr = qmp_chardev_open_socket(backend->socket, errp);
         break;
-    case CHARDEV_BACKEND_KIND_DGRAM:
-        chr = qmp_chardev_open_dgram(backend->dgram, errp);
+    case CHARDEV_BACKEND_KIND_UDP:
+        chr = qmp_chardev_open_udp(backend->udp, errp);
         break;
 #ifdef HAVE_CHARDEV_TTY
     case CHARDEV_BACKEND_KIND_PTY:
commit b9b5df6f0cee6b09ef3b2e5228761dd3c2cdcad7
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Sun May 19 13:22:11 2013 +0200

    ide/macio: fix wrong opaque with TRIM support
    
    Commit 215e47b9 enabled TRIM by default, which revealed a bug in TRIM
    support for the IDE macio emulation driver, introduced in d353fb72.
    
    The call to dma_bdrv_io() is using a wrong opaque of type IDEState
    instead of DBDMA_io. This patch fixes that.
    
    Fixes LP#1179104
    
    Reported-by: Michael Tokarev <mjt at tls.msk.ru>
    Tested-off-by: Michael Tokarev <mjt at tls.msk.ru>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index bf12a10..e1e4f41 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -144,7 +144,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
         break;
     case IDE_DMA_TRIM:
         m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num,
-                               ide_issue_trim, pmac_ide_transfer_cb, s,
+                               ide_issue_trim, pmac_ide_transfer_cb, io,
                                DMA_DIRECTION_TO_DEVICE);
         break;
     }
commit 118d1e4f59c36078a0d76d090d4c16deace47233
Author: Petar Jovanovic <petar.jovanovic at imgtec.com>
Date:   Mon May 13 17:14:35 2013 +0200

    target-mips: set carry bit correctly in DSPControl register
    
    First we need to clear the bit and then we set the given value.
    Instruction ADDSC sets the bit and instruction ADDWC uses this bit.
    
    Signed-off-by: Petar Jovanovic <petar.jovanovic at imgtec.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index 655dc8a..918a898 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -54,9 +54,10 @@ static inline void set_DSPControl_overflow_flag(uint32_t flag, int position,
     env->active_tc.DSPControl |= (target_ulong)flag << position;
 }
 
-static inline void set_DSPControl_carryflag(uint32_t flag, CPUMIPSState *env)
+static inline void set_DSPControl_carryflag(bool flag, CPUMIPSState *env)
 {
-    env->active_tc.DSPControl |= (target_ulong)flag << 13;
+    env->active_tc.DSPControl &= ~(1 << 13);
+    env->active_tc.DSPControl |= flag << 13;
 }
 
 static inline uint32_t get_DSPControl_carryflag(CPUMIPSState *env)
@@ -1267,7 +1268,7 @@ SUBUH_QB(subuh_r, 1);
 target_ulong helper_addsc(target_ulong rs, target_ulong rt, CPUMIPSState *env)
 {
     uint64_t temp, tempRs, tempRt;
-    int32_t flag;
+    bool flag;
 
     tempRs = (uint64_t)rs & MIPSDSP_LLO;
     tempRt = (uint64_t)rt & MIPSDSP_LLO;
commit 0ba365f4a9752a82502e829a3e8cb5f03a1ffc0c
Author: Petar Jovanovic <petar.jovanovic at imgtec.com>
Date:   Sat May 18 03:53:41 2013 +0200

    target-mips: fix EXTPDP and setting up pos field in the DSPControl reg
    
    This change makes sure that modifications of pos field in the DSPControl
    register do not trash other bits in the register. This bug can be triggered
    with the additional test case in mips32-dsp/extpdp.c in this commit.
    
    In addition to this, this change corrects incorrect calculation of the mask
    for EXTPDP.
    
    Signed-off-by: Petar Jovanovic <petar.jovanovic at imgtec.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index a55f866..655dc8a 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -19,6 +19,7 @@
 
 #include "cpu.h"
 #include "helper.h"
+#include "qemu/bitops.h"
 
 /* As the byte ordering doesn't matter, i.e. all columns are treated
    identically, these unions can be used directly.  */
@@ -90,10 +91,10 @@ static inline void set_DSPControl_pos(uint32_t pos, CPUMIPSState *env)
     dspc = env->active_tc.DSPControl;
 #ifndef TARGET_MIPS64
     dspc = dspc & 0xFFFFFFC0;
-    dspc |= pos;
+    dspc |= (pos & 0x3F);
 #else
     dspc = dspc & 0xFFFFFF80;
-    dspc |= pos;
+    dspc |= (pos & 0x7F);
 #endif
     env->active_tc.DSPControl = dspc;
 }
@@ -3439,10 +3440,9 @@ target_ulong helper_extpdp(target_ulong ac, target_ulong size,
     if (sub >= -1) {
         acc  = ((uint64_t)env->active_tc.HI[ac] << 32) |
                ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
-        temp = (acc >> (start_pos - size)) &
-               (((uint32_t)0x01 << (size + 1)) - 1);
+        temp = extract64(acc, start_pos - size, size + 1);
 
-        set_DSPControl_pos(start_pos - (size + 1), env);
+        set_DSPControl_pos(sub, env);
         set_DSPControl_efi(0, env);
     } else {
         set_DSPControl_efi(1, env);
diff --git a/tests/tcg/mips/mips32-dsp/extpdp.c b/tests/tcg/mips/mips32-dsp/extpdp.c
index 15ba082..79ee16e 100644
--- a/tests/tcg/mips/mips32-dsp/extpdp.c
+++ b/tests/tcg/mips/mips32-dsp/extpdp.c
@@ -42,5 +42,23 @@ int main()
     efi = (dsp >> 14) & 0x01;
     assert(efi == 1);
 
+
+    ach = 0;
+    acl = 0;
+    dsp = 0;
+    result = 0;
+
+    __asm
+        ("wrdsp %1\n\t"
+         "mthi %2, $ac1\n\t"
+         "mtlo %3, $ac1\n\t"
+         "extpdp %0, $ac1, 0x00\n\t"
+         "rddsp %1\n\t"
+         : "=r"(rt), "+r"(dsp)
+         : "r"(ach), "r"(acl)
+        );
+    assert(dsp == 0x3F);
+    assert(result == rt);
+
     return 0;
 }
commit d2ad50210b35c2685640f7df931a0fccb49334f7
Author: Hu Tao <hutao at cn.fujitsu.com>
Date:   Wed May 15 14:04:29 2013 +0800

    target-moxie: replace target_phys_addr_t with hwaddr
    
    target_phys_addr_t has been already replaced by hwaddr, but this
    one is introduced after.
    
    Signed-off-by: Hu Tao <hutao at cn.fujitsu.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/target-moxie/helper.c b/target-moxie/helper.c
index 6e0ac2a..5cfe889 100644
--- a/target-moxie/helper.c
+++ b/target-moxie/helper.c
@@ -116,7 +116,7 @@ int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
     return 1;
 }
 
-target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
+hwaddr cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
 {
     return addr;
 }
commit 3a8ae21bd07e8a02e6e2eb4896790a62f979acda
Author: Ed Maste <emaste at freebsd.org>
Date:   Thu May 16 11:32:28 2013 -0400

    Rename hexdump to avoid FreeBSD libutil conflict
    
    On FreeBSD libutil is used for openpty(), but it also provides a hexdump()
    which conflicts with QEMU's.
    
    Signed-off-by: Ed Maste <emaste at freebsd.org>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
index 8b33138..60f5299 100644
--- a/hw/dma/pl330.c
+++ b/hw/dma/pl330.c
@@ -1157,7 +1157,7 @@ static int pl330_exec_cycle(PL330Chan *channel)
         if (PL330_ERR_DEBUG > 1) {
             DB_PRINT("PL330 read from memory @%08x (size = %08x):\n",
                       q->addr, len);
-            hexdump((char *)buf, stderr, "", len);
+            qemu_hexdump((char *)buf, stderr, "", len);
         }
         fifo_res = pl330_fifo_push(&s->fifo, buf, len, q->tag);
         if (fifo_res == PL330_FIFO_OK) {
@@ -1189,7 +1189,7 @@ static int pl330_exec_cycle(PL330Chan *channel)
             if (PL330_ERR_DEBUG > 1) {
                 DB_PRINT("PL330 read from memory @%08x (size = %08x):\n",
                          q->addr, len);
-                hexdump((char *)buf, stderr, "", len);
+                qemu_hexdump((char *)buf, stderr, "", len);
             }
             if (q->inc) {
                 q->addr += len;
diff --git a/include/qemu-common.h b/include/qemu-common.h
index 7f18b8e..b9057d1 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -443,7 +443,7 @@ int mod_utf8_codepoint(const char *s, size_t n, char **end);
  * Hexdump a buffer to a file. An optional string prefix is added to every line
  */
 
-void hexdump(const char *buf, FILE *fp, const char *prefix, size_t size);
+void qemu_hexdump(const char *buf, FILE *fp, const char *prefix, size_t size);
 
 /* vector definitions */
 #ifdef __ALTIVEC__
diff --git a/util/hexdump.c b/util/hexdump.c
index 0d0efc8..969b340 100644
--- a/util/hexdump.c
+++ b/util/hexdump.c
@@ -15,7 +15,7 @@
 
 #include "qemu-common.h"
 
-void hexdump(const char *buf, FILE *fp, const char *prefix, size_t size)
+void qemu_hexdump(const char *buf, FILE *fp, const char *prefix, size_t size)
 {
     unsigned int b;
 
diff --git a/util/iov.c b/util/iov.c
index 78bbbe1..cc6e837 100644
--- a/util/iov.c
+++ b/util/iov.c
@@ -225,7 +225,7 @@ void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt,
     size = size > limit ? limit : size;
     buf = g_malloc(size);
     iov_to_buf(iov, iov_cnt, 0, buf, size);
-    hexdump(buf, fp, prefix, size);
+    qemu_hexdump(buf, fp, prefix, size);
     g_free(buf);
 }
 
commit 997aba8e257d183e978e9b08a26aceb4e905378d
Author: Michael Tokarev <mjt at tls.msk.ru>
Date:   Tue May 14 14:55:17 2013 +0400

    remove some double-includes
    
    Some source files #include the same header more than
    once for no good reason.  Remove second #includes in
    such cases.
    
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/audio/audio_win_int.c b/audio/audio_win_int.c
index 5869052..e132405 100644
--- a/audio/audio_win_int.c
+++ b/audio/audio_win_int.c
@@ -1,7 +1,6 @@
 /* public domain */
 
 #include "qemu-common.h"
-#include "audio.h"
 
 #define AUDIO_CAP "win-int"
 #include <windows.h>
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index 0fd9465..4405dbd 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -24,7 +24,6 @@
 #include "net/net.h"
 #include "sysemu/sysemu.h"
 #include "hw/boards.h"
-#include "hw/sysbus.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 
diff --git a/hw/audio/marvell_88w8618.c b/hw/audio/marvell_88w8618.c
index de06dfd..c5d88a7 100644
--- a/hw/audio/marvell_88w8618.c
+++ b/hw/audio/marvell_88w8618.c
@@ -12,7 +12,6 @@
 #include "hw/sysbus.h"
 #include "hw/hw.h"
 #include "hw/i2c/i2c.h"
-#include "hw/sysbus.h"
 #include "audio/audio.h"
 
 #define MP_AUDIO_SIZE           0x00001000
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 9d521cc..5033d51 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -37,7 +37,6 @@
 #include "sysemu/char.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/arch_init.h"
-#include "hw/boards.h"
 #include "qemu/log.h"
 #include "hw/mips/bios.h"
 #include "hw/ide.h"
diff --git a/hw/misc/lm32_sys.c b/hw/misc/lm32_sys.c
index 33a3b80..aeaf2b7 100644
--- a/hw/misc/lm32_sys.c
+++ b/hw/misc/lm32_sys.c
@@ -34,7 +34,6 @@
 #include "qemu/log.h"
 #include "qemu/error-report.h"
 #include "sysemu/sysemu.h"
-#include "qemu/log.h"
 
 enum {
     R_CTRL = 0,
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index c96ac81..218ea23 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -43,8 +43,6 @@
 #include "hw/ppc/xics.h"
 #include "hw/pci/msi.h"
 
-#include "sysemu/kvm.h"
-#include "kvm_ppc.h"
 #include "hw/pci/pci.h"
 
 #include "exec/address-spaces.h"
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index f518aee..8f0b7e8 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1,6 +1,5 @@
 #include "sysemu/sysemu.h"
 #include "cpu.h"
-#include "sysemu/sysemu.h"
 #include "helper_regs.h"
 #include "hw/ppc/spapr.h"
 #include "mmu-hash64.h"
diff --git a/hw/timer/exynos4210_rtc.c b/hw/timer/exynos4210_rtc.c
index bceee44..3ac77f9 100644
--- a/hw/timer/exynos4210_rtc.c
+++ b/hw/timer/exynos4210_rtc.c
@@ -31,7 +31,6 @@
 #include "hw/ptimer.h"
 
 #include "hw/hw.h"
-#include "qemu/timer.h"
 #include "sysemu/sysemu.h"
 
 #include "hw/arm/exynos4210.h"
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 2bd7090..740cf49 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -7,7 +7,6 @@
 #include "hw/isa/isa.h"
 #include "hw/block/fdc.h"
 #include "net/net.h"
-#include "exec/memory.h"
 #include "hw/i386/ioapic.h"
 
 /* PC-style peripherals (also used by other machines).  */
diff --git a/include/qapi/qmp/qlist.h b/include/qapi/qmp/qlist.h
index 382f04c..6cc4831 100644
--- a/include/qapi/qmp/qlist.h
+++ b/include/qapi/qmp/qlist.h
@@ -15,7 +15,6 @@
 
 #include "qapi/qmp/qobject.h"
 #include "qemu/queue.h"
-#include "qemu/queue.h"
 
 typedef struct QListEntry {
     QObject *value;
diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h
index ccfccae..ad4a9e5 100644
--- a/include/qemu/config-file.h
+++ b/include/qemu/config-file.h
@@ -4,7 +4,6 @@
 #include <stdio.h>
 #include "qemu/option.h"
 #include "qapi/error.h"
-#include "qemu/option.h"
 
 QemuOptsList *qemu_find_opts(const char *group);
 QemuOptsList *qemu_find_opts_err(const char *group, Error **errp);
diff --git a/monitor.c b/monitor.c
index 62aaebe..6ce2a4e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -63,7 +63,6 @@
 #ifdef CONFIG_TRACE_SIMPLE
 #include "trace/simple.h"
 #endif
-#include "ui/qemu-spice.h"
 #include "exec/memory.h"
 #include "qmp-commands.h"
 #include "hmp.h"
diff --git a/page_cache.c b/page_cache.c
index 938a79c..a05db64 100644
--- a/page_cache.c
+++ b/page_cache.c
@@ -21,7 +21,6 @@
 #include <sys/types.h>
 #include <stdbool.h>
 #include <glib.h>
-#include <strings.h>
 
 #include "qemu-common.h"
 #include "migration/page_cache.h"
diff --git a/slirp/misc.c b/slirp/misc.c
index 8ecced5..0bcc481 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -242,8 +242,6 @@ strdup(str)
 }
 #endif
 
-#include "monitor/monitor.h"
-
 void lprint(const char *format, ...)
 {
     va_list args;
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 725071e..3ab2946 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -30,8 +30,6 @@
 #include "cpu.h"
 #include "sysemu/cpus.h"
 #include "sysemu/device_tree.h"
-#include "hw/sysbus.h"
-#include "hw/ppc/spapr.h"
 #include "mmu-hash64.h"
 
 #include "hw/sysbus.h"
diff --git a/tests/tcg/linux-test.c b/tests/tcg/linux-test.c
index 83cb32d..1c6c013 100644
--- a/tests/tcg/linux-test.c
+++ b/tests/tcg/linux-test.c
@@ -39,7 +39,6 @@
 #include <dirent.h>
 #include <setjmp.h>
 #include <sys/shm.h>
-#include <sched.h>
 
 #define TESTPATH "/tmp/linux-test.tmp"
 #define TESTPORT 7654
commit 7bc9315d3a6a3c7d437e1c3d0e826121a035444a
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Tue Apr 30 10:59:50 2013 +0800

    translate: remove redundantly included qemu/timer.h
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Reviewed-By: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/translate-all.c b/translate-all.c
index da93608..d04a116 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -55,7 +55,6 @@
 #else
 #include "exec/address-spaces.h"
 #endif
-#include "qemu/timer.h"
 
 #include "exec/cputlb.h"
 #include "translate-all.h"
commit ce3a4718fe8edbe56b485778a76e9393e4f27c0e
Author: Qiao Nuohan <qiaonuohan at cn.fujitsu.com>
Date:   Wed May 8 12:39:01 2013 +0800

    Remove twice include of qemu-common.h
    
    This patch is used to remove twice include of "qemu-common.h" in
    block/win32-aio.c
    
    Signed-off-by: Qiao Nuohan <qiaonuohan at cn.fujitsu.com>
    Reviewed-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/block/win32-aio.c b/block/win32-aio.c
index 5d0fbbf..fcb7c75 100644
--- a/block/win32-aio.c
+++ b/block/win32-aio.c
@@ -25,7 +25,6 @@
 #include "qemu/timer.h"
 #include "block/block_int.h"
 #include "qemu/module.h"
-#include "qemu-common.h"
 #include "block/aio.h"
 #include "raw-aio.h"
 #include "qemu/event_notifier.h"
commit e24fed4ed4cb006c76924dacb1274f71477b9e3c
Author: Christophe Lyon <christophe.lyon at linaro.org>
Date:   Tue Apr 2 14:03:38 2013 +0200

    fix /proc/self/maps output
    
    Add a space at end of line when there is no filename to print, to
    conform to linux kernel format (see show_map_vma() in
    fs/proc/task_mmu.c).
    
    Signed-off-by: Christophe Lyon <christophe.lyon at linaro.org>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 30e93bc..1b3c0ed 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5050,10 +5050,10 @@ static int open_self_maps(void *cpu_env, int fd)
         }
         if (h2g_valid(min) && h2g_valid(max)) {
             dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
-                    " %c%c%c%c %08" PRIx64 " %02x:%02x %d%s%s\n",
+                    " %c%c%c%c %08" PRIx64 " %02x:%02x %d %s%s\n",
                     h2g(min), h2g(max), flag_r, flag_w,
                     flag_x, flag_p, offset, dev_maj, dev_min, inode,
-                    path[0] ? "          " : "", path);
+                    path[0] ? "         " : "", path);
         }
     }
 
commit 489ed4bbae309a6d897f6e037481c4c04f0737b5
Author: Petar Jovanovic <petar.jovanovic at imgtec.com>
Date:   Mon May 13 15:20:26 2013 +0200

    target-mips: fix incorrect behaviour for EXTP
    
    The mask for EXTP instruction when size=31 has not been correctly
    calculated.
    
    The test (mips32-dsp/extp.c) has been extended to include the case that
    triggers the issue.
    
    Signed-off-by: Petar Jovanovic <petar.jovanovic at imgtec.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index 9212789..a55f866 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -3415,8 +3415,7 @@ target_ulong helper_extp(target_ulong ac, target_ulong size, CPUMIPSState *env)
     if (sub >= -1) {
         acc = ((uint64_t)env->active_tc.HI[ac] << 32) |
               ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
-        temp = (acc >> (start_pos - size)) &
-               (((uint32_t)0x01 << (size + 1)) - 1);
+        temp = (acc >> (start_pos - size)) & (~0U >> (31 - size));
         set_DSPControl_efi(0, env);
     } else {
         set_DSPControl_efi(1, env);
diff --git a/tests/tcg/mips/mips32-dsp/extp.c b/tests/tcg/mips/mips32-dsp/extp.c
index 21a67af..b18bdb3 100644
--- a/tests/tcg/mips/mips32-dsp/extp.c
+++ b/tests/tcg/mips/mips32-dsp/extp.c
@@ -40,5 +40,23 @@ int main()
     dsp = (dsp >> 14) & 0x01;
     assert(dsp == 1);
 
+    ach = 0;
+    acl = 0x80000001;
+    dsp = 0x1F;
+    result = 0x80000001;
+
+    __asm
+        ("wrdsp %1\n\t"
+         "mthi %2, $ac2\n\t"
+         "mtlo %3, $ac2\n\t"
+         "extp %0, $ac2, 0x1F\n\t"
+         "rddsp %1\n\t"
+         : "=r"(rt), "+r"(dsp)
+         : "r"(ach), "r"(acl)
+        );
+    dsp = (dsp >> 14) & 0x01;
+    assert(dsp == 0);
+    assert(result == rt);
+
     return 0;
 }
commit 91b96cdc5befe56e7d9651189d0cbf06fc3f3902
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri May 17 10:01:00 2013 -0500

    Update version for 1.5.0-rc3 release
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/VERSION b/VERSION
index 0101924..80fd6ef 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.4.92
+1.4.93
commit ce4cc31695ee7e647ef5a3a3c1258089794dcb83
Merge: 77417f1 2b72001
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri May 17 10:00:30 2013 -0500

    Merge remote-tracking branch 'mdroth/qga-pull-2013-05-13' into staging
    
    * mdroth/qga-pull-2013-05-13:
      qga: unlink just created guest-file if fchmod() or fdopen() fails on it
      qga: distinguish binary modes in "guest_file_open_modes" map
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 77417f10701d330c7005b0f0a2c0cef9e05d430d
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Thu May 16 16:25:44 2013 -0500

    Revert "migration: don't account sleep time for calculating bandwidth"
    
    This reverts commit 7161082c8d8cf167c508976887a0a63f4db92b51.
    
    Reverting this patch fixes a divide-by-zero error in qemu that can be
    fairly reliably triggered by doing block migration. In this case, the
    configuration/error was:
    
    source: temp/x86_64-softmmu/qemu-system-x86_64 -enable-kvm -L temp-bios
    -M pc-i440fx-1.4 -m 512M -kernel boot/vmlinuz-x86_64 -initrd
    boot/test-initramfs-x86_64.img.gz -vga std -append seed=1234 -drive
    file=disk1.img,if=virtio -drive file=disk2.img,if=virtio -device
    virtio-net-pci,netdev=net0 -netdev user,id=net0 -monitor
    unix:/tmp/vm-hmp.sock,server,nowait -qmp
    unix:/tmp/vm-qmp.sock,server,nowait -vnc :100
    
    16837 Floating point exception(core dumped)
    
    target: temp/x86_64-softmmu/qemu-system-x86_64 -enable-kvm -L temp-bios
    -M pc-i440fx-1.4 -m 512M -kernel boot/vmlinuz-x86_64 -initrd
    boot/test-initramfs-x86_64.img.gz -vga std -append seed=1234 -drive
    file=target_disk1.img,if=virtio -drive file=target_disk2.img,if=virtio
    -device virtio-net-pci,netdev=net0 -netdev user,id=net0 -incoming
    unix:/tmp/migrate.sock -monitor
    unix:/tmp/vm-hmp-incoming.sock,server,nowait -qmp
    unix:/tmp/vm-qmp-incoming.sock,server,nowait -vnc :101
    
    Receiving block device images
    20 %
    21 %
    load of migration failed
    
    This revert potentially re-introduces a bug that was present in 1.4,
    but fixes a prevalent issue with block migration so we should revert
    it for now and take an updated patch later.
    
    Conflicts:
    
    	migration.c
    
    * fixed up to remove logic introduced in 7161082c while leaving
      changes in HEAD intact
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Message-id: 1368739544-31021-1-git-send-email-mdroth at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/migration.c b/migration.c
index 3eb0fad..bfbc345 100644
--- a/migration.c
+++ b/migration.c
@@ -498,7 +498,6 @@ static void *migration_thread(void *opaque)
 {
     MigrationState *s = opaque;
     int64_t initial_time = qemu_get_clock_ms(rt_clock);
-    int64_t sleep_time = 0;
     int64_t initial_bytes = 0;
     int64_t max_size = 0;
     int64_t start_time = initial_time;
@@ -541,7 +540,7 @@ static void *migration_thread(void *opaque)
         current_time = qemu_get_clock_ms(rt_clock);
         if (current_time >= initial_time + BUFFER_DELAY) {
             uint64_t transferred_bytes = qemu_ftell(s->file) - initial_bytes;
-            uint64_t time_spent = current_time - initial_time - sleep_time;
+            uint64_t time_spent = current_time - initial_time;
             double bandwidth = transferred_bytes / time_spent;
             max_size = bandwidth * migrate_max_downtime() / 1000000;
 
@@ -555,14 +554,12 @@ static void *migration_thread(void *opaque)
             }
 
             qemu_file_reset_rate_limit(s->file);
-            sleep_time = 0;
             initial_time = current_time;
             initial_bytes = qemu_ftell(s->file);
         }
         if (qemu_file_rate_limit(s->file)) {
             /* usleep expects microseconds */
             g_usleep((initial_time + BUFFER_DELAY - current_time)*1000);
-            sleep_time += qemu_get_clock_ms(rt_clock) - current_time;
         }
     }
 
commit 3cb8c205e36531a07dff1d8414c9e2cbf04c980b
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu May 16 17:36:01 2013 +0200

    main-loop: partial revert of 5e3bc73
    
    This patch reverts part of 5e3bc735d93dd23f074b5116fd11e1ad8cd4962f.
    
    Paolo Bonzini wrote this patch and commented:
    
    "WSAEventSelect is edge-triggered and the event will not be signaled if
    the socket handler does not consume all the data in the socket buffer."
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 1368718561-7816-3-git-send-email-stefanha at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/main-loop.c b/main-loop.c
index 2b8eed7..cf36645 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -394,6 +394,20 @@ static int os_host_main_loop_wait(uint32_t timeout)
         return ret;
     }
 
+    FD_ZERO(&rfds);
+    FD_ZERO(&wfds);
+    FD_ZERO(&xfds);
+    nfds = pollfds_fill(gpollfds, &rfds, &wfds, &xfds);
+    if (nfds >= 0) {
+        select_ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv0);
+        if (select_ret != 0) {
+            timeout = 0;
+        }
+        if (select_ret > 0) {
+            pollfds_poll(gpollfds, nfds, &rfds, &wfds, &xfds);
+        }
+    }
+
     g_main_context_prepare(context, &max_priority);
     n_poll_fds = g_main_context_query(context, max_priority, &poll_timeout,
                                       poll_fds, ARRAY_SIZE(poll_fds));
@@ -426,24 +440,6 @@ static int os_host_main_loop_wait(uint32_t timeout)
         g_main_context_dispatch(context);
     }
 
-    /* Call select after g_poll to avoid a useless iteration and therefore
-     * improve socket latency.
-     */
-
-    FD_ZERO(&rfds);
-    FD_ZERO(&wfds);
-    FD_ZERO(&xfds);
-    nfds = pollfds_fill(gpollfds, &rfds, &wfds, &xfds);
-    if (nfds >= 0) {
-        select_ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv0);
-        if (select_ret != 0) {
-            timeout = 0;
-        }
-        if (select_ret > 0) {
-            pollfds_poll(gpollfds, nfds, &rfds, &wfds, &xfds);
-        }
-    }
-
     return select_ret || g_poll_ret;
 }
 #endif
commit 8db165b36ef893ac69af0452f20eeb78e7b26b5a
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu May 16 17:36:00 2013 +0200

    main-loop: narrow win32 pollfds_fill() event bitmasks
    
    pollfds_fill() and pollfds_poll() translate GPollFD to rfds/wfds/xfds
    for sockets on win32.  select(2) is the underlying system call which is
    used to monitor sockets for activity.
    
    Currently file descriptors that monitor G_IO_ERR will be included in
    both rfds and wfds.  As a result, select(2) will report writability on
    file descriptors where we only really wanted to monitor readability
    (with errors).
    
    slirp_pollfds_poll() hit this issue: UDP sockets are blocking sockets so
    we hang in sorecvfrom() when G_IO_ERR is set due to the socket being
    writable (we only wanted to check for readability).
    
    This patch fixes the slirp_pollfds_poll() hang.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Message-id: 1368718561-7816-2-git-send-email-stefanha at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/main-loop.c b/main-loop.c
index f46aece..2b8eed7 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -333,11 +333,11 @@ static int pollfds_fill(GArray *pollfds, fd_set *rfds, fd_set *wfds,
         GPollFD *pfd = &g_array_index(pollfds, GPollFD, i);
         int fd = pfd->fd;
         int events = pfd->events;
-        if (events & (G_IO_IN | G_IO_HUP | G_IO_ERR)) {
+        if (events & G_IO_IN) {
             FD_SET(fd, rfds);
             nfds = MAX(nfds, fd);
         }
-        if (events & (G_IO_OUT | G_IO_ERR)) {
+        if (events & G_IO_OUT) {
             FD_SET(fd, wfds);
             nfds = MAX(nfds, fd);
         }
@@ -360,10 +360,10 @@ static void pollfds_poll(GArray *pollfds, int nfds, fd_set *rfds,
         int revents = 0;
 
         if (FD_ISSET(fd, rfds)) {
-            revents |= G_IO_IN | G_IO_HUP | G_IO_ERR;
+            revents |= G_IO_IN;
         }
         if (FD_ISSET(fd, wfds)) {
-            revents |= G_IO_OUT | G_IO_ERR;
+            revents |= G_IO_OUT;
         }
         if (FD_ISSET(fd, xfds)) {
             revents |= G_IO_PRI;
commit 6d46895b51103fa26c97ee0e0d895c004e9594d7
Author: KONRAD Frederic <fred.konrad at greensocs.com>
Date:   Thu May 16 19:06:07 2013 +0200

    virtio: add virtio_bus_get_dev_path.
    
    This adds virtio_bus_get_dev_path to fix migration id string which is wrong
    since the virtio refactoring.
    
    Signed-off-by: KONRAD Frederic <fred.konrad at greensocs.com>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 1368723967-21050-1-git-send-email-fred.konrad at greensocs.com
    Cc: mdroth <mdroth at linux.vnet.ibm.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index aab72ff..ea2e11a 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -154,12 +154,26 @@ void virtio_bus_set_vdev_config(VirtioBusState *bus, uint8_t *config)
     }
 }
 
+static char *virtio_bus_get_dev_path(DeviceState *dev)
+{
+    BusState *bus = qdev_get_parent_bus(dev);
+    DeviceState *proxy = DEVICE(bus->parent);
+    return qdev_get_dev_path(proxy);
+}
+
+static void virtio_bus_class_init(ObjectClass *klass, void *data)
+{
+    BusClass *bus_class = BUS_CLASS(klass);
+    bus_class->get_dev_path = virtio_bus_get_dev_path;
+}
+
 static const TypeInfo virtio_bus_info = {
     .name = TYPE_VIRTIO_BUS,
     .parent = TYPE_BUS,
     .instance_size = sizeof(VirtioBusState),
     .abstract = true,
     .class_size = sizeof(VirtioBusClass),
+    .class_init = virtio_bus_class_init
 };
 
 static void virtio_register_types(void)
commit c49fdf137f0ff74804e421f157297ab0ded5d012
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Wed May 15 16:38:35 2013 -0500

    Update version for 1.5.0-rc2 release
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/VERSION b/VERSION
index 8d9b8b2..0101924 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.4.91
+1.4.92
commit 6b41659f4eaf1daefd232a7eea6d96885eb52ee7
Merge: 8593e05 ad7f375
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Wed May 15 14:57:30 2013 -0500

    Merge remote-tracking branch 'luiz/queue/qmp' into staging
    
    # By Michael Roth (1) and Zhangleiqiang (1)
    # Via Luiz Capitulino
    * luiz/queue/qmp:
      qapi: fix leak in unit tests
      qmp: fix handling of cmd with Equals in qmp-shell
    
    Message-id: 1368625179-27962-1-git-send-email-lcapitulino at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 8593e050871c632e245190725b11f1e10c629ff2
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed May 15 17:46:11 2013 +0200

    qemu-common: Resolve vector build breakes for AltiVec
    
    On Mac OS X ppc, altivec.h defines "vector", leading to build breakage
    when used as variable name, e.g. in tracing code.
    Fix this by undefining identifiers after altivec.h inclusion.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>
    Message-id: 1368632771-4328-1-git-send-email-andreas.faerber at web.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/include/qemu-common.h b/include/qemu-common.h
index af769f5..7f18b8e 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -448,12 +448,18 @@ void hexdump(const char *buf, FILE *fp, const char *prefix, size_t size);
 /* vector definitions */
 #ifdef __ALTIVEC__
 #include <altivec.h>
-#define VECTYPE        vector unsigned char
+/* The altivec.h header says we're allowed to undef these for
+ * C++ compatibility.  Here we don't care about C++, but we
+ * undef them anyway to avoid namespace pollution.
+ */
+#undef vector
+#undef pixel
+#undef bool
+#define VECTYPE        __vector unsigned char
 #define SPLAT(p)       vec_splat(vec_ld(0, p), 0)
 #define ALL_EQ(v1, v2) vec_all_eq(v1, v2)
 /* altivec.h may redefine the bool macro as vector type.
  * Reset it to POSIX semantics. */
-#undef bool
 #define bool _Bool
 #elif defined __SSE2__
 #include <emmintrin.h>
commit 262f27b93f459ec1dee4100015c109f5e1242091
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed May 15 15:00:39 2013 +0200

    ide-test: Fix endianness problems
    
    The test case passes on big endian hosts now (tested on ppc64)
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Message-id: 1368622839-7084-1-git-send-email-kwolf at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/tests/ide-test.c b/tests/ide-test.c
index bdc1da7..365e995 100644
--- a/tests/ide-test.c
+++ b/tests/ide-test.c
@@ -252,7 +252,10 @@ static void test_bmdma_simple_rw(void)
     uintptr_t guest_buf = guest_alloc(guest_malloc, len);
 
     PrdtEntry prdt[] = {
-        { .addr = guest_buf, .size = len | PRDT_EOT },
+        {
+            .addr = cpu_to_le32(guest_buf),
+            .size = cpu_to_le32(len | PRDT_EOT),
+        },
     };
 
     buf = g_malloc(len);
@@ -304,7 +307,10 @@ static void test_bmdma_short_prdt(void)
     uint8_t status;
 
     PrdtEntry prdt[] = {
-        { .addr = 0, .size = 0x10 | PRDT_EOT },
+        {
+            .addr = 0,
+            .size = cpu_to_le32(0x10 | PRDT_EOT),
+        },
     };
 
     /* Normal request */
@@ -325,7 +331,10 @@ static void test_bmdma_long_prdt(void)
     uint8_t status;
 
     PrdtEntry prdt[] = {
-        { .addr = 0, .size = 0x1000 | PRDT_EOT },
+        {
+            .addr = 0,
+            .size = cpu_to_le32(0x1000 | PRDT_EOT),
+        },
     };
 
     /* Normal request */
@@ -355,6 +364,17 @@ static void test_bmdma_teardown(void)
     ide_test_quit();
 }
 
+static void string_cpu_to_be16(uint16_t *s, size_t bytes)
+{
+    g_assert((bytes & 1) == 0);
+    bytes /= 2;
+
+    while (bytes--) {
+        *s = cpu_to_be16(*s);
+        s++;
+    }
+}
+
 static void test_identify(void)
 {
     uint8_t data;
@@ -389,10 +409,12 @@ static void test_identify(void)
     assert_bit_clear(data, BSY | DF | ERR | DRQ);
 
     /* Check serial number/version in the buffer */
-    ret = memcmp(&buf[10], "ettsidks            ", 20);
+    string_cpu_to_be16(&buf[10], 20);
+    ret = memcmp(&buf[10], "testdisk            ", 20);
     g_assert(ret == 0);
 
-    ret = memcmp(&buf[23], "evsroi n", 8);
+    string_cpu_to_be16(&buf[23], 8);
+    ret = memcmp(&buf[23], "version ", 8);
     g_assert(ret == 0);
 
     /* Write cache enabled bit */
commit 913b4b6bf39c97bc503a629b43c66d3270b5f3f5
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue May 14 16:33:36 2013 +0100

    hw/pci-host/versatile.c: Provide property for forcing broken IRQ mapping
    
    Although we try our best to automatically detect broken versions
    of Linux which assume the old broken IRQ mapping we used to implement
    for our model of the Versatile PCI controller, it turns out that
    some particularly new kernels manage to outwit the autodetection.
    
    We therefore provide a property for enabling the old broken IRQ
    mapping, so that if users happen to have such a kernel they can
    work around its deficiencies with the command line option:
      -global versatile_pci.broken-irq-mapping=1
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1368545616-22344-4-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
index f19e2f5..2f996d9 100644
--- a/hw/pci-host/versatile.c
+++ b/hw/pci-host/versatile.c
@@ -54,6 +54,10 @@
  *   1      | 30 | 27 | 28 | 92
  *   2      | 27 | 27 | 29 | 93
  *   3      | 28 | 27 | 30 | 94
+ *
+ * Since our autodetection is not perfect we also provide a
+ * property so the user can make us start in BROKEN or FORCE_OK
+ * on reset if they know they have a bad or good kernel.
  */
 enum {
     PCI_VPB_IRQMAP_ASSUME_OK,
@@ -82,6 +86,7 @@ typedef struct {
     /* Constant for life of device: */
     int realview;
     uint32_t mem_win_size[3];
+    uint8_t irq_mapping_prop;
 
     /* Variable state: */
     uint32_t imap[3];
@@ -366,7 +371,7 @@ static void pci_vpb_reset(DeviceState *d)
     s->smap[2] = 0;
     s->selfid = 0;
     s->flags = 0;
-    s->irq_mapping = PCI_VPB_IRQMAP_ASSUME_OK;
+    s->irq_mapping = s->irq_mapping_prop;
 
     pci_vpb_update_all_windows(s);
 }
@@ -476,6 +481,12 @@ static const TypeInfo versatile_pci_host_info = {
     .class_init    = versatile_pci_host_class_init,
 };
 
+static Property pci_vpb_properties[] = {
+    DEFINE_PROP_UINT8("broken-irq-mapping", PCIVPBState, irq_mapping_prop,
+                      PCI_VPB_IRQMAP_ASSUME_OK),
+    DEFINE_PROP_END_OF_LIST()
+};
+
 static void pci_vpb_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -483,6 +494,7 @@ static void pci_vpb_class_init(ObjectClass *klass, void *data)
     dc->realize = pci_vpb_realize;
     dc->reset = pci_vpb_reset;
     dc->vmsd = &pci_vpb_vmstate;
+    dc->props = pci_vpb_properties;
 }
 
 static const TypeInfo pci_vpb_info = {
commit bc04d89165a4be6169cf44f1bdada9d48f8bad4b
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue May 14 16:33:35 2013 +0100

    hw/pci-host/versatile.c: Update autodetect to detect newer kernels
    
    Newer versatilepb kernels still don't get the IRQ mapping right
    for the PCI controller, but they get it differently wrong (they add
    a fixed +64 offset to everything they write to PCI_INTERRUPT_LINE).
    Update the autodetection to handle these too, and include a more
    detailed comment on the various different behaviours that might
    be present.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1368545616-22344-3-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
index 2bb09fa..f19e2f5 100644
--- a/hw/pci-host/versatile.c
+++ b/hw/pci-host/versatile.c
@@ -28,6 +28,32 @@
  * this allows a newer kernel to use the INTERRUPT_LINE
  * registers arbitrarily once it has indicated that it isn't
  * broken in its init code somewhere.
+ *
+ * Unfortunately we have to cope with multiple different
+ * variants on the broken kernel behaviour:
+ *  phase I (before kernel commit 1bc39ac5d) kernels assume old
+ *   QEMU behaviour, so they use IRQ 27 for all slots
+ *  phase II (1bc39ac5d and later, but before e3e92a7be6) kernels
+ *   swizzle IRQs between slots, but do it wrongly, so they
+ *   work only for every fourth PCI card, and only if (like old
+ *   QEMU) the PCI host device is at slot 0 rather than where
+ *   the h/w actually puts it
+ *  phase III (e3e92a7be6 and later) kernels still swizzle IRQs between
+ *   slots wrongly, but add a fixed offset of 64 to everything
+ *   they write to PCI_INTERRUPT_LINE.
+ *
+ * We live in hope of a mythical phase IV kernel which might
+ * actually behave in ways that work on the hardware. Such a
+ * kernel should probably start off by writing some value neither
+ * 27 nor 91 to slot zero's PCI_INTERRUPT_LINE register to
+ * disable the autodetection. After that it can do what it likes.
+ *
+ * Slot % 4 | hw | I  | II | III
+ * -------------------------------
+ *   0      | 29 | 27 | 27 | 91
+ *   1      | 30 | 27 | 28 | 92
+ *   2      | 27 | 27 | 29 | 93
+ *   3      | 28 | 27 | 30 | 94
  */
 enum {
     PCI_VPB_IRQMAP_ASSUME_OK,
@@ -214,6 +240,41 @@ static const MemoryRegionOps pci_vpb_reg_ops = {
     },
 };
 
+static int pci_vpb_broken_irq(int slot, int irq)
+{
+    /* Determine whether this IRQ value for this slot represents a
+     * known broken Linux kernel behaviour for this slot.
+     * Return one of the PCI_VPB_IRQMAP_ constants:
+     *   BROKEN : if this definitely looks like a broken kernel
+     *   FORCE_OK : if this definitely looks good
+     *   ASSUME_OK : if we can't tell
+     */
+    slot %= PCI_NUM_PINS;
+
+    if (irq == 27) {
+        if (slot == 2) {
+            /* Might be a Phase I kernel, or might be a fixed kernel,
+             * since slot 2 is where we expect this IRQ.
+             */
+            return PCI_VPB_IRQMAP_ASSUME_OK;
+        }
+        /* Phase I kernel */
+        return PCI_VPB_IRQMAP_BROKEN;
+    }
+    if (irq == slot + 27) {
+        /* Phase II kernel */
+        return PCI_VPB_IRQMAP_BROKEN;
+    }
+    if (irq == slot + 27 + 64) {
+        /* Phase III kernel */
+        return PCI_VPB_IRQMAP_BROKEN;
+    }
+    /* Anything else must be a fixed kernel, possibly using an
+     * arbitrary irq map.
+     */
+    return PCI_VPB_IRQMAP_FORCE_OK;
+}
+
 static void pci_vpb_config_write(void *opaque, hwaddr addr,
                                  uint64_t val, unsigned size)
 {
@@ -221,13 +282,7 @@ static void pci_vpb_config_write(void *opaque, hwaddr addr,
     if (!s->realview && (addr & 0xff) == PCI_INTERRUPT_LINE
         && s->irq_mapping == PCI_VPB_IRQMAP_ASSUME_OK) {
         uint8_t devfn = addr >> 8;
-        if ((PCI_SLOT(devfn) % PCI_NUM_PINS) != 2) {
-            if (val == 27) {
-                s->irq_mapping = PCI_VPB_IRQMAP_BROKEN;
-            } else {
-                s->irq_mapping = PCI_VPB_IRQMAP_FORCE_OK;
-            }
-        }
+        s->irq_mapping = pci_vpb_broken_irq(PCI_SLOT(devfn), val);
     }
     pci_data_write(&s->pci_bus, addr, val, size);
 }
commit 33201b51cbce9f18d6702a56429a4dbbe18a9961
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue May 14 16:33:34 2013 +0100

    Revert "versatile_pci: Put the host bridge PCI device at slot 29"
    
    This reverts commit 5f37ef92b7690423ac6311d3c597e182fc5f8fe6.
    It turns out that some kernels incorrectly depend on the
    old QEMU behaviour of not putting the host PCI bridge device
    where the hardware puts it, because they use a swizzling IRQ
    mapping which is incorrect but happens to match up with old
    broken QEMU when the slot number mod 4 is zero. Since we
    start PCI devices at 11, if we put the host bridge at 29
    then the first real PCI device goes at 11 and doesn't work.
    Not putting the host bridge at 29 means it defaults to 11,
    so the first real PCI device is at 12 and works.
    
    Since continuing with the old behaviour doesn't cause problems
    for kernels which do work with hardware, the simplest fix for
    this is to revert the change.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1368545616-22344-2-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
index 540daf7..2bb09fa 100644
--- a/hw/pci-host/versatile.c
+++ b/hw/pci-host/versatile.c
@@ -331,8 +331,6 @@ static void pci_vpb_init(Object *obj)
 
     object_initialize(&s->pci_dev, TYPE_VERSATILE_PCI_HOST);
     qdev_set_parent_bus(DEVICE(&s->pci_dev), BUS(&s->pci_bus));
-    object_property_set_int(OBJECT(&s->pci_dev), PCI_DEVFN(29, 0), "addr",
-                            NULL);
 
     /* Window sizes for VersatilePB; realview_pci's init will override */
     s->mem_win_size[0] = 0x0c000000;
commit 1405b6290fa2143e02dcede90b116d8d663ae669
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat May 11 21:46:58 2013 +0200

    w32: Fix configure test for -march=i486
    
    The latest version of MinGW needs a test for __sync_val_compare_and_swap
    to fix a missing symbol linker error.
    
    Reported-by: Igor Mitsyanko <i.mitsyanko at gmail.com>
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Message-id: 1368301619-32097-2-git-send-email-sw at weilnetz.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/configure b/configure
index 29b5589..5ae7e4a 100755
--- a/configure
+++ b/configure
@@ -1346,6 +1346,7 @@ static int sfaa(int *ptr)
 int main(void)
 {
   int val = 42;
+  val = __sync_val_compare_and_swap(&val, 0, 1);
   sfaa(&val);
   return val;
 }
commit 2d16c8e9885d4344a264c68feae28ae1e5f1c993
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue May 14 21:36:39 2013 +0100

    configure: Detect uuid on MacOSX (fixes compile failure)
    
    Commit 7791dba3ec broke compilation on MacOSX, because it introduced
    a new include of util.h. On MacOSX this includes pwd.h which in turn
    includes the system uuid/uuid.h, which causes a compile failure if
    QEMU was configured without CONFIG_UUID due to a conflict between
    the system header and our fallback versions:
      block/vdi.c:124:20: error: static declaration of 'uuid_generate'
      follows non-static declaration
      static inline void uuid_generate(uuid_t out)
                         ^
      /usr/include/uuid/uuid.h:63:6: note: previous declaration is here
      void uuid_generate(uuid_t out);
           ^
    
    Fix this breakage by improving configure's check for uuid to work on
    MacOSX (where there is no need to link in a separate libuuid).
    
    Note that if the user explicitly runs configure with '--disable-uuid'
    on MacOSX then QEMU will fail to compile.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1368563799-22755-1-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/configure b/configure
index cab6332..29b5589 100755
--- a/configure
+++ b/configure
@@ -1948,6 +1948,8 @@ fi
 
 ##########################################
 # uuid_generate() probe, used for vdi block driver
+# Note that on some systems (notably MacOSX) no extra library
+# need be linked to get the uuid functions.
 if test "$uuid" != "no" ; then
   uuid_libs="-luuid"
   cat > $TMPC << EOF
@@ -1959,7 +1961,9 @@ int main(void)
     return 0;
 }
 EOF
-  if compile_prog "" "$uuid_libs" ; then
+  if compile_prog "" "" ; then
+    uuid="yes"
+  elif compile_prog "" "$uuid_libs" ; then
     uuid="yes"
     libs_softmmu="$uuid_libs $libs_softmmu"
     libs_tools="$uuid_libs $libs_tools"
commit 1483adcf6ac978656718d4383d909c96dce395a6
Author: Lei Li <lilei at linux.vnet.ibm.com>
Date:   Wed May 15 16:20:40 2013 +0800

    vnc: Make ledstate comparison before modifiers updated
    
    The ledstate should be compared before modifiers updated,
    otherwise the ledstate would be the same as current_led_state.
    
    Reported-by: Gerd Hoffmann <kraxel at redhat.com>
    Signed-off-by: Lei Li <lilei at linux.vnet.ibm.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Message-id: 1368606040-11950-1-git-send-email-lilei at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/ui/vnc.c b/ui/vnc.c
index 89108de..dfc7459 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1601,6 +1601,7 @@ static void kbd_leds(void *opaque, int ledstate)
 {
     VncState *vs = opaque;
     int caps, num, scr;
+    bool has_changed = (ledstate != current_led_state(vs));
 
     caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
     num  = ledstate & QEMU_NUM_LOCK_LED  ? 1 : 0;
@@ -1617,7 +1618,7 @@ static void kbd_leds(void *opaque, int ledstate)
     }
 
     /* Sending the current led state message to the client */
-    if (ledstate != current_led_state(vs)) {
+    if (has_changed) {
         vnc_led_state_change(vs);
     }
 }
commit 800ced8cac361c5d492ac82c4aa344ff769ecf2e
Author: KONRAD Frederic <fred.konrad at greensocs.com>
Date:   Wed May 15 14:12:50 2013 +0200

    virtio-net-x: forward the netclient name and type.
    
    This forwards the name and the type of virtio-net-x to fix the bad
    behaviour of "info network" command.
    
    Signed-off-by: KONRAD Frederic <fred.konrad at greensocs.com>
    Message-id: 1368619970-23892-3-git-send-email-fred.konrad at greensocs.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c
index 5a3d97c..a1cdfb0 100644
--- a/hw/s390x/s390-virtio-bus.c
+++ b/hw/s390x/s390-virtio-bus.c
@@ -152,10 +152,13 @@ static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev)
 
 static int s390_virtio_net_init(VirtIOS390Device *s390_dev)
 {
+    DeviceState *qdev = DEVICE(s390_dev);
     VirtIONetS390 *dev = VIRTIO_NET_S390(s390_dev);
     DeviceState *vdev = DEVICE(&dev->vdev);
 
     virtio_net_set_config_size(&dev->vdev, s390_dev->host_features);
+    virtio_net_set_netclient_name(&dev->vdev, qdev->id,
+                                  object_get_typename(OBJECT(qdev)));
     qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
     if (qdev_init(vdev) < 0) {
         return -1;
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 76e6d32..5f5e267 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -550,10 +550,13 @@ static int virtio_ccw_exit(VirtioCcwDevice *dev)
 
 static int virtio_ccw_net_init(VirtioCcwDevice *ccw_dev)
 {
+    DeviceState *qdev = DEVICE(ccw_dev);
     VirtIONetCcw *dev = VIRTIO_NET_CCW(ccw_dev);
     DeviceState *vdev = DEVICE(&dev->vdev);
 
     virtio_net_set_config_size(&dev->vdev, ccw_dev->host_features[0]);
+    virtio_net_set_netclient_name(&dev->vdev, qdev->id,
+                                  object_get_typename(OBJECT(qdev)));
     qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
     if (qdev_init(vdev) < 0) {
         return -1;
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 113fbd9..70d2c6b 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1398,10 +1398,13 @@ static Property virtio_net_properties[] = {
 
 static int virtio_net_pci_init(VirtIOPCIProxy *vpci_dev)
 {
+    DeviceState *qdev = DEVICE(vpci_dev);
     VirtIONetPCI *dev = VIRTIO_NET_PCI(vpci_dev);
     DeviceState *vdev = DEVICE(&dev->vdev);
 
     virtio_net_set_config_size(&dev->vdev, vpci_dev->host_features);
+    virtio_net_set_netclient_name(&dev->vdev, qdev->id,
+                                  object_get_typename(OBJECT(qdev)));
     qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
     if (qdev_init(vdev) < 0) {
         return -1;
commit 8a253ec26ec6eb636c962a47767370f6032b8cf5
Author: KONRAD Frederic <fred.konrad at greensocs.com>
Date:   Wed May 15 14:12:49 2013 +0200

    virtio-net: add virtio_net_set_netclient_name.
    
    This adds virtio_net_set_netclient_name, which is used to set the
    name and type shown in "info network" command.
    
    Signed-off-by: KONRAD Frederic <fred.konrad at greensocs.com>
    Message-id: 1368619970-23892-2-git-send-email-fred.konrad at greensocs.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 9f18d6a..bed0822 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1275,6 +1275,29 @@ void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features)
     n->config_size = config_size;
 }
 
+void virtio_net_set_netclient_name(VirtIONet *n, const char *name,
+                                   const char *type)
+{
+    /*
+     * The name can be NULL, the netclient name will be type.x.
+     */
+    assert(type != NULL);
+
+    if (n->netclient_name) {
+        g_free(n->netclient_name);
+        n->netclient_name = NULL;
+    }
+    if (n->netclient_type) {
+        g_free(n->netclient_type);
+        n->netclient_type = NULL;
+    }
+
+    if (name != NULL) {
+        n->netclient_name = g_strdup(name);
+    }
+    n->netclient_type = g_strdup(type);
+}
+
 static int virtio_net_device_init(VirtIODevice *vdev)
 {
     int i;
@@ -1315,8 +1338,17 @@ static int virtio_net_device_init(VirtIODevice *vdev)
     memcpy(&n->mac[0], &n->nic_conf.macaddr, sizeof(n->mac));
     n->status = VIRTIO_NET_S_LINK_UP;
 
-    n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf,
-                          object_get_typename(OBJECT(qdev)), qdev->id, n);
+    if (n->netclient_type) {
+        /*
+         * Happen when virtio_net_set_netclient_name has been called.
+         */
+        n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf,
+                              n->netclient_type, n->netclient_name, n);
+    } else {
+        n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf,
+                              object_get_typename(OBJECT(qdev)), qdev->id, n);
+    }
+
     peer_test_vnet_hdr(n);
     if (peer_has_vnet_hdr(n)) {
         for (i = 0; i < n->max_queues; i++) {
@@ -1357,6 +1389,15 @@ static int virtio_net_device_exit(DeviceState *qdev)
 
     unregister_savevm(qdev, "virtio-net", n);
 
+    if (n->netclient_name) {
+        g_free(n->netclient_name);
+        n->netclient_name = NULL;
+    }
+    if (n->netclient_type) {
+        g_free(n->netclient_type);
+        n->netclient_type = NULL;
+    }
+
     g_free(n->mac_table.macs);
     g_free(n->vlans);
 
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index ce4ab50..beeead7 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -188,6 +188,8 @@ typedef struct VirtIONet {
     uint16_t max_queues;
     uint16_t curr_queues;
     size_t config_size;
+    char *netclient_name;
+    char *netclient_type;
 } VirtIONet;
 
 #define VIRTIO_NET_CTRL_MAC    1
@@ -255,5 +257,7 @@ struct virtio_net_ctrl_mq {
     DEFINE_PROP_STRING("tx", _state, _field.tx)
 
 void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features);
+void virtio_net_set_netclient_name(VirtIONet *n, const char *name,
+                                   const char *type);
 
 #endif
commit ad7f375df681503baa6ebef065818868e1216976
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Thu May 9 21:20:57 2013 -0500

    qapi: fix leak in unit tests
    
    qmp_output_get_qobject() increments the qobject's reference count. Since
    we currently pass this straight into qobject_to_json() so we can feed
    the data into a QMP input visitor, we never actually free the underlying
    qobject when qmp_output_visitor_cleanup() is called. This causes leaks
    on all of the QMP serialization tests.
    
    Fix this by holding a pointer to the qobject and decref'ing it before
    returning from qmp_deserialize().
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c
index e84926f..8c8adac 100644
--- a/tests/test-visitor-serialization.c
+++ b/tests/test-visitor-serialization.c
@@ -657,11 +657,16 @@ static void qmp_deserialize(void **native_out, void *datap,
                             VisitorFunc visit, Error **errp)
 {
     QmpSerializeData *d = datap;
-    QString *output_json = qobject_to_json(qmp_output_get_qobject(d->qov));
-    QObject *obj = qobject_from_json(qstring_get_str(output_json));
+    QString *output_json;
+    QObject *obj_orig, *obj;
+
+    obj_orig = qmp_output_get_qobject(d->qov);
+    output_json = qobject_to_json(obj_orig);
+    obj = qobject_from_json(qstring_get_str(output_json));
 
     QDECREF(output_json);
     d->qiv = qmp_input_visitor_new(obj);
+    qobject_decref(obj_orig);
     qobject_decref(obj);
     visit(qmp_input_get_visitor(d->qiv), native_out, errp);
 }
commit 74bc9066bc2cf61dd12994ea3b73401d33112656
Author: Zhangleiqiang <zhangleiqiang at huawei.com>
Date:   Mon May 6 08:31:23 2013 +0000

    qmp: fix handling of cmd with Equals in qmp-shell
    
    	qmp: fix handling of cmd with equal mark in qmp-shell
    
        qmp-shell splits the argument and value of input command
    	by equal mark("="). But there are commands whose values
    	include equal mark themselves, and the json built by
    	qmp-shell will not correct. For example, when using NBD as
    	the target of block-backup command, the input
    	"block-backup target=nbd+unix:///drive0?socket=/tmp/nbd.sock"
    	will fail, because the json built will be as follows:
    
        {
    		"execute":"block-backup",
    		"arguments":{"target":"nbd+unix:///drive0?socket"}
    	}
    
        Fix it by joining the sections split by equal mark excluding the
    	first section in __build_cmd function when the length of sections
    	is larger than two.
    
    Signed-off-by: zhangleiqiang <zhangleiqiang at huawei.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/QMP/qmp-shell b/QMP/qmp-shell
index d126e63..73cb3b6 100755
--- a/QMP/qmp-shell
+++ b/QMP/qmp-shell
@@ -99,6 +99,8 @@ class QMPShell(qmp.QEMUMonitorProtocol):
         for arg in cmdargs[1:]:
             opt = arg.split('=')
             try:
+                if(len(opt) > 2):
+                    opt[1] = '='.join(opt[1:])
                 value = int(opt[1])
             except ValueError:
                 if opt[1] == 'true':
commit 2b720018060179b394f8ce736983373ab80dd37c
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Wed May 8 17:31:36 2013 +0200

    qga: unlink just created guest-file if fchmod() or fdopen() fails on it
    
    We shouldn't allow guest filesystem pollution on error paths.
    
    Suggested-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 2eec712..e199738 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -355,6 +355,9 @@ safe_open_or_create(const char *path, const char *mode, Error **err)
             }
 
             close(fd);
+            if (oflag & O_CREAT) {
+                unlink(path);
+            }
         }
     }
 
commit 8fe6bbca7176c9dfb35083a71bda95c1856e2ed5
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Wed May 8 17:31:35 2013 +0200

    qga: distinguish binary modes in "guest_file_open_modes" map
    
    In Windows guests this may make a difference.
    
    Since the original patch (commit c689b4f1) sought to be pedantic and to
    consider theoretical corner cases of portability, we should fix it up
    where it failed to come through in that pursuit.
    
    Suggested-by: Eric Blake <eblake at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 04c6951..2eec712 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -242,17 +242,27 @@ static GuestFileHandle *guest_file_handle_find(int64_t id, Error **err)
 
 typedef const char * const ccpc;
 
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
 /* http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html */
 static const struct {
     ccpc *forms;
     int oflag_base;
 } guest_file_open_modes[] = {
-    { (ccpc[]){ "r",  "rb",         NULL }, O_RDONLY                      },
-    { (ccpc[]){ "w",  "wb",         NULL }, O_WRONLY | O_CREAT | O_TRUNC  },
-    { (ccpc[]){ "a",  "ab",         NULL }, O_WRONLY | O_CREAT | O_APPEND },
-    { (ccpc[]){ "r+", "rb+", "r+b", NULL }, O_RDWR                        },
-    { (ccpc[]){ "w+", "wb+", "w+b", NULL }, O_RDWR   | O_CREAT | O_TRUNC  },
-    { (ccpc[]){ "a+", "ab+", "a+b", NULL }, O_RDWR   | O_CREAT | O_APPEND }
+    { (ccpc[]){ "r",          NULL }, O_RDONLY                                 },
+    { (ccpc[]){ "rb",         NULL }, O_RDONLY                      | O_BINARY },
+    { (ccpc[]){ "w",          NULL }, O_WRONLY | O_CREAT | O_TRUNC             },
+    { (ccpc[]){ "wb",         NULL }, O_WRONLY | O_CREAT | O_TRUNC  | O_BINARY },
+    { (ccpc[]){ "a",          NULL }, O_WRONLY | O_CREAT | O_APPEND            },
+    { (ccpc[]){ "ab",         NULL }, O_WRONLY | O_CREAT | O_APPEND | O_BINARY },
+    { (ccpc[]){ "r+",         NULL }, O_RDWR                                   },
+    { (ccpc[]){ "rb+", "r+b", NULL }, O_RDWR                        | O_BINARY },
+    { (ccpc[]){ "w+",         NULL }, O_RDWR   | O_CREAT | O_TRUNC             },
+    { (ccpc[]){ "wb+", "w+b", NULL }, O_RDWR   | O_CREAT | O_TRUNC  | O_BINARY },
+    { (ccpc[]){ "a+",         NULL }, O_RDWR   | O_CREAT | O_APPEND            },
+    { (ccpc[]){ "ab+", "a+b", NULL }, O_RDWR   | O_CREAT | O_APPEND | O_BINARY }
 };
 
 static int


More information about the Spice-commits mailing list